mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 19:21:11 +08:00
fix: 修复跨 VM 共享 Shape 指针问题
This commit is contained in:
@@ -7,7 +7,7 @@ use crate::shape_forge::ShapeId;
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct PropTemplate {
|
pub struct PropTemplate {
|
||||||
pub shape_id: ShapeId,
|
pub shape_id: ShapeId,
|
||||||
pub ptr_bits: u64,
|
pub position: u8,
|
||||||
pub generation: u32,
|
pub generation: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,13 +67,13 @@ mod tests {
|
|||||||
let forge = PropForge::new();
|
let forge = PropForge::new();
|
||||||
let t = PropTemplate {
|
let t = PropTemplate {
|
||||||
shape_id: 1,
|
shape_id: 1,
|
||||||
ptr_bits: 3,
|
position: 3,
|
||||||
generation: 10,
|
generation: 10,
|
||||||
};
|
};
|
||||||
forge.upsert(1, t);
|
forge.upsert(1, t);
|
||||||
let got = forge.get_template(1).unwrap();
|
let got = forge.get_template(1).unwrap();
|
||||||
assert_eq!(got.shape_id, 1);
|
assert_eq!(got.shape_id, 1);
|
||||||
assert_eq!(got.ptr_bits, 3);
|
assert_eq!(got.position, 3);
|
||||||
assert_eq!(got.generation, 10);
|
assert_eq!(got.generation, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ mod tests {
|
|||||||
1,
|
1,
|
||||||
PropTemplate {
|
PropTemplate {
|
||||||
shape_id: 1,
|
shape_id: 1,
|
||||||
ptr_bits: 3,
|
position: 3,
|
||||||
generation: 10,
|
generation: 10,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -92,7 +92,7 @@ mod tests {
|
|||||||
1,
|
1,
|
||||||
PropTemplate {
|
PropTemplate {
|
||||||
shape_id: 1,
|
shape_id: 1,
|
||||||
ptr_bits: 7,
|
position: 7,
|
||||||
generation: 5,
|
generation: 5,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -107,7 +107,7 @@ mod tests {
|
|||||||
1,
|
1,
|
||||||
PropTemplate {
|
PropTemplate {
|
||||||
shape_id: 1,
|
shape_id: 1,
|
||||||
ptr_bits: 3,
|
position: 3,
|
||||||
generation: 5,
|
generation: 5,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -115,12 +115,12 @@ mod tests {
|
|||||||
1,
|
1,
|
||||||
PropTemplate {
|
PropTemplate {
|
||||||
shape_id: 1,
|
shape_id: 1,
|
||||||
ptr_bits: 7,
|
position: 7,
|
||||||
generation: 10,
|
generation: 10,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let got = forge.get_template(1).unwrap();
|
let got = forge.get_template(1).unwrap();
|
||||||
assert_eq!(got.generation, 10);
|
assert_eq!(got.generation, 10);
|
||||||
assert_eq!(got.ptr_bits, 7);
|
assert_eq!(got.position, 7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+60
-42
@@ -571,6 +571,17 @@ impl Vm {
|
|||||||
self.kernel.string_forge().lookup(val.as_string_index())
|
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> {
|
fn resolve_property(&self, obj: &JsObject, prop_name_si: u32) -> Option<JsValue> {
|
||||||
if let Some(pos) = self
|
if let Some(pos) = self
|
||||||
.kernel
|
.kernel
|
||||||
@@ -634,7 +645,7 @@ impl Vm {
|
|||||||
new_shape_id,
|
new_shape_id,
|
||||||
PropTemplate {
|
PropTemplate {
|
||||||
shape_id: new_shape_id,
|
shape_id: new_shape_id,
|
||||||
ptr_bits: ptr as u64,
|
position: new_pos,
|
||||||
generation: obj.generation(),
|
generation: obj.generation(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -954,12 +965,19 @@ impl Vm {
|
|||||||
} else if let Some(template) =
|
} else if let Some(template) =
|
||||||
self.kernel.prop_forge().get_template(obj.shape_id())
|
self.kernel.prop_forge().get_template(obj.shape_id())
|
||||||
{
|
{
|
||||||
if template.ptr_bits != 0 {
|
let pos = template.position as usize;
|
||||||
let ptr = template.ptr_bits;
|
if let Some(vec) = obj.hash_props_vec() {
|
||||||
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
|
if pos < vec.len() {
|
||||||
self.bytecode[self.pc - 2] = ptr as u32;
|
let ptr = &*vec[pos] as *const JsValue;
|
||||||
self.bytecode[self.pc - 1] = (ptr >> 32) as u32;
|
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
|
||||||
self.regs[a] = unsafe { *(ptr as *const JsValue) };
|
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 {
|
} else {
|
||||||
self.regs[a] = self
|
self.regs[a] = self
|
||||||
.resolve_property(obj, prop_name_si)
|
.resolve_property(obj, prop_name_si)
|
||||||
@@ -1029,7 +1047,7 @@ impl Vm {
|
|||||||
new_shape_id,
|
new_shape_id,
|
||||||
PropTemplate {
|
PropTemplate {
|
||||||
shape_id: new_shape_id,
|
shape_id: new_shape_id,
|
||||||
ptr_bits: ptr as u64,
|
position: new_pos,
|
||||||
generation: obj.generation(),
|
generation: obj.generation(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -1306,12 +1324,12 @@ impl Vm {
|
|||||||
} else if let Some(template) =
|
} else if let Some(template) =
|
||||||
self.kernel.prop_forge().get_template(obj.shape_id())
|
self.kernel.prop_forge().get_template(obj.shape_id())
|
||||||
{
|
{
|
||||||
if template.ptr_bits != 0 {
|
if let Some(ptr) = self.template_prop_ptr(obj, &template) {
|
||||||
let ptr = template.ptr_bits;
|
|
||||||
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
|
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
|
||||||
self.bytecode[self.pc - 2] = ptr as u32;
|
self.bytecode[self.pc - 2] = ptr as u32;
|
||||||
self.bytecode[self.pc - 1] = (ptr >> 32) as u32;
|
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
|
||||||
unsafe { *(ptr as *const JsValue) }
|
unsafe { *ptr }
|
||||||
} else {
|
} else {
|
||||||
self.resolve_property(obj, prop_name_si)
|
self.resolve_property(obj, prop_name_si)
|
||||||
.unwrap_or(JsValue::undefined())
|
.unwrap_or(JsValue::undefined())
|
||||||
@@ -1367,7 +1385,7 @@ impl Vm {
|
|||||||
new_shape_id,
|
new_shape_id,
|
||||||
PropTemplate {
|
PropTemplate {
|
||||||
shape_id: new_shape_id,
|
shape_id: new_shape_id,
|
||||||
ptr_bits: ptr as u64,
|
position: new_pos,
|
||||||
generation: obj.generation(),
|
generation: obj.generation(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -1400,12 +1418,12 @@ impl Vm {
|
|||||||
} else if let Some(template) =
|
} else if let Some(template) =
|
||||||
self.kernel.prop_forge().get_template(obj.shape_id())
|
self.kernel.prop_forge().get_template(obj.shape_id())
|
||||||
{
|
{
|
||||||
if template.ptr_bits != 0 {
|
if let Some(ptr) = self.template_prop_ptr(obj, &template) {
|
||||||
let ptr = template.ptr_bits;
|
|
||||||
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
|
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
|
||||||
self.bytecode[self.pc - 2] = ptr as u32;
|
self.bytecode[self.pc - 2] = ptr as u32;
|
||||||
self.bytecode[self.pc - 1] = (ptr >> 32) as u32;
|
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
|
||||||
unsafe { *(ptr as *const JsValue) }
|
unsafe { *ptr }
|
||||||
} else {
|
} else {
|
||||||
self.resolve_property(obj, prop_name_si)
|
self.resolve_property(obj, prop_name_si)
|
||||||
.unwrap_or(JsValue::undefined())
|
.unwrap_or(JsValue::undefined())
|
||||||
@@ -1461,7 +1479,7 @@ impl Vm {
|
|||||||
new_shape_id,
|
new_shape_id,
|
||||||
PropTemplate {
|
PropTemplate {
|
||||||
shape_id: new_shape_id,
|
shape_id: new_shape_id,
|
||||||
ptr_bits: ptr as u64,
|
position: new_pos,
|
||||||
generation: obj.generation(),
|
generation: obj.generation(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -1564,12 +1582,12 @@ impl Vm {
|
|||||||
} else if let Some(template) =
|
} else if let Some(template) =
|
||||||
self.kernel.prop_forge().get_template(obj.shape_id())
|
self.kernel.prop_forge().get_template(obj.shape_id())
|
||||||
{
|
{
|
||||||
if template.ptr_bits != 0 {
|
if let Some(ptr) = self.template_prop_ptr(obj, &template) {
|
||||||
let ptr = template.ptr_bits;
|
|
||||||
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
|
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
|
||||||
self.bytecode[self.pc - 2] = ptr as u32;
|
self.bytecode[self.pc - 2] = ptr as u32;
|
||||||
self.bytecode[self.pc - 1] = (ptr >> 32) as u32;
|
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
|
||||||
unsafe { *(ptr as *const JsValue) }
|
unsafe { *ptr }
|
||||||
} else {
|
} else {
|
||||||
self.resolve_property(obj, prop_name_si)
|
self.resolve_property(obj, prop_name_si)
|
||||||
.unwrap_or(JsValue::undefined())
|
.unwrap_or(JsValue::undefined())
|
||||||
@@ -1628,12 +1646,12 @@ impl Vm {
|
|||||||
} else if let Some(template) =
|
} else if let Some(template) =
|
||||||
self.kernel.prop_forge().get_template(obj.shape_id())
|
self.kernel.prop_forge().get_template(obj.shape_id())
|
||||||
{
|
{
|
||||||
if template.ptr_bits != 0 {
|
if let Some(ptr) = self.template_prop_ptr(obj, &template) {
|
||||||
let ptr = template.ptr_bits;
|
|
||||||
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
|
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
|
||||||
self.bytecode[self.pc - 2] = ptr as u32;
|
self.bytecode[self.pc - 2] = ptr as u32;
|
||||||
self.bytecode[self.pc - 1] = (ptr >> 32) as u32;
|
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
|
||||||
unsafe { *(ptr as *const JsValue) }
|
unsafe { *ptr }
|
||||||
} else {
|
} else {
|
||||||
self.resolve_property(obj, prop_name_si)
|
self.resolve_property(obj, prop_name_si)
|
||||||
.unwrap_or(JsValue::undefined())
|
.unwrap_or(JsValue::undefined())
|
||||||
@@ -1683,12 +1701,12 @@ impl Vm {
|
|||||||
} else if let Some(template) =
|
} else if let Some(template) =
|
||||||
self.kernel.prop_forge().get_template(obj.shape_id())
|
self.kernel.prop_forge().get_template(obj.shape_id())
|
||||||
{
|
{
|
||||||
if template.ptr_bits != 0 {
|
if let Some(ptr) = self.template_prop_ptr(obj, &template) {
|
||||||
let ptr = template.ptr_bits;
|
|
||||||
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
|
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
|
||||||
self.bytecode[self.pc - 2] = ptr as u32;
|
self.bytecode[self.pc - 2] = ptr as u32;
|
||||||
self.bytecode[self.pc - 1] = (ptr >> 32) as u32;
|
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
|
||||||
unsafe { *(ptr as *const JsValue) }
|
unsafe { *ptr }
|
||||||
} else {
|
} else {
|
||||||
self.resolve_property(obj, prop_name_si)
|
self.resolve_property(obj, prop_name_si)
|
||||||
.unwrap_or(JsValue::undefined())
|
.unwrap_or(JsValue::undefined())
|
||||||
@@ -1738,12 +1756,12 @@ impl Vm {
|
|||||||
} else if let Some(template) =
|
} else if let Some(template) =
|
||||||
self.kernel.prop_forge().get_template(obj.shape_id())
|
self.kernel.prop_forge().get_template(obj.shape_id())
|
||||||
{
|
{
|
||||||
if template.ptr_bits != 0 {
|
if let Some(ptr) = self.template_prop_ptr(obj, &template) {
|
||||||
let ptr = template.ptr_bits;
|
|
||||||
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
|
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
|
||||||
self.bytecode[self.pc - 2] = ptr as u32;
|
self.bytecode[self.pc - 2] = ptr as u32;
|
||||||
self.bytecode[self.pc - 1] = (ptr >> 32) as u32;
|
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
|
||||||
unsafe { *(ptr as *const JsValue) }
|
unsafe { *ptr }
|
||||||
} else {
|
} else {
|
||||||
self.resolve_property(obj, prop_name_si)
|
self.resolve_property(obj, prop_name_si)
|
||||||
.unwrap_or(JsValue::undefined())
|
.unwrap_or(JsValue::undefined())
|
||||||
@@ -1793,12 +1811,12 @@ impl Vm {
|
|||||||
} else if let Some(template) =
|
} else if let Some(template) =
|
||||||
self.kernel.prop_forge().get_template(obj.shape_id())
|
self.kernel.prop_forge().get_template(obj.shape_id())
|
||||||
{
|
{
|
||||||
if template.ptr_bits != 0 {
|
if let Some(ptr) = self.template_prop_ptr(obj, &template) {
|
||||||
let ptr = template.ptr_bits;
|
|
||||||
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
|
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
|
||||||
self.bytecode[self.pc - 2] = ptr as u32;
|
self.bytecode[self.pc - 2] = ptr as u32;
|
||||||
self.bytecode[self.pc - 1] = (ptr >> 32) as u32;
|
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
|
||||||
unsafe { *(ptr as *const JsValue) }
|
unsafe { *ptr }
|
||||||
} else {
|
} else {
|
||||||
self.resolve_property(obj, prop_name_si)
|
self.resolve_property(obj, prop_name_si)
|
||||||
.unwrap_or(JsValue::undefined())
|
.unwrap_or(JsValue::undefined())
|
||||||
@@ -1848,12 +1866,12 @@ impl Vm {
|
|||||||
} else if let Some(template) =
|
} else if let Some(template) =
|
||||||
self.kernel.prop_forge().get_template(obj.shape_id())
|
self.kernel.prop_forge().get_template(obj.shape_id())
|
||||||
{
|
{
|
||||||
if template.ptr_bits != 0 {
|
if let Some(ptr) = self.template_prop_ptr(obj, &template) {
|
||||||
let ptr = template.ptr_bits;
|
|
||||||
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
|
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
|
||||||
self.bytecode[self.pc - 2] = ptr as u32;
|
self.bytecode[self.pc - 2] = ptr as u32;
|
||||||
self.bytecode[self.pc - 1] = (ptr >> 32) as u32;
|
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
|
||||||
unsafe { *(ptr as *const JsValue) }
|
unsafe { *ptr }
|
||||||
} else {
|
} else {
|
||||||
self.resolve_property(obj, prop_name_si)
|
self.resolve_property(obj, prop_name_si)
|
||||||
.unwrap_or(JsValue::undefined())
|
.unwrap_or(JsValue::undefined())
|
||||||
|
|||||||
Reference in New Issue
Block a user