Browse Source

Cleanup some bytecompiler code (#2918)

pull/2919/head
raskad 2 years ago committed by GitHub
parent
commit
2faa2470db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 74
      boa_engine/src/bytecompiler/class.rs
  2. 26
      boa_engine/src/bytecompiler/expression/object_literal.rs
  3. 12
      boa_engine/src/bytecompiler/function.rs
  4. 43
      boa_engine/src/bytecompiler/mod.rs
  5. 13
      boa_engine/src/bytecompiler/statement/try.rs

74
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 crate::vm::{BindingOpcode, Opcode};
use boa_ast::{ use boa_ast::{
expression::Identifier, expression::Identifier,
@ -108,79 +108,79 @@ 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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit(Opcode::DefineClassStaticGetterByName, &[index]); self.emit(Opcode::DefineClassStaticGetterByName, &[index]);
} }
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit(Opcode::DefineClassStaticSetterByName, &[index]); self.emit(Opcode::DefineClassStaticSetterByName, &[index]);
} }
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit(Opcode::DefineClassStaticMethodByName, &[index]); self.emit(Opcode::DefineClassStaticMethodByName, &[index]);
} }
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit(Opcode::DefineClassStaticMethodByName, &[index]); self.emit(Opcode::DefineClassStaticMethodByName, &[index]);
} }
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit(Opcode::DefineClassStaticMethodByName, &[index]); self.emit(Opcode::DefineClassStaticMethodByName, &[index]);
} }
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit(Opcode::DefineClassStaticMethodByName, &[index]); self.emit(Opcode::DefineClassStaticMethodByName, &[index]);
} }
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
self.emit_opcode(Opcode::DefineClassStaticMethodByValue); self.emit_opcode(Opcode::DefineClassStaticMethodByValue);
} }
}, },
@ -191,32 +191,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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
let index = self.get_or_insert_private_name(*name); let index = self.get_or_insert_private_name(*name);
self.emit(Opcode::SetPrivateGetter, &[index]); self.emit(Opcode::SetPrivateGetter, &[index]);
} }
MethodDefinition::Set(expr) => { 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); let index = self.get_or_insert_private_name(*name);
self.emit(Opcode::SetPrivateSetter, &[index]); self.emit(Opcode::SetPrivateSetter, &[index]);
} }
MethodDefinition::Ordinary(expr) => { 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); let index = self.get_or_insert_private_name(*name);
self.emit(Opcode::SetPrivateMethod, &[index]); self.emit(Opcode::SetPrivateMethod, &[index]);
} }
MethodDefinition::Async(expr) => { 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); let index = self.get_or_insert_private_name(*name);
self.emit(Opcode::SetPrivateMethod, &[index]); self.emit(Opcode::SetPrivateMethod, &[index]);
} }
MethodDefinition::Generator(expr) => { 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); let index = self.get_or_insert_private_name(*name);
self.emit(Opcode::SetPrivateMethod, &[index]); self.emit(Opcode::SetPrivateMethod, &[index]);
} }
MethodDefinition::AsyncGenerator(expr) => { 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); let index = self.get_or_insert_private_name(*name);
self.emit(Opcode::SetPrivateMethod, &[index]); self.emit(Opcode::SetPrivateMethod, &[index]);
} }
@ -393,32 +393,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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
let index = self.get_or_insert_private_name(*name); let index = self.get_or_insert_private_name(*name);
self.emit(Opcode::PushClassPrivateGetter, &[index]); self.emit(Opcode::PushClassPrivateGetter, &[index]);
} }
MethodDefinition::Set(expr) => { 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); let index = self.get_or_insert_private_name(*name);
self.emit(Opcode::PushClassPrivateSetter, &[index]); self.emit(Opcode::PushClassPrivateSetter, &[index]);
} }
MethodDefinition::Ordinary(expr) => { 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); let index = self.get_or_insert_private_name(*name);
self.emit(Opcode::PushClassPrivateMethod, &[index]); self.emit(Opcode::PushClassPrivateMethod, &[index]);
} }
MethodDefinition::Async(expr) => { 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); let index = self.get_or_insert_private_name(*name);
self.emit(Opcode::PushClassPrivateMethod, &[index]); self.emit(Opcode::PushClassPrivateMethod, &[index]);
} }
MethodDefinition::Generator(expr) => { 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); let index = self.get_or_insert_private_name(*name);
self.emit(Opcode::PushClassPrivateMethod, &[index]); self.emit(Opcode::PushClassPrivateMethod, &[index]);
} }
MethodDefinition::AsyncGenerator(expr) => { 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); let index = self.get_or_insert_private_name(*name);
self.emit(Opcode::PushClassPrivateMethod, &[index]); self.emit(Opcode::PushClassPrivateMethod, &[index]);
} }
@ -438,79 +438,79 @@ 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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit(Opcode::DefineClassGetterByName, &[index]); self.emit(Opcode::DefineClassGetterByName, &[index]);
} }
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit(Opcode::DefineClassSetterByName, &[index]); self.emit(Opcode::DefineClassSetterByName, &[index]);
} }
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit(Opcode::DefineClassMethodByName, &[index]); self.emit(Opcode::DefineClassMethodByName, &[index]);
} }
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit(Opcode::DefineClassMethodByName, &[index]); self.emit(Opcode::DefineClassMethodByName, &[index]);
} }
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit(Opcode::DefineClassMethodByName, &[index]); self.emit(Opcode::DefineClassMethodByName, &[index]);
} }
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
let index = self.get_or_insert_name((*name).into()); let index = self.get_or_insert_name((*name).into());
self.emit(Opcode::DefineClassMethodByName, &[index]); self.emit(Opcode::DefineClassMethodByName, &[index]);
} }
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(), NodeKind::Expression, class_name, true); self.method(expr.into(), class_name);
self.emit_opcode(Opcode::DefineClassMethodByValue); self.emit_opcode(Opcode::DefineClassMethodByValue);
} }
}, },

