feat: 补充 VM 对象相关字节码执行逻辑

This commit is contained in:
2026-06-05 17:59:13 +08:00
parent ed8513c284
commit c8f7b86b04
2 changed files with 34 additions and 2 deletions
+1 -2
View File
@@ -2,8 +2,6 @@ use crate::value::JsValue;
pub type ShapeId = u32; pub type ShapeId = u32;
pub const EMPTY_SHAPE_ID: ShapeId = 0;
/// Layout: /// Layout:
/// header: u32 bits /// header: u32 bits
/// [0:23] shape_id /// [0:23] shape_id
@@ -178,6 +176,7 @@ impl JsObject {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::shape::EMPTY_SHAPE_ID;
#[test] #[test]
fn object_size_64_bytes() { fn object_size_64_bytes() {
+33
View File
@@ -5,6 +5,9 @@ use oxide_compiler::module::CompiledModule;
use oxide_compiler::opcode::{self, OpCode}; use oxide_compiler::opcode::{self, OpCode};
use crate::coercion; use crate::coercion;
use crate::mem::Epoch;
use crate::object::JsObject;
use crate::shape::EMPTY_SHAPE_ID;
use crate::value::JsValue; use crate::value::JsValue;
pub struct CallFrame { pub struct CallFrame {
@@ -21,6 +24,7 @@ pub struct Vm {
frames: Vec<CallFrame>, frames: Vec<CallFrame>,
string_table: HashMap<String, u32>, string_table: HashMap<String, u32>,
string_reverse: Vec<String>, string_reverse: Vec<String>,
pub epoch: Epoch,
} }
impl Vm { impl Vm {
@@ -33,6 +37,7 @@ impl Vm {
frames: Vec::with_capacity(128), frames: Vec::with_capacity(128),
string_table: HashMap::with_capacity(64), string_table: HashMap::with_capacity(64),
string_reverse: Vec::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() { if !op.is_implemented() {
return Ok(JsValue::undefined()); return Ok(JsValue::undefined());