Browse Source

Remove unused class environments (#3332)

pull/3341/head
raskad 1 year ago committed by GitHub
parent
commit
38b9f17a8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      boa_engine/src/builtins/function/mod.rs
  2. 127
      boa_engine/src/bytecompiler/class.rs
  3. 17
      boa_engine/src/bytecompiler/function.rs
  4. 3
      boa_engine/src/bytecompiler/mod.rs
  5. 22
      boa_engine/src/vm/code_block.rs
  6. 4
      boa_engine/src/vm/flowgraph/mod.rs
  7. 17
      boa_engine/src/vm/opcode/define/class/getter.rs
  8. 17
      boa_engine/src/vm/opcode/define/class/method.rs
  9. 17
      boa_engine/src/vm/opcode/define/class/setter.rs
  10. 9
      boa_engine/src/vm/opcode/mod.rs
  11. 2
      boa_engine/src/vm/opcode/push/class/field.rs
  12. 17
      boa_engine/src/vm/opcode/push/class/private.rs
  13. 32
      boa_engine/src/vm/opcode/set/home_object.rs
  14. 15
      boa_engine/src/vm/opcode/set/private.rs

8
boa_engine/src/builtins/function/mod.rs

@ -225,9 +225,6 @@ pub struct OrdinaryFunction {
/// The `[[HomeObject]]` internal slot. /// The `[[HomeObject]]` internal slot.
pub(crate) home_object: Option<JsObject>, pub(crate) home_object: Option<JsObject>,
/// The class object that this function is associated with.
pub(crate) class_object: Option<JsObject>,
/// The `[[ScriptOrModule]]` internal slot. /// The `[[ScriptOrModule]]` internal slot.
pub(crate) script_or_module: Option<ActiveRunnable>, pub(crate) script_or_module: Option<ActiveRunnable>,
@ -322,11 +319,6 @@ impl OrdinaryFunction {
} }
} }
/// Sets the class object.
pub(crate) fn set_class_object(&mut self, object: JsObject) {
self.class_object = Some(object);
}
/// Gets the `Realm` from where this function originates. /// Gets the `Realm` from where this function originates.
#[must_use] #[must_use]
pub const fn realm(&self) -> &Realm { pub const fn realm(&self) -> &Realm {

127
boa_engine/src/bytecompiler/class.rs

@ -26,6 +26,15 @@ impl ByteCompiler<'_, '_> {
pub(crate) fn compile_class(&mut self, class: &Class, expression: bool) { pub(crate) fn compile_class(&mut self, class: &Class, expression: bool) {
let class_name = class.name().map_or(Sym::EMPTY_STRING, Identifier::sym); let class_name = class.name().map_or(Sym::EMPTY_STRING, Identifier::sym);
let class_env: Option<super::Label> = match class.name() {
Some(name) if class.has_binding_identifier() => {
self.push_compile_environment(false);
self.create_immutable_binding(name, true);
Some(self.emit_opcode_with_operand(Opcode::PushDeclarativeEnvironment))
}
_ => None,
};
let mut compiler = ByteCompiler::new( let mut compiler = ByteCompiler::new(
class_name, class_name,
true, true,
@ -34,14 +43,6 @@ impl ByteCompiler<'_, '_> {
self.context, self.context,
); );
if let Some(class_name) = class.name() {
if class.has_binding_identifier() {
compiler.code_block_flags |= CodeBlockFlags::HAS_BINDING_IDENTIFIER;
compiler.push_compile_environment(false);
compiler.create_immutable_binding(class_name, true);
}
}
compiler.push_compile_environment(true); compiler.push_compile_environment(true);
if let Some(expr) = class.constructor() { if let Some(expr) = class.constructor() {
@ -80,10 +81,6 @@ impl ByteCompiler<'_, '_> {
} }
compiler.emit_opcode(Opcode::SetReturnValue); compiler.emit_opcode(Opcode::SetReturnValue);
if class.name().is_some() && class.has_binding_identifier() {
compiler.pop_compile_environment();
}
let code = Gc::new(compiler.finish()); let code = Gc::new(compiler.finish());
let index = self.functions.len() as u32; let index = self.functions.len() as u32;
self.functions.push(code); self.functions.push(code);
@ -92,15 +89,6 @@ impl ByteCompiler<'_, '_> {
&[Operand::Varying(index), Operand::Bool(false)], &[Operand::Varying(index), Operand::Bool(false)],
); );
let class_env: Option<super::Label> = match class.name() {
Some(name) if class.has_binding_identifier() => {
self.push_compile_environment(false);
self.create_immutable_binding(name, true);
Some(self.emit_opcode_with_operand(Opcode::PushDeclarativeEnvironment))
}
_ => None,
};
self.emit_opcode(Opcode::Dup); self.emit_opcode(Opcode::Dup);
if let Some(node) = class.super_ref() { if let Some(node) = class.super_ref() {
self.compile_expr(node, true); self.compile_expr(node, true);
@ -131,6 +119,12 @@ impl ByteCompiler<'_, '_> {
let mut static_elements = Vec::new(); let mut static_elements = Vec::new();
let mut static_field_name_count = 0; let mut static_field_name_count = 0;
if class_env.is_some() {
self.emit_opcode(Opcode::Dup);
self.emit_binding(BindingOpcode::InitConst, class_name.into());
}
// TODO: set function name for getter and setters
for element in class.elements() { for element in class.elements() {
match element { match element {
ClassElement::StaticMethodDefinition(name, method_definition) => { ClassElement::StaticMethodDefinition(name, method_definition) => {
@ -138,7 +132,7 @@ impl ByteCompiler<'_, '_> {
match method_definition { match method_definition {
MethodDefinition::Get(expr) => match name { MethodDefinition::Get(expr) => match name {
PropertyName::Literal(name) => { PropertyName::Literal(name) => {
self.method(expr.into(), class_name); self.method(expr.into());
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit_with_varying_operand( self.emit_with_varying_operand(
Opcode::DefineClassStaticGetterByName, Opcode::DefineClassStaticGetterByName,
@ -148,13 +142,13 @@ impl ByteCompiler<'_, '_> {
PropertyName::Computed(name_node) => { PropertyName::Computed(name_node) => {
self.compile_expr(name_node, true); self.compile_expr(name_node, true);
self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::ToPropertyKey);
self.method(expr.into(), class_name); self.method(expr.into());
self.emit_opcode(Opcode::DefineClassStaticGetterByValue); self.emit_opcode(Opcode::DefineClassStaticGetterByValue);
} }
}, },
MethodDefinition::Set(expr) => match name { MethodDefinition::Set(expr) => match name {
PropertyName::Literal(name) => { PropertyName::Literal(name) => {
self.method(expr.into(), class_name); self.method(expr.into());
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit_with_varying_operand( self.emit_with_varying_operand(
Opcode::DefineClassStaticSetterByName, Opcode::DefineClassStaticSetterByName,
@ -164,13 +158,13 @@ impl ByteCompiler<'_, '_> {
PropertyName::Computed(name_node) => { PropertyName::Computed(name_node) => {
self.compile_expr(name_node, true); self.compile_expr(name_node, true);
self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::ToPropertyKey);
self.method(expr.into(), class_name); self.method(expr.into());
self.emit_opcode(Opcode::DefineClassStaticSetterByValue); self.emit_opcode(Opcode::DefineClassStaticSetterByValue);
} }
}, },
MethodDefinition::Ordinary(expr) => match name { MethodDefinition::Ordinary(expr) => match name {
PropertyName::Literal(name) => { PropertyName::Literal(name) => {
self.method(expr.into(), class_name); self.method(expr.into());
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit_with_varying_operand( self.emit_with_varying_operand(
Opcode::DefineClassStaticMethodByName, Opcode::DefineClassStaticMethodByName,
@ -180,13 +174,13 @@ impl ByteCompiler<'_, '_> {
PropertyName::Computed(name_node) => { PropertyName::Computed(name_node) => {
self.compile_expr(name_node, true); self.compile_expr(name_node, true);
self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::ToPropertyKey);
self.method(expr.into(), class_name); self.method(expr.into());
self.emit_opcode(Opcode::DefineClassStaticMethodByValue); self.emit_opcode(Opcode::DefineClassStaticMethodByValue);
} }
}, },
MethodDefinition::Async(expr) => match name { MethodDefinition::Async(expr) => match name {
PropertyName::Literal(name) => { PropertyName::Literal(name) => {
self.method(expr.into(), class_name); self.method(expr.into());
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit_with_varying_operand( self.emit_with_varying_operand(
Opcode::DefineClassStaticMethodByName, Opcode::DefineClassStaticMethodByName,
@ -196,13 +190,13 @@ impl ByteCompiler<'_, '_> {
PropertyName::Computed(name_node) => { PropertyName::Computed(name_node) => {
self.compile_expr(name_node, true); self.compile_expr(name_node, true);
self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::ToPropertyKey);
self.method(expr.into(), class_name); self.method(expr.into());
self.emit_opcode(Opcode::DefineClassStaticMethodByValue); self.emit_opcode(Opcode::DefineClassStaticMethodByValue);
} }
}, },
MethodDefinition::Generator(expr) => match name { MethodDefinition::Generator(expr) => match name {
PropertyName::Literal(name) => { PropertyName::Literal(name) => {
self.method(expr.into(), class_name); self.method(expr.into());
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit_with_varying_operand( self.emit_with_varying_operand(
Opcode::DefineClassStaticMethodByName, Opcode::DefineClassStaticMethodByName,
@ -212,13 +206,13 @@ impl ByteCompiler<'_, '_> {
PropertyName::Computed(name_node) => { PropertyName::Computed(name_node) => {
self.compile_expr(name_node, true); self.compile_expr(name_node, true);
self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::ToPropertyKey);
self.method(expr.into(), class_name); self.method(expr.into());
self.emit_opcode(Opcode::DefineClassStaticMethodByValue); self.emit_opcode(Opcode::DefineClassStaticMethodByValue);
} }
}, },
MethodDefinition::AsyncGenerator(expr) => match name { MethodDefinition::AsyncGenerator(expr) => match name {
PropertyName::Literal(name) => { PropertyName::Literal(name) => {
self.method(expr.into(), class_name); self.method(expr.into());
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit_with_varying_operand( self.emit_with_varying_operand(
Opcode::DefineClassStaticMethodByName, Opcode::DefineClassStaticMethodByName,
@ -228,7 +222,7 @@ impl ByteCompiler<'_, '_> {
PropertyName::Computed(name_node) => { PropertyName::Computed(name_node) => {
self.compile_expr(name_node, true); self.compile_expr(name_node, true);
self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::ToPropertyKey);
self.method(expr.into(), class_name); self.method(expr.into());
self.emit_opcode(Opcode::DefineClassStaticMethodByValue); self.emit_opcode(Opcode::DefineClassStaticMethodByValue);
} }
}, },
@ -238,32 +232,32 @@ impl ByteCompiler<'_, '_> {
self.emit_opcode(Opcode::Dup); self.emit_opcode(Opcode::Dup);
match method_definition { match method_definition {
MethodDefinition::Get(expr) => { MethodDefinition::Get(expr) => {
self.method(expr.into(), class_name); 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::SetPrivateGetter, index); self.emit_with_varying_operand(Opcode::SetPrivateGetter, index);
} }
MethodDefinition::Set(expr) => { MethodDefinition::Set(expr) => {
self.method(expr.into(), class_name); 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::SetPrivateSetter, index); self.emit_with_varying_operand(Opcode::SetPrivateSetter, index);
} }
MethodDefinition::Ordinary(expr) => { MethodDefinition::Ordinary(expr) => {
self.method(expr.into(), class_name); 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::SetPrivateMethod, index); self.emit_with_varying_operand(Opcode::SetPrivateMethod, index);
} }
MethodDefinition::Async(expr) => { MethodDefinition::Async(expr) => {
self.method(expr.into(), class_name); 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::SetPrivateMethod, index); self.emit_with_varying_operand(Opcode::SetPrivateMethod, index);
} }
MethodDefinition::Generator(expr) => { MethodDefinition::Generator(expr) => {
self.method(expr.into(), class_name); 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::SetPrivateMethod, index); self.emit_with_varying_operand(Opcode::SetPrivateMethod, index);
} }
MethodDefinition::AsyncGenerator(expr) => { MethodDefinition::AsyncGenerator(expr) => {
self.method(expr.into(), class_name); 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::SetPrivateMethod, index); self.emit_with_varying_operand(Opcode::SetPrivateMethod, index);
} }
@ -288,8 +282,6 @@ impl ByteCompiler<'_, '_> {
self.current_environment.clone(), self.current_environment.clone(),
self.context, self.context,
); );
field_compiler.push_compile_environment(false);
field_compiler.create_immutable_binding(class_name.into(), true);
field_compiler.push_compile_environment(true); field_compiler.push_compile_environment(true);
if let Some(node) = field { if let Some(node) = field {
field_compiler.compile_expr(node, true); field_compiler.compile_expr(node, true);
@ -298,7 +290,6 @@ impl ByteCompiler<'_, '_> {
} }
field_compiler.emit_opcode(Opcode::SetReturnValue); field_compiler.emit_opcode(Opcode::SetReturnValue);
field_compiler.pop_compile_environment();
field_compiler.pop_compile_environment(); field_compiler.pop_compile_environment();
field_compiler.code_block_flags |= CodeBlockFlags::IN_CLASS_FIELD_INITIALIZER; field_compiler.code_block_flags |= CodeBlockFlags::IN_CLASS_FIELD_INITIALIZER;
@ -323,8 +314,6 @@ impl ByteCompiler<'_, '_> {
self.current_environment.clone(), self.current_environment.clone(),
self.context, self.context,
); );
field_compiler.push_compile_environment(false);
field_compiler.create_immutable_binding(class_name.into(), true);
field_compiler.push_compile_environment(true); field_compiler.push_compile_environment(true);
if let Some(node) = field { if let Some(node) = field {
field_compiler.compile_expr(node, true); field_compiler.compile_expr(node, true);
@ -332,7 +321,6 @@ impl ByteCompiler<'_, '_> {
field_compiler.emit_opcode(Opcode::PushUndefined); field_compiler.emit_opcode(Opcode::PushUndefined);
} }
field_compiler.pop_compile_environment(); field_compiler.pop_compile_environment();
field_compiler.pop_compile_environment();
field_compiler.emit_opcode(Opcode::SetReturnValue); field_compiler.emit_opcode(Opcode::SetReturnValue);
@ -370,8 +358,6 @@ impl ByteCompiler<'_, '_> {
self.current_environment.clone(), self.current_environment.clone(),
self.context, self.context,
); );
field_compiler.push_compile_environment(false);
field_compiler.create_immutable_binding(class_name.into(), true);
field_compiler.push_compile_environment(true); field_compiler.push_compile_environment(true);
if let Some(node) = field { if let Some(node) = field {
field_compiler.compile_expr(node, true); field_compiler.compile_expr(node, true);
@ -380,7 +366,6 @@ impl ByteCompiler<'_, '_> {
} }
field_compiler.emit_opcode(Opcode::SetReturnValue); field_compiler.emit_opcode(Opcode::SetReturnValue);
field_compiler.pop_compile_environment();
field_compiler.pop_compile_environment(); field_compiler.pop_compile_environment();
field_compiler.code_block_flags |= CodeBlockFlags::IN_CLASS_FIELD_INITIALIZER; field_compiler.code_block_flags |= CodeBlockFlags::IN_CLASS_FIELD_INITIALIZER;
@ -408,8 +393,6 @@ impl ByteCompiler<'_, '_> {
self.current_environment.clone(), self.current_environment.clone(),
self.context, self.context,
); );
compiler.push_compile_environment(false);
compiler.create_immutable_binding(class_name.into(), true);
compiler.push_compile_environment(true); compiler.push_compile_environment(true);
compiler.function_declaration_instantiation( compiler.function_declaration_instantiation(
@ -422,7 +405,6 @@ impl ByteCompiler<'_, '_> {
compiler.compile_statement_list(body.statements(), false, false); compiler.compile_statement_list(body.statements(), false, false);
compiler.pop_compile_environment(); compiler.pop_compile_environment();
compiler.pop_compile_environment();
let code = Gc::new(compiler.finish()); let code = Gc::new(compiler.finish());
static_elements.push(StaticElement::StaticBlock(code)); static_elements.push(StaticElement::StaticBlock(code));
@ -431,32 +413,32 @@ impl ByteCompiler<'_, '_> {
self.emit_opcode(Opcode::Dup); self.emit_opcode(Opcode::Dup);
match method_definition { match method_definition {
MethodDefinition::Get(expr) => { MethodDefinition::Get(expr) => {
self.method(expr.into(), class_name); 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::PushClassPrivateGetter, index); self.emit_with_varying_operand(Opcode::PushClassPrivateGetter, index);
} }
MethodDefinition::Set(expr) => { MethodDefinition::Set(expr) => {
self.method(expr.into(), class_name); 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::PushClassPrivateSetter, index); self.emit_with_varying_operand(Opcode::PushClassPrivateSetter, index);
} }
MethodDefinition::Ordinary(expr) => { MethodDefinition::Ordinary(expr) => {
self.method(expr.into(), class_name); 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.method(expr.into(), class_name); 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.method(expr.into(), class_name); 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.method(expr.into(), class_name); 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);
} }
@ -468,7 +450,7 @@ impl ByteCompiler<'_, '_> {
match method_definition { match method_definition {
MethodDefinition::Get(expr) => match name { MethodDefinition::Get(expr) => match name {
PropertyName::Literal(name) => { PropertyName::Literal(name) => {
self.method(expr.into(), class_name); self.method(expr.into());
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit_with_varying_operand( self.emit_with_varying_operand(
Opcode::DefineClassGetterByName, Opcode::DefineClassGetterByName,
@ -478,13 +460,13 @@ impl ByteCompiler<'_, '_> {
PropertyName::Computed(name_node) => { PropertyName::Computed(name_node) => {
self.compile_expr(name_node, true); self.compile_expr(name_node, true);
self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::ToPropertyKey);
self.method(expr.into(), class_name); self.method(expr.into());
self.emit_opcode(Opcode::DefineClassGetterByValue); self.emit_opcode(Opcode::DefineClassGetterByValue);
} }
}, },
MethodDefinition::Set(expr) => match name { MethodDefinition::Set(expr) => match name {
PropertyName::Literal(name) => { PropertyName::Literal(name) => {
self.method(expr.into(), class_name); self.method(expr.into());
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit_with_varying_operand( self.emit_with_varying_operand(
Opcode::DefineClassSetterByName, Opcode::DefineClassSetterByName,
@ -494,13 +476,13 @@ impl ByteCompiler<'_, '_> {
PropertyName::Computed(name_node) => { PropertyName::Computed(name_node) => {
self.compile_expr(name_node, true); self.compile_expr(name_node, true);
self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::ToPropertyKey);
self.method(expr.into(), class_name); self.method(expr.into());
self.emit_opcode(Opcode::DefineClassSetterByValue); self.emit_opcode(Opcode::DefineClassSetterByValue);
} }
}, },
MethodDefinition::Ordinary(expr) => match name { MethodDefinition::Ordinary(expr) => match name {
PropertyName::Literal(name) => { PropertyName::Literal(name) => {
self.method(expr.into(), class_name); self.method(expr.into());
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit_with_varying_operand( self.emit_with_varying_operand(
Opcode::DefineClassMethodByName, Opcode::DefineClassMethodByName,
@ -510,13 +492,13 @@ impl ByteCompiler<'_, '_> {
PropertyName::Computed(name_node) => { PropertyName::Computed(name_node) => {
self.compile_expr(name_node, true); self.compile_expr(name_node, true);
self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::ToPropertyKey);
self.method(expr.into(), class_name); self.method(expr.into());
self.emit_opcode(Opcode::DefineClassMethodByValue); self.emit_opcode(Opcode::DefineClassMethodByValue);
} }
}, },
MethodDefinition::Async(expr) => match name { MethodDefinition::Async(expr) => match name {
PropertyName::Literal(name) => { PropertyName::Literal(name) => {
self.method(expr.into(), class_name); self.method(expr.into());
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit_with_varying_operand( self.emit_with_varying_operand(
Opcode::DefineClassMethodByName, Opcode::DefineClassMethodByName,
@ -526,13 +508,13 @@ impl ByteCompiler<'_, '_> {
PropertyName::Computed(name_node) => { PropertyName::Computed(name_node) => {
self.compile_expr(name_node, true); self.compile_expr(name_node, true);
self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::ToPropertyKey);
self.method(expr.into(), class_name); self.method(expr.into());
self.emit_opcode(Opcode::DefineClassMethodByValue); self.emit_opcode(Opcode::DefineClassMethodByValue);
} }
}, },
MethodDefinition::Generator(expr) => match name { MethodDefinition::Generator(expr) => match name {
PropertyName::Literal(name) => { PropertyName::Literal(name) => {
self.method(expr.into(), class_name); self.method(expr.into());
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit_with_varying_operand( self.emit_with_varying_operand(
Opcode::DefineClassMethodByName, Opcode::DefineClassMethodByName,
@ -542,13 +524,13 @@ impl ByteCompiler<'_, '_> {
PropertyName::Computed(name_node) => { PropertyName::Computed(name_node) => {
self.compile_expr(name_node, true); self.compile_expr(name_node, true);
self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::ToPropertyKey);
self.method(expr.into(), class_name); self.method(expr.into());
self.emit_opcode(Opcode::DefineClassMethodByValue); self.emit_opcode(Opcode::DefineClassMethodByValue);
} }
}, },
MethodDefinition::AsyncGenerator(expr) => match name { MethodDefinition::AsyncGenerator(expr) => match name {
PropertyName::Literal(name) => { PropertyName::Literal(name) => {
self.method(expr.into(), class_name); self.method(expr.into());
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit_with_varying_operand( self.emit_with_varying_operand(
Opcode::DefineClassMethodByName, Opcode::DefineClassMethodByName,
@ -558,7 +540,7 @@ impl ByteCompiler<'_, '_> {
PropertyName::Computed(name_node) => { PropertyName::Computed(name_node) => {
self.compile_expr(name_node, true); self.compile_expr(name_node, true);
self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::ToPropertyKey);
self.method(expr.into(), class_name); self.method(expr.into());
self.emit_opcode(Opcode::DefineClassMethodByValue); self.emit_opcode(Opcode::DefineClassMethodByValue);
} }
}, },
@ -578,7 +560,7 @@ impl ByteCompiler<'_, '_> {
Opcode::GetFunction, Opcode::GetFunction,
&[Operand::Varying(index), Operand::Bool(false)], &[Operand::Varying(index), Operand::Bool(false)],
); );
self.emit_opcode(Opcode::SetHomeObjectClass); self.emit_opcode(Opcode::SetHomeObject);
self.emit_with_varying_operand(Opcode::Call, 0); self.emit_with_varying_operand(Opcode::Call, 0);
self.emit_opcode(Opcode::Pop); self.emit_opcode(Opcode::Pop);
} }
@ -591,7 +573,7 @@ impl ByteCompiler<'_, '_> {
Opcode::GetFunction, Opcode::GetFunction,
&[Operand::Varying(index), Operand::Bool(false)], &[Operand::Varying(index), Operand::Bool(false)],
); );
self.emit_opcode(Opcode::SetHomeObjectClass); self.emit_opcode(Opcode::SetHomeObject);
self.emit_with_varying_operand(Opcode::Call, 0); self.emit_with_varying_operand(Opcode::Call, 0);
if let Some(name_index) = name_index { if let Some(name_index) = name_index {
self.emit_with_varying_operand(Opcode::DefineOwnPropertyByName, name_index); self.emit_with_varying_operand(Opcode::DefineOwnPropertyByName, name_index);
@ -608,9 +590,6 @@ impl ByteCompiler<'_, '_> {
self.emit_opcode(Opcode::Pop); self.emit_opcode(Opcode::Pop);
if let Some(class_env) = class_env { if let Some(class_env) = class_env {
self.emit_opcode(Opcode::Dup);
self.emit_binding(BindingOpcode::InitConst, class_name.into());
let env_index = self.pop_compile_environment(); let env_index = self.pop_compile_environment();
self.patch_jump_with_target(class_env, env_index); self.patch_jump_with_target(class_env, env_index);
self.emit_opcode(Opcode::PopEnvironment); self.emit_opcode(Opcode::PopEnvironment);

17
boa_engine/src/bytecompiler/function.rs

@ -21,7 +21,6 @@ pub(crate) struct FunctionCompiler {
strict: bool, strict: bool,
arrow: bool, arrow: bool,
binding_identifier: Option<Sym>, binding_identifier: Option<Sym>,
class_name: Option<Sym>,
} }
impl FunctionCompiler { impl FunctionCompiler {
@ -34,7 +33,6 @@ impl FunctionCompiler {
strict: false, strict: false,
arrow: false, arrow: false,
binding_identifier: None, binding_identifier: None,
class_name: None,
} }
} }
@ -79,12 +77,6 @@ impl FunctionCompiler {
self self
} }
/// Indicate if the function has a class associated with it.
pub(crate) const fn class_name(mut self, class_name: Sym) -> Self {
self.class_name = Some(class_name);
self
}
/// Compile a function statement list and it's parameters into bytecode. /// Compile a function statement list and it's parameters into bytecode.
pub(crate) fn compile( pub(crate) fn compile(
mut self, mut self,
@ -106,11 +98,6 @@ impl FunctionCompiler {
compiler.this_mode = ThisMode::Lexical; compiler.this_mode = ThisMode::Lexical;
} }
if let Some(class_name) = self.class_name {
compiler.push_compile_environment(false);
compiler.create_immutable_binding(class_name.into(), true);
}
if let Some(binding_identifier) = self.binding_identifier { if let Some(binding_identifier) = self.binding_identifier {
compiler.code_block_flags |= CodeBlockFlags::HAS_BINDING_IDENTIFIER; compiler.code_block_flags |= CodeBlockFlags::HAS_BINDING_IDENTIFIER;
compiler.push_compile_environment(false); compiler.push_compile_environment(false);
@ -184,10 +171,6 @@ impl FunctionCompiler {
compiler.pop_compile_environment(); compiler.pop_compile_environment();
} }
if self.class_name.is_some() {
compiler.pop_compile_environment();
}
compiler.params = parameters.clone(); compiler.params = parameters.clone();
Gc::new(compiler.finish()) Gc::new(compiler.finish())

3
boa_engine/src/bytecompiler/mod.rs

@ -1378,7 +1378,7 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
} }
/// Compile a class method AST Node into bytecode. /// Compile a class method AST Node into bytecode.
fn method(&mut self, function: FunctionSpec<'_>, class_name: Sym) { fn method(&mut self, function: FunctionSpec<'_>) {
let (generator, r#async, arrow) = ( let (generator, r#async, arrow) = (
function.kind.is_generator(), function.kind.is_generator(),
function.kind.is_async(), function.kind.is_async(),
@ -1409,7 +1409,6 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
.strict(true) .strict(true)
.arrow(arrow) .arrow(arrow)
.binding_identifier(binding_identifier) .binding_identifier(binding_identifier)
.class_name(class_name)
.compile( .compile(
parameters, parameters,
body, body,

22
boa_engine/src/vm/code_block.rs

@ -479,7 +479,6 @@ impl CodeBlock {
| Instruction::PushClassPrototype | Instruction::PushClassPrototype
| Instruction::SetClassPrototype | Instruction::SetClassPrototype
| Instruction::SetHomeObject | Instruction::SetHomeObject
| Instruction::SetHomeObjectClass
| Instruction::Add | Instruction::Add
| Instruction::Sub | Instruction::Sub
| Instruction::Div | Instruction::Div
@ -643,7 +642,8 @@ impl CodeBlock {
| Instruction::Reserved54 | Instruction::Reserved54
| Instruction::Reserved55 | Instruction::Reserved55
| Instruction::Reserved56 | Instruction::Reserved56
| Instruction::Reserved57 => unreachable!("Reserved opcodes are unrechable"), | Instruction::Reserved57
| Instruction::Reserved58 => unreachable!("Reserved opcodes are unrechable"),
} }
} }
} }
@ -784,7 +784,6 @@ pub(crate) fn create_function_object(
code, code,
environments: context.vm.environments.clone(), environments: context.vm.environments.clone(),
home_object: None, home_object: None,
class_object: None,
script_or_module, script_or_module,
kind: FunctionKind::Async, kind: FunctionKind::Async,
realm: context.realm().clone(), realm: context.realm().clone(),
@ -794,7 +793,6 @@ pub(crate) fn create_function_object(
code, code,
environments: context.vm.environments.clone(), environments: context.vm.environments.clone(),
home_object: None, home_object: None,
class_object: None,
script_or_module, script_or_module,
kind: FunctionKind::Ordinary { kind: FunctionKind::Ordinary {
constructor_kind: ConstructorKind::Base, constructor_kind: ConstructorKind::Base,
@ -871,7 +869,6 @@ pub(crate) fn create_function_object_fast(
let function = OrdinaryFunction { let function = OrdinaryFunction {
code, code,
environments: context.vm.environments.clone(), environments: context.vm.environments.clone(),
class_object: None,
script_or_module, script_or_module,
home_object: None, home_object: None,
kind, kind,
@ -965,7 +962,6 @@ pub(crate) fn create_generator_function_object(
code, code,
environments: context.vm.environments.clone(), environments: context.vm.environments.clone(),
home_object: None, home_object: None,
class_object: None,
script_or_module, script_or_module,
kind: FunctionKind::AsyncGenerator, kind: FunctionKind::AsyncGenerator,
realm: context.realm().clone(), realm: context.realm().clone(),
@ -980,7 +976,6 @@ pub(crate) fn create_generator_function_object(
code, code,
environments: context.vm.environments.clone(), environments: context.vm.environments.clone(),
home_object: None, home_object: None,
class_object: None,
script_or_module, script_or_module,
kind: FunctionKind::Generator, kind: FunctionKind::Generator,
realm: context.realm().clone(), realm: context.realm().clone(),
@ -1043,7 +1038,6 @@ impl JsObject {
let code = function.code.clone(); let code = function.code.clone();
let mut environments = function.environments.clone(); let mut environments = function.environments.clone();
let script_or_module = function.script_or_module.clone(); let script_or_module = function.script_or_module.clone();
let class_object = function.class_object.clone();
drop(object); drop(object);
@ -1069,18 +1063,6 @@ impl JsObject {
let mut last_env = code.compile_environments.len() - 1; let mut last_env = code.compile_environments.len() - 1;
if let Some(class_object) = class_object {
let index = context
.vm
.environments
.push_lexical(code.compile_environments[last_env].clone());
context
.vm
.environments
.put_lexical_value(index, 0, class_object.into());
last_env -= 1;
}
if code.has_binding_identifier() { if code.has_binding_identifier() {
let index = context let index = context
.vm .vm

4
boa_engine/src/vm/flowgraph/mod.rs

@ -357,7 +357,6 @@ impl CodeBlock {
| Instruction::PushClassPrototype | Instruction::PushClassPrototype
| Instruction::SetClassPrototype | Instruction::SetClassPrototype
| Instruction::SetHomeObject | Instruction::SetHomeObject
| Instruction::SetHomeObjectClass
| Instruction::Add | Instruction::Add
| Instruction::Sub | Instruction::Sub
| Instruction::Div | Instruction::Div
@ -522,7 +521,8 @@ impl CodeBlock {
| Instruction::Reserved54 | Instruction::Reserved54
| Instruction::Reserved55 | Instruction::Reserved55
| Instruction::Reserved56 | Instruction::Reserved56
| Instruction::Reserved57 => unreachable!("Reserved opcodes are unrechable"), | Instruction::Reserved57
| Instruction::Reserved58 => unreachable!("Reserved opcodes are unrechable"),
} }
} }

17
boa_engine/src/vm/opcode/define/class/getter.rs

@ -1,6 +1,5 @@
use crate::{ use crate::{
builtins::function::set_function_name, builtins::function::set_function_name,
object::CONSTRUCTOR,
property::PropertyDescriptor, property::PropertyDescriptor,
vm::{opcode::Operation, CompletionType}, vm::{opcode::Operation, CompletionType},
Context, JsResult, JsString, Context, JsResult, JsString,
@ -29,7 +28,6 @@ impl DefineClassStaticGetterByName {
.as_function_mut() .as_function_mut()
.expect("method must be function object"); .expect("method must be function object");
function_mut.set_home_object(class.clone()); function_mut.set_home_object(class.clone());
function_mut.set_class_object(class.clone());
} }
let set = class let set = class
.__get_own_property__(&key, context)? .__get_own_property__(&key, context)?
@ -93,13 +91,6 @@ impl DefineClassGetterByName {
.as_function_mut() .as_function_mut()
.expect("method must be function object"); .expect("method must be function object");
function_mut.set_home_object(class_proto.clone()); function_mut.set_home_object(class_proto.clone());
let class = class_proto
.get(CONSTRUCTOR, context)
.expect("class prototype must have constructor")
.as_object()
.expect("class must be object")
.clone();
function_mut.set_class_object(class);
} }
let set = class_proto let set = class_proto
.__get_own_property__(&key, context)? .__get_own_property__(&key, context)?
@ -169,7 +160,6 @@ impl Operation for DefineClassStaticGetterByValue {
.as_function_mut() .as_function_mut()
.expect("method must be function object"); .expect("method must be function object");
function_mut.set_home_object(class.clone()); function_mut.set_home_object(class.clone());
function_mut.set_class_object(class.clone());
} }
let set = class let set = class
.__get_own_property__(&key, context)? .__get_own_property__(&key, context)?
@ -219,13 +209,6 @@ impl Operation for DefineClassGetterByValue {
.as_function_mut() .as_function_mut()
.expect("method must be function object"); .expect("method must be function object");
function_mut.set_home_object(class_proto.clone()); function_mut.set_home_object(class_proto.clone());
let class = class_proto
.get(CONSTRUCTOR, context)
.expect("class prototype must have constructor")
.as_object()
.expect("class must be object")
.clone();
function_mut.set_class_object(class);
} }
let set = class_proto let set = class_proto
.__get_own_property__(&key, context)? .__get_own_property__(&key, context)?

17
boa_engine/src/vm/opcode/define/class/method.rs

@ -1,6 +1,5 @@
use crate::{ use crate::{
builtins::function::set_function_name, builtins::function::set_function_name,
object::CONSTRUCTOR,
property::PropertyDescriptor, property::PropertyDescriptor,
vm::{opcode::Operation, CompletionType}, vm::{opcode::Operation, CompletionType},
Context, JsResult, Context, JsResult,
@ -29,7 +28,6 @@ impl DefineClassStaticMethodByName {
.as_function_mut() .as_function_mut()
.expect("method must be function object"); .expect("method must be function object");
function_mut.set_home_object(class.clone()); function_mut.set_home_object(class.clone());
function_mut.set_class_object(class.clone());
} }
class.__define_own_property__( class.__define_own_property__(
@ -89,13 +87,6 @@ impl DefineClassMethodByName {
.as_function_mut() .as_function_mut()
.expect("method must be function object"); .expect("method must be function object");
function_mut.set_home_object(class_proto.clone()); function_mut.set_home_object(class_proto.clone());
let class = class_proto
.get(CONSTRUCTOR, context)
.expect("class prototype must have constructor")
.as_object()
.expect("class must be object")
.clone();
function_mut.set_class_object(class);
} }
class_proto.__define_own_property__( class_proto.__define_own_property__(
@ -161,7 +152,6 @@ impl Operation for DefineClassStaticMethodByValue {
.as_function_mut() .as_function_mut()
.expect("method must be function object"); .expect("method must be function object");
function_mut.set_home_object(class.clone()); function_mut.set_home_object(class.clone());
function_mut.set_class_object(class.clone());
} }
class.define_property_or_throw( class.define_property_or_throw(
@ -207,13 +197,6 @@ impl Operation for DefineClassMethodByValue {
.as_function_mut() .as_function_mut()
.expect("method must be function object"); .expect("method must be function object");
function_mut.set_home_object(class_proto.clone()); function_mut.set_home_object(class_proto.clone());
let class = class_proto
.get(CONSTRUCTOR, context)
.expect("class prototype must have constructor")
.as_object()
.expect("class must be object")
.clone();
function_mut.set_class_object(class);
} }
class_proto.__define_own_property__( class_proto.__define_own_property__(

17
boa_engine/src/vm/opcode/define/class/setter.rs

@ -1,6 +1,5 @@
use crate::{ use crate::{
builtins::function::set_function_name, builtins::function::set_function_name,
object::CONSTRUCTOR,
property::PropertyDescriptor, property::PropertyDescriptor,
vm::{opcode::Operation, CompletionType}, vm::{opcode::Operation, CompletionType},
Context, JsResult, JsString, Context, JsResult, JsString,
@ -29,7 +28,6 @@ impl DefineClassStaticSetterByName {
.as_function_mut() .as_function_mut()
.expect("method must be function object"); .expect("method must be function object");
function_mut.set_home_object(class.clone()); function_mut.set_home_object(class.clone());
function_mut.set_class_object(class.clone());
} }
let get = class let get = class
.__get_own_property__(&key, context)? .__get_own_property__(&key, context)?
@ -94,13 +92,6 @@ impl DefineClassSetterByName {
.as_function_mut() .as_function_mut()
.expect("method must be function object"); .expect("method must be function object");
function_mut.set_home_object(class_proto.clone()); function_mut.set_home_object(class_proto.clone());
let class = class_proto
.get(CONSTRUCTOR, context)
.expect("class prototype must have constructor")
.as_object()
.expect("class must be object")
.clone();
function_mut.set_class_object(class);
} }
let get = class_proto let get = class_proto
.__get_own_property__(&key, context)? .__get_own_property__(&key, context)?
@ -172,7 +163,6 @@ impl Operation for DefineClassStaticSetterByValue {
.as_function_mut() .as_function_mut()
.expect("method must be function object"); .expect("method must be function object");
function_mut.set_home_object(class.clone()); function_mut.set_home_object(class.clone());
function_mut.set_class_object(class.clone());
} }
let get = class let get = class
.__get_own_property__(&key, context)? .__get_own_property__(&key, context)?
@ -224,13 +214,6 @@ impl Operation for DefineClassSetterByValue {
.as_function_mut() .as_function_mut()
.expect("method must be function object"); .expect("method must be function object");
function_mut.set_home_object(class_proto.clone()); function_mut.set_home_object(class_proto.clone());
let class = class_proto
.get(CONSTRUCTOR, context)
.expect("class prototype must have constructor")
.as_object()
.expect("class must be object")
.clone();
function_mut.set_class_object(class);
} }
let get = class_proto let get = class_proto
.__get_own_property__(&key, context)? .__get_own_property__(&key, context)?

9
boa_engine/src/vm/opcode/mod.rs

@ -736,13 +736,6 @@ generate_opcodes! {
/// Stack: home, function **=>** home, function /// Stack: home, function **=>** home, function
SetHomeObject, SetHomeObject,
/// Set home object internal slot of a class method.
///
/// Operands:
///
/// Stack: home, function **=>** home, function
SetHomeObjectClass,
/// Set the prototype of an object if the value is an object or null. /// Set the prototype of an object if the value is an object or null.
/// ///
/// Operands: /// Operands:
@ -2178,6 +2171,8 @@ generate_opcodes! {
Reserved56 => Reserved, Reserved56 => Reserved,
/// Reserved [`Opcode`]. /// Reserved [`Opcode`].
Reserved57 => Reserved, Reserved57 => Reserved,
/// Reserved [`Opcode`].
Reserved58 => Reserved,
} }
/// Specific opcodes for bindings. /// Specific opcodes for bindings.

2
boa_engine/src/vm/opcode/push/class/field.rs

@ -32,7 +32,6 @@ impl Operation for PushClassField {
.as_object() .as_object()
.expect("class must be function object"); .expect("class must be function object");
field_function.set_home_object(class_object.clone()); field_function.set_home_object(class_object.clone());
field_function.set_class_object(class_object.clone());
class_object class_object
.borrow_mut() .borrow_mut()
.as_function_mut() .as_function_mut()
@ -70,7 +69,6 @@ impl PushClassFieldPrivate {
.as_object() .as_object()
.expect("class must be function object"); .expect("class must be function object");
field_function.set_home_object(class_object.clone()); field_function.set_home_object(class_object.clone());
field_function.set_class_object(class_object.clone());
class_object class_object
.borrow_mut() .borrow_mut()

17
boa_engine/src/vm/opcode/push/class/private.rs

@ -44,11 +44,6 @@ impl PushClassPrivateMethod {
PrivateElement::Method(method_object.clone()), PrivateElement::Method(method_object.clone()),
); );
let mut method_object_mut = method_object.borrow_mut();
let function = method_object_mut
.as_function_mut()
.expect("method must be function object");
function.set_class_object(class_object.clone());
Ok(CompletionType::Normal) Ok(CompletionType::Normal)
} }
} }
@ -100,11 +95,7 @@ impl PushClassPrivateGetter {
setter: None, setter: None,
}, },
); );
let mut getter_object_mut = getter_object.borrow_mut();
let function = getter_object_mut
.as_function_mut()
.expect("getter must be function object");
function.set_class_object(class_object.clone());
Ok(CompletionType::Normal) Ok(CompletionType::Normal)
} }
} }
@ -156,11 +147,7 @@ impl PushClassPrivateSetter {
setter: Some(setter_object.clone()), setter: Some(setter_object.clone()),
}, },
); );
let mut setter_object_mut = setter_object.borrow_mut();
let function = setter_object_mut
.as_function_mut()
.expect("setter must be function object");
function.set_class_object(class_object.clone());
Ok(CompletionType::Normal) Ok(CompletionType::Normal)
} }
} }

32
boa_engine/src/vm/opcode/set/home_object.rs

@ -33,35 +33,3 @@ impl Operation for SetHomeObject {
Ok(CompletionType::Normal) Ok(CompletionType::Normal)
} }
} }
/// `SetHomeObjectClass` implements the Opcode Operation for `Opcode::SetHomeObjectClass`
///
/// Operation:
/// - Set home object internal slot of a function object.
#[derive(Debug, Clone, Copy)]
pub(crate) struct SetHomeObjectClass;
impl Operation for SetHomeObjectClass {
const NAME: &'static str = "SetHomeObjectClass";
const INSTRUCTION: &'static str = "INST - SetHomeObjectClass";
fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> {
let function = context.vm.pop();
let home = context.vm.pop();
{
let function_object = function.as_object().expect("must be object");
let home_object = home.as_object().expect("must be object");
let mut function_object_mut = function_object.borrow_mut();
let function_mut = function_object_mut
.as_function_mut()
.expect("must be function object");
function_mut.set_home_object(home_object.clone());
function_mut.set_class_object(home_object.clone());
}
context.vm.push(home);
context.vm.push(function);
Ok(CompletionType::Normal)
}
}

15
boa_engine/src/vm/opcode/set/private.rs

@ -132,11 +132,6 @@ impl SetPrivateMethod {
object.private_name(name), object.private_name(name),
PrivateElement::Method(value.clone()), PrivateElement::Method(value.clone()),
); );
let mut value_mut = value.borrow_mut();
let function = value_mut
.as_function_mut()
.expect("method must be a function");
function.set_class_object(object.clone());
Ok(CompletionType::Normal) Ok(CompletionType::Normal)
} }
@ -187,11 +182,6 @@ impl SetPrivateSetter {
setter: Some(value.clone()), setter: Some(value.clone()),
}, },
); );
let mut value_mut = value.borrow_mut();
let function = value_mut
.as_function_mut()
.expect("method must be a function");
function.set_class_object(object.clone());
Ok(CompletionType::Normal) Ok(CompletionType::Normal)
} }
@ -242,11 +232,6 @@ impl SetPrivateGetter {
setter: None, setter: None,
}, },
); );
let mut value_mut = value.borrow_mut();
let function = value_mut
.as_function_mut()
.expect("method must be a function");
function.set_class_object(object.clone());
Ok(CompletionType::Normal) Ok(CompletionType::Normal)
} }

Loading…
Cancel
Save