Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make environments opcodes use varying operands #3340

Merged
merged 1 commit into from
Oct 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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 @@ -26,13 +26,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 @@ -43,7 +44,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 @@ -59,15 +61,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 @@ -76,10 +74,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 @@ -119,7 +117,7 @@ impl ByteCompiler<'_, '_> {
let mut static_elements = Vec::new();
let mut static_field_name_count = 0;

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 @@ -282,7 +280,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 @@ -314,7 +314,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 @@ -358,7 +358,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 @@ -393,7 +393,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 @@ -589,9 +589,8 @@ impl ByteCompiler<'_, '_> {
self.emit_opcode(Opcode::Swap);
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(false);
env_label = Some(self.emit_opcode_with_operand(Opcode::PushDeclarativeEnvironment));
let env_index = self.push_compile_environment(false);
self.emit_with_varying_operand(Opcode::PushDeclarativeEnvironment, 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
8 changes: 3 additions & 5 deletions boa_engine/src/bytecompiler/statement/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +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);
}
}