feat(iter): 迭代协议支持对象字面量 computed key 与 upvalue 捕获
This commit is contained in:
@@ -5,7 +5,7 @@ use oxide_bytecode::module::Constant;
|
||||
use oxide_bytecode::opcode::OpCode;
|
||||
use oxide_ir::inst::Inst;
|
||||
use oxide_ir::operand::Operand;
|
||||
use oxide_parser::{Expression, ObjectPropertyKind, PropertyKey, PropertyKind};
|
||||
use oxide_parser::{Expression, ObjectPropertyKind, PropertyKind};
|
||||
|
||||
impl Emitter {
|
||||
pub(crate) fn emit_object_expression(
|
||||
@@ -17,13 +17,17 @@ impl Emitter {
|
||||
let ObjectPropertyKind::ObjectProperty(p) = prop else {
|
||||
return Err("spread properties not yet supported".into());
|
||||
};
|
||||
let prop_name = match &p.key {
|
||||
PropertyKey::StaticIdentifier(ident) => ident.name.as_str().to_string(),
|
||||
PropertyKey::StringLiteral(s) => s.value.to_string(),
|
||||
_ => return Err("unsupported object property key type".into()),
|
||||
let computed = p.computed;
|
||||
let prop_name = if computed {
|
||||
"<computed>".to_string()
|
||||
} else {
|
||||
self.class_property_name(&p.key)?
|
||||
};
|
||||
match p.kind {
|
||||
PropertyKind::Get | PropertyKind::Set => {
|
||||
if computed {
|
||||
return Err("computed object accessors not yet supported".into());
|
||||
}
|
||||
let accessor_reg = self.emit_expression(&p.value, ctx)?;
|
||||
if let Some(sub_mod) = ctx.nested.last_mut() {
|
||||
sub_mod.function_name = Some(prop_name.to_string());
|
||||
@@ -43,20 +47,31 @@ impl Emitter {
|
||||
));
|
||||
}
|
||||
_ => {
|
||||
let idx = ctx.add_constant(Constant::String(prop_name.to_string()));
|
||||
let key_reg = ctx.alloc_reg();
|
||||
ctx.inst(Inst::load_const(Operand::Reg(key_reg), idx));
|
||||
let key_reg = if computed {
|
||||
self.emit_expression(p.key.to_expression(), ctx)?
|
||||
} else {
|
||||
let idx = ctx.add_constant(Constant::String(prop_name.to_string()));
|
||||
let reg = ctx.alloc_reg();
|
||||
ctx.inst(Inst::load_const(Operand::Reg(reg), idx));
|
||||
reg
|
||||
};
|
||||
let val_reg = self.emit_expression(&p.value, ctx)?;
|
||||
if matches!(&p.value, Expression::ArrowFunctionExpression(_)) {
|
||||
if let Some(sub_mod) = ctx.nested.last_mut() {
|
||||
sub_mod.function_name = Some(prop_name.to_string());
|
||||
}
|
||||
}
|
||||
let op = if computed { OpCode::SET_PROP_DYNAMIC } else { OpCode::SET_PROP };
|
||||
let operands = if computed {
|
||||
(Operand::Reg(key_reg), Operand::Reg(val_reg))
|
||||
} else {
|
||||
(Operand::Reg(val_reg), Operand::Reg(key_reg))
|
||||
};
|
||||
ctx.inst(Inst::new(
|
||||
OpCode::SET_PROP,
|
||||
op,
|
||||
Operand::Reg(obj_reg),
|
||||
Operand::Reg(val_reg),
|
||||
Operand::Reg(key_reg),
|
||||
operands.0,
|
||||
operands.1,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user