mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-24 02:31:13 +08:00
feat: 支持可选链空值合并与逻辑赋值
This commit is contained in:
@@ -23,6 +23,12 @@ impl Vm {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn dispatch_nullish(&mut self, rd: usize, a: usize, b: usize) {
|
||||
let val = self.regs[a];
|
||||
self.regs[rd] = if val.is_nullish() { self.regs[b] } else { val };
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn dispatch_not(&mut self, rd: usize, a: usize) {
|
||||
let b = !coercion::to_boolean(self.regs[a], self.kernel_core.string_forge().as_ref());
|
||||
|
||||
@@ -687,6 +687,13 @@ impl Vm {
|
||||
}
|
||||
}
|
||||
|
||||
OpCode::JMP_IF_NULLISH => {
|
||||
if self.regs[rd].is_nullish() {
|
||||
let offset = opcode::offset16(instr) as isize;
|
||||
self.pc = ((self.pc as isize) + offset - 1) as usize;
|
||||
}
|
||||
}
|
||||
|
||||
OpCode::LOAD_VAR => {
|
||||
if a == 254
|
||||
&& self.frames.last().map(|frame| frame.is_derived_constructor).unwrap_or(false)
|
||||
@@ -1016,15 +1023,30 @@ impl Vm {
|
||||
}
|
||||
|
||||
OpCode::DELETE_PROP_STATIC => {
|
||||
let _ = self.bytecode[self.pc];
|
||||
let prop_idx = self.bytecode[self.pc] as usize;
|
||||
self.pc += 1;
|
||||
throw_err!(self, TypeError, "property deletion not supported");
|
||||
let key_val = self.constants.get(prop_idx).copied().unwrap_or_else(JsValue::undefined);
|
||||
let prop_name_si = self.property_key_si(key_val);
|
||||
let Some(obj_ptr) = self.checked_object_ptr(self.regs[rd], "delete on non-object")? else {
|
||||
continue;
|
||||
};
|
||||
let obj = unsafe { &mut *obj_ptr };
|
||||
if let Some(pos) = self.kernel_core.shape_forge().lookup_position(obj.shape_id(), prop_name_si) {
|
||||
obj.set_prop_at(pos, JsValue::undefined());
|
||||
}
|
||||
self.regs[rd] = JsValue::bool(true);
|
||||
}
|
||||
|
||||
OpCode::DELETE_PROP_DYNAMIC => {
|
||||
let _ = self.regs[a];
|
||||
let _ = self.regs[b];
|
||||
throw_err!(self, TypeError, "property deletion not supported");
|
||||
let prop_name_si = self.property_key_si(self.regs[b]);
|
||||
let Some(obj_ptr) = self.checked_object_ptr(self.regs[rd], "delete on non-object")? else {
|
||||
continue;
|
||||
};
|
||||
let obj = unsafe { &mut *obj_ptr };
|
||||
if let Some(pos) = self.kernel_core.shape_forge().lookup_position(obj.shape_id(), prop_name_si) {
|
||||
obj.set_prop_at(pos, JsValue::undefined());
|
||||
}
|
||||
self.regs[rd] = JsValue::bool(true);
|
||||
}
|
||||
|
||||
OpCode::INSTANCEOF => {
|
||||
@@ -1047,6 +1069,10 @@ impl Vm {
|
||||
self.dispatch_or(rd, a, b);
|
||||
}
|
||||
|
||||
OpCode::NULLISH => {
|
||||
self.dispatch_nullish(rd, a, b);
|
||||
}
|
||||
|
||||
OpCode::INC_PRE => {
|
||||
let n = coercion::to_number(self.regs[rd], self.kernel_core.string_forge().as_ref());
|
||||
let result = JsValue::float(n + 1.0);
|
||||
|
||||
Reference in New Issue
Block a user