From e890a8ea8a7240c6aa4524f2a8578203ad4d2a92 Mon Sep 17 00:00:00 2001 From: Iban Eguia Moraza Date: Sun, 26 Dec 2021 13:38:30 +0100 Subject: [PATCH] Using the interner in the AST (parser) --- Cargo.lock | 17 +- boa/Cargo.toml | 4 +- boa/benches/full.rs | 20 +- boa/src/builtins/array/tests.rs | 1 - boa/src/builtins/console/mod.rs | 8 +- boa/src/builtins/dataview/mod.rs | 2 +- boa/src/builtins/function/arguments.rs | 11 +- boa/src/builtins/function/mod.rs | 52 +-- boa/src/builtins/map/map_iterator.rs | 4 +- boa/src/builtins/set/set_iterator.rs | 6 +- boa/src/bytecompiler.rs | 277 +++++++++---- boa/src/context.rs | 14 +- .../declarative_environment_record.rs | 122 ++++-- .../environment/environment_record_trait.rs | 39 +- .../function_environment_record.rs | 28 +- .../environment/global_environment_record.rs | 139 +++++-- boa/src/environment/lexical_environment.rs | 18 +- .../environment/object_environment_record.rs | 106 +++-- boa/src/gc.rs | 4 +- boa/src/object/jsobject.rs | 14 +- boa/src/property/mod.rs | 5 +- boa/src/realm.rs | 2 +- boa/src/syntax/ast/constant.rs | 48 +-- boa/src/syntax/ast/keyword.rs | 6 + boa/src/syntax/ast/node/array/mod.rs | 10 +- boa/src/syntax/ast/node/await_expr/mod.rs | 11 +- boa/src/syntax/ast/node/block/mod.rs | 26 +- boa/src/syntax/ast/node/call/mod.rs | 14 +- .../node/conditional/conditional_op/mod.rs | 15 +- .../ast/node/conditional/if_node/mod.rs | 29 +- .../declaration/arrow_function_decl/mod.rs | 28 +- .../declaration/async_function_decl/mod.rs | 50 ++- .../declaration/async_function_expr/mod.rs | 51 ++- .../declaration/async_generator_decl/mod.rs | 49 ++- .../declaration/async_generator_expr/mod.rs | 56 ++- .../ast/node/declaration/function_decl/mod.rs | 44 +- .../ast/node/declaration/function_expr/mod.rs | 58 ++- .../node/declaration/generator_decl/mod.rs | 44 +- .../node/declaration/generator_expr/mod.rs | 60 ++- boa/src/syntax/ast/node/declaration/mod.rs | 215 ++++++---- .../ast/node/field/get_const_field/mod.rs | 23 +- .../syntax/ast/node/field/get_field/mod.rs | 12 +- boa/src/syntax/ast/node/identifier/mod.rs | 42 +- .../node/{ => iteration}/break_node/mod.rs | 38 +- .../node/{ => iteration}/break_node/tests.rs | 4 +- .../ast/node/iteration/continue_node/mod.rs | 34 +- .../ast/node/iteration/do_while_loop/mod.rs | 41 +- .../ast/node/iteration/for_in_loop/mod.rs | 41 +- .../syntax/ast/node/iteration/for_loop/mod.rs | 51 ++- .../ast/node/iteration/for_of_loop/mod.rs | 42 +- boa/src/syntax/ast/node/iteration/mod.rs | 27 +- .../ast/node/iteration/while_loop/mod.rs | 40 +- boa/src/syntax/ast/node/mod.rs | 212 +++++----- boa/src/syntax/ast/node/new/mod.rs | 8 +- boa/src/syntax/ast/node/object/mod.rs | 70 ++-- .../syntax/ast/node/operator/assign/mod.rs | 12 +- .../syntax/ast/node/operator/bin_op/mod.rs | 13 +- .../syntax/ast/node/operator/unary_op/mod.rs | 8 +- boa/src/syntax/ast/node/return_smt/mod.rs | 18 +- boa/src/syntax/ast/node/spread/mod.rs | 8 +- boa/src/syntax/ast/node/statement_list/mod.rs | 60 +-- boa/src/syntax/ast/node/switch/mod.rs | 35 +- boa/src/syntax/ast/node/template/mod.rs | 90 ++-- boa/src/syntax/ast/node/throw/mod.rs | 8 +- boa/src/syntax/ast/node/try_node/mod.rs | 55 +-- boa/src/syntax/ast/node/yield/mod.rs | 13 +- boa/src/syntax/ast/punctuator.rs | 124 +++--- boa/src/syntax/lexer/regex.rs | 101 +---- boa/src/syntax/lexer/template.rs | 6 +- boa/src/syntax/lexer/tests.rs | 140 ++++--- boa/src/syntax/lexer/token.rs | 53 ++- .../parser/cursor/buffered_lexer/tests.rs | 12 +- .../expression/assignment/arrow_function.rs | 12 +- .../parser/expression/left_hand_side/call.rs | 13 +- .../expression/left_hand_side/member.rs | 10 +- .../expression/left_hand_side/template.rs | 16 +- .../primary/array_initializer/tests.rs | 22 +- .../primary/async_function_expression/mod.rs | 16 +- .../async_function_expression/tests.rs | 26 +- .../primary/async_generator_expression/mod.rs | 18 +- .../{test.rs => tests.rs} | 26 +- .../primary/function_expression/mod.rs | 14 +- .../primary/function_expression/tests.rs | 26 +- .../primary/generator_expression/mod.rs | 14 +- .../primary/generator_expression/tests.rs | 12 +- .../syntax/parser/expression/primary/mod.rs | 33 +- .../primary/object_initializer/mod.rs | 54 +-- .../primary/object_initializer/tests.rs | 117 +++--- .../parser/expression/primary/template/mod.rs | 21 +- .../syntax/parser/expression/primary/tests.rs | 14 +- boa/src/syntax/parser/expression/tests.rs | 385 +++++++++++++----- boa/src/syntax/parser/expression/update.rs | 6 +- boa/src/syntax/parser/function/mod.rs | 7 +- boa/src/syntax/parser/function/tests.rs | 259 ++++++++---- .../syntax/parser/statement/block/tests.rs | 42 +- .../syntax/parser/statement/break_stm/mod.rs | 2 +- .../parser/statement/break_stm/tests.rs | 52 +-- .../parser/statement/continue_stm/mod.rs | 2 +- .../parser/statement/continue_stm/tests.rs | 48 ++- .../hoistable/async_function_decl/tests.rs | 12 +- .../hoistable/async_generator_decl/tests.rs | 4 +- .../hoistable/function_decl/tests.rs | 12 +- .../hoistable/generator_decl/tests.rs | 4 +- .../statement/declaration/hoistable/mod.rs | 19 +- .../parser/statement/declaration/tests.rs | 110 +++-- .../syntax/parser/statement/if_stm/tests.rs | 4 +- .../statement/iteration/for_statement.rs | 2 +- .../parser/statement/iteration/tests.rs | 58 ++- .../parser/statement/labelled_stm/mod.rs | 9 +- boa/src/syntax/parser/statement/mod.rs | 87 ++-- .../syntax/parser/statement/switch/tests.rs | 24 +- .../syntax/parser/statement/throw/tests.rs | 4 +- .../syntax/parser/statement/try_stm/catch.rs | 10 +- .../syntax/parser/statement/try_stm/tests.rs | 49 +-- boa/src/syntax/parser/tests.rs | 166 +++++--- boa/src/tests.rs | 1 - boa/src/value/mod.rs | 2 +- boa/src/vm/call_frame.rs | 3 +- boa/src/vm/code_block.rs | 114 +++--- boa/src/vm/mod.rs | 71 ++-- boa_cli/Cargo.toml | 2 +- boa_cli/src/main.rs | 2 +- boa_interner/Cargo.toml | 3 +- boa_interner/src/lib.rs | 249 ++++++++++- boa_interner/src/tests.rs | 74 ++++ boa_tester/Cargo.toml | 4 +- boa_tester/src/exec/mod.rs | 4 +- yarn.lock | 42 +- 128 files changed, 3368 insertions(+), 2192 deletions(-) rename boa/src/syntax/ast/node/{ => iteration}/break_node/mod.rs (65%) rename boa/src/syntax/ast/node/{ => iteration}/break_node/tests.rs (89%) rename boa/src/syntax/parser/expression/primary/async_generator_expression/{test.rs => tests.rs} (67%) create mode 100644 boa_interner/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 049f5cc3e4f..ff94a50d2f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -112,6 +112,7 @@ dependencies = [ name = "boa_interner" version = "0.13.0" dependencies = [ + "gc", "serde", "string-interner", ] @@ -231,9 +232,9 @@ dependencies = [ [[package]] name = "clipboard-win" -version = "4.2.2" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db8340083d28acb43451166543b98c838299b7e0863621be53a338adceea0ed" +checksum = "1951fb8aa063a2ee18b4b4d217e4aa2ec9cc4f2430482983f607fa10cd36d7aa" dependencies = [ "error-code", "str-buf", @@ -1193,9 +1194,9 @@ checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" [[package]] name = "serde" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" +checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" dependencies = [ "serde_derive", ] @@ -1212,9 +1213,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" +checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" dependencies = [ "proc-macro2", "quote", @@ -1223,9 +1224,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.73" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" +checksum = "ee2bb9cd061c5865d345bb02ca49fcef1391741b672b54a0bf7b679badec3142" dependencies = [ "itoa 1.0.1", "ryu", diff --git a/boa/Cargo.toml b/boa/Cargo.toml index b9877c94802..dedfebb59dc 100644 --- a/boa/Cargo.toml +++ b/boa/Cargo.toml @@ -22,8 +22,8 @@ console = [] boa_unicode = { path = "../boa_unicode", version = "0.13.0" } boa_interner = { path = "../boa_interner", version = "0.13.0" } gc = { version = "0.4.1", features = ["derive"] } -serde = { version = "1.0.132", features = ["derive", "rc"] } -serde_json = "1.0.73" +serde = { version = "1.0.133", features = ["derive", "rc"] } +serde_json = "1.0.74" rand = "0.8.4" num-traits = "0.2.14" regress = "0.4.1" diff --git a/boa/benches/full.rs b/boa/benches/full.rs index c2eedd22731..57b36527c1b 100644 --- a/boa/benches/full.rs +++ b/boa/benches/full.rs @@ -1,7 +1,6 @@ //! Benchmarks of the whole execution engine in Boa. -use boa::{realm::Realm, syntax::Parser, Context}; -use boa_interner::Interner; +use boa::{realm::Realm, Context}; use criterion::{black_box, criterion_group, criterion_main, Criterion}; #[cfg(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu"))] @@ -21,9 +20,9 @@ macro_rules! full_benchmarks { $( { static CODE: &str = include_str!(concat!("bench_scripts/", stringify!($name), ".js")); - let mut interner = Interner::new(); + let mut context = Context::default(); c.bench_function(concat!($id, " (Parser)"), move |b| { - b.iter(|| Parser::new(black_box(CODE.as_bytes()), false).parse_all(&mut interner)) + b.iter(|| context.parse(black_box(CODE))) }); } )* @@ -32,11 +31,11 @@ macro_rules! full_benchmarks { $( { static CODE: &str = include_str!(concat!("bench_scripts/", stringify!($name), ".js")); - let mut interner = Interner::new(); - let statement_list = Parser::new(CODE.as_bytes(), false).parse_all( &mut interner).expect("parsing failed"); + let mut context = Context::default(); + let statement_list = context.parse(CODE).expect("parsing failed"); c.bench_function(concat!($id, " (Compiler)"), move |b| { b.iter(|| { - Context::compile(black_box(statement_list.clone())); + context.compile(black_box(statement_list.clone())) }) }); } @@ -46,13 +45,12 @@ macro_rules! full_benchmarks { $( { static CODE: &str = include_str!(concat!("bench_scripts/", stringify!($name), ".js")); - let mut interner = Interner::new(); - let statement_list = Parser::new(CODE.as_bytes(), false).parse_all( &mut interner).expect("parsing failed"); - let code_block = Context::compile(statement_list); let mut context = Context::default(); + let statement_list = context.parse(CODE).expect("parsing failed"); + let code_block = context.compile(statement_list); c.bench_function(concat!($id, " (Execution)"), move |b| { b.iter(|| { - context.execute(black_box(code_block.clone())).unwrap(); + context.execute(black_box(code_block.clone())).unwrap() }) }); } diff --git a/boa/src/builtins/array/tests.rs b/boa/src/builtins/array/tests.rs index 9d4d683ba0a..2374fb13635 100644 --- a/boa/src/builtins/array/tests.rs +++ b/boa/src/builtins/array/tests.rs @@ -117,7 +117,6 @@ fn of() { assert_eq!(context.eval("a.length").unwrap(), JsValue::new(3)); } -#[ignore] #[test] fn concat() { let mut context = Context::default(); diff --git a/boa/src/builtins/console/mod.rs b/boa/src/builtins/console/mod.rs index 861fef63506..bbea231e94e 100644 --- a/boa/src/builtins/console/mod.rs +++ b/boa/src/builtins/console/mod.rs @@ -304,7 +304,13 @@ impl Console { let mut prev_frame = context.vm.frame.as_ref(); while let Some(frame) = prev_frame { - stack_trace.push(frame.code.name.to_string()); + stack_trace.push( + context + .interner() + .resolve(frame.code.name) + .expect("string disappeared") + .to_owned(), + ); prev_frame = frame.prev.as_ref(); } diff --git a/boa/src/builtins/dataview/mod.rs b/boa/src/builtins/dataview/mod.rs index 37207e6494f..e57d77efa43 100644 --- a/boa/src/builtins/dataview/mod.rs +++ b/boa/src/builtins/dataview/mod.rs @@ -1,6 +1,7 @@ use crate::{ builtins::{array_buffer::SharedMemoryOrder, typed_array::TypedArrayName, BuiltIn, JsArgs}, context::StandardObjects, + gc::{Finalize, Trace}, object::{ internal_methods::get_prototype_from_constructor, ConstructorBuilder, FunctionBuilder, JsObject, ObjectData, @@ -10,7 +11,6 @@ use crate::{ value::JsValue, Context, JsResult, }; -use gc::{Finalize, Trace}; #[derive(Debug, Clone, Trace, Finalize)] pub struct DataView { diff --git a/boa/src/builtins/function/arguments.rs b/boa/src/builtins/function/arguments.rs index 7ef1e56c768..c74b63303ad 100644 --- a/boa/src/builtins/function/arguments.rs +++ b/boa/src/builtins/function/arguments.rs @@ -1,14 +1,13 @@ use crate::{ builtins::Array, environment::lexical_environment::Environment, + gc::{Finalize, Trace}, object::{FunctionBuilder, JsObject, ObjectData}, property::PropertyDescriptor, symbol::{self, WellKnownSymbols}, syntax::ast::node::FormalParameter, Context, JsValue, }; - -use gc::{Finalize, Trace}; use rustc_hash::FxHashSet; #[derive(Debug, Clone, Trace, Finalize)] @@ -171,9 +170,9 @@ impl Arguments { // a. Let name be parameterNames[index]. for (index, parameter_name_vec) in formals.iter().map(|fp| fp.names()).enumerate().rev() { - for parameter_name in parameter_name_vec.iter().cloned() { + for parameter_name in parameter_name_vec.iter().copied() { // b. If name is not an element of mappedNames, then - if !mapped_names.contains(parameter_name) { + if !mapped_names.contains(¶meter_name) { // i. Add name as an element of the list mappedNames. mapped_names.insert(parameter_name); // ii. If index < len, then @@ -189,7 +188,7 @@ impl Arguments { // 1. Let getterClosure be a new Abstract Closure with no parameters that captures // name and env and performs the following steps when called: |_, _, captures, context| { - captures.0.get_binding_value(&captures.1, false, context) + captures.0.get_binding_value(captures.1, false, context) }, (env.clone(), parameter_name.to_owned()), ) @@ -212,7 +211,7 @@ impl Arguments { // a. Return env.SetMutableBinding(name, value, false). captures .0 - .set_mutable_binding(&captures.1, value, false, context) + .set_mutable_binding(captures.1, value, false, context) .map(|_| JsValue::Undefined) // Ok(JsValue::Undefined) }, diff --git a/boa/src/builtins/function/mod.rs b/boa/src/builtins/function/mod.rs index 7da13c01387..9c9658bb248 100644 --- a/boa/src/builtins/function/mod.rs +++ b/boa/src/builtins/function/mod.rs @@ -11,39 +11,29 @@ //! [spec]: https://tc39.es/ecma262/#sec-function-objects //! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function -use std::{ - any::Any, - borrow::Cow, - fmt, - ops::{Deref, DerefMut}, -}; - -use dyn_clone::DynClone; -use gc::{Gc, GcCell}; - +use super::JsArgs; use crate::{ builtins::BuiltIn, context::StandardObjects, environment::lexical_environment::Environment, - gc::{Finalize, Trace}, - object::JsObject, - object::{internal_methods::get_prototype_from_constructor, NativeObject, ObjectData}, - property::Attribute, - property::PropertyDescriptor, - BoaProfiler, Context, JsResult, JsValue, -}; -use crate::{object::Object, symbol::WellKnownSymbols}; -use crate::{ - object::{ConstructorBuilder, FunctionBuilder}, - property::PropertyKey, - JsString, -}; -use crate::{ - object::{Ref, RefMut}, + gc::{self, Finalize, Gc, Trace}, + object::{ + internal_methods::get_prototype_from_constructor, JsObject, NativeObject, Object, + ObjectData, + }, + object::{ConstructorBuilder, FunctionBuilder, Ref, RefMut}, + property::{Attribute, PropertyDescriptor, PropertyKey}, + symbol::WellKnownSymbols, value::IntegerOrInfinity, + BoaProfiler, Context, JsResult, JsString, JsValue, +}; +use dyn_clone::DynClone; +use std::{ + any::Any, + borrow::Cow, + fmt, + ops::{Deref, DerefMut}, }; - -use super::JsArgs; pub(crate) mod arguments; #[cfg(test)] @@ -136,7 +126,7 @@ impl ConstructorKind { /// with `Any::downcast_ref` and `Any::downcast_mut` to recover the original /// type. #[derive(Clone, Debug, Trace, Finalize)] -pub struct Captures(Gc>>); +pub struct Captures(Gc>>); impl Captures { /// Creates a new capture context. @@ -144,7 +134,7 @@ impl Captures { where T: NativeObject, { - Self(Gc::new(GcCell::new(Box::new(captures)))) + Self(Gc::new(gc::Cell::new(Box::new(captures)))) } /// Casts `Captures` to `Any` @@ -152,7 +142,7 @@ impl Captures { /// # Panics /// /// Panics if it's already borrowed as `&mut Any` - pub fn as_any(&self) -> gc::GcCellRef<'_, dyn Any> { + pub fn as_any(&self) -> gc::Ref<'_, dyn Any> { Ref::map(self.0.borrow(), |data| data.deref().as_any()) } @@ -161,7 +151,7 @@ impl Captures { /// # Panics /// /// Panics if it's already borrowed as `&mut Any` - pub fn as_mut_any(&self) -> gc::GcCellRefMut<'_, Box, dyn Any> { + pub fn as_mut_any(&self) -> gc::RefMut<'_, Box, dyn Any> { RefMut::map(self.0.borrow_mut(), |data| data.deref_mut().as_mut_any()) } } diff --git a/boa/src/builtins/map/map_iterator.rs b/boa/src/builtins/map/map_iterator.rs index 340ff75a292..b7cbb1ab63e 100644 --- a/boa/src/builtins/map/map_iterator.rs +++ b/boa/src/builtins/map/map_iterator.rs @@ -1,13 +1,13 @@ +use super::ordered_map::MapLock; use crate::{ builtins::{function::make_builtin_fn, iterable::create_iter_result_object, Array, JsValue}, + gc::{Finalize, Trace}, object::{JsObject, ObjectData}, property::{PropertyDescriptor, PropertyNameKind}, symbol::WellKnownSymbols, BoaProfiler, Context, JsResult, }; -use gc::{Finalize, Trace}; -use super::ordered_map::MapLock; /// The Map Iterator object represents an iteration over a map. It implements the iterator protocol. /// /// More information: diff --git a/boa/src/builtins/set/set_iterator.rs b/boa/src/builtins/set/set_iterator.rs index 3720423143d..c82ac608ca3 100644 --- a/boa/src/builtins/set/set_iterator.rs +++ b/boa/src/builtins/set/set_iterator.rs @@ -1,13 +1,11 @@ use crate::{ - builtins::Array, - builtins::JsValue, - builtins::{function::make_builtin_fn, iterable::create_iter_result_object}, + builtins::{function::make_builtin_fn, iterable::create_iter_result_object, Array, JsValue}, + gc::{Finalize, Trace}, object::{JsObject, ObjectData}, property::{PropertyDescriptor, PropertyNameKind}, symbol::WellKnownSymbols, BoaProfiler, Context, JsResult, }; -use gc::{Finalize, Trace}; /// The Set Iterator object represents an iteration over a set. It implements the iterator protocol. /// diff --git a/boa/src/bytecompiler.rs b/boa/src/bytecompiler.rs index 1aa6e62dfe7..5f219cbbfba 100644 --- a/boa/src/bytecompiler.rs +++ b/boa/src/bytecompiler.rs @@ -1,7 +1,6 @@ -use gc::Gc; - use crate::{ builtins::function::ThisMode, + gc::Gc, syntax::ast::{ node::{ declaration::{BindingPatternTypeArray, BindingPatternTypeObject, DeclarationPattern}, @@ -16,7 +15,9 @@ use crate::{ vm::{CodeBlock, Opcode}, JsBigInt, JsString, JsValue, }; -use std::{collections::HashMap, mem::size_of}; +use boa_interner::{Interner, Sym}; +use rustc_hash::FxHashMap; +use std::mem::size_of; #[derive(Debug, Clone, PartialEq, Eq, Hash)] enum Literal { @@ -32,7 +33,7 @@ struct Label { #[derive(Debug, Clone)] struct JumpControlInfo { - label: Option>, + label: Option, start_address: u32, kind: JumpControlInfoKind, breaks: Vec