26
boa_engine/src/bytecompiler/expression/object_literal.rs

@ -1,5 +1,5 @@
use crate::{ use crate::{
bytecompiler::{Access, ByteCompiler, NodeKind}, bytecompiler::{Access, ByteCompiler},
vm::Opcode, vm::Opcode,
}; };
use boa_ast::{ use boa_ast::{
@ -46,7 +46,7 @@ impl ByteCompiler<'_, '_> {
PropertyDefinition::MethodDefinition(name, kind) => match kind { PropertyDefinition::MethodDefinition(name, kind) => match kind {
MethodDefinition::Get(expr) => match name { MethodDefinition::Get(expr) => match name {
PropertyName::Literal(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()); let index = self.get_or_insert_name((*name).into());
self.emit(Opcode::SetPropertyGetterByName, &[index]); self.emit(Opcode::SetPropertyGetterByName, &[index]);
} }
@ -54,7 +54,7 @@ impl ByteCompiler<'_, '_> {
self.compile_expr(name_node, true); self.compile_expr(name_node, true);
self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::ToPropertyKey);
self.emit_opcode(Opcode::Dup); 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_opcode(Opcode::SetFunctionName);
self.emit_u8(1); self.emit_u8(1);
self.emit_opcode(Opcode::SetPropertyGetterByValue); self.emit_opcode(Opcode::SetPropertyGetterByValue);
@ -62,7 +62,7 @@ impl ByteCompiler<'_, '_> {
}, },
MethodDefinition::Set(expr) => match name { MethodDefinition::Set(expr) => match name {
PropertyName::Literal(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()); let index = self.get_or_insert_name((*name).into());
self.emit(Opcode::SetPropertySetterByName, &[index]); self.emit(Opcode::SetPropertySetterByName, &[index]);
} }
@ -70,7 +70,7 @@ impl ByteCompiler<'_, '_> {
self.compile_expr(name_node, true); self.compile_expr(name_node, true);
self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::ToPropertyKey);
self.emit_opcode(Opcode::Dup); 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_opcode(Opcode::SetFunctionName);
self.emit_u8(2); self.emit_u8(2);
self.emit_opcode(Opcode::SetPropertySetterByValue); self.emit_opcode(Opcode::SetPropertySetterByValue);
@ -78,7 +78,7 @@ impl ByteCompiler<'_, '_> {
}, },
MethodDefinition::Ordinary(expr) => match name { MethodDefinition::Ordinary(expr) => match name {
PropertyName::Literal(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()); let index = self.get_or_insert_name((*name).into());
self.emit(Opcode::DefineOwnPropertyByName, &[index]); self.emit(Opcode::DefineOwnPropertyByName, &[index]);
} }
@ -86,7 +86,7 @@ impl ByteCompiler<'_, '_> {
self.compile_expr(name_node, true); self.compile_expr(name_node, true);
self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::ToPropertyKey);
self.emit_opcode(Opcode::Dup); 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_opcode(Opcode::SetFunctionName);
self.emit_u8(0); self.emit_u8(0);
self.emit_opcode(Opcode::DefineOwnPropertyByValue); self.emit_opcode(Opcode::DefineOwnPropertyByValue);
@ -94,7 +94,7 @@ impl ByteCompiler<'_, '_> {
}, },
MethodDefinition::Async(expr) => match name { MethodDefinition::Async(expr) => match name {
PropertyName::Literal(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()); let index = self.get_or_insert_name((*name).into());
self.emit(Opcode::DefineOwnPropertyByName, &[index]); self.emit(Opcode::DefineOwnPropertyByName, &[index]);
} }
@ -102,7 +102,7 @@ impl ByteCompiler<'_, '_> {
self.compile_expr(name_node, true); self.compile_expr(name_node, true);
self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::ToPropertyKey);
self.emit_opcode(Opcode::Dup); 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_opcode(Opcode::SetFunctionName);
self.emit_u8(0); self.emit_u8(0);
self.emit_opcode(Opcode::DefineOwnPropertyByValue); self.emit_opcode(Opcode::DefineOwnPropertyByValue);
@ -110,7 +110,7 @@ impl ByteCompiler<'_, '_> {
}, },
MethodDefinition::Generator(expr) => match name { MethodDefinition::Generator(expr) => match name {
PropertyName::Literal(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()); let index = self.get_or_insert_name((*name).into());
self.emit(Opcode::DefineOwnPropertyByName, &[index]); self.emit(Opcode::DefineOwnPropertyByName, &[index]);
} }
@ -118,7 +118,7 @@ impl ByteCompiler<'_, '_> {
self.compile_expr(name_node, true); self.compile_expr(name_node, true);
self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::ToPropertyKey);
self.emit_opcode(Opcode::Dup); 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_opcode(Opcode::SetFunctionName);
self.emit_u8(0); self.emit_u8(0);
self.emit_opcode(Opcode::DefineOwnPropertyByValue); self.emit_opcode(Opcode::DefineOwnPropertyByValue);
@ -126,7 +126,7 @@ impl ByteCompiler<'_, '_> {
}, },
MethodDefinition::AsyncGenerator(expr) => match name { MethodDefinition::AsyncGenerator(expr) => match name {
PropertyName::Literal(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()); let index = self.get_or_insert_name((*name).into());
self.emit(Opcode::DefineOwnPropertyByName, &[index]); self.emit(Opcode::DefineOwnPropertyByName, &[index]);
} }
@ -134,7 +134,7 @@ impl ByteCompiler<'_, '_> {
self.compile_expr(name_node, true); self.compile_expr(name_node, true);
self.emit_opcode(Opcode::ToPropertyKey); self.emit_opcode(Opcode::ToPropertyKey);
self.emit_opcode(Opcode::Dup); 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_opcode(Opcode::SetFunctionName);
self.emit_u8(0); self.emit_u8(0);
self.emit_opcode(Opcode::DefineOwnPropertyByValue); self.emit_opcode(Opcode::DefineOwnPropertyByValue);

12
boa_engine/src/bytecompiler/function.rs

@ -150,9 +150,15 @@ impl FunctionCompiler {
compiler.params = parameters.clone(); 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 if compiler
compiler.emit(Opcode::PushUndefined, &[]); .bytecode
compiler.emit(Opcode::Return, &[]); .last()
.filter(|last| **last == Opcode::Return as u8)
.is_none()
{
compiler.emit_opcode(Opcode::PushUndefined);
compiler.emit_opcode(Opcode::Return);
}
Gc::new(compiler.finish()) Gc::new(compiler.finish())
} }

43
boa_engine/src/bytecompiler/mod.rs

@ -1150,12 +1150,7 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
} }
/// Compile an object method AST Node into bytecode. /// Compile an object method AST Node into bytecode.
pub(crate) fn object_method( pub(crate) fn object_method(&mut self, function: FunctionSpec<'_>) {
&mut self,
function: FunctionSpec<'_>,
node_kind: NodeKind,
use_expr: bool,
) {
let (generator, r#async, arrow) = ( let (generator, r#async, arrow) = (
function.is_generator(), function.is_generator(),
function.is_async(), function.is_async(),
@ -1212,30 +1207,10 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
if !generator { if !generator {
self.emit_u8(1); 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. /// Compile a class method AST Node into bytecode.
fn method( fn method(&mut self, function: FunctionSpec<'_>, class_name: Sym) {
&mut self,
function: FunctionSpec<'_>,
node_kind: NodeKind,
class_name: Sym,
use_expr: bool,
) {
let (generator, r#async, arrow) = ( let (generator, r#async, arrow) = (
function.is_generator(), function.is_generator(),
function.is_async(), function.is_async(),
@ -1293,20 +1268,6 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
if !generator { if !generator {
self.emit_u8(1); 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) { fn call(&mut self, callable: Callable<'_>, use_expr: bool) {

13
boa_engine/src/bytecompiler/statement/try.rs

@ -5,7 +5,7 @@ use crate::{
use boa_ast::{ use boa_ast::{
declaration::Binding, declaration::Binding,
operations::bound_names, operations::bound_names,
statement::{Finally, Try}, statement::{Catch, Finally, Try},
}; };
impl ByteCompiler<'_, '_> { impl ByteCompiler<'_, '_> {
@ -33,8 +33,8 @@ impl ByteCompiler<'_, '_> {
let finally = self.jump(); let finally = self.jump();
self.patch_jump(catch_start); self.patch_jump(catch_start);
if t.catch().is_some() { if let Some(catch) = t.catch() {
self.compile_catch_stmt(t, use_expr); self.compile_catch_stmt(catch, t.finally().is_some(), use_expr);
} }
self.patch_jump(finally); self.patch_jump(finally);
@ -55,10 +55,7 @@ impl ByteCompiler<'_, '_> {
} }
} }
pub(crate) fn compile_catch_stmt(&mut self, parent_try: &Try, use_expr: bool) { pub(crate) fn compile_catch_stmt(&mut self, catch: &Catch, finally: bool, use_expr: bool) {
let catch = parent_try
.catch()
.expect("Catch must exist for compile_catch_stmt to have been invoked");
self.set_jump_control_in_catch(true); self.set_jump_control_in_catch(true);
let catch_end = self.emit_opcode_with_operand(Opcode::CatchStart); 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.patch_jump_with_target(push_env.1, env_info.index as u32);
self.emit_opcode(Opcode::PopEnvironment); self.emit_opcode(Opcode::PopEnvironment);
if parent_try.finally().is_some() { if finally {
self.emit_opcode(Opcode::CatchEnd); self.emit_opcode(Opcode::CatchEnd);
} else { } else {
self.emit_opcode(Opcode::CatchEnd2); self.emit_opcode(Opcode::CatchEnd2);

Loading…
Cancel
Save