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 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);
}
},

26
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);

12
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())
}

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.
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) {

13
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);

Loading…
Cancel
Save