fix: class 方法/访问器/constructor/prototype 属性描述符(非枚举/只读),新增 DEFINE_PROP_ATTRS/DEFINE_ACCESSOR_ATTRS
- opcode.rs/inst.rs/contract.rs/vm.rs/vm_dispatch_ctrl.rs:新增两个带 attrs 扩展字的 define 指令 (attrs bit0=writable, bit1=enumerable, bit2=configurable,与 PropAttributes 一致) - class/method.rs:方法与非计算访问器改按规范非枚举安装(DefineMethod 语义) - class/prototype.rs:proto.constructor 非枚举;ctor.prototype 三标志全 false(MakeConstructor) - 效果:language/statements/class 1782 pass/948 fail -> 1910 pass/716 fail(+128/-232)
This commit is contained in:
@@ -8,6 +8,9 @@ use oxide_ir::inst::Inst;
|
||||
use oxide_ir::operand::Operand;
|
||||
use oxide_parser::{ClassElement, MethodDefinitionKind, PropertyKey};
|
||||
|
||||
/// class 方法/访问器属性描述符:writable + configurable,enumerable = false(规范 DefineMethod)。
|
||||
const CLASS_METHOD_ATTRS: u32 = 0b101;
|
||||
|
||||
impl Emitter {
|
||||
pub(crate) fn emit_class_methods(
|
||||
&self, elements: &[ClassElement], ctor_reg: u32, proto_reg: u32, self_binding: &[(&str, u32)],
|
||||
@@ -39,21 +42,13 @@ impl Emitter {
|
||||
self.emit_class_method_function(method, &method_name, Operand::Reg(home_reg), ctx, self_binding)?;
|
||||
match method.kind {
|
||||
MethodDefinitionKind::Method => {
|
||||
if method.computed {
|
||||
ctx.inst(Inst::new(
|
||||
OpCode::SET_PROP_DYNAMIC,
|
||||
Operand::Reg(home_reg),
|
||||
Operand::Reg(key_reg),
|
||||
Operand::Reg(accessor_reg),
|
||||
));
|
||||
} else {
|
||||
ctx.inst(Inst::new(
|
||||
OpCode::SET_PROP,
|
||||
Operand::Reg(home_reg),
|
||||
Operand::Reg(accessor_reg),
|
||||
Operand::Reg(key_reg),
|
||||
));
|
||||
}
|
||||
// class 方法按规范为非枚举数据属性(DefineMethod:writable/configurable,enumerable=false)。
|
||||
ctx.inst(Inst::define_prop_attrs(
|
||||
Operand::Reg(home_reg),
|
||||
Operand::Reg(accessor_reg),
|
||||
Operand::Reg(key_reg),
|
||||
CLASS_METHOD_ATTRS,
|
||||
));
|
||||
}
|
||||
MethodDefinitionKind::Get | MethodDefinitionKind::Set => {
|
||||
if method.computed {
|
||||
@@ -67,11 +62,12 @@ impl Emitter {
|
||||
};
|
||||
let key_name = self.class_property_name(&method.key)?;
|
||||
let key_idx = ctx.add_constant(Constant::String(key_name));
|
||||
ctx.inst(Inst::define_accessor(
|
||||
ctx.inst(Inst::define_accessor_attrs(
|
||||
Operand::Reg(home_reg),
|
||||
Operand::Reg(get_reg),
|
||||
Operand::Reg(set_reg),
|
||||
key_idx as u32,
|
||||
CLASS_METHOD_ATTRS,
|
||||
));
|
||||
}
|
||||
MethodDefinitionKind::Constructor => continue,
|
||||
|
||||
@@ -42,20 +42,22 @@ impl Emitter {
|
||||
let ctor_key_idx = ctx.add_constant(Constant::String("constructor".to_string()));
|
||||
let ctor_key_reg = ctx.alloc_reg();
|
||||
ctx.inst(Inst::load_const(Operand::Reg(ctor_key_reg), ctor_key_idx));
|
||||
ctx.inst(Inst::new(
|
||||
OpCode::SET_PROP,
|
||||
// Class.prototype.constructor:writable/configurable,enumerable = false。
|
||||
ctx.inst(Inst::define_prop_attrs(
|
||||
Operand::Reg(proto_reg),
|
||||
Operand::Reg(ctor_reg),
|
||||
Operand::Reg(ctor_key_reg),
|
||||
0b101,
|
||||
));
|
||||
let proto_key_idx = ctx.add_constant(Constant::String("prototype".to_string()));
|
||||
let proto_key_reg = ctx.alloc_reg();
|
||||
ctx.inst(Inst::load_const(Operand::Reg(proto_key_reg), proto_key_idx));
|
||||
ctx.inst(Inst::new(
|
||||
OpCode::SET_PROP,
|
||||
// 类构造器 .prototype 属性:writable/enumerable/configurable 全 false(MakeConstructor)。
|
||||
ctx.inst(Inst::define_prop_attrs(
|
||||
Operand::Reg(ctor_reg),
|
||||
Operand::Reg(proto_reg),
|
||||
Operand::Reg(proto_key_reg),
|
||||
0b000,
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user