Skip to content

Commit

Permalink
Make environments opcodes use varying operands
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat committed Oct 2, 2023
1 parent 6149ec2 commit 885cd26
Show file tree
Hide file tree
Showing 13 changed files with 145 additions and 127 deletions.
9 changes: 3 additions & 6 deletions boa_engine/src/builtins/eval/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,16 +232,13 @@ impl Eval {
context,
);

compiler.push_compile_environment(strict);

let push_env = compiler.emit_opcode_with_operand(Opcode::PushDeclarativeEnvironment);
let env_index = compiler.push_compile_environment(strict);
compiler.emit_with_varying_operand(Opcode::PushDeclarativeEnvironment, env_index);

compiler.eval_declaration_instantiation(&body, strict)?;
compiler.compile_statement_list(body.statements(), true, false);

let env_index = compiler.pop_compile_environment();
compiler.patch_jump_with_target(push_env, env_index);

compiler.pop_compile_environment();
compiler.emit_opcode(Opcode::PopEnvironment);

let code_block = Gc::new(compiler.finish());
Expand Down
37 changes: 18 additions & 19 deletions boa_engine/src/bytecompiler/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ 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 class_env: Option<super::Label> = match class.name() {
let class_env = match class.name() {
Some(name) if class.has_binding_identifier() => {
self.push_compile_environment(false);
let env_index = self.push_compile_environment(false);
self.create_immutable_binding(name, true);
Some(self.emit_opcode_with_operand(Opcode::PushDeclarativeEnvironment))
self.emit_with_varying_operand(Opcode::PushDeclarativeEnvironment, env_index);
true
}
_ => None,
_ => false,
};

let mut compiler = ByteCompiler::new(
Expand All @@ -34,7 +35,8 @@ impl ByteCompiler<'_, '_> {
self.context,
);

compiler.push_compile_environment(true);
// Function environment
let _ = compiler.push_compile_environment(true);

if let Some(expr) = class.constructor() {
compiler.length = expr.parameters().length();
Expand All @@ -50,15 +52,11 @@ impl ByteCompiler<'_, '_> {

compiler.compile_statement_list(expr.body().statements(), false, false);

let env_index = compiler.pop_compile_environment();

if let Some(env_label) = env_label {
compiler.patch_jump_with_target(env_label, env_index);
if env_label {
compiler.pop_compile_environment();
} else {
compiler.code_block_flags |= CodeBlockFlags::IS_CLASS_CONSTRUCTOR;
}

compiler.emit_opcode(Opcode::PushUndefined);
} else {
if class.super_ref().is_some() {
Expand All @@ -67,10 +65,10 @@ impl ByteCompiler<'_, '_> {
compiler.emit_opcode(Opcode::RestParameterPop);
compiler.emit_opcode(Opcode::PushUndefined);
}
compiler.pop_compile_environment();
compiler.code_block_flags |= CodeBlockFlags::IS_CLASS_CONSTRUCTOR;
}
compiler.emit_opcode(Opcode::SetReturnValue);
compiler.pop_compile_environment();

let code = Gc::new(compiler.finish());
let index = self.functions.len() as u32;
Expand Down Expand Up @@ -107,7 +105,7 @@ impl ByteCompiler<'_, '_> {
}
self.patch_jump_with_target(count_label, count);

if class_env.is_some() {
if class_env {
self.emit_opcode(Opcode::Dup);
self.emit_binding(BindingOpcode::InitConst, class_name.into());
}
Expand Down Expand Up @@ -271,7 +269,9 @@ impl ByteCompiler<'_, '_> {
self.current_environment.clone(),
self.context,
);
field_compiler.push_compile_environment(true);

// Function environment
let _ = field_compiler.push_compile_environment(true);
if let Some(node) = field {
field_compiler.compile_expr(node, true);
} else {
Expand Down Expand Up @@ -303,7 +303,7 @@ impl ByteCompiler<'_, '_> {
self.current_environment.clone(),
self.context,
);
field_compiler.push_compile_environment(true);
let _ = field_compiler.push_compile_environment(true);
if let Some(node) = field {
field_compiler.compile_expr(node, true);
} else {
Expand Down Expand Up @@ -345,7 +345,7 @@ impl ByteCompiler<'_, '_> {
self.current_environment.clone(),
self.context,
);
field_compiler.push_compile_environment(true);
let _ = field_compiler.push_compile_environment(true);
if let Some(node) = field {
field_compiler.compile_expr(node, true);
} else {
Expand Down Expand Up @@ -392,7 +392,7 @@ impl ByteCompiler<'_, '_> {
self.current_environment.clone(),
self.context,
);
compiler.push_compile_environment(true);
let _ = compiler.push_compile_environment(true);

compiler.function_declaration_instantiation(
body,
Expand Down Expand Up @@ -575,9 +575,8 @@ impl ByteCompiler<'_, '_> {

self.emit_opcode(Opcode::Pop);

if let Some(class_env) = class_env {
let env_index = self.pop_compile_environment();
self.patch_jump_with_target(class_env, env_index);
if class_env {
self.pop_compile_environment();
self.emit_opcode(Opcode::PopEnvironment);
}

Expand Down
13 changes: 7 additions & 6 deletions boa_engine/src/bytecompiler/declarations.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
bytecompiler::{ByteCompiler, FunctionCompiler, FunctionSpec, Label, NodeKind},
bytecompiler::{ByteCompiler, FunctionCompiler, FunctionSpec, NodeKind},
environments::BindingLocatorError,
vm::{
create_function_object_fast, create_generator_function_object, BindingOpcode,
Expand Down Expand Up @@ -809,8 +809,8 @@ impl ByteCompiler<'_, '_> {
arrow: bool,
strict: bool,
generator: bool,
) -> (Option<Label>, bool) {
let mut env_label = None;
) -> (bool, bool) {
let mut env_label = false;
let mut additional_env = false;

// 1. Let calleeContext be the running execution context.
Expand Down Expand Up @@ -910,7 +910,7 @@ impl ByteCompiler<'_, '_> {
// c. Let env be NewDeclarativeEnvironment(calleeEnv).
// d. Assert: The VariableEnvironment of calleeContext is calleeEnv.
// e. Set the LexicalEnvironment of calleeContext to env.
self.push_compile_environment(false);
let _ = self.push_compile_environment(false);
additional_env = true;
}

Expand Down Expand Up @@ -1030,8 +1030,9 @@ impl ByteCompiler<'_, '_> {
// visibility of declarations in the function body.
// b. Let varEnv be NewDeclarativeEnvironment(env).
// c. Set the VariableEnvironment of calleeContext to varEnv.
self.push_compile_environment(true);
env_label = Some(self.emit_opcode_with_operand(Opcode::PushFunctionEnvironment));
let env_index = self.push_compile_environment(true);
self.emit_with_varying_operand(Opcode::PushFunctionEnvironment, env_index);
env_label = true;

// d. Let instantiatedVarNames be a new empty List.
let mut instantiated_var_names = Vec::new();
Expand Down
17 changes: 10 additions & 7 deletions boa_engine/src/bytecompiler/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,32 @@ use boa_ast::expression::Identifier;

impl ByteCompiler<'_, '_> {
/// Push either a new declarative or function environment on the compile time environment stack.
pub(crate) fn push_compile_environment(&mut self, function_scope: bool) {
#[must_use]
pub(crate) fn push_compile_environment(&mut self, function_scope: bool) -> u32 {
self.current_open_environments_count += 1;

self.current_environment = Rc::new(CompileTimeEnvironment::new(
self.current_environment.clone(),
function_scope,
));

let index = self.compile_environments.len() as u32;
self.compile_environments
.push(self.current_environment.clone());

index
}

/// Pops the top compile time environment and returns its index in the compile time environments array.
#[track_caller]
pub(crate) fn pop_compile_environment(&mut self) -> u32 {
pub(crate) fn pop_compile_environment(&mut self) {
self.current_open_environments_count -= 1;
let index = self.compile_environments.len() as u32;
self.compile_environments
.push(self.current_environment.clone());

let outer = self
.current_environment
.outer()
.expect("cannot pop the global environment");
self.current_environment = outer;

index
}

/// Get the binding locator of the binding at bytecode compile time.
Expand Down
9 changes: 4 additions & 5 deletions boa_engine/src/bytecompiler/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,12 @@ impl FunctionCompiler {

if let Some(binding_identifier) = self.binding_identifier {
compiler.code_block_flags |= CodeBlockFlags::HAS_BINDING_IDENTIFIER;
compiler.push_compile_environment(false);
let _ = compiler.push_compile_environment(false);
compiler.create_immutable_binding(binding_identifier.into(), self.strict);
}

// Function environment
compiler.push_compile_environment(true);
let _ = compiler.push_compile_environment(true);

// Taken from:
// - 15.9.3 Runtime Semantics: EvaluateAsyncConciseBody: <https://tc39.es/ecma262/#sec-runtime-semantics-evaluateasyncconcisebody>
Expand Down Expand Up @@ -155,9 +155,8 @@ impl FunctionCompiler {

compiler.compile_statement_list(body.statements(), false, false);

if let Some(env_labels) = env_label {
let env_index = compiler.pop_compile_environment();
compiler.patch_jump_with_target(env_labels, env_index);
if env_label {
compiler.pop_compile_environment();
}

if additional_env {
Expand Down
7 changes: 3 additions & 4 deletions boa_engine/src/bytecompiler/statement/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ use boa_ast::statement::Block;
impl ByteCompiler<'_, '_> {
/// Compile a [`Block`] `boa_ast` node
pub(crate) fn compile_block(&mut self, block: &Block, use_expr: bool) {
self.push_compile_environment(false);
let push_env = self.emit_opcode_with_operand(Opcode::PushDeclarativeEnvironment);
let env_index = self.push_compile_environment(false);
self.emit_with_varying_operand(Opcode::PushDeclarativeEnvironment, env_index);

self.block_declaration_instantiation(block);
self.compile_statement_list(block.statement_list(), use_expr, true);

let env_index = self.pop_compile_environment();
self.patch_jump_with_target(push_env, env_index);
self.pop_compile_environment();

self.emit_opcode(Opcode::PopEnvironment);
}
Expand Down

0 comments on commit 885cd26

Please sign in to comment.