diff --git a/core/engine/src/bytecompiler/class.rs b/core/engine/src/bytecompiler/class.rs index f18b9f6f9e..04d3087548 100644 --- a/core/engine/src/bytecompiler/class.rs +++ b/core/engine/src/bytecompiler/class.rs @@ -423,21 +423,33 @@ impl ByteCompiler<'_> { self.emit_with_varying_operand(Opcode::PushClassPrivateSetter, index); } 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()); let index = self.get_or_insert_private_name(*name); self.emit_with_varying_operand(Opcode::PushClassPrivateMethod, index); } 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()); let index = self.get_or_insert_private_name(*name); self.emit_with_varying_operand(Opcode::PushClassPrivateMethod, index); } 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()); let index = self.get_or_insert_private_name(*name); self.emit_with_varying_operand(Opcode::PushClassPrivateMethod, index); } 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()); let index = self.get_or_insert_private_name(*name); self.emit_with_varying_operand(Opcode::PushClassPrivateMethod, index); diff --git a/core/engine/src/vm/opcode/mod.rs b/core/engine/src/vm/opcode/mod.rs index 15a362159d..f3a318192a 100644 --- a/core/engine/src/vm/opcode/mod.rs +++ b/core/engine/src/vm/opcode/mod.rs @@ -1450,7 +1450,7 @@ generate_opcodes! { /// /// Operands: index: `u32` /// - /// Stack: class, method **=>** + /// Stack: class, class_proto, method **=>** PushClassPrivateMethod { index: VaryingOperand }, /// Deletes a property by name of an object. diff --git a/core/engine/src/vm/opcode/push/class/private.rs b/core/engine/src/vm/opcode/push/class/private.rs index 032c330000..d40b355597 100644 --- a/core/engine/src/vm/opcode/push/class/private.rs +++ b/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 method = context.vm.pop(); 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 desc = PropertyDescriptor::builder() @@ -35,9 +41,10 @@ impl PushClassPrivateMethod { &mut InternalMethodContext::new(context), ) .expect("failed to set name property on private method"); - - let class = context.vm.pop(); - let class_object = class.as_object().expect("class must be function object"); + method_object + .downcast_mut::() + .expect("method must be function object") + .set_home_object(class_proto_object.clone()); class_object .downcast_mut::()