fix: 修复跨 VM 共享 Shape 指针问题

This commit is contained in:
2026-06-07 15:33:52 +08:00
parent f725d81b36
commit 3b3d9c224a
2 changed files with 68 additions and 50 deletions
+8 -8
View File
@@ -7,7 +7,7 @@ use crate::shape_forge::ShapeId;
#[derive(Debug, Clone)]
pub struct PropTemplate {
pub shape_id: ShapeId,
pub ptr_bits: u64,
pub position: u8,
pub generation: u32,
}
@@ -67,13 +67,13 @@ mod tests {
let forge = PropForge::new();
let t = PropTemplate {
shape_id: 1,
ptr_bits: 3,
position: 3,
generation: 10,
};
forge.upsert(1, t);
let got = forge.get_template(1).unwrap();
assert_eq!(got.shape_id, 1);
assert_eq!(got.ptr_bits, 3);
assert_eq!(got.position, 3);
assert_eq!(got.generation, 10);
}
@@ -84,7 +84,7 @@ mod tests {
1,
PropTemplate {
shape_id: 1,
ptr_bits: 3,
position: 3,
generation: 10,
},
);
@@ -92,7 +92,7 @@ mod tests {
1,
PropTemplate {
shape_id: 1,
ptr_bits: 7,
position: 7,
generation: 5,
},
);
@@ -107,7 +107,7 @@ mod tests {
1,
PropTemplate {
shape_id: 1,
ptr_bits: 3,
position: 3,
generation: 5,
},
);
@@ -115,12 +115,12 @@ mod tests {
1,
PropTemplate {
shape_id: 1,
ptr_bits: 7,
position: 7,
generation: 10,
},
);
let got = forge.get_template(1).unwrap();
assert_eq!(got.generation, 10);
assert_eq!(got.ptr_bits, 7);
assert_eq!(got.position, 7);
}
}
+60 -42
View File
@@ -571,6 +571,17 @@ impl Vm {
self.kernel.string_forge().lookup(val.as_string_index())
}
fn template_prop_ptr(&self, obj: &JsObject, template: &PropTemplate) -> Option<*const JsValue> {
let pos = template.position as usize;
obj.hash_props_vec().and_then(|vec| {
if pos < vec.len() {
Some(&*vec[pos] as *const JsValue)
} else {
None
}
})
}
fn resolve_property(&self, obj: &JsObject, prop_name_si: u32) -> Option<JsValue> {
if let Some(pos) = self
.kernel
@@ -634,7 +645,7 @@ impl Vm {
new_shape_id,
PropTemplate {
shape_id: new_shape_id,
ptr_bits: ptr as u64,
position: new_pos,
generation: obj.generation(),
},
);
@@ -954,12 +965,19 @@ impl Vm {
} else if let Some(template) =
self.kernel.prop_forge().get_template(obj.shape_id())
{
if template.ptr_bits != 0 {
let ptr = template.ptr_bits;
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
self.bytecode[self.pc - 2] = ptr as u32;
self.bytecode[self.pc - 1] = (ptr >> 32) as u32;
self.regs[a] = unsafe { *(ptr as *const JsValue) };
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)
@@ -1029,7 +1047,7 @@ impl Vm {
new_shape_id,
PropTemplate {
shape_id: new_shape_id,
ptr_bits: ptr as u64,
position: new_pos,
generation: obj.generation(),
},
);
@@ -1306,12 +1324,12 @@ impl Vm {
} else if let Some(template) =
self.kernel.prop_forge().get_template(obj.shape_id())
{
if template.ptr_bits != 0 {
let ptr = template.ptr_bits;
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 >> 32) as u32;
unsafe { *(ptr as *const JsValue) }
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
unsafe { *ptr }
} else {
self.resolve_property(obj, prop_name_si)
.unwrap_or(JsValue::undefined())
@@ -1367,7 +1385,7 @@ impl Vm {
new_shape_id,
PropTemplate {
shape_id: new_shape_id,
ptr_bits: ptr as u64,
position: new_pos,
generation: obj.generation(),
},
);
@@ -1400,12 +1418,12 @@ impl Vm {
} else if let Some(template) =
self.kernel.prop_forge().get_template(obj.shape_id())
{
if template.ptr_bits != 0 {
let ptr = template.ptr_bits;
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 >> 32) as u32;
unsafe { *(ptr as *const JsValue) }
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
unsafe { *ptr }
} else {
self.resolve_property(obj, prop_name_si)
.unwrap_or(JsValue::undefined())
@@ -1461,7 +1479,7 @@ impl Vm {
new_shape_id,
PropTemplate {
shape_id: new_shape_id,
ptr_bits: ptr as u64,
position: new_pos,
generation: obj.generation(),
},
);
@@ -1564,12 +1582,12 @@ impl Vm {
} else if let Some(template) =
self.kernel.prop_forge().get_template(obj.shape_id())
{
if template.ptr_bits != 0 {
let ptr = template.ptr_bits;
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 >> 32) as u32;
unsafe { *(ptr as *const JsValue) }
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
unsafe { *ptr }
} else {
self.resolve_property(obj, prop_name_si)
.unwrap_or(JsValue::undefined())
@@ -1628,12 +1646,12 @@ impl Vm {
} else if let Some(template) =
self.kernel.prop_forge().get_template(obj.shape_id())
{
if template.ptr_bits != 0 {
let ptr = template.ptr_bits;
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 >> 32) as u32;
unsafe { *(ptr as *const JsValue) }
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
unsafe { *ptr }
} else {
self.resolve_property(obj, prop_name_si)
.unwrap_or(JsValue::undefined())
@@ -1683,12 +1701,12 @@ impl Vm {
} else if let Some(template) =
self.kernel.prop_forge().get_template(obj.shape_id())
{
if template.ptr_bits != 0 {
let ptr = template.ptr_bits;
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 >> 32) as u32;
unsafe { *(ptr as *const JsValue) }
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
unsafe { *ptr }
} else {
self.resolve_property(obj, prop_name_si)
.unwrap_or(JsValue::undefined())
@@ -1738,12 +1756,12 @@ impl Vm {
} else if let Some(template) =
self.kernel.prop_forge().get_template(obj.shape_id())
{
if template.ptr_bits != 0 {
let ptr = template.ptr_bits;
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 >> 32) as u32;
unsafe { *(ptr as *const JsValue) }
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
unsafe { *ptr }
} else {
self.resolve_property(obj, prop_name_si)
.unwrap_or(JsValue::undefined())
@@ -1793,12 +1811,12 @@ impl Vm {
} else if let Some(template) =
self.kernel.prop_forge().get_template(obj.shape_id())
{
if template.ptr_bits != 0 {
let ptr = template.ptr_bits;
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 >> 32) as u32;
unsafe { *(ptr as *const JsValue) }
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
unsafe { *ptr }
} else {
self.resolve_property(obj, prop_name_si)
.unwrap_or(JsValue::undefined())
@@ -1848,12 +1866,12 @@ impl Vm {
} else if let Some(template) =
self.kernel.prop_forge().get_template(obj.shape_id())
{
if template.ptr_bits != 0 {
let ptr = template.ptr_bits;
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 >> 32) as u32;
unsafe { *(ptr as *const JsValue) }
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
unsafe { *ptr }
} else {
self.resolve_property(obj, prop_name_si)
.unwrap_or(JsValue::undefined())