fix: 修复同步调用参数限制与内建语义错误
This commit is contained in:
@@ -4,9 +4,9 @@ use oxide_types::value::JsValue;
|
||||
|
||||
impl Vm {
|
||||
#[inline(always)]
|
||||
pub(crate) fn dispatch_add(&mut self, rd: usize, a: usize, b: usize) {
|
||||
let lhs = self.regs[a];
|
||||
let rhs = self.regs[b];
|
||||
pub(crate) fn dispatch_add(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
|
||||
let lhs = self.coerce_primitive_bounded(self.regs[a], false)?;
|
||||
let rhs = self.coerce_primitive_bounded(self.regs[b], false)?;
|
||||
if lhs.is_string() || rhs.is_string() {
|
||||
let ls = coercion::to_string(self.kernel_core.string_forge().as_ref(), lhs);
|
||||
let rs = coercion::to_string(self.kernel_core.string_forge().as_ref(), rhs);
|
||||
@@ -17,5 +17,6 @@ impl Vm {
|
||||
let rn = coercion::to_number(rhs, self.kernel_core.string_forge().as_ref());
|
||||
self.regs[rd] = JsValue::float(ln + rn);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use crate::coercion;
|
||||
use crate::vm::Vm;
|
||||
use oxide_types::value::JsValue;
|
||||
|
||||
@@ -13,92 +12,98 @@ impl Vm {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn dispatch_bit_and(&mut self, rd: usize, a: usize, b: usize) {
|
||||
let sf = self.kernel_core.string_forge().as_ref();
|
||||
self.regs[rd] = JsValue::int(coercion::to_int32(self.regs[a], sf) & coercion::to_int32(self.regs[b], sf));
|
||||
pub(crate) fn dispatch_bit_and(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
|
||||
self.regs[rd] =
|
||||
JsValue::int(self.coerce_int32_bounded(self.regs[a])? & self.coerce_int32_bounded(self.regs[b])?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn dispatch_bit_or(&mut self, rd: usize, a: usize, b: usize) {
|
||||
let sf = self.kernel_core.string_forge().as_ref();
|
||||
self.regs[rd] = JsValue::int(coercion::to_int32(self.regs[a], sf) | coercion::to_int32(self.regs[b], sf));
|
||||
pub(crate) fn dispatch_bit_or(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
|
||||
self.regs[rd] =
|
||||
JsValue::int(self.coerce_int32_bounded(self.regs[a])? | self.coerce_int32_bounded(self.regs[b])?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn dispatch_bit_xor(&mut self, rd: usize, a: usize, b: usize) {
|
||||
let sf = self.kernel_core.string_forge().as_ref();
|
||||
self.regs[rd] = JsValue::int(coercion::to_int32(self.regs[a], sf) ^ coercion::to_int32(self.regs[b], sf));
|
||||
pub(crate) fn dispatch_bit_xor(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
|
||||
self.regs[rd] =
|
||||
JsValue::int(self.coerce_int32_bounded(self.regs[a])? ^ self.coerce_int32_bounded(self.regs[b])?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn dispatch_shl(&mut self, rd: usize, a: usize, b: usize) {
|
||||
let sf = self.kernel_core.string_forge().as_ref();
|
||||
let lhs = coercion::to_int32(self.regs[a], sf);
|
||||
let shift = coercion::to_uint32(self.regs[b], sf) & 0x1F;
|
||||
pub(crate) fn dispatch_shl(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
|
||||
let lhs = self.coerce_int32_bounded(self.regs[a])?;
|
||||
let shift = self.coerce_uint32_bounded(self.regs[b])? & 0x1F;
|
||||
self.regs[rd] = JsValue::int(lhs.wrapping_shl(shift));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn dispatch_shr(&mut self, rd: usize, a: usize, b: usize) {
|
||||
let sf = self.kernel_core.string_forge().as_ref();
|
||||
let lhs = coercion::to_int32(self.regs[a], sf);
|
||||
let shift = coercion::to_uint32(self.regs[b], sf) & 0x1F;
|
||||
pub(crate) fn dispatch_shr(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
|
||||
let lhs = self.coerce_int32_bounded(self.regs[a])?;
|
||||
let shift = self.coerce_uint32_bounded(self.regs[b])? & 0x1F;
|
||||
self.regs[rd] = JsValue::int(lhs >> shift);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn dispatch_ushr(&mut self, rd: usize, a: usize, b: usize) {
|
||||
let sf = self.kernel_core.string_forge().as_ref();
|
||||
let lhs = coercion::to_uint32(self.regs[a], sf);
|
||||
let shift = coercion::to_uint32(self.regs[b], sf) & 0x1F;
|
||||
pub(crate) fn dispatch_ushr(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
|
||||
let lhs = self.coerce_uint32_bounded(self.regs[a])?;
|
||||
let shift = self.coerce_uint32_bounded(self.regs[b])? & 0x1F;
|
||||
self.write_ushr_result(rd, lhs >> shift);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn dispatch_bit_not(&mut self, rd: usize, a: usize) {
|
||||
let sf = self.kernel_core.string_forge().as_ref();
|
||||
self.regs[rd] = JsValue::int(!coercion::to_int32(self.regs[a], sf));
|
||||
pub(crate) fn dispatch_bit_not(&mut self, rd: usize, a: usize) -> Result<(), String> {
|
||||
self.regs[rd] = JsValue::int(!self.coerce_int32_bounded(self.regs[a])?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn dispatch_compound_bit_and(&mut self, rd: usize, a: usize) {
|
||||
let sf = self.kernel_core.string_forge().as_ref();
|
||||
self.regs[rd] = JsValue::int(coercion::to_int32(self.regs[rd], sf) & coercion::to_int32(self.regs[a], sf));
|
||||
pub(crate) fn dispatch_compound_bit_and(&mut self, rd: usize, a: usize) -> Result<(), String> {
|
||||
self.regs[rd] =
|
||||
JsValue::int(self.coerce_int32_bounded(self.regs[rd])? & self.coerce_int32_bounded(self.regs[a])?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn dispatch_compound_bit_or(&mut self, rd: usize, a: usize) {
|
||||
let sf = self.kernel_core.string_forge().as_ref();
|
||||
self.regs[rd] = JsValue::int(coercion::to_int32(self.regs[rd], sf) | coercion::to_int32(self.regs[a], sf));
|
||||
pub(crate) fn dispatch_compound_bit_or(&mut self, rd: usize, a: usize) -> Result<(), String> {
|
||||
self.regs[rd] =
|
||||
JsValue::int(self.coerce_int32_bounded(self.regs[rd])? | self.coerce_int32_bounded(self.regs[a])?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn dispatch_compound_bit_xor(&mut self, rd: usize, a: usize) {
|
||||
let sf = self.kernel_core.string_forge().as_ref();
|
||||
self.regs[rd] = JsValue::int(coercion::to_int32(self.regs[rd], sf) ^ coercion::to_int32(self.regs[a], sf));
|
||||
pub(crate) fn dispatch_compound_bit_xor(&mut self, rd: usize, a: usize) -> Result<(), String> {
|
||||
self.regs[rd] =
|
||||
JsValue::int(self.coerce_int32_bounded(self.regs[rd])? ^ self.coerce_int32_bounded(self.regs[a])?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn dispatch_compound_shl(&mut self, rd: usize, a: usize) {
|
||||
let sf = self.kernel_core.string_forge().as_ref();
|
||||
let lhs = coercion::to_int32(self.regs[rd], sf);
|
||||
let shift = coercion::to_uint32(self.regs[a], sf) & 0x1F;
|
||||
pub(crate) fn dispatch_compound_shl(&mut self, rd: usize, a: usize) -> Result<(), String> {
|
||||
let lhs = self.coerce_int32_bounded(self.regs[rd])?;
|
||||
let shift = self.coerce_uint32_bounded(self.regs[a])? & 0x1F;
|
||||
self.regs[rd] = JsValue::int(lhs.wrapping_shl(shift));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn dispatch_compound_shr(&mut self, rd: usize, a: usize) {
|
||||
let sf = self.kernel_core.string_forge().as_ref();
|
||||
let lhs = coercion::to_int32(self.regs[rd], sf);
|
||||
let shift = coercion::to_uint32(self.regs[a], sf) & 0x1F;
|
||||
pub(crate) fn dispatch_compound_shr(&mut self, rd: usize, a: usize) -> Result<(), String> {
|
||||
let lhs = self.coerce_int32_bounded(self.regs[rd])?;
|
||||
let shift = self.coerce_uint32_bounded(self.regs[a])? & 0x1F;
|
||||
self.regs[rd] = JsValue::int(lhs >> shift);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn dispatch_compound_ushr(&mut self, rd: usize, a: usize) {
|
||||
let sf = self.kernel_core.string_forge().as_ref();
|
||||
let lhs = coercion::to_uint32(self.regs[rd], sf);
|
||||
let shift = coercion::to_uint32(self.regs[a], sf) & 0x1F;
|
||||
pub(crate) fn dispatch_compound_ushr(&mut self, rd: usize, a: usize) -> Result<(), String> {
|
||||
let lhs = self.coerce_uint32_bounded(self.regs[rd])?;
|
||||
let shift = self.coerce_uint32_bounded(self.regs[a])? & 0x1F;
|
||||
self.write_ushr_result(rd, lhs >> shift);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ impl Vm {
|
||||
let receiver = self.regs[rd];
|
||||
let obj = unsafe { &mut *obj_ptr };
|
||||
let prop_val = self.read_member_prop(obj, prop_name_si, receiver)?;
|
||||
let n = coercion::to_number(prop_val, self.kernel_core.string_forge().as_ref());
|
||||
let n = self.coerce_number_bounded(prop_val)?;
|
||||
let new_val = JsValue::float(n + 1.0);
|
||||
self.set_member_prop(obj, prop_name_si, new_val, receiver)?;
|
||||
self.regs[a] = new_val;
|
||||
@@ -61,7 +61,7 @@ impl Vm {
|
||||
let receiver = self.regs[rd];
|
||||
let obj = unsafe { &mut *obj_ptr };
|
||||
let prop_val = self.read_member_prop(obj, prop_name_si, receiver)?;
|
||||
let n = coercion::to_number(prop_val, self.kernel_core.string_forge().as_ref());
|
||||
let n = self.coerce_number_bounded(prop_val)?;
|
||||
let new_val = JsValue::float(n - 1.0);
|
||||
self.set_member_prop(obj, prop_name_si, new_val, receiver)?;
|
||||
self.regs[a] = new_val;
|
||||
@@ -76,7 +76,7 @@ impl Vm {
|
||||
let obj = unsafe { &mut *obj_ptr };
|
||||
let prop_name_si = self.property_key_si(self.regs[a]);
|
||||
let prop_val = self.ordinary_get(obj, prop_name_si, receiver)?;
|
||||
let n = coercion::to_number(prop_val, self.kernel_core.string_forge().as_ref());
|
||||
let n = self.coerce_number_bounded(prop_val)?;
|
||||
let new_val = JsValue::float(n + 1.0);
|
||||
self.ordinary_set(obj, prop_name_si, new_val, receiver)?;
|
||||
self.regs[b] = new_val;
|
||||
@@ -91,7 +91,7 @@ impl Vm {
|
||||
let obj = unsafe { &mut *obj_ptr };
|
||||
let prop_name_si = self.property_key_si(self.regs[a]);
|
||||
let prop_val = self.ordinary_get(obj, prop_name_si, receiver)?;
|
||||
let n = coercion::to_number(prop_val, self.kernel_core.string_forge().as_ref());
|
||||
let n = self.coerce_number_bounded(prop_val)?;
|
||||
let new_val = JsValue::float(n - 1.0);
|
||||
self.ordinary_set(obj, prop_name_si, new_val, receiver)?;
|
||||
self.regs[b] = new_val;
|
||||
@@ -103,9 +103,12 @@ impl Vm {
|
||||
return Ok(());
|
||||
};
|
||||
let receiver = self.regs[rd];
|
||||
let obj = unsafe { &mut *obj_ptr };
|
||||
let prop_val = self.read_member_prop(obj, prop_name_si, receiver)?;
|
||||
let rhs = self.regs[a];
|
||||
let prop_raw = {
|
||||
let obj = unsafe { &mut *obj_ptr };
|
||||
self.read_member_prop(obj, prop_name_si, receiver)?
|
||||
};
|
||||
let prop_val = self.coerce_primitive_bounded(prop_raw, false)?;
|
||||
let rhs = self.coerce_primitive_bounded(self.regs[a], false)?;
|
||||
let new_val = if prop_val.is_string() || rhs.is_string() {
|
||||
let ls = coercion::to_string(self.kernel_core.string_forge().as_ref(), prop_val);
|
||||
let rs = coercion::to_string(self.kernel_core.string_forge().as_ref(), rhs);
|
||||
@@ -115,6 +118,7 @@ impl Vm {
|
||||
let rn = coercion::to_number(rhs, self.kernel_core.string_forge().as_ref());
|
||||
JsValue::float(ln + rn)
|
||||
};
|
||||
let obj = unsafe { &mut *obj_ptr };
|
||||
self.set_member_prop(obj, prop_name_si, new_val, receiver)?;
|
||||
self.regs[a] = new_val;
|
||||
Ok(())
|
||||
@@ -130,12 +134,15 @@ impl Vm {
|
||||
return Ok(());
|
||||
};
|
||||
let receiver = self.regs[rd];
|
||||
let obj = unsafe { &mut *obj_ptr };
|
||||
let prop_val = self.read_member_prop(obj, prop_name_si, receiver)?;
|
||||
let ln = coercion::to_number(prop_val, self.kernel_core.string_forge().as_ref());
|
||||
let rn = coercion::to_number(self.regs[a], self.kernel_core.string_forge().as_ref());
|
||||
let ln = {
|
||||
let obj = unsafe { &mut *obj_ptr };
|
||||
let prop_val = self.read_member_prop(obj, prop_name_si, receiver)?;
|
||||
self.coerce_number_bounded(prop_val)?
|
||||
};
|
||||
let rn = self.coerce_number_bounded(self.regs[a])?;
|
||||
let new_val = JsValue::float(op(ln, rn));
|
||||
self.regs[a] = new_val;
|
||||
let obj = unsafe { &mut *obj_ptr };
|
||||
self.set_member_prop(obj, prop_name_si, new_val, receiver)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user