From c8f7b86b04a4661f7791fa139e0a8855786eb151 Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Fri, 5 Jun 2026 17:59:13 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=A1=A5=E5=85=85=20VM=20=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1=E7=9B=B8=E5=85=B3=E5=AD=97=E8=8A=82=E7=A0=81=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_vm/src/object.rs | 3 +-- crates/oxide_vm/src/vm.rs | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/crates/oxide_vm/src/object.rs b/crates/oxide_vm/src/object.rs index 365992bd..0a6762dd 100644 --- a/crates/oxide_vm/src/object.rs +++ b/crates/oxide_vm/src/object.rs @@ -2,8 +2,6 @@ use crate::value::JsValue; pub type ShapeId = u32; -pub const EMPTY_SHAPE_ID: ShapeId = 0; - /// Layout: /// header: u32 bits /// [0:23] shape_id @@ -178,6 +176,7 @@ impl JsObject { #[cfg(test)] mod tests { use super::*; + use crate::shape::EMPTY_SHAPE_ID; #[test] fn object_size_64_bytes() { diff --git a/crates/oxide_vm/src/vm.rs b/crates/oxide_vm/src/vm.rs index a37dc795..32ec8698 100644 --- a/crates/oxide_vm/src/vm.rs +++ b/crates/oxide_vm/src/vm.rs @@ -5,6 +5,9 @@ use oxide_compiler::module::CompiledModule; use oxide_compiler::opcode::{self, OpCode}; use crate::coercion; +use crate::mem::Epoch; +use crate::object::JsObject; +use crate::shape::EMPTY_SHAPE_ID; use crate::value::JsValue; pub struct CallFrame { @@ -21,6 +24,7 @@ pub struct Vm { frames: Vec, string_table: HashMap, string_reverse: Vec, + pub epoch: Epoch, } impl Vm { @@ -33,6 +37,7 @@ impl Vm { frames: Vec::with_capacity(128), string_table: HashMap::with_capacity(64), string_reverse: Vec::with_capacity(64), + epoch: Epoch::new(), } } @@ -244,6 +249,34 @@ impl Vm { } } + OpCode::NEW_OBJECT => { + let obj = self + .epoch + .alloc(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + self.regs[rd] = JsValue::object(obj as *mut u8); + } + + OpCode::NEW_ARRAY => { + let n = opcode::imm16(instr) as usize; + let obj = + self.epoch + .alloc(JsObject::new_array(EMPTY_SHAPE_ID, JsValue::null(), n)); + self.regs[rd] = JsValue::object(obj as *mut u8); + } + + OpCode::SET_ELEM => { + let obj_ptr = self.regs[rd].as_object_ptr() as *mut JsObject; + if obj_ptr.is_null() { + return Err("SET_ELEM on non-object".into()); + } + let idx = self.regs[a].as_int() as usize; + let obj = unsafe { &mut *obj_ptr }; + obj.set_prop(idx as u8, self.regs[b]); + if idx as u8 >= obj.prop_count() { + obj.set_prop_count(idx as u8 + 1); + } + } + _ => { if !op.is_implemented() { return Ok(JsValue::undefined());