diff --git a/crates/oxide_vm/src/mem.rs b/crates/oxide_vm/src/mem.rs index 9d97a003..7b6333a6 100644 --- a/crates/oxide_vm/src/mem.rs +++ b/crates/oxide_vm/src/mem.rs @@ -90,6 +90,10 @@ impl Epoch { self.bump.alloc(value) } + pub fn bump(&self) -> &bumpalo::Bump { + &self.bump + } + /// Bump-allocate a value using a closure for initialization. /// Better for compiler optimization — construct directly on arena. pub fn alloc_with(&self, f: F) -> *mut T diff --git a/crates/oxide_vm/src/object.rs b/crates/oxide_vm/src/object.rs index 53b33274..cf4b8a6f 100644 --- a/crates/oxide_vm/src/object.rs +++ b/crates/oxide_vm/src/object.rs @@ -138,6 +138,13 @@ impl JsObject { } } + pub fn set_prop_expand(&mut self, offset: u8, val: JsValue, bump: &bumpalo::Bump) { + if offset >= 4 && (self.overflow.is_null() || offset >= self.prop_count()) { + self.alloc_overflow(bump, (offset as usize) + 1); + } + self.set_prop(offset, val); + } + pub fn proto(&self) -> JsValue { self.proto } diff --git a/crates/oxide_vm/src/vm.rs b/crates/oxide_vm/src/vm.rs index f1a91d3e..b3bfba57 100644 --- a/crates/oxide_vm/src/vm.rs +++ b/crates/oxide_vm/src/vm.rs @@ -76,6 +76,13 @@ impl Vm { None } + pub fn rerun(&mut self) -> Result { + self.pc = 0; + self.regs = [JsValue::undefined(); 256]; + self.frames.clear(); + self.dispatch() + } + pub fn run(&mut self, module: &CompiledModule) -> Result { self.string_table.clear(); self.string_reverse.clear(); @@ -349,7 +356,7 @@ impl Vm { let new_shape_id = shape::make_shape(obj.shape_id(), prop_name_si); obj.set_shape_id(new_shape_id); obj.set_prop_count(new_offset + 1); - obj.set_prop(new_offset, self.regs[a]); + obj.set_prop_expand(new_offset, self.regs[a], &self.epoch.bump()); obj.bump_generation(); } } @@ -388,7 +395,7 @@ impl Vm { let new_shape_id = shape::make_shape(obj.shape_id(), prop_name_si); obj.set_shape_id(new_shape_id); obj.set_prop_count(new_offset + 1); - obj.set_prop(new_offset, self.regs[b]); + obj.set_prop_expand(new_offset, self.regs[b], &self.epoch.bump()); obj.bump_generation(); } }