From edfafc4e0324da1548f672e6c1edc51a6e1337b5 Mon Sep 17 00:00:00 2001 From: Halid Odat Date: Mon, 7 Sep 2020 12:40:02 +0200 Subject: [PATCH] Feature `Context` (#656) - Move `Console` to `Context` - Change `Context::global()` to `Context::global_object()` - Remove some `use std::borrow::Borrow` - Add some pub exports - Add `Context::eval()` - Deprecate forward_val, forward, exec - Make boa_cli use Context::eval() - Deprecated forward forward_val and exec - Make deprecated functions --- .github/dependabot.yml | 1 - boa/benches/exec.rs | 68 ++-- boa/benches/full.rs | 48 +-- boa/examples/classes.rs | 22 +- boa/src/builtins/array/mod.rs | 112 ++---- boa/src/builtins/array/tests.rs | 183 ++++----- boa/src/builtins/bigint/conversions.rs | 4 +- boa/src/builtins/bigint/mod.rs | 21 +- boa/src/builtins/bigint/tests.rs | 61 ++- boa/src/builtins/boolean/mod.rs | 14 +- boa/src/builtins/boolean/tests.rs | 11 +- boa/src/builtins/console/mod.rs | 41 +- boa/src/builtins/console/tests.rs | 23 +- boa/src/builtins/date/mod.rs | 28 +- boa/src/builtins/date/tests.rs | 183 ++++----- boa/src/builtins/error/mod.rs | 11 +- boa/src/builtins/error/range.rs | 11 +- boa/src/builtins/error/reference.rs | 11 +- boa/src/builtins/error/syntax.rs | 11 +- boa/src/builtins/error/type.rs | 11 +- boa/src/builtins/function/mod.rs | 21 +- boa/src/builtins/function/tests.rs | 9 +- boa/src/builtins/global_this/mod.rs | 6 +- boa/src/builtins/infinity/mod.rs | 4 +- boa/src/builtins/json/mod.rs | 13 +- boa/src/builtins/json/tests.rs | 74 ++-- boa/src/builtins/map/mod.rs | 23 +- boa/src/builtins/map/tests.rs | 44 +-- boa/src/builtins/math/mod.rs | 78 ++-- boa/src/builtins/math/tests.rs | 101 ++--- boa/src/builtins/mod.rs | 6 +- boa/src/builtins/nan/mod.rs | 4 +- boa/src/builtins/number/mod.rs | 61 ++- boa/src/builtins/number/tests.rs | 119 ++---- boa/src/builtins/object/gcobject.rs | 14 +- boa/src/builtins/object/mod.rs | 32 +- boa/src/builtins/object/tests.rs | 27 +- boa/src/builtins/regexp/mod.rs | 33 +- boa/src/builtins/regexp/tests.rs | 16 +- boa/src/builtins/string/mod.rs | 82 ++-- boa/src/builtins/string/tests.rs | 113 ++---- boa/src/builtins/symbol/mod.rs | 13 +- boa/src/builtins/symbol/tests.rs | 11 +- boa/src/builtins/undefined/mod.rs | 4 +- boa/src/class.rs | 27 +- boa/src/context.rs | 496 +++++++++++++++++++++++++ boa/src/exec/array/mod.rs | 4 +- boa/src/exec/block/mod.rs | 6 +- boa/src/exec/break_node/mod.rs | 14 +- boa/src/exec/break_node/tests.rs | 9 +- boa/src/exec/call/mod.rs | 8 +- boa/src/exec/conditional/mod.rs | 11 +- boa/src/exec/declaration/mod.rs | 14 +- boa/src/exec/exception.rs | 96 ----- boa/src/exec/field/mod.rs | 6 +- boa/src/exec/identifier/mod.rs | 4 +- boa/src/exec/iteration/mod.rs | 53 ++- boa/src/exec/mod.rs | 346 +---------------- boa/src/exec/new/mod.rs | 4 +- boa/src/exec/object/mod.rs | 10 +- boa/src/exec/operator/mod.rs | 17 +- boa/src/exec/return_smt/mod.rs | 8 +- boa/src/exec/spread/mod.rs | 4 +- boa/src/exec/statement_list.rs | 10 +- boa/src/exec/switch/mod.rs | 20 +- boa/src/exec/tests.rs | 71 ++-- boa/src/exec/throw/mod.rs | 4 +- boa/src/exec/try_node/mod.rs | 4 +- boa/src/lib.rs | 49 +-- boa/src/syntax/mod.rs | 3 + boa/src/value/equality.rs | 4 +- boa/src/value/mod.rs | 56 ++- boa/src/value/operations.rs | 38 +- boa/src/value/tests.rs | 260 +++++-------- boa_cli/src/main.rs | 10 +- boa_wasm/src/lib.rs | 5 +- tester/src/exec.rs | 26 +- 77 files changed, 1558 insertions(+), 1922 deletions(-) create mode 100644 boa/src/context.rs delete mode 100644 boa/src/exec/exception.rs diff --git a/.github/dependabot.yml b/.github/dependabot.yml index ee3b5ac93a..a032fb3008 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,4 +1,3 @@ ---- version: 2 updates: - package-ecosystem: "npm" diff --git a/boa/benches/exec.rs b/boa/benches/exec.rs index c768fb8707..3730634ac6 100644 --- a/boa/benches/exec.rs +++ b/boa/benches/exec.rs @@ -1,6 +1,6 @@ //! Benchmarks of the whole execution engine in Boa. -use boa::{exec::Interpreter, realm::Realm, Executable, Parser}; +use boa::{exec::Executable, realm::Realm, syntax::Parser, Context}; use criterion::{black_box, criterion_group, criterion_main, Criterion}; #[cfg(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu"))] @@ -18,8 +18,7 @@ static SYMBOL_CREATION: &str = include_str!("bench_scripts/symbol_creation.js"); fn symbol_creation(c: &mut Criterion) { // Create new Realm and interpreter. - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); // Parse the AST nodes. let nodes = Parser::new(SYMBOL_CREATION.as_bytes()).parse_all().unwrap(); @@ -34,8 +33,7 @@ static FOR_LOOP: &str = include_str!("bench_scripts/for_loop.js"); fn for_loop_execution(c: &mut Criterion) { // Create new Realm and interpreter. - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); // Parse the AST nodes. let nodes = Parser::new(FOR_LOOP.as_bytes()).parse_all().unwrap(); @@ -50,8 +48,7 @@ static FIBONACCI: &str = include_str!("bench_scripts/fibonacci.js"); fn fibonacci(c: &mut Criterion) { // Create new Realm and interpreter. - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); // Parse the AST nodes. let nodes = Parser::new(FIBONACCI.as_bytes()).parse_all().unwrap(); @@ -66,8 +63,7 @@ static OBJECT_CREATION: &str = include_str!("bench_scripts/object_creation.js"); fn object_creation(c: &mut Criterion) { // Create new Realm and interpreter. - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); // Parse the AST nodes. let nodes = Parser::new(OBJECT_CREATION.as_bytes()).parse_all().unwrap(); @@ -82,8 +78,7 @@ static OBJECT_PROP_ACCESS_CONST: &str = include_str!("bench_scripts/object_prop_ fn object_prop_access_const(c: &mut Criterion) { // Create new Realm and interpreter. - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); // Parse the AST nodes. let nodes = Parser::new(OBJECT_PROP_ACCESS_CONST.as_bytes()) @@ -100,8 +95,7 @@ static OBJECT_PROP_ACCESS_DYN: &str = include_str!("bench_scripts/object_prop_ac fn object_prop_access_dyn(c: &mut Criterion) { // Create new Realm and interpreter. - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); // Parse the AST nodes. let nodes = Parser::new(OBJECT_PROP_ACCESS_DYN.as_bytes()) @@ -118,8 +112,7 @@ static REGEXP_LITERAL_CREATION: &str = include_str!("bench_scripts/regexp_litera fn regexp_literal_creation(c: &mut Criterion) { // Create new Realm and interpreter. - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); // Parse the AST nodes. let nodes = Parser::new(REGEXP_LITERAL_CREATION.as_bytes()) @@ -136,8 +129,7 @@ static REGEXP_CREATION: &str = include_str!("bench_scripts/regexp_creation.js"); fn regexp_creation(c: &mut Criterion) { // Create new Realm and interpreter. - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); // Parse the AST nodes. let nodes = Parser::new(REGEXP_CREATION.as_bytes()).parse_all().unwrap(); @@ -152,8 +144,7 @@ static REGEXP_LITERAL: &str = include_str!("bench_scripts/regexp_literal.js"); fn regexp_literal(c: &mut Criterion) { // Create new Realm and interpreter. - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); // Parse the AST nodes. let nodes = Parser::new(REGEXP_LITERAL.as_bytes()).parse_all().unwrap(); @@ -168,8 +159,7 @@ static REGEXP: &str = include_str!("bench_scripts/regexp.js"); fn regexp(c: &mut Criterion) { // Create new Realm and interpreter. - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); // Parse the AST nodes. let nodes = Parser::new(REGEXP.as_bytes()).parse_all().unwrap(); @@ -183,8 +173,7 @@ fn regexp(c: &mut Criterion) { static ARRAY_ACCESS: &str = include_str!("bench_scripts/array_access.js"); fn array_access(c: &mut Criterion) { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let nodes = Parser::new(ARRAY_ACCESS.as_bytes()).parse_all().unwrap(); @@ -196,8 +185,7 @@ fn array_access(c: &mut Criterion) { static ARRAY_CREATE: &str = include_str!("bench_scripts/array_create.js"); fn array_creation(c: &mut Criterion) { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let nodes = Parser::new(ARRAY_CREATE.as_bytes()).parse_all().unwrap(); @@ -209,8 +197,7 @@ fn array_creation(c: &mut Criterion) { static ARRAY_POP: &str = include_str!("bench_scripts/array_pop.js"); fn array_pop(c: &mut Criterion) { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let nodes = Parser::new(ARRAY_POP.as_bytes()).parse_all().unwrap(); @@ -222,8 +209,7 @@ fn array_pop(c: &mut Criterion) { static STRING_CONCAT: &str = include_str!("bench_scripts/string_concat.js"); fn string_concat(c: &mut Criterion) { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let nodes = Parser::new(STRING_CONCAT.as_bytes()).parse_all().unwrap(); @@ -235,8 +221,7 @@ fn string_concat(c: &mut Criterion) { static STRING_COMPARE: &str = include_str!("bench_scripts/string_compare.js"); fn string_compare(c: &mut Criterion) { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let nodes = Parser::new(STRING_COMPARE.as_bytes()).parse_all().unwrap(); @@ -248,8 +233,7 @@ fn string_compare(c: &mut Criterion) { static STRING_COPY: &str = include_str!("bench_scripts/string_copy.js"); fn string_copy(c: &mut Criterion) { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let nodes = Parser::new(STRING_COPY.as_bytes()).parse_all().unwrap(); @@ -261,8 +245,7 @@ fn string_copy(c: &mut Criterion) { static NUMBER_OBJECT_ACCESS: &str = include_str!("bench_scripts/number_object_access.js"); fn number_object_access(c: &mut Criterion) { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let nodes = Parser::new(NUMBER_OBJECT_ACCESS.as_bytes()) .parse_all() @@ -276,8 +259,7 @@ fn number_object_access(c: &mut Criterion) { static BOOLEAN_OBJECT_ACCESS: &str = include_str!("bench_scripts/boolean_object_access.js"); fn boolean_object_access(c: &mut Criterion) { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let nodes = Parser::new(BOOLEAN_OBJECT_ACCESS.as_bytes()) .parse_all() @@ -291,8 +273,7 @@ fn boolean_object_access(c: &mut Criterion) { static STRING_OBJECT_ACCESS: &str = include_str!("bench_scripts/string_object_access.js"); fn string_object_access(c: &mut Criterion) { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let nodes = Parser::new(STRING_OBJECT_ACCESS.as_bytes()) .parse_all() @@ -306,8 +287,7 @@ fn string_object_access(c: &mut Criterion) { static ARITHMETIC_OPERATIONS: &str = include_str!("bench_scripts/arithmetic_operations.js"); fn arithmetic_operations(c: &mut Criterion) { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let nodes = Parser::new(ARITHMETIC_OPERATIONS.as_bytes()) .parse_all() @@ -321,8 +301,7 @@ fn arithmetic_operations(c: &mut Criterion) { static CLEAN_JS: &str = include_str!("bench_scripts/clean_js.js"); fn clean_js(c: &mut Criterion) { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let nodes = Parser::new(CLEAN_JS.as_bytes()).parse_all().unwrap(); c.bench_function("Clean js (Execution)", move |b| { b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) @@ -332,8 +311,7 @@ fn clean_js(c: &mut Criterion) { static MINI_JS: &str = include_str!("bench_scripts/mini_js.js"); fn mini_js(c: &mut Criterion) { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let nodes = Parser::new(MINI_JS.as_bytes()).parse_all().unwrap(); c.bench_function("Mini js (Execution)", move |b| { b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) diff --git a/boa/benches/full.rs b/boa/benches/full.rs index d979c5ea68..a46682db38 100644 --- a/boa/benches/full.rs +++ b/boa/benches/full.rs @@ -1,6 +1,6 @@ //! Benchmarks of whole program execution in Boa. -use boa::exec; +use boa::Context; use criterion::{black_box, criterion_group, criterion_main, Criterion}; #[cfg(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu"))] @@ -15,7 +15,7 @@ static SYMBOL_CREATION: &str = include_str!("bench_scripts/symbol_creation.js"); fn symbol_creation(c: &mut Criterion) { // Execute the code by taking into account realm creation, lexing and parsing c.bench_function("Symbols (Full)", move |b| { - b.iter(|| exec(black_box(SYMBOL_CREATION))) + b.iter(|| Context::new().eval(black_box(SYMBOL_CREATION))) }); } @@ -24,7 +24,7 @@ static FOR_LOOP: &str = include_str!("bench_scripts/for_loop.js"); fn for_loop(c: &mut Criterion) { // Execute the code by taking into account realm creation, lexing and parsing c.bench_function("For loop (Full)", move |b| { - b.iter(|| exec(black_box(FOR_LOOP))) + b.iter(|| Context::new().eval(black_box(FOR_LOOP))) }); } @@ -33,7 +33,7 @@ static FIBONACCI: &str = include_str!("bench_scripts/fibonacci.js"); fn fibonacci(c: &mut Criterion) { // Execute the code by taking into account realm creation, lexing and parsing c.bench_function("Fibonacci (Full)", move |b| { - b.iter(|| exec(black_box(FIBONACCI))) + b.iter(|| Context::new().eval(black_box(FIBONACCI))) }); } @@ -42,7 +42,7 @@ static OBJECT_CREATION: &str = include_str!("bench_scripts/object_creation.js"); fn object_creation(c: &mut Criterion) { // Execute the code by taking into account realm creation, lexing and parsing c.bench_function("Object Creation (Full)", move |b| { - b.iter(|| exec(black_box(OBJECT_CREATION))) + b.iter(|| Context::new().eval(black_box(OBJECT_CREATION))) }); } @@ -51,7 +51,7 @@ static OBJECT_PROP_ACCESS_CONST: &str = include_str!("bench_scripts/object_prop_ fn object_prop_access_const(c: &mut Criterion) { // Execute the code by taking into account realm creation, lexing and parsing c.bench_function("Static Object Property Access (Full)", move |b| { - b.iter(|| exec(black_box(OBJECT_PROP_ACCESS_CONST))) + b.iter(|| Context::new().eval(black_box(OBJECT_PROP_ACCESS_CONST))) }); } @@ -60,7 +60,7 @@ static OBJECT_PROP_ACCESS_DYN: &str = include_str!("bench_scripts/object_prop_ac fn object_prop_access_dyn(c: &mut Criterion) { // Execute the code by taking into account realm creation, lexing and parsing c.bench_function("Dynamic Object Property Access (Full)", move |b| { - b.iter(|| exec(black_box(OBJECT_PROP_ACCESS_DYN))) + b.iter(|| Context::new().eval(black_box(OBJECT_PROP_ACCESS_DYN))) }); } @@ -69,7 +69,7 @@ static REGEXP_LITERAL_CREATION: &str = include_str!("bench_scripts/regexp_litera fn regexp_literal_creation(c: &mut Criterion) { // Execute the code by taking into account realm creation, lexing and parsing c.bench_function("RegExp Literal Creation (Full)", move |b| { - b.iter(|| exec(black_box(REGEXP_LITERAL_CREATION))) + b.iter(|| Context::new().eval(black_box(REGEXP_LITERAL_CREATION))) }); } @@ -78,7 +78,7 @@ static REGEXP_CREATION: &str = include_str!("bench_scripts/regexp_creation.js"); fn regexp_creation(c: &mut Criterion) { // Execute the code by taking into account realm creation, lexing and parsing c.bench_function("RegExp (Full)", move |b| { - b.iter(|| exec(black_box(REGEXP_CREATION))) + b.iter(|| Context::new().eval(black_box(REGEXP_CREATION))) }); } @@ -87,7 +87,7 @@ static REGEXP_LITERAL: &str = include_str!("bench_scripts/regexp_literal.js"); fn regexp_literal(c: &mut Criterion) { // Execute the code by taking into account realm creation, lexing and parsing c.bench_function("RegExp Literal (Full)", move |b| { - b.iter(|| exec(black_box(REGEXP_LITERAL))) + b.iter(|| Context::new().eval(black_box(REGEXP_LITERAL))) }); } @@ -95,14 +95,16 @@ static REGEXP: &str = include_str!("bench_scripts/regexp.js"); fn regexp(c: &mut Criterion) { // Execute the code by taking into account realm creation, lexing and parsing - c.bench_function("RegExp (Full)", move |b| b.iter(|| exec(black_box(REGEXP)))); + c.bench_function("RegExp (Full)", move |b| { + b.iter(|| Context::new().eval(black_box(REGEXP))) + }); } static ARRAY_ACCESS: &str = include_str!("bench_scripts/array_access.js"); fn array_access(c: &mut Criterion) { c.bench_function("Array access (Full)", move |b| { - b.iter(|| exec(black_box(ARRAY_ACCESS))) + b.iter(|| Context::new().eval(black_box(ARRAY_ACCESS))) }); } @@ -110,7 +112,7 @@ static ARRAY_CREATE: &str = include_str!("bench_scripts/array_create.js"); fn array_creation(c: &mut Criterion) { c.bench_function("Array creation (Full)", move |b| { - b.iter(|| exec(black_box(ARRAY_CREATE))) + b.iter(|| Context::new().eval(black_box(ARRAY_CREATE))) }); } @@ -118,7 +120,7 @@ static ARRAY_POP: &str = include_str!("bench_scripts/array_pop.js"); fn array_pop(c: &mut Criterion) { c.bench_function("Array pop (Full)", move |b| { - b.iter(|| exec(black_box(ARRAY_POP))) + b.iter(|| Context::new().eval(black_box(ARRAY_POP))) }); } @@ -126,7 +128,7 @@ static STRING_CONCAT: &str = include_str!("bench_scripts/string_concat.js"); fn string_concat(c: &mut Criterion) { c.bench_function("String concatenation (Full)", move |b| { - b.iter(|| exec(black_box(STRING_CONCAT))) + b.iter(|| Context::new().eval(black_box(STRING_CONCAT))) }); } @@ -134,7 +136,7 @@ static STRING_COMPARE: &str = include_str!("bench_scripts/string_compare.js"); fn string_compare(c: &mut Criterion) { c.bench_function("String comparison (Full)", move |b| { - b.iter(|| exec(black_box(STRING_COMPARE))) + b.iter(|| Context::new().eval(black_box(STRING_COMPARE))) }); } @@ -142,7 +144,7 @@ static STRING_COPY: &str = include_str!("bench_scripts/string_copy.js"); fn string_copy(c: &mut Criterion) { c.bench_function("String copy (Full)", move |b| { - b.iter(|| exec(black_box(STRING_COPY))) + b.iter(|| Context::new().eval(black_box(STRING_COPY))) }); } @@ -150,7 +152,7 @@ static NUMBER_OBJECT_ACCESS: &str = include_str!("bench_scripts/number_object_ac fn number_object_access(c: &mut Criterion) { c.bench_function("Number Object Access (Full)", move |b| { - b.iter(|| exec(black_box(NUMBER_OBJECT_ACCESS))) + b.iter(|| Context::new().eval(black_box(NUMBER_OBJECT_ACCESS))) }); } @@ -158,7 +160,7 @@ static BOOLEAN_OBJECT_ACCESS: &str = include_str!("bench_scripts/boolean_object_ fn boolean_object_access(c: &mut Criterion) { c.bench_function("Boolean Object Access (Full)", move |b| { - b.iter(|| exec(black_box(BOOLEAN_OBJECT_ACCESS))) + b.iter(|| Context::new().eval(black_box(BOOLEAN_OBJECT_ACCESS))) }); } @@ -166,7 +168,7 @@ static STRING_OBJECT_ACCESS: &str = include_str!("bench_scripts/string_object_ac fn string_object_access(c: &mut Criterion) { c.bench_function("String Object Access (Full)", move |b| { - b.iter(|| exec(black_box(STRING_OBJECT_ACCESS))) + b.iter(|| Context::new().eval(black_box(STRING_OBJECT_ACCESS))) }); } @@ -174,7 +176,7 @@ static ARITHMETIC_OPERATIONS: &str = include_str!("bench_scripts/arithmetic_oper fn arithmetic_operations(c: &mut Criterion) { c.bench_function("Arithmetic operations (Full)", move |b| { - b.iter(|| exec(black_box(ARITHMETIC_OPERATIONS))) + b.iter(|| Context::new().eval(black_box(ARITHMETIC_OPERATIONS))) }); } @@ -182,7 +184,7 @@ static CLEAN_JS: &str = include_str!("bench_scripts/clean_js.js"); fn clean_js(c: &mut Criterion) { c.bench_function("Clean js (Full)", move |b| { - b.iter(|| exec(black_box(CLEAN_JS))) + b.iter(|| Context::new().eval(black_box(CLEAN_JS))) }); } @@ -190,7 +192,7 @@ static MINI_JS: &str = include_str!("bench_scripts/mini_js.js"); fn mini_js(c: &mut Criterion) { c.bench_function("Mini js (Full)", move |b| { - b.iter(|| exec(black_box(MINI_JS))) + b.iter(|| Context::new().eval(black_box(MINI_JS))) }); } diff --git a/boa/examples/classes.rs b/boa/examples/classes.rs index 52c38d6e45..b0706ca79b 100644 --- a/boa/examples/classes.rs +++ b/boa/examples/classes.rs @@ -1,10 +1,7 @@ use boa::{ class::{Class, ClassBuilder}, - exec::Interpreter, - forward_val, property::Attribute, - realm::Realm, - Finalize, Result, Trace, Value, + Context, Finalize, Result, Trace, Value, }; // We create a new struct that is going to represent a person. @@ -28,7 +25,7 @@ struct Person { // or any function that matches that signature. impl Person { /// This function says hello - fn say_hello(this: &Value, _: &[Value], ctx: &mut Interpreter) -> Result { + fn say_hello(this: &Value, _: &[Value], ctx: &mut Context) -> Result { // We check if this is an object. if let Some(object) = this.as_object() { // If it is we downcast the type to type `Person`. @@ -59,7 +56,7 @@ impl Class for Person { const LENGTH: usize = 2; // This is what is called when we do `new Person()` - fn constructor(_this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + fn constructor(_this: &Value, args: &[Value], ctx: &mut Context) -> Result { // we get the first arguemnt of undefined if the first one is unavalable and call `to_string`. // // This is equivalent to `String(arg)`. @@ -117,15 +114,14 @@ impl Class for Person { } fn main() { - let realm = Realm::create(); - let mut context = Interpreter::new(realm); + let mut context = Context::new(); // we register the global class `Person`. context.register_global_class::().unwrap(); - forward_val( - &mut context, - r" + context + .eval( + r" let person = new Person('John', 19); person.sayHello(); @@ -140,6 +136,6 @@ fn main() { console.log(person.inheritedProperty); console.log(Person.prototype.inheritedProperty === person.inheritedProperty); ", - ) - .unwrap(); + ) + .unwrap(); } diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index c54aad546e..7a262acd45 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -15,15 +15,11 @@ mod tests; use super::function::{make_builtin_fn, make_constructor_fn}; use crate::{ builtins::object::{ObjectData, PROTOTYPE}, - exec::Interpreter, property::{Attribute, Property}, value::{same_value_zero, Value}, - BoaProfiler, Result, -}; -use std::{ - borrow::Borrow, - cmp::{max, min}, + BoaProfiler, Context, Result, }; +use std::cmp::{max, min}; /// JavaScript `Array` built-in implementation. #[derive(Debug, Clone, Copy)] @@ -37,7 +33,7 @@ impl Array { pub(crate) const LENGTH: usize = 1; /// Creates a new `Array` instance. - pub(crate) fn new_array(interpreter: &Interpreter) -> Result { + pub(crate) fn new_array(interpreter: &Context) -> Result { let array = Value::new_object(Some( &interpreter .realm() @@ -52,10 +48,9 @@ impl Array { .environment .get_binding_value("Array") .expect("Array was not initialized") - .borrow() .get_field(PROTOTYPE), ); - array.borrow().set_field("length", Value::from(0)); + array.set_field("length", Value::from(0)); Ok(array) } @@ -104,12 +99,12 @@ impl Array { } /// Create a new array - pub(crate) fn make_array(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn make_array(this: &Value, args: &[Value], ctx: &mut Context) -> Result { // Make a new Object which will internally represent the Array (mapping // between indices and values): this creates an Object with no prototype // Set Prototype - let prototype = ctx.realm.global_obj.get_field("Array").get_field(PROTOTYPE); + let prototype = ctx.global_object().get_field("Array").get_field(PROTOTYPE); this.as_object_mut() .expect("this should be an array object") @@ -163,7 +158,7 @@ impl Array { pub(crate) fn is_array( _this: &Value, args: &[Value], - _interpreter: &mut Interpreter, + _interpreter: &mut Context, ) -> Result { match args.get(0).and_then(|x| x.as_object()) { Some(object) => Ok(Value::from(object.is_array())), @@ -183,7 +178,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.concat /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat - pub(crate) fn concat(this: &Value, args: &[Value], _: &mut Interpreter) -> Result { + pub(crate) fn concat(this: &Value, args: &[Value], _: &mut Context) -> Result { if args.is_empty() { // If concat is called with no arguments, it returns the original array return Ok(this.clone()); @@ -220,7 +215,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.push /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push - pub(crate) fn push(this: &Value, args: &[Value], _: &mut Interpreter) -> Result { + pub(crate) fn push(this: &Value, args: &[Value], _: &mut Context) -> Result { let new_array = Self::add_to_array_object(this, args)?; Ok(new_array.get_field("length")) } @@ -235,7 +230,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.pop /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop - pub(crate) fn pop(this: &Value, _: &[Value], _: &mut Interpreter) -> Result { + pub(crate) fn pop(this: &Value, _: &[Value], _: &mut Context) -> Result { let curr_length = this.get_field("length").as_number().unwrap() as i32; if curr_length < 1 { @@ -258,11 +253,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.foreach /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach - pub(crate) fn for_each( - this: &Value, - args: &[Value], - interpreter: &mut Interpreter, - ) -> Result { + pub(crate) fn for_each(this: &Value, args: &[Value], ctx: &mut Context) -> Result { if args.is_empty() { return Err(Value::from("Missing argument for Array.prototype.forEach")); } @@ -276,7 +267,7 @@ impl Array { let element = this.get_field(i); let arguments = [element, Value::from(i), this.clone()]; - interpreter.call(callback_arg, &this_arg, &arguments)?; + ctx.call(callback_arg, &this_arg, &arguments)?; } Ok(Value::undefined()) @@ -294,7 +285,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.join /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join - pub(crate) fn join(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn join(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let separator = if args.is_empty() { String::from(",") } else { @@ -327,7 +318,7 @@ impl Array { /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.tostring /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toString #[allow(clippy::wrong_self_convention)] - pub(crate) fn to_string(this: &Value, _args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn to_string(this: &Value, _args: &[Value], ctx: &mut Context) -> Result { let method_name = "join"; let mut arguments = vec![Value::from(",")]; // 2. @@ -335,8 +326,7 @@ impl Array { // 3. if !method.is_function() { method = ctx - .realm - .global_obj + .global_object() .get_field("Object") .get_field(PROTOTYPE) .get_field("toString"); @@ -367,7 +357,7 @@ impl Array { /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.reverse /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse #[allow(clippy::else_if_without_else)] - pub(crate) fn reverse(this: &Value, _: &[Value], _: &mut Interpreter) -> Result { + pub(crate) fn reverse(this: &Value, _: &[Value], _: &mut Context) -> Result { let len = this.get_field("length").as_number().unwrap() as i32; let middle: i32 = len.wrapping_div(2); @@ -406,7 +396,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.shift /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift - pub(crate) fn shift(this: &Value, _: &[Value], _: &mut Interpreter) -> Result { + pub(crate) fn shift(this: &Value, _: &[Value], _: &mut Context) -> Result { let len = this.get_field("length").as_number().unwrap() as i32; if len == 0 { @@ -447,7 +437,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.unshift /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift - pub(crate) fn unshift(this: &Value, args: &[Value], _: &mut Interpreter) -> Result { + pub(crate) fn unshift(this: &Value, args: &[Value], _: &mut Context) -> Result { let len = this.get_field("length").as_number().unwrap() as i32; let arg_c: i32 = args.len() as i32; @@ -492,11 +482,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.every /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every - pub(crate) fn every( - this: &Value, - args: &[Value], - interpreter: &mut Interpreter, - ) -> Result { + pub(crate) fn every(this: &Value, args: &[Value], interpreter: &mut Context) -> Result { if args.is_empty() { return Err(Value::from( "missing callback when calling function Array.prototype.every", @@ -538,11 +524,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.map /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map - pub(crate) fn map( - this: &Value, - args: &[Value], - interpreter: &mut Interpreter, - ) -> Result { + pub(crate) fn map(this: &Value, args: &[Value], interpreter: &mut Context) -> Result { if args.is_empty() { return Err(Value::from( "missing argument 0 when calling function Array.prototype.map", @@ -589,7 +571,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.indexof /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf - pub(crate) fn index_of(this: &Value, args: &[Value], _: &mut Interpreter) -> Result { + pub(crate) fn index_of(this: &Value, args: &[Value], _: &mut Context) -> Result { // If no arguments, return -1. Not described in spec, but is what chrome does. if args.is_empty() { return Ok(Value::from(-1)); @@ -642,11 +624,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.lastindexof /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf - pub(crate) fn last_index_of( - this: &Value, - args: &[Value], - _: &mut Interpreter, - ) -> Result { + pub(crate) fn last_index_of(this: &Value, args: &[Value], _: &mut Context) -> Result { // If no arguments, return -1. Not described in spec, but is what chrome does. if args.is_empty() { return Ok(Value::from(-1)); @@ -696,11 +674,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.find /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find - pub(crate) fn find( - this: &Value, - args: &[Value], - interpreter: &mut Interpreter, - ) -> Result { + pub(crate) fn find(this: &Value, args: &[Value], interpreter: &mut Context) -> Result { if args.is_empty() { return Err(Value::from( "missing callback when calling function Array.prototype.find", @@ -735,7 +709,7 @@ impl Array { pub(crate) fn find_index( this: &Value, args: &[Value], - interpreter: &mut Interpreter, + interpreter: &mut Context, ) -> Result { if args.is_empty() { return Err(Value::from( @@ -774,7 +748,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.fill /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill - pub(crate) fn fill(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn fill(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let len: i32 = this.get_field("length").as_number().unwrap() as i32; let default_value = Value::undefined(); @@ -814,11 +788,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.includes /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes - pub(crate) fn includes_value( - this: &Value, - args: &[Value], - _: &mut Interpreter, - ) -> Result { + pub(crate) fn includes_value(this: &Value, args: &[Value], _: &mut Context) -> Result { let search_element = args.get(0).cloned().unwrap_or_else(Value::undefined); let length = this.get_field("length").as_number().unwrap() as i32; @@ -848,11 +818,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.slice /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice - pub(crate) fn slice( - this: &Value, - args: &[Value], - interpreter: &mut Interpreter, - ) -> Result { + pub(crate) fn slice(this: &Value, args: &[Value], interpreter: &mut Context) -> Result { let new_array = Self::new_array(interpreter)?; let len = this.get_field("length").as_number().unwrap() as i32; @@ -897,11 +863,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.filter /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter - pub(crate) fn filter( - this: &Value, - args: &[Value], - interpreter: &mut Interpreter, - ) -> Result { + pub(crate) fn filter(this: &Value, args: &[Value], interpreter: &mut Context) -> Result { if args.is_empty() { return Err(Value::from( "missing argument 0 when calling function Array.prototype.filter", @@ -951,11 +913,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.some /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some - pub(crate) fn some( - this: &Value, - args: &[Value], - interpreter: &mut Interpreter, - ) -> Result { + pub(crate) fn some(this: &Value, args: &[Value], interpreter: &mut Context) -> Result { if args.is_empty() { return Err(Value::from( "missing callback when calling function Array.prototype.some", @@ -998,11 +956,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.reduce /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce - pub(crate) fn reduce( - this: &Value, - args: &[Value], - interpreter: &mut Interpreter, - ) -> Result { + pub(crate) fn reduce(this: &Value, args: &[Value], interpreter: &mut Context) -> Result { let this = this.to_object(interpreter)?; let callback = match args.get(0) { Some(value) if value.is_function() => value, @@ -1063,7 +1017,7 @@ impl Array { pub(crate) fn reduce_right( this: &Value, args: &[Value], - interpreter: &mut Interpreter, + interpreter: &mut Context, ) -> Result { let this = this.to_object(interpreter)?; let callback = match args.get(0) { @@ -1136,8 +1090,8 @@ impl Array { /// Initialise the `Array` object on the global object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { - let global = interpreter.global(); + pub(crate) fn init(interpreter: &mut Context) -> (&'static str, Value) { + let global = interpreter.global_object(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); // Create prototype diff --git a/boa/src/builtins/array/tests.rs b/boa/src/builtins/array/tests.rs index 378ef0d9ad..fa066ad979 100644 --- a/boa/src/builtins/array/tests.rs +++ b/boa/src/builtins/array/tests.rs @@ -1,42 +1,68 @@ -use crate::{exec::Interpreter, forward, realm::Realm}; +use crate::{forward, Context, Value}; #[test] fn is_array() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var empty = []; var new_arr = new Array(); var many = ["a", "b", "c"]; "#; - eprintln!("{}", forward(&mut engine, init)); - assert_eq!(forward(&mut engine, "Array.isArray(empty)"), "true"); - assert_eq!(forward(&mut engine, "Array.isArray(new_arr)"), "true"); - assert_eq!(forward(&mut engine, "Array.isArray(many)"), "true"); - assert_eq!(forward(&mut engine, "Array.isArray([1, 2, 3])"), "true"); - assert_eq!(forward(&mut engine, "Array.isArray([])"), "true"); - assert_eq!(forward(&mut engine, "Array.isArray({})"), "false"); - // assert_eq!(forward(&mut engine, "Array.isArray(new Array)"), "true"); - assert_eq!(forward(&mut engine, "Array.isArray()"), "false"); + engine.eval(init).unwrap(); assert_eq!( - forward(&mut engine, "Array.isArray({ constructor: Array })"), - "false" + engine.eval("Array.isArray(empty)").unwrap(), + Value::Boolean(true) ); assert_eq!( - forward( - &mut engine, - "Array.isArray({ push: Array.prototype.push, concat: Array.prototype.concat })" - ), - "false" + engine.eval("Array.isArray(new_arr)").unwrap(), + Value::Boolean(true) + ); + assert_eq!( + engine.eval("Array.isArray(many)").unwrap(), + Value::Boolean(true) ); - assert_eq!(forward(&mut engine, "Array.isArray(17)"), "false"); assert_eq!( - forward(&mut engine, "Array.isArray({ __proto__: Array.prototype })"), - "false" + engine.eval("Array.isArray([1, 2, 3])").unwrap(), + Value::Boolean(true) ); assert_eq!( - forward(&mut engine, "Array.isArray({ length: 0 })"), - "false" + engine.eval("Array.isArray([])").unwrap(), + Value::Boolean(true) + ); + assert_eq!( + engine.eval("Array.isArray({})").unwrap(), + Value::Boolean(false) + ); + // assert_eq!(engine.eval("Array.isArray(new Array)"), "true"); + assert_eq!( + engine.eval("Array.isArray()").unwrap(), + Value::Boolean(false) + ); + assert_eq!( + engine + .eval("Array.isArray({ constructor: Array })") + .unwrap(), + Value::Boolean(false) + ); + assert_eq!( + engine + .eval("Array.isArray({ push: Array.prototype.push, concat: Array.prototype.concat })") + .unwrap(), + Value::Boolean(false) + ); + assert_eq!( + engine.eval("Array.isArray(17)").unwrap(), + Value::Boolean(false) + ); + assert_eq!( + engine + .eval("Array.isArray({ __proto__: Array.prototype })") + .unwrap(), + Value::Boolean(false) + ); + assert_eq!( + engine.eval("Array.isArray({ length: 0 })").unwrap(), + Value::Boolean(false) ); } @@ -44,31 +70,45 @@ fn is_array() { #[ignore] fn concat() { //TODO: array display formatter - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var empty = new Array(); var one = new Array(1); "#; - eprintln!("{}", forward(&mut engine, init)); + engine.eval(init).unwrap(); // Empty ++ Empty - let ee = forward(&mut engine, "empty.concat(empty)"); - assert_eq!(ee, String::from("[]")); + let ee = engine + .eval("empty.concat(empty)") + .unwrap() + .to_string(&mut engine) + .unwrap(); + assert_eq!(ee, "[]"); // Empty ++ NonEmpty - let en = forward(&mut engine, "empty.concat(one)"); - assert_eq!(en, String::from("[a]")); + let en = engine + .eval("empty.concat(one)") + .unwrap() + .to_string(&mut engine) + .unwrap(); + assert_eq!(en, "[a]"); // NonEmpty ++ Empty - let ne = forward(&mut engine, "one.concat(empty)"); - assert_eq!(ne, String::from("a.b.c")); + let ne = engine + .eval("one.concat(empty)") + .unwrap() + .to_string(&mut engine) + .unwrap(); + assert_eq!(ne, "a.b.c"); // NonEmpty ++ NonEmpty - let nn = forward(&mut engine, "one.concat(one)"); - assert_eq!(nn, String::from("a.b.c")); + let nn = engine + .eval("one.concat(one)") + .unwrap() + .to_string(&mut engine) + .unwrap(); + assert_eq!(nn, "a.b.c"); } #[test] fn join() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var empty = [ ]; var one = ["a"]; @@ -88,8 +128,7 @@ fn join() { #[test] fn to_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var empty = [ ]; var one = ["a"]; @@ -109,8 +148,7 @@ fn to_string() { #[test] fn every() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); // taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every let init = r#" var empty = []; @@ -154,8 +192,7 @@ fn every() { #[test] fn find() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" function comp(a) { return a == "a"; @@ -169,8 +206,7 @@ fn find() { #[test] fn find_index() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let code = r#" function comp(item) { @@ -195,8 +231,7 @@ fn find_index() { #[test] fn push() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var arr = [1, 2]; "#; @@ -210,8 +245,7 @@ fn push() { #[test] fn pop() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var empty = [ ]; var one = [1]; @@ -232,8 +266,7 @@ fn pop() { #[test] fn shift() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var empty = [ ]; var one = [1]; @@ -254,8 +287,7 @@ fn shift() { #[test] fn unshift() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var arr = [3, 4]; "#; @@ -269,8 +301,7 @@ fn unshift() { #[test] fn reverse() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var arr = [1, 2]; var reversed = arr.reverse(); @@ -284,8 +315,7 @@ fn reverse() { #[test] fn index_of() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var empty = [ ]; var one = ["a"]; @@ -348,8 +378,7 @@ fn index_of() { #[test] fn last_index_of() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var empty = [ ]; var one = ["a"]; @@ -412,8 +441,7 @@ fn last_index_of() { #[test] fn fill_obj_ref() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); // test object reference forward(&mut engine, "a = (new Array(3)).fill({});"); @@ -423,8 +451,7 @@ fn fill_obj_ref() { #[test] fn fill() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); forward(&mut engine, "var a = [1, 2, 3];"); assert_eq!( @@ -519,8 +546,7 @@ fn fill() { #[test] fn includes_value() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var empty = [ ]; var one = ["a"]; @@ -558,8 +584,7 @@ fn includes_value() { #[test] fn map() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let js = r#" var empty = []; @@ -622,8 +647,7 @@ fn map() { #[test] fn slice() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var empty = [ ].slice(); var one = ["a"].slice(); @@ -646,8 +670,7 @@ fn slice() { #[test] fn for_each() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = [2, 3, 4, 5]; var sum = 0; @@ -669,8 +692,7 @@ fn for_each() { #[test] fn for_each_push_value() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = [1, 2, 3, 4]; function callingCallback(item, index, list) { @@ -690,8 +712,7 @@ fn for_each_push_value() { #[test] fn filter() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let js = r#" var empty = []; @@ -760,8 +781,7 @@ fn filter() { #[test] fn some() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var empty = []; @@ -809,8 +829,7 @@ fn some() { #[test] fn reduce() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var arr = [1, 2, 3, 4]; @@ -919,8 +938,7 @@ fn reduce() { #[test] fn reduce_right() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var arr = [1, 2, 3, 4]; @@ -1042,8 +1060,7 @@ fn reduce_right() { #[test] fn call_array_constructor_with_one_argument() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var empty = new Array(0); diff --git a/boa/src/builtins/bigint/conversions.rs b/boa/src/builtins/bigint/conversions.rs index b03c759b6c..88494ad0a5 100644 --- a/boa/src/builtins/bigint/conversions.rs +++ b/boa/src/builtins/bigint/conversions.rs @@ -1,6 +1,6 @@ use super::BigInt; -use crate::{builtins::Number, exec::Interpreter, Value}; +use crate::{builtins::Number, Context, Value}; use num_traits::cast::{FromPrimitive, ToPrimitive}; use std::convert::TryFrom; @@ -14,7 +14,7 @@ impl BigInt { /// /// [spec]: https://tc39.es/ecma262/#sec-stringtobigint #[inline] - pub(crate) fn from_string(string: &str, _ctx: &mut Interpreter) -> Result { + pub(crate) fn from_string(string: &str, _ctx: &mut Context) -> Result { if string.is_empty() { return Ok(BigInt::from(0)); } diff --git a/boa/src/builtins/bigint/mod.rs b/boa/src/builtins/bigint/mod.rs index f22cd2f479..aedc84363a 100644 --- a/boa/src/builtins/bigint/mod.rs +++ b/boa/src/builtins/bigint/mod.rs @@ -17,9 +17,8 @@ use crate::{ function::{make_builtin_fn, make_constructor_fn}, object::ObjectData, }, - exec::Interpreter, value::{RcBigInt, Value}, - BoaProfiler, Result, + BoaProfiler, Context, Result, }; use gc::{unsafe_empty_trace, Finalize, Trace}; @@ -61,7 +60,7 @@ impl BigInt { /// /// [spec]: https://tc39.es/ecma262/#sec-thisbigintvalue #[inline] - fn this_bigint_value(value: &Value, ctx: &mut Interpreter) -> Result { + fn this_bigint_value(value: &Value, ctx: &mut Context) -> Result { match value { // 1. If Type(value) is BigInt, return value. Value::BigInt(ref bigint) => return Ok(bigint.clone()), @@ -91,7 +90,7 @@ impl BigInt { /// /// [spec]: https://tc39.es/ecma262/#sec-bigint-objects /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/BigInt - pub(crate) fn make_bigint(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn make_bigint(_: &Value, args: &[Value], ctx: &mut Context) -> Result { let data = match args.get(0) { Some(ref value) => value.to_bigint(ctx)?, None => RcBigInt::from(Self::from(0)), @@ -110,7 +109,7 @@ impl BigInt { /// [spec]: https://tc39.es/ecma262/#sec-bigint.prototype.tostring /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString #[allow(clippy::wrong_self_convention)] - pub(crate) fn to_string(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn to_string(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let radix = if !args.is_empty() { args[0].to_integer(ctx)? as i32 } else { @@ -135,7 +134,7 @@ impl BigInt { /// /// [spec]: https://tc39.es/ecma262/#sec-bigint.prototype.valueof /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/valueOf - pub(crate) fn value_of(this: &Value, _args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn value_of(this: &Value, _args: &[Value], ctx: &mut Context) -> Result { Ok(Value::from(Self::this_bigint_value(this, ctx)?)) } @@ -146,7 +145,7 @@ impl BigInt { /// [spec]: https://tc39.es/ecma262/#sec-bigint.asintn /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asIntN #[allow(clippy::wrong_self_convention)] - pub(crate) fn as_int_n(_this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn as_int_n(_this: &Value, args: &[Value], ctx: &mut Context) -> Result { let (modulo, bits) = Self::calculate_as_uint_n(args, ctx)?; if bits > 0 && modulo >= BigInt::from(2).pow(&BigInt::from(bits as i64 - 1)) { @@ -165,7 +164,7 @@ impl BigInt { /// [spec]: https://tc39.es/ecma262/#sec-bigint.asuintn /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asUintN #[allow(clippy::wrong_self_convention)] - pub(crate) fn as_uint_n(_this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn as_uint_n(_this: &Value, args: &[Value], ctx: &mut Context) -> Result { let (modulo, _) = Self::calculate_as_uint_n(args, ctx)?; Ok(Value::from(modulo)) @@ -176,7 +175,7 @@ impl BigInt { /// This function expects the same arguments as `as_uint_n` and wraps the value of a `BigInt`. /// Additionally to the wrapped unsigned value it returns the converted `bits` argument, so it /// can be reused from the `as_int_n` method. - fn calculate_as_uint_n(args: &[Value], ctx: &mut Interpreter) -> Result<(BigInt, u32)> { + fn calculate_as_uint_n(args: &[Value], ctx: &mut Context) -> Result<(BigInt, u32)> { use std::convert::TryFrom; let undefined_value = Value::undefined(); @@ -200,8 +199,8 @@ impl BigInt { /// Initialise the `BigInt` object on the global object. #[inline] - pub fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { - let global = interpreter.global(); + pub fn init(interpreter: &mut Context) -> (&'static str, Value) { + let global = interpreter.global_object(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let prototype = Value::new_object(Some(global)); diff --git a/boa/src/builtins/bigint/tests.rs b/boa/src/builtins/bigint/tests.rs index d816fac806..e190496ecb 100644 --- a/boa/src/builtins/bigint/tests.rs +++ b/boa/src/builtins/bigint/tests.rs @@ -1,9 +1,8 @@ -use crate::{forward, Interpreter, Realm}; +use crate::{forward, Context}; #[test] fn equality() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "0n == 0n"), "true"); assert_eq!(forward(&mut engine, "1n == 0n"), "false"); @@ -56,8 +55,7 @@ fn equality() { #[test] fn bigint_function_conversion_from_integer() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "BigInt(1000)"), "1000n"); assert_eq!( @@ -72,8 +70,7 @@ fn bigint_function_conversion_from_integer() { #[test] fn bigint_function_conversion_from_rational() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "BigInt(0.0)"), "0n"); assert_eq!(forward(&mut engine, "BigInt(1.0)"), "1n"); @@ -82,8 +79,7 @@ fn bigint_function_conversion_from_rational() { #[test] fn bigint_function_conversion_from_rational_with_fractional_part() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let scenario = r#" try { @@ -100,8 +96,7 @@ fn bigint_function_conversion_from_rational_with_fractional_part() { #[test] fn bigint_function_conversion_from_null() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let scenario = r#" try { @@ -118,8 +113,7 @@ fn bigint_function_conversion_from_null() { #[test] fn bigint_function_conversion_from_undefined() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let scenario = r#" try { @@ -136,8 +130,7 @@ fn bigint_function_conversion_from_undefined() { #[test] fn bigint_function_conversion_from_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "BigInt('')"), "0n"); assert_eq!( @@ -152,24 +145,21 @@ fn bigint_function_conversion_from_string() { #[test] fn add() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "10000n + 1000n"), "11000n"); } #[test] fn sub() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "10000n - 1000n"), "9000n"); } #[test] fn mul() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!( forward(&mut engine, "123456789n * 102030n"), @@ -179,32 +169,28 @@ fn mul() { #[test] fn div() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "15000n / 50n"), "300n"); } #[test] fn div_with_truncation() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "15001n / 50n"), "300n"); } #[test] fn r#mod() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "15007n % 10n"), "7n"); } #[test] fn pow() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!( forward(&mut engine, "100n ** 10n"), @@ -214,8 +200,7 @@ fn pow() { #[test] fn to_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "1000n.toString()"), "\"1000\""); assert_eq!(forward(&mut engine, "1000n.toString(2)"), "\"1111101000\""); @@ -225,8 +210,7 @@ fn to_string() { #[test] fn as_int_n() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "BigInt.asIntN(0, 1n)"), "0n"); assert_eq!(forward(&mut engine, "BigInt.asIntN(1, 1n)"), "-1n"); @@ -286,8 +270,7 @@ fn as_int_n() { #[test] fn as_int_n_errors() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_throws(&mut engine, "BigInt.asIntN(-1, 0n)", "RangeError"); assert_throws(&mut engine, "BigInt.asIntN(-2.5, 0n)", "RangeError"); @@ -301,8 +284,7 @@ fn as_int_n_errors() { #[test] fn as_uint_n() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "BigInt.asUintN(0, -2n)"), "0n"); assert_eq!(forward(&mut engine, "BigInt.asUintN(0, -1n)"), "0n"); @@ -353,8 +335,7 @@ fn as_uint_n() { #[test] fn as_uint_n_errors() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_throws(&mut engine, "BigInt.asUintN(-1, 0n)", "RangeError"); assert_throws(&mut engine, "BigInt.asUintN(-2.5, 0n)", "RangeError"); @@ -366,7 +347,7 @@ fn as_uint_n_errors() { assert_throws(&mut engine, "BigInt.asUintN(0n, 0n)", "TypeError"); } -fn assert_throws(engine: &mut Interpreter, src: &str, error_type: &str) { +fn assert_throws(engine: &mut Context, src: &str, error_type: &str) { let result = forward(engine, src); assert!(result.contains(error_type)); } diff --git a/boa/src/builtins/boolean/mod.rs b/boa/src/builtins/boolean/mod.rs index 70d94fca32..f4ea177a3f 100644 --- a/boa/src/builtins/boolean/mod.rs +++ b/boa/src/builtins/boolean/mod.rs @@ -13,7 +13,7 @@ mod tests; use super::function::{make_builtin_fn, make_constructor_fn}; -use crate::{builtins::object::ObjectData, exec::Interpreter, BoaProfiler, Result, Value}; +use crate::{builtins::object::ObjectData, BoaProfiler, Context, Result, Value}; /// Boolean implementation. #[derive(Debug, Clone, Copy)] @@ -32,7 +32,7 @@ impl Boolean { /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-thisbooleanvalue - fn this_boolean_value(value: &Value, ctx: &mut Interpreter) -> Result { + fn this_boolean_value(value: &Value, ctx: &mut Context) -> Result { match value { Value::Boolean(boolean) => return Ok(*boolean), Value::Object(ref object) => { @@ -53,7 +53,7 @@ impl Boolean { pub(crate) fn construct_boolean( this: &Value, args: &[Value], - _: &mut Interpreter, + _: &mut Context, ) -> Result { // Get the argument, if any let data = args.get(0).map(|x| x.to_boolean()).unwrap_or(false); @@ -71,7 +71,7 @@ impl Boolean { /// [spec]: https://tc39.es/ecma262/#sec-boolean-object /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean/toString #[allow(clippy::wrong_self_convention)] - pub(crate) fn to_string(this: &Value, _: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn to_string(this: &Value, _: &[Value], ctx: &mut Context) -> Result { let boolean = Self::this_boolean_value(this, ctx)?; Ok(Value::from(boolean.to_string())) } @@ -85,14 +85,14 @@ impl Boolean { /// [spec]: https://tc39.es/ecma262/#sec-boolean.prototype.valueof /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean/valueOf #[inline] - pub(crate) fn value_of(this: &Value, _: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn value_of(this: &Value, _: &[Value], ctx: &mut Context) -> Result { Ok(Value::from(Self::this_boolean_value(this, ctx)?)) } /// Initialise the `Boolean` object on the global object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { - let global = interpreter.global(); + pub(crate) fn init(interpreter: &mut Context) -> (&'static str, Value) { + let global = interpreter.global_object(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); // Create Prototype diff --git a/boa/src/builtins/boolean/tests.rs b/boa/src/builtins/boolean/tests.rs index 84eae25e80..9008983d5f 100644 --- a/boa/src/builtins/boolean/tests.rs +++ b/boa/src/builtins/boolean/tests.rs @@ -1,11 +1,10 @@ -use crate::{exec::Interpreter, forward, forward_val, realm::Realm, value::same_value}; +use crate::{forward, forward_val, value::same_value, Context}; /// Test the correct type is returned from call and construct #[allow(clippy::unwrap_used)] #[test] fn construct_and_call() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var one = new Boolean(1); var zero = Boolean(0); @@ -20,8 +19,7 @@ fn construct_and_call() { #[test] fn constructor_gives_true_instance() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var trueVal = new Boolean(true); var trueNum = new Boolean(1); @@ -50,8 +48,7 @@ fn constructor_gives_true_instance() { #[test] fn instances_have_correct_proto_set() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var boolInstance = new Boolean(true); var boolProto = Boolean.prototype; diff --git a/boa/src/builtins/console/mod.rs b/boa/src/builtins/console/mod.rs index 48c5e3bd5f..b9504f7a9e 100644 --- a/boa/src/builtins/console/mod.rs +++ b/boa/src/builtins/console/mod.rs @@ -18,9 +18,8 @@ mod tests; use crate::{ builtins::function::make_builtin_fn, - exec::Interpreter, value::{display_obj, RcString, Value}, - BoaProfiler, Result, + BoaProfiler, Context, Result, }; use rustc_hash::FxHashMap; use std::time::SystemTime; @@ -57,7 +56,7 @@ pub(crate) fn logger(msg: LogMessage, console_state: &Console) { } /// This represents the `console` formatter. -pub fn formatter(data: &[Value], ctx: &mut Interpreter) -> Result { +pub fn formatter(data: &[Value], ctx: &mut Context) -> Result { let target = data.get(0).cloned().unwrap_or_default().to_string(ctx)?; match data.len() { @@ -152,7 +151,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#assert /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/assert - pub(crate) fn assert(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn assert(_: &Value, args: &[Value], ctx: &mut Context) -> Result { let assertion = get_arg_at_index::(args, 0).unwrap_or_default(); if !assertion { @@ -183,7 +182,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#clear /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/clear - pub(crate) fn clear(_: &Value, _: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn clear(_: &Value, _: &[Value], ctx: &mut Context) -> Result { ctx.console_mut().groups.clear(); Ok(Value::undefined()) } @@ -198,7 +197,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#debug /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/debug - pub(crate) fn debug(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn debug(_: &Value, args: &[Value], ctx: &mut Context) -> Result { logger(LogMessage::Log(formatter(args, ctx)?), ctx.console()); Ok(Value::undefined()) } @@ -213,7 +212,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#error /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/error - pub(crate) fn error(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn error(_: &Value, args: &[Value], ctx: &mut Context) -> Result { logger(LogMessage::Error(formatter(args, ctx)?), ctx.console()); Ok(Value::undefined()) } @@ -228,7 +227,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#info /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/info - pub(crate) fn info(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn info(_: &Value, args: &[Value], ctx: &mut Context) -> Result { logger(LogMessage::Info(formatter(args, ctx)?), ctx.console()); Ok(Value::undefined()) } @@ -243,7 +242,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#log /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/log - pub(crate) fn log(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn log(_: &Value, args: &[Value], ctx: &mut Context) -> Result { logger(LogMessage::Log(formatter(args, ctx)?), ctx.console()); Ok(Value::undefined()) } @@ -258,7 +257,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#trace /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/trace - pub(crate) fn trace(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn trace(_: &Value, args: &[Value], ctx: &mut Context) -> Result { if !args.is_empty() { logger(LogMessage::Log(formatter(args, ctx)?), ctx.console()); @@ -282,7 +281,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#warn /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/warn - pub(crate) fn warn(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn warn(_: &Value, args: &[Value], ctx: &mut Context) -> Result { logger(LogMessage::Warn(formatter(args, ctx)?), ctx.console()); Ok(Value::undefined()) } @@ -297,7 +296,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#count /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/count - pub(crate) fn count(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn count(_: &Value, args: &[Value], ctx: &mut Context) -> Result { let label = match args.get(0) { Some(value) => value.to_string(ctx)?, None => "default".into(), @@ -321,7 +320,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#countreset /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/countReset - pub(crate) fn count_reset(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn count_reset(_: &Value, args: &[Value], ctx: &mut Context) -> Result { let label = match args.get(0) { Some(value) => value.to_string(ctx)?, None => "default".into(), @@ -355,7 +354,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#time /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/time - pub(crate) fn time(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn time(_: &Value, args: &[Value], ctx: &mut Context) -> Result { let label = match args.get(0) { Some(value) => value.to_string(ctx)?, None => "default".into(), @@ -384,7 +383,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#timelog /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/timeLog - pub(crate) fn time_log(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn time_log(_: &Value, args: &[Value], ctx: &mut Context) -> Result { let label = match args.get(0) { Some(value) => value.to_string(ctx)?, None => "default".into(), @@ -417,7 +416,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#timeend /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/timeEnd - pub(crate) fn time_end(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn time_end(_: &Value, args: &[Value], ctx: &mut Context) -> Result { let label = match args.get(0) { Some(value) => value.to_string(ctx)?, None => "default".into(), @@ -449,7 +448,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#group /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/group - pub(crate) fn group(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn group(_: &Value, args: &[Value], ctx: &mut Context) -> Result { let group_label = formatter(args, ctx)?; logger( @@ -471,7 +470,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#groupend /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/groupEnd - pub(crate) fn group_end(_: &Value, _: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn group_end(_: &Value, _: &[Value], ctx: &mut Context) -> Result { ctx.console_mut().groups.pop(); Ok(Value::undefined()) @@ -487,7 +486,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#dir /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/dir - pub(crate) fn dir(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn dir(_: &Value, args: &[Value], ctx: &mut Context) -> Result { let undefined = Value::undefined(); logger( LogMessage::Info(display_obj(args.get(0).unwrap_or(&undefined), true)), @@ -499,8 +498,8 @@ impl Console { /// Initialise the `console` object on the global object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { - let global = interpreter.global(); + pub(crate) fn init(interpreter: &mut Context) -> (&'static str, Value) { + let global = interpreter.global_object(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let console = Value::new_object(Some(global)); diff --git a/boa/src/builtins/console/tests.rs b/boa/src/builtins/console/tests.rs index 8b293f8145..1a89a3e668 100644 --- a/boa/src/builtins/console/tests.rs +++ b/boa/src/builtins/console/tests.rs @@ -1,24 +1,21 @@ -use crate::{builtins::console::formatter, exec::Interpreter, realm::Realm, Value}; +use crate::{builtins::console::formatter, Context, Value}; #[test] fn formatter_no_args_is_empty_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(formatter(&[], &mut engine).unwrap(), ""); } #[test] fn formatter_empty_format_string_is_empty_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let val = Value::string("".to_string()); assert_eq!(formatter(&[val], &mut engine).unwrap(), ""); } #[test] fn formatter_format_without_args_renders_verbatim() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let val = [Value::string("%d %s %% %f")]; let res = formatter(&val, &mut engine).unwrap(); assert_eq!(res, "%d %s %% %f"); @@ -26,8 +23,7 @@ fn formatter_format_without_args_renders_verbatim() { #[test] fn formatter_empty_format_string_concatenates_rest_of_args() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let val = [ Value::string(""), @@ -40,8 +36,7 @@ fn formatter_empty_format_string_concatenates_rest_of_args() { #[test] fn formatter_utf_8_checks() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let val = [ Value::string("Są takie chwile %dą %są tu%sów %привет%ź".to_string()), @@ -55,8 +50,7 @@ fn formatter_utf_8_checks() { #[test] fn formatter_trailing_format_leader_renders() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let val = [ Value::string("%%%%%".to_string()), @@ -69,8 +63,7 @@ fn formatter_trailing_format_leader_renders() { #[test] #[allow(clippy::approx_constant)] fn formatter_float_format_works() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let val = [Value::string("%f".to_string()), Value::rational(3.1415)]; let res = formatter(&val, &mut engine).unwrap(); diff --git a/boa/src/builtins/date/mod.rs b/boa/src/builtins/date/mod.rs index c88801cb92..46485a8ff7 100644 --- a/boa/src/builtins/date/mod.rs +++ b/boa/src/builtins/date/mod.rs @@ -6,8 +6,8 @@ use crate::{ function::{make_builtin_fn, make_constructor_fn}, object::ObjectData, }, - value::PreferredType, - BoaProfiler, Interpreter, Result, Value, + value::{PreferredType, Value}, + BoaProfiler, Context, Result, }; use chrono::{prelude::*, Duration, LocalResult}; use gc::{unsafe_empty_trace, Finalize, Trace}; @@ -39,13 +39,13 @@ fn ignore_ambiguity(result: LocalResult) -> Option { macro_rules! getter_method { ($name:ident) => {{ - fn get_value(this: &Value, _: &[Value], ctx: &mut Interpreter) -> Result { + fn get_value(this: &Value, _: &[Value], ctx: &mut Context) -> Result { Ok(Value::from(this_time_value(this, ctx)?.$name())) } get_value }}; (Self::$name:ident) => {{ - fn get_value(_: &Value, _: &[Value], _: &mut Interpreter) -> Result { + fn get_value(_: &Value, _: &[Value], _: &mut Context) -> Result { Ok(Value::from(Date::$name())) } get_value @@ -54,7 +54,7 @@ macro_rules! getter_method { macro_rules! setter_method { ($name:ident($($e:expr),* $(,)?)) => {{ - fn set_value(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + fn set_value(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let mut result = this_time_value(this, ctx)?; result.$name( $( @@ -245,7 +245,7 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date-constructor /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date - pub(crate) fn make_date(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn make_date(this: &Value, args: &[Value], ctx: &mut Context) -> Result { if this.is_global() { Self::make_date_string() } else if args.is_empty() { @@ -300,7 +300,7 @@ impl Date { pub(crate) fn make_date_single( this: &Value, args: &[Value], - ctx: &mut Interpreter, + ctx: &mut Context, ) -> Result { let value = &args[0]; let tv = match this_time_value(value, ctx) { @@ -337,7 +337,7 @@ impl Date { pub(crate) fn make_date_multiple( this: &Value, args: &[Value], - ctx: &mut Interpreter, + ctx: &mut Context, ) -> Result { let year = args[0].to_number(ctx)?; let month = args[1].to_number(ctx)?; @@ -1163,7 +1163,7 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.now /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now - pub(crate) fn now(_: &Value, _: &[Value], _: &mut Interpreter) -> Result { + pub(crate) fn now(_: &Value, _: &[Value], _: &mut Context) -> Result { Ok(Value::from(Utc::now().timestamp_millis() as f64)) } @@ -1179,7 +1179,7 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.parse /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse - pub(crate) fn parse(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn parse(_: &Value, args: &[Value], ctx: &mut Context) -> Result { // This method is implementation-defined and discouraged, so we just require the same format as the string // constructor. @@ -1203,7 +1203,7 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.utc /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC - pub(crate) fn utc(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn utc(_: &Value, args: &[Value], ctx: &mut Context) -> Result { let year = args .get(0) .map_or(Ok(f64::NAN), |value| value.to_number(ctx))?; @@ -1241,8 +1241,8 @@ impl Date { /// Initialise the `Date` object on the global object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { - let global = interpreter.global(); + pub(crate) fn init(interpreter: &mut Context) -> (&'static str, Value) { + let global = interpreter.global_object(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let prototype = Value::new_object(Some(global)); @@ -1580,7 +1580,7 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-thistimevalue #[inline] -pub fn this_time_value(value: &Value, ctx: &mut Interpreter) -> Result { +pub fn this_time_value(value: &Value, ctx: &mut Context) -> Result { if let Value::Object(ref object) = value { if let ObjectData::Date(ref date) = object.borrow().data { return Ok(*date); diff --git a/boa/src/builtins/date/tests.rs b/boa/src/builtins/date/tests.rs index 6bb7d9976e..5dd9d01db4 100644 --- a/boa/src/builtins/date/tests.rs +++ b/boa/src/builtins/date/tests.rs @@ -1,12 +1,12 @@ #![allow(clippy::zero_prefixed_literal)] -use crate::{builtins::object::ObjectData, forward, forward_val, Interpreter, Realm, Value}; +use crate::{builtins::object::ObjectData, forward, forward_val, Context, Value}; use chrono::prelude::*; // NOTE: Javascript Uses 0-based months, where chrono uses 1-based months. Many of the assertions look wrong because of // this. -fn forward_dt_utc(engine: &mut Interpreter, src: &str) -> Option { +fn forward_dt_utc(engine: &mut Context, src: &str) -> Option { let date_time = if let Ok(v) = forward_val(engine, src) { v } else { @@ -24,7 +24,7 @@ fn forward_dt_utc(engine: &mut Interpreter, src: &str) -> Option } } -fn forward_dt_local(engine: &mut Interpreter, src: &str) -> Option { +fn forward_dt_local(engine: &mut Context, src: &str) -> Option { let date_time = forward_dt_utc(engine, src); // The timestamp is converted to UTC for internal representation @@ -53,8 +53,7 @@ fn date_display() { #[test] fn date_this_time_value() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let error = forward_val( &mut engine, @@ -74,8 +73,7 @@ fn date_this_time_value() { #[test] fn date_call() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let dt1 = forward(&mut engine, "Date()"); @@ -89,8 +87,7 @@ fn date_call() -> Result<(), Box> { #[test] fn date_ctor_call() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let dt1 = forward_dt_local(&mut engine, "new Date()"); @@ -104,8 +101,7 @@ fn date_ctor_call() -> Result<(), Box> { #[test] fn date_ctor_call_string() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let date_time = forward_dt_utc(&mut engine, "new Date('2020-06-08T09:16:15.779-06:30')"); @@ -119,8 +115,7 @@ fn date_ctor_call_string() -> Result<(), Box> { #[test] fn date_ctor_call_string_invalid() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let date_time = forward_dt_local(&mut engine, "new Date('nope')"); assert_eq!(None, date_time); @@ -129,8 +124,7 @@ fn date_ctor_call_string_invalid() -> Result<(), Box> { #[test] fn date_ctor_call_number() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let date_time = forward_dt_utc(&mut engine, "new Date(1594199775779)"); assert_eq!( @@ -142,8 +136,7 @@ fn date_ctor_call_number() -> Result<(), Box> { #[test] fn date_ctor_call_date() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let date_time = forward_dt_utc(&mut engine, "new Date(new Date(1594199775779))"); @@ -156,8 +149,7 @@ fn date_ctor_call_date() -> Result<(), Box> { #[test] fn date_ctor_call_multiple() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let date_time = forward_dt_local(&mut engine, "new Date(2020, 06, 08, 09, 16, 15, 779)"); @@ -170,8 +162,7 @@ fn date_ctor_call_multiple() -> Result<(), Box> { #[test] fn date_ctor_call_multiple_90s() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let date_time = forward_dt_local(&mut engine, "new Date(99, 06, 08, 09, 16, 15, 779)"); @@ -185,8 +176,7 @@ fn date_ctor_call_multiple_90s() -> Result<(), Box> { #[test] fn date_ctor_call_multiple_nan() -> Result<(), Box> { fn check(src: &str) { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let date_time = forward_dt_local(&mut engine, src); assert_eq!(None, date_time); } @@ -204,8 +194,7 @@ fn date_ctor_call_multiple_nan() -> Result<(), Box> { #[test] fn date_ctor_now_call() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let date_time = forward(&mut engine, "Date.now()"); let dt1 = u64::from_str_radix(&date_time, 10)?; @@ -221,8 +210,7 @@ fn date_ctor_now_call() -> Result<(), Box> { #[test] fn date_ctor_parse_call() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let date_time = forward_val(&mut engine, "Date.parse('2020-06-08T09:16:15.779-07:30')"); @@ -232,8 +220,7 @@ fn date_ctor_parse_call() -> Result<(), Box> { #[test] fn date_ctor_utc_call() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let date_time = forward_val(&mut engine, "Date.UTC(2020, 06, 08, 09, 16, 15, 779)"); @@ -244,8 +231,7 @@ fn date_ctor_utc_call() -> Result<(), Box> { #[test] fn date_ctor_utc_call_nan() -> Result<(), Box> { fn check(src: &str) { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let date_time = forward_val(&mut engine, src).expect("Expected Success"); assert_eq!(Value::Rational(f64::NAN), date_time); } @@ -263,8 +249,7 @@ fn date_ctor_utc_call_nan() -> Result<(), Box> { #[test] fn date_proto_get_date_call() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -280,8 +265,7 @@ fn date_proto_get_date_call() -> Result<(), Box> { #[test] fn date_proto_get_day_call() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -296,8 +280,7 @@ fn date_proto_get_day_call() -> Result<(), Box> { #[test] fn date_proto_get_full_year_call() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -312,8 +295,7 @@ fn date_proto_get_full_year_call() -> Result<(), Box> { #[test] fn date_proto_get_hours_call() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -328,8 +310,7 @@ fn date_proto_get_hours_call() -> Result<(), Box> { #[test] fn date_proto_get_milliseconds_call() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -344,8 +325,7 @@ fn date_proto_get_milliseconds_call() -> Result<(), Box> #[test] fn date_proto_get_minutes_call() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -360,8 +340,7 @@ fn date_proto_get_minutes_call() -> Result<(), Box> { #[test] fn date_proto_get_month() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -377,8 +356,7 @@ fn date_proto_get_month() -> Result<(), Box> { #[test] fn date_proto_get_seconds() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -393,8 +371,7 @@ fn date_proto_get_seconds() -> Result<(), Box> { #[test] fn date_proto_get_time() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -414,8 +391,7 @@ fn date_proto_get_time() -> Result<(), Box> { #[test] fn date_proto_get_year() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -430,8 +406,7 @@ fn date_proto_get_year() -> Result<(), Box> { #[test] fn date_proto_get_timezone_offset() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -461,8 +436,7 @@ fn date_proto_get_timezone_offset() -> Result<(), Box> { #[test] fn date_proto_get_utc_date_call() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -478,8 +452,7 @@ fn date_proto_get_utc_date_call() -> Result<(), Box> { #[test] fn date_proto_get_utc_day_call() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -494,8 +467,7 @@ fn date_proto_get_utc_day_call() -> Result<(), Box> { #[test] fn date_proto_get_utc_full_year_call() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -510,8 +482,7 @@ fn date_proto_get_utc_full_year_call() -> Result<(), Box> #[test] fn date_proto_get_utc_hours_call() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -526,8 +497,7 @@ fn date_proto_get_utc_hours_call() -> Result<(), Box> { #[test] fn date_proto_get_utc_milliseconds_call() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -542,8 +512,7 @@ fn date_proto_get_utc_milliseconds_call() -> Result<(), Box Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -558,8 +527,7 @@ fn date_proto_get_utc_minutes_call() -> Result<(), Box> { #[test] fn date_proto_get_utc_month() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -575,8 +543,7 @@ fn date_proto_get_utc_month() -> Result<(), Box> { #[test] fn date_proto_get_utc_seconds() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -591,8 +558,7 @@ fn date_proto_get_utc_seconds() -> Result<(), Box> { #[test] fn date_proto_set_date() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_dt_local( &mut engine, @@ -624,8 +590,7 @@ fn date_proto_set_date() -> Result<(), Box> { #[test] fn date_proto_set_full_year() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_dt_local( &mut engine, @@ -697,8 +662,7 @@ fn date_proto_set_full_year() -> Result<(), Box> { #[test] fn date_proto_set_hours() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_dt_local( &mut engine, @@ -752,8 +716,7 @@ fn date_proto_set_hours() -> Result<(), Box> { #[test] fn date_proto_set_milliseconds() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_dt_local( &mut engine, @@ -781,8 +744,7 @@ fn date_proto_set_milliseconds() -> Result<(), Box> { #[test] fn date_proto_set_minutes() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_dt_local( &mut engine, @@ -828,8 +790,7 @@ fn date_proto_set_minutes() -> Result<(), Box> { #[test] fn date_proto_set_month() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_dt_local( &mut engine, @@ -866,8 +827,7 @@ fn date_proto_set_month() -> Result<(), Box> { #[test] fn date_proto_set_seconds() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_dt_local( &mut engine, @@ -904,8 +864,7 @@ fn date_proto_set_seconds() -> Result<(), Box> { #[test] fn set_year() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_dt_local( &mut engine, @@ -930,8 +889,7 @@ fn set_year() -> Result<(), Box> { #[test] fn date_proto_set_time() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_dt_local( &mut engine, @@ -947,8 +905,7 @@ fn date_proto_set_time() -> Result<(), Box> { #[test] fn date_proto_set_utc_date() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_dt_utc( &mut engine, @@ -980,8 +937,7 @@ fn date_proto_set_utc_date() -> Result<(), Box> { #[test] fn date_proto_set_utc_full_year() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_dt_utc( &mut engine, @@ -1053,8 +1009,7 @@ fn date_proto_set_utc_full_year() -> Result<(), Box> { #[test] fn date_proto_set_utc_hours() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_dt_utc( &mut engine, @@ -1108,8 +1063,7 @@ fn date_proto_set_utc_hours() -> Result<(), Box> { #[test] fn date_proto_set_utc_milliseconds() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_dt_utc( &mut engine, @@ -1137,8 +1091,7 @@ fn date_proto_set_utc_milliseconds() -> Result<(), Box> { #[test] fn date_proto_set_utc_minutes() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_dt_utc( &mut engine, @@ -1184,8 +1137,7 @@ fn date_proto_set_utc_minutes() -> Result<(), Box> { #[test] fn date_proto_set_utc_month() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_dt_utc( &mut engine, @@ -1222,8 +1174,7 @@ fn date_proto_set_utc_month() -> Result<(), Box> { #[test] fn date_proto_set_utc_seconds() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_dt_utc( &mut engine, @@ -1260,8 +1211,7 @@ fn date_proto_set_utc_seconds() -> Result<(), Box> { #[test] fn date_proto_to_date_string() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -1275,8 +1225,7 @@ fn date_proto_to_date_string() -> Result<(), Box> { #[test] fn date_proto_to_gmt_string() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -1290,8 +1239,7 @@ fn date_proto_to_gmt_string() -> Result<(), Box> { #[test] fn date_proto_to_iso_string() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -1305,8 +1253,7 @@ fn date_proto_to_iso_string() -> Result<(), Box> { #[test] fn date_proto_to_json() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -1320,8 +1267,7 @@ fn date_proto_to_json() -> Result<(), Box> { #[test] fn date_proto_to_string() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -1343,8 +1289,7 @@ fn date_proto_to_string() -> Result<(), Box> { #[test] fn date_proto_to_time_string() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -1364,8 +1309,7 @@ fn date_proto_to_time_string() -> Result<(), Box> { #[test] fn date_proto_to_utc_string() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -1379,8 +1323,7 @@ fn date_proto_to_utc_string() -> Result<(), Box> { #[test] fn date_proto_value_of() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -1394,8 +1337,7 @@ fn date_proto_value_of() -> Result<(), Box> { #[test] fn date_neg() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, @@ -1409,8 +1351,7 @@ fn date_neg() -> Result<(), Box> { #[test] fn date_json() -> Result<(), Box> { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward_val( &mut engine, diff --git a/boa/src/builtins/error/mod.rs b/boa/src/builtins/error/mod.rs index 5b52b4d240..4357f55fc6 100644 --- a/boa/src/builtins/error/mod.rs +++ b/boa/src/builtins/error/mod.rs @@ -15,9 +15,8 @@ use crate::{ function::{make_builtin_fn, make_constructor_fn}, object::ObjectData, }, - exec::Interpreter, profiler::BoaProfiler, - Result, Value, + Context, Result, Value, }; pub(crate) mod range; @@ -46,7 +45,7 @@ impl Error { pub(crate) const LENGTH: usize = 1; /// Create a new error object. - pub(crate) fn make_error(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn make_error(this: &Value, args: &[Value], ctx: &mut Context) -> Result { if let Some(message) = args.get(0) { this.set_field("message", message.to_string(ctx)?); } @@ -68,7 +67,7 @@ impl Error { /// [spec]: https://tc39.es/ecma262/#sec-error.prototype.tostring /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/toString #[allow(clippy::wrong_self_convention)] - pub(crate) fn to_string(this: &Value, _: &[Value], _: &mut Interpreter) -> Result { + pub(crate) fn to_string(this: &Value, _: &[Value], _: &mut Context) -> Result { let name = this.get_field("name"); let message = this.get_field("message"); Ok(Value::from(format!( @@ -80,8 +79,8 @@ impl Error { /// Initialise the global object with the `Error` object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { - let global = interpreter.global(); + pub(crate) fn init(interpreter: &mut Context) -> (&'static str, Value) { + let global = interpreter.global_object(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let prototype = Value::new_object(Some(global)); diff --git a/boa/src/builtins/error/range.rs b/boa/src/builtins/error/range.rs index 952d94aff5..8bfe505fe3 100644 --- a/boa/src/builtins/error/range.rs +++ b/boa/src/builtins/error/range.rs @@ -11,9 +11,8 @@ use crate::{ builtins::{function::make_builtin_fn, function::make_constructor_fn, object::ObjectData}, - exec::Interpreter, profiler::BoaProfiler, - Result, Value, + Context, Result, Value, }; /// JavaScript `RangeError` impleentation. @@ -28,7 +27,7 @@ impl RangeError { pub(crate) const LENGTH: usize = 1; /// Create a new error object. - pub(crate) fn make_error(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn make_error(this: &Value, args: &[Value], ctx: &mut Context) -> Result { if let Some(message) = args.get(0) { this.set_field("message", message.to_string(ctx)?); } @@ -50,7 +49,7 @@ impl RangeError { /// [spec]: https://tc39.es/ecma262/#sec-error.prototype.tostring /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/toString #[allow(clippy::wrong_self_convention)] - pub(crate) fn to_string(this: &Value, _: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn to_string(this: &Value, _: &[Value], ctx: &mut Context) -> Result { let name = this.get_field("name").to_string(ctx)?; let message = this.get_field("message").to_string(ctx)?; @@ -59,8 +58,8 @@ impl RangeError { /// Initialise the global object with the `RangeError` object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { - let global = interpreter.global(); + pub(crate) fn init(interpreter: &mut Context) -> (&'static str, Value) { + let global = interpreter.global_object(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let prototype = Value::new_object(Some(global)); diff --git a/boa/src/builtins/error/reference.rs b/boa/src/builtins/error/reference.rs index 811ddf626a..a1310dbc3f 100644 --- a/boa/src/builtins/error/reference.rs +++ b/boa/src/builtins/error/reference.rs @@ -11,9 +11,8 @@ use crate::{ builtins::{function::make_builtin_fn, function::make_constructor_fn, object::ObjectData}, - exec::Interpreter, profiler::BoaProfiler, - Result, Value, + Context, Result, Value, }; #[derive(Debug, Clone, Copy)] @@ -27,7 +26,7 @@ impl ReferenceError { pub(crate) const LENGTH: usize = 1; /// Create a new error object. - pub(crate) fn make_error(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn make_error(this: &Value, args: &[Value], ctx: &mut Context) -> Result { if let Some(message) = args.get(0) { this.set_field("message", message.to_string(ctx)?); } @@ -49,7 +48,7 @@ impl ReferenceError { /// [spec]: https://tc39.es/ecma262/#sec-error.prototype.tostring /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/toString #[allow(clippy::wrong_self_convention)] - pub(crate) fn to_string(this: &Value, _: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn to_string(this: &Value, _: &[Value], ctx: &mut Context) -> Result { let name = this.get_field("name").to_string(ctx)?; let message = this.get_field("message").to_string(ctx)?; @@ -57,8 +56,8 @@ impl ReferenceError { } /// Initialise the global object with the `ReferenceError` object. - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { - let global = interpreter.global(); + pub(crate) fn init(interpreter: &mut Context) -> (&'static str, Value) { + let global = interpreter.global_object(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let prototype = Value::new_object(Some(global)); diff --git a/boa/src/builtins/error/syntax.rs b/boa/src/builtins/error/syntax.rs index 3e0ca8e2f7..30e2dfc188 100644 --- a/boa/src/builtins/error/syntax.rs +++ b/boa/src/builtins/error/syntax.rs @@ -13,9 +13,8 @@ use crate::{ builtins::{function::make_builtin_fn, function::make_constructor_fn, object::ObjectData}, - exec::Interpreter, profiler::BoaProfiler, - Result, Value, + Context, Result, Value, }; /// JavaScript `SyntaxError` impleentation. @@ -30,7 +29,7 @@ impl SyntaxError { pub(crate) const LENGTH: usize = 1; /// Create a new error object. - pub(crate) fn make_error(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn make_error(this: &Value, args: &[Value], ctx: &mut Context) -> Result { if let Some(message) = args.get(0) { this.set_field("message", message.to_string(ctx)?); } @@ -52,7 +51,7 @@ impl SyntaxError { /// [spec]: https://tc39.es/ecma262/#sec-error.prototype.tostring /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/toString #[allow(clippy::wrong_self_convention)] - pub(crate) fn to_string(this: &Value, _: &[Value], _: &mut Interpreter) -> Result { + pub(crate) fn to_string(this: &Value, _: &[Value], _: &mut Context) -> Result { let name = this.get_field("name"); let message = this.get_field("message"); // FIXME: This should not use `.display()` @@ -61,8 +60,8 @@ impl SyntaxError { /// Initialise the global object with the `SyntaxError` object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { - let global = interpreter.global(); + pub(crate) fn init(interpreter: &mut Context) -> (&'static str, Value) { + let global = interpreter.global_object(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let prototype = Value::new_object(Some(global)); diff --git a/boa/src/builtins/error/type.rs b/boa/src/builtins/error/type.rs index 4fc214bdc3..8377c3f54f 100644 --- a/boa/src/builtins/error/type.rs +++ b/boa/src/builtins/error/type.rs @@ -17,8 +17,7 @@ use crate::{ builtins::{function::make_builtin_fn, function::make_constructor_fn, object::ObjectData}, - exec::Interpreter, - BoaProfiler, Result, Value, + BoaProfiler, Context, Result, Value, }; /// JavaScript `TypeError` implementation. @@ -33,7 +32,7 @@ impl TypeError { pub(crate) const LENGTH: usize = 1; /// Create a new error object. - pub(crate) fn make_error(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn make_error(this: &Value, args: &[Value], ctx: &mut Context) -> Result { if let Some(message) = args.get(0) { this.set_field("message", message.to_string(ctx)?); } @@ -55,7 +54,7 @@ impl TypeError { /// [spec]: https://tc39.es/ecma262/#sec-error.prototype.tostring /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/toString #[allow(clippy::wrong_self_convention)] - pub(crate) fn to_string(this: &Value, _: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn to_string(this: &Value, _: &[Value], ctx: &mut Context) -> Result { let name = this.get_field("name").to_string(ctx)?; let message = this.get_field("message").to_string(ctx)?; @@ -64,8 +63,8 @@ impl TypeError { /// Initialise the global object with the `RangeError` object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { - let global = interpreter.global(); + pub(crate) fn init(interpreter: &mut Context) -> (&'static str, Value) { + let global = interpreter.global_object(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let prototype = Value::new_object(Some(global)); diff --git a/boa/src/builtins/function/mod.rs b/boa/src/builtins/function/mod.rs index ba722e7119..24624a115c 100644 --- a/boa/src/builtins/function/mod.rs +++ b/boa/src/builtins/function/mod.rs @@ -17,10 +17,9 @@ use crate::{ Array, }, environment::lexical_environment::Environment, - exec::Interpreter, property::{Attribute, Property}, - syntax::ast::node::{statement_list::RcStatementList, FormalParameter}, - BoaProfiler, Result, Value, + syntax::ast::node::{FormalParameter, RcStatementList}, + BoaProfiler, Context, Result, Value, }; use bitflags::bitflags; use gc::{unsafe_empty_trace, Finalize, Trace}; @@ -29,8 +28,8 @@ use std::fmt::{self, Debug}; #[cfg(test)] mod tests; -/// _fn(this, arguments, ctx) -> Result_ - The signature of a built-in function -pub type NativeFunction = fn(&Value, &[Value], &mut Interpreter) -> Result; +/// _fn(this, arguments, ctx) -> ResultValue_ - The signature of a built-in function +pub type NativeFunction = fn(&Value, &[Value], &mut Context) -> Result; #[derive(Clone, Copy, Finalize)] pub struct BuiltInFunction(pub(crate) NativeFunction); @@ -117,7 +116,7 @@ impl Function { param: &FormalParameter, index: usize, args_list: &[Value], - interpreter: &mut Interpreter, + interpreter: &mut Context, local_env: &Environment, ) { // Create array of values @@ -201,7 +200,7 @@ pub fn create_unmapped_arguments_object(arguments_list: &[Value]) -> Value { /// Create new function `[[Construct]]` /// // This gets called when a new Function() is created. -pub fn make_function(this: &Value, _: &[Value], _: &mut Interpreter) -> Result { +pub fn make_function(this: &Value, _: &[Value], _: &mut Context) -> Result { this.set_data(ObjectData::Function(Function::BuiltIn( BuiltInFunction(|_, _, _| Ok(Value::undefined())), FunctionFlags::CALLABLE | FunctionFlags::CONSTRUCTABLE, @@ -286,7 +285,7 @@ pub fn make_builtin_fn( name: N, parent: &Value, length: usize, - interpreter: &Interpreter, + interpreter: &Context, ) where N: Into, { @@ -296,7 +295,7 @@ pub fn make_builtin_fn( let mut function = Object::function( Function::BuiltIn(function.into(), FunctionFlags::CALLABLE), interpreter - .global() + .global_object() .get_field("Function") .get_field("prototype"), ); @@ -310,8 +309,8 @@ pub fn make_builtin_fn( /// Initialise the `Function` object on the global object. #[inline] -pub fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { - let global = interpreter.global(); +pub fn init(interpreter: &mut Context) -> (&'static str, Value) { + let global = interpreter.global_object(); let _timer = BoaProfiler::global().start_event("function", "init"); let prototype = Value::new_object(Some(global)); diff --git a/boa/src/builtins/function/tests.rs b/boa/src/builtins/function/tests.rs index ca8b8156ef..287734fa30 100644 --- a/boa/src/builtins/function/tests.rs +++ b/boa/src/builtins/function/tests.rs @@ -1,10 +1,10 @@ -use crate::{exec::Interpreter, forward, forward_val, realm::Realm}; +use crate::{forward, forward_val, Context}; #[allow(clippy::float_cmp)] #[test] fn check_arguments_object() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); + let init = r#" function jason(a, b) { return arguments[0]; @@ -26,8 +26,7 @@ fn check_arguments_object() { #[test] fn check_self_mutating_func() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let func = r#" function x() { x.y = 3; diff --git a/boa/src/builtins/global_this/mod.rs b/boa/src/builtins/global_this/mod.rs index f43d9aa38c..23e45020bd 100644 --- a/boa/src/builtins/global_this/mod.rs +++ b/boa/src/builtins/global_this/mod.rs @@ -10,7 +10,7 @@ //! [spec]: https://tc39.es/ecma262/#sec-globalthis //! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis -use crate::{BoaProfiler, Interpreter, Value}; +use crate::{BoaProfiler, Context, Value}; #[cfg(test)] mod tests; @@ -24,8 +24,8 @@ impl GlobalThis { /// Initialize the `globalThis` property on the global object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { - let global = interpreter.global(); + pub(crate) fn init(interpreter: &mut Context) -> (&'static str, Value) { + let global = interpreter.global_object(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); (Self::NAME, global.clone()) diff --git a/boa/src/builtins/infinity/mod.rs b/boa/src/builtins/infinity/mod.rs index e0d2b475b9..b1e8c26da7 100644 --- a/boa/src/builtins/infinity/mod.rs +++ b/boa/src/builtins/infinity/mod.rs @@ -12,7 +12,7 @@ #[cfg(test)] mod tests; -use crate::{BoaProfiler, Interpreter, Value}; +use crate::{BoaProfiler, Context, Value}; /// JavaScript global `Infinity` property. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -24,7 +24,7 @@ impl Infinity { /// Initialize the `Infinity` property on the global object. #[inline] - pub(crate) fn init(_interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(_interpreter: &mut Context) -> (&'static str, Value) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); (Self::NAME, Value::from(f64::INFINITY)) diff --git a/boa/src/builtins/json/mod.rs b/boa/src/builtins/json/mod.rs index 508d1e8bee..dae55bf357 100644 --- a/boa/src/builtins/json/mod.rs +++ b/boa/src/builtins/json/mod.rs @@ -15,9 +15,8 @@ use crate::{ builtins::function::make_builtin_fn, - exec::Interpreter, property::{Property, PropertyKey}, - BoaProfiler, Result, Value, + BoaProfiler, Context, Result, Value, }; use serde_json::{self, Value as JSONValue}; @@ -44,7 +43,7 @@ impl Json { /// /// [spec]: https://tc39.es/ecma262/#sec-json.parse /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse - pub(crate) fn parse(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn parse(_: &Value, args: &[Value], ctx: &mut Context) -> Result { match serde_json::from_str::( &args .get(0) @@ -74,7 +73,7 @@ impl Json { /// [polyfill]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse fn walk( reviver: &Value, - ctx: &mut Interpreter, + ctx: &mut Context, holder: &mut Value, key: &PropertyKey, ) -> Result { @@ -115,7 +114,7 @@ impl Json { /// /// [spec]: https://tc39.es/ecma262/#sec-json.stringify /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify - pub(crate) fn stringify(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn stringify(_: &Value, args: &[Value], ctx: &mut Context) -> Result { let object = match args.get(0) { Some(obj) if obj.is_symbol() || obj.is_function() || obj.is_undefined() => { return Ok(Value::undefined()) @@ -179,8 +178,8 @@ impl Json { /// Initialise the `JSON` object on the global object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { - let global = interpreter.global(); + pub(crate) fn init(interpreter: &mut Context) -> (&'static str, Value) { + let global = interpreter.global_object(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let json = Value::new_object(Some(global)); diff --git a/boa/src/builtins/json/tests.rs b/boa/src/builtins/json/tests.rs index 1f32e91bdd..2c9776e7d9 100644 --- a/boa/src/builtins/json/tests.rs +++ b/boa/src/builtins/json/tests.rs @@ -1,12 +1,8 @@ -use crate::{ - builtins::object::PROTOTYPE, exec::Interpreter, forward, forward_val, realm::Realm, - value::same_value, -}; +use crate::{builtins::object::PROTOTYPE, forward, forward_val, value::same_value, Context}; #[test] fn json_sanity() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!( forward(&mut engine, r#"JSON.parse('{"aaa":"bbb"}').aaa == 'bbb'"#), "true" @@ -22,8 +18,7 @@ fn json_sanity() { #[test] fn json_stringify_remove_undefined_values_from_objects() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward( &mut engine, @@ -36,8 +31,7 @@ fn json_stringify_remove_undefined_values_from_objects() { #[test] fn json_stringify_remove_function_values_from_objects() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward( &mut engine, @@ -50,8 +44,7 @@ fn json_stringify_remove_function_values_from_objects() { #[test] fn json_stringify_remove_symbols_from_objects() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward( &mut engine, @@ -64,8 +57,7 @@ fn json_stringify_remove_symbols_from_objects() { #[test] fn json_stringify_replacer_array_strings() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward( &mut engine, r#"JSON.stringify({aaa: 'bbb', bbb: 'ccc', ccc: 'ddd'}, ['aaa', 'bbb'])"#, @@ -76,8 +68,7 @@ fn json_stringify_replacer_array_strings() { #[test] fn json_stringify_replacer_array_numbers() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward( &mut engine, r#"JSON.stringify({ 0: 'aaa', 1: 'bbb', 2: 'ccc'}, [1, 2])"#, @@ -88,8 +79,7 @@ fn json_stringify_replacer_array_numbers() { #[test] fn json_stringify_replacer_function() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward( &mut engine, r#"JSON.stringify({ aaa: 1, bbb: 2}, (key, value) => { @@ -106,8 +96,7 @@ fn json_stringify_replacer_function() { #[test] fn json_stringify_arrays() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward(&mut engine, r#"JSON.stringify(['a', 'b'])"#); let expected = forward(&mut engine, r#"'["a","b"]'"#); @@ -116,8 +105,7 @@ fn json_stringify_arrays() { #[test] fn json_stringify_object_array() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward(&mut engine, r#"JSON.stringify([{a: 'b'}, {b: 'c'}])"#); let expected = forward(&mut engine, r#"'[{"a":"b"},{"b":"c"}]'"#); @@ -126,8 +114,7 @@ fn json_stringify_object_array() { #[test] fn json_stringify_array_converts_undefined_to_null() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward(&mut engine, r#"JSON.stringify([undefined])"#); let expected = forward(&mut engine, r#"'[null]'"#); @@ -136,8 +123,7 @@ fn json_stringify_array_converts_undefined_to_null() { #[test] fn json_stringify_array_converts_function_to_null() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward(&mut engine, r#"JSON.stringify([() => {}])"#); let expected = forward(&mut engine, r#"'[null]'"#); @@ -146,8 +132,7 @@ fn json_stringify_array_converts_function_to_null() { #[test] fn json_stringify_array_converts_symbol_to_null() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward(&mut engine, r#"JSON.stringify([Symbol()])"#); let expected = forward(&mut engine, r#"'[null]'"#); @@ -155,8 +140,7 @@ fn json_stringify_array_converts_symbol_to_null() { } #[test] fn json_stringify_function_replacer_propogate_error() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual = forward( &mut engine, @@ -177,8 +161,7 @@ fn json_stringify_function_replacer_propogate_error() { #[test] fn json_stringify_function() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual_function = forward(&mut engine, r#"JSON.stringify(() => {})"#); let expected = forward(&mut engine, r#"undefined"#); @@ -188,8 +171,7 @@ fn json_stringify_function() { #[test] fn json_stringify_undefined() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual_undefined = forward(&mut engine, r#"JSON.stringify(undefined)"#); let expected = forward(&mut engine, r#"undefined"#); @@ -198,8 +180,7 @@ fn json_stringify_undefined() { #[test] fn json_stringify_symbol() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual_symbol = forward(&mut engine, r#"JSON.stringify(Symbol())"#); let expected = forward(&mut engine, r#"undefined"#); @@ -209,8 +190,7 @@ fn json_stringify_symbol() { #[test] fn json_stringify_no_args() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual_no_args = forward(&mut engine, r#"JSON.stringify()"#); let expected = forward(&mut engine, r#"undefined"#); @@ -220,8 +200,7 @@ fn json_stringify_no_args() { #[test] fn json_parse_array_with_reviver() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let result = forward_val( &mut engine, r#"JSON.parse('[1,2,3,4]', function(k, v){ @@ -252,8 +231,7 @@ fn json_parse_array_with_reviver() { #[test] fn json_parse_object_with_reviver() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let result = forward( &mut engine, r#" @@ -279,8 +257,7 @@ fn json_parse_object_with_reviver() { #[test] fn json_parse_sets_prototypes() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" const jsonString = "{ \"ob\":{\"ject\":1}, @@ -302,13 +279,11 @@ fn json_parse_sets_prototypes() { .prototype() .clone(); let global_object_prototype = engine - .realm - .global_obj + .global_object() .get_field("Object") .get_field(PROTOTYPE); let global_array_prototype = engine - .realm - .global_obj + .global_object() .get_field("Array") .get_field(PROTOTYPE); assert_eq!( @@ -320,8 +295,7 @@ fn json_parse_sets_prototypes() { #[test] fn json_fields_should_be_enumerable() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let actual_object = forward( &mut engine, r#" diff --git a/boa/src/builtins/map/mod.rs b/boa/src/builtins/map/mod.rs index 75f160dd9b..5fab3455bd 100644 --- a/boa/src/builtins/map/mod.rs +++ b/boa/src/builtins/map/mod.rs @@ -3,9 +3,8 @@ use super::function::{make_builtin_fn, make_constructor_fn}; use crate::{ builtins::object::{ObjectData, PROTOTYPE}, - exec::Interpreter, property::{Attribute, Property}, - BoaProfiler, Result, Value, + BoaProfiler, Context, Result, Value, }; use ordered_map::OrderedMap; @@ -41,7 +40,7 @@ impl Map { /// /// [spec]: https://tc39.es/ecma262/#sec-map.prototype.set /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set - pub(crate) fn set(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn set(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let (key, value) = match args.len() { 0 => (Value::Undefined, Value::Undefined), 1 => (args[0].clone(), Value::Undefined), @@ -74,7 +73,7 @@ impl Map { /// /// [spec]: https://tc39.es/ecma262/#sec-map.prototype.delete /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete - pub(crate) fn delete(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn delete(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let undefined = Value::Undefined; let key = match args.len() { 0 => &undefined, @@ -106,7 +105,7 @@ impl Map { /// /// [spec]: https://tc39.es/ecma262/#sec-map.prototype.get /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get - pub(crate) fn get(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn get(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let undefined = Value::Undefined; let key = match args.len() { 0 => &undefined, @@ -137,7 +136,7 @@ impl Map { /// /// [spec]: https://tc39.es/ecma262/#sec-map.prototype.clear /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear - pub(crate) fn clear(this: &Value, _: &[Value], _: &mut Interpreter) -> Result { + pub(crate) fn clear(this: &Value, _: &[Value], _: &mut Context) -> Result { this.set_data(ObjectData::Map(OrderedMap::new())); Self::set_size(this, 0); @@ -155,7 +154,7 @@ impl Map { /// /// [spec]: https://tc39.es/ecma262/#sec-map.prototype.has /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has - pub(crate) fn has(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn has(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let undefined = Value::Undefined; let key = match args.len() { 0 => &undefined, @@ -185,7 +184,7 @@ impl Map { pub(crate) fn for_each( this: &Value, args: &[Value], - interpreter: &mut Interpreter, + interpreter: &mut Context, ) -> Result { if args.is_empty() { return Err(Value::from("Missing argument for Map.prototype.forEach")); @@ -224,12 +223,12 @@ impl Map { } /// Create a new map - pub(crate) fn make_map(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn make_map(this: &Value, args: &[Value], ctx: &mut Context) -> Result { // Make a new Object which will internally represent the Array (mapping // between indices and values): this creates an Object with no prototype // Set Prototype - let prototype = ctx.realm.global_obj.get_field("Map").get_field(PROTOTYPE); + let prototype = ctx.global_object().get_field("Map").get_field(PROTOTYPE); this.as_object_mut() .expect("this is array object") @@ -281,8 +280,8 @@ impl Map { } /// Initialise the `Map` object on the global object. - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { - let global = interpreter.global(); + pub(crate) fn init(interpreter: &mut Context) -> (&'static str, Value) { + let global = interpreter.global_object(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); // Create prototype diff --git a/boa/src/builtins/map/tests.rs b/boa/src/builtins/map/tests.rs index a0d7b62294..761cbdf025 100644 --- a/boa/src/builtins/map/tests.rs +++ b/boa/src/builtins/map/tests.rs @@ -1,9 +1,8 @@ -use crate::{exec::Interpreter, forward, realm::Realm}; +use crate::{forward, Context}; #[test] fn construct_empty() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var empty = new Map(); "#; @@ -14,8 +13,7 @@ fn construct_empty() { #[test] fn construct_from_array() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" let map = new Map([["1", "one"], ["2", "two"]]); "#; @@ -26,8 +24,7 @@ fn construct_from_array() { #[test] fn clone() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" let original = new Map([["1", "one"], ["2", "two"]]); let clone = new Map(original); @@ -48,8 +45,7 @@ fn clone() { #[test] fn merge() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" let first = new Map([["1", "one"], ["2", "two"]]); let second = new Map([["2", "second two"], ["3", "three"]]); @@ -68,8 +64,7 @@ fn merge() { #[test] fn get() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" let map = new Map([["1", "one"], ["2", "two"]]); "#; @@ -86,8 +81,7 @@ fn get() { #[test] fn set() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" let map = new Map(); "#; @@ -105,8 +99,7 @@ fn set() { #[test] fn clear() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" let map = new Map([["1", "one"], ["2", "two"]]); map.clear(); @@ -118,8 +111,7 @@ fn clear() { #[test] fn delete() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" let map = new Map([["1", "one"], ["2", "two"]]); "#; @@ -134,8 +126,7 @@ fn delete() { #[test] fn has() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" let map = new Map([["1", "one"]]); "#; @@ -150,8 +141,7 @@ fn has() { #[test] fn for_each() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" let map = new Map([[1, 5], [2, 10], [3, 15]]); let valueSum = 0; @@ -172,8 +162,7 @@ fn for_each() { #[test] fn modify_key() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" let obj = new Object(); let map = new Map([[obj, "one"]]); @@ -186,8 +175,7 @@ fn modify_key() { #[test] fn order() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" let map = new Map([[1, "one"]]); map.set(2, "two"); @@ -213,8 +201,7 @@ fn order() { #[test] fn recursive_display() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" let map = new Map(); let array = new Array([map]); @@ -229,8 +216,7 @@ fn recursive_display() { #[test] fn not_a_function() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r" try { let map = Map() diff --git a/boa/src/builtins/math/mod.rs b/boa/src/builtins/math/mod.rs index b332c37629..d17769e9e0 100644 --- a/boa/src/builtins/math/mod.rs +++ b/boa/src/builtins/math/mod.rs @@ -11,7 +11,7 @@ //! [spec]: https://tc39.es/ecma262/#sec-math-object //! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math -use crate::{builtins::function::make_builtin_fn, exec::Interpreter, BoaProfiler, Result, Value}; +use crate::{builtins::function::make_builtin_fn, BoaProfiler, Context, Result, Value}; use std::f64; #[cfg(test)] @@ -33,7 +33,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.abs /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/abs - pub(crate) fn abs(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn abs(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -50,7 +50,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.acos /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acos - pub(crate) fn acos(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn acos(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -67,7 +67,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.acosh /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acosh - pub(crate) fn acosh(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn acosh(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -84,7 +84,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.asin /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asin - pub(crate) fn asin(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn asin(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -101,7 +101,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.asinh /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asinh - pub(crate) fn asinh(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn asinh(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -118,7 +118,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.atan /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan - pub(crate) fn atan(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn atan(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -135,7 +135,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.atanh /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atanh - pub(crate) fn atanh(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn atanh(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -152,7 +152,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.atan2 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2 - pub(crate) fn atan2(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn atan2(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(match ( args.get(0).map(|x| x.to_number(ctx)).transpose()?, args.get(1).map(|x| x.to_number(ctx)).transpose()?, @@ -171,7 +171,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.cbrt /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cbrt - pub(crate) fn cbrt(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn cbrt(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -188,7 +188,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.ceil /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil - pub(crate) fn ceil(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn ceil(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -205,7 +205,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.clz32 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 - pub(crate) fn clz32(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn clz32(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_u32(ctx)) @@ -223,7 +223,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.cos /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cos - pub(crate) fn cos(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn cos(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -240,7 +240,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.cosh /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cosh - pub(crate) fn cosh(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn cosh(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -257,7 +257,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.exp /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/exp - pub(crate) fn exp(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn exp(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -276,7 +276,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.expm1 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/expm1 - pub(crate) fn expm1(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn expm1(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -293,7 +293,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.floor /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor - pub(crate) fn floor(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn floor(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -310,7 +310,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.fround /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround - pub(crate) fn fround(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn fround(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -327,7 +327,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.hypot /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/hypot - pub(crate) fn hypot(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn hypot(_: &Value, args: &[Value], ctx: &mut Context) -> Result { let mut result = 0f64; for arg in args { let x = arg.to_number(ctx)?; @@ -344,7 +344,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.imul /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul - pub(crate) fn imul(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn imul(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(match ( args.get(0).map(|x| x.to_u32(ctx)).transpose()?, args.get(1).map(|x| x.to_u32(ctx)).transpose()?, @@ -363,7 +363,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.log /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log - pub(crate) fn log(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn log(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -380,7 +380,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.log1p /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log1p - pub(crate) fn log1p(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn log1p(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -397,7 +397,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.log10 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log10 - pub(crate) fn log10(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn log10(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -414,7 +414,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.log2 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log2 - pub(crate) fn log2(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn log2(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -431,7 +431,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.max /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max - pub(crate) fn max(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn max(_: &Value, args: &[Value], ctx: &mut Context) -> Result { let mut max = f64::NEG_INFINITY; for arg in args { let num = arg.to_number(ctx)?; @@ -448,7 +448,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.min /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min - pub(crate) fn min(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn min(_: &Value, args: &[Value], ctx: &mut Context) -> Result { let mut min = f64::INFINITY; for arg in args { let num = arg.to_number(ctx)?; @@ -465,7 +465,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.pow /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/pow - pub(crate) fn pow(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn pow(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(match ( args.get(0).map(|x| x.to_number(ctx)).transpose()?, args.get(1).map(|x| x.to_number(ctx)).transpose()?, @@ -484,7 +484,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.random /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random - pub(crate) fn random(_: &Value, _: &[Value], _: &mut Interpreter) -> Result { + pub(crate) fn random(_: &Value, _: &[Value], _: &mut Context) -> Result { Ok(rand::random::().into()) } @@ -496,7 +496,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.round /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round - pub(crate) fn round(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn round(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -513,7 +513,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.sign /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign - pub(crate) fn sign(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn sign(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -539,7 +539,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.sin /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sin - pub(crate) fn sin(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn sin(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -556,7 +556,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.sinh /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sinh - pub(crate) fn sinh(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn sinh(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -573,7 +573,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.sqrt /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sqrt - pub(crate) fn sqrt(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn sqrt(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -590,7 +590,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.tan /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/tan - pub(crate) fn tan(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn tan(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -607,7 +607,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.tanh /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/tanh - pub(crate) fn tanh(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn tanh(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -624,7 +624,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.trunc /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc - pub(crate) fn trunc(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn trunc(_: &Value, args: &[Value], ctx: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(ctx)) @@ -634,8 +634,8 @@ impl Math { } /// Create a new `Math` object - pub(crate) fn create(interpreter: &mut Interpreter) -> Value { - let global = interpreter.global(); + pub(crate) fn create(interpreter: &mut Context) -> Value { + let global = interpreter.global_object(); let _timer = BoaProfiler::global().start_event("math:create", "init"); let math = Value::new_object(Some(global)); @@ -692,7 +692,7 @@ impl Math { /// Initialise the `Math` object on the global object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(interpreter: &mut Context) -> (&'static str, Value) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); (Self::NAME, Self::create(interpreter)) diff --git a/boa/src/builtins/math/tests.rs b/boa/src/builtins/math/tests.rs index 492e604c4a..80b5bd01ad 100644 --- a/boa/src/builtins/math/tests.rs +++ b/boa/src/builtins/math/tests.rs @@ -1,12 +1,11 @@ #![allow(clippy::float_cmp)] -use crate::{exec::Interpreter, forward, forward_val, realm::Realm}; +use crate::{forward, forward_val, Context}; use std::f64; #[test] fn abs() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.abs(3 - 5); var b = Math.abs(1.23456 - 7.89012); @@ -23,8 +22,7 @@ fn abs() { #[test] fn acos() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.acos(8 / 10); var b = Math.acos(5 / 3); @@ -47,8 +45,7 @@ fn acos() { #[test] fn acosh() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.acosh(2); var b = Math.acosh(-1); @@ -68,8 +65,7 @@ fn acosh() { #[test] fn asin() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.asin(6 / 10); var b = Math.asin(5 / 3); @@ -86,8 +82,7 @@ fn asin() { #[test] fn asinh() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.asinh(1); var b = Math.asinh(0); @@ -104,8 +99,7 @@ fn asinh() { #[test] fn atan() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.atan(1); var b = Math.atan(0); @@ -125,8 +119,7 @@ fn atan() { #[test] fn atan2() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.atan2(90, 15); var b = Math.atan2(15, 90); @@ -143,8 +136,7 @@ fn atan2() { #[test] fn cbrt() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.cbrt(64); var b = Math.cbrt(-1); @@ -164,8 +156,7 @@ fn cbrt() { #[test] fn ceil() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.ceil(1.95); var b = Math.ceil(4); @@ -186,8 +177,7 @@ fn ceil() { #[test] #[allow(clippy::many_single_char_names)] fn clz32() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.clz32(); var b = Math.clz32({}); @@ -222,8 +212,7 @@ fn clz32() { #[test] fn cos() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.cos(0); var b = Math.cos(1); @@ -240,8 +229,7 @@ fn cos() { #[test] fn cosh() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.cosh(0); var b = Math.cosh(1); @@ -261,8 +249,7 @@ fn cosh() { #[test] fn exp() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.exp(0); var b = Math.exp(-1); @@ -283,8 +270,7 @@ fn exp() { #[test] #[allow(clippy::many_single_char_names)] fn expm1() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.expm1(); var b = Math.expm1({}); @@ -329,8 +315,7 @@ fn expm1() { #[test] fn floor() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.floor(1.95); var b = Math.floor(-3.01); @@ -351,8 +336,7 @@ fn floor() { #[test] #[allow(clippy::many_single_char_names)] fn fround() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.fround(NaN); var b = Math.fround(Infinity); @@ -385,8 +369,7 @@ fn fround() { #[test] #[allow(clippy::many_single_char_names)] fn hypot() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.hypot(); var b = Math.hypot(3, 4); @@ -419,8 +402,7 @@ fn hypot() { #[test] #[allow(clippy::many_single_char_names)] fn imul() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.imul(3, 4); var b = Math.imul(-5, 12); @@ -449,8 +431,7 @@ fn imul() { #[test] fn log() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.log(1); var b = Math.log(10); @@ -471,8 +452,7 @@ fn log() { #[test] #[allow(clippy::many_single_char_names)] fn log1p() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.log1p(1); var b = Math.log1p(0); @@ -504,8 +484,7 @@ fn log1p() { #[test] fn log10() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.log10(2); var b = Math.log10(1); @@ -525,8 +504,7 @@ fn log10() { #[test] fn log2() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.log2(3); var b = Math.log2(1); @@ -546,8 +524,7 @@ fn log2() { #[test] fn max() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.max(10, 20); var b = Math.max(-10, -20); @@ -567,8 +544,7 @@ fn max() { #[test] fn min() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.min(10, 20); var b = Math.min(-10, -20); @@ -588,8 +564,7 @@ fn min() { #[test] fn pow() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.pow(2, 10); var b = Math.pow(-7, 2); @@ -612,8 +587,7 @@ fn pow() { #[test] fn round() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.round(20.5); var b = Math.round(-20.3); @@ -630,8 +604,7 @@ fn round() { #[test] fn sign() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.sign(3); var b = Math.sign(-3); @@ -651,8 +624,7 @@ fn sign() { #[test] fn sin() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.sin(0); var b = Math.sin(1); @@ -669,8 +641,7 @@ fn sin() { #[test] fn sinh() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.sinh(0); var b = Math.sinh(1); @@ -687,8 +658,7 @@ fn sinh() { #[test] fn sqrt() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.sqrt(0); var b = Math.sqrt(2); @@ -708,8 +678,7 @@ fn sqrt() { #[test] fn tan() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.tan(1.1); "#; @@ -727,8 +696,7 @@ fn tan() { #[test] fn tanh() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.tanh(1); var b = Math.tanh(0); @@ -745,8 +713,7 @@ fn tanh() { #[test] fn trunc() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = Math.trunc(13.37); var b = Math.trunc(0.123); diff --git a/boa/src/builtins/mod.rs b/boa/src/builtins/mod.rs index 1d373393fc..afd3284de5 100644 --- a/boa/src/builtins/mod.rs +++ b/boa/src/builtins/mod.rs @@ -39,11 +39,11 @@ pub(crate) use self::{ symbol::Symbol, undefined::Undefined, }; -use crate::{Interpreter, Value}; +use crate::{Context, Value}; /// Initializes builtin objects and functions #[inline] -pub fn init(interpreter: &mut Interpreter) { +pub fn init(interpreter: &mut Context) { let globals = [ // The `Function` global must be initialized before other types. function::init, @@ -75,7 +75,7 @@ pub fn init(interpreter: &mut Interpreter) { for init in &globals { let (name, value) = init(interpreter); - let global = interpreter.global(); + let global = interpreter.global_object(); match global { Value::Object(ref global_object) => { global_object.borrow_mut().insert_field(name, value); diff --git a/boa/src/builtins/nan/mod.rs b/boa/src/builtins/nan/mod.rs index ceeb53c3b0..1dfb55c3c5 100644 --- a/boa/src/builtins/nan/mod.rs +++ b/boa/src/builtins/nan/mod.rs @@ -13,7 +13,7 @@ #[cfg(test)] mod tests; -use crate::{BoaProfiler, Interpreter, Value}; +use crate::{BoaProfiler, Context, Value}; /// JavaScript global `NaN` property. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -25,7 +25,7 @@ impl NaN { /// Initialize the `NaN` property on the global object. #[inline] - pub(crate) fn init(_interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(_interpreter: &mut Context) -> (&'static str, Value) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); (Self::NAME, Value::from(f64::NAN)) diff --git a/boa/src/builtins/number/mod.rs b/boa/src/builtins/number/mod.rs index a4d1f1cce0..17a4131a9f 100644 --- a/boa/src/builtins/number/mod.rs +++ b/boa/src/builtins/number/mod.rs @@ -17,7 +17,10 @@ use super::{ function::{make_builtin_fn, make_constructor_fn}, object::ObjectData, }; -use crate::{exec::Interpreter, value::AbstractRelation, BoaProfiler, Result, Value}; +use crate::{ + value::{AbstractRelation, Value}, + BoaProfiler, Context, Result, +}; use num_traits::float::FloatCore; mod conversions; @@ -101,7 +104,7 @@ impl Number { /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-thisnumbervalue - fn this_number_value(value: &Value, ctx: &mut Interpreter) -> Result { + fn this_number_value(value: &Value, ctx: &mut Context) -> Result { match *value { Value::Integer(integer) => return Ok(f64::from(integer)), Value::Rational(rational) => return Ok(rational), @@ -128,11 +131,7 @@ impl Number { /// `[[Construct]]` - Creates a Number instance /// /// `[[Call]]` - Creates a number primitive - pub(crate) fn make_number( - this: &Value, - args: &[Value], - ctx: &mut Interpreter, - ) -> Result { + pub(crate) fn make_number(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let data = match args.get(0) { Some(ref value) => value.to_numeric_number(ctx)?, None => 0.0, @@ -156,7 +155,7 @@ impl Number { pub(crate) fn to_exponential( this: &Value, _args: &[Value], - ctx: &mut Interpreter, + ctx: &mut Context, ) -> Result { let this_num = Self::this_number_value(this, ctx)?; let this_str_num = Self::num_to_exponential(this_num); @@ -174,7 +173,7 @@ impl Number { /// [spec]: https://tc39.es/ecma262/#sec-number.prototype.tofixed /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed #[allow(clippy::wrong_self_convention)] - pub(crate) fn to_fixed(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn to_fixed(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let this_num = Self::this_number_value(this, ctx)?; let precision = match args.get(0) { Some(n) => match n.to_integer(ctx)? as i32 { @@ -204,7 +203,7 @@ impl Number { pub(crate) fn to_locale_string( this: &Value, _args: &[Value], - ctx: &mut Interpreter, + ctx: &mut Context, ) -> Result { let this_num = Self::this_number_value(this, ctx)?; let this_str_num = format!("{}", this_num); @@ -222,11 +221,7 @@ impl Number { /// [spec]: https://tc39.es/ecma262/#sec-number.prototype.toexponential /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision #[allow(clippy::wrong_self_convention)] - pub(crate) fn to_precision( - this: &Value, - args: &[Value], - ctx: &mut Interpreter, - ) -> Result { + pub(crate) fn to_precision(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let this_num = Self::this_number_value(this, ctx)?; let _num_str_len = format!("{}", this_num).len(); let _precision = match args.get(0) { @@ -380,7 +375,7 @@ impl Number { /// [spec]: https://tc39.es/ecma262/#sec-number.prototype.tostring /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString #[allow(clippy::wrong_self_convention)] - pub(crate) fn to_string(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn to_string(this: &Value, args: &[Value], ctx: &mut Context) -> Result { // 1. Let x be ? thisNumberValue(this value). let x = Self::this_number_value(this, ctx)?; @@ -435,7 +430,7 @@ impl Number { /// /// [spec]: https://tc39.es/ecma262/#sec-number.prototype.valueof /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/valueOf - pub(crate) fn value_of(this: &Value, _args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn value_of(this: &Value, _args: &[Value], ctx: &mut Context) -> Result { Ok(Value::from(Self::this_number_value(this, ctx)?)) } @@ -453,11 +448,7 @@ impl Number { /// /// [spec]: https://tc39.es/ecma262/#sec-parseint-string-radix /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt - pub(crate) fn parse_int( - _this: &Value, - args: &[Value], - _ctx: &mut Interpreter, - ) -> Result { + pub(crate) fn parse_int(_this: &Value, args: &[Value], _ctx: &mut Context) -> Result { if let (Some(val), r) = (args.get(0), args.get(1)) { let mut radix = if let Some(rx) = r { if let Value::Integer(i) = rx { @@ -523,11 +514,7 @@ impl Number { /// /// [spec]: https://tc39.es/ecma262/#sec-parsefloat-string /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseFloat - pub(crate) fn parse_float( - _this: &Value, - args: &[Value], - _ctx: &mut Interpreter, - ) -> Result { + pub(crate) fn parse_float(_this: &Value, args: &[Value], _ctx: &mut Context) -> Result { if let Some(val) = args.get(0) { match val { Value::String(s) => { @@ -572,7 +559,7 @@ impl Number { pub(crate) fn global_is_finite( _this: &Value, args: &[Value], - ctx: &mut Interpreter, + ctx: &mut Context, ) -> Result { if let Some(value) = args.get(0) { let number = value.to_number(ctx)?; @@ -596,11 +583,7 @@ impl Number { /// /// [spec]: https://tc39.es/ecma262/#sec-isnan-number /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN - pub(crate) fn global_is_nan( - _this: &Value, - args: &[Value], - ctx: &mut Interpreter, - ) -> Result { + pub(crate) fn global_is_nan(_this: &Value, args: &[Value], ctx: &mut Context) -> Result { if let Some(value) = args.get(0) { let number = value.to_number(ctx)?; Ok(number.is_nan().into()) @@ -626,7 +609,7 @@ impl Number { pub(crate) fn number_is_finite( _this: &Value, args: &[Value], - _ctx: &mut Interpreter, + _ctx: &mut Context, ) -> Result { Ok(Value::from(if let Some(val) = args.get(0) { match val { @@ -652,7 +635,7 @@ impl Number { pub(crate) fn number_is_integer( _this: &Value, args: &[Value], - _ctx: &mut Interpreter, + _ctx: &mut Context, ) -> Result { Ok(args.get(0).map_or(false, Self::is_integer).into()) } @@ -674,7 +657,7 @@ impl Number { pub(crate) fn number_is_nan( _this: &Value, args: &[Value], - _ctx: &mut Interpreter, + _ctx: &mut Context, ) -> Result { Ok(Value::from(if let Some(val) = args.get(0) { match val { @@ -704,7 +687,7 @@ impl Number { pub(crate) fn is_safe_integer( _this: &Value, args: &[Value], - _ctx: &mut Interpreter, + _ctx: &mut Context, ) -> Result { Ok(Value::from(match args.get(0) { Some(Value::Integer(_)) => true, @@ -739,8 +722,8 @@ impl Number { /// Initialise the `Number` object on the global object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { - let global = interpreter.global(); + pub(crate) fn init(interpreter: &mut Context) -> (&'static str, Value) { + let global = interpreter.global_object(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let prototype = Value::new_object(Some(global)); diff --git a/boa/src/builtins/number/tests.rs b/boa/src/builtins/number/tests.rs index 2f95a928e7..055b6d55a2 100644 --- a/boa/src/builtins/number/tests.rs +++ b/boa/src/builtins/number/tests.rs @@ -1,11 +1,10 @@ #![allow(clippy::float_cmp)] -use crate::{builtins::Number, exec::Interpreter, forward, forward_val, realm::Realm}; +use crate::{builtins::Number, forward, forward_val, Context}; #[test] fn integer_number_primitive_to_number_object() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let scenario = r#" (100).toString() === "100" @@ -16,8 +15,7 @@ fn integer_number_primitive_to_number_object() { #[test] fn call_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var default_zero = Number(); var int_one = Number(1); @@ -51,8 +49,7 @@ fn call_number() { #[test] fn to_exponential() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var default_exp = Number().toExponential(); var int_exp = Number(5).toExponential(); @@ -80,8 +77,7 @@ fn to_exponential() { #[test] fn to_fixed() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var default_fixed = Number().toFixed(); var pos_fixed = Number("3.456e+4").toFixed(); @@ -106,8 +102,7 @@ fn to_fixed() { #[test] fn to_locale_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var default_locale = Number().toLocaleString(); var small_locale = Number(5).toLocaleString(); @@ -133,8 +128,7 @@ fn to_locale_string() { #[test] #[ignore] fn to_precision() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var default_precision = Number().toPrecision(); var low_precision = Number(123456789).toPrecision(1); @@ -165,8 +159,7 @@ fn to_precision() { #[test] fn to_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!("\"NaN\"", &forward(&mut engine, "Number(NaN).toString()")); assert_eq!( @@ -338,8 +331,7 @@ fn to_string() { #[test] fn num_to_string_exponential() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!("\"0\"", forward(&mut engine, "(0).toString()")); assert_eq!("\"0\"", forward(&mut engine, "(-0).toString()")); @@ -377,8 +369,7 @@ fn num_to_string_exponential() { #[test] fn value_of() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); // TODO: In addition to parsing numbers from strings, parse them bare As of October 2019 // the parser does not understand scientific e.g., Xe+Y or -Xe-Y notation. let init = r#" @@ -436,8 +427,7 @@ fn same_value_zero() { #[test] fn from_bigint() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(&forward(&mut engine, "Number(0n)"), "0",); assert_eq!(&forward(&mut engine, "Number(100000n)"), "100000",); @@ -447,8 +437,7 @@ fn from_bigint() { #[test] fn number_constants() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert!(!forward_val(&mut engine, "Number.EPSILON") .unwrap() @@ -475,48 +464,42 @@ fn number_constants() { #[test] fn parse_int_simple() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(&forward(&mut engine, "parseInt(\"6\")"), "6"); } #[test] fn parse_int_negative() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(&forward(&mut engine, "parseInt(\"-9\")"), "-9"); } #[test] fn parse_int_already_int() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(&forward(&mut engine, "parseInt(100)"), "100"); } #[test] fn parse_int_float() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(&forward(&mut engine, "parseInt(100.5)"), "100"); } #[test] fn parse_int_float_str() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(&forward(&mut engine, "parseInt(\"100.5\")"), "NaN"); } #[test] fn parse_int_inferred_hex() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(&forward(&mut engine, "parseInt(\"0xA\")"), "10"); } @@ -525,16 +508,14 @@ fn parse_int_inferred_hex() { /// a radix 10 if no radix is specified. Some alternative implementations default to a radix of 8. #[test] fn parse_int_zero_start() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(&forward(&mut engine, "parseInt(\"018\")"), "18"); } #[test] fn parse_int_varying_radix() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let base_str = "1000"; @@ -553,8 +534,7 @@ fn parse_int_varying_radix() { #[test] fn parse_int_negative_varying_radix() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let base_str = "-1000"; @@ -573,16 +553,14 @@ fn parse_int_negative_varying_radix() { #[test] fn parse_int_malformed_str() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(&forward(&mut engine, "parseInt(\"hello\")"), "NaN"); } #[test] fn parse_int_undefined() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(&forward(&mut engine, "parseInt(undefined)"), "NaN"); } @@ -591,8 +569,7 @@ fn parse_int_undefined() { /// passed as the first argument. #[test] fn parse_int_no_args() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(&forward(&mut engine, "parseInt()"), "NaN"); } @@ -600,64 +577,56 @@ fn parse_int_no_args() { /// Shows that extra arguments to parseInt are ignored. #[test] fn parse_int_too_many_args() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(&forward(&mut engine, "parseInt(\"100\", 10, 10)"), "100"); } #[test] fn parse_float_simple() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(&forward(&mut engine, "parseFloat(\"6.5\")"), "6.5"); } #[test] fn parse_float_int() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(&forward(&mut engine, "parseFloat(10)"), "10"); } #[test] fn parse_float_int_str() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(&forward(&mut engine, "parseFloat(\"8\")"), "8"); } #[test] fn parse_float_already_float() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(&forward(&mut engine, "parseFloat(17.5)"), "17.5"); } #[test] fn parse_float_negative() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(&forward(&mut engine, "parseFloat(\"-99.7\")"), "-99.7"); } #[test] fn parse_float_malformed_str() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(&forward(&mut engine, "parseFloat(\"hello\")"), "NaN"); } #[test] fn parse_float_undefined() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(&forward(&mut engine, "parseFloat(undefined)"), "NaN"); } @@ -665,8 +634,7 @@ fn parse_float_undefined() { /// No arguments to parseFloat is treated the same as passing undefined as the first argument. #[test] fn parse_float_no_args() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(&forward(&mut engine, "parseFloat()"), "NaN"); } @@ -674,16 +642,14 @@ fn parse_float_no_args() { /// Shows that the parseFloat function ignores extra arguments. #[test] fn parse_float_too_many_args() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(&forward(&mut engine, "parseFloat(\"100.5\", 10)"), "100.5"); } #[test] fn global_is_finite() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!("false", &forward(&mut engine, "isFinite(Infinity)")); assert_eq!("false", &forward(&mut engine, "isFinite(NaN)")); @@ -698,8 +664,7 @@ fn global_is_finite() { #[test] fn global_is_nan() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!("true", &forward(&mut engine, "isNaN(NaN)")); assert_eq!("true", &forward(&mut engine, "isNaN('NaN')")); @@ -720,8 +685,7 @@ fn global_is_nan() { #[test] fn number_is_finite() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!("false", &forward(&mut engine, "Number.isFinite(Infinity)")); assert_eq!("false", &forward(&mut engine, "Number.isFinite(NaN)")); @@ -747,8 +711,7 @@ fn number_is_finite() { #[test] fn number_is_integer() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!("true", &forward(&mut engine, "Number.isInteger(0)")); assert_eq!("true", &forward(&mut engine, "Number.isInteger(1)")); @@ -795,8 +758,7 @@ fn number_is_integer() { #[test] fn number_is_nan() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!("true", &forward(&mut engine, "Number.isNaN(NaN)")); assert_eq!("true", &forward(&mut engine, "Number.isNaN(Number.NaN)")); @@ -829,8 +791,7 @@ fn number_is_nan() { #[test] fn number_is_safe_integer() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!("true", &forward(&mut engine, "Number.isSafeInteger(3)")); assert_eq!( diff --git a/boa/src/builtins/object/gcobject.rs b/boa/src/builtins/object/gcobject.rs index 124edb713e..b7f5d439ee 100644 --- a/boa/src/builtins/object/gcobject.rs +++ b/boa/src/builtins/object/gcobject.rs @@ -11,7 +11,7 @@ use crate::{ function_environment_record::BindingStatus, lexical_environment::new_function_environment, }, syntax::ast::node::RcStatementList, - Executable, Interpreter, Result, Value, + Context, Executable, Result, Value, }; use gc::{Finalize, Gc, GcCell, GcCellRef, GcCellRefMut, Trace}; use std::{ @@ -107,7 +107,7 @@ impl GcObject { // // #[track_caller] - pub fn call(&self, this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub fn call(&self, this: &Value, args: &[Value], ctx: &mut Context) -> Result { let this_function_object = self.clone(); let f_body = if let Some(function) = self.borrow().as_function() { if function.is_callable() { @@ -160,7 +160,7 @@ impl GcObject { .borrow_mut() .initialize_binding("arguments", arguments_obj); - ctx.realm.environment.push(local_env); + ctx.realm_mut().environment.push(local_env); FunctionBody::Ordinary(body.clone()) } @@ -176,7 +176,7 @@ impl GcObject { FunctionBody::BuiltIn(func) => func(this, args, ctx), FunctionBody::Ordinary(body) => { let result = body.run(ctx); - ctx.realm.environment.pop(); + ctx.realm_mut().environment.pop(); result } @@ -189,7 +189,7 @@ impl GcObject { /// Panics if the object is currently mutably borrowed. // #[track_caller] - pub fn construct(&self, args: &[Value], ctx: &mut Interpreter) -> Result { + pub fn construct(&self, args: &[Value], ctx: &mut Context) -> Result { let this = Object::create(self.borrow().get(&PROTOTYPE.into())).into(); let this_function_object = self.clone(); @@ -242,13 +242,13 @@ impl GcObject { .borrow_mut() .initialize_binding("arguments", arguments_obj); - ctx.realm.environment.push(local_env); + ctx.realm_mut().environment.push(local_env); // Call body should be set before reaching here let _ = body.run(ctx); // local_env gets dropped here, its no longer needed - let binding = ctx.realm.environment.get_this_binding(); + let binding = ctx.realm_mut().environment.get_this_binding(); Ok(binding) } } diff --git a/boa/src/builtins/object/mod.rs b/boa/src/builtins/object/mod.rs index eeb31a986c..46e1b1e560 100644 --- a/boa/src/builtins/object/mod.rs +++ b/boa/src/builtins/object/mod.rs @@ -19,10 +19,9 @@ use crate::{ map::ordered_map::OrderedMap, BigInt, Date, RegExp, }, - exec::Interpreter, property::{Property, PropertyKey}, value::{same_value, RcBigInt, RcString, RcSymbol, Value}, - BoaProfiler, Result, + BoaProfiler, Context, Result, }; use gc::{Finalize, Trace}; use rustc_hash::FxHashMap; @@ -469,14 +468,15 @@ impl Object { } /// Create a new object. -pub fn make_object(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { +pub fn make_object(_: &Value, args: &[Value], ctx: &mut Context) -> Result { if let Some(arg) = args.get(0) { if !arg.is_null_or_undefined() { return arg.to_object(ctx); } } + let global = ctx.global_object(); - Ok(Value::new_object(Some(ctx.global()))) + Ok(Value::new_object(Some(global))) } /// `Object.create( proto, [propertiesObject] )` @@ -489,7 +489,7 @@ pub fn make_object(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result Result { +pub fn create(_: &Value, args: &[Value], interpreter: &mut Context) -> Result { let prototype = args.get(0).cloned().unwrap_or_else(Value::undefined); let properties = args.get(1).cloned().unwrap_or_else(Value::undefined); @@ -510,7 +510,7 @@ pub fn create(_: &Value, args: &[Value], interpreter: &mut Interpreter) -> Resul } /// Uses the SameValue algorithm to check equality of objects -pub fn is(_: &Value, args: &[Value], _: &mut Interpreter) -> Result { +pub fn is(_: &Value, args: &[Value], _: &mut Context) -> Result { let x = args.get(0).cloned().unwrap_or_else(Value::undefined); let y = args.get(1).cloned().unwrap_or_else(Value::undefined); @@ -518,7 +518,7 @@ pub fn is(_: &Value, args: &[Value], _: &mut Interpreter) -> Result { } /// Get the `prototype` of an object. -pub fn get_prototype_of(_: &Value, args: &[Value], _: &mut Interpreter) -> Result { +pub fn get_prototype_of(_: &Value, args: &[Value], _: &mut Context) -> Result { let obj = args.get(0).expect("Cannot get object"); Ok(obj .as_object() @@ -526,7 +526,7 @@ pub fn get_prototype_of(_: &Value, args: &[Value], _: &mut Interpreter) -> Resul } /// Set the `prototype` of an object. -pub fn set_prototype_of(_: &Value, args: &[Value], _: &mut Interpreter) -> Result { +pub fn set_prototype_of(_: &Value, args: &[Value], _: &mut Context) -> Result { let obj = args.get(0).expect("Cannot get object").clone(); let proto = args.get(1).expect("Cannot get object").clone(); obj.as_object_mut().unwrap().prototype = proto; @@ -534,7 +534,7 @@ pub fn set_prototype_of(_: &Value, args: &[Value], _: &mut Interpreter) -> Resul } /// Define a property in an object -pub fn define_property(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { +pub fn define_property(_: &Value, args: &[Value], ctx: &mut Context) -> Result { let obj = args.get(0).expect("Cannot get object"); let prop = args.get(1).expect("Cannot get object").to_string(ctx)?; let desc = Property::from(args.get(2).expect("Cannot get object")); @@ -552,7 +552,7 @@ pub fn define_property(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Resu /// /// [spec]: https://tc39.es/ecma262/#sec-object.prototype.tostring /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString -pub fn to_string(this: &Value, _: &[Value], _: &mut Interpreter) -> Result { +pub fn to_string(this: &Value, _: &[Value], _: &mut Context) -> Result { // FIXME: it should not display the object. Ok(this.display().to_string().into()) } @@ -568,7 +568,7 @@ pub fn to_string(this: &Value, _: &[Value], _: &mut Interpreter) -> Result Result { +pub fn has_own_property(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let prop = if args.is_empty() { None } else { @@ -586,11 +586,7 @@ pub fn has_own_property(this: &Value, args: &[Value], ctx: &mut Interpreter) -> } } -pub fn property_is_enumerable( - this: &Value, - args: &[Value], - ctx: &mut Interpreter, -) -> Result { +pub fn property_is_enumerable(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let key = match args.get(0) { None => return Ok(Value::from(false)), Some(key) => key, @@ -610,8 +606,8 @@ pub fn property_is_enumerable( /// Initialise the `Object` object on the global object. #[inline] -pub fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { - let global = interpreter.global(); +pub fn init(interpreter: &mut Context) -> (&'static str, Value) { + let global = interpreter.global_object(); let _timer = BoaProfiler::global().start_event("object", "init"); let prototype = Value::new_object(None); diff --git a/boa/src/builtins/object/tests.rs b/boa/src/builtins/object/tests.rs index ae405a67e7..7ea3f6478b 100644 --- a/boa/src/builtins/object/tests.rs +++ b/boa/src/builtins/object/tests.rs @@ -1,9 +1,8 @@ -use crate::{exec::Interpreter, forward, realm::Realm}; +use crate::{forward, Context}; #[test] fn object_create_with_regular_object() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" const foo = { a: 5 }; @@ -18,8 +17,7 @@ fn object_create_with_regular_object() { #[test] fn object_create_with_undefined() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" try { @@ -38,8 +36,7 @@ fn object_create_with_undefined() { #[test] fn object_create_with_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" try { @@ -60,8 +57,7 @@ fn object_create_with_number() { #[ignore] // to test on __proto__ somehow. __proto__ getter is not working as expected currently fn object_create_with_function() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" const x = function (){}; @@ -75,8 +71,7 @@ fn object_create_with_function() { #[test] fn object_is() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var foo = { a: 1}; @@ -96,13 +91,12 @@ fn object_is() { assert_eq!(forward(&mut engine, "Object.is(NaN, 0/0)"), "true"); assert_eq!(forward(&mut engine, "Object.is()"), "true"); assert_eq!(forward(&mut engine, "Object.is(undefined)"), "true"); - assert!(engine.realm.global_obj.is_global()); - assert!(!engine.realm.global_obj.get_field("Object").is_global()); + assert!(engine.global_object().is_global()); + assert!(!engine.global_object().get_field("Object").is_global()); } #[test] fn object_has_own_property() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" let x = { someProp: 1, undefinedProp: undefined, nullProp: null }; "#; @@ -122,8 +116,7 @@ fn object_has_own_property() { #[test] fn object_property_is_enumerable() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" let x = { enumerableProp: 'yes' }; "#; diff --git a/boa/src/builtins/regexp/mod.rs b/boa/src/builtins/regexp/mod.rs index 8e60291626..04383c3292 100644 --- a/boa/src/builtins/regexp/mod.rs +++ b/boa/src/builtins/regexp/mod.rs @@ -14,10 +14,9 @@ use regex::Regex; use super::function::{make_builtin_fn, make_constructor_fn}; use crate::{ builtins::object::ObjectData, - exec::Interpreter, property::Property, value::{RcString, Value}, - BoaProfiler, Result, + BoaProfiler, Context, Result, }; use gc::{unsafe_empty_trace, Finalize, Trace}; @@ -70,7 +69,7 @@ impl RegExp { pub(crate) const LENGTH: usize = 2; /// Create a new `RegExp` - pub(crate) fn make_regexp(this: &Value, args: &[Value], _: &mut Interpreter) -> Result { + pub(crate) fn make_regexp(this: &Value, args: &[Value], _: &mut Context) -> Result { let arg = args.get(0).ok_or_else(Value::undefined)?; let mut regex_body = String::new(); let mut regex_flags = String::new(); @@ -167,7 +166,7 @@ impl RegExp { // /// // /// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.dotAll // /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/dotAll - // fn get_dot_all(this: &Value, _: &[Value], _: &mut Interpreter) -> Result { + // fn get_dot_all(this: &Value, _: &[Value], _: &mut Context) -> Result { // this.with_internal_state_ref(|regex: &RegExp| Ok(Value::from(regex.dot_all))) // } @@ -182,7 +181,7 @@ impl RegExp { // /// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.flags // /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/flags // /// [flags]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Advanced_searching_with_flags_2 - // fn get_flags(this: &Value, _: &[Value], _: &mut Interpreter) -> Result { + // fn get_flags(this: &Value, _: &[Value], _: &mut Context) -> Result { // this.with_internal_state_ref(|regex: &RegExp| Ok(Value::from(regex.flags.clone()))) // } @@ -196,7 +195,7 @@ impl RegExp { // /// // /// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.global // /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/global - // fn get_global(this: &Value, _: &[Value], _: &mut Interpreter) -> Result { + // fn get_global(this: &Value, _: &[Value], _: &mut Context) -> Result { // this.with_internal_state_ref(|regex: &RegExp| Ok(Value::from(regex.global))) // } @@ -210,7 +209,7 @@ impl RegExp { // /// // /// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.ignorecase // /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/ignoreCase - // fn get_ignore_case(this: &Value, _: &[Value], _: &mut Interpreter) -> Result { + // fn get_ignore_case(this: &Value, _: &[Value], _: &mut Context) -> Result { // this.with_internal_state_ref(|regex: &RegExp| Ok(Value::from(regex.ignore_case))) // } @@ -224,7 +223,7 @@ impl RegExp { // /// // /// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.multiline // /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/multiline - // fn get_multiline(this: &Value, _: &[Value], _: &mut Interpreter) -> Result { + // fn get_multiline(this: &Value, _: &[Value], _: &mut Context) -> Result { // this.with_internal_state_ref(|regex: &RegExp| Ok(Value::from(regex.multiline))) // } @@ -239,7 +238,7 @@ impl RegExp { // /// // /// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.source // /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/source - // fn get_source(this: &Value, _: &[Value], _: &mut Interpreter) -> Result { + // fn get_source(this: &Value, _: &[Value], _: &mut Context) -> Result { // Ok(this.get_internal_slot("OriginalSource")) // } @@ -253,7 +252,7 @@ impl RegExp { // /// // /// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.sticky // /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky - // fn get_sticky(this: &Value, _: &[Value], _: &mut Interpreter) -> Result { + // fn get_sticky(this: &Value, _: &[Value], _: &mut Context) -> Result { // this.with_internal_state_ref(|regex: &RegExp| Ok(Value::from(regex.sticky))) // } @@ -268,7 +267,7 @@ impl RegExp { // /// // /// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.unicode // /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/unicode - // fn get_unicode(this: &Value, _: &[Value], _: &mut Interpreter) -> Result { + // fn get_unicode(this: &Value, _: &[Value], _: &mut Context) -> Result { // this.with_internal_state_ref(|regex: &RegExp| Ok(Value::from(regex.unicode))) // } @@ -284,7 +283,7 @@ impl RegExp { /// /// [spec]: https://tc39.es/ecma262/#sec-regexp.prototype.test /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test - pub(crate) fn test(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn test(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let arg_str = args .get(0) .expect("could not get argument") @@ -323,7 +322,7 @@ impl RegExp { /// /// [spec]: https://tc39.es/ecma262/#sec-regexp.prototype.exec /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec - pub(crate) fn exec(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn exec(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let arg_str = args .get(0) .expect("could not get argument") @@ -379,7 +378,7 @@ impl RegExp { /// /// [spec]: https://tc39.es/ecma262/#sec-regexp.prototype-@@match /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@match - pub(crate) fn r#match(this: &Value, arg: RcString, ctx: &mut Interpreter) -> Result { + pub(crate) fn r#match(this: &Value, arg: RcString, ctx: &mut Context) -> Result { let (matcher, flags) = if let Some(object) = this.as_object() { let regex = object.as_regexp().unwrap(); (regex.matcher.clone(), regex.flags.clone()) @@ -411,7 +410,7 @@ impl RegExp { /// [spec]: https://tc39.es/ecma262/#sec-regexp.prototype.tostring /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/toString #[allow(clippy::wrong_self_convention)] - pub(crate) fn to_string(this: &Value, _: &[Value], _: &mut Interpreter) -> Result { + pub(crate) fn to_string(this: &Value, _: &[Value], _: &mut Context) -> Result { let (body, flags) = if let Some(object) = this.as_object() { let regex = object.as_regexp().unwrap(); (regex.original_source.clone(), regex.flags.clone()) @@ -478,9 +477,9 @@ impl RegExp { /// Initialise the `RegExp` object on the global object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(interpreter: &mut Context) -> (&'static str, Value) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); - let global = interpreter.global(); + let global = interpreter.global_object(); // Create prototype let prototype = Value::new_object(Some(global)); diff --git a/boa/src/builtins/regexp/tests.rs b/boa/src/builtins/regexp/tests.rs index b407a30fa5..a1a4450065 100644 --- a/boa/src/builtins/regexp/tests.rs +++ b/boa/src/builtins/regexp/tests.rs @@ -1,9 +1,8 @@ -use crate::{exec::Interpreter, forward, realm::Realm}; +use crate::{forward, Context}; #[test] fn constructors() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var constructed = new RegExp("[0-9]+(\\.[0-9]+)?"); var literal = /[0-9]+(\.[0-9]+)?/; @@ -20,7 +19,7 @@ fn constructors() { // #[test] // fn flags() { -// let mut engine = Interpreter::new(); +// let mut engine = Context::new(); // let init = r#" // var re_gi = /test/gi; // var re_sm = /test/sm; @@ -46,8 +45,7 @@ fn constructors() { #[test] fn last_index() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var regex = /[0-9]+(\.[0-9]+)?/g; "#; @@ -62,8 +60,7 @@ fn last_index() { #[test] fn exec() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var re = /quick\s(brown).+?(jumps)/ig; var result = re.exec('The Quick Brown Fox Jumps Over The Lazy Dog'); @@ -85,8 +82,7 @@ fn exec() { #[test] fn to_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!( forward(&mut engine, "(new RegExp('a+b+c')).toString()"), diff --git a/boa/src/builtins/string/mod.rs b/boa/src/builtins/string/mod.rs index 446062b7ca..d51c4d2411 100644 --- a/boa/src/builtins/string/mod.rs +++ b/boa/src/builtins/string/mod.rs @@ -18,10 +18,9 @@ use crate::{ object::{Object, ObjectData}, RegExp, }, - exec::Interpreter, property::Property, value::{RcString, Value}, - BoaProfiler, Result, + BoaProfiler, Context, Result, }; use regex::Regex; use std::string::String as StdString; @@ -48,7 +47,7 @@ impl String { /// which can differ in JavaScript engines. In Boa it is `2^32 - 1` pub(crate) const MAX_STRING_LENGTH: f64 = u32::MAX as f64; - fn this_string_value(this: &Value, ctx: &mut Interpreter) -> Result { + fn this_string_value(this: &Value, ctx: &mut Context) -> Result { match this { Value::String(ref string) => return Ok(string.clone()), Value::Object(ref object) => { @@ -67,11 +66,7 @@ impl String { /// /// [[Call]] - Returns a new native `string` /// - pub(crate) fn make_string( - this: &Value, - args: &[Value], - ctx: &mut Interpreter, - ) -> Result { + pub(crate) fn make_string(this: &Value, args: &[Value], ctx: &mut Context) -> Result { // This value is used by console.log and other routines to match Obexpecty"failed to parse argument for String method"pe // to its Javascript Identifier (global constructor method name) let string = match args.get(0) { @@ -91,7 +86,7 @@ impl String { /// Get the string value to a primitive string #[allow(clippy::wrong_self_convention)] #[inline] - pub(crate) fn to_string(this: &Value, _: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn to_string(this: &Value, _: &[Value], ctx: &mut Context) -> Result { // Get String from String Object and send it back as a new value Ok(Value::from(Self::this_string_value(this, ctx)?)) } @@ -112,7 +107,7 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.charat /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charAt - pub(crate) fn char_at(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn char_at(this: &Value, args: &[Value], ctx: &mut Context) -> Result { // First we get it the actual string a private field stored on the object only the engine has access to. // Then we convert it into a Rust String by wrapping it in from_value let primitive_val = this.to_string(ctx)?; @@ -154,11 +149,7 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.charcodeat /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt - pub(crate) fn char_code_at( - this: &Value, - args: &[Value], - ctx: &mut Interpreter, - ) -> Result { + pub(crate) fn char_code_at(this: &Value, args: &[Value], ctx: &mut Context) -> Result { // First we get it the actual string a private field stored on the object only the engine has access to. // Then we convert it into a Rust String by wrapping it in from_value let primitive_val = this.to_string(ctx)?; @@ -198,7 +189,7 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.concat /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/concat - pub(crate) fn concat(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn concat(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let object = this.require_object_coercible(ctx)?; let mut string = object.to_string(ctx)?.to_string(); @@ -220,7 +211,7 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.repeat /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat - pub(crate) fn repeat(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn repeat(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let object = this.require_object_coercible(ctx)?; let string = object.to_string(ctx)?; @@ -254,7 +245,7 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.slice /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice - pub(crate) fn slice(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn slice(this: &Value, args: &[Value], ctx: &mut Context) -> Result { // First we get it the actual string a private field stored on the object only the engine has access to. // Then we convert it into a Rust String by wrapping it in from_value let primitive_val = this.to_string(ctx)?; @@ -304,11 +295,7 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.startswith /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith - pub(crate) fn starts_with( - this: &Value, - args: &[Value], - ctx: &mut Interpreter, - ) -> Result { + pub(crate) fn starts_with(this: &Value, args: &[Value], ctx: &mut Context) -> Result { // First we get it the actual string a private field stored on the object only the engine has access to. // Then we convert it into a Rust String by wrapping it in from_value let primitive_val = this.to_string(ctx)?; @@ -351,7 +338,7 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.endswith /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith - pub(crate) fn ends_with(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn ends_with(this: &Value, args: &[Value], ctx: &mut Context) -> Result { // First we get it the actual string a private field stored on the object only the engine has access to. // Then we convert it into a Rust String by wrapping it in from_value let primitive_val = this.to_string(ctx)?; @@ -397,7 +384,7 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.includes /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes - pub(crate) fn includes(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn includes(this: &Value, args: &[Value], ctx: &mut Context) -> Result { // First we get it the actual string a private field stored on the object only the engine has access to. // Then we convert it into a Rust String by wrapping it in from_value let primitive_val = this.to_string(ctx)?; @@ -459,7 +446,7 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.replace /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace - pub(crate) fn replace(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn replace(this: &Value, args: &[Value], ctx: &mut Context) -> Result { // TODO: Support Symbol replacer let primitive_val = this.to_string(ctx)?; if args.is_empty() { @@ -617,7 +604,7 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.indexof /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf - pub(crate) fn index_of(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn index_of(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let this = this.require_object_coercible(ctx)?; let string = this.to_string(ctx)?; @@ -660,11 +647,7 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.lastindexof /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/lastIndexOf - pub(crate) fn last_index_of( - this: &Value, - args: &[Value], - ctx: &mut Interpreter, - ) -> Result { + pub(crate) fn last_index_of(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let this = this.require_object_coercible(ctx)?; let string = this.to_string(ctx)?; @@ -705,7 +688,7 @@ impl String { /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.match /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match /// [regex]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions - pub(crate) fn r#match(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn r#match(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let re = RegExp::make_regexp(&Value::from(Object::default()), &[args[0].clone()], ctx)?; RegExp::r#match(&re, this.to_string(ctx)?, ctx) } @@ -756,7 +739,7 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.padend /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd - pub(crate) fn pad_end(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn pad_end(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let primitive = this.to_string(ctx)?; if args.is_empty() { return Err(Value::from("padEnd requires maxLength argument")); @@ -783,7 +766,7 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.padstart /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart - pub(crate) fn pad_start(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn pad_start(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let primitive = this.to_string(ctx)?; if args.is_empty() { return Err(Value::from("padStart requires maxLength argument")); @@ -808,11 +791,11 @@ impl String { // And does not include: // '\u{FEFF}' (zero width non-breaking space) match c { - // Explicit whitespace: https://tc39.es/ecma262/#sec-white-space + // Explicit whitespace: https://tc39.es/ecma262/#sec-white-space '\u{0009}' | '\u{000B}' | '\u{000C}' | '\u{0020}' | '\u{00A0}' | '\u{FEFF}' | - // Unicode Space_Seperator category + // Unicode Space_Seperator category '\u{1680}' | '\u{2000}'..='\u{200A}' | '\u{202F}' | '\u{205F}' | '\u{3000}' | - // Line terminators: https://tc39.es/ecma262/#sec-line-terminators + // Line terminators: https://tc39.es/ecma262/#sec-line-terminators '\u{000A}' | '\u{000D}' | '\u{2028}' | '\u{2029}' => true, _ => false, } @@ -830,7 +813,7 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.trim /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim - pub(crate) fn trim(this: &Value, _: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn trim(this: &Value, _: &[Value], ctx: &mut Context) -> Result { let this = this.require_object_coercible(ctx)?; let string = this.to_string(ctx)?; Ok(Value::from( @@ -850,8 +833,7 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.trimstart /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trimStart - pub(crate) fn trim_start(this: &Value, _: &[Value], ctx: &mut Interpreter) -> Result { - let this = this.require_object_coercible(ctx)?; + pub(crate) fn trim_start(this: &Value, _: &[Value], ctx: &mut Context) -> Result { let string = this.to_string(ctx)?; Ok(Value::from( string.trim_start_matches(Self::is_trimmable_whitespace), @@ -870,7 +852,7 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.trimend /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trimEnd - pub(crate) fn trim_end(this: &Value, _: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn trim_end(this: &Value, _: &[Value], ctx: &mut Context) -> Result { let this = this.require_object_coercible(ctx)?; let string = this.to_string(ctx)?; Ok(Value::from( @@ -889,7 +871,7 @@ impl String { /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.tolowercase /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase #[allow(clippy::wrong_self_convention)] - pub(crate) fn to_lowercase(this: &Value, _: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn to_lowercase(this: &Value, _: &[Value], ctx: &mut Context) -> Result { // First we get it the actual string a private field stored on the object only the engine has access to. // Then we convert it into a Rust String by wrapping it in from_value let this_str = this.to_string(ctx)?; @@ -911,7 +893,7 @@ impl String { /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.toUppercase /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase #[allow(clippy::wrong_self_convention)] - pub(crate) fn to_uppercase(this: &Value, _: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn to_uppercase(this: &Value, _: &[Value], ctx: &mut Context) -> Result { // First we get it the actual string a private field stored on the object only the engine has access to. // Then we convert it into a Rust String by wrapping it in from_value let this_str = this.to_string(ctx)?; @@ -930,7 +912,7 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.substring /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring - pub(crate) fn substring(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn substring(this: &Value, args: &[Value], ctx: &mut Context) -> Result { // First we get it the actual string a private field stored on the object only the engine has access to. // Then we convert it into a Rust String by wrapping it in from_value let primitive_val = this.to_string(ctx)?; @@ -979,7 +961,7 @@ impl String { /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.substr /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr /// - pub(crate) fn substr(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn substr(this: &Value, args: &[Value], ctx: &mut Context) -> Result { // First we get it the actual string a private field stored on the object only the engine has access to. // Then we convert it into a Rust String by wrapping it in from_value let primitive_val = this.to_string(ctx)?; @@ -1035,7 +1017,7 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.value_of /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/valueOf - pub(crate) fn value_of(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn value_of(this: &Value, args: &[Value], ctx: &mut Context) -> Result { // Use the to_string method because it is specified to do the same thing in this case Self::to_string(this, args, ctx) } @@ -1053,7 +1035,7 @@ impl String { /// [regex]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions /// [cg]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges // TODO: update this method to return iterator - pub(crate) fn match_all(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn match_all(this: &Value, args: &[Value], ctx: &mut Context) -> Result { let re: Value = match args.get(0) { Some(arg) => { if arg.is_null() { @@ -1084,12 +1066,12 @@ impl String { /// Initialise the `String` object on the global object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(interpreter: &mut Context) -> (&'static str, Value) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); // Create `String` `prototype` - let global = interpreter.global(); + let global = interpreter.global_object(); let prototype = Value::new_object(Some(global)); let length = Property::default().value(Value::from(0)); diff --git a/boa/src/builtins/string/tests.rs b/boa/src/builtins/string/tests.rs index 3666f4a1cb..5778e37e09 100644 --- a/boa/src/builtins/string/tests.rs +++ b/boa/src/builtins/string/tests.rs @@ -1,12 +1,11 @@ -use crate::{exec::Interpreter, forward, forward_val, realm::Realm}; +use crate::{forward, forward_val, Context}; ///TODO: re-enable when getProperty() is finished; #[test] #[ignore] fn length() { //TEST262: https://github.com/tc39/test262/blob/master/test/built-ins/String/length.js - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" const a = new String(' '); const b = new String('\ud834\udf06'); @@ -30,8 +29,7 @@ fn length() { #[test] fn new_string_has_length() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" let a = new String("1234"); a @@ -43,8 +41,7 @@ fn new_string_has_length() { #[test] fn new_utf8_string_has_length() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" let a = new String("中文"); a @@ -56,8 +53,7 @@ fn new_utf8_string_has_length() { #[test] fn concat() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var hello = new String('Hello, '); var world = new String('world! '); @@ -74,8 +70,7 @@ fn concat() { #[test] fn generic_concat() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" Number.prototype.concat = String.prototype.concat; let number = new Number(100); @@ -90,8 +85,7 @@ fn generic_concat() { #[test] /// Test the correct type is returned from call and construct fn construct_and_call() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var hello = new String('Hello'); var world = String('world'); @@ -108,8 +102,7 @@ fn construct_and_call() { #[test] fn repeat() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var empty = new String(''); var en = new String('english'); @@ -130,8 +123,7 @@ fn repeat() { #[test] fn repeat_throws_when_count_is_negative() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!( forward( @@ -150,8 +142,7 @@ fn repeat_throws_when_count_is_negative() { #[test] fn repeat_throws_when_count_is_infinity() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!( forward( @@ -170,8 +161,7 @@ fn repeat_throws_when_count_is_infinity() { #[test] fn repeat_throws_when_count_overflows_max_length() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!( forward( @@ -190,8 +180,7 @@ fn repeat_throws_when_count_overflows_max_length() { #[test] fn repeat_generic() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = "Number.prototype.repeat = String.prototype.repeat;"; forward(&mut engine, init); @@ -205,8 +194,7 @@ fn repeat_generic() { #[test] fn replace() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = "abc"; a = a.replace("a", "2"); @@ -220,8 +208,7 @@ fn replace() { #[test] fn replace_no_match() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = "abc"; a = a.replace(/d/, "$&$&"); @@ -234,8 +221,7 @@ fn replace_no_match() { #[test] fn replace_with_capture_groups() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var re = /(\w+)\s(\w+)/; var a = "John Smith"; @@ -250,8 +236,7 @@ fn replace_with_capture_groups() { #[test] fn replace_with_tenth_capture_group() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var re = /(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)/; var a = "0123456789"; @@ -265,8 +250,7 @@ fn replace_with_tenth_capture_group() { #[test] fn replace_substitutions() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var re = / two /; var a = "one two three"; @@ -288,8 +272,7 @@ fn replace_substitutions() { #[test] fn replace_with_function() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var a = "ecmascript is cool"; var p1, p2, p3; @@ -315,8 +298,7 @@ fn replace_with_function() { #[test] fn starts_with() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var empty = new String(''); var en = new String('english'); @@ -340,8 +322,7 @@ fn starts_with() { #[test] fn ends_with() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var empty = new String(''); var en = new String('english'); @@ -365,8 +346,7 @@ fn ends_with() { #[test] fn match_all() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "'aa'.matchAll(null).length"), "0"); assert_eq!(forward(&mut engine, "'aa'.matchAll(/b/).length"), "0"); @@ -408,8 +388,7 @@ fn match_all() { #[test] fn test_match() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var str = new String('The Quick Brown Fox Jumps Over The Lazy Dog'); var result1 = str.match(/quick\s(brown).+?(jumps)/i); @@ -453,8 +432,7 @@ fn test_match() { #[test] fn trim() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "'Hello'.trim()"), "\"Hello\""); assert_eq!(forward(&mut engine, "' \nHello'.trim()"), "\"Hello\""); assert_eq!(forward(&mut engine, "'Hello \n\r'.trim()"), "\"Hello\""); @@ -463,8 +441,7 @@ fn trim() { #[test] fn trim_start() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "'Hello'.trimStart()"), "\"Hello\""); assert_eq!(forward(&mut engine, "' \nHello'.trimStart()"), "\"Hello\""); assert_eq!( @@ -476,8 +453,7 @@ fn trim_start() { #[test] fn trim_end() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "'Hello'.trimEnd()"), "\"Hello\""); assert_eq!(forward(&mut engine, "' \nHello'.trimEnd()"), "\" \nHello\""); assert_eq!(forward(&mut engine, "'Hello \n'.trimEnd()"), "\"Hello\""); @@ -486,8 +462,7 @@ fn trim_end() { #[test] fn index_of_with_no_arguments() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "''.indexOf()"), "-1"); assert_eq!(forward(&mut engine, "'undefined'.indexOf()"), "0"); assert_eq!(forward(&mut engine, "'a1undefined'.indexOf()"), "2"); @@ -498,8 +473,7 @@ fn index_of_with_no_arguments() { #[test] fn index_of_with_string_search_string_argument() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "''.indexOf('hello')"), "-1"); assert_eq!( forward(&mut engine, "'undefined'.indexOf('undefined')"), @@ -525,8 +499,7 @@ fn index_of_with_string_search_string_argument() { #[test] fn index_of_with_non_string_search_string_argument() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "''.indexOf(1)"), "-1"); assert_eq!(forward(&mut engine, "'1'.indexOf(1)"), "0"); assert_eq!(forward(&mut engine, "'true'.indexOf(true)"), "0"); @@ -537,8 +510,7 @@ fn index_of_with_non_string_search_string_argument() { #[test] fn index_of_with_from_index_argument() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "''.indexOf('x', 2)"), "-1"); assert_eq!(forward(&mut engine, "'x'.indexOf('x', 2)"), "-1"); assert_eq!(forward(&mut engine, "'abcx'.indexOf('x', 2)"), "3"); @@ -553,8 +525,7 @@ fn index_of_with_from_index_argument() { #[test] fn generic_index_of() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); forward_val( &mut engine, "Number.prototype.indexOf = String.prototype.indexOf", @@ -568,8 +539,7 @@ fn generic_index_of() { #[test] fn index_of_empty_search_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "''.indexOf('')"), "0"); assert_eq!(forward(&mut engine, "''.indexOf('', 10)"), "0"); @@ -580,8 +550,7 @@ fn index_of_empty_search_string() { #[test] fn last_index_of_with_no_arguments() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "''.lastIndexOf()"), "-1"); assert_eq!(forward(&mut engine, "'undefined'.lastIndexOf()"), "0"); assert_eq!(forward(&mut engine, "'a1undefined'.lastIndexOf()"), "2"); @@ -601,8 +570,7 @@ fn last_index_of_with_no_arguments() { #[test] fn last_index_of_with_string_search_string_argument() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "''.lastIndexOf('hello')"), "-1"); assert_eq!( forward(&mut engine, "'undefined'.lastIndexOf('undefined')"), @@ -637,8 +605,7 @@ fn last_index_of_with_string_search_string_argument() { #[test] fn last_index_of_with_non_string_search_string_argument() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "''.lastIndexOf(1)"), "-1"); assert_eq!(forward(&mut engine, "'1'.lastIndexOf(1)"), "0"); assert_eq!(forward(&mut engine, "'11'.lastIndexOf(1)"), "1"); @@ -653,8 +620,7 @@ fn last_index_of_with_non_string_search_string_argument() { #[test] fn last_index_of_with_from_index_argument() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "''.lastIndexOf('x', 2)"), "-1"); assert_eq!(forward(&mut engine, "'x'.lastIndexOf('x', 2)"), "-1"); assert_eq!(forward(&mut engine, "'abcxx'.lastIndexOf('x', 2)"), "4"); @@ -669,8 +635,7 @@ fn last_index_of_with_from_index_argument() { #[test] fn last_index_with_empty_search_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "''.lastIndexOf('')"), "0"); assert_eq!(forward(&mut engine, "'x'.lastIndexOf('', 2)"), "1"); assert_eq!(forward(&mut engine, "'abcxx'.lastIndexOf('', 4)"), "4"); @@ -681,8 +646,7 @@ fn last_index_with_empty_search_string() { #[test] fn generic_last_index_of() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); forward_val( &mut engine, "Number.prototype.lastIndexOf = String.prototype.lastIndexOf", @@ -696,8 +660,7 @@ fn generic_last_index_of() { #[test] fn last_index_non_integer_position_argument() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!( forward(&mut engine, "''.lastIndexOf('x', new Number(4))"), "-1" diff --git a/boa/src/builtins/symbol/mod.rs b/boa/src/builtins/symbol/mod.rs index 6140bb078b..576a0a7c0f 100644 --- a/boa/src/builtins/symbol/mod.rs +++ b/boa/src/builtins/symbol/mod.rs @@ -20,10 +20,9 @@ mod tests; use super::function::{make_builtin_fn, make_constructor_fn}; use crate::{ - exec::Interpreter, property::{Attribute, Property}, value::{RcString, RcSymbol, Value}, - BoaProfiler, Result, + BoaProfiler, Context, Result, }; use gc::{Finalize, Trace}; @@ -56,7 +55,7 @@ impl Symbol { self.hash } - fn this_symbol_value(value: &Value, ctx: &mut Interpreter) -> Result { + fn this_symbol_value(value: &Value, ctx: &mut Context) -> Result { match value { Value::Symbol(ref symbol) => return Ok(symbol.clone()), Value::Object(ref object) => { @@ -82,7 +81,7 @@ impl Symbol { /// /// [spec]: https://tc39.es/ecma262/#sec-symbol-description /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/Symbol - pub(crate) fn call(_: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn call(_: &Value, args: &[Value], ctx: &mut Context) -> Result { let description = match args.get(0) { Some(ref value) if !value.is_undefined() => Some(value.to_string(ctx)?), _ => None, @@ -102,7 +101,7 @@ impl Symbol { /// [spec]: https://tc39.es/ecma262/#sec-symbol.prototype.tostring /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toString #[allow(clippy::wrong_self_convention)] - pub(crate) fn to_string(this: &Value, _: &[Value], ctx: &mut Interpreter) -> Result { + pub(crate) fn to_string(this: &Value, _: &[Value], ctx: &mut Context) -> Result { let symbol = Self::this_symbol_value(this, ctx)?; let description = symbol.description().unwrap_or(""); Ok(Value::from(format!("Symbol({})", description))) @@ -110,7 +109,7 @@ impl Symbol { /// Initialise the `Symbol` object on the global object. #[inline] - pub fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { + pub fn init(interpreter: &mut Context) -> (&'static str, Value) { // Define the Well-Known Symbols // https://tc39.es/ecma262/#sec-well-known-symbols let symbol_async_iterator = @@ -129,7 +128,7 @@ impl Symbol { let symbol_to_string_tag = interpreter.construct_symbol(Some("Symbol.toStringTag".into())); let symbol_unscopables = interpreter.construct_symbol(Some("Symbol.unscopables".into())); - let global = interpreter.global(); + let global = interpreter.global_object(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); // Create prototype object diff --git a/boa/src/builtins/symbol/tests.rs b/boa/src/builtins/symbol/tests.rs index 3e7f293ec9..9f3bfee68a 100644 --- a/boa/src/builtins/symbol/tests.rs +++ b/boa/src/builtins/symbol/tests.rs @@ -1,9 +1,8 @@ -use crate::{exec::Interpreter, forward, forward_val, realm::Realm}; +use crate::{forward, forward_val, Context}; #[test] fn call_symbol_and_check_return_type() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var sym = Symbol(); "#; @@ -14,8 +13,7 @@ fn call_symbol_and_check_return_type() { #[test] fn print_symbol_expect_description() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var sym = Symbol("Hello"); "#; @@ -26,8 +24,7 @@ fn print_symbol_expect_description() { #[test] fn symbol_access() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var x = {}; var sym1 = Symbol("Hello"); diff --git a/boa/src/builtins/undefined/mod.rs b/boa/src/builtins/undefined/mod.rs index 6913b08d47..76a4357901 100644 --- a/boa/src/builtins/undefined/mod.rs +++ b/boa/src/builtins/undefined/mod.rs @@ -12,7 +12,7 @@ #[cfg(test)] mod tests; -use crate::{BoaProfiler, Interpreter, Value}; +use crate::{BoaProfiler, Context, Value}; /// JavaScript global `undefined` property. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -24,7 +24,7 @@ impl Undefined { /// Initialize the `undefined` property on the global object. #[inline] - pub(crate) fn init(_interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(_interpreter: &mut Context) -> (&'static str, Value) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); (Self::NAME, Value::undefined()) diff --git a/boa/src/class.rs b/boa/src/class.rs index 4640bfb4c6..6ce089a0d0 100644 --- a/boa/src/class.rs +++ b/boa/src/class.rs @@ -5,10 +5,7 @@ //!# use boa::{ //!# property::Attribute, //!# class::{Class, ClassBuilder}, -//!# exec::Interpreter, -//!# forward_val, -//!# realm::Realm, -//!# Finalize, Value, Result, Trace, +//!# Context, Finalize, Result, Trace, Value, //!# }; //!# //! // This does not have to be an enum it can also be a struct. @@ -27,7 +24,7 @@ //! const LENGTH: usize = 1; //! //! // This is what is called when we do `new Animal()` -//! fn constructor(_this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result { +//! fn constructor(_this: &Value, args: &[Value], ctx: &mut Context) -> Result { //! // This is equivalent to `String(arg)`. //! let kind = args.get(0).cloned().unwrap_or_default().to_string(ctx)?; //! @@ -68,7 +65,7 @@ use crate::{ object::{GcObject, NativeObject, Object, ObjectData, PROTOTYPE}, }, property::{Attribute, Property, PropertyKey}, - Interpreter, Result, Value, + Context, Result, Value, }; use std::fmt::Debug; @@ -82,7 +79,7 @@ pub trait Class: NativeObject + Sized { const ATTRIBUTE: Attribute = Attribute::all(); /// The constructor of the class. - fn constructor(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result; + fn constructor(this: &Value, args: &[Value], ctx: &mut Context) -> Result; /// Initializes the internals and the methods of the class. fn init(class: &mut ClassBuilder<'_>) -> Result<()>; @@ -93,13 +90,13 @@ pub trait Class: NativeObject + Sized { /// This is automatically implemented, when a type implements `Class`. pub trait ClassConstructor: Class { /// The raw constructor that mathces the `NativeFunction` signature. - fn raw_constructor(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result + fn raw_constructor(this: &Value, args: &[Value], ctx: &mut Context) -> Result where Self: Sized; } impl ClassConstructor for T { - fn raw_constructor(this: &Value, args: &[Value], ctx: &mut Interpreter) -> Result + fn raw_constructor(this: &Value, args: &[Value], ctx: &mut Context) -> Result where Self: Sized, { @@ -113,7 +110,7 @@ impl ClassConstructor for T { #[derive(Debug)] pub struct ClassBuilder<'context> { /// The current context. - context: &'context mut Interpreter, + context: &'context mut Context, /// The constructor object. object: GcObject, @@ -123,11 +120,11 @@ pub struct ClassBuilder<'context> { } impl<'context> ClassBuilder<'context> { - pub(crate) fn new(context: &'context mut Interpreter) -> Self + pub(crate) fn new(context: &'context mut Context) -> Self where T: ClassConstructor, { - let global = context.global(); + let global = context.global_object(); let prototype = { let object_prototype = global.get_field("Object").get_field(PROTOTYPE); @@ -190,7 +187,7 @@ impl<'context> ClassBuilder<'context> { let mut function = Object::function( Function::BuiltIn(function.into(), FunctionFlags::CALLABLE), self.context - .global() + .global_object() .get_field("Function") .get_field("prototype"), ); @@ -214,7 +211,7 @@ impl<'context> ClassBuilder<'context> { let mut function = Object::function( Function::BuiltIn(function.into(), FunctionFlags::CALLABLE), self.context - .global() + .global_object() .get_field("Function") .get_field("prototype"), ); @@ -262,7 +259,7 @@ impl<'context> ClassBuilder<'context> { } /// Return the current context. - pub fn context(&mut self) -> &'_ mut Interpreter { + pub fn context(&mut self) -> &'_ mut Context { self.context } } diff --git a/boa/src/context.rs b/boa/src/context.rs new file mode 100644 index 0000000000..8330fae6b0 --- /dev/null +++ b/boa/src/context.rs @@ -0,0 +1,496 @@ +//! Javascript context. + +use crate::{ + builtins::{ + self, + function::{Function, FunctionFlags, NativeFunction}, + object::ObjectData, + object::{GcObject, Object, PROTOTYPE}, + Console, Symbol, + }, + class::{Class, ClassBuilder}, + exec::Interpreter, + property::{Property, PropertyKey}, + realm::Realm, + syntax::{ + ast::{ + node::{ + statement_list::RcStatementList, Call, FormalParameter, Identifier, New, + StatementList, + }, + Const, Node, + }, + Parser, + }, + value::{PreferredType, RcString, RcSymbol, Type, Value}, + BoaProfiler, Executable, Result, +}; +use std::result::Result as StdResult; + +/// Javascript context. It is the primary way to interact with the runtime. +/// +/// For each `Context` instance a new instance of runtime is created. +/// It means that it is safe to use different contexts in different threads, +/// but each `Context` instance must be used only from a single thread. +#[derive(Debug)] +pub struct Context { + /// realm holds both the global object and the environment + realm: Realm, + + /// The current executor. + executor: Interpreter, + + /// Symbol hash. + /// + /// For now this is an incremented u32 number. + symbol_count: u32, + + /// console object state. + console: Console, +} + +impl Default for Context { + fn default() -> Self { + let realm = Realm::create(); + let executor = Interpreter::new(); + let mut context = Self { + realm, + executor, + symbol_count: 0, + console: Console::default(), + }; + + // Add new builtIns to Context Realm + // At a later date this can be removed from here and called explicitly, + // but for now we almost always want these default builtins + context.create_intrinsics(); + + context + } +} + +impl Context { + /// Create a new `Context`. + pub fn new() -> Self { + Default::default() + } + + pub fn realm(&self) -> &Realm { + &self.realm + } + + pub fn realm_mut(&mut self) -> &mut Realm { + &mut self.realm + } + + pub fn executor(&mut self) -> &mut Interpreter { + &mut self.executor + } + + /// A helper function for getting a immutable reference to the `console` object. + pub(crate) fn console(&self) -> &Console { + &self.console + } + + /// A helper function for getting a mutable reference to the `console` object. + pub(crate) fn console_mut(&mut self) -> &mut Console { + &mut self.console + } + + /// Sets up the default global objects within Global + fn create_intrinsics(&mut self) { + let _timer = BoaProfiler::global().start_event("create_intrinsics", "interpreter"); + // Create intrinsics, add global objects here + builtins::init(self); + } + + /// Generates a new `Symbol` internal hash. + /// + /// This currently is an incremented value. + #[inline] + fn generate_hash(&mut self) -> u32 { + let hash = self.symbol_count; + self.symbol_count += 1; + hash + } + + /// Construct a new `Symbol` with an optional description. + #[inline] + pub fn construct_symbol(&mut self, description: Option) -> RcSymbol { + RcSymbol::from(Symbol::new(self.generate_hash(), description)) + } + + /// Construct an empty object. + #[inline] + pub fn construct_object(&self) -> GcObject { + let object_prototype = self + .global_object() + .get_field("Object") + .get_field(PROTOTYPE); + GcObject::new(Object::create(object_prototype)) + } + + /// + pub(crate) fn call(&mut self, f: &Value, this: &Value, args: &[Value]) -> Result { + match *f { + Value::Object(ref object) => object.call(this, args, self), + _ => self.throw_type_error("not a function"), + } + } + + /// Return the global object. + pub fn global_object(&self) -> &Value { + &self.realm.global_obj + } + + /// Constructs a `RangeError` with the specified message. + pub fn construct_range_error(&mut self, message: M) -> Value + where + M: Into, + { + // Runs a `new RangeError(message)`. + New::from(Call::new( + Identifier::from("RangeError"), + vec![Const::from(message.into()).into()], + )) + .run(self) + .expect_err("RangeError should always throw") + } + + /// Throws a `RangeError` with the specified message. + pub fn throw_range_error(&mut self, message: M) -> Result + where + M: Into, + { + Err(self.construct_range_error(message)) + } + + /// Constructs a `TypeError` with the specified message. + pub fn construct_type_error(&mut self, message: M) -> Value + where + M: Into, + { + // Runs a `new TypeError(message)`. + New::from(Call::new( + Identifier::from("TypeError"), + vec![Const::from(message.into()).into()], + )) + .run(self) + .expect_err("TypeError should always throw") + } + + /// Throws a `TypeError` with the specified message. + pub fn throw_type_error(&mut self, message: M) -> Result + where + M: Into, + { + Err(self.construct_type_error(message)) + } + + /// Constructs a `ReferenceError` with the specified message. + pub fn construct_reference_error(&mut self, message: M) -> Value + where + M: Into, + { + New::from(Call::new( + Identifier::from("ReferenceError"), + vec![Const::from(message.into() + " is not defined").into()], + )) + .run(self) + .expect_err("ReferenceError should always throw") + } + + /// Throws a `ReferenceError` with the specified message. + pub fn throw_reference_error(&mut self, message: M) -> Result + where + M: Into, + { + Err(self.construct_reference_error(message)) + } + + /// Constructs a `SyntaxError` with the specified message. + pub fn construct_syntax_error(&mut self, message: M) -> Value + where + M: Into, + { + New::from(Call::new( + Identifier::from("SyntaxError"), + vec![Const::from(message.into()).into()], + )) + .run(self) + .expect_err("SyntaxError should always throw") + } + + /// Throws a `SyntaxError` with the specified message. + pub fn throw_syntax_error(&mut self, message: M) -> Result + where + M: Into, + { + Err(self.construct_syntax_error(message)) + } + + /// Utility to create a function Value for Function Declarations, Arrow Functions or Function Expressions + pub(crate) fn create_function( + &mut self, + params: P, + body: B, + flags: FunctionFlags, + ) -> Value + where + P: Into>, + B: Into, + { + let function_prototype = self + .global_object() + .get_field("Function") + .get_field(PROTOTYPE); + + // Every new function has a prototype property pre-made + let proto = Value::new_object(Some(self.global_object())); + + let params = params.into(); + let params_len = params.len(); + let func = Function::Ordinary { + flags, + body: RcStatementList::from(body.into()), + params, + environment: self.realm.environment.get_current_environment().clone(), + }; + + let new_func = Object::function(func, function_prototype); + + let val = Value::from(new_func); + + // Set constructor field to the newly created Value (function object) + proto.set_field("constructor", val.clone()); + + val.set_field(PROTOTYPE, proto); + val.set_field("length", Value::from(params_len)); + + val + } + + /// Create a new builin function. + pub fn create_builtin_function( + &mut self, + name: &str, + length: usize, + body: NativeFunction, + ) -> Result { + let function_prototype = self + .global_object() + .get_field("Function") + .get_field(PROTOTYPE); + + // Every new function has a prototype property pre-made + let proto = Value::new_object(Some(self.global_object())); + let mut function = Object::function( + Function::BuiltIn(body.into(), FunctionFlags::CALLABLE), + function_prototype, + ); + function.set(PROTOTYPE.into(), proto); + function.set("length".into(), length.into()); + function.set("name".into(), name.into()); + + Ok(GcObject::new(function)) + } + + /// Register a global function. + pub fn register_global_function( + &mut self, + name: &str, + length: usize, + body: NativeFunction, + ) -> Result<()> { + let function = self.create_builtin_function(name, length, body)?; + self.global_object().set_field(name, function); + Ok(()) + } + + /// Converts an array object into a rust vector of values. + /// + /// This is useful for the spread operator, for any other object an `Err` is returned + pub(crate) fn extract_array_properties(&mut self, value: &Value) -> StdResult, ()> { + if let Value::Object(ref x) = value { + // Check if object is array + if let ObjectData::Array = x.borrow().data { + let length = value.get_field("length").as_number().unwrap() as i32; + let values = (0..length) + .map(|idx| value.get_field(idx.to_string())) + .collect(); + return Ok(values); + } + // Check if object is a Map + else if let ObjectData::Map(ref map) = x.borrow().data { + let values = map + .iter() + .map(|(key, value)| { + // Construct a new array containing the key-value pair + let array = Value::new_object(Some( + &self + .realm() + .environment + .get_global_object() + .expect("Could not get global object"), + )); + array.set_data(ObjectData::Array); + array.as_object_mut().expect("object").set_prototype( + self.realm() + .environment + .get_binding_value("Array") + .expect("Array was not initialized") + .get_field(PROTOTYPE), + ); + array.set_field("0", key); + array.set_field("1", value); + array.set_field("length", Value::from(2)); + array + }) + .collect(); + return Ok(values); + } + + return Err(()); + } + + Err(()) + } + + /// Converts an object to a primitive. + /// + /// More information: + /// - [ECMAScript][spec] + /// + /// [spec]: https://tc39.es/ecma262/#sec-ordinarytoprimitive + pub(crate) fn ordinary_to_primitive( + &mut self, + o: &Value, + hint: PreferredType, + ) -> Result { + // 1. Assert: Type(O) is Object. + debug_assert!(o.get_type() == Type::Object); + // 2. Assert: Type(hint) is String and its value is either "string" or "number". + debug_assert!(hint == PreferredType::String || hint == PreferredType::Number); + + // 3. If hint is "string", then + // a. Let methodNames be « "toString", "valueOf" ». + // 4. Else, + // a. Let methodNames be « "valueOf", "toString" ». + let method_names = if hint == PreferredType::String { + ["toString", "valueOf"] + } else { + ["valueOf", "toString"] + }; + + // 5. For each name in methodNames in List order, do + for name in &method_names { + // a. Let method be ? Get(O, name). + let method: Value = o.get_field(*name); + // b. If IsCallable(method) is true, then + if method.is_function() { + // i. Let result be ? Call(method, O). + let result = self.call(&method, &o, &[])?; + // ii. If Type(result) is not Object, return result. + if !result.is_object() { + return Ok(result); + } + } + } + + // 6. Throw a TypeError exception. + self.throw_type_error("cannot convert object to primitive value") + } + + /// https://tc39.es/ecma262/#sec-hasproperty + pub(crate) fn has_property(&self, obj: &Value, key: &PropertyKey) -> bool { + if let Some(obj) = obj.as_object() { + obj.has_property(key) + } else { + false + } + } + + pub(crate) fn set_value(&mut self, node: &Node, value: Value) -> Result { + match node { + Node::Identifier(ref name) => { + self.realm + .environment + .set_mutable_binding(name.as_ref(), value.clone(), true); + Ok(value) + } + Node::GetConstField(ref get_const_field_node) => Ok(get_const_field_node + .obj() + .run(self)? + .set_field(get_const_field_node.field(), value)), + Node::GetField(ref get_field) => { + let field = get_field.field().run(self)?; + let key = field.to_property_key(self)?; + Ok(get_field.obj().run(self)?.set_field(key, value)) + } + _ => panic!("TypeError: invalid assignment to {}", node), + } + } + + /// Register a global class of type `T`, where `T` implemets `Class`. + /// + /// # Example + /// ```ignore + /// #[derive(Debug, Trace, Finalize)] + /// struct MyClass; + /// + /// impl Class for MyClass { + /// // ... + /// } + /// + /// context.register_global_class::(); + /// ``` + pub fn register_global_class(&mut self) -> Result<()> + where + T: Class, + { + let mut class_builder = ClassBuilder::new::(self); + T::init(&mut class_builder)?; + + let class = class_builder.build(); + let property = Property::data_descriptor(class.into(), T::ATTRIBUTE); + self.global_object() + .as_object_mut() + .unwrap() + .insert_property(T::NAME, property); + Ok(()) + } + + fn parser_expr(src: &str) -> StdResult { + Parser::new(src.as_bytes()) + .parse_all() + .map_err(|e| e.to_string()) + } + + /// Evaluates the given code. + /// + /// # Examples + /// ``` + ///# use boa::Context; + /// let mut context = Context::new(); + /// + /// let value = context.eval("1 + 3").unwrap(); + /// + /// assert!(value.is_number()); + /// assert_eq!(value.as_number().unwrap(), 4.0); + /// ``` + #[allow(clippy::unit_arg, clippy::drop_copy)] + pub fn eval(&mut self, src: &str) -> Result { + let main_timer = BoaProfiler::global().start_event("Main", "Main"); + + let result = match Self::parser_expr(src) { + Ok(expr) => expr.run(self), + Err(e) => self.throw_type_error(e), + }; + + // The main_timer needs to be dropped before the BoaProfiler is. + drop(main_timer); + BoaProfiler::global().drop(); + + result + } +} diff --git a/boa/src/exec/array/mod.rs b/boa/src/exec/array/mod.rs index a83ec78ab4..3aa5831dd4 100644 --- a/boa/src/exec/array/mod.rs +++ b/boa/src/exec/array/mod.rs @@ -1,6 +1,6 @@ //! Array declaration execution. -use super::{Executable, Interpreter}; +use super::{Context, Executable}; use crate::{ builtins::Array, syntax::ast::node::{ArrayDecl, Node}, @@ -8,7 +8,7 @@ use crate::{ }; impl Executable for ArrayDecl { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("ArrayDecl", "exec"); let array = Array::new_array(interpreter)?; let mut elements = Vec::new(); diff --git a/boa/src/exec/block/mod.rs b/boa/src/exec/block/mod.rs index 2cf740512a..7564d3fef1 100644 --- a/boa/src/exec/block/mod.rs +++ b/boa/src/exec/block/mod.rs @@ -1,13 +1,13 @@ //! Block statement execution. -use super::{Executable, Interpreter, InterpreterState}; +use super::{Context, Executable, InterpreterState}; use crate::{ environment::lexical_environment::new_declarative_environment, syntax::ast::node::Block, BoaProfiler, Result, Value, }; impl Executable for Block { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("Block", "exec"); { let env = &mut interpreter.realm_mut().environment; @@ -22,7 +22,7 @@ impl Executable for Block { for statement in self.statements() { obj = statement.run(interpreter)?; - match interpreter.get_current_state() { + match interpreter.executor().get_current_state() { InterpreterState::Return => { // Early return. break; diff --git a/boa/src/exec/break_node/mod.rs b/boa/src/exec/break_node/mod.rs index ac0b901d0e..17d16eddf3 100644 --- a/boa/src/exec/break_node/mod.rs +++ b/boa/src/exec/break_node/mod.rs @@ -1,4 +1,4 @@ -use super::{Executable, Interpreter, InterpreterState}; +use super::{Context, Executable, InterpreterState}; use crate::{ syntax::ast::node::{Break, Continue}, Result, Value, @@ -8,16 +8,20 @@ use crate::{ mod tests; impl Executable for Break { - fn run(&self, interpreter: &mut Interpreter) -> Result { - interpreter.set_current_state(InterpreterState::Break(self.label().map(String::from))); + fn run(&self, interpreter: &mut Context) -> Result { + interpreter + .executor() + .set_current_state(InterpreterState::Break(self.label().map(String::from))); Ok(Value::undefined()) } } impl Executable for Continue { - fn run(&self, interpreter: &mut Interpreter) -> Result { - interpreter.set_current_state(InterpreterState::Continue(self.label().map(String::from))); + fn run(&self, interpreter: &mut Context) -> Result { + interpreter + .executor() + .set_current_state(InterpreterState::Continue(self.label().map(String::from))); Ok(Value::undefined()) } diff --git a/boa/src/exec/break_node/tests.rs b/boa/src/exec/break_node/tests.rs index 2cbb2db032..02d2557e9e 100644 --- a/boa/src/exec/break_node/tests.rs +++ b/boa/src/exec/break_node/tests.rs @@ -1,17 +1,16 @@ -use super::{Interpreter, InterpreterState}; -use crate::{exec::Executable, syntax::ast::node::Break, Realm}; +use super::{Context, InterpreterState}; +use crate::{exec::Executable, syntax::ast::node::Break}; #[test] fn check_post_state() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let brk: Break = Break::new("label"); brk.run(&mut engine).unwrap(); assert_eq!( - engine.get_current_state(), + engine.executor().get_current_state(), &InterpreterState::Break(Some("label".to_string())) ); } diff --git a/boa/src/exec/call/mod.rs b/boa/src/exec/call/mod.rs index a1246f0957..c0b6666561 100644 --- a/boa/src/exec/call/mod.rs +++ b/boa/src/exec/call/mod.rs @@ -1,4 +1,4 @@ -use super::{Executable, Interpreter, InterpreterState}; +use super::{Context, Executable, InterpreterState}; use crate::{ syntax::ast::node::{Call, Node}, value::{Type, Value}, @@ -6,7 +6,7 @@ use crate::{ }; impl Executable for Call { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("Call", "exec"); let (this, func) = match self.expr() { Node::GetConstField(ref get_const_field) => { @@ -44,7 +44,9 @@ impl Executable for Call { let fnct_result = interpreter.call(&func, &this, &v_args); // unset the early return flag - interpreter.set_current_state(InterpreterState::Executing); + interpreter + .executor() + .set_current_state(InterpreterState::Executing); fnct_result } diff --git a/boa/src/exec/conditional/mod.rs b/boa/src/exec/conditional/mod.rs index 912566924a..4b56464649 100644 --- a/boa/src/exec/conditional/mod.rs +++ b/boa/src/exec/conditional/mod.rs @@ -1,13 +1,12 @@ -use super::{Executable, Interpreter}; +use super::{Context, Executable}; use crate::{ syntax::ast::node::{ConditionalOp, If}, Result, Value, }; -use std::borrow::Borrow; impl Executable for If { - fn run(&self, interpreter: &mut Interpreter) -> Result { - Ok(if self.cond().run(interpreter)?.borrow().to_boolean() { + fn run(&self, interpreter: &mut Context) -> Result { + Ok(if self.cond().run(interpreter)?.to_boolean() { self.body().run(interpreter)? } else if let Some(ref else_e) = self.else_node() { else_e.run(interpreter)? @@ -18,8 +17,8 @@ impl Executable for If { } impl Executable for ConditionalOp { - fn run(&self, interpreter: &mut Interpreter) -> Result { - Ok(if self.cond().run(interpreter)?.borrow().to_boolean() { + fn run(&self, interpreter: &mut Context) -> Result { + Ok(if self.cond().run(interpreter)?.to_boolean() { self.if_true().run(interpreter)? } else { self.if_false().run(interpreter)? diff --git a/boa/src/exec/declaration/mod.rs b/boa/src/exec/declaration/mod.rs index ae2276b0b5..a882ea78aa 100644 --- a/boa/src/exec/declaration/mod.rs +++ b/boa/src/exec/declaration/mod.rs @@ -1,6 +1,6 @@ //! Declaration execution. -use super::{Executable, Interpreter}; +use super::{Context, Executable}; use crate::{ builtins::function::FunctionFlags, environment::lexical_environment::VariableScope, @@ -11,7 +11,7 @@ use crate::{ }; impl Executable for FunctionDecl { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("FunctionDecl", "exec"); let val = interpreter.create_function( self.parameters().to_vec(), @@ -37,7 +37,7 @@ impl Executable for FunctionDecl { } impl Executable for FunctionExpr { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { let val = interpreter.create_function( self.parameters().to_vec(), self.body().to_vec(), @@ -53,7 +53,7 @@ impl Executable for FunctionExpr { } impl Executable for VarDeclList { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { for var in self.as_ref() { let val = match var.init() { Some(v) => v.run(interpreter)?, @@ -79,7 +79,7 @@ impl Executable for VarDeclList { } impl Executable for ConstDeclList { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { for decl in self.as_ref() { let val = decl.init().run(interpreter)?; @@ -98,7 +98,7 @@ impl Executable for ConstDeclList { } impl Executable for LetDeclList { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { for var in self.as_ref() { let val = match var.init() { Some(v) => v.run(interpreter)?, @@ -119,7 +119,7 @@ impl Executable for LetDeclList { } impl Executable for ArrowFunctionDecl { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { Ok(interpreter.create_function( self.params().to_vec(), self.body().to_vec(), diff --git a/boa/src/exec/exception.rs b/boa/src/exec/exception.rs deleted file mode 100644 index 06ea6e8830..0000000000 --- a/boa/src/exec/exception.rs +++ /dev/null @@ -1,96 +0,0 @@ -use super::*; -use crate::{ - exec::Executable, - syntax::ast::{ - node::{Call, Identifier, New}, - Const, - }, -}; - -impl Interpreter { - /// Constructs a `RangeError` with the specified message. - pub fn construct_range_error(&mut self, message: M) -> Value - where - M: Into, - { - // Runs a `new RangeError(message)`. - New::from(Call::new( - Identifier::from("RangeError"), - vec![Const::from(message.into()).into()], - )) - .run(self) - .expect_err("RangeError should always throw") - } - - /// Throws a `RangeError` with the specified message. - pub fn throw_range_error(&mut self, message: M) -> Result - where - M: Into, - { - Err(self.construct_range_error(message)) - } - - /// Constructs a `TypeError` with the specified message. - pub fn construct_type_error(&mut self, message: M) -> Value - where - M: Into, - { - // Runs a `new TypeError(message)`. - New::from(Call::new( - Identifier::from("TypeError"), - vec![Const::from(message.into()).into()], - )) - .run(self) - .expect_err("TypeError should always throw") - } - - /// Throws a `TypeError` with the specified message. - pub fn throw_type_error(&mut self, message: M) -> Result - where - M: Into, - { - Err(self.construct_type_error(message)) - } - - /// Constructs a `ReferenceError` with the specified message. - pub fn construct_reference_error(&mut self, message: M) -> Value - where - M: Into, - { - New::from(Call::new( - Identifier::from("ReferenceError"), - vec![Const::from(message.into() + " is not defined").into()], - )) - .run(self) - .expect_err("ReferenceError should always throw") - } - - /// Throws a `ReferenceError` with the specified message. - pub fn throw_reference_error(&mut self, message: M) -> Result - where - M: Into, - { - Err(self.construct_reference_error(message)) - } - - /// Constructs a `SyntaxError` with the specified message. - pub fn construct_syntax_error(&mut self, message: M) -> Value - where - M: Into, - { - New::from(Call::new( - Identifier::from("SyntaxError"), - vec![Const::from(message.into()).into()], - )) - .run(self) - .expect_err("SyntaxError should always throw") - } - - /// Throws a `SyntaxError` with the specified message. - pub fn throw_syntax_error(&mut self, message: M) -> Result - where - M: Into, - { - Err(self.construct_syntax_error(message)) - } -} diff --git a/boa/src/exec/field/mod.rs b/boa/src/exec/field/mod.rs index 2ce38deacc..5cc0b156f5 100644 --- a/boa/src/exec/field/mod.rs +++ b/boa/src/exec/field/mod.rs @@ -1,4 +1,4 @@ -use super::{Executable, Interpreter}; +use super::{Context, Executable}; use crate::{ syntax::ast::node::{GetConstField, GetField}, value::{Type, Value}, @@ -6,7 +6,7 @@ use crate::{ }; impl Executable for GetConstField { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { let mut obj = self.obj().run(interpreter)?; if obj.get_type() != Type::Object { obj = obj.to_object(interpreter)?; @@ -17,7 +17,7 @@ impl Executable for GetConstField { } impl Executable for GetField { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { let mut obj = self.obj().run(interpreter)?; if obj.get_type() != Type::Object { obj = obj.to_object(interpreter)?; diff --git a/boa/src/exec/identifier/mod.rs b/boa/src/exec/identifier/mod.rs index 10118f4c10..6b113acc57 100644 --- a/boa/src/exec/identifier/mod.rs +++ b/boa/src/exec/identifier/mod.rs @@ -1,8 +1,8 @@ -use super::{Executable, Interpreter}; +use super::{Context, Executable}; use crate::{syntax::ast::node::identifier::Identifier, Result, Value}; impl Executable for Identifier { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { interpreter .realm() .environment diff --git a/boa/src/exec/iteration/mod.rs b/boa/src/exec/iteration/mod.rs index 80e914e7b3..29d04b2c02 100644 --- a/boa/src/exec/iteration/mod.rs +++ b/boa/src/exec/iteration/mod.rs @@ -1,18 +1,17 @@ //! Iteration node execution. -use super::{Executable, Interpreter, InterpreterState}; +use super::{Context, Executable, InterpreterState}; use crate::{ environment::lexical_environment::new_declarative_environment, syntax::ast::node::{DoWhileLoop, ForLoop, WhileLoop}, BoaProfiler, Result, Value, }; -use std::borrow::Borrow; #[cfg(test)] mod tests; impl Executable for ForLoop { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { // Create the block environment. let _timer = BoaProfiler::global().start_event("ForLoop", "exec"); { @@ -34,17 +33,21 @@ impl Executable for ForLoop { { let result = self.body().run(interpreter)?; - match interpreter.get_current_state() { + match interpreter.executor().get_current_state() { InterpreterState::Break(_label) => { // TODO break to label. // Loops 'consume' breaks. - interpreter.set_current_state(InterpreterState::Executing); + interpreter + .executor() + .set_current_state(InterpreterState::Executing); break; } InterpreterState::Continue(_label) => { // TODO continue to label. - interpreter.set_current_state(InterpreterState::Executing); + interpreter + .executor() + .set_current_state(InterpreterState::Executing); // after breaking out of the block, continue execution of the loop } InterpreterState::Return => { @@ -68,21 +71,25 @@ impl Executable for ForLoop { } impl Executable for WhileLoop { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { let mut result = Value::undefined(); - while self.cond().run(interpreter)?.borrow().to_boolean() { + while self.cond().run(interpreter)?.to_boolean() { result = self.expr().run(interpreter)?; - match interpreter.get_current_state() { + match interpreter.executor().get_current_state() { InterpreterState::Break(_label) => { // TODO break to label. // Loops 'consume' breaks. - interpreter.set_current_state(InterpreterState::Executing); + interpreter + .executor() + .set_current_state(InterpreterState::Executing); break; } InterpreterState::Continue(_label) => { // TODO continue to label. - interpreter.set_current_state(InterpreterState::Executing); + interpreter + .executor() + .set_current_state(InterpreterState::Executing); // after breaking out of the block, continue execution of the loop } InterpreterState::Return => { @@ -98,19 +105,23 @@ impl Executable for WhileLoop { } impl Executable for DoWhileLoop { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { let mut result = self.body().run(interpreter)?; - match interpreter.get_current_state() { + match interpreter.executor().get_current_state() { InterpreterState::Break(_label) => { // TODO break to label. // Loops 'consume' breaks. - interpreter.set_current_state(InterpreterState::Executing); + interpreter + .executor() + .set_current_state(InterpreterState::Executing); return Ok(result); } InterpreterState::Continue(_label) => { // TODO continue to label; - interpreter.set_current_state(InterpreterState::Executing); + interpreter + .executor() + .set_current_state(InterpreterState::Executing); // after breaking out of the block, continue execution of the loop } InterpreterState::Return => { @@ -121,19 +132,23 @@ impl Executable for DoWhileLoop { } } - while self.cond().run(interpreter)?.borrow().to_boolean() { + while self.cond().run(interpreter)?.to_boolean() { result = self.body().run(interpreter)?; - match interpreter.get_current_state() { + match interpreter.executor().get_current_state() { InterpreterState::Break(_label) => { // TODO break to label. // Loops 'consume' breaks. - interpreter.set_current_state(InterpreterState::Executing); + interpreter + .executor() + .set_current_state(InterpreterState::Executing); break; } InterpreterState::Continue(_label) => { // TODO continue to label. - interpreter.set_current_state(InterpreterState::Executing); + interpreter + .executor() + .set_current_state(InterpreterState::Executing); // after breaking out of the block, continue execution of the loop } InterpreterState::Return => { diff --git a/boa/src/exec/mod.rs b/boa/src/exec/mod.rs index 105c1ce183..7f7b990563 100644 --- a/boa/src/exec/mod.rs +++ b/boa/src/exec/mod.rs @@ -6,7 +6,6 @@ mod break_node; mod call; mod conditional; mod declaration; -mod exception; mod field; mod identifier; mod iteration; @@ -17,33 +16,20 @@ mod return_smt; mod spread; mod statement_list; mod switch; -#[cfg(test)] -mod tests; mod throw; mod try_node; +#[cfg(test)] +mod tests; + use crate::{ - builtins, - builtins::{ - function::{Function, FunctionFlags, NativeFunction}, - object::{GcObject, Object, ObjectData, PROTOTYPE}, - Console, Symbol, - }, - class::{Class, ClassBuilder}, - property::{Property, PropertyKey}, - realm::Realm, - syntax::ast::{ - constant::Const, - node::{FormalParameter, Node, RcStatementList, StatementList}, - }, - value::{PreferredType, RcString, RcSymbol, Type, Value}, - BoaProfiler, Result, + syntax::ast::{constant::Const, node::Node}, + BoaProfiler, Context, Result, Value, }; -use std::result::Result as StdResult; pub trait Executable { - /// Runs this executable in the given executor. - fn run(&self, interpreter: &mut Interpreter) -> Result; + /// Runs this executable in the given context. + fn run(&self, interpreter: &mut Context) -> Result; } #[derive(Debug, Eq, PartialEq)] @@ -59,269 +45,19 @@ pub(crate) enum InterpreterState { pub struct Interpreter { /// the current state of the interpreter. state: InterpreterState, +} - /// realm holds both the global object and the environment - pub realm: Realm, - - /// This is for generating an unique internal `Symbol` hash. - symbol_count: u32, - - /// console object state. - console: Console, +impl Default for Interpreter { + fn default() -> Self { + Self::new() + } } impl Interpreter { /// Creates a new interpreter. - pub fn new(realm: Realm) -> Self { - let mut interpreter = Self { + pub fn new() -> Self { + Self { state: InterpreterState::Executing, - realm, - symbol_count: 0, - console: Console::default(), - }; - - // Add new builtIns to Interpreter Realm - // At a later date this can be removed from here and called explicitly, but for now we almost always want these default builtins - interpreter.create_intrinsics(); - - interpreter - } - - /// Sets up the default global objects within Global - fn create_intrinsics(&mut self) { - let _timer = BoaProfiler::global().start_event("create_intrinsics", "interpreter"); - // Create intrinsics, add global objects here - builtins::init(self); - } - - /// Retrieves the `Realm` of this executor. - #[inline] - pub(crate) fn realm(&self) -> &Realm { - &self.realm - } - - /// Retrieves the `Realm` of this executor as a mutable reference. - #[inline] - pub(crate) fn realm_mut(&mut self) -> &mut Realm { - &mut self.realm - } - - /// Retrieves the global object of the `Realm` of this executor. - #[inline] - pub fn global(&self) -> &Value { - &self.realm.global_obj - } - - /// Generates a new `Symbol` internal hash. - /// - /// This currently is an incremented value. - #[inline] - pub(crate) fn generate_hash(&mut self) -> u32 { - let hash = self.symbol_count; - self.symbol_count += 1; - hash - } - - /// Utility to create a function Value for Function Declarations, Arrow Functions or Function Expressions - pub(crate) fn create_function( - &mut self, - params: P, - body: B, - flags: FunctionFlags, - ) -> Value - where - P: Into>, - B: Into, - { - let function_prototype = self.global().get_field("Function").get_field(PROTOTYPE); - - // Every new function has a prototype property pre-made - let proto = Value::new_object(Some(self.global())); - - let params = params.into(); - let params_len = params.len(); - let func = Function::Ordinary { - flags, - body: RcStatementList::from(body.into()), - params, - environment: self.realm.environment.get_current_environment().clone(), - }; - - let new_func = Object::function(func, function_prototype); - - let val = Value::from(new_func); - - // Set constructor field to the newly created Value (function object) - proto.set_field("constructor", val.clone()); - - val.set_field(PROTOTYPE, proto); - val.set_field("length", Value::from(params_len)); - - val - } - - /// Utility to create a function Value for Function Declarations, Arrow Functions or Function Expressions - pub fn create_builtin_function( - &mut self, - name: &str, - length: usize, - body: NativeFunction, - ) -> Result { - let function_prototype = self.global().get_field("Function").get_field(PROTOTYPE); - - // Every new function has a prototype property pre-made - let proto = Value::new_object(Some(self.global())); - let mut function = Object::function( - Function::BuiltIn(body.into(), FunctionFlags::CALLABLE), - function_prototype, - ); - function.set(PROTOTYPE.into(), proto); - function.set("length".into(), length.into()); - function.set("name".into(), name.into()); - - Ok(GcObject::new(function)) - } - - pub fn register_global_function( - &mut self, - name: &str, - length: usize, - body: NativeFunction, - ) -> Result<()> { - let function = self.create_builtin_function(name, length, body)?; - self.global().set_field(name, function); - Ok(()) - } - - /// - pub(crate) fn call(&mut self, f: &Value, this: &Value, args: &[Value]) -> Result { - match *f { - Value::Object(ref object) => object.call(this, args, self), - _ => self.throw_type_error("not a function"), - } - } - - /// Converts an array object into a rust vector of values. - /// - /// This is useful for the spread operator, for any other object an `Err` is returned - pub(crate) fn extract_array_properties(&mut self, value: &Value) -> StdResult, ()> { - if let Value::Object(ref x) = value { - // Check if object is array - if let ObjectData::Array = x.borrow().data { - let length = value.get_field("length").as_number().unwrap() as i32; - let values = (0..length) - .map(|idx| value.get_field(idx.to_string())) - .collect(); - return Ok(values); - } - // Check if object is a Map - else if let ObjectData::Map(ref map) = x.borrow().data { - let values = map - .iter() - .map(|(key, value)| { - // Construct a new array containing the key-value pair - let array = Value::new_object(Some( - &self - .realm() - .environment - .get_global_object() - .expect("Could not get global object"), - )); - array.set_data(ObjectData::Array); - array.as_object_mut().expect("object").set_prototype( - self.realm() - .environment - .get_binding_value("Array") - .expect("Array was not initialized") - .get_field(PROTOTYPE), - ); - array.set_field("0", key); - array.set_field("1", value); - array.set_field("length", Value::from(2)); - array - }) - .collect(); - return Ok(values); - } - - return Err(()); - } - - Err(()) - } - - /// Converts an object to a primitive. - /// - /// More information: - /// - [ECMAScript][spec] - /// - /// [spec]: https://tc39.es/ecma262/#sec-ordinarytoprimitive - pub(crate) fn ordinary_to_primitive( - &mut self, - o: &Value, - hint: PreferredType, - ) -> Result { - // 1. Assert: Type(O) is Object. - debug_assert!(o.get_type() == Type::Object); - // 2. Assert: Type(hint) is String and its value is either "string" or "number". - debug_assert!(hint == PreferredType::String || hint == PreferredType::Number); - - // 3. If hint is "string", then - // a. Let methodNames be « "toString", "valueOf" ». - // 4. Else, - // a. Let methodNames be « "valueOf", "toString" ». - let method_names = if hint == PreferredType::String { - ["toString", "valueOf"] - } else { - ["valueOf", "toString"] - }; - - // 5. For each name in methodNames in List order, do - for name in &method_names { - // a. Let method be ? Get(O, name). - let method: Value = o.get_field(*name); - // b. If IsCallable(method) is true, then - if method.is_function() { - // i. Let result be ? Call(method, O). - let result = self.call(&method, &o, &[])?; - // ii. If Type(result) is not Object, return result. - if !result.is_object() { - return Ok(result); - } - } - } - - // 6. Throw a TypeError exception. - self.throw_type_error("cannot convert object to primitive value") - } - - /// https://tc39.es/ecma262/#sec-hasproperty - pub(crate) fn has_property(&self, obj: &Value, key: &PropertyKey) -> bool { - if let Some(obj) = obj.as_object() { - obj.has_property(key) - } else { - false - } - } - - fn set_value(&mut self, node: &Node, value: Value) -> Result { - match node { - Node::Identifier(ref name) => { - self.realm - .environment - .set_mutable_binding(name.as_ref(), value.clone(), true); - Ok(value) - } - Node::GetConstField(ref get_const_field_node) => Ok(get_const_field_node - .obj() - .run(self)? - .set_field(get_const_field_node.field(), value)), - Node::GetField(ref get_field) => { - let field = get_field.field().run(self)?; - let key = field.to_property_key(self)?; - Ok(get_field.obj().run(self)?.set_field(key, value)) - } - _ => panic!("TypeError: invalid assignment to {}", node), } } @@ -334,62 +70,10 @@ impl Interpreter { pub(crate) fn get_current_state(&self) -> &InterpreterState { &self.state } - - /// A helper function for getting a immutable reference to the `console` object. - pub(crate) fn console(&self) -> &Console { - &self.console - } - - /// A helper function for getting a mutable reference to the `console` object. - pub(crate) fn console_mut(&mut self) -> &mut Console { - &mut self.console - } - - /// Construct a new `Symbol` with an optional description. - #[inline] - pub fn construct_symbol(&mut self, description: Option) -> RcSymbol { - RcSymbol::from(Symbol::new(self.generate_hash(), description)) - } - - /// Construct an empty object. - #[inline] - pub fn construct_object(&self) -> GcObject { - let object_prototype = self.global().get_field("Object").get_field(PROTOTYPE); - GcObject::new(Object::create(object_prototype)) - } - - /// Register a global class of type `T`, where `T` implemets `Class`. - /// - /// # Example - /// ```ignore - /// #[derive(Debug, Trace, Finalize)] - /// struct MyClass; - /// - /// impl Class for MyClass { - /// // ... - /// } - /// - /// context.register_global_class::(); - /// ``` - pub fn register_global_class(&mut self) -> Result<()> - where - T: Class, - { - let mut class_builder = ClassBuilder::new::(self); - T::init(&mut class_builder)?; - - let class = class_builder.build(); - let property = Property::data_descriptor(class.into(), T::ATTRIBUTE); - self.global() - .as_object_mut() - .unwrap() - .insert_property(T::NAME, property); - Ok(()) - } } impl Executable for Node { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("Executable", "exec"); match *self { Node::Const(Const::Null) => Ok(Value::null()), diff --git a/boa/src/exec/new/mod.rs b/boa/src/exec/new/mod.rs index 476d5d576c..5266cc090a 100644 --- a/boa/src/exec/new/mod.rs +++ b/boa/src/exec/new/mod.rs @@ -1,8 +1,8 @@ -use super::{Executable, Interpreter}; +use super::{Context, Executable}; use crate::{syntax::ast::node::New, BoaProfiler, Result, Value}; impl Executable for New { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("New", "exec"); let func_object = self.expr().run(interpreter)?; diff --git a/boa/src/exec/object/mod.rs b/boa/src/exec/object/mod.rs index 26fa6ba0b8..6485f64695 100644 --- a/boa/src/exec/object/mod.rs +++ b/boa/src/exec/object/mod.rs @@ -1,16 +1,14 @@ //! Object execution. -use super::{Executable, Interpreter}; +use super::{Context, Executable}; use crate::{ syntax::ast::node::MethodDefinitionKind, syntax::ast::node::{Object, PropertyDefinition}, Result, Value, }; -use std::borrow::Borrow; - impl Executable for Object { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { let global_val = &interpreter .realm() .environment @@ -22,11 +20,11 @@ impl Executable for Object { for property in self.properties().iter() { match property { PropertyDefinition::Property(key, value) => { - obj.borrow().set_field(key.clone(), value.run(interpreter)?); + obj.set_field(key.clone(), value.run(interpreter)?); } PropertyDefinition::MethodDefinition(kind, name, func) => { if let MethodDefinitionKind::Ordinary = kind { - obj.borrow().set_field(name.clone(), func.run(interpreter)?); + obj.set_field(name.clone(), func.run(interpreter)?); } else { // TODO: Implement other types of MethodDefinitionKinds. unimplemented!("other types of property method definitions."); diff --git a/boa/src/exec/operator/mod.rs b/boa/src/exec/operator/mod.rs index c96a7a7cde..b3b1d8f296 100644 --- a/boa/src/exec/operator/mod.rs +++ b/boa/src/exec/operator/mod.rs @@ -2,7 +2,7 @@ #[cfg(test)] mod tests; -use super::{Executable, Interpreter}; +use super::{Context, Executable}; use crate::{ environment::lexical_environment::VariableScope, syntax::ast::{ @@ -13,7 +13,7 @@ use crate::{ }; impl Executable for Assign { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("Assign", "exec"); let val = self.rhs().run(interpreter)?; match self.lhs() { @@ -49,7 +49,7 @@ impl Executable for Assign { } impl Executable for BinOp { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { match self.op() { op::BinOp::Num(op) => { let x = self.lhs().run(interpreter)?; @@ -133,7 +133,7 @@ impl Executable for BinOp { .ok_or_else(|| interpreter.construct_reference_error(name.as_ref()))?; let v_b = self.rhs().run(interpreter)?; let value = Self::run_assign(op, v_a, v_b, interpreter)?; - interpreter.realm.environment.set_mutable_binding( + interpreter.realm_mut().environment.set_mutable_binding( name.as_ref(), value.clone(), true, @@ -160,12 +160,7 @@ impl Executable for BinOp { impl BinOp { /// Runs the assignment operators. - fn run_assign( - op: AssignOp, - x: Value, - y: Value, - interpreter: &mut Interpreter, - ) -> Result { + fn run_assign(op: AssignOp, x: Value, y: Value, interpreter: &mut Context) -> Result { match op { AssignOp::Add => x.add(&y, interpreter), AssignOp::Sub => x.sub(&y, interpreter), @@ -183,7 +178,7 @@ impl BinOp { } impl Executable for UnaryOp { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { let x = self.target().run(interpreter)?; Ok(match self.op() { diff --git a/boa/src/exec/return_smt/mod.rs b/boa/src/exec/return_smt/mod.rs index bd5e912f11..112c0ec6f7 100644 --- a/boa/src/exec/return_smt/mod.rs +++ b/boa/src/exec/return_smt/mod.rs @@ -1,14 +1,16 @@ -use super::{Executable, Interpreter, InterpreterState}; +use super::{Context, Executable, InterpreterState}; use crate::{syntax::ast::node::Return, Result, Value}; impl Executable for Return { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { let result = match self.expr() { Some(ref v) => v.run(interpreter), None => Ok(Value::undefined()), }; // Set flag for return - interpreter.set_current_state(InterpreterState::Return); + interpreter + .executor() + .set_current_state(InterpreterState::Return); result } } diff --git a/boa/src/exec/spread/mod.rs b/boa/src/exec/spread/mod.rs index 1c3d90e042..d5fa2805b7 100644 --- a/boa/src/exec/spread/mod.rs +++ b/boa/src/exec/spread/mod.rs @@ -1,8 +1,8 @@ -use super::{Executable, Interpreter}; +use super::{Context, Executable}; use crate::{syntax::ast::node::Spread, Result, Value}; impl Executable for Spread { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { // TODO: for now we can do nothing but return the value as-is self.val().run(interpreter) } diff --git a/boa/src/exec/statement_list.rs b/boa/src/exec/statement_list.rs index 50229fb4fc..f4aedb53e0 100644 --- a/boa/src/exec/statement_list.rs +++ b/boa/src/exec/statement_list.rs @@ -1,19 +1,21 @@ //! Statement list execution. -use super::{Executable, Interpreter, InterpreterState}; +use super::{Context, Executable, InterpreterState}; use crate::{syntax::ast::node::StatementList, BoaProfiler, Result, Value}; impl Executable for StatementList { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("StatementList", "exec"); // https://tc39.es/ecma262/#sec-block-runtime-semantics-evaluation // The return value is uninitialized, which means it defaults to Value::Undefined let mut obj = Value::default(); - interpreter.set_current_state(InterpreterState::Executing); + interpreter + .executor() + .set_current_state(InterpreterState::Executing); for (i, item) in self.statements().iter().enumerate() { let val = item.run(interpreter)?; - match interpreter.get_current_state() { + match interpreter.executor().get_current_state() { InterpreterState::Return => { // Early return. obj = val; diff --git a/boa/src/exec/switch/mod.rs b/boa/src/exec/switch/mod.rs index a145f2e7bd..316e2bc720 100644 --- a/boa/src/exec/switch/mod.rs +++ b/boa/src/exec/switch/mod.rs @@ -1,15 +1,17 @@ -use super::{Executable, Interpreter, InterpreterState}; +use super::{Context, Executable, InterpreterState}; use crate::{syntax::ast::node::Switch, Result, Value}; #[cfg(test)] mod tests; impl Executable for Switch { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { let val = self.val().run(interpreter)?; let mut result = Value::null(); let mut matched = false; - interpreter.set_current_state(InterpreterState::Executing); + interpreter + .executor() + .set_current_state(InterpreterState::Executing); // If a case block does not end with a break statement then subsequent cases will be run without // checking their conditions until a break is encountered. @@ -21,7 +23,7 @@ impl Executable for Switch { if fall_through || val.strict_equals(&cond.run(interpreter)?) { matched = true; let result = block.run(interpreter)?; - match interpreter.get_current_state() { + match interpreter.executor().get_current_state() { InterpreterState::Return => { // Early return. return Ok(result); @@ -29,7 +31,9 @@ impl Executable for Switch { InterpreterState::Break(_label) => { // TODO, break to a label. // Break statement encountered so therefore end switch statement. - interpreter.set_current_state(InterpreterState::Executing); + interpreter + .executor() + .set_current_state(InterpreterState::Executing); break; } InterpreterState::Continue(_label) => { @@ -46,10 +50,12 @@ impl Executable for Switch { if !matched { if let Some(default) = self.default() { - interpreter.set_current_state(InterpreterState::Executing); + interpreter + .executor() + .set_current_state(InterpreterState::Executing); for (i, item) in default.iter().enumerate() { let val = item.run(interpreter)?; - match interpreter.get_current_state() { + match interpreter.executor().get_current_state() { InterpreterState::Return => { // Early return. result = val; diff --git a/boa/src/exec/tests.rs b/boa/src/exec/tests.rs index 8c755a9881..74c9dd0954 100644 --- a/boa/src/exec/tests.rs +++ b/boa/src/exec/tests.rs @@ -1,4 +1,4 @@ -use crate::{builtins::Number, exec, exec::Interpreter, forward, forward_val, realm::Realm, Value}; +use crate::{builtins::Number, exec, forward, forward_val, Context, Value}; #[test] fn function_declaration_returns_undefined() { @@ -109,8 +109,7 @@ fn object_field_set() { #[test] fn spread_with_arguments() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let scenario = r#" const a = [1, "test", 3, 4]; @@ -136,8 +135,7 @@ fn spread_with_arguments() { #[test] fn array_rest_with_arguments() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let scenario = r#" var b = [4, 5, 6] @@ -715,8 +713,7 @@ mod in_operator { #[test] fn should_type_error_when_rhs_not_object() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let scenario = r#" var x = false; @@ -733,8 +730,7 @@ mod in_operator { #[test] fn should_set_this_value() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let scenario = r#" function Foo() { @@ -752,8 +748,7 @@ mod in_operator { #[test] fn new_instance_should_point_to_prototype() { // A new instance should point to a prototype object created with the constructor function - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let scenario = r#" function Foo() {} @@ -880,8 +875,7 @@ fn function_decl_hoisting() { #[test] fn to_bigint() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert!(Value::null().to_bigint(&mut engine).is_err()); assert!(Value::undefined().to_bigint(&mut engine).is_err()); @@ -892,8 +886,7 @@ fn to_bigint() { #[test] fn to_index() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(Value::undefined().to_index(&mut engine).unwrap(), 0); assert!(Value::integer(-1).to_index(&mut engine).is_err()); @@ -901,8 +894,7 @@ fn to_index() { #[test] fn to_integer() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert!(Number::equal( Value::number(f64::NAN).to_integer(&mut engine).unwrap(), @@ -939,8 +931,7 @@ fn to_integer() { #[test] fn to_length() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(Value::number(f64::NAN).to_length(&mut engine).unwrap(), 0); assert_eq!( @@ -971,8 +962,7 @@ fn to_length() { #[test] fn to_int32() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); macro_rules! check_to_int32 { ($from:expr => $to:expr) => { @@ -1085,8 +1075,7 @@ fn to_int32() { #[test] fn to_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(Value::null().to_string(&mut engine).unwrap(), "null"); assert_eq!( @@ -1103,8 +1092,7 @@ fn to_string() { #[test] fn calling_function_with_unspecified_arguments() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let scenario = r#" function test(a, b) { return b; @@ -1118,8 +1106,7 @@ fn calling_function_with_unspecified_arguments() { #[test] fn to_object() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert!(Value::undefined() .to_object(&mut engine) @@ -1133,8 +1120,7 @@ fn to_object() { #[test] fn check_this_binding_in_object_literal() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" var foo = { a: 3, @@ -1149,8 +1135,7 @@ fn check_this_binding_in_object_literal() { #[test] fn array_creation_benchmark() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" (function(){ let testArr = []; @@ -1167,8 +1152,7 @@ fn array_creation_benchmark() { #[test] fn array_pop_benchmark() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" (function(){ let testArray = [83, 93, 27, 29, 2828, 234, 23, 56, 32, 56, 67, 77, 32, @@ -1201,8 +1185,7 @@ fn array_pop_benchmark() { #[test] fn number_object_access_benchmark() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" new Number( new Number( @@ -1218,8 +1201,7 @@ fn number_object_access_benchmark() { #[test] fn not_a_function() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let init = r#" let a = {}; let b = true; @@ -1283,8 +1265,7 @@ fn comma_operator() { fn assignment_to_non_assignable() { // Relates to the behaviour described at // https://tc39.es/ecma262/#sec-assignment-operators-static-semantics-early-errors - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); // Tests all assignment operators as per [spec] and [mdn] // @@ -1306,8 +1287,7 @@ fn assignment_to_non_assignable() { fn multicharacter_assignment_to_non_assignable() { // Relates to the behaviour described at // https://tc39.es/ecma262/#sec-assignment-operators-static-semantics-early-errors - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let test_cases = ["3 **= 5", "3 <<= 5", "3 >>= 5"]; @@ -1322,8 +1302,7 @@ fn multicharacter_assignment_to_non_assignable() { #[test] #[ignore] fn multicharacter_bitwise_assignment_to_non_assignable() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); // Disabled - awaiting implementation. let test_cases = ["3 >>>= 5", "3 &&= 5", "3 ||= 5", "3 ??= 5"]; @@ -1338,8 +1317,7 @@ fn multicharacter_bitwise_assignment_to_non_assignable() { #[test] fn assign_to_array_decl() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert!(forward(&mut engine, "[1] = [2]").starts_with("Uncaught \"SyntaxError\": ")); assert!(forward(&mut engine, "[3, 5] = [7, 8]").starts_with("Uncaught \"SyntaxError\": ")); @@ -1349,8 +1327,7 @@ fn assign_to_array_decl() { #[test] fn assign_to_object_decl() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); const ERR_MSG: &str = "Uncaught \"SyntaxError\": \"expected token \';\', got \':\' in expression statement at line 1, col 3\""; diff --git a/boa/src/exec/throw/mod.rs b/boa/src/exec/throw/mod.rs index 49761f95cb..cd277ee7d1 100644 --- a/boa/src/exec/throw/mod.rs +++ b/boa/src/exec/throw/mod.rs @@ -1,9 +1,9 @@ -use super::{Executable, Interpreter}; +use super::{Context, Executable}; use crate::{syntax::ast::node::Throw, Result, Value}; impl Executable for Throw { #[inline] - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { Err(self.expr().run(interpreter)?) } } diff --git a/boa/src/exec/try_node/mod.rs b/boa/src/exec/try_node/mod.rs index 4981efcc8b..cd3d0cc4ef 100644 --- a/boa/src/exec/try_node/mod.rs +++ b/boa/src/exec/try_node/mod.rs @@ -1,6 +1,6 @@ //! Try..catch node execution. -use super::{Executable, Interpreter}; +use super::{Context, Executable}; use crate::{ environment::lexical_environment::{new_declarative_environment, VariableScope}, syntax::ast::node::Try, @@ -11,7 +11,7 @@ use crate::{ mod tests; impl Executable for Try { - fn run(&self, interpreter: &mut Interpreter) -> Result { + fn run(&self, interpreter: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("Try", "exec"); let res = self.block().run(interpreter).map_or_else( |err| { diff --git a/boa/src/lib.rs b/boa/src/lib.rs index 4ef322fa9b..f0d2a9b45c 100644 --- a/boa/src/lib.rs +++ b/boa/src/lib.rs @@ -44,21 +44,21 @@ pub mod realm; pub mod syntax; pub mod value; -use crate::syntax::ast::node::StatementList; -pub use crate::{ - exec::{Executable, Interpreter}, - profiler::BoaProfiler, - realm::Realm, - syntax::{ - lexer::Lexer, - parser::{ParseError, Parser}, - }, - value::Value, -}; +mod context; + use std::result::Result as StdResult; +pub(crate) use crate::{exec::Executable, profiler::BoaProfiler}; pub use gc::{custom_trace, unsafe_empty_trace, Finalize, Trace}; +// Export things to root level +pub use crate::{context::Context, value::Value}; + +use crate::syntax::{ + ast::node::StatementList, + parser::{ParseError, Parser}, +}; + /// The result of a Javascript expression is represented like this so it can succeed (`Ok`) or fail (`Err`) #[must_use] pub type Result = StdResult; @@ -72,9 +72,10 @@ pub fn parse(src: &str) -> StdResult { Parser::new(src.as_bytes()).parse_all() } -/// Execute the code using an existing Interpreter -/// The str is consumed and the state of the Interpreter is changed -pub fn forward(engine: &mut Interpreter, src: &str) -> String { +/// Execute the code using an existing Context +/// The str is consumed and the state of the Context is changed +#[cfg(test)] +pub(crate) fn forward(engine: &mut Context, src: &str) -> String { // Setup executor let expr = match parse(src) { Ok(res) => res, @@ -94,12 +95,13 @@ pub fn forward(engine: &mut Interpreter, src: &str) -> String { ) } -/// Execute the code using an existing Interpreter. -/// The str is consumed and the state of the Interpreter is changed +/// Execute the code using an existing Context. +/// The str is consumed and the state of the Context is changed /// Similar to `forward`, except the current value is returned instad of the string /// If the interpreter fails parsing an error value is returned instead (error object) #[allow(clippy::unit_arg, clippy::drop_copy)] -pub fn forward_val(engine: &mut Interpreter, src: &str) -> Result { +#[cfg(test)] +pub(crate) fn forward_val(engine: &mut Context, src: &str) -> Result { let main_timer = BoaProfiler::global().start_event("Main", "Main"); // Setup executor let result = parse(src) @@ -117,10 +119,11 @@ pub fn forward_val(engine: &mut Interpreter, src: &str) -> Result { result } -/// Create a clean Interpreter and execute the code -pub fn exec(src: &str) -> String { - // Create new Realm - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); - forward(&mut engine, src) +/// Create a clean Context and execute the code +#[cfg(test)] +pub(crate) fn exec(src: &str) -> String { + match Context::new().eval(src) { + Ok(value) => value.display().to_string(), + Err(error) => error.display().to_string(), + } } diff --git a/boa/src/syntax/mod.rs b/boa/src/syntax/mod.rs index 6605bf23af..802f7a1d19 100644 --- a/boa/src/syntax/mod.rs +++ b/boa/src/syntax/mod.rs @@ -3,3 +3,6 @@ pub mod ast; pub mod lexer; pub mod parser; + +pub use lexer::Lexer; +pub use parser::Parser; diff --git a/boa/src/value/equality.rs b/boa/src/value/equality.rs index 93ffc3bd7b..7cb09bf5e7 100644 --- a/boa/src/value/equality.rs +++ b/boa/src/value/equality.rs @@ -1,5 +1,5 @@ use super::*; -use crate::{builtins::Number, Interpreter}; +use crate::{builtins::Number, Context}; impl Value { /// Strict equality comparison. @@ -37,7 +37,7 @@ impl Value { /// This method is executed when doing abstract equality comparisons with the `==` operator. /// For more information, check #[allow(clippy::float_cmp)] - pub fn equals(&self, other: &Self, interpreter: &mut Interpreter) -> Result { + pub fn equals(&self, other: &Self, interpreter: &mut Context) -> Result { // 1. If Type(x) is the same as Type(y), then // a. Return the result of performing Strict Equality Comparison x === y. if self.get_type() == other.get_type() { diff --git a/boa/src/value/mod.rs b/boa/src/value/mod.rs index 3f451c6b2f..ec1688cc08 100644 --- a/boa/src/value/mod.rs +++ b/boa/src/value/mod.rs @@ -5,7 +5,6 @@ #[cfg(test)] mod tests; -use crate::exec::Interpreter; use crate::{ builtins::{ number::{f64_to_int32, f64_to_uint32}, @@ -13,8 +12,8 @@ use crate::{ BigInt, Number, }, property::{Attribute, Property, PropertyKey}, + BoaProfiler, Context, Result, }; -use crate::{BoaProfiler, Result}; use gc::{Finalize, GcCellRef, GcCellRefMut, Trace}; use serde_json::{map::Map, Number as JSONNumber, Value as JSONValue}; use std::{ @@ -174,7 +173,7 @@ impl Value { } /// Convert from a JSON value to a JS value - pub fn from_json(json: JSONValue, interpreter: &mut Interpreter) -> Self { + pub fn from_json(json: JSONValue, interpreter: &mut Context) -> Self { match json { JSONValue::Number(v) => { if let Some(Ok(integer_32)) = v.as_i64().map(i32::try_from) { @@ -187,8 +186,7 @@ impl Value { JSONValue::Bool(v) => Self::boolean(v), JSONValue::Array(vs) => { let global_array_prototype = interpreter - .realm - .global_obj + .global_object() .get_field("Array") .get_field(PROTOTYPE); let new_obj = @@ -210,7 +208,7 @@ impl Value { new_obj } JSONValue::Object(obj) => { - let new_obj = Value::new_object(Some(interpreter.global())); + let new_obj = Value::new_object(Some(interpreter.global_object())); for (key, json) in obj.into_iter() { let value = Self::from_json(json, interpreter); new_obj.set_property( @@ -228,7 +226,7 @@ impl Value { } /// Converts the `Value` to `JSON`. - pub fn to_json(&self, interpreter: &mut Interpreter) -> Result { + pub fn to_json(&self, interpreter: &mut Context) -> Result { let to_json = self.get_field("toJSON"); if to_json.is_function() { let json_value = interpreter.call(&to_json, self, &[])?; @@ -582,11 +580,7 @@ impl Value { /// The abstract operation ToPrimitive takes an input argument and an optional argument PreferredType. /// /// - pub fn to_primitive( - &self, - ctx: &mut Interpreter, - preferred_type: PreferredType, - ) -> Result { + pub fn to_primitive(&self, ctx: &mut Context, preferred_type: PreferredType) -> Result { // 1. Assert: input is an ECMAScript language value. (always a value not need to check) // 2. If Type(input) is Object, then if let Value::Object(_) = self { @@ -610,7 +604,7 @@ impl Value { /// Converts the value to a `BigInt`. /// /// This function is equivelent to `BigInt(value)` in JavaScript. - pub fn to_bigint(&self, ctx: &mut Interpreter) -> Result { + pub fn to_bigint(&self, ctx: &mut Context) -> Result { match self { Value::Null => Err(ctx.construct_type_error("cannot convert null to a BigInt")), Value::Undefined => { @@ -657,7 +651,7 @@ impl Value { /// Converts the value to a string. /// /// This function is equivalent to `String(value)` in JavaScript. - pub fn to_string(&self, ctx: &mut Interpreter) -> Result { + pub fn to_string(&self, ctx: &mut Context) -> Result { match self { Value::Null => Ok("null".into()), Value::Undefined => Ok("undefined".into()), @@ -679,14 +673,14 @@ impl Value { /// This function is equivalent to `Object(value)` in JavaScript /// /// See: - pub fn to_object(&self, ctx: &mut Interpreter) -> Result { + pub fn to_object(&self, ctx: &mut Context) -> Result { match self { Value::Undefined | Value::Null => { ctx.throw_type_error("cannot convert 'null' or 'undefined' to object") } Value::Boolean(boolean) => { let proto = ctx - .realm + .realm() .environment .get_binding_value("Boolean") .expect("Boolean was not initialized") @@ -699,7 +693,7 @@ impl Value { } Value::Integer(integer) => { let proto = ctx - .realm + .realm() .environment .get_binding_value("Number") .expect("Number was not initialized") @@ -711,7 +705,7 @@ impl Value { } Value::Rational(rational) => { let proto = ctx - .realm + .realm() .environment .get_binding_value("Number") .expect("Number was not initialized") @@ -724,7 +718,7 @@ impl Value { } Value::String(ref string) => { let proto = ctx - .realm + .realm() .environment .get_binding_value("String") .expect("String was not initialized") @@ -737,7 +731,7 @@ impl Value { } Value::Symbol(ref symbol) => { let proto = ctx - .realm + .realm() .environment .get_binding_value("Symbol") .expect("Symbol was not initialized") @@ -750,7 +744,7 @@ impl Value { } Value::BigInt(ref bigint) => { let proto = ctx - .realm + .realm() .environment .get_binding_value("BigInt") .expect("BigInt was not initialized") @@ -766,7 +760,7 @@ impl Value { /// Converts the value to a `PropertyKey`, that can be used as a key for properties. /// /// See - pub fn to_property_key(&self, ctx: &mut Interpreter) -> Result { + pub fn to_property_key(&self, ctx: &mut Context) -> Result { Ok(match self { // Fast path: Value::String(string) => string.clone().into(), @@ -783,7 +777,7 @@ impl Value { /// It returns value converted to a numeric value of type `Number` or `BigInt`. /// /// See: - pub fn to_numeric(&self, ctx: &mut Interpreter) -> Result { + pub fn to_numeric(&self, ctx: &mut Context) -> Result { let primitive = self.to_primitive(ctx, PreferredType::Number)?; if let Some(bigint) = primitive.as_bigint() { return Ok(bigint.clone().into()); @@ -796,7 +790,7 @@ impl Value { /// This function is equivalent to `value | 0` in JavaScript /// /// See: - pub fn to_u32(&self, ctx: &mut Interpreter) -> Result { + pub fn to_u32(&self, ctx: &mut Context) -> Result { // This is the fast path, if the value is Integer we can just return it. if let Value::Integer(number) = *self { return Ok(number as u32); @@ -809,7 +803,7 @@ impl Value { /// Converts a value to an integral 32 bit signed integer. /// /// See: - pub fn to_i32(&self, ctx: &mut Interpreter) -> Result { + pub fn to_i32(&self, ctx: &mut Context) -> Result { // This is the fast path, if the value is Integer we can just return it. if let Value::Integer(number) = *self { return Ok(number); @@ -822,7 +816,7 @@ impl Value { /// Converts a value to a non-negative integer if it is a valid integer index value. /// /// See: - pub fn to_index(&self, ctx: &mut Interpreter) -> Result { + pub fn to_index(&self, ctx: &mut Context) -> Result { if self.is_undefined() { return Ok(0); } @@ -843,7 +837,7 @@ impl Value { /// Converts argument to an integer suitable for use as the length of an array-like object. /// /// See: - pub fn to_length(&self, ctx: &mut Interpreter) -> Result { + pub fn to_length(&self, ctx: &mut Context) -> Result { // 1. Let len be ? ToInteger(argument). let len = self.to_integer(ctx)?; @@ -859,7 +853,7 @@ impl Value { /// Converts a value to an integral Number value. /// /// See: - pub fn to_integer(&self, ctx: &mut Interpreter) -> Result { + pub fn to_integer(&self, ctx: &mut Context) -> Result { // 1. Let number be ? ToNumber(argument). let number = self.to_number(ctx)?; @@ -883,7 +877,7 @@ impl Value { /// This function is equivalent to the unary `+` operator (`+value`) in JavaScript /// /// See: https://tc39.es/ecma262/#sec-tonumber - pub fn to_number(&self, ctx: &mut Interpreter) -> Result { + pub fn to_number(&self, ctx: &mut Context) -> Result { match *self { Value::Null => Ok(0.0), Value::Undefined => Ok(f64::NAN), @@ -911,7 +905,7 @@ impl Value { /// This function is equivalent to `Number(value)` in JavaScript /// /// See: - pub fn to_numeric_number(&self, ctx: &mut Interpreter) -> Result { + pub fn to_numeric_number(&self, ctx: &mut Context) -> Result { let primitive = self.to_primitive(ctx, PreferredType::Number)?; if let Some(ref bigint) = primitive.as_bigint() { return Ok(bigint.to_f64()); @@ -931,7 +925,7 @@ impl Value { /// [table]: https://tc39.es/ecma262/#table-14 /// [spec]: https://tc39.es/ecma262/#sec-requireobjectcoercible #[inline] - pub fn require_object_coercible<'a>(&'a self, ctx: &mut Interpreter) -> Result<&'a Value> { + pub fn require_object_coercible<'a>(&'a self, ctx: &mut Context) -> Result<&'a Value> { if self.is_null_or_undefined() { Err(ctx.construct_type_error("cannot convert null or undefined to Object")) } else { diff --git a/boa/src/value/operations.rs b/boa/src/value/operations.rs index 59942f1b5f..143fabf7a4 100644 --- a/boa/src/value/operations.rs +++ b/boa/src/value/operations.rs @@ -3,7 +3,7 @@ use crate::builtins::number::{f64_to_int32, f64_to_uint32, Number}; impl Value { #[inline] - pub fn add(&self, other: &Self, ctx: &mut Interpreter) -> Result { + pub fn add(&self, other: &Self, ctx: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::rational(f64::from(*x) + f64::from(*y)), @@ -40,7 +40,7 @@ impl Value { } #[inline] - pub fn sub(&self, other: &Self, ctx: &mut Interpreter) -> Result { + pub fn sub(&self, other: &Self, ctx: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::rational(f64::from(*x) - f64::from(*y)), @@ -68,7 +68,7 @@ impl Value { } #[inline] - pub fn mul(&self, other: &Self, ctx: &mut Interpreter) -> Result { + pub fn mul(&self, other: &Self, ctx: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::rational(f64::from(*x) * f64::from(*y)), @@ -96,7 +96,7 @@ impl Value { } #[inline] - pub fn div(&self, other: &Self, ctx: &mut Interpreter) -> Result { + pub fn div(&self, other: &Self, ctx: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::rational(f64::from(*x) / f64::from(*y)), @@ -124,7 +124,7 @@ impl Value { } #[inline] - pub fn rem(&self, other: &Self, ctx: &mut Interpreter) -> Result { + pub fn rem(&self, other: &Self, ctx: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::integer(x % *y), @@ -152,7 +152,7 @@ impl Value { } #[inline] - pub fn pow(&self, other: &Self, ctx: &mut Interpreter) -> Result { + pub fn pow(&self, other: &Self, ctx: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::rational(f64::from(*x).powi(*y)), @@ -178,7 +178,7 @@ impl Value { } #[inline] - pub fn bitand(&self, other: &Self, ctx: &mut Interpreter) -> Result { + pub fn bitand(&self, other: &Self, ctx: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::integer(x & y), @@ -210,7 +210,7 @@ impl Value { } #[inline] - pub fn bitor(&self, other: &Self, ctx: &mut Interpreter) -> Result { + pub fn bitor(&self, other: &Self, ctx: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::integer(x | y), @@ -242,7 +242,7 @@ impl Value { } #[inline] - pub fn bitxor(&self, other: &Self, ctx: &mut Interpreter) -> Result { + pub fn bitxor(&self, other: &Self, ctx: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::integer(x ^ y), @@ -274,7 +274,7 @@ impl Value { } #[inline] - pub fn shl(&self, other: &Self, ctx: &mut Interpreter) -> Result { + pub fn shl(&self, other: &Self, ctx: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::integer(x.wrapping_shl(*y as u32)), @@ -310,7 +310,7 @@ impl Value { } #[inline] - pub fn shr(&self, other: &Self, ctx: &mut Interpreter) -> Result { + pub fn shr(&self, other: &Self, ctx: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::integer(x.wrapping_shr(*y as u32)), @@ -346,7 +346,7 @@ impl Value { } #[inline] - pub fn ushr(&self, other: &Self, ctx: &mut Interpreter) -> Result { + pub fn ushr(&self, other: &Self, ctx: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => { @@ -381,7 +381,7 @@ impl Value { } #[inline] - pub fn neg(&self, interpreter: &mut Interpreter) -> Result { + pub fn neg(&self, interpreter: &mut Context) -> Result { Ok(match *self { Self::Symbol(_) | Self::Undefined => Self::rational(NAN), Self::Object(_) => Self::rational(match self.to_numeric_number(interpreter) { @@ -401,7 +401,7 @@ impl Value { } #[inline] - pub fn not(&self, _: &mut Interpreter) -> Result { + pub fn not(&self, _: &mut Context) -> Result { Ok(!self.to_boolean()) } @@ -426,7 +426,7 @@ impl Value { &self, other: &Self, left_first: bool, - ctx: &mut Interpreter, + ctx: &mut Context, ) -> Result { Ok(match (self, other) { // Fast path (for some common operations): @@ -525,7 +525,7 @@ impl Value { /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Less_than /// [spec]: https://tc39.es/ecma262/#sec-relational-operators-runtime-semantics-evaluation #[inline] - pub fn lt(&self, other: &Self, ctx: &mut Interpreter) -> Result { + pub fn lt(&self, other: &Self, ctx: &mut Context) -> Result { match self.abstract_relation(other, true, ctx)? { AbstractRelation::True => Ok(true), AbstractRelation::False | AbstractRelation::Undefined => Ok(false), @@ -542,7 +542,7 @@ impl Value { /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Less_than_or_equal /// [spec]: https://tc39.es/ecma262/#sec-relational-operators-runtime-semantics-evaluation #[inline] - pub fn le(&self, other: &Self, ctx: &mut Interpreter) -> Result { + pub fn le(&self, other: &Self, ctx: &mut Context) -> Result { match other.abstract_relation(self, false, ctx)? { AbstractRelation::False => Ok(true), AbstractRelation::True | AbstractRelation::Undefined => Ok(false), @@ -559,7 +559,7 @@ impl Value { /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Greater_than /// [spec]: https://tc39.es/ecma262/#sec-relational-operators-runtime-semantics-evaluation #[inline] - pub fn gt(&self, other: &Self, ctx: &mut Interpreter) -> Result { + pub fn gt(&self, other: &Self, ctx: &mut Context) -> Result { match other.abstract_relation(self, false, ctx)? { AbstractRelation::True => Ok(true), AbstractRelation::False | AbstractRelation::Undefined => Ok(false), @@ -576,7 +576,7 @@ impl Value { /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Greater_than_or_equal /// [spec]: https://tc39.es/ecma262/#sec-relational-operators-runtime-semantics-evaluation #[inline] - pub fn ge(&self, other: &Self, ctx: &mut Interpreter) -> Result { + pub fn ge(&self, other: &Self, ctx: &mut Context) -> Result { match self.abstract_relation(other, true, ctx)? { AbstractRelation::False => Ok(true), AbstractRelation::True | AbstractRelation::Undefined => Ok(false), diff --git a/boa/src/value/tests.rs b/boa/src/value/tests.rs index c797c46585..ce667c1ee1 100644 --- a/boa/src/value/tests.rs +++ b/boa/src/value/tests.rs @@ -1,5 +1,5 @@ use super::*; -use crate::{forward, forward_val, Interpreter, Realm}; +use crate::{forward, forward_val, Context}; use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; @@ -54,8 +54,7 @@ fn number_is_true() { // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness #[test] fn abstract_equality_comparison() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!(forward(&mut engine, "undefined == undefined"), "true"); assert_eq!(forward(&mut engine, "null == null"), "true"); @@ -159,8 +158,7 @@ fn hash_object() { #[test] fn get_types() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); assert_eq!( forward_val(&mut engine, "undefined").unwrap().get_type(), @@ -250,8 +248,7 @@ fn to_string() { #[test] fn add_number_and_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let value = forward_val(&mut engine, "1 + 2").unwrap(); let value = value.to_i32(&mut engine).unwrap(); @@ -260,8 +257,7 @@ fn add_number_and_number() { #[test] fn add_number_and_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let value = forward_val(&mut engine, "1 + \" + 2 = 3\"").unwrap(); let value = value.to_string(&mut engine).unwrap(); @@ -270,8 +266,7 @@ fn add_number_and_string() { #[test] fn add_string_and_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let value = forward_val(&mut engine, "\"Hello\" + \", world\"").unwrap(); let value = value.to_string(&mut engine).unwrap(); @@ -280,8 +275,7 @@ fn add_string_and_string() { #[test] fn add_number_object_and_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let value = forward_val(&mut engine, "new Number(10) + 6").unwrap(); let value = value.to_i32(&mut engine).unwrap(); @@ -290,8 +284,7 @@ fn add_number_object_and_number() { #[test] fn add_number_object_and_string_object() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let value = forward_val(&mut engine, "new Number(10) + new String(\"0\")").unwrap(); let value = value.to_string(&mut engine).unwrap(); @@ -300,8 +293,7 @@ fn add_number_object_and_string_object() { #[test] fn sub_number_and_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let value = forward_val(&mut engine, "1 - 999").unwrap(); let value = value.to_i32(&mut engine).unwrap(); @@ -310,8 +302,7 @@ fn sub_number_and_number() { #[test] fn sub_number_object_and_number_object() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let value = forward_val(&mut engine, "new Number(1) - new Number(999)").unwrap(); let value = value.to_i32(&mut engine).unwrap(); @@ -320,8 +311,7 @@ fn sub_number_object_and_number_object() { #[test] fn sub_string_and_number_object() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let value = forward_val(&mut engine, "'Hello' - new Number(999)").unwrap(); let value = value.to_number(&mut engine).unwrap(); @@ -330,8 +320,7 @@ fn sub_string_and_number_object() { #[test] fn bitand_integer_and_integer() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let value = forward_val(&mut engine, "0xFFFF & 0xFF").unwrap(); let value = value.to_i32(&mut engine).unwrap(); @@ -340,8 +329,7 @@ fn bitand_integer_and_integer() { #[test] fn bitand_integer_and_rational() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let value = forward_val(&mut engine, "0xFFFF & 255.5").unwrap(); let value = value.to_i32(&mut engine).unwrap(); @@ -350,8 +338,7 @@ fn bitand_integer_and_rational() { #[test] fn bitand_rational_and_rational() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let value = forward_val(&mut engine, "255.772 & 255.5").unwrap(); let value = value.to_i32(&mut engine).unwrap(); @@ -361,8 +348,7 @@ fn bitand_rational_and_rational() { #[test] #[allow(clippy::float_cmp)] fn pow_number_and_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let value = forward_val(&mut engine, "3 ** 3").unwrap(); let value = value.to_number(&mut engine).unwrap(); @@ -371,8 +357,7 @@ fn pow_number_and_number() { #[test] fn pow_number_and_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let value = forward_val(&mut engine, "3 ** 'Hello'").unwrap(); let value = value.to_number(&mut engine).unwrap(); @@ -381,8 +366,7 @@ fn pow_number_and_string() { #[test] fn assign_pow_number_and_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let value = forward_val( &mut engine, @@ -406,8 +390,7 @@ fn display_string() { #[test] fn display_array_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let value = forward_val(&mut engine, "[\"Hello\"]").unwrap(); assert_eq!(value.display().to_string(), "[ \"Hello\" ]"); @@ -415,8 +398,7 @@ fn display_array_string() { #[test] fn display_boolean_object() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let d_obj = r#" let bool = new Boolean(0); bool @@ -427,8 +409,7 @@ fn display_boolean_object() { #[test] fn display_number_object() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let d_obj = r#" let num = new Number(3.14); num @@ -439,8 +420,7 @@ fn display_number_object() { #[test] fn display_negative_zero_object() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let d_obj = r#" let num = new Number(-0); num @@ -451,8 +431,7 @@ fn display_negative_zero_object() { #[test] fn debug_object() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let value = forward_val(&mut engine, "new Array([new Date()])").unwrap(); // We don't care about the contents of the debug display (it is *debug* after all). In the commit that this test was @@ -466,8 +445,7 @@ fn debug_object() { #[test] #[ignore] // TODO: Once objects are printed in a simpler way this test can be simplified and used fn display_object() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let d_obj = r#" let o = {a: 'a'}; o @@ -531,8 +509,7 @@ mod abstract_relational_comparison { #[test] fn number_less_than_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1 < 2" => true); check_comparison!(engine, "2 < 2" => false); check_comparison!(engine, "3 < 2" => false); @@ -542,8 +519,7 @@ mod abstract_relational_comparison { #[test] fn string_less_than_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "'1' < 2" => true); check_comparison!(engine, "'2' < 2" => false); check_comparison!(engine, "'3' < 2" => false); @@ -553,8 +529,7 @@ mod abstract_relational_comparison { #[test] fn number_less_than_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1 < '2'" => true); check_comparison!(engine, "2 < '2'" => false); check_comparison!(engine, "3 < '2'" => false); @@ -564,8 +539,7 @@ mod abstract_relational_comparison { #[test] fn number_object_less_than_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "new Number(1) < '2'" => true); check_comparison!(engine, "new Number(2) < '2'" => false); check_comparison!(engine, "new Number(3) < '2'" => false); @@ -575,8 +549,7 @@ mod abstract_relational_comparison { #[test] fn number_object_less_than_number_object() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "new Number(1) < new Number(2)" => true); check_comparison!(engine, "new Number(2) < new Number(2)" => false); check_comparison!(engine, "new Number(3) < new Number(2)" => false); @@ -586,8 +559,7 @@ mod abstract_relational_comparison { #[test] fn string_less_than_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "'hello' < 'hello'" => false); check_comparison!(engine, "'hell' < 'hello'" => true); check_comparison!(engine, "'hello, world' < 'world'" => true); @@ -596,8 +568,7 @@ mod abstract_relational_comparison { #[test] fn string_object_less_than_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "new String('hello') < 'hello'" => false); check_comparison!(engine, "new String('hell') < 'hello'" => true); check_comparison!(engine, "new String('hello, world') < 'world'" => true); @@ -606,8 +577,7 @@ mod abstract_relational_comparison { #[test] fn string_object_less_than_string_object() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "new String('hello') < new String('hello')" => false); check_comparison!(engine, "new String('hell') < new String('hello')" => true); check_comparison!(engine, "new String('hello, world') < new String('world')" => true); @@ -616,8 +586,7 @@ mod abstract_relational_comparison { #[test] fn bigint_less_than_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1n < 10" => true); check_comparison!(engine, "10n < 10" => false); check_comparison!(engine, "100n < 10" => false); @@ -626,8 +595,7 @@ mod abstract_relational_comparison { #[test] fn number_less_than_bigint() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "10 < 1n" => false); check_comparison!(engine, "1 < 1n" => false); check_comparison!(engine, "-1 < -1n" => false); @@ -636,40 +604,35 @@ mod abstract_relational_comparison { #[test] fn negative_infnity_less_than_bigint() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "-Infinity < -10000000000n" => true); check_comparison!(engine, "-Infinity < (-1n << 100n)" => true); } #[test] fn bigint_less_than_infinity() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1000n < NaN" => false); check_comparison!(engine, "(1n << 100n) < NaN" => false); } #[test] fn nan_less_than_bigint() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "NaN < -10000000000n" => false); check_comparison!(engine, "NaN < (-1n << 100n)" => false); } #[test] fn bigint_less_than_nan() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1000n < Infinity" => true); check_comparison!(engine, "(1n << 100n) < Infinity" => true); } #[test] fn bigint_less_than_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1000n < '1000'" => false); check_comparison!(engine, "1000n < '2000'" => true); check_comparison!(engine, "1n < '-1'" => false); @@ -679,8 +642,7 @@ mod abstract_relational_comparison { #[test] fn string_less_than_bigint() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "'1000' < 1000n" => false); check_comparison!(engine, "'2000' < 1000n" => false); check_comparison!(engine, "'500' < 1000n" => true); @@ -693,8 +655,7 @@ mod abstract_relational_comparison { #[test] fn number_less_than_or_equal_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1 <= 2" => true); check_comparison!(engine, "2 <= 2" => true); check_comparison!(engine, "3 <= 2" => false); @@ -704,8 +665,7 @@ mod abstract_relational_comparison { #[test] fn string_less_than_or_equal_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "'1' <= 2" => true); check_comparison!(engine, "'2' <= 2" => true); check_comparison!(engine, "'3' <= 2" => false); @@ -715,8 +675,7 @@ mod abstract_relational_comparison { #[test] fn number_less_than_or_equal_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1 <= '2'" => true); check_comparison!(engine, "2 <= '2'" => true); check_comparison!(engine, "3 <= '2'" => false); @@ -726,8 +685,7 @@ mod abstract_relational_comparison { #[test] fn number_object_less_than_or_equal_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "new Number(1) <= '2'" => true); check_comparison!(engine, "new Number(2) <= '2'" => true); check_comparison!(engine, "new Number(3) <= '2'" => false); @@ -737,8 +695,7 @@ mod abstract_relational_comparison { #[test] fn number_object_less_than_number_or_equal_object() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "new Number(1) <= new Number(2)" => true); check_comparison!(engine, "new Number(2) <= new Number(2)" => true); check_comparison!(engine, "new Number(3) <= new Number(2)" => false); @@ -748,8 +705,7 @@ mod abstract_relational_comparison { #[test] fn string_less_than_or_equal_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "'hello' <= 'hello'" => true); check_comparison!(engine, "'hell' <= 'hello'" => true); check_comparison!(engine, "'hello, world' <= 'world'" => true); @@ -758,8 +714,7 @@ mod abstract_relational_comparison { #[test] fn string_object_less_than_or_equal_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "new String('hello') <= 'hello'" => true); check_comparison!(engine, "new String('hell') <= 'hello'" => true); check_comparison!(engine, "new String('hello, world') <= 'world'" => true); @@ -768,8 +723,7 @@ mod abstract_relational_comparison { #[test] fn string_object_less_than_string_or_equal_object() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "new String('hello') <= new String('hello')" => true); check_comparison!(engine, "new String('hell') <= new String('hello')" => true); check_comparison!(engine, "new String('hello, world') <= new String('world')" => true); @@ -778,8 +732,7 @@ mod abstract_relational_comparison { #[test] fn bigint_less_than_or_equal_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1n <= 10" => true); check_comparison!(engine, "10n <= 10" => true); check_comparison!(engine, "100n <= 10" => false); @@ -788,8 +741,7 @@ mod abstract_relational_comparison { #[test] fn number_less_than_or_equal_bigint() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "10 <= 1n" => false); check_comparison!(engine, "1 <= 1n" => true); check_comparison!(engine, "-1 <= -1n" => true); @@ -798,40 +750,35 @@ mod abstract_relational_comparison { #[test] fn negative_infnity_less_than_or_equal_bigint() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "-Infinity <= -10000000000n" => true); check_comparison!(engine, "-Infinity <= (-1n << 100n)" => true); } #[test] fn bigint_less_than_or_equal_infinity() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1000n <= NaN" => false); check_comparison!(engine, "(1n << 100n) <= NaN" => false); } #[test] fn nan_less_than_or_equal_bigint() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "NaN <= -10000000000n" => false); check_comparison!(engine, "NaN <= (-1n << 100n)" => false); } #[test] fn bigint_less_than_or_equal_nan() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1000n <= Infinity" => true); check_comparison!(engine, "(1n << 100n) <= Infinity" => true); } #[test] fn bigint_less_than_or_equal_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1000n <= '1000'" => true); check_comparison!(engine, "1000n <= '2000'" => true); check_comparison!(engine, "1n <= '-1'" => false); @@ -841,8 +788,7 @@ mod abstract_relational_comparison { #[test] fn string_less_than_or_equal_bigint() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "'1000' <= 1000n" => true); check_comparison!(engine, "'2000' <= 1000n" => false); check_comparison!(engine, "'500' <= 1000n" => true); @@ -855,8 +801,7 @@ mod abstract_relational_comparison { #[test] fn number_greater_than_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1 > 2" => false); check_comparison!(engine, "2 > 2" => false); check_comparison!(engine, "3 > 2" => true); @@ -866,8 +811,7 @@ mod abstract_relational_comparison { #[test] fn string_greater_than_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "'1' > 2" => false); check_comparison!(engine, "'2' > 2" => false); check_comparison!(engine, "'3' > 2" => true); @@ -877,8 +821,7 @@ mod abstract_relational_comparison { #[test] fn number_less_greater_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1 > '2'" => false); check_comparison!(engine, "2 > '2'" => false); check_comparison!(engine, "3 > '2'" => true); @@ -888,8 +831,7 @@ mod abstract_relational_comparison { #[test] fn number_object_greater_than_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "new Number(1) > '2'" => false); check_comparison!(engine, "new Number(2) > '2'" => false); check_comparison!(engine, "new Number(3) > '2'" => true); @@ -899,8 +841,7 @@ mod abstract_relational_comparison { #[test] fn number_object_greater_than_number_object() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "new Number(1) > new Number(2)" => false); check_comparison!(engine, "new Number(2) > new Number(2)" => false); check_comparison!(engine, "new Number(3) > new Number(2)" => true); @@ -910,8 +851,7 @@ mod abstract_relational_comparison { #[test] fn string_greater_than_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "'hello' > 'hello'" => false); check_comparison!(engine, "'hell' > 'hello'" => false); check_comparison!(engine, "'hello, world' > 'world'" => false); @@ -921,8 +861,7 @@ mod abstract_relational_comparison { #[test] fn string_object_greater_than_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "new String('hello') > 'hello'" => false); check_comparison!(engine, "new String('hell') > 'hello'" => false); check_comparison!(engine, "new String('hello, world') > 'world'" => false); @@ -932,8 +871,7 @@ mod abstract_relational_comparison { #[test] fn string_object_greater_than_string_object() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "new String('hello') > new String('hello')" => false); check_comparison!(engine, "new String('hell') > new String('hello')" => false); check_comparison!(engine, "new String('hello, world') > new String('world')" => false); @@ -943,8 +881,7 @@ mod abstract_relational_comparison { #[test] fn bigint_greater_than_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1n > 10" => false); check_comparison!(engine, "10n > 10" => false); check_comparison!(engine, "100n > 10" => true); @@ -953,8 +890,7 @@ mod abstract_relational_comparison { #[test] fn number_greater_than_bigint() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "10 > 1n" => true); check_comparison!(engine, "1 > 1n" => false); check_comparison!(engine, "-1 > -1n" => false); @@ -963,40 +899,35 @@ mod abstract_relational_comparison { #[test] fn negative_infnity_greater_than_bigint() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "-Infinity > -10000000000n" => false); check_comparison!(engine, "-Infinity > (-1n << 100n)" => false); } #[test] fn bigint_greater_than_infinity() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1000n > NaN" => false); check_comparison!(engine, "(1n << 100n) > NaN" => false); } #[test] fn nan_greater_than_bigint() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "NaN > -10000000000n" => false); check_comparison!(engine, "NaN > (-1n << 100n)" => false); } #[test] fn bigint_greater_than_nan() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1000n > Infinity" => false); check_comparison!(engine, "(1n << 100n) > Infinity" => false); } #[test] fn bigint_greater_than_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1000n > '1000'" => false); check_comparison!(engine, "1000n > '2000'" => false); check_comparison!(engine, "1n > '-1'" => true); @@ -1006,8 +937,7 @@ mod abstract_relational_comparison { #[test] fn string_greater_than_bigint() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "'1000' > 1000n" => false); check_comparison!(engine, "'2000' > 1000n" => true); check_comparison!(engine, "'500' > 1000n" => false); @@ -1020,8 +950,7 @@ mod abstract_relational_comparison { #[test] fn number_greater_than_or_equal_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1 >= 2" => false); check_comparison!(engine, "2 >= 2" => true); check_comparison!(engine, "3 >= 2" => true); @@ -1031,8 +960,7 @@ mod abstract_relational_comparison { #[test] fn string_greater_than_or_equal_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "'1' >= 2" => false); check_comparison!(engine, "'2' >= 2" => true); check_comparison!(engine, "'3' >= 2" => true); @@ -1042,8 +970,7 @@ mod abstract_relational_comparison { #[test] fn number_less_greater_or_equal_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1 >= '2'" => false); check_comparison!(engine, "2 >= '2'" => true); check_comparison!(engine, "3 >= '2'" => true); @@ -1053,8 +980,7 @@ mod abstract_relational_comparison { #[test] fn number_object_greater_than_or_equal_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "new Number(1) >= '2'" => false); check_comparison!(engine, "new Number(2) >= '2'" => true); check_comparison!(engine, "new Number(3) >= '2'" => true); @@ -1064,8 +990,7 @@ mod abstract_relational_comparison { #[test] fn number_object_greater_than_or_equal_number_object() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "new Number(1) >= new Number(2)" => false); check_comparison!(engine, "new Number(2) >= new Number(2)" => true); check_comparison!(engine, "new Number(3) >= new Number(2)" => true); @@ -1075,8 +1000,7 @@ mod abstract_relational_comparison { #[test] fn string_greater_than_or_equal_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "'hello' >= 'hello'" => true); check_comparison!(engine, "'hell' >= 'hello'" => false); check_comparison!(engine, "'hello, world' >= 'world'" => false); @@ -1086,8 +1010,7 @@ mod abstract_relational_comparison { #[test] fn string_object_greater_or_equal_than_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "new String('hello') >= 'hello'" => true); check_comparison!(engine, "new String('hell') >= 'hello'" => false); check_comparison!(engine, "new String('hello, world') >= 'world'" => false); @@ -1097,8 +1020,7 @@ mod abstract_relational_comparison { #[test] fn string_object_greater_than_or_equal_string_object() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "new String('hello') >= new String('hello')" => true); check_comparison!(engine, "new String('hell') >= new String('hello')" => false); check_comparison!(engine, "new String('hello, world') >= new String('world')" => false); @@ -1108,8 +1030,7 @@ mod abstract_relational_comparison { #[test] fn bigint_greater_than_or_equal_number() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1n >= 10" => false); check_comparison!(engine, "10n >= 10" => true); check_comparison!(engine, "100n >= 10" => true); @@ -1118,8 +1039,7 @@ mod abstract_relational_comparison { #[test] fn number_greater_than_or_equal_bigint() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "10 >= 1n" => true); check_comparison!(engine, "1 >= 1n" => true); check_comparison!(engine, "-1 >= -1n" => true); @@ -1128,40 +1048,35 @@ mod abstract_relational_comparison { #[test] fn negative_infnity_greater_or_equal_than_bigint() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "-Infinity >= -10000000000n" => false); check_comparison!(engine, "-Infinity >= (-1n << 100n)" => false); } #[test] fn bigint_greater_than_or_equal_infinity() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1000n >= NaN" => false); check_comparison!(engine, "(1n << 100n) >= NaN" => false); } #[test] fn nan_greater_than_or_equal_bigint() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "NaN >= -10000000000n" => false); check_comparison!(engine, "NaN >= (-1n << 100n)" => false); } #[test] fn bigint_greater_than_or_equal_nan() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1000n >= Infinity" => false); check_comparison!(engine, "(1n << 100n) >= Infinity" => false); } #[test] fn bigint_greater_than_or_equal_string() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "1000n >= '1000'" => true); check_comparison!(engine, "1000n >= '2000'" => false); check_comparison!(engine, "1n >= '-1'" => true); @@ -1171,8 +1086,7 @@ mod abstract_relational_comparison { #[test] fn string_greater_than_or_equal_bigint() { - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); check_comparison!(engine, "'1000' >= 1000n" => true); check_comparison!(engine, "'2000' >= 1000n" => true); check_comparison!(engine, "'500' >= 1000n" => false); diff --git a/boa_cli/src/main.rs b/boa_cli/src/main.rs index adfb999e41..8ca8fb8f7e 100644 --- a/boa_cli/src/main.rs +++ b/boa_cli/src/main.rs @@ -25,7 +25,7 @@ clippy::as_conversions )] -use boa::{exec::Interpreter, forward_val, realm::Realm, syntax::ast::node::StatementList}; +use boa::{syntax::ast::node::StatementList, Context}; use colored::*; use rustyline::{config::Config, error::ReadlineError, EditMode, Editor}; use std::{fs::read_to_string, path::PathBuf}; @@ -139,9 +139,7 @@ fn dump(src: &str, args: &Opt) -> Result<(), String> { pub fn main() -> Result<(), std::io::Error> { let args = Opt::from_args(); - let realm = Realm::create(); - - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); for file in &args.files { let buffer = read_to_string(file)?; @@ -151,7 +149,7 @@ pub fn main() -> Result<(), std::io::Error> { eprintln!("{}", e); } } else { - match forward_val(&mut engine, &buffer) { + match engine.eval(&buffer) { Ok(v) => println!("{}", v.display()), Err(v) => eprintln!("Uncaught {}", v.display()), } @@ -187,7 +185,7 @@ pub fn main() -> Result<(), std::io::Error> { eprintln!("{}", e); } } else { - match forward_val(&mut engine, line.trim_end()) { + match engine.eval(line.trim_end()) { Ok(v) => println!("{}", v.display()), Err(v) => { eprintln!("{}: {}", "Uncaught".red(), v.display().to_string().red()) diff --git a/boa_wasm/src/lib.rs b/boa_wasm/src/lib.rs index f8a1e689fb..95b0fc7bb2 100644 --- a/boa_wasm/src/lib.rs +++ b/boa_wasm/src/lib.rs @@ -1,11 +1,10 @@ -use boa::{parse, Executable, Interpreter, Realm}; +use boa::{exec::Executable, parse, Context}; use wasm_bindgen::prelude::*; #[wasm_bindgen] pub fn evaluate(src: &str) -> Result { // Setup executor - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); let expr = match parse(src) { Ok(res) => res, diff --git a/tester/src/exec.rs b/tester/src/exec.rs index 7eb1559cb4..0a0caa6093 100644 --- a/tester/src/exec.rs +++ b/tester/src/exec.rs @@ -1,7 +1,7 @@ //! Execution module for the test runner. use super::{Harness, Outcome, Phase, SuiteResult, Test, TestFlags, TestResult, TestSuite, CLI}; -use boa::{forward_val, parse, Interpreter, Realm}; +use boa::{parse, Context}; use colored::Colorize; use fxhash::FxHashSet; use once_cell::sync::Lazy; @@ -94,20 +94,20 @@ impl Test { if self.flags.contains(TestFlags::RAW) { let mut engine = self.set_up_env(&harness, false); - let res = forward_val(&mut engine, &self.content); + let res = engine.eval(&self.content); passed = res.is_ok() } else { if self.flags.contains(TestFlags::STRICT) { let mut engine = self.set_up_env(&harness, true); - let res = forward_val(&mut engine, &self.content); + let res = engine.eval(&self.content); passed = res.is_ok() } if passed && self.flags.contains(TestFlags::NO_STRICT) { let mut engine = self.set_up_env(&harness, false); - let res = forward_val(&mut engine, &self.content); + let res = engine.eval(&self.content); passed = res.is_ok() } @@ -160,24 +160,26 @@ impl Test { } /// Sets the environment up to run the test. - fn set_up_env(&self, harness: &Harness, strict: bool) -> Interpreter { + fn set_up_env(&self, harness: &Harness, strict: bool) -> Context { // Create new Realm // TODO: in parallel. - let realm = Realm::create(); - let mut engine = Interpreter::new(realm); + let mut engine = Context::new(); // TODO: set up the environment. if strict { - forward_val(&mut engine, r#""use strict";"#).expect("could not set strict mode"); + engine + .eval(r#""use strict";"#) + .expect("could not set strict mode"); } - forward_val(&mut engine, &harness.assert).expect("could not run assert.js"); - forward_val(&mut engine, &harness.sta).expect("could not run sta.js"); + engine + .eval(&harness.assert) + .expect("could not run assert.js"); + engine.eval(&harness.sta).expect("could not run sta.js"); self.includes.iter().for_each(|include| { - let res = forward_val( - &mut engine, + let res = engine.eval( &harness .includes .get(include)