mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 03:01:12 +08:00
feat: 对象方法 super 门加计算型 super 成员加 VM 步序对齐
This commit is contained in:
@@ -88,22 +88,12 @@ impl Emitter {
|
||||
let pair = match tag {
|
||||
Expression::StaticMemberExpression(member) => {
|
||||
if matches!(&member.object, Expression::Super(_)) {
|
||||
if !ctx.in_instance_method && !ctx.in_static_method && !ctx.in_derived_constructor {
|
||||
return Err("super property only supported in class methods".into());
|
||||
}
|
||||
let this_reg = self.emit_super_this(ctx)?;
|
||||
let prop_name = member.property.name.as_str();
|
||||
let key_reg = ctx.alloc_reg();
|
||||
let idx = ctx.add_constant(Constant::String(prop_name.to_string()));
|
||||
ctx.inst(Inst::load_const(Operand::Reg(key_reg), idx));
|
||||
let this_reg = ctx.alloc_reg();
|
||||
ctx.inst(Inst::new(OpCode::LOAD_VAR, Operand::Reg(this_reg), Operand::This, Operand::None));
|
||||
let callee_reg = ctx.alloc_reg();
|
||||
let op = if ctx.in_static_method {
|
||||
OpCode::SUPER_STATIC_GET_PROP
|
||||
} else {
|
||||
OpCode::SUPER_GET_PROP
|
||||
};
|
||||
ctx.inst(Inst::new(op, Operand::Reg(callee_reg), Operand::Reg(this_reg), Operand::Reg(key_reg)));
|
||||
let callee_reg = self.emit_super_get(this_reg, key_reg, ctx);
|
||||
(callee_reg, this_reg)
|
||||
} else {
|
||||
let obj_reg = self.emit_expression(&member.object, ctx)?;
|
||||
@@ -123,30 +113,37 @@ impl Emitter {
|
||||
}
|
||||
}
|
||||
Expression::ComputedMemberExpression(member) => {
|
||||
let obj_reg = self.emit_expression(&member.object, ctx)?;
|
||||
if let Some(key) = crate::expr::member::computed_const_key(&member.expression) {
|
||||
let key_reg = ctx.alloc_reg();
|
||||
let idx = ctx.add_constant(Constant::String(key));
|
||||
ctx.inst(Inst::load_const(Operand::Reg(key_reg), idx));
|
||||
let callee_reg = ctx.alloc_reg();
|
||||
ctx.inst(Inst::new(
|
||||
OpCode::LOAD_VAR,
|
||||
Operand::Reg(callee_reg),
|
||||
Operand::Reg(obj_reg),
|
||||
Operand::None,
|
||||
));
|
||||
ctx.inst(Inst::ic_get(Operand::Reg(callee_reg), Operand::Reg(key_reg)));
|
||||
(callee_reg, obj_reg)
|
||||
} else {
|
||||
if matches!(&member.object, Expression::Super(_)) {
|
||||
let this_reg = self.emit_super_this(ctx)?;
|
||||
let key_reg = self.emit_expression(&member.expression, ctx)?;
|
||||
let callee_reg = ctx.alloc_reg();
|
||||
ctx.inst(Inst::new(
|
||||
OpCode::GET_PROP_DYNAMIC,
|
||||
Operand::Reg(obj_reg),
|
||||
Operand::Reg(key_reg),
|
||||
Operand::Reg(callee_reg),
|
||||
));
|
||||
(callee_reg, obj_reg)
|
||||
let callee_reg = self.emit_super_get(this_reg, key_reg, ctx);
|
||||
(callee_reg, this_reg)
|
||||
} else {
|
||||
let obj_reg = self.emit_expression(&member.object, ctx)?;
|
||||
if let Some(key) = crate::expr::member::computed_const_key(&member.expression) {
|
||||
let key_reg = ctx.alloc_reg();
|
||||
let idx = ctx.add_constant(Constant::String(key));
|
||||
ctx.inst(Inst::load_const(Operand::Reg(key_reg), idx));
|
||||
let callee_reg = ctx.alloc_reg();
|
||||
ctx.inst(Inst::new(
|
||||
OpCode::LOAD_VAR,
|
||||
Operand::Reg(callee_reg),
|
||||
Operand::Reg(obj_reg),
|
||||
Operand::None,
|
||||
));
|
||||
ctx.inst(Inst::ic_get(Operand::Reg(callee_reg), Operand::Reg(key_reg)));
|
||||
(callee_reg, obj_reg)
|
||||
} else {
|
||||
let key_reg = self.emit_expression(&member.expression, ctx)?;
|
||||
let callee_reg = ctx.alloc_reg();
|
||||
ctx.inst(Inst::new(
|
||||
OpCode::GET_PROP_DYNAMIC,
|
||||
Operand::Reg(obj_reg),
|
||||
Operand::Reg(key_reg),
|
||||
Operand::Reg(callee_reg),
|
||||
));
|
||||
(callee_reg, obj_reg)
|
||||
}
|
||||
}
|
||||
}
|
||||
Expression::PrivateFieldExpression(member) => {
|
||||
|
||||
Reference in New Issue
Block a user