Browse Source

Fix HomeObject for private class methods (#3897)

pull/3906/head
raskad 5 months ago committed by GitHub
parent
commit
5bf2e92d2f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 12
      core/engine/src/bytecompiler/class.rs
  2. 2
      core/engine/src/vm/opcode/mod.rs
  3. 13
      core/engine/src/vm/opcode/push/class/private.rs

12
core/engine/src/bytecompiler/class.rs

@ -423,21 +423,33 @@ impl ByteCompiler<'_> {
self.emit_with_varying_operand(Opcode::PushClassPrivateSetter, index); self.emit_with_varying_operand(Opcode::PushClassPrivateSetter, index);
} }
MethodDefinition::Ordinary(expr) => { MethodDefinition::Ordinary(expr) => {
self.emit(Opcode::RotateLeft, &[Operand::U8(3)]);
self.emit_opcode(Opcode::Dup);
self.emit(Opcode::RotateRight, &[Operand::U8(4)]);
self.method(expr.into()); self.method(expr.into());
let index = self.get_or_insert_private_name(*name); let index = self.get_or_insert_private_name(*name);
self.emit_with_varying_operand(Opcode::PushClassPrivateMethod, index); self.emit_with_varying_operand(Opcode::PushClassPrivateMethod, index);
} }
MethodDefinition::Async(expr) => { MethodDefinition::Async(expr) => {
self.emit(Opcode::RotateLeft, &[Operand::U8(3)]);
self.emit_opcode(Opcode::Dup);
self.emit(Opcode::RotateRight, &[Operand::U8(4)]);
self.method(expr.into()); self.method(expr.into());
let index = self.get_or_insert_private_name(*name); let index = self.get_or_insert_private_name(*name);
self.emit_with_varying_operand(Opcode::PushClassPrivateMethod, index); self.emit_with_varying_operand(Opcode::PushClassPrivateMethod, index);
} }
MethodDefinition::Generator(expr) => { MethodDefinition::Generator(expr) => {
self.emit(Opcode::RotateLeft, &[Operand::U8(3)]);
self.emit_opcode(Opcode::Dup);
self.emit(Opcode::RotateRight, &[Operand::U8(4)]);
self.method(expr.into()); self.method(expr.into());
let index = self.get_or_insert_private_name(*name); let index = self.get_or_insert_private_name(*name);
self.emit_with_varying_operand(Opcode::PushClassPrivateMethod, index); self.emit_with_varying_operand(Opcode::PushClassPrivateMethod, index);
} }
MethodDefinition::AsyncGenerator(expr) => { MethodDefinition::AsyncGenerator(expr) => {
self.emit(Opcode::RotateLeft, &[Operand::U8(3)]);
self.emit_opcode(Opcode::Dup);
self.emit(Opcode::RotateRight, &[Operand::U8(4)]);
self.method(expr.into()); self.method(expr.into());
let index = self.get_or_insert_private_name(*name); let index = self.get_or_insert_private_name(*name);
self.emit_with_varying_operand(Opcode::PushClassPrivateMethod, index); self.emit_with_varying_operand(Opcode::PushClassPrivateMethod, index);

2
core/engine/src/vm/opcode/mod.rs

@ -1450,7 +1450,7 @@ generate_opcodes! {
/// ///
/// Operands: index: `u32` /// Operands: index: `u32`
/// ///
/// Stack: class, method **=>** /// Stack: class, class_proto, method **=>**
PushClassPrivateMethod { index: VaryingOperand }, PushClassPrivateMethod { index: VaryingOperand },
/// Deletes a property by name of an object. /// Deletes a property by name of an object.

13
core/engine/src/vm/opcode/push/class/private.rs

@ -20,6 +20,12 @@ impl PushClassPrivateMethod {
let name = context.vm.frame().code_block().constant_string(index); let name = context.vm.frame().code_block().constant_string(index);
let method = context.vm.pop(); let method = context.vm.pop();
let method_object = method.as_callable().expect("method must be callable"); let method_object = method.as_callable().expect("method must be callable");
let class_proto = context.vm.pop();
let class_proto_object = class_proto
.as_object()
.expect("class_proto must be function object");
let class = context.vm.pop();
let class_object = class.as_object().expect("class must be function object");
let name_string = js_string!(js_str!("#"), &name); let name_string = js_string!(js_str!("#"), &name);
let desc = PropertyDescriptor::builder() let desc = PropertyDescriptor::builder()
@ -35,9 +41,10 @@ impl PushClassPrivateMethod {
&mut InternalMethodContext::new(context), &mut InternalMethodContext::new(context),
) )
.expect("failed to set name property on private method"); .expect("failed to set name property on private method");
method_object
let class = context.vm.pop(); .downcast_mut::<OrdinaryFunction>()
let class_object = class.as_object().expect("class must be function object"); .expect("method must be function object")
.set_home_object(class_proto_object.clone());
class_object class_object
.downcast_mut::<OrdinaryFunction>() .downcast_mut::<OrdinaryFunction>()

Loading…
Cancel
Save