diff --git a/boa_engine/src/bytecompiler/class.rs b/boa_engine/src/bytecompiler/class.rs index ecee3e966b3..60bb3e26551 100644 --- a/boa_engine/src/bytecompiler/class.rs +++ b/boa_engine/src/bytecompiler/class.rs @@ -1,4 +1,4 @@ -use super::{ByteCompiler, Literal, NodeKind}; +use super::{ByteCompiler, Literal}; use crate::vm::{BindingOpcode, Opcode}; use boa_ast::{ expression::Identifier, @@ -108,79 +108,79 @@ impl ByteCompiler<'_, '_> { match method_definition { MethodDefinition::Get(expr) => match name { PropertyName::Literal(name) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_name((*name).into()); self.emit(Opcode::DefineClassStaticGetterByName, &[index]); } PropertyName::Computed(name_node) => { self.compile_expr(name_node, true); self.emit_opcode(Opcode::ToPropertyKey); - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); self.emit_opcode(Opcode::DefineClassStaticGetterByValue); } }, MethodDefinition::Set(expr) => match name { PropertyName::Literal(name) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_name((*name).into()); self.emit(Opcode::DefineClassStaticSetterByName, &[index]); } PropertyName::Computed(name_node) => { self.compile_expr(name_node, true); self.emit_opcode(Opcode::ToPropertyKey); - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); self.emit_opcode(Opcode::DefineClassStaticSetterByValue); } }, MethodDefinition::Ordinary(expr) => match name { PropertyName::Literal(name) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_name((*name).into()); self.emit(Opcode::DefineClassStaticMethodByName, &[index]); } PropertyName::Computed(name_node) => { self.compile_expr(name_node, true); self.emit_opcode(Opcode::ToPropertyKey); - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); self.emit_opcode(Opcode::DefineClassStaticMethodByValue); } }, MethodDefinition::Async(expr) => match name { PropertyName::Literal(name) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_name((*name).into()); self.emit(Opcode::DefineClassStaticMethodByName, &[index]); } PropertyName::Computed(name_node) => { self.compile_expr(name_node, true); self.emit_opcode(Opcode::ToPropertyKey); - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); self.emit_opcode(Opcode::DefineClassStaticMethodByValue); } }, MethodDefinition::Generator(expr) => match name { PropertyName::Literal(name) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_name((*name).into()); self.emit(Opcode::DefineClassStaticMethodByName, &[index]); } PropertyName::Computed(name_node) => { self.compile_expr(name_node, true); self.emit_opcode(Opcode::ToPropertyKey); - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); self.emit_opcode(Opcode::DefineClassStaticMethodByValue); } }, MethodDefinition::AsyncGenerator(expr) => match name { PropertyName::Literal(name) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_name((*name).into()); self.emit(Opcode::DefineClassStaticMethodByName, &[index]); } PropertyName::Computed(name_node) => { self.compile_expr(name_node, true); self.emit_opcode(Opcode::ToPropertyKey); - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); self.emit_opcode(Opcode::DefineClassStaticMethodByValue); } }, @@ -191,32 +191,32 @@ impl ByteCompiler<'_, '_> { self.emit_opcode(Opcode::Dup); match method_definition { MethodDefinition::Get(expr) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_private_name(*name); self.emit(Opcode::SetPrivateGetter, &[index]); } MethodDefinition::Set(expr) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_private_name(*name); self.emit(Opcode::SetPrivateSetter, &[index]); } MethodDefinition::Ordinary(expr) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_private_name(*name); self.emit(Opcode::SetPrivateMethod, &[index]); } MethodDefinition::Async(expr) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_private_name(*name); self.emit(Opcode::SetPrivateMethod, &[index]); } MethodDefinition::Generator(expr) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_private_name(*name); self.emit(Opcode::SetPrivateMethod, &[index]); } MethodDefinition::AsyncGenerator(expr) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_private_name(*name); self.emit(Opcode::SetPrivateMethod, &[index]); } @@ -393,32 +393,32 @@ impl ByteCompiler<'_, '_> { self.emit_opcode(Opcode::Dup); match method_definition { MethodDefinition::Get(expr) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_private_name(*name); self.emit(Opcode::PushClassPrivateGetter, &[index]); } MethodDefinition::Set(expr) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_private_name(*name); self.emit(Opcode::PushClassPrivateSetter, &[index]); } MethodDefinition::Ordinary(expr) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_private_name(*name); self.emit(Opcode::PushClassPrivateMethod, &[index]); } MethodDefinition::Async(expr) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_private_name(*name); self.emit(Opcode::PushClassPrivateMethod, &[index]); } MethodDefinition::Generator(expr) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_private_name(*name); self.emit(Opcode::PushClassPrivateMethod, &[index]); } MethodDefinition::AsyncGenerator(expr) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_private_name(*name); self.emit(Opcode::PushClassPrivateMethod, &[index]); } @@ -438,79 +438,79 @@ impl ByteCompiler<'_, '_> { match method_definition { MethodDefinition::Get(expr) => match name { PropertyName::Literal(name) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_name((*name).into()); self.emit(Opcode::DefineClassGetterByName, &[index]); } PropertyName::Computed(name_node) => { self.compile_expr(name_node, true); self.emit_opcode(Opcode::ToPropertyKey); - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); self.emit_opcode(Opcode::DefineClassGetterByValue); } }, MethodDefinition::Set(expr) => match name { PropertyName::Literal(name) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_name((*name).into()); self.emit(Opcode::DefineClassSetterByName, &[index]); } PropertyName::Computed(name_node) => { self.compile_expr(name_node, true); self.emit_opcode(Opcode::ToPropertyKey); - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); self.emit_opcode(Opcode::DefineClassSetterByValue); } }, MethodDefinition::Ordinary(expr) => match name { PropertyName::Literal(name) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_name((*name).into()); self.emit(Opcode::DefineClassMethodByName, &[index]); } PropertyName::Computed(name_node) => { self.compile_expr(name_node, true); self.emit_opcode(Opcode::ToPropertyKey); - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); self.emit_opcode(Opcode::DefineClassMethodByValue); } }, MethodDefinition::Async(expr) => match name { PropertyName::Literal(name) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_name((*name).into()); self.emit(Opcode::DefineClassMethodByName, &[index]); } PropertyName::Computed(name_node) => { self.compile_expr(name_node, true); self.emit_opcode(Opcode::ToPropertyKey); - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); self.emit_opcode(Opcode::DefineClassMethodByValue); } }, MethodDefinition::Generator(expr) => match name { PropertyName::Literal(name) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_name((*name).into()); self.emit(Opcode::DefineClassMethodByName, &[index]); } PropertyName::Computed(name_node) => { self.compile_expr(name_node, true); self.emit_opcode(Opcode::ToPropertyKey); - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); self.emit_opcode(Opcode::DefineClassMethodByValue); } }, MethodDefinition::AsyncGenerator(expr) => match name { PropertyName::Literal(name) => { - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); let index = self.get_or_insert_name((*name).into()); self.emit(Opcode::DefineClassMethodByName, &[index]); } PropertyName::Computed(name_node) => { self.compile_expr(name_node, true); self.emit_opcode(Opcode::ToPropertyKey); - self.method(expr.into(), NodeKind::Expression, class_name, true); + self.method(expr.into(), class_name); self.emit_opcode(Opcode::DefineClassMethodByValue); } }, diff --git a/boa_engine/src/bytecompiler/expression/object_literal.rs b/boa_engine/src/bytecompiler/expression/object_literal.rs index 260c409ce3f..29add1a056f 100644 --- a/boa_engine/src/bytecompiler/expression/object_literal.rs +++ b/boa_engine/src/bytecompiler/expression/object_literal.rs @@ -1,5 +1,5 @@ use crate::{ - bytecompiler::{Access, ByteCompiler, NodeKind}, + bytecompiler::{Access, ByteCompiler}, vm::Opcode, }; use boa_ast::{ @@ -46,7 +46,7 @@ impl ByteCompiler<'_, '_> { PropertyDefinition::MethodDefinition(name, kind) => match kind { MethodDefinition::Get(expr) => match name { PropertyName::Literal(name) => { - self.object_method(expr.into(), NodeKind::Expression, true); + self.object_method(expr.into()); let index = self.get_or_insert_name((*name).into()); self.emit(Opcode::SetPropertyGetterByName, &[index]); } @@ -54,7 +54,7 @@ impl ByteCompiler<'_, '_> { self.compile_expr(name_node, true); self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::Dup); - self.object_method(expr.into(), NodeKind::Expression, true); + self.object_method(expr.into()); self.emit_opcode(Opcode::SetFunctionName); self.emit_u8(1); self.emit_opcode(Opcode::SetPropertyGetterByValue); @@ -62,7 +62,7 @@ impl ByteCompiler<'_, '_> { }, MethodDefinition::Set(expr) => match name { PropertyName::Literal(name) => { - self.object_method(expr.into(), NodeKind::Expression, true); + self.object_method(expr.into()); let index = self.get_or_insert_name((*name).into()); self.emit(Opcode::SetPropertySetterByName, &[index]); } @@ -70,7 +70,7 @@ impl ByteCompiler<'_, '_> { self.compile_expr(name_node, true); self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::Dup); - self.object_method(expr.into(), NodeKind::Expression, true); + self.object_method(expr.into()); self.emit_opcode(Opcode::SetFunctionName); self.emit_u8(2); self.emit_opcode(Opcode::SetPropertySetterByValue); @@ -78,7 +78,7 @@ impl ByteCompiler<'_, '_> { }, MethodDefinition::Ordinary(expr) => match name { PropertyName::Literal(name) => { - self.object_method(expr.into(), NodeKind::Expression, true); + self.object_method(expr.into()); let index = self.get_or_insert_name((*name).into()); self.emit(Opcode::DefineOwnPropertyByName, &[index]); } @@ -86,7 +86,7 @@ impl ByteCompiler<'_, '_> { self.compile_expr(name_node, true); self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::Dup); - self.object_method(expr.into(), NodeKind::Expression, true); + self.object_method(expr.into()); self.emit_opcode(Opcode::SetFunctionName); self.emit_u8(0); self.emit_opcode(Opcode::DefineOwnPropertyByValue); @@ -94,7 +94,7 @@ impl ByteCompiler<'_, '_> { }, MethodDefinition::Async(expr) => match name { PropertyName::Literal(name) => { - self.object_method(expr.into(), NodeKind::Expression, true); + self.object_method(expr.into()); let index = self.get_or_insert_name((*name).into()); self.emit(Opcode::DefineOwnPropertyByName, &[index]); } @@ -102,7 +102,7 @@ impl ByteCompiler<'_, '_> { self.compile_expr(name_node, true); self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::Dup); - self.object_method(expr.into(), NodeKind::Expression, true); + self.object_method(expr.into()); self.emit_opcode(Opcode::SetFunctionName); self.emit_u8(0); self.emit_opcode(Opcode::DefineOwnPropertyByValue); @@ -110,7 +110,7 @@ impl ByteCompiler<'_, '_> { }, MethodDefinition::Generator(expr) => match name { PropertyName::Literal(name) => { - self.object_method(expr.into(), NodeKind::Expression, true); + self.object_method(expr.into()); let index = self.get_or_insert_name((*name).into()); self.emit(Opcode::DefineOwnPropertyByName, &[index]); } @@ -118,7 +118,7 @@ impl ByteCompiler<'_, '_> { self.compile_expr(name_node, true); self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::Dup); - self.object_method(expr.into(), NodeKind::Expression, true); + self.object_method(expr.into()); self.emit_opcode(Opcode::SetFunctionName); self.emit_u8(0); self.emit_opcode(Opcode::DefineOwnPropertyByValue); @@ -126,7 +126,7 @@ impl ByteCompiler<'_, '_> { }, MethodDefinition::AsyncGenerator(expr) => match name { PropertyName::Literal(name) => { - self.object_method(expr.into(), NodeKind::Expression, true); + self.object_method(expr.into()); let index = self.get_or_insert_name((*name).into()); self.emit(Opcode::DefineOwnPropertyByName, &[index]); } @@ -134,7 +134,7 @@ impl ByteCompiler<'_, '_> { self.compile_expr(name_node, true); self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::Dup); - self.object_method(expr.into(), NodeKind::Expression, true); + self.object_method(expr.into()); self.emit_opcode(Opcode::SetFunctionName); self.emit_u8(0); self.emit_opcode(Opcode::DefineOwnPropertyByValue); diff --git a/boa_engine/src/bytecompiler/function.rs b/boa_engine/src/bytecompiler/function.rs index 1a503554eaf..92cdd5eaeb7 100644 --- a/boa_engine/src/bytecompiler/function.rs +++ b/boa_engine/src/bytecompiler/function.rs @@ -150,9 +150,15 @@ impl FunctionCompiler { compiler.params = parameters.clone(); - // TODO These are redundant if a function returns so may need to check if a function returns and adding these if it doesn't - compiler.emit(Opcode::PushUndefined, &[]); - compiler.emit(Opcode::Return, &[]); + if compiler + .bytecode + .last() + .filter(|last| **last == Opcode::Return as u8) + .is_none() + { + compiler.emit_opcode(Opcode::PushUndefined); + compiler.emit_opcode(Opcode::Return); + } Gc::new(compiler.finish()) } diff --git a/boa_engine/src/bytecompiler/mod.rs b/boa_engine/src/bytecompiler/mod.rs index bf95902c5cb..1d451fd8a55 100644 --- a/boa_engine/src/bytecompiler/mod.rs +++ b/boa_engine/src/bytecompiler/mod.rs @@ -1150,12 +1150,7 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> { } /// Compile an object method AST Node into bytecode. - pub(crate) fn object_method( - &mut self, - function: FunctionSpec<'_>, - node_kind: NodeKind, - use_expr: bool, - ) { + pub(crate) fn object_method(&mut self, function: FunctionSpec<'_>) { let (generator, r#async, arrow) = ( function.is_generator(), function.is_async(), @@ -1212,30 +1207,10 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> { if !generator { self.emit_u8(1); } - - match node_kind { - NodeKind::Declaration => { - self.emit_binding( - BindingOpcode::InitVar, - name.expect("function declaration must have a name"), - ); - } - NodeKind::Expression => { - if !use_expr { - self.emit(Opcode::Pop, &[]); - } - } - } } /// Compile a class method AST Node into bytecode. - fn method( - &mut self, - function: FunctionSpec<'_>, - node_kind: NodeKind, - class_name: Sym, - use_expr: bool, - ) { + fn method(&mut self, function: FunctionSpec<'_>, class_name: Sym) { let (generator, r#async, arrow) = ( function.is_generator(), function.is_async(), @@ -1293,20 +1268,6 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> { if !generator { self.emit_u8(1); } - - match node_kind { - NodeKind::Declaration => { - self.emit_binding( - BindingOpcode::InitVar, - name.expect("function declaration must have a name"), - ); - } - NodeKind::Expression => { - if !use_expr { - self.emit(Opcode::Pop, &[]); - } - } - } } fn call(&mut self, callable: Callable<'_>, use_expr: bool) { diff --git a/boa_engine/src/bytecompiler/statement/try.rs b/boa_engine/src/bytecompiler/statement/try.rs index 51e2aa12050..209cec32b49 100644 --- a/boa_engine/src/bytecompiler/statement/try.rs +++ b/boa_engine/src/bytecompiler/statement/try.rs @@ -5,7 +5,7 @@ use crate::{ use boa_ast::{ declaration::Binding, operations::bound_names, - statement::{Finally, Try}, + statement::{Catch, Finally, Try}, }; impl ByteCompiler<'_, '_> { @@ -33,8 +33,8 @@ impl ByteCompiler<'_, '_> { let finally = self.jump(); self.patch_jump(catch_start); - if t.catch().is_some() { - self.compile_catch_stmt(t, use_expr); + if let Some(catch) = t.catch() { + self.compile_catch_stmt(catch, t.finally().is_some(), use_expr); } self.patch_jump(finally); @@ -55,10 +55,7 @@ impl ByteCompiler<'_, '_> { } } - pub(crate) fn compile_catch_stmt(&mut self, parent_try: &Try, use_expr: bool) { - let catch = parent_try - .catch() - .expect("Catch must exist for compile_catch_stmt to have been invoked"); + pub(crate) fn compile_catch_stmt(&mut self, catch: &Catch, finally: bool, use_expr: bool) { self.set_jump_control_in_catch(true); let catch_end = self.emit_opcode_with_operand(Opcode::CatchStart); @@ -95,7 +92,7 @@ impl ByteCompiler<'_, '_> { self.patch_jump_with_target(push_env.1, env_info.index as u32); self.emit_opcode(Opcode::PopEnvironment); - if parent_try.finally().is_some() { + if finally { self.emit_opcode(Opcode::CatchEnd); } else { self.emit_opcode(Opcode::CatchEnd2);