Skip to content

Commit

Permalink
Merge 75edd12 into 0a843d2
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat committed Mar 15, 2023
2 parents 0a843d2 + 75edd12 commit 4d5e85d
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 141 deletions.
107 changes: 32 additions & 75 deletions boa_engine/src/bytecompiler/class.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::{ByteCompiler, Literal, NodeKind};
use crate::vm::{BindingOpcode, CodeBlock, Opcode};
use crate::vm::{BindingOpcode, Opcode};
use boa_ast::{
declaration::Binding,
expression::Identifier,
Expand All @@ -9,7 +9,6 @@ use boa_ast::{
};
use boa_gc::Gc;
use boa_interner::Sym;
use rustc_hash::FxHashMap;

impl ByteCompiler<'_, '_> {
/// This function compiles a class declaration or expression.
Expand All @@ -20,22 +19,11 @@ impl ByteCompiler<'_, '_> {
pub(crate) fn compile_class(&mut self, class: &Class, expression: bool) {
let class_name = class.name().map_or(Sym::EMPTY_STRING, Identifier::sym);

let code = CodeBlock::new(class_name, 0, true);
let mut compiler = ByteCompiler {
code_block: code,
literals_map: FxHashMap::default(),
names_map: FxHashMap::default(),
private_names_map: FxHashMap::default(),
bindings_map: FxHashMap::default(),
jump_info: Vec::new(),
in_async_generator: false,
json_parse: self.json_parse,
context: self.context,
};
let mut compiler = ByteCompiler::new(class_name, true, self.json_parse, self.context);

if let Some(class_name) = class.name() {
if class.has_binding_identifier() {
compiler.code_block.has_binding_identifier = true;
compiler.has_binding_identifier = true;
compiler.context.push_compile_time_environment(false);
compiler.context.create_immutable_binding(class_name, true);
}
Expand All @@ -44,12 +32,12 @@ impl ByteCompiler<'_, '_> {
compiler.context.push_compile_time_environment(true);

if let Some(expr) = class.constructor() {
compiler.code_block.length = expr.parameters().length();
compiler.code_block.params = expr.parameters().clone();
compiler.length = expr.parameters().length();
compiler.params = expr.parameters().clone();
compiler
.context
.create_mutable_binding(Sym::ARGUMENTS.into(), false, false);
compiler.code_block.arguments_binding = Some(
compiler.arguments_binding = Some(
compiler
.context
.initialize_mutable_binding(Sym::ARGUMENTS.into(), false),
Expand Down Expand Up @@ -84,10 +72,9 @@ impl ByteCompiler<'_, '_> {
compiler.emit_opcode(Opcode::RestParameterPop);
}
let env_label = if expr.parameters().has_expressions() {
compiler.code_block.num_bindings = compiler.context.get_binding_number();
compiler.num_bindings = compiler.context.get_binding_number();
compiler.context.push_compile_time_environment(true);
compiler.code_block.function_environment_push_location =
compiler.next_opcode_location();
compiler.function_environment_push_location = compiler.next_opcode_location();
Some(compiler.emit_opcode_with_two_operands(Opcode::PushFunctionEnvironment))
} else {
None
Expand All @@ -107,8 +94,8 @@ impl ByteCompiler<'_, '_> {
let (num_bindings, compile_environment) =
compiler.context.pop_compile_time_environment();
compiler.push_compile_environment(compile_environment);
compiler.code_block.num_bindings = num_bindings;
compiler.code_block.is_class_constructor = true;
compiler.num_bindings = num_bindings;
compiler.is_class_constructor = true;
}
} else {
if class.super_ref().is_some() {
Expand All @@ -117,8 +104,8 @@ impl ByteCompiler<'_, '_> {
let (num_bindings, compile_environment) =
compiler.context.pop_compile_time_environment();
compiler.push_compile_environment(compile_environment);
compiler.code_block.num_bindings = num_bindings;
compiler.code_block.is_class_constructor = true;
compiler.num_bindings = num_bindings;
compiler.is_class_constructor = true;
}

if class.name().is_some() && class.has_binding_identifier() {
Expand All @@ -130,8 +117,8 @@ impl ByteCompiler<'_, '_> {
compiler.emit_opcode(Opcode::Return);

let code = Gc::new(compiler.finish());
let index = self.code_block.functions.len() as u32;
self.code_block.functions.push(code);
let index = self.functions.len() as u32;
self.functions.push(code);
self.emit(Opcode::GetFunction, &[index]);
self.emit_u8(0);

Expand Down Expand Up @@ -279,18 +266,8 @@ impl ByteCompiler<'_, '_> {
self.compile_expr(name, true);
}
}
let field_code = CodeBlock::new(Sym::EMPTY_STRING, 0, true);
let mut field_compiler = ByteCompiler {
code_block: field_code,
literals_map: FxHashMap::default(),
names_map: FxHashMap::default(),
private_names_map: FxHashMap::default(),
bindings_map: FxHashMap::default(),
jump_info: Vec::new(),
in_async_generator: false,
json_parse: self.json_parse,
context: self.context,
};
let mut field_compiler =
ByteCompiler::new(Sym::EMPTY_STRING, true, self.json_parse, self.context);
field_compiler.context.push_compile_time_environment(false);
field_compiler
.context
Expand All @@ -307,33 +284,23 @@ impl ByteCompiler<'_, '_> {
let (_, compile_environment) =
field_compiler.context.pop_compile_time_environment();
field_compiler.push_compile_environment(compile_environment);
field_compiler.code_block.num_bindings = num_bindings;
field_compiler.num_bindings = num_bindings;
field_compiler.emit_opcode(Opcode::Return);

let mut code = field_compiler.finish();
code.class_field_initializer_name = Some(Sym::EMPTY_STRING);
let code = Gc::new(code);
let index = self.code_block.functions.len() as u32;
self.code_block.functions.push(code);
let index = self.functions.len() as u32;
self.functions.push(code);
self.emit(Opcode::GetFunction, &[index]);
self.emit_u8(0);
self.emit_opcode(Opcode::PushClassField);
}
ClassElement::PrivateFieldDefinition(name, field) => {
self.emit_opcode(Opcode::Dup);
let name_index = self.get_or_insert_private_name(*name);
let field_code = CodeBlock::new(Sym::EMPTY_STRING, 0, true);
let mut field_compiler = ByteCompiler {
code_block: field_code,
literals_map: FxHashMap::default(),
names_map: FxHashMap::default(),
private_names_map: FxHashMap::default(),
bindings_map: FxHashMap::default(),
jump_info: Vec::new(),
in_async_generator: false,
json_parse: self.json_parse,
context: self.context,
};
let mut field_compiler =
ByteCompiler::new(class_name, true, self.json_parse, self.context);
field_compiler.context.push_compile_time_environment(false);
field_compiler
.context
Expand All @@ -350,14 +317,14 @@ impl ByteCompiler<'_, '_> {
let (_, compile_environment) =
field_compiler.context.pop_compile_time_environment();
field_compiler.push_compile_environment(compile_environment);
field_compiler.code_block.num_bindings = num_bindings;
field_compiler.num_bindings = num_bindings;
field_compiler.emit_opcode(Opcode::Return);

let mut code = field_compiler.finish();
code.class_field_initializer_name = Some(Sym::EMPTY_STRING);
let code = Gc::new(code);
let index = self.code_block.functions.len() as u32;
self.code_block.functions.push(code);
let index = self.functions.len() as u32;
self.functions.push(code);
self.emit(Opcode::GetFunction, &[index]);
self.emit_u8(0);
self.emit(Opcode::PushClassFieldPrivate, &[name_index]);
Expand All @@ -375,18 +342,8 @@ impl ByteCompiler<'_, '_> {
None
}
};
let field_code = CodeBlock::new(Sym::EMPTY_STRING, 0, true);
let mut field_compiler = ByteCompiler {
code_block: field_code,
literals_map: FxHashMap::default(),
names_map: FxHashMap::default(),
private_names_map: FxHashMap::default(),
bindings_map: FxHashMap::default(),
jump_info: Vec::new(),
in_async_generator: false,
json_parse: self.json_parse,
context: self.context,
};
let mut field_compiler =
ByteCompiler::new(class_name, true, self.json_parse, self.context);
field_compiler.context.push_compile_time_environment(false);
field_compiler
.context
Expand All @@ -403,14 +360,14 @@ impl ByteCompiler<'_, '_> {
let (_, compile_environment) =
field_compiler.context.pop_compile_time_environment();
field_compiler.push_compile_environment(compile_environment);
field_compiler.code_block.num_bindings = num_bindings;
field_compiler.num_bindings = num_bindings;
field_compiler.emit_opcode(Opcode::Return);

let mut code = field_compiler.finish();
code.class_field_initializer_name = Some(Sym::EMPTY_STRING);
let code = Gc::new(code);
let index = self.code_block.functions.len() as u32;
self.code_block.functions.push(code);
let index = self.functions.len() as u32;
self.functions.push(code);
self.emit(Opcode::GetFunction, &[index]);
self.emit_u8(0);
self.emit_opcode(Opcode::SetHomeObject);
Expand Down Expand Up @@ -447,11 +404,11 @@ impl ByteCompiler<'_, '_> {
compiler.push_compile_environment(compile_environment);
let (_, compile_environment) = compiler.context.pop_compile_time_environment();
compiler.push_compile_environment(compile_environment);
compiler.code_block.num_bindings = num_bindings;
compiler.num_bindings = num_bindings;

let code = Gc::new(compiler.finish());
let index = self.code_block.functions.len() as u32;
self.code_block.functions.push(code);
let index = self.functions.len() as u32;
self.functions.push(code);
self.emit(Opcode::GetFunction, &[index]);
self.emit_u8(0);
self.emit_opcode(Opcode::SetHomeObject);
Expand Down
33 changes: 11 additions & 22 deletions boa_engine/src/bytecompiler/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use boa_ast::{
};
use boa_gc::Gc;
use boa_interner::Sym;
use rustc_hash::FxHashMap;

/// `FunctionCompiler` is used to compile AST functions to bytecode.
#[derive(Debug, Clone, Copy)]
Expand Down Expand Up @@ -95,24 +94,15 @@ impl FunctionCompiler {
self.strict = self.strict || body.strict();

let length = parameters.length();
let mut code = CodeBlock::new(self.name, length, self.strict);

let mut compiler = ByteCompiler::new(self.name, self.strict, false, context);
compiler.length = length;
compiler.in_async_generator = self.generator && self.r#async;

if self.arrow {
code.this_mode = ThisMode::Lexical;
compiler.this_mode = ThisMode::Lexical;
}

let mut compiler = ByteCompiler {
code_block: code,
literals_map: FxHashMap::default(),
names_map: FxHashMap::default(),
private_names_map: FxHashMap::default(),
bindings_map: FxHashMap::default(),
jump_info: Vec::new(),
in_async_generator: self.generator && self.r#async,
json_parse: false,
context,
};

if let Some(class_name) = self.class_name {
compiler.context.push_compile_time_environment(false);
compiler
Expand All @@ -121,7 +111,7 @@ impl FunctionCompiler {
}

if let Some(binding_identifier) = self.binding_identifier {
compiler.code_block.has_binding_identifier = true;
compiler.has_binding_identifier = true;
compiler.context.push_compile_time_environment(false);
compiler
.context
Expand All @@ -139,7 +129,7 @@ impl FunctionCompiler {
compiler
.context
.create_mutable_binding(Sym::ARGUMENTS.into(), false, false);
compiler.code_block.arguments_binding = Some(
compiler.arguments_binding = Some(
compiler
.context
.initialize_mutable_binding(Sym::ARGUMENTS.into(), false),
Expand Down Expand Up @@ -184,10 +174,9 @@ impl FunctionCompiler {
}

let env_label = if parameters.has_expressions() {
compiler.code_block.num_bindings = compiler.context.get_binding_number();
compiler.num_bindings = compiler.context.get_binding_number();
compiler.context.push_compile_time_environment(true);
compiler.code_block.function_environment_push_location =
compiler.next_opcode_location();
compiler.function_environment_push_location = compiler.next_opcode_location();
Some(compiler.emit_opcode_with_two_operands(Opcode::PushFunctionEnvironment))
} else {
None
Expand Down Expand Up @@ -215,7 +204,7 @@ impl FunctionCompiler {
let (num_bindings, compile_environment) =
compiler.context.pop_compile_time_environment();
compiler.push_compile_environment(compile_environment);
compiler.code_block.num_bindings = num_bindings;
compiler.num_bindings = num_bindings;
}

if self.binding_identifier.is_some() {
Expand All @@ -228,7 +217,7 @@ impl FunctionCompiler {
compiler.push_compile_environment(compile_environment);
}

compiler.code_block.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
compiler.emit(Opcode::PushUndefined, &[]);
Expand Down

0 comments on commit 4d5e85d

Please sign in to comment.