mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
fix: 统一 IC 扩展字回写逻辑
This commit is contained in:
+35
-36
@@ -110,9 +110,7 @@ macro_rules! member_read_prop {
|
||||
.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;
|
||||
$self.write_ic_back($obj.shape_id(), ptr);
|
||||
unsafe { *ptr }
|
||||
} else {
|
||||
$self
|
||||
@@ -126,9 +124,7 @@ macro_rules! member_read_prop {
|
||||
.lookup_position($obj.shape_id(), $prop_name_si)
|
||||
{
|
||||
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.write_ic_back($obj.shape_id(), ptr);
|
||||
}
|
||||
}
|
||||
val
|
||||
@@ -515,9 +511,7 @@ impl Vm {
|
||||
obj.set_prop_at(pos, val);
|
||||
// IC write-back: 3 extension words (shape_id + ptr_lo + ptr_hi)
|
||||
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.write_ic_back(obj.shape_id(), ptr);
|
||||
}
|
||||
} else {
|
||||
let new_shape_id = self
|
||||
@@ -528,9 +522,7 @@ impl Vm {
|
||||
let new_pos = obj.push_prop(val);
|
||||
obj.bump_generation();
|
||||
if let Some(ptr) = obj.prop_ptr_at(new_pos) {
|
||||
self.bytecode[self.pc - 3] = new_shape_id & 0x00FF_FFFF;
|
||||
self.bytecode[self.pc - 2] = ptr as u32;
|
||||
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
|
||||
self.write_ic_back(new_shape_id, ptr);
|
||||
self.kernel.prop_forge().upsert(
|
||||
new_shape_id,
|
||||
PropTemplate {
|
||||
@@ -545,6 +537,16 @@ impl Vm {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_ic_back(&mut self, shape_id: u32, ptr: *const JsValue) {
|
||||
debug_assert!(
|
||||
self.pc >= 3,
|
||||
"IC write-back requires 3 extension words before pc"
|
||||
);
|
||||
self.bytecode[self.pc - 3] = shape_id & 0x00FF_FFFF;
|
||||
self.bytecode[self.pc - 2] = ptr as u32;
|
||||
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
|
||||
}
|
||||
|
||||
pub fn rerun(&mut self) -> Result<JsValue, String> {
|
||||
self.clear_execution_state();
|
||||
self.active_reg_limit = self.root_reg_limit;
|
||||
@@ -1081,9 +1083,7 @@ impl Vm {
|
||||
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.write_ic_back(obj.shape_id(), ptr);
|
||||
self.regs[a] = unsafe { *(ptr) };
|
||||
} else {
|
||||
self.regs[a] = self
|
||||
@@ -1107,9 +1107,7 @@ impl Vm {
|
||||
.lookup_position(obj.shape_id(), prop_name_si)
|
||||
{
|
||||
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.write_ic_back(obj.shape_id(), ptr);
|
||||
}
|
||||
}
|
||||
self.regs[a] = val;
|
||||
@@ -1145,9 +1143,7 @@ impl Vm {
|
||||
{
|
||||
obj.set_prop_at(pos, self.regs[a]);
|
||||
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.write_ic_back(obj.shape_id(), ptr);
|
||||
}
|
||||
} else {
|
||||
let new_shape_id = self
|
||||
@@ -1158,9 +1154,7 @@ impl Vm {
|
||||
let new_pos = obj.push_prop(self.regs[a]);
|
||||
obj.bump_generation();
|
||||
if let Some(ptr) = obj.prop_ptr_at(new_pos) {
|
||||
self.bytecode[self.pc - 3] = new_shape_id & 0x00FF_FFFF;
|
||||
self.bytecode[self.pc - 2] = ptr as u32;
|
||||
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
|
||||
self.write_ic_back(new_shape_id, ptr);
|
||||
self.kernel.prop_forge().upsert(
|
||||
new_shape_id,
|
||||
PropTemplate {
|
||||
@@ -1495,9 +1489,7 @@ impl Vm {
|
||||
{
|
||||
obj.set_prop_at(pos, new_val);
|
||||
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.write_ic_back(obj.shape_id(), ptr);
|
||||
}
|
||||
} else {
|
||||
let new_shape_id = self
|
||||
@@ -1508,9 +1500,7 @@ impl Vm {
|
||||
let new_pos = obj.push_prop(new_val);
|
||||
obj.bump_generation();
|
||||
if let Some(ptr) = obj.prop_ptr_at(new_pos) {
|
||||
self.bytecode[self.pc - 3] = new_shape_id & 0x00FF_FFFF;
|
||||
self.bytecode[self.pc - 2] = ptr as u32;
|
||||
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
|
||||
self.write_ic_back(new_shape_id, ptr);
|
||||
self.kernel.prop_forge().upsert(
|
||||
new_shape_id,
|
||||
PropTemplate {
|
||||
@@ -1546,9 +1536,7 @@ impl Vm {
|
||||
{
|
||||
obj.set_prop_at(pos, new_val);
|
||||
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.write_ic_back(obj.shape_id(), ptr);
|
||||
}
|
||||
} else {
|
||||
let new_shape_id = self
|
||||
@@ -1559,9 +1547,7 @@ impl Vm {
|
||||
let new_pos = obj.push_prop(new_val);
|
||||
obj.bump_generation();
|
||||
if let Some(ptr) = obj.prop_ptr_at(new_pos) {
|
||||
self.bytecode[self.pc - 3] = new_shape_id & 0x00FF_FFFF;
|
||||
self.bytecode[self.pc - 2] = ptr as u32;
|
||||
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
|
||||
self.write_ic_back(new_shape_id, ptr);
|
||||
self.kernel.prop_forge().upsert(
|
||||
new_shape_id,
|
||||
PropTemplate {
|
||||
@@ -2016,4 +2002,17 @@ mod tests {
|
||||
"unexpected error: {err}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_ic_back_updates_three_extension_words() {
|
||||
let mut vm = Vm::new();
|
||||
vm.bytecode = vec![0, 0, 0];
|
||||
vm.pc = 3;
|
||||
let boxed = Box::new(JsValue::int(42));
|
||||
let ptr = &*boxed as *const JsValue;
|
||||
vm.write_ic_back(0x1234_5678, ptr);
|
||||
assert_eq!(vm.bytecode[0], 0x0034_5678);
|
||||
assert_eq!(vm.bytecode[1], ptr as u32);
|
||||
assert_eq!(vm.bytecode[2], (ptr as u64 >> 32) as u32);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user