Skip to content

Commit

Permalink
Move ByteCompiler boolean flags to bitflag
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat committed Sep 26, 2023
1 parent c747841 commit 39a9f75
Show file tree
Hide file tree
Showing 11 changed files with 61 additions and 39 deletions.
8 changes: 4 additions & 4 deletions boa_engine/src/bytecompiler/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ impl ByteCompiler<'_, '_> {
let mut compiler = ByteCompiler::new(
class_name,
true,
self.json_parse,
self.json_parse(),
self.current_environment.clone(),
self.context,
);
Expand Down Expand Up @@ -274,7 +274,7 @@ impl ByteCompiler<'_, '_> {
let mut field_compiler = ByteCompiler::new(
Sym::EMPTY_STRING,
true,
self.json_parse,
self.json_parse(),
self.current_environment.clone(),
self.context,
);
Expand Down Expand Up @@ -309,7 +309,7 @@ impl ByteCompiler<'_, '_> {
let mut field_compiler = ByteCompiler::new(
class_name,
true,
self.json_parse,
self.json_parse(),
self.current_environment.clone(),
self.context,
);
Expand Down Expand Up @@ -354,7 +354,7 @@ impl ByteCompiler<'_, '_> {
let mut field_compiler = ByteCompiler::new(
class_name,
true,
self.json_parse,
self.json_parse(),
self.current_environment.clone(),
self.context,
);
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/bytecompiler/declarations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1067,7 +1067,7 @@ impl ByteCompiler<'_, '_> {
}

if generator {
self.emit(Opcode::Generator, &[Operand::U8(self.in_async().into())]);
self.emit(Opcode::Generator, &[Operand::Bool(self.is_async())]);
self.emit_opcode(Opcode::Pop);
}

Expand Down
10 changes: 5 additions & 5 deletions boa_engine/src/bytecompiler/expression/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ impl ByteCompiler<'_, '_> {
// stack: value

if r#yield.delegate() {
if self.in_async() {
if self.is_async() {
self.emit_opcode(Opcode::GetAsyncIterator);
} else {
self.emit_opcode(Opcode::GetIterator);
Expand All @@ -180,14 +180,14 @@ impl ByteCompiler<'_, '_> {
let (throw_method_undefined, return_method_undefined) =
self.emit_opcode_with_two_operands(Opcode::GeneratorDelegateNext);

if self.in_async() {
if self.is_async() {
self.emit_opcode(Opcode::Pop);
self.emit_opcode(Opcode::Await);
}

let (return_gen, exit) =
self.emit_opcode_with_two_operands(Opcode::GeneratorDelegateResume);
if self.in_async() {
if self.is_async() {
self.emit_opcode(Opcode::IteratorValue);
self.async_generator_yield();
} else {
Expand All @@ -198,7 +198,7 @@ impl ByteCompiler<'_, '_> {

self.patch_jump(return_gen);
self.patch_jump(return_method_undefined);
if self.in_async() {
if self.is_async() {
self.emit_opcode(Opcode::Await);
self.emit_opcode(Opcode::Pop);
}
Expand All @@ -207,7 +207,7 @@ impl ByteCompiler<'_, '_> {
self.r#return(true);

self.patch_jump(throw_method_undefined);
self.iterator_close(self.in_async());
self.iterator_close(self.is_async());
self.emit_opcode(Opcode::Throw);

self.patch_jump(exit);
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/bytecompiler/expression/object_literal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ impl ByteCompiler<'_, '_> {
PropertyName::Literal(name) => {
self.compile_expr(expr, true);
let index = self.get_or_insert_name((*name).into());
if *name == Sym::__PROTO__ && !self.json_parse {
if *name == Sym::__PROTO__ && !self.json_parse() {
self.emit_opcode(Opcode::SetPrototype);
} else {
self.emit(Opcode::DefineOwnPropertyByName, &[Operand::U32(index)]);
Expand Down
15 changes: 9 additions & 6 deletions boa_engine/src/bytecompiler/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::rc::Rc;

use crate::{
builtins::function::ThisMode,
bytecompiler::ByteCompiler,
bytecompiler::{ByteCompiler, ByteCompilerFlags},
environments::CompileTimeEnvironment,
vm::{CodeBlock, CodeBlockFlags, Opcode},
Context,
Expand Down Expand Up @@ -111,8 +111,11 @@ impl FunctionCompiler {

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

compiler.flags.set(ByteCompilerFlags::ASYNC, self.r#async);
compiler
.flags
.set(ByteCompilerFlags::GENERATOR, self.generator);

if self.arrow {
compiler.this_mode = ThisMode::Lexical;
Expand Down Expand Up @@ -143,7 +146,7 @@ impl FunctionCompiler {
// `FunctionDeclarationInstantiation` (so they are propagated).
//
// See: 15.6.2 Runtime Semantics: EvaluateAsyncGeneratorBody: https://tc39.es/ecma262/#sec-runtime-semantics-evaluateasyncgeneratorbody
if compiler.in_async() && !compiler.in_generator() {
if compiler.is_async() && !compiler.is_generator() {
// 1. Let promiseCapability be ! NewPromiseCapability(%Promise%).
//
// Note: If the promise capability is already set, then we do nothing.
Expand Down Expand Up @@ -193,10 +196,10 @@ impl FunctionCompiler {
// - 27.6.3.2 AsyncGeneratorStart ( generator, generatorBody ): <https://tc39.es/ecma262/#sec-asyncgeneratorstart>
//
// Note: We do handle exceptions thrown by generator body in `AsyncGeneratorStart`.
if compiler.in_generator() {
if compiler.is_generator() {
assert!(compiler.async_handler.is_none());

if compiler.in_async() {
if compiler.is_async() {
// Patched in `ByteCompiler::finish()`.
compiler.async_handler = Some(compiler.push_handler());
}
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/bytecompiler/jump_control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ impl JumpRecord {
compiler.emit_opcode(Opcode::SetReturnValue);
}

match (compiler.in_async(), compiler.in_generator()) {
match (compiler.is_async(), compiler.is_generator()) {
// Taken from:
// - 27.6.3.2 AsyncGeneratorStart ( generator, generatorBody ): https://tc39.es/ecma262/#sec-asyncgeneratorstart
//
Expand Down
43 changes: 31 additions & 12 deletions boa_engine/src/bytecompiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::{
vm::{BindingOpcode, CodeBlock, CodeBlockFlags, GeneratorResumeKind, Handler, Opcode},
Context, JsBigInt, JsString, JsValue,
};
use bitflags::bitflags;
use boa_ast::{
declaration::{Binding, LexicalDeclaration, VarDeclaration},
expression::{
Expand Down Expand Up @@ -248,6 +249,20 @@ pub(crate) enum EnvironmentAccess {
// }
// }

bitflags! {
/// Flags for [`ByteCompiler`].
#[derive(Clone, Copy, Debug)]
pub(crate) struct ByteCompilerFlags: u8 {
const ASYNC = 0b0000_0001;
const GENERATOR = 0b0000_0010;
const HAS_WITH_STATEMENT = 0b0000_0100;
const IN_WITH_STATEMENT = 0b0000_1000;
const IN_EVAL = 0b0001_0000;
const HAS_EVAL = 0b0010_0000;
const JSON_PARSE = 0b0100_0000;
}
}

/// The [`ByteCompiler`] is used to compile ECMAScript AST from [`boa_ast`] to bytecode.
#[derive(Debug)]
#[allow(clippy::struct_excessive_bools)]
Expand Down Expand Up @@ -293,9 +308,8 @@ pub struct ByteCompiler<'ctx, 'host> {
names_map: FxHashMap<Identifier, u32>,
bindings_map: FxHashMap<BindingLocator, EnvironmentAccess>,
jump_info: Vec<JumpControlInfo>,
pub(crate) in_async: bool,
in_generator: bool,

pub(crate) flags: ByteCompilerFlags,
can_optimize_local_variables: bool,
#[allow(dead_code)]
fast_local_variable_count: u32,
Expand All @@ -305,7 +319,6 @@ pub struct ByteCompiler<'ctx, 'host> {
///
/// Async functions and async generator functions, need to be closed and resolved.
pub(crate) async_handler: Option<u32>,
json_parse: bool,

// TODO: remove when we separate scripts from the context
context: &'ctx mut Context<'host>,
Expand All @@ -331,6 +344,9 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
) -> ByteCompiler<'ctx, 'host> {
let mut code_block_flags = CodeBlockFlags::empty();
code_block_flags.set(CodeBlockFlags::STRICT, strict);

let mut flags = ByteCompilerFlags::empty();
flags.set(ByteCompilerFlags::JSON_PARSE, json_parse);
Self {
function_name: name,
length: 0,
Expand All @@ -352,16 +368,15 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
names_map: FxHashMap::default(),
bindings_map: FxHashMap::default(),
jump_info: Vec::new(),
in_async: false,
in_generator: false,
can_optimize_local_variables: false,
fast_local_variable_count: 0,
function_environment_index: None,
async_handler: None,
json_parse,
current_environment,
context,

flags,

#[cfg(feature = "annex-b")]
annex_b_function_names: Vec::new(),
}
Expand All @@ -371,16 +386,20 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
self.code_block_flags.contains(CodeBlockFlags::STRICT)
}

pub(crate) const fn in_async(&self) -> bool {
self.in_async
pub(crate) const fn is_async(&self) -> bool {
self.flags.contains(ByteCompilerFlags::ASYNC)
}

pub(crate) const fn is_generator(&self) -> bool {
self.flags.contains(ByteCompilerFlags::GENERATOR)
}

pub(crate) const fn in_generator(&self) -> bool {
self.in_generator
pub(crate) const fn is_async_generator(&self) -> bool {
self.is_async() && self.is_generator()
}

pub(crate) const fn in_async_generator(&self) -> bool {
self.in_async() && self.in_generator()
pub(crate) const fn json_parse(&self) -> bool {
self.flags.contains(ByteCompilerFlags::JSON_PARSE)
}

pub(crate) fn interner(&self) -> &Interner {
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/bytecompiler/statement/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ impl ByteCompiler<'_, '_> {
Statement::Return(ret) => {
if let Some(expr) = ret.target() {
self.compile_expr(expr, true);
if self.in_async_generator() {
if self.is_async_generator() {
self.emit_opcode(Opcode::Await);
self.emit_opcode(Opcode::GeneratorNext);
}
Expand Down
8 changes: 4 additions & 4 deletions boa_engine/src/bytecompiler/statement/try.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl ByteCompiler<'_, '_> {

// If it has a finally but no catch and we are in a generator, then we still need it
// to handle `return()` call on generators.
let catch_handler = if has_finally && (self.in_generator() || has_catch) {
let catch_handler = if has_finally && (self.is_generator() || has_catch) {
self.current_stack_value_count += 2;
Some(self.push_handler())
} else {
Expand All @@ -50,7 +50,7 @@ impl ByteCompiler<'_, '_> {
self.compile_catch_stmt(catch, has_finally, use_expr);
} else {
// Note: implicit !has_catch
if self.in_generator() && has_finally {
if self.is_generator() && has_finally {
// Is this a generator `return()` empty exception?
//
// This is false because when the `Exception` opcode is executed,
Expand All @@ -77,7 +77,7 @@ impl ByteCompiler<'_, '_> {
}

// Note: implicit has_finally
if !has_catch && self.in_generator() {
if !has_catch && self.is_generator() {
// Is this a generator `return()` empty exception?
self.emit_opcode(Opcode::PushTrue);
}
Expand Down Expand Up @@ -154,7 +154,7 @@ impl ByteCompiler<'_, '_> {

if has_catch {
self.emit_opcode(Opcode::ReThrow);
} else if self.in_generator() {
} else if self.is_generator() {
let is_generator_exit = self.jump_if_true();
self.emit_opcode(Opcode::Throw);
self.patch_jump(is_generator_exit);
Expand Down
4 changes: 2 additions & 2 deletions boa_engine/src/bytecompiler/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl ByteCompiler<'_, '_> {
let start = self.next_opcode_location();
self.emit_opcode(Opcode::IteratorStackEmpty);
let empty = self.jump_if_true();
self.iterator_close(self.in_async_generator());
self.iterator_close(self.is_async_generator());
self.emit(Opcode::Jump, &[Operand::U32(start)]);
self.patch_jump(empty);
}
Expand All @@ -65,7 +65,7 @@ impl ByteCompiler<'_, '_> {
/// [yield]: https://tc39.es/ecma262/#sec-yield
pub(super) fn r#yield(&mut self) {
// 1. Let generatorKind be GetGeneratorKind().
if self.in_async() {
if self.is_async() {
// 2. If generatorKind is async, return ? AsyncGeneratorYield(? Await(value)).
self.emit_opcode(Opcode::Await);
self.emit_opcode(Opcode::GeneratorNext);
Expand Down
4 changes: 2 additions & 2 deletions boa_engine/src/module/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use rustc_hash::{FxHashMap, FxHashSet, FxHasher};

use crate::{
builtins::{promise::PromiseCapability, Promise},
bytecompiler::{ByteCompiler, EnvironmentAccess, FunctionSpec, Operand},
bytecompiler::{ByteCompiler, ByteCompilerFlags, EnvironmentAccess, FunctionSpec, Operand},
environments::{BindingLocator, CompileTimeEnvironment, EnvironmentStack},
module::ModuleKind,
object::{FunctionObjectBuilder, JsPromise, RecursionLimiter},
Expand Down Expand Up @@ -1415,7 +1415,7 @@ impl SourceTextModule {
let mut compiler =
ByteCompiler::new(Sym::MAIN, true, false, module_compile_env.clone(), context);

compiler.in_async = true;
compiler.flags |= ByteCompilerFlags::ASYNC;
compiler.async_handler = Some(compiler.push_handler());

let mut imports = Vec::new();
Expand Down

0 comments on commit 39a9f75

Please sign in to comment.