fix: 修复数组长度与槽位索引截断问题

This commit is contained in:
爱特每羊队
2026-06-08 22:55:52 +08:00
parent 22cbccdf6c
commit e57e140bef
16 changed files with 242 additions and 159 deletions
+43 -23
View File
@@ -105,7 +105,11 @@ macro_rules! member_read_prop {
if cached_shape_id != 0 && cached_shape_id == $obj.shape_id() && cached_ptr != 0 {
unsafe { *(cached_ptr as *const JsValue) }
} else if let Some(template) = $self.kernel.prop_forge().get_template($obj.shape_id()) {
if let Some(ptr) = $self.template_prop_ptr($obj, &template) {
if template.prop_name != $prop_name_si {
$self
.resolve_property($obj, $prop_name_si)
.unwrap_or(JsValue::undefined())
} else if let Some(ptr) = $self.template_prop_ptr($obj, &template) {
$self.bytecode[$self.pc - 3] = $obj.shape_id() & 0x00FF_FFFF;
$self.bytecode[$self.pc - 2] = ptr as u32;
$self.bytecode[$self.pc - 1] = (ptr as u64 >> 32) as u32;
@@ -116,15 +120,16 @@ macro_rules! member_read_prop {
.unwrap_or(JsValue::undefined())
}
} else if let Some(val) = $self.resolve_property($obj, $prop_name_si) {
let pos = $self
if let Some(pos) = $self
.kernel
.shape_forge()
.lookup_position($obj.shape_id(), $prop_name_si)
.unwrap_or(0);
if let Some(ptr) = $obj.prop_ptr_at(pos) {
$self.bytecode[$self.pc - 3] = $obj.shape_id() & 0x00FF_FFFF;
$self.bytecode[$self.pc - 2] = ptr as u32;
$self.bytecode[$self.pc - 1] = (ptr as u64 >> 32) as u32;
{
if let Some(ptr) = $obj.prop_ptr_at(pos) {
$self.bytecode[$self.pc - 3] = $obj.shape_id() & 0x00FF_FFFF;
$self.bytecode[$self.pc - 2] = ptr as u32;
$self.bytecode[$self.pc - 1] = (ptr as u64 >> 32) as u32;
}
}
val
} else {
@@ -397,6 +402,10 @@ impl Vm {
}
fn resolve_property(&self, obj: &JsObject, prop_name_si: u32) -> Option<JsValue> {
let length_si = self.kernel.string_forge().intern("length").0;
if obj.is_array() && prop_name_si == length_si {
return Some(JsValue::int(obj.prop_count() as i32));
}
if let Some(pos) = self
.kernel
.shape_forge()
@@ -459,6 +468,7 @@ impl Vm {
new_shape_id,
PropTemplate {
shape_id: new_shape_id,
prop_name: prop_name_si,
position: new_pos,
generation: obj.generation(),
},
@@ -1023,14 +1033,20 @@ impl Vm {
} else if let Some(template) =
self.kernel.prop_forge().get_template(obj.shape_id())
{
let pos = template.position as usize;
if let Some(vec) = obj.hash_props_vec() {
if pos < vec.len() {
let ptr = &*vec[pos] as *const JsValue;
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
self.bytecode[self.pc - 2] = ptr as u32;
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
self.regs[a] = unsafe { *(ptr) };
if template.prop_name == prop_name_si {
let pos = template.position as usize;
if let Some(vec) = obj.hash_props_vec() {
if pos < vec.len() {
let ptr = &*vec[pos] as *const JsValue;
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
self.bytecode[self.pc - 2] = ptr as u32;
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
self.regs[a] = unsafe { *(ptr) };
} else {
self.regs[a] = self
.resolve_property(obj, prop_name_si)
.unwrap_or(JsValue::undefined());
}
} else {
self.regs[a] = self
.resolve_property(obj, prop_name_si)
@@ -1042,15 +1058,16 @@ impl Vm {
.unwrap_or(JsValue::undefined());
}
} else if let Some(val) = self.resolve_property(obj, prop_name_si) {
let pos = self
if let Some(pos) = self
.kernel
.shape_forge()
.lookup_position(obj.shape_id(), prop_name_si)
.unwrap_or(0);
if let Some(ptr) = obj.prop_ptr_at(pos) {
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
self.bytecode[self.pc - 2] = ptr as u32;
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
{
if let Some(ptr) = obj.prop_ptr_at(pos) {
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
self.bytecode[self.pc - 2] = ptr as u32;
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
}
}
self.regs[a] = val;
} else {
@@ -1105,6 +1122,7 @@ impl Vm {
new_shape_id,
PropTemplate {
shape_id: new_shape_id,
prop_name: prop_name_si,
position: new_pos,
generation: obj.generation(),
},
@@ -1221,9 +1239,9 @@ impl Vm {
if obj_ptr.is_null() {
throw_err!(self, TypeError, "SET_ELEM on non-object");
}
let idx = self.regs[a].as_int() as usize;
let idx = self.regs[a].as_int().max(0) as u32;
let obj = unsafe { &mut *obj_ptr };
obj.set_prop_at(idx as u8, self.regs[b]);
obj.set_prop_at(idx, self.regs[b]);
}
OpCode::COMPOUND_ADD => {
@@ -1507,6 +1525,7 @@ impl Vm {
new_shape_id,
PropTemplate {
shape_id: new_shape_id,
prop_name: prop_name_si,
position: new_pos,
generation: obj.generation(),
},
@@ -1557,6 +1576,7 @@ impl Vm {
new_shape_id,
PropTemplate {
shape_id: new_shape_id,
prop_name: prop_name_si,
position: new_pos,
generation: obj.generation(),
},