feat: 支持对象进行完整 ES 属性解析

This commit is contained in:
2026-06-05 19:10:44 +08:00
parent 89a9ec8b4a
commit 11f2a2e7cb
3 changed files with 71 additions and 21 deletions
+28 -18
View File
@@ -61,6 +61,21 @@ impl Vm {
self.string_reverse.get(idx).map(|s| s.as_str())
}
fn resolve_property(&self, obj: &JsObject, prop_name_si: u32) -> Option<JsValue> {
if let Some(offset) = shape::lookup_offset(obj.shape_id(), prop_name_si) {
return Some(obj.get_prop(offset));
}
let mut proto = obj.proto();
while proto.is_object() {
let proto_obj = unsafe { &*proto.as_js_object_ptr() };
if let Some(offset) = shape::lookup_offset(proto_obj.shape_id(), prop_name_si) {
return Some(proto_obj.get_prop(offset));
}
proto = proto_obj.proto();
}
None
}
pub fn run(&mut self, module: &CompiledModule) -> Result<JsValue, String> {
self.string_table.clear();
self.string_reverse.clear();
@@ -265,14 +280,14 @@ impl Vm {
if cached_shape_id != 0 && cached_shape_id == obj.shape_id() {
self.regs[a] = obj.get_prop(cached_offset);
} else if let Some(val) = self.resolve_property(obj, prop_name_si) {
let offset =
shape::lookup_offset(obj.shape_id(), prop_name_si).unwrap_or(0);
let new_ext = (obj.shape_id() & 0x00FF_FFFF) | ((offset as u32) << 24);
self.bytecode[self.pc - 1] = new_ext;
self.regs[a] = val;
} else {
if let Some(offset) = shape::lookup_offset(obj.shape_id(), prop_name_si) {
let new_ext = (obj.shape_id() & 0x00FF_FFFF) | ((offset as u32) << 24);
self.bytecode[self.pc - 1] = new_ext;
self.regs[a] = obj.get_prop(offset);
} else {
self.regs[a] = JsValue::undefined();
}
self.regs[a] = JsValue::undefined();
}
}
@@ -316,13 +331,10 @@ impl Vm {
}
let obj = unsafe { &*obj_ptr };
let prop_name_si = self.regs[b].as_string_index();
if let Some(offset) = shape::lookup_offset(obj.shape_id(), prop_name_si) {
self.regs[a] = obj.get_prop(offset);
} else {
self.regs[a] = JsValue::undefined();
}
self.regs[a] = self
.resolve_property(obj, prop_name_si)
.unwrap_or(JsValue::undefined());
}
OpCode::SET_PROP => {
let obj_ptr = self.regs[rd].as_object_ptr() as *mut JsObject;
if obj_ptr.is_null() {
@@ -353,11 +365,9 @@ impl Vm {
return Err("GET_PROP_DYNAMIC key not a string".into());
}
let prop_name_si = key_val.as_string_index();
if let Some(offset) = shape::lookup_offset(obj.shape_id(), prop_name_si) {
self.regs[b] = obj.get_prop(offset);
} else {
self.regs[b] = JsValue::undefined();
}
self.regs[b] = self
.resolve_property(obj, prop_name_si)
.unwrap_or(JsValue::undefined());
}
OpCode::SET_PROP_DYNAMIC => {