mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-24 18:51:13 +08:00
feat: 支持对象进行完整 ES 属性解析
This commit is contained in:
+28
-18
@@ -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 => {
|
||||
|
||||
Reference in New Issue
Block a user