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:
爱特每羊队
2026-08-12 14:11:02 +08:00
parent 5726d4126b
commit 1a4663dcab
7 changed files with 98 additions and 20 deletions
+12 -16
View File
@@ -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,
+6 -4
View File
@@ -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(())
}