fix: 修复数组回调与原始值属性访问

This commit is contained in:
2026-06-17 12:59:11 +08:00
parent 6a99209af8
commit f7834df245
10 changed files with 328 additions and 66 deletions
+49 -27
View File
@@ -59,6 +59,36 @@ impl Vm {
make_private_name_id(local_id)
}
fn primitive_property_get(&mut self, val: JsValue, prop_name_si: u32) -> Result<Option<JsValue>, String> {
if val.is_string() {
let length_si = self.kernel_core.string_forge().intern("length").0;
if prop_name_si == length_si {
let len = self
.kernel_core
.string_forge()
.lookup(val.as_string_index())
.unwrap_or_default()
.encode_utf16()
.count();
return Ok(Some(JsValue::int(len as i32)));
}
let proto_ptr = self.session.builtin_world().string_proto.as_ptr() as *mut JsObject;
let proto = unsafe { &*proto_ptr };
return self.ordinary_get(proto, prop_name_si, val).map(Some);
}
if val.is_int() || val.is_double() {
let proto_ptr = self.session.builtin_world().number_proto.as_ptr() as *mut JsObject;
let proto = unsafe { &*proto_ptr };
return self.ordinary_get(proto, prop_name_si, val).map(Some);
}
if val.is_bool() {
let proto_ptr = self.session.builtin_world().boolean_proto.as_ptr() as *mut JsObject;
let proto = unsafe { &*proto_ptr };
return self.ordinary_get(proto, prop_name_si, val).map(Some);
}
Ok(None)
}
fn private_slot(&self, obj: &JsObject, private_key: u32) -> Option<u32> {
self.kernel_core.shape_forge().lookup_position(obj.shape_id(), private_key)
}
@@ -138,27 +168,11 @@ impl Vm {
let val = self.regs[a];
let obj_ptr = val.as_object_ptr() as *mut JsObject;
if obj_ptr.is_null() {
if val.is_string() {
let proto_ptr = self.session.builtin_world().string_proto.as_ptr() as *mut JsObject;
let proto = unsafe { &*proto_ptr };
let prop_name_si = self.property_key_si(self.regs[b]);
let resolved = self.ordinary_get(proto, prop_name_si, val)?;
if !resolved.is_undefined() {
self.regs[a] = resolved;
self.pc += 3;
return Ok(());
}
}
if val.is_int() || val.is_double() {
let proto_ptr = self.session.builtin_world().number_proto.as_ptr() as *mut JsObject;
let proto = unsafe { &*proto_ptr };
let prop_name_si = self.property_key_si(self.regs[b]);
let resolved = self.ordinary_get(proto, prop_name_si, val)?;
if !resolved.is_undefined() {
self.regs[a] = resolved;
self.pc += 3;
return Ok(());
}
let prop_name_si = self.property_key_si(self.regs[b]);
if let Some(resolved) = self.primitive_property_get(val, prop_name_si)? {
self.regs[a] = resolved;
self.pc += 3;
return Ok(());
}
self.raise_type_error("IC_GET_PROP on non-object")?;
return Ok(());
@@ -222,7 +236,7 @@ impl Vm {
}
fn dispatch_ic_set_prop(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
let Some(obj_ptr) = self.checked_object_ptr(self.regs[rd], "IC_SET_PROP on non-object")? else {
let Some(obj_ptr) = self.checked_object_ptr(self.regs[rd], "Cannot create property on non-object")? else {
return Ok(());
};
@@ -286,11 +300,15 @@ impl Vm {
}
fn dispatch_get_prop(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
let prop_name_si = self.property_key_si(self.regs[b]);
if let Some(value) = self.primitive_property_get(self.regs[rd], prop_name_si)? {
self.regs[a] = value;
return Ok(());
}
let Some(obj_ptr) = self.checked_object_ptr(self.regs[rd], "GET_PROP on non-object")? else {
return Ok(());
};
let obj = unsafe { &*obj_ptr };
let prop_name_si = self.property_key_si(self.regs[b]);
let val = self.ordinary_get_with_target(obj, prop_name_si, self.regs[rd], a as u8)?;
if self.accessor_frame_target_reg.take().is_none() {
self.regs[a] = val;
@@ -299,7 +317,7 @@ impl Vm {
}
fn dispatch_set_prop(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
let Some(obj_ptr) = self.checked_object_ptr(self.regs[rd], "SET_PROP on non-object")? else {
let Some(obj_ptr) = self.checked_object_ptr(self.regs[rd], "Cannot create property on non-object")? else {
return Ok(());
};
let prop_name_si = self.property_key_si(self.regs[b]);
@@ -320,11 +338,15 @@ impl Vm {
}
fn dispatch_get_prop_dynamic(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
let prop_name_si = self.property_key_si(self.regs[a]);
if let Some(value) = self.primitive_property_get(self.regs[rd], prop_name_si)? {
self.regs[b] = value;
return Ok(());
}
let Some(obj_ptr) = self.checked_object_ptr(self.regs[rd], "GET_PROP_DYNAMIC on non-object")? else {
return Ok(());
};
let obj = unsafe { &*obj_ptr };
let prop_name_si = self.property_key_si(self.regs[a]);
let val = self.ordinary_get_with_target(obj, prop_name_si, self.regs[rd], b as u8)?;
if self.accessor_frame_target_reg.take().is_none() {
self.regs[b] = val;
@@ -333,7 +355,7 @@ impl Vm {
}
fn dispatch_set_prop_dynamic(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
let Some(obj_ptr) = self.checked_object_ptr(self.regs[rd], "SET_PROP_DYNAMIC on non-object")? else {
let Some(obj_ptr) = self.checked_object_ptr(self.regs[rd], "Cannot create property on non-object")? else {
return Ok(());
};
let prop_name_si = self.property_key_si(self.regs[a]);
@@ -354,7 +376,7 @@ impl Vm {
}
fn dispatch_set_elem(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
let Some(obj_ptr) = self.checked_object_ptr(self.regs[rd], "SET_ELEM on non-object")? else {
let Some(obj_ptr) = self.checked_object_ptr(self.regs[rd], "Cannot create property on non-object")? else {
return Ok(());
};
let idx = if self.regs[a].is_int() {