feat: 支持编译对象构造并统一属性字段名获取

This commit is contained in:
爱特每羊队
2026-06-05 18:23:16 +08:00
parent 28ccfae557
commit 660e522de9
2 changed files with 47 additions and 22 deletions
+27
View File
@@ -347,6 +347,33 @@ impl Compiler {
));
Ok(r)
}
Expression::ObjectExpression(obj) => {
let obj_reg = ctx.alloc_reg();
ctx.emit(opcode::encode(OpCode::NEW_OBJECT, obj_reg, 0, 0));
for prop in &obj.properties {
let oxide_parser::ObjectPropertyKind::ObjectProperty(p) = prop else {
return Err("spread properties not yet supported".into());
};
let prop_name = match &p.key {
oxide_parser::PropertyKey::StaticIdentifier(ident) => {
ident.name.as_str().to_string()
}
oxide_parser::PropertyKey::StringLiteral(s) => s.value.to_string(),
_ => return Err("unsupported object property key type".into()),
};
let idx = ctx.add_constant(Constant::String(prop_name.to_string()));
let key_reg = ctx.alloc_reg();
ctx.emit(opcode::encode(
OpCode::LOAD_CONST,
key_reg,
(idx & 0xFF) as u8,
((idx >> 8) & 0xFF) as u8,
));
let val_reg = self.emit_expression(&p.value, ctx)?;
ctx.emit(opcode::encode(OpCode::SET_PROP, obj_reg, val_reg, key_reg));
}
Ok(obj_reg)
}
_ => Err(format!(
"unsupported expression type: {:?}",
std::mem::discriminant(expr)
+20 -22
View File
@@ -313,8 +313,7 @@ impl Vm {
return Err("GET_PROP on non-object".into());
}
let obj = unsafe { &*obj_ptr };
let prop_val = self.constants[opcode::imm16(instr) as usize];
let prop_name_si = prop_val.as_string_index();
let prop_name_si = self.regs[b].as_string_index();
if let Some(offset) = shape::lookup_offset(obj.shape_id(), prop_name_si) {
self.regs[a] = obj.get_prop(offset);
} else {
@@ -322,6 +321,25 @@ impl Vm {
}
}
OpCode::SET_PROP => {
let obj_ptr = self.regs[rd].as_object_ptr() as *mut JsObject;
if obj_ptr.is_null() {
return Err("SET_PROP on non-object".into());
}
let obj = unsafe { &mut *obj_ptr };
let prop_name_si = self.regs[b].as_string_index();
if let Some(offset) = shape::lookup_offset(obj.shape_id(), prop_name_si) {
obj.set_prop(offset, self.regs[a]);
} else {
let new_offset = obj.prop_count();
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.bump_generation();
}
}
OpCode::GET_PROP_DYNAMIC => {
let obj_ptr = self.regs[rd].as_object_ptr() as *mut JsObject;
if obj_ptr.is_null() {
@@ -340,26 +358,6 @@ impl Vm {
}
}
OpCode::SET_PROP => {
let obj_ptr = self.regs[rd].as_object_ptr() as *mut JsObject;
if obj_ptr.is_null() {
return Err("SET_PROP on non-object".into());
}
let obj = unsafe { &mut *obj_ptr };
let prop_val = self.constants[opcode::imm16(instr) as usize];
let prop_name_si = prop_val.as_string_index();
if let Some(offset) = shape::lookup_offset(obj.shape_id(), prop_name_si) {
obj.set_prop(offset, self.regs[a]);
} else {
let new_offset = obj.prop_count();
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.bump_generation();
}
}
OpCode::SET_PROP_DYNAMIC => {
let obj_ptr = self.regs[rd].as_object_ptr() as *mut JsObject;
if obj_ptr.is_null() {