diff --git a/boa/benches/exec.rs b/boa/benches/exec.rs index 43fdb45cbb..99789f4af8 100644 --- a/boa/benches/exec.rs +++ b/boa/benches/exec.rs @@ -17,8 +17,7 @@ fn create_realm(c: &mut Criterion) { static SYMBOL_CREATION: &str = include_str!("bench_scripts/symbol_creation.js"); fn symbol_creation(c: &mut Criterion) { - // Create new Realm and interpreter. - let mut engine = Context::new(); + let mut context = Context::new(); // Parse the AST nodes. let nodes = Parser::new(SYMBOL_CREATION.as_bytes(), false) @@ -27,30 +26,28 @@ fn symbol_creation(c: &mut Criterion) { // Execute the parsed nodes, passing them through a black box, to avoid over-optimizing by the compiler c.bench_function("Symbols (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } static FOR_LOOP: &str = include_str!("bench_scripts/for_loop.js"); fn for_loop_execution(c: &mut Criterion) { - // Create new Realm and interpreter. - let mut engine = Context::new(); + let mut context = Context::new(); // Parse the AST nodes. let nodes = Parser::new(FOR_LOOP.as_bytes(), false).parse_all().unwrap(); // Execute the parsed nodes, passing them through a black box, to avoid over-optimizing by the compiler c.bench_function("For loop (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } static FIBONACCI: &str = include_str!("bench_scripts/fibonacci.js"); fn fibonacci(c: &mut Criterion) { - // Create new Realm and interpreter. - let mut engine = Context::new(); + let mut context = Context::new(); // Parse the AST nodes. let nodes = Parser::new(FIBONACCI.as_bytes(), false) @@ -59,15 +56,14 @@ fn fibonacci(c: &mut Criterion) { // Execute the parsed nodes, passing them through a black box, to avoid over-optimizing by the compiler c.bench_function("Fibonacci (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } static OBJECT_CREATION: &str = include_str!("bench_scripts/object_creation.js"); fn object_creation(c: &mut Criterion) { - // Create new Realm and interpreter. - let mut engine = Context::new(); + let mut context = Context::new(); // Parse the AST nodes. let nodes = Parser::new(OBJECT_CREATION.as_bytes(), false) @@ -76,15 +72,14 @@ fn object_creation(c: &mut Criterion) { // Execute the parsed nodes, passing them through a black box, to avoid over-optimizing by the compiler c.bench_function("Object Creation (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } static OBJECT_PROP_ACCESS_CONST: &str = include_str!("bench_scripts/object_prop_access_const.js"); fn object_prop_access_const(c: &mut Criterion) { - // Create new Realm and interpreter. - let mut engine = Context::new(); + let mut context = Context::new(); // Parse the AST nodes. let nodes = Parser::new(OBJECT_PROP_ACCESS_CONST.as_bytes(), false) @@ -93,15 +88,14 @@ fn object_prop_access_const(c: &mut Criterion) { // Execute the parsed nodes, passing them through a black box, to avoid over-optimizing by the compiler c.bench_function("Static Object Property Access (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } static OBJECT_PROP_ACCESS_DYN: &str = include_str!("bench_scripts/object_prop_access_dyn.js"); fn object_prop_access_dyn(c: &mut Criterion) { - // Create new Realm and interpreter. - let mut engine = Context::new(); + let mut context = Context::new(); // Parse the AST nodes. let nodes = Parser::new(OBJECT_PROP_ACCESS_DYN.as_bytes(), false) @@ -110,15 +104,14 @@ fn object_prop_access_dyn(c: &mut Criterion) { // Execute the parsed nodes, passing them through a black box, to avoid over-optimizing by the compiler c.bench_function("Dynamic Object Property Access (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } static REGEXP_LITERAL_CREATION: &str = include_str!("bench_scripts/regexp_literal_creation.js"); fn regexp_literal_creation(c: &mut Criterion) { - // Create new Realm and interpreter. - let mut engine = Context::new(); + let mut context = Context::new(); // Parse the AST nodes. let nodes = Parser::new(REGEXP_LITERAL_CREATION.as_bytes(), false) @@ -127,15 +120,14 @@ fn regexp_literal_creation(c: &mut Criterion) { // Execute the parsed nodes, passing them through a black box, to avoid over-optimizing by the compiler c.bench_function("RegExp Literal Creation (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } static REGEXP_CREATION: &str = include_str!("bench_scripts/regexp_creation.js"); fn regexp_creation(c: &mut Criterion) { - // Create new Realm and interpreter. - let mut engine = Context::new(); + let mut context = Context::new(); // Parse the AST nodes. let nodes = Parser::new(REGEXP_CREATION.as_bytes(), false) @@ -144,15 +136,14 @@ fn regexp_creation(c: &mut Criterion) { // Execute the parsed nodes, passing them through a black box, to avoid over-optimizing by the compiler c.bench_function("RegExp (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } static REGEXP_LITERAL: &str = include_str!("bench_scripts/regexp_literal.js"); fn regexp_literal(c: &mut Criterion) { - // Create new Realm and interpreter. - let mut engine = Context::new(); + let mut context = Context::new(); // Parse the AST nodes. let nodes = Parser::new(REGEXP_LITERAL.as_bytes(), false) @@ -161,182 +152,181 @@ fn regexp_literal(c: &mut Criterion) { // Execute the parsed nodes, passing them through a black box, to avoid over-optimizing by the compiler c.bench_function("RegExp Literal (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } static REGEXP: &str = include_str!("bench_scripts/regexp.js"); fn regexp(c: &mut Criterion) { - // Create new Realm and interpreter. - let mut engine = Context::new(); + let mut context = Context::new(); // Parse the AST nodes. let nodes = Parser::new(REGEXP.as_bytes(), false).parse_all().unwrap(); // Execute the parsed nodes, passing them through a black box, to avoid over-optimizing by the compiler c.bench_function("RegExp (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } static ARRAY_ACCESS: &str = include_str!("bench_scripts/array_access.js"); fn array_access(c: &mut Criterion) { - let mut engine = Context::new(); + let mut context = Context::new(); let nodes = Parser::new(ARRAY_ACCESS.as_bytes(), false) .parse_all() .unwrap(); c.bench_function("Array access (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } static ARRAY_CREATE: &str = include_str!("bench_scripts/array_create.js"); fn array_creation(c: &mut Criterion) { - let mut engine = Context::new(); + let mut context = Context::new(); let nodes = Parser::new(ARRAY_CREATE.as_bytes(), false) .parse_all() .unwrap(); c.bench_function("Array creation (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } static ARRAY_POP: &str = include_str!("bench_scripts/array_pop.js"); fn array_pop(c: &mut Criterion) { - let mut engine = Context::new(); + let mut context = Context::new(); let nodes = Parser::new(ARRAY_POP.as_bytes(), false) .parse_all() .unwrap(); c.bench_function("Array pop (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } static STRING_CONCAT: &str = include_str!("bench_scripts/string_concat.js"); fn string_concat(c: &mut Criterion) { - let mut engine = Context::new(); + let mut context = Context::new(); let nodes = Parser::new(STRING_CONCAT.as_bytes(), false) .parse_all() .unwrap(); c.bench_function("String concatenation (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } static STRING_COMPARE: &str = include_str!("bench_scripts/string_compare.js"); fn string_compare(c: &mut Criterion) { - let mut engine = Context::new(); + let mut context = Context::new(); let nodes = Parser::new(STRING_COMPARE.as_bytes(), false) .parse_all() .unwrap(); c.bench_function("String comparison (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } static STRING_COPY: &str = include_str!("bench_scripts/string_copy.js"); fn string_copy(c: &mut Criterion) { - let mut engine = Context::new(); + let mut context = Context::new(); let nodes = Parser::new(STRING_COPY.as_bytes(), false) .parse_all() .unwrap(); c.bench_function("String copy (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } static NUMBER_OBJECT_ACCESS: &str = include_str!("bench_scripts/number_object_access.js"); fn number_object_access(c: &mut Criterion) { - let mut engine = Context::new(); + let mut context = Context::new(); let nodes = Parser::new(NUMBER_OBJECT_ACCESS.as_bytes(), false) .parse_all() .unwrap(); c.bench_function("Number Object Access (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } static BOOLEAN_OBJECT_ACCESS: &str = include_str!("bench_scripts/boolean_object_access.js"); fn boolean_object_access(c: &mut Criterion) { - let mut engine = Context::new(); + let mut context = Context::new(); let nodes = Parser::new(BOOLEAN_OBJECT_ACCESS.as_bytes(), false) .parse_all() .unwrap(); c.bench_function("Boolean Object Access (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } static STRING_OBJECT_ACCESS: &str = include_str!("bench_scripts/string_object_access.js"); fn string_object_access(c: &mut Criterion) { - let mut engine = Context::new(); + let mut context = Context::new(); let nodes = Parser::new(STRING_OBJECT_ACCESS.as_bytes(), false) .parse_all() .unwrap(); c.bench_function("String Object Access (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } static ARITHMETIC_OPERATIONS: &str = include_str!("bench_scripts/arithmetic_operations.js"); fn arithmetic_operations(c: &mut Criterion) { - let mut engine = Context::new(); + let mut context = Context::new(); let nodes = Parser::new(ARITHMETIC_OPERATIONS.as_bytes(), false) .parse_all() .unwrap(); c.bench_function("Arithmetic operations (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } static CLEAN_JS: &str = include_str!("bench_scripts/clean_js.js"); fn clean_js(c: &mut Criterion) { - let mut engine = Context::new(); + let mut context = Context::new(); let nodes = Parser::new(CLEAN_JS.as_bytes(), false).parse_all().unwrap(); c.bench_function("Clean js (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } static MINI_JS: &str = include_str!("bench_scripts/mini_js.js"); fn mini_js(c: &mut Criterion) { - let mut engine = Context::new(); + let mut context = Context::new(); let nodes = Parser::new(MINI_JS.as_bytes(), false).parse_all().unwrap(); c.bench_function("Mini js (Execution)", move |b| { - b.iter(|| black_box(&nodes).run(&mut engine).unwrap()) + b.iter(|| black_box(&nodes).run(&mut context).unwrap()) }); } diff --git a/boa/examples/classes.rs b/boa/examples/classes.rs index 7f62147c8e..1e10e22293 100644 --- a/boa/examples/classes.rs +++ b/boa/examples/classes.rs @@ -26,7 +26,7 @@ struct Person { // or any function that matches that signature. impl Person { /// This function says hello - fn say_hello(this: &Value, _: &[Value], ctx: &mut Context) -> Result { + fn say_hello(this: &Value, _: &[Value], context: &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`. @@ -42,7 +42,7 @@ impl Person { } // If `this` was not an object or the type was not an native object `Person`, // we throw a `TypeError`. - ctx.throw_type_error("'this' is not a Person object") + context.throw_type_error("'this' is not a Person object") } } @@ -57,15 +57,19 @@ 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 Context) -> Result { + fn constructor(_this: &Value, args: &[Value], context: &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)`. - let name = args.get(0).cloned().unwrap_or_default().to_string(ctx)?; + let name = args + .get(0) + .cloned() + .unwrap_or_default() + .to_string(context)?; // we get the second arguemnt of undefined if the first one is unavalable and call `to_u32`. // // This is equivalent to `arg | 0`. - let age = args.get(1).cloned().unwrap_or_default().to_u32(ctx)?; + let age = args.get(1).cloned().unwrap_or_default().to_u32(context)?; // we construct the the native struct `Person` let person = Person { diff --git a/boa/src/builtins/array/array_iterator.rs b/boa/src/builtins/array/array_iterator.rs index 13128a6f51..8a7bf51354 100644 --- a/boa/src/builtins/array/array_iterator.rs +++ b/boa/src/builtins/array/array_iterator.rs @@ -1,10 +1,10 @@ use crate::{ builtins::{function::make_builtin_fn, iterable::create_iter_result_object, Array, Value}, + gc::{Finalize, Trace}, object::ObjectData, property::{Attribute, DataDescriptor}, BoaProfiler, Context, Result, }; -use gc::{Finalize, Trace}; #[derive(Debug, Clone, Finalize, Trace)] pub enum ArrayIterationKind { @@ -46,16 +46,16 @@ impl ArrayIterator { /// /// [spec]: https://tc39.es/ecma262/#sec-createarrayiterator pub(crate) fn create_array_iterator( - ctx: &Context, + context: &Context, array: Value, kind: ArrayIterationKind, ) -> Result { - let array_iterator = Value::new_object(Some(ctx.global_object())); + let array_iterator = Value::new_object(Some(context.global_object())); array_iterator.set_data(ObjectData::ArrayIterator(Self::new(array, kind))); array_iterator .as_object() .expect("array iterator object") - .set_prototype_instance(ctx.iterator_prototypes().array_iterator().into()); + .set_prototype_instance(context.iterator_prototypes().array_iterator().into()); Ok(array_iterator) } @@ -67,48 +67,48 @@ impl ArrayIterator { /// - [ECMA reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-%arrayiteratorprototype%.next - pub(crate) fn next(this: &Value, _args: &[Value], ctx: &mut Context) -> Result { + pub(crate) fn next(this: &Value, _: &[Value], context: &mut Context) -> Result { if let Value::Object(ref object) = this { let mut object = object.borrow_mut(); if let Some(array_iterator) = object.as_array_iterator_mut() { let index = array_iterator.next_index; if array_iterator.array.is_undefined() { - return Ok(create_iter_result_object(ctx, Value::undefined(), true)); + return Ok(create_iter_result_object(context, Value::undefined(), true)); } let len = array_iterator .array .get_field("length") .as_number() - .ok_or_else(|| ctx.construct_type_error("Not an array"))? + .ok_or_else(|| context.construct_type_error("Not an array"))? as u32; if array_iterator.next_index >= len { array_iterator.array = Value::undefined(); - return Ok(create_iter_result_object(ctx, Value::undefined(), true)); + return Ok(create_iter_result_object(context, Value::undefined(), true)); } array_iterator.next_index = index + 1; match array_iterator.kind { ArrayIterationKind::Key => { - Ok(create_iter_result_object(ctx, index.into(), false)) + Ok(create_iter_result_object(context, index.into(), false)) } ArrayIterationKind::Value => { let element_value = array_iterator.array.get_field(index); - Ok(create_iter_result_object(ctx, element_value, false)) + Ok(create_iter_result_object(context, element_value, false)) } ArrayIterationKind::KeyAndValue => { let element_value = array_iterator.array.get_field(index); let result = Array::constructor( - &Value::new_object(Some(ctx.global_object())), + &Value::new_object(Some(context.global_object())), &[index.into(), element_value], - ctx, + context, )?; - Ok(create_iter_result_object(ctx, result, false)) + Ok(create_iter_result_object(context, result, false)) } } } else { - ctx.throw_type_error("`this` is not an ArrayIterator") + context.throw_type_error("`this` is not an ArrayIterator") } } else { - ctx.throw_type_error("`this` is not an ArrayIterator") + context.throw_type_error("`this` is not an ArrayIterator") } } @@ -118,19 +118,19 @@ impl ArrayIterator { /// - [ECMA reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-%arrayiteratorprototype%-object - pub(crate) fn create_prototype(ctx: &mut Context, iterator_prototype: Value) -> Value { - let global = ctx.global_object(); + pub(crate) fn create_prototype(context: &mut Context, iterator_prototype: Value) -> Value { + let global = context.global_object(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); // Create prototype let array_iterator = Value::new_object(Some(global)); - make_builtin_fn(Self::next, "next", &array_iterator, 0, ctx); + make_builtin_fn(Self::next, "next", &array_iterator, 0, context); array_iterator .as_object() .expect("array iterator prototype object") .set_prototype_instance(iterator_prototype); - let to_string_tag = ctx.well_known_symbols().to_string_tag_symbol(); + let to_string_tag = context.well_known_symbols().to_string_tag_symbol(); let to_string_tag_property = DataDescriptor::new("Array Iterator", Attribute::CONFIGURABLE); array_iterator.set_property(to_string_tag, to_string_tag_property); array_iterator diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index 972577e50e..1041a747f4 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -275,11 +275,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.isarray /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray - pub(crate) fn is_array( - _this: &Value, - args: &[Value], - _interpreter: &mut Context, - ) -> Result { + pub(crate) fn is_array(_: &Value, args: &[Value], _: &mut Context) -> Result { match args.get(0).and_then(|x| x.as_object()) { Some(object) => Ok(Value::from(object.borrow().is_array())), None => Ok(Value::from(false)), @@ -373,7 +369,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], ctx: &mut Context) -> Result { + pub(crate) fn for_each(this: &Value, args: &[Value], context: &mut Context) -> Result { if args.is_empty() { return Err(Value::from("Missing argument for Array.prototype.forEach")); } @@ -387,7 +383,7 @@ impl Array { let element = this.get_field(i); let arguments = [element, Value::from(i), this.clone()]; - ctx.call(callback_arg, &this_arg, &arguments)?; + context.call(callback_arg, &this_arg, &arguments)?; } Ok(Value::undefined()) @@ -405,20 +401,20 @@ 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 Context) -> Result { + pub(crate) fn join(this: &Value, args: &[Value], context: &mut Context) -> Result { let separator = if args.is_empty() { String::from(",") } else { args.get(0) .expect("Could not get argument") - .to_string(ctx)? + .to_string(context)? .to_string() }; let mut elem_strs = Vec::new(); let length = this.get_field("length").as_number().unwrap() as i32; for n in 0..length { - let elem_str = this.get_field(n).to_string(ctx)?.to_string(); + let elem_str = this.get_field(n).to_string(context)?.to_string(); elem_strs.push(elem_str); } @@ -438,14 +434,14 @@ 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 Context) -> Result { + pub(crate) fn to_string(this: &Value, _: &[Value], context: &mut Context) -> Result { let method_name = "join"; let mut arguments = vec![Value::from(",")]; // 2. let mut method = this.get_field(method_name); // 3. if !method.is_function() { - method = ctx + method = context .global_object() .get_field("Object") .get_field(PROTOTYPE) @@ -454,7 +450,7 @@ impl Array { arguments = Vec::new(); } // 4. - let join = ctx.call(&method, this, &arguments)?; + let join = context.call(&method, this, &arguments)?; let string = if let Value::String(ref s) = join { Value::from(s.as_str()) @@ -602,7 +598,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 Context) -> Result { + pub(crate) fn every(this: &Value, args: &[Value], context: &mut Context) -> Result { if args.is_empty() { return Err(Value::from( "missing callback when calling function Array.prototype.every", @@ -620,7 +616,7 @@ impl Array { while i < len { let element = this.get_field(i); let arguments = [element, Value::from(i), this.clone()]; - let result = interpreter.call(callback, &this_arg, &arguments)?; + let result = context.call(callback, &this_arg, &arguments)?; if !result.to_boolean() { return Ok(Value::from(false)); } @@ -798,7 +794,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 Context) -> Result { + pub(crate) fn find(this: &Value, args: &[Value], context: &mut Context) -> Result { if args.is_empty() { return Err(Value::from( "missing callback when calling function Array.prototype.find", @@ -810,7 +806,7 @@ impl Array { for i in 0..len { let element = this.get_field(i); let arguments = [element.clone(), Value::from(i), this.clone()]; - let result = interpreter.call(callback, &this_arg, &arguments)?; + let result = context.call(callback, &this_arg, &arguments)?; if result.to_boolean() { return Ok(element); } @@ -830,11 +826,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.findindex /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex - pub(crate) fn find_index( - this: &Value, - args: &[Value], - interpreter: &mut Context, - ) -> Result { + pub(crate) fn find_index(this: &Value, args: &[Value], context: &mut Context) -> Result { if args.is_empty() { return Err(Value::from( "Missing argument for Array.prototype.findIndex", @@ -851,7 +843,7 @@ impl Array { let element = this.get_field(i); let arguments = [element, Value::from(i), this.clone()]; - let result = interpreter.call(predicate_arg, &this_arg, &arguments)?; + let result = context.call(predicate_arg, &this_arg, &arguments)?; if result.to_boolean() { return Ok(Value::rational(f64::from(i))); @@ -872,17 +864,17 @@ 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 Context) -> Result { + pub(crate) fn fill(this: &Value, args: &[Value], context: &mut Context) -> Result { let len: i32 = this.get_field("length").as_number().unwrap() as i32; let default_value = Value::undefined(); let value = args.get(0).unwrap_or(&default_value); - let relative_start = args.get(1).unwrap_or(&default_value).to_number(ctx)? as i32; + let relative_start = args.get(1).unwrap_or(&default_value).to_number(context)? as i32; let relative_end_val = args.get(2).unwrap_or(&default_value); let relative_end = if relative_end_val.is_undefined() { len } else { - relative_end_val.to_number(ctx)? as i32 + relative_end_val.to_number(context)? as i32 }; let start = if relative_start < 0 { max(len + relative_start, 0) @@ -942,8 +934,8 @@ 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 Context) -> Result { - let new_array = Self::new_array(interpreter)?; + pub(crate) fn slice(this: &Value, args: &[Value], context: &mut Context) -> Result { + let new_array = Self::new_array(context)?; let len = this.get_field("length").as_number().unwrap() as i32; let start = match args.get(0) { @@ -987,7 +979,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 Context) -> Result { + pub(crate) fn filter(this: &Value, args: &[Value], context: &mut Context) -> Result { if args.is_empty() { return Err(Value::from( "missing argument 0 when calling function Array.prototype.filter", @@ -999,7 +991,7 @@ impl Array { let length = this.get_field("length").as_number().unwrap() as i32; - let new = Self::new_array(interpreter)?; + let new = Self::new_array(context)?; let values = (0..length) .filter_map(|idx| { @@ -1007,7 +999,7 @@ impl Array { let args = [element.clone(), Value::from(idx), new.clone()]; - let callback_result = interpreter + let callback_result = context .call(&callback, &this_val, &args) .unwrap_or_else(|_| Value::undefined()); @@ -1037,7 +1029,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 Context) -> Result { + pub(crate) fn some(this: &Value, args: &[Value], context: &mut Context) -> Result { if args.is_empty() { return Err(Value::from( "missing callback when calling function Array.prototype.some", @@ -1055,7 +1047,7 @@ impl Array { while i < len { let element = this.get_field(i); let arguments = [element, Value::from(i), this.clone()]; - let result = interpreter.call(callback, &this_arg, &arguments)?; + let result = context.call(callback, &this_arg, &arguments)?; if result.to_boolean() { return Ok(Value::from(true)); } @@ -1080,16 +1072,16 @@ 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 Context) -> Result { - let this: Value = this.to_object(interpreter)?.into(); + pub(crate) fn reduce(this: &Value, args: &[Value], context: &mut Context) -> Result { + let this: Value = this.to_object(context)?.into(); let callback = match args.get(0) { Some(value) if value.is_function() => value, - _ => return interpreter.throw_type_error("Reduce was called without a callback"), + _ => return context.throw_type_error("Reduce was called without a callback"), }; let initial_value = args.get(1).cloned().unwrap_or_else(Value::undefined); - let mut length = this.get_field("length").to_length(interpreter)?; + let mut length = this.get_field("length").to_length(context)?; if length == 0 && initial_value.is_undefined() { - return interpreter + return context .throw_type_error("Reduce was called on an empty array and with no initial value"); } let mut k = 0; @@ -1103,7 +1095,7 @@ impl Array { k += 1; } if !k_present { - return interpreter.throw_type_error( + return context.throw_type_error( "Reduce was called on an empty array and with no initial value", ); } @@ -1116,11 +1108,11 @@ impl Array { while k < length { if this.has_field(k) { let arguments = [accumulator, this.get_field(k), Value::from(k), this.clone()]; - accumulator = interpreter.call(&callback, &Value::undefined(), &arguments)?; + accumulator = context.call(&callback, &Value::undefined(), &arguments)?; /* We keep track of possibly shortened length in order to prevent unnecessary iteration. It may also be necessary to do this since shortening the array length does not delete array elements. See: https://github.com/boa-dev/boa/issues/557 */ - length = min(length, this.get_field("length").to_length(interpreter)?); + length = min(length, this.get_field("length").to_length(context)?); } k += 1; } @@ -1141,18 +1133,18 @@ impl Array { pub(crate) fn reduce_right( this: &Value, args: &[Value], - interpreter: &mut Context, + context: &mut Context, ) -> Result { - let this: Value = this.to_object(interpreter)?.into(); + let this: Value = this.to_object(context)?.into(); let callback = match args.get(0) { Some(value) if value.is_function() => value, - _ => return interpreter.throw_type_error("reduceRight was called without a callback"), + _ => return context.throw_type_error("reduceRight was called without a callback"), }; let initial_value = args.get(1).cloned().unwrap_or_else(Value::undefined); - let mut length = this.get_field("length").to_length(interpreter)?; + let mut length = this.get_field("length").to_length(context)?; if length == 0 { return if initial_value.is_undefined() { - interpreter.throw_type_error( + context.throw_type_error( "reduceRight was called on an empty array and with no initial value", ) } else { @@ -1175,7 +1167,7 @@ impl Array { k -= 1; } if !k_present { - return interpreter.throw_type_error( + return context.throw_type_error( "reduceRight was called on an empty array and with no initial value", ); } @@ -1189,11 +1181,11 @@ impl Array { while k != usize::MAX { if this.has_field(k) { let arguments = [accumulator, this.get_field(k), Value::from(k), this.clone()]; - accumulator = interpreter.call(&callback, &Value::undefined(), &arguments)?; + accumulator = context.call(&callback, &Value::undefined(), &arguments)?; /* We keep track of possibly shortened length in order to prevent unnecessary iteration. It may also be necessary to do this since shortening the array length does not delete array elements. See: https://github.com/boa-dev/boa/issues/557 */ - length = min(length, this.get_field("length").to_length(interpreter)?); + length = min(length, this.get_field("length").to_length(context)?); // move k to the last defined element if necessary or return if the length was set to 0 if k >= length { @@ -1223,8 +1215,8 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.values /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/values - pub(crate) fn values(this: &Value, _: &[Value], ctx: &mut Context) -> Result { - ArrayIterator::create_array_iterator(ctx, this.clone(), ArrayIterationKind::Value) + pub(crate) fn values(this: &Value, _: &[Value], context: &mut Context) -> Result { + ArrayIterator::create_array_iterator(context, this.clone(), ArrayIterationKind::Value) } /// `Array.prototype.keys( )` @@ -1237,8 +1229,8 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.values /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/values - pub(crate) fn keys(this: &Value, _: &[Value], ctx: &mut Context) -> Result { - ArrayIterator::create_array_iterator(ctx, this.clone(), ArrayIterationKind::Key) + pub(crate) fn keys(this: &Value, _: &[Value], context: &mut Context) -> Result { + ArrayIterator::create_array_iterator(context, this.clone(), ArrayIterationKind::Key) } /// `Array.prototype.entries( )` @@ -1251,7 +1243,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.values /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/values - pub(crate) fn entries(this: &Value, _: &[Value], ctx: &mut Context) -> Result { - ArrayIterator::create_array_iterator(ctx, this.clone(), ArrayIterationKind::KeyAndValue) + pub(crate) fn entries(this: &Value, _: &[Value], context: &mut Context) -> Result { + ArrayIterator::create_array_iterator(context, this.clone(), ArrayIterationKind::KeyAndValue) } } diff --git a/boa/src/builtins/array/tests.rs b/boa/src/builtins/array/tests.rs index 464383d75b..869928ccea 100644 --- a/boa/src/builtins/array/tests.rs +++ b/boa/src/builtins/array/tests.rs @@ -2,66 +2,66 @@ use crate::{forward, Context, Value}; #[test] fn is_array() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var empty = []; var new_arr = new Array(); var many = ["a", "b", "c"]; "#; - engine.eval(init).unwrap(); + context.eval(init).unwrap(); assert_eq!( - engine.eval("Array.isArray(empty)").unwrap(), + context.eval("Array.isArray(empty)").unwrap(), Value::Boolean(true) ); assert_eq!( - engine.eval("Array.isArray(new_arr)").unwrap(), + context.eval("Array.isArray(new_arr)").unwrap(), Value::Boolean(true) ); assert_eq!( - engine.eval("Array.isArray(many)").unwrap(), + context.eval("Array.isArray(many)").unwrap(), Value::Boolean(true) ); assert_eq!( - engine.eval("Array.isArray([1, 2, 3])").unwrap(), + context.eval("Array.isArray([1, 2, 3])").unwrap(), Value::Boolean(true) ); assert_eq!( - engine.eval("Array.isArray([])").unwrap(), + context.eval("Array.isArray([])").unwrap(), Value::Boolean(true) ); assert_eq!( - engine.eval("Array.isArray({})").unwrap(), + context.eval("Array.isArray({})").unwrap(), Value::Boolean(false) ); - // assert_eq!(engine.eval("Array.isArray(new Array)"), "true"); + // assert_eq!(context.eval("Array.isArray(new Array)"), "true"); assert_eq!( - engine.eval("Array.isArray()").unwrap(), + context.eval("Array.isArray()").unwrap(), Value::Boolean(false) ); assert_eq!( - engine + context .eval("Array.isArray({ constructor: Array })") .unwrap(), Value::Boolean(false) ); assert_eq!( - engine + context .eval("Array.isArray({ push: Array.prototype.push, concat: Array.prototype.concat })") .unwrap(), Value::Boolean(false) ); assert_eq!( - engine.eval("Array.isArray(17)").unwrap(), + context.eval("Array.isArray(17)").unwrap(), Value::Boolean(false) ); assert_eq!( - engine + context .eval("Array.isArray({ __proto__: Array.prototype })") .unwrap(), Value::Boolean(false) ); assert_eq!( - engine.eval("Array.isArray({ length: 0 })").unwrap(), + context.eval("Array.isArray({ length: 0 })").unwrap(), Value::Boolean(false) ); } @@ -70,85 +70,85 @@ fn is_array() { #[ignore] fn concat() { //TODO: array display formatter - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var empty = new Array(); var one = new Array(1); "#; - engine.eval(init).unwrap(); + context.eval(init).unwrap(); // Empty ++ Empty - let ee = engine + let ee = context .eval("empty.concat(empty)") .unwrap() - .to_string(&mut engine) + .to_string(&mut context) .unwrap(); assert_eq!(ee, "[]"); // Empty ++ NonEmpty - let en = engine + let en = context .eval("empty.concat(one)") .unwrap() - .to_string(&mut engine) + .to_string(&mut context) .unwrap(); assert_eq!(en, "[a]"); // NonEmpty ++ Empty - let ne = engine + let ne = context .eval("one.concat(empty)") .unwrap() - .to_string(&mut engine) + .to_string(&mut context) .unwrap(); assert_eq!(ne, "a.b.c"); // NonEmpty ++ NonEmpty - let nn = engine + let nn = context .eval("one.concat(one)") .unwrap() - .to_string(&mut engine) + .to_string(&mut context) .unwrap(); assert_eq!(nn, "a.b.c"); } #[test] fn join() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var empty = [ ]; var one = ["a"]; var many = ["a", "b", "c"]; "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); // Empty - let empty = forward(&mut engine, "empty.join('.')"); + let empty = forward(&mut context, "empty.join('.')"); assert_eq!(empty, String::from("\"\"")); // One - let one = forward(&mut engine, "one.join('.')"); + let one = forward(&mut context, "one.join('.')"); assert_eq!(one, String::from("\"a\"")); // Many - let many = forward(&mut engine, "many.join('.')"); + let many = forward(&mut context, "many.join('.')"); assert_eq!(many, String::from("\"a.b.c\"")); } #[test] fn to_string() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var empty = [ ]; var one = ["a"]; var many = ["a", "b", "c"]; "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); // Empty - let empty = forward(&mut engine, "empty.toString()"); + let empty = forward(&mut context, "empty.toString()"); assert_eq!(empty, String::from("\"\"")); // One - let one = forward(&mut engine, "one.toString()"); + let one = forward(&mut context, "one.toString()"); assert_eq!(one, String::from("\"a\"")); // Many - let many = forward(&mut engine, "many.toString()"); + let many = forward(&mut context, "many.toString()"); assert_eq!(many, String::from("\"a,b,c\"")); } #[test] fn every() { - let mut engine = Context::new(); + let mut context = Context::new(); // taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every let init = r#" var empty = []; @@ -173,40 +173,40 @@ fn every() { return elem < 3; } "#; - eprintln!("{}", forward(&mut engine, init)); - let result = forward(&mut engine, "array.every(callback);"); + eprintln!("{}", forward(&mut context, init)); + let result = forward(&mut context, "array.every(callback);"); assert_eq!(result, "true"); - let result = forward(&mut engine, "empty.every(callback);"); + let result = forward(&mut context, "empty.every(callback);"); assert_eq!(result, "true"); - let result = forward(&mut engine, "array.every(callback2);"); + let result = forward(&mut context, "array.every(callback2);"); assert_eq!(result, "false"); - let result = forward(&mut engine, "appendArray.every(appendingCallback);"); + let result = forward(&mut context, "appendArray.every(appendingCallback);"); assert_eq!(result, "true"); - let result = forward(&mut engine, "delArray.every(deletingCallback);"); + let result = forward(&mut context, "delArray.every(deletingCallback);"); assert_eq!(result, "true"); } #[test] fn find() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" function comp(a) { return a == "a"; } var many = ["a", "b", "c"]; "#; - eprintln!("{}", forward(&mut engine, init)); - let found = forward(&mut engine, "many.find(comp)"); + eprintln!("{}", forward(&mut context, init)); + let found = forward(&mut context, "many.find(comp)"); assert_eq!(found, String::from("\"a\"")); } #[test] fn find_index() { - let mut engine = Context::new(); + let mut context = Context::new(); let code = r#" function comp(item) { @@ -217,336 +217,336 @@ fn find_index() { var missing = [4, 5, 6]; "#; - forward(&mut engine, code); + forward(&mut context, code); - let many = forward(&mut engine, "many.findIndex(comp)"); + let many = forward(&mut context, "many.findIndex(comp)"); assert_eq!(many, String::from("1")); - let empty = forward(&mut engine, "empty.findIndex(comp)"); + let empty = forward(&mut context, "empty.findIndex(comp)"); assert_eq!(empty, String::from("-1")); - let missing = forward(&mut engine, "missing.findIndex(comp)"); + let missing = forward(&mut context, "missing.findIndex(comp)"); assert_eq!(missing, String::from("-1")); } #[test] fn push() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var arr = [1, 2]; "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - assert_eq!(forward(&mut engine, "arr.push()"), "2"); - assert_eq!(forward(&mut engine, "arr.push(3, 4)"), "4"); - assert_eq!(forward(&mut engine, "arr[2]"), "3"); - assert_eq!(forward(&mut engine, "arr[3]"), "4"); + assert_eq!(forward(&mut context, "arr.push()"), "2"); + assert_eq!(forward(&mut context, "arr.push(3, 4)"), "4"); + assert_eq!(forward(&mut context, "arr[2]"), "3"); + assert_eq!(forward(&mut context, "arr[3]"), "4"); } #[test] fn pop() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var empty = [ ]; var one = [1]; var many = [1, 2, 3, 4]; "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); assert_eq!( - forward(&mut engine, "empty.pop()"), + forward(&mut context, "empty.pop()"), String::from("undefined") ); - assert_eq!(forward(&mut engine, "one.pop()"), "1"); - assert_eq!(forward(&mut engine, "one.length"), "0"); - assert_eq!(forward(&mut engine, "many.pop()"), "4"); - assert_eq!(forward(&mut engine, "many[0]"), "1"); - assert_eq!(forward(&mut engine, "many.length"), "3"); + assert_eq!(forward(&mut context, "one.pop()"), "1"); + assert_eq!(forward(&mut context, "one.length"), "0"); + assert_eq!(forward(&mut context, "many.pop()"), "4"); + assert_eq!(forward(&mut context, "many[0]"), "1"); + assert_eq!(forward(&mut context, "many.length"), "3"); } #[test] fn shift() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var empty = [ ]; var one = [1]; var many = [1, 2, 3, 4]; "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); assert_eq!( - forward(&mut engine, "empty.shift()"), + forward(&mut context, "empty.shift()"), String::from("undefined") ); - assert_eq!(forward(&mut engine, "one.shift()"), "1"); - assert_eq!(forward(&mut engine, "one.length"), "0"); - assert_eq!(forward(&mut engine, "many.shift()"), "1"); - assert_eq!(forward(&mut engine, "many[0]"), "2"); - assert_eq!(forward(&mut engine, "many.length"), "3"); + assert_eq!(forward(&mut context, "one.shift()"), "1"); + assert_eq!(forward(&mut context, "one.length"), "0"); + assert_eq!(forward(&mut context, "many.shift()"), "1"); + assert_eq!(forward(&mut context, "many[0]"), "2"); + assert_eq!(forward(&mut context, "many.length"), "3"); } #[test] fn unshift() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var arr = [3, 4]; "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - assert_eq!(forward(&mut engine, "arr.unshift()"), "2"); - assert_eq!(forward(&mut engine, "arr.unshift(1, 2)"), "4"); - assert_eq!(forward(&mut engine, "arr[0]"), "1"); - assert_eq!(forward(&mut engine, "arr[1]"), "2"); + assert_eq!(forward(&mut context, "arr.unshift()"), "2"); + assert_eq!(forward(&mut context, "arr.unshift(1, 2)"), "4"); + assert_eq!(forward(&mut context, "arr[0]"), "1"); + assert_eq!(forward(&mut context, "arr[1]"), "2"); } #[test] fn reverse() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var arr = [1, 2]; var reversed = arr.reverse(); "#; - eprintln!("{}", forward(&mut engine, init)); - assert_eq!(forward(&mut engine, "reversed[0]"), "2"); - assert_eq!(forward(&mut engine, "reversed[1]"), "1"); - assert_eq!(forward(&mut engine, "arr[0]"), "2"); - assert_eq!(forward(&mut engine, "arr[1]"), "1"); + eprintln!("{}", forward(&mut context, init)); + assert_eq!(forward(&mut context, "reversed[0]"), "2"); + assert_eq!(forward(&mut context, "reversed[1]"), "1"); + assert_eq!(forward(&mut context, "arr[0]"), "2"); + assert_eq!(forward(&mut context, "arr[1]"), "1"); } #[test] fn index_of() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var empty = [ ]; var one = ["a"]; var many = ["a", "b", "c"]; var duplicates = ["a", "b", "c", "a", "b"]; "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); // Empty - let empty = forward(&mut engine, "empty.indexOf('a')"); + let empty = forward(&mut context, "empty.indexOf('a')"); assert_eq!(empty, String::from("-1")); // One - let one = forward(&mut engine, "one.indexOf('a')"); + let one = forward(&mut context, "one.indexOf('a')"); assert_eq!(one, String::from("0")); // Missing from one - let missing_from_one = forward(&mut engine, "one.indexOf('b')"); + let missing_from_one = forward(&mut context, "one.indexOf('b')"); assert_eq!(missing_from_one, String::from("-1")); // First in many - let first_in_many = forward(&mut engine, "many.indexOf('a')"); + let first_in_many = forward(&mut context, "many.indexOf('a')"); assert_eq!(first_in_many, String::from("0")); // Second in many - let second_in_many = forward(&mut engine, "many.indexOf('b')"); + let second_in_many = forward(&mut context, "many.indexOf('b')"); assert_eq!(second_in_many, String::from("1")); // First in duplicates - let first_in_many = forward(&mut engine, "duplicates.indexOf('a')"); + let first_in_many = forward(&mut context, "duplicates.indexOf('a')"); assert_eq!(first_in_many, String::from("0")); // Second in duplicates - let second_in_many = forward(&mut engine, "duplicates.indexOf('b')"); + let second_in_many = forward(&mut context, "duplicates.indexOf('b')"); assert_eq!(second_in_many, String::from("1")); // Positive fromIndex greater than array length - let fromindex_greater_than_length = forward(&mut engine, "one.indexOf('a', 2)"); + let fromindex_greater_than_length = forward(&mut context, "one.indexOf('a', 2)"); assert_eq!(fromindex_greater_than_length, String::from("-1")); // Positive fromIndex missed match - let fromindex_misses_match = forward(&mut engine, "many.indexOf('a', 1)"); + let fromindex_misses_match = forward(&mut context, "many.indexOf('a', 1)"); assert_eq!(fromindex_misses_match, String::from("-1")); // Positive fromIndex matched - let fromindex_matches = forward(&mut engine, "many.indexOf('b', 1)"); + let fromindex_matches = forward(&mut context, "many.indexOf('b', 1)"); assert_eq!(fromindex_matches, String::from("1")); // Positive fromIndex with duplicates - let first_in_many = forward(&mut engine, "duplicates.indexOf('a', 1)"); + let first_in_many = forward(&mut context, "duplicates.indexOf('a', 1)"); assert_eq!(first_in_many, String::from("3")); // Negative fromIndex greater than array length - let fromindex_greater_than_length = forward(&mut engine, "one.indexOf('a', -2)"); + let fromindex_greater_than_length = forward(&mut context, "one.indexOf('a', -2)"); assert_eq!(fromindex_greater_than_length, String::from("0")); // Negative fromIndex missed match - let fromindex_misses_match = forward(&mut engine, "many.indexOf('b', -1)"); + let fromindex_misses_match = forward(&mut context, "many.indexOf('b', -1)"); assert_eq!(fromindex_misses_match, String::from("-1")); // Negative fromIndex matched - let fromindex_matches = forward(&mut engine, "many.indexOf('c', -1)"); + let fromindex_matches = forward(&mut context, "many.indexOf('c', -1)"); assert_eq!(fromindex_matches, String::from("2")); // Negative fromIndex with duplicates - let second_in_many = forward(&mut engine, "duplicates.indexOf('b', -2)"); + let second_in_many = forward(&mut context, "duplicates.indexOf('b', -2)"); assert_eq!(second_in_many, String::from("4")); } #[test] fn last_index_of() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var empty = [ ]; var one = ["a"]; var many = ["a", "b", "c"]; var duplicates = ["a", "b", "c", "a", "b"]; "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); // Empty - let empty = forward(&mut engine, "empty.lastIndexOf('a')"); + let empty = forward(&mut context, "empty.lastIndexOf('a')"); assert_eq!(empty, String::from("-1")); // One - let one = forward(&mut engine, "one.lastIndexOf('a')"); + let one = forward(&mut context, "one.lastIndexOf('a')"); assert_eq!(one, String::from("0")); // Missing from one - let missing_from_one = forward(&mut engine, "one.lastIndexOf('b')"); + let missing_from_one = forward(&mut context, "one.lastIndexOf('b')"); assert_eq!(missing_from_one, String::from("-1")); // First in many - let first_in_many = forward(&mut engine, "many.lastIndexOf('a')"); + let first_in_many = forward(&mut context, "many.lastIndexOf('a')"); assert_eq!(first_in_many, String::from("0")); // Second in many - let second_in_many = forward(&mut engine, "many.lastIndexOf('b')"); + let second_in_many = forward(&mut context, "many.lastIndexOf('b')"); assert_eq!(second_in_many, String::from("1")); // 4th in duplicates - let first_in_many = forward(&mut engine, "duplicates.lastIndexOf('a')"); + let first_in_many = forward(&mut context, "duplicates.lastIndexOf('a')"); assert_eq!(first_in_many, String::from("3")); // 5th in duplicates - let second_in_many = forward(&mut engine, "duplicates.lastIndexOf('b')"); + let second_in_many = forward(&mut context, "duplicates.lastIndexOf('b')"); assert_eq!(second_in_many, String::from("4")); // Positive fromIndex greater than array length - let fromindex_greater_than_length = forward(&mut engine, "one.lastIndexOf('a', 2)"); + let fromindex_greater_than_length = forward(&mut context, "one.lastIndexOf('a', 2)"); assert_eq!(fromindex_greater_than_length, String::from("0")); // Positive fromIndex missed match - let fromindex_misses_match = forward(&mut engine, "many.lastIndexOf('c', 1)"); + let fromindex_misses_match = forward(&mut context, "many.lastIndexOf('c', 1)"); assert_eq!(fromindex_misses_match, String::from("-1")); // Positive fromIndex matched - let fromindex_matches = forward(&mut engine, "many.lastIndexOf('b', 1)"); + let fromindex_matches = forward(&mut context, "many.lastIndexOf('b', 1)"); assert_eq!(fromindex_matches, String::from("1")); // Positive fromIndex with duplicates - let first_in_many = forward(&mut engine, "duplicates.lastIndexOf('a', 1)"); + let first_in_many = forward(&mut context, "duplicates.lastIndexOf('a', 1)"); assert_eq!(first_in_many, String::from("0")); // Negative fromIndex greater than array length - let fromindex_greater_than_length = forward(&mut engine, "one.lastIndexOf('a', -2)"); + let fromindex_greater_than_length = forward(&mut context, "one.lastIndexOf('a', -2)"); assert_eq!(fromindex_greater_than_length, String::from("-1")); // Negative fromIndex missed match - let fromindex_misses_match = forward(&mut engine, "many.lastIndexOf('c', -2)"); + let fromindex_misses_match = forward(&mut context, "many.lastIndexOf('c', -2)"); assert_eq!(fromindex_misses_match, String::from("-1")); // Negative fromIndex matched - let fromindex_matches = forward(&mut engine, "many.lastIndexOf('c', -1)"); + let fromindex_matches = forward(&mut context, "many.lastIndexOf('c', -1)"); assert_eq!(fromindex_matches, String::from("2")); // Negative fromIndex with duplicates - let second_in_many = forward(&mut engine, "duplicates.lastIndexOf('b', -2)"); + let second_in_many = forward(&mut context, "duplicates.lastIndexOf('b', -2)"); assert_eq!(second_in_many, String::from("1")); } #[test] fn fill_obj_ref() { - let mut engine = Context::new(); + let mut context = Context::new(); // test object reference - forward(&mut engine, "a = (new Array(3)).fill({});"); - forward(&mut engine, "a[0].hi = 'hi';"); - assert_eq!(forward(&mut engine, "a[0].hi"), "\"hi\""); + forward(&mut context, "a = (new Array(3)).fill({});"); + forward(&mut context, "a[0].hi = 'hi';"); + assert_eq!(forward(&mut context, "a[0].hi"), "\"hi\""); } #[test] fn fill() { - let mut engine = Context::new(); + let mut context = Context::new(); - forward(&mut engine, "var a = [1, 2, 3];"); + forward(&mut context, "var a = [1, 2, 3];"); assert_eq!( - forward(&mut engine, "a.fill(4).join()"), + forward(&mut context, "a.fill(4).join()"), String::from("\"4,4,4\"") ); // make sure the array is modified - assert_eq!(forward(&mut engine, "a.join()"), String::from("\"4,4,4\"")); + assert_eq!(forward(&mut context, "a.join()"), String::from("\"4,4,4\"")); - forward(&mut engine, "a = [1, 2, 3];"); + forward(&mut context, "a = [1, 2, 3];"); assert_eq!( - forward(&mut engine, "a.fill(4, '1').join()"), + forward(&mut context, "a.fill(4, '1').join()"), String::from("\"1,4,4\"") ); - forward(&mut engine, "a = [1, 2, 3];"); + forward(&mut context, "a = [1, 2, 3];"); assert_eq!( - forward(&mut engine, "a.fill(4, 1, 2).join()"), + forward(&mut context, "a.fill(4, 1, 2).join()"), String::from("\"1,4,3\"") ); - forward(&mut engine, "a = [1, 2, 3];"); + forward(&mut context, "a = [1, 2, 3];"); assert_eq!( - forward(&mut engine, "a.fill(4, 1, 1).join()"), + forward(&mut context, "a.fill(4, 1, 1).join()"), String::from("\"1,2,3\"") ); - forward(&mut engine, "a = [1, 2, 3];"); + forward(&mut context, "a = [1, 2, 3];"); assert_eq!( - forward(&mut engine, "a.fill(4, 3, 3).join()"), + forward(&mut context, "a.fill(4, 3, 3).join()"), String::from("\"1,2,3\"") ); - forward(&mut engine, "a = [1, 2, 3];"); + forward(&mut context, "a = [1, 2, 3];"); assert_eq!( - forward(&mut engine, "a.fill(4, -3, -2).join()"), + forward(&mut context, "a.fill(4, -3, -2).join()"), String::from("\"4,2,3\"") ); - forward(&mut engine, "a = [1, 2, 3];"); + forward(&mut context, "a = [1, 2, 3];"); assert_eq!( - forward(&mut engine, "a.fill(4, NaN, NaN).join()"), + forward(&mut context, "a.fill(4, NaN, NaN).join()"), String::from("\"1,2,3\"") ); - forward(&mut engine, "a = [1, 2, 3];"); + forward(&mut context, "a = [1, 2, 3];"); assert_eq!( - forward(&mut engine, "a.fill(4, 3, 5).join()"), + forward(&mut context, "a.fill(4, 3, 5).join()"), String::from("\"1,2,3\"") ); - forward(&mut engine, "a = [1, 2, 3];"); + forward(&mut context, "a = [1, 2, 3];"); assert_eq!( - forward(&mut engine, "a.fill(4, '1.2', '2.5').join()"), + forward(&mut context, "a.fill(4, '1.2', '2.5').join()"), String::from("\"1,4,3\"") ); - forward(&mut engine, "a = [1, 2, 3];"); + forward(&mut context, "a = [1, 2, 3];"); assert_eq!( - forward(&mut engine, "a.fill(4, 'str').join()"), + forward(&mut context, "a.fill(4, 'str').join()"), String::from("\"4,4,4\"") ); - forward(&mut engine, "a = [1, 2, 3];"); + forward(&mut context, "a = [1, 2, 3];"); assert_eq!( - forward(&mut engine, "a.fill(4, 'str', 'str').join()"), + forward(&mut context, "a.fill(4, 'str', 'str').join()"), String::from("\"1,2,3\"") ); - forward(&mut engine, "a = [1, 2, 3];"); + forward(&mut context, "a = [1, 2, 3];"); assert_eq!( - forward(&mut engine, "a.fill(4, undefined, null).join()"), + forward(&mut context, "a.fill(4, undefined, null).join()"), String::from("\"1,2,3\"") ); - forward(&mut engine, "a = [1, 2, 3];"); + forward(&mut context, "a = [1, 2, 3];"); assert_eq!( - forward(&mut engine, "a.fill(4, undefined, undefined).join()"), + forward(&mut context, "a.fill(4, undefined, undefined).join()"), String::from("\"4,4,4\"") ); assert_eq!( - forward(&mut engine, "a.fill().join()"), + forward(&mut context, "a.fill().join()"), String::from("\"undefined,undefined,undefined\"") ); // test object reference - forward(&mut engine, "a = (new Array(3)).fill({});"); - forward(&mut engine, "a[0].hi = 'hi';"); - assert_eq!(forward(&mut engine, "a[0].hi"), String::from("\"hi\"")); + forward(&mut context, "a = (new Array(3)).fill({});"); + forward(&mut context, "a[0].hi = 'hi';"); + assert_eq!(forward(&mut context, "a[0].hi"), String::from("\"hi\"")); } #[test] fn includes_value() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var empty = [ ]; var one = ["a"]; @@ -554,37 +554,37 @@ fn includes_value() { var duplicates = ["a", "b", "c", "a", "b"]; var undefined = [undefined]; "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); // Empty - let empty = forward(&mut engine, "empty.includes('a')"); + let empty = forward(&mut context, "empty.includes('a')"); assert_eq!(empty, String::from("false")); // One - let one = forward(&mut engine, "one.includes('a')"); + let one = forward(&mut context, "one.includes('a')"); assert_eq!(one, String::from("true")); // Missing from one - let missing_from_one = forward(&mut engine, "one.includes('b')"); + let missing_from_one = forward(&mut context, "one.includes('b')"); assert_eq!(missing_from_one, String::from("false")); // In many - let first_in_many = forward(&mut engine, "many.includes('c')"); + let first_in_many = forward(&mut context, "many.includes('c')"); assert_eq!(first_in_many, String::from("true")); // Missing from many - let second_in_many = forward(&mut engine, "many.includes('d')"); + let second_in_many = forward(&mut context, "many.includes('d')"); assert_eq!(second_in_many, String::from("false")); // In duplicates - let first_in_many = forward(&mut engine, "duplicates.includes('a')"); + let first_in_many = forward(&mut context, "duplicates.includes('a')"); assert_eq!(first_in_many, String::from("true")); // Missing from duplicates - let second_in_many = forward(&mut engine, "duplicates.includes('d')"); + let second_in_many = forward(&mut context, "duplicates.includes('d')"); assert_eq!(second_in_many, String::from("false")); } #[test] fn map() { - let mut engine = Context::new(); + let mut context = Context::new(); let js = r#" var empty = []; @@ -603,37 +603,40 @@ fn map() { var many_mapped = many.map(v => '_' + v + '_'); "#; - forward(&mut engine, js); + forward(&mut context, js); // assert the old arrays have not been modified - assert_eq!(forward(&mut engine, "one[0]"), String::from("\"x\"")); + assert_eq!(forward(&mut context, "one[0]"), String::from("\"x\"")); assert_eq!( - forward(&mut engine, "many[2] + many[1] + many[0]"), + forward(&mut context, "many[2] + many[1] + many[0]"), String::from("\"zyx\"") ); // NB: These tests need to be rewritten once `Display` has been implemented for `Array` // Empty assert_eq!( - forward(&mut engine, "empty_mapped.length"), + forward(&mut context, "empty_mapped.length"), String::from("0") ); // One - assert_eq!(forward(&mut engine, "one_mapped.length"), String::from("1")); assert_eq!( - forward(&mut engine, "one_mapped[0]"), + forward(&mut context, "one_mapped.length"), + String::from("1") + ); + assert_eq!( + forward(&mut context, "one_mapped[0]"), String::from("\"_x\"") ); // Many assert_eq!( - forward(&mut engine, "many_mapped.length"), + forward(&mut context, "many_mapped.length"), String::from("3") ); assert_eq!( forward( - &mut engine, + &mut context, "many_mapped[0] + many_mapped[1] + many_mapped[2]" ), String::from("\"_x__y__z_\"") @@ -641,13 +644,13 @@ fn map() { // TODO: uncomment when `this` has been implemented // One but it uses `this` inside the callback - // let one_with_this = forward(&mut engine, "one.map(callbackThatUsesThis, _this)[0];"); + // let one_with_this = forward(&mut context, "one.map(callbackThatUsesThis, _this)[0];"); // assert_eq!(one_with_this, String::from("The answer to life is: 42")) } #[test] fn slice() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var empty = [ ].slice(); var one = ["a"].slice(); @@ -655,22 +658,22 @@ fn slice() { var many2 = ["a", "b", "c", "d"].slice(2, 3); var many3 = ["a", "b", "c", "d"].slice(7); "#; - eprintln!("{}", forward(&mut engine, init)); - - assert_eq!(forward(&mut engine, "empty.length"), "0"); - assert_eq!(forward(&mut engine, "one[0]"), "\"a\""); - assert_eq!(forward(&mut engine, "many1[0]"), "\"b\""); - assert_eq!(forward(&mut engine, "many1[1]"), "\"c\""); - assert_eq!(forward(&mut engine, "many1[2]"), "\"d\""); - assert_eq!(forward(&mut engine, "many1.length"), "3"); - assert_eq!(forward(&mut engine, "many2[0]"), "\"c\""); - assert_eq!(forward(&mut engine, "many2.length"), "1"); - assert_eq!(forward(&mut engine, "many3.length"), "0"); + eprintln!("{}", forward(&mut context, init)); + + assert_eq!(forward(&mut context, "empty.length"), "0"); + assert_eq!(forward(&mut context, "one[0]"), "\"a\""); + assert_eq!(forward(&mut context, "many1[0]"), "\"b\""); + assert_eq!(forward(&mut context, "many1[1]"), "\"c\""); + assert_eq!(forward(&mut context, "many1[2]"), "\"d\""); + assert_eq!(forward(&mut context, "many1.length"), "3"); + assert_eq!(forward(&mut context, "many2[0]"), "\"c\""); + assert_eq!(forward(&mut context, "many2.length"), "1"); + assert_eq!(forward(&mut context, "many3.length"), "0"); } #[test] fn for_each() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = [2, 3, 4, 5]; var sum = 0; @@ -683,16 +686,16 @@ fn for_each() { } a.forEach(callingCallback); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - assert_eq!(forward(&mut engine, "sum"), "14"); - assert_eq!(forward(&mut engine, "indexSum"), "6"); - assert_eq!(forward(&mut engine, "listLengthSum"), "16"); + assert_eq!(forward(&mut context, "sum"), "14"); + assert_eq!(forward(&mut context, "indexSum"), "6"); + assert_eq!(forward(&mut context, "listLengthSum"), "16"); } #[test] fn for_each_push_value() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = [1, 2, 3, 4]; function callingCallback(item, index, list) { @@ -700,19 +703,19 @@ fn for_each_push_value() { } a.forEach(callingCallback); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); // [ 1, 2, 3, 4, 2, 4, 6, 8 ] - assert_eq!(forward(&mut engine, "a.length"), "8"); - assert_eq!(forward(&mut engine, "a[4]"), "2"); - assert_eq!(forward(&mut engine, "a[5]"), "4"); - assert_eq!(forward(&mut engine, "a[6]"), "6"); - assert_eq!(forward(&mut engine, "a[7]"), "8"); + assert_eq!(forward(&mut context, "a.length"), "8"); + assert_eq!(forward(&mut context, "a[4]"), "2"); + assert_eq!(forward(&mut context, "a[5]"), "4"); + assert_eq!(forward(&mut context, "a[6]"), "6"); + assert_eq!(forward(&mut context, "a[7]"), "8"); } #[test] fn filter() { - let mut engine = Context::new(); + let mut context = Context::new(); let js = r#" var empty = []; @@ -726,62 +729,62 @@ fn filter() { var many_zero_filtered = many.filter(v => v === "0"); "#; - forward(&mut engine, js); + forward(&mut context, js); // assert the old arrays have not been modified - assert_eq!(forward(&mut engine, "one[0]"), String::from("\"1\"")); + assert_eq!(forward(&mut context, "one[0]"), String::from("\"1\"")); assert_eq!( - forward(&mut engine, "many[2] + many[1] + many[0]"), + forward(&mut context, "many[2] + many[1] + many[0]"), String::from("\"101\"") ); // NB: These tests need to be rewritten once `Display` has been implemented for `Array` // Empty assert_eq!( - forward(&mut engine, "empty_filtered.length"), + forward(&mut context, "empty_filtered.length"), String::from("0") ); // One filtered on "1" assert_eq!( - forward(&mut engine, "one_filtered.length"), + forward(&mut context, "one_filtered.length"), String::from("1") ); assert_eq!( - forward(&mut engine, "one_filtered[0]"), + forward(&mut context, "one_filtered[0]"), String::from("\"1\"") ); // One filtered on "0" assert_eq!( - forward(&mut engine, "zero_filtered.length"), + forward(&mut context, "zero_filtered.length"), String::from("0") ); // Many filtered on "1" assert_eq!( - forward(&mut engine, "many_one_filtered.length"), + forward(&mut context, "many_one_filtered.length"), String::from("2") ); assert_eq!( - forward(&mut engine, "many_one_filtered[0] + many_one_filtered[1]"), + forward(&mut context, "many_one_filtered[0] + many_one_filtered[1]"), String::from("\"11\"") ); // Many filtered on "0" assert_eq!( - forward(&mut engine, "many_zero_filtered.length"), + forward(&mut context, "many_zero_filtered.length"), String::from("1") ); assert_eq!( - forward(&mut engine, "many_zero_filtered[0]"), + forward(&mut context, "many_zero_filtered[0]"), String::from("\"0\"") ); } #[test] fn some() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var empty = []; @@ -806,30 +809,30 @@ fn some() { return elem < 3; } "#; - forward(&mut engine, init); - let result = forward(&mut engine, "array.some(lessThan10);"); + forward(&mut context, init); + let result = forward(&mut context, "array.some(lessThan10);"); assert_eq!(result, "true"); - let result = forward(&mut engine, "empty.some(lessThan10);"); + let result = forward(&mut context, "empty.some(lessThan10);"); assert_eq!(result, "false"); - let result = forward(&mut engine, "array.some(greaterThan10);"); + let result = forward(&mut context, "array.some(greaterThan10);"); assert_eq!(result, "false"); - let result = forward(&mut engine, "appendArray.some(appendingCallback);"); - let append_array_length = forward(&mut engine, "appendArray.length"); + let result = forward(&mut context, "appendArray.some(appendingCallback);"); + let append_array_length = forward(&mut context, "appendArray.length"); assert_eq!(append_array_length, "5"); assert_eq!(result, "true"); - let result = forward(&mut engine, "delArray.some(deletingCallback);"); - let del_array_length = forward(&mut engine, "delArray.length"); + let result = forward(&mut context, "delArray.some(deletingCallback);"); + let del_array_length = forward(&mut context, "delArray.length"); assert_eq!(del_array_length, "3"); assert_eq!(result, "true"); } #[test] fn reduce() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var arr = [1, 2, 3, 4]; @@ -857,39 +860,39 @@ fn reduce() { delete delArray[3]; "#; - forward(&mut engine, init); + forward(&mut context, init); // empty array - let result = forward(&mut engine, "[].reduce(add, 0)"); + let result = forward(&mut context, "[].reduce(add, 0)"); assert_eq!(result, "0"); // simple with initial value - let result = forward(&mut engine, "arr.reduce(add, 0)"); + let result = forward(&mut context, "arr.reduce(add, 0)"); assert_eq!(result, "10"); // without initial value - let result = forward(&mut engine, "arr.reduce(add)"); + let result = forward(&mut context, "arr.reduce(add)"); assert_eq!(result, "10"); // with some items missing - let result = forward(&mut engine, "delArray.reduce(add, 0)"); + let result = forward(&mut context, "delArray.reduce(add, 0)"); assert_eq!(result, "8"); // with index - let result = forward(&mut engine, "arr.reduce(addIdx, 0)"); + let result = forward(&mut context, "arr.reduce(addIdx, 0)"); assert_eq!(result, "6"); // with array - let result = forward(&mut engine, "arr.reduce(addLen, 0)"); + let result = forward(&mut context, "arr.reduce(addLen, 0)"); assert_eq!(result, "16"); // resizing the array as reduce progresses - let result = forward(&mut engine, "arr.reduce(addResize, 0)"); + let result = forward(&mut context, "arr.reduce(addResize, 0)"); assert_eq!(result, "6"); // Empty array let result = forward( - &mut engine, + &mut context, r#" try { [].reduce((acc, x) => acc + x); @@ -905,7 +908,7 @@ fn reduce() { // Array with no defined elements let result = forward( - &mut engine, + &mut context, r#" try { var arr = [0, 1]; @@ -924,7 +927,7 @@ fn reduce() { // No callback let result = forward( - &mut engine, + &mut context, r#" try { arr.reduce(""); @@ -938,7 +941,7 @@ fn reduce() { #[test] fn reduce_right() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var arr = [1, 2, 3, 4]; @@ -972,46 +975,46 @@ fn reduce_right() { delete delArray[3]; "#; - forward(&mut engine, init); + forward(&mut context, init); // empty array - let result = forward(&mut engine, "[].reduceRight(sub, 0)"); + let result = forward(&mut context, "[].reduceRight(sub, 0)"); assert_eq!(result, "0"); // simple with initial value - let result = forward(&mut engine, "arr.reduceRight(sub, 0)"); + let result = forward(&mut context, "arr.reduceRight(sub, 0)"); assert_eq!(result, "-10"); // without initial value - let result = forward(&mut engine, "arr.reduceRight(sub)"); + let result = forward(&mut context, "arr.reduceRight(sub)"); assert_eq!(result, "-2"); // with some items missing - let result = forward(&mut engine, "delArray.reduceRight(sub, 0)"); + let result = forward(&mut context, "delArray.reduceRight(sub, 0)"); assert_eq!(result, "-8"); // with index - let result = forward(&mut engine, "arr.reduceRight(subIdx)"); + let result = forward(&mut context, "arr.reduceRight(subIdx)"); assert_eq!(result, "1"); // with array - let result = forward(&mut engine, "arr.reduceRight(subLen)"); + let result = forward(&mut context, "arr.reduceRight(subLen)"); assert_eq!(result, "-8"); // resizing the array as reduce progresses - let result = forward(&mut engine, "arr.reduceRight(subResize, 0)"); + let result = forward(&mut context, "arr.reduceRight(subResize, 0)"); assert_eq!(result, "-5"); // reset array - forward(&mut engine, "arr = [1, 2, 3, 4];"); + forward(&mut context, "arr = [1, 2, 3, 4];"); // resizing the array to 0 as reduce progresses - let result = forward(&mut engine, "arr.reduceRight(subResize0, 0)"); + let result = forward(&mut context, "arr.reduceRight(subResize0, 0)"); assert_eq!(result, "-7"); // Empty array let result = forward( - &mut engine, + &mut context, r#" try { [].reduceRight((acc, x) => acc + x); @@ -1027,7 +1030,7 @@ fn reduce_right() { // Array with no defined elements let result = forward( - &mut engine, + &mut context, r#" try { var arr = [0, 1]; @@ -1046,7 +1049,7 @@ fn reduce_right() { // No callback let result = forward( - &mut engine, + &mut context, r#" try { arr.reduceRight(""); @@ -1060,7 +1063,7 @@ fn reduce_right() { #[test] fn call_array_constructor_with_one_argument() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var empty = new Array(0); @@ -1068,163 +1071,163 @@ fn call_array_constructor_with_one_argument() { var one = new Array("Hello, world!"); "#; - forward(&mut engine, init); - // let result = forward(&mut engine, "empty.length"); + forward(&mut context, init); + // let result = forward(&mut context, "empty.length"); // assert_eq!(result, "0"); - // let result = forward(&mut engine, "five.length"); + // let result = forward(&mut context, "five.length"); // assert_eq!(result, "5"); - // let result = forward(&mut engine, "one.length"); + // let result = forward(&mut context, "one.length"); // assert_eq!(result, "1"); } #[test] fn array_values_simple() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var iterator = [1, 2, 3].values(); var next = iterator.next(); "#; - forward(&mut engine, init); - assert_eq!(forward(&mut engine, "next.value"), "1"); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iterator.next()"); - assert_eq!(forward(&mut engine, "next.value"), "2"); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iterator.next()"); - assert_eq!(forward(&mut engine, "next.value"), "3"); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iterator.next()"); - assert_eq!(forward(&mut engine, "next.value"), "undefined"); - assert_eq!(forward(&mut engine, "next.done"), "true"); + forward(&mut context, init); + assert_eq!(forward(&mut context, "next.value"), "1"); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iterator.next()"); + assert_eq!(forward(&mut context, "next.value"), "2"); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iterator.next()"); + assert_eq!(forward(&mut context, "next.value"), "3"); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iterator.next()"); + assert_eq!(forward(&mut context, "next.value"), "undefined"); + assert_eq!(forward(&mut context, "next.done"), "true"); } #[test] fn array_keys_simple() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var iterator = [1, 2, 3].keys(); var next = iterator.next(); "#; - forward(&mut engine, init); - assert_eq!(forward(&mut engine, "next.value"), "0"); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iterator.next()"); - assert_eq!(forward(&mut engine, "next.value"), "1"); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iterator.next()"); - assert_eq!(forward(&mut engine, "next.value"), "2"); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iterator.next()"); - assert_eq!(forward(&mut engine, "next.value"), "undefined"); - assert_eq!(forward(&mut engine, "next.done"), "true"); + forward(&mut context, init); + assert_eq!(forward(&mut context, "next.value"), "0"); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iterator.next()"); + assert_eq!(forward(&mut context, "next.value"), "1"); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iterator.next()"); + assert_eq!(forward(&mut context, "next.value"), "2"); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iterator.next()"); + assert_eq!(forward(&mut context, "next.value"), "undefined"); + assert_eq!(forward(&mut context, "next.done"), "true"); } #[test] fn array_entries_simple() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var iterator = [1, 2, 3].entries(); var next = iterator.next(); "#; - forward(&mut engine, init); - assert_eq!(forward(&mut engine, "next.value"), "[ 0, 1 ]"); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iterator.next()"); - assert_eq!(forward(&mut engine, "next.value"), "[ 1, 2 ]"); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iterator.next()"); - assert_eq!(forward(&mut engine, "next.value"), "[ 2, 3 ]"); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iterator.next()"); - assert_eq!(forward(&mut engine, "next.value"), "undefined"); - assert_eq!(forward(&mut engine, "next.done"), "true"); + forward(&mut context, init); + assert_eq!(forward(&mut context, "next.value"), "[ 0, 1 ]"); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iterator.next()"); + assert_eq!(forward(&mut context, "next.value"), "[ 1, 2 ]"); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iterator.next()"); + assert_eq!(forward(&mut context, "next.value"), "[ 2, 3 ]"); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iterator.next()"); + assert_eq!(forward(&mut context, "next.value"), "undefined"); + assert_eq!(forward(&mut context, "next.done"), "true"); } #[test] fn array_values_empty() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var iterator = [].values(); var next = iterator.next(); "#; - forward(&mut engine, init); - assert_eq!(forward(&mut engine, "next.value"), "undefined"); - assert_eq!(forward(&mut engine, "next.done"), "true"); + forward(&mut context, init); + assert_eq!(forward(&mut context, "next.value"), "undefined"); + assert_eq!(forward(&mut context, "next.done"), "true"); } #[test] fn array_values_sparse() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var array = Array(); array[3] = 5; var iterator = array.values(); var next = iterator.next(); "#; - forward(&mut engine, init); - assert_eq!(forward(&mut engine, "next.value"), "undefined"); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iterator.next()"); - assert_eq!(forward(&mut engine, "next.value"), "undefined"); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iterator.next()"); - assert_eq!(forward(&mut engine, "next.value"), "undefined"); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iterator.next()"); - assert_eq!(forward(&mut engine, "next.value"), "5"); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iterator.next()"); - assert_eq!(forward(&mut engine, "next.value"), "undefined"); - assert_eq!(forward(&mut engine, "next.done"), "true"); + forward(&mut context, init); + assert_eq!(forward(&mut context, "next.value"), "undefined"); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iterator.next()"); + assert_eq!(forward(&mut context, "next.value"), "undefined"); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iterator.next()"); + assert_eq!(forward(&mut context, "next.value"), "undefined"); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iterator.next()"); + assert_eq!(forward(&mut context, "next.value"), "5"); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iterator.next()"); + assert_eq!(forward(&mut context, "next.value"), "undefined"); + assert_eq!(forward(&mut context, "next.done"), "true"); } #[test] fn array_symbol_iterator() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var iterator = [1, 2, 3][Symbol.iterator](); var next = iterator.next(); "#; - forward(&mut engine, init); - assert_eq!(forward(&mut engine, "next.value"), "1"); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iterator.next()"); - assert_eq!(forward(&mut engine, "next.value"), "2"); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iterator.next()"); - assert_eq!(forward(&mut engine, "next.value"), "3"); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iterator.next()"); - assert_eq!(forward(&mut engine, "next.value"), "undefined"); - assert_eq!(forward(&mut engine, "next.done"), "true"); + forward(&mut context, init); + assert_eq!(forward(&mut context, "next.value"), "1"); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iterator.next()"); + assert_eq!(forward(&mut context, "next.value"), "2"); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iterator.next()"); + assert_eq!(forward(&mut context, "next.value"), "3"); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iterator.next()"); + assert_eq!(forward(&mut context, "next.value"), "undefined"); + assert_eq!(forward(&mut context, "next.done"), "true"); } #[test] fn array_values_symbol_iterator() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var iterator = [1, 2, 3].values(); iterator === iterator[Symbol.iterator](); "#; - assert_eq!(forward(&mut engine, init), "true"); + assert_eq!(forward(&mut context, init), "true"); } #[test] fn array_spread_arrays() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" const array1 = [2, 3]; const array2 = [1, ...array1]; array2[0] === 1 && array2[1] === 2 && array2[2] === 3; "#; - assert_eq!(forward(&mut engine, init), "true"); + assert_eq!(forward(&mut context, init), "true"); } #[test] fn array_spread_non_iterable() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" try { const array2 = [...5]; @@ -1232,5 +1235,5 @@ fn array_spread_non_iterable() { err.name === "TypeError" && err.message === "Not an iterable" } "#; - assert_eq!(forward(&mut engine, init), "true"); + assert_eq!(forward(&mut context, init), "true"); } diff --git a/boa/src/builtins/bigint/mod.rs b/boa/src/builtins/bigint/mod.rs index 94570ba253..8875be6747 100644 --- a/boa/src/builtins/bigint/mod.rs +++ b/boa/src/builtins/bigint/mod.rs @@ -14,14 +14,13 @@ use crate::{ builtins::BuiltIn, + gc::{empty_trace, Finalize, Trace}, object::{ConstructorBuilder, ObjectData}, property::Attribute, value::{RcBigInt, Value}, BoaProfiler, Context, Result, }; -use gc::{unsafe_empty_trace, Finalize, Trace}; - #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -103,7 +102,7 @@ impl BigInt { /// /// [spec]: https://tc39.es/ecma262/#sec-thisbigintvalue #[inline] - fn this_bigint_value(value: &Value, ctx: &mut Context) -> Result { + fn this_bigint_value(value: &Value, context: &mut Context) -> Result { match value { // 1. If Type(value) is BigInt, return value. Value::BigInt(ref bigint) => return Ok(bigint.clone()), @@ -120,7 +119,7 @@ impl BigInt { } // 3. Throw a TypeError exception. - Err(ctx.construct_type_error("'this' is not a BigInt")) + Err(context.construct_type_error("'this' is not a BigInt")) } /// `BigInt.prototype.toString( [radix] )` @@ -134,18 +133,18 @@ 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 Context) -> Result { + pub(crate) fn to_string(this: &Value, args: &[Value], context: &mut Context) -> Result { let radix = if !args.is_empty() { - args[0].to_integer(ctx)? as i32 + args[0].to_integer(context)? as i32 } else { 10 }; if radix < 2 || radix > 36 { - return ctx + return context .throw_range_error("radix must be an integer at least 2 and no greater than 36"); } Ok(Value::from( - Self::this_bigint_value(this, ctx)?.to_string_radix(radix as u32), + Self::this_bigint_value(this, context)?.to_string_radix(radix as u32), )) } @@ -159,8 +158,8 @@ 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 Context) -> Result { - Ok(Value::from(Self::this_bigint_value(this, ctx)?)) + pub(crate) fn value_of(this: &Value, _: &[Value], context: &mut Context) -> Result { + Ok(Value::from(Self::this_bigint_value(this, context)?)) } /// `BigInt.asIntN()` @@ -170,8 +169,8 @@ 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 Context) -> Result { - let (modulo, bits) = Self::calculate_as_uint_n(args, ctx)?; + pub(crate) fn as_int_n(_: &Value, args: &[Value], context: &mut Context) -> Result { + let (modulo, bits) = Self::calculate_as_uint_n(args, context)?; if bits > 0 && modulo @@ -197,8 +196,8 @@ 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 Context) -> Result { - let (modulo, _) = Self::calculate_as_uint_n(args, ctx)?; + pub(crate) fn as_uint_n(_: &Value, args: &[Value], context: &mut Context) -> Result { + let (modulo, _) = Self::calculate_as_uint_n(args, context)?; Ok(Value::from(modulo)) } @@ -208,7 +207,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 Context) -> Result<(BigInt, u32)> { + fn calculate_as_uint_n(args: &[Value], context: &mut Context) -> Result<(BigInt, u32)> { use std::convert::TryFrom; let undefined_value = Value::undefined(); @@ -216,10 +215,10 @@ impl BigInt { let bits_arg = args.get(0).unwrap_or(&undefined_value); let bigint_arg = args.get(1).unwrap_or(&undefined_value); - let bits = bits_arg.to_index(ctx)?; + let bits = bits_arg.to_index(context)?; let bits = u32::try_from(bits).unwrap_or(u32::MAX); - let bigint = bigint_arg.to_bigint(ctx)?; + let bigint = bigint_arg.to_bigint(context)?; Ok(( bigint.as_inner().clone().mod_floor( @@ -237,5 +236,5 @@ unsafe impl Trace for BigInt { // BigInt type implements an empty trace becasue the inner structure // `num_bigint::BigInt` does not implement `Trace` trait. // If it did this would be unsound. - unsafe_empty_trace!(); + empty_trace!(); } diff --git a/boa/src/builtins/bigint/tests.rs b/boa/src/builtins/bigint/tests.rs index 06f4e726b2..0caf9b2ddf 100644 --- a/boa/src/builtins/bigint/tests.rs +++ b/boa/src/builtins/bigint/tests.rs @@ -2,84 +2,84 @@ use crate::{forward, Context}; #[test] fn equality() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(forward(&mut engine, "0n == 0n"), "true"); - assert_eq!(forward(&mut engine, "1n == 0n"), "false"); + assert_eq!(forward(&mut context, "0n == 0n"), "true"); + assert_eq!(forward(&mut context, "1n == 0n"), "false"); assert_eq!( forward( - &mut engine, + &mut context, "1000000000000000000000000000000000n == 1000000000000000000000000000000000n" ), "true" ); - assert_eq!(forward(&mut engine, "0n == ''"), "true"); - assert_eq!(forward(&mut engine, "100n == '100'"), "true"); - assert_eq!(forward(&mut engine, "100n == '100.5'"), "false"); + assert_eq!(forward(&mut context, "0n == ''"), "true"); + assert_eq!(forward(&mut context, "100n == '100'"), "true"); + assert_eq!(forward(&mut context, "100n == '100.5'"), "false"); assert_eq!( - forward(&mut engine, "10000000000000000n == '10000000000000000'"), + forward(&mut context, "10000000000000000n == '10000000000000000'"), "true" ); - assert_eq!(forward(&mut engine, "'' == 0n"), "true"); - assert_eq!(forward(&mut engine, "'100' == 100n"), "true"); - assert_eq!(forward(&mut engine, "'100.5' == 100n"), "false"); + assert_eq!(forward(&mut context, "'' == 0n"), "true"); + assert_eq!(forward(&mut context, "'100' == 100n"), "true"); + assert_eq!(forward(&mut context, "'100.5' == 100n"), "false"); assert_eq!( - forward(&mut engine, "'10000000000000000' == 10000000000000000n"), + forward(&mut context, "'10000000000000000' == 10000000000000000n"), "true" ); - assert_eq!(forward(&mut engine, "0n == 0"), "true"); - assert_eq!(forward(&mut engine, "0n == 0.0"), "true"); - assert_eq!(forward(&mut engine, "100n == 100"), "true"); - assert_eq!(forward(&mut engine, "100n == 100.0"), "true"); - assert_eq!(forward(&mut engine, "100n == '100.5'"), "false"); - assert_eq!(forward(&mut engine, "100n == '1005'"), "false"); + assert_eq!(forward(&mut context, "0n == 0"), "true"); + assert_eq!(forward(&mut context, "0n == 0.0"), "true"); + assert_eq!(forward(&mut context, "100n == 100"), "true"); + assert_eq!(forward(&mut context, "100n == 100.0"), "true"); + assert_eq!(forward(&mut context, "100n == '100.5'"), "false"); + assert_eq!(forward(&mut context, "100n == '1005'"), "false"); assert_eq!( - forward(&mut engine, "10000000000000000n == 10000000000000000"), + forward(&mut context, "10000000000000000n == 10000000000000000"), "true" ); - assert_eq!(forward(&mut engine, "0 == 0n"), "true"); - assert_eq!(forward(&mut engine, "0.0 == 0n"), "true"); - assert_eq!(forward(&mut engine, "100 == 100n"), "true"); - assert_eq!(forward(&mut engine, "100.0 == 100n"), "true"); - assert_eq!(forward(&mut engine, "100.5 == 100n"), "false"); - assert_eq!(forward(&mut engine, "1005 == 100n"), "false"); + assert_eq!(forward(&mut context, "0 == 0n"), "true"); + assert_eq!(forward(&mut context, "0.0 == 0n"), "true"); + assert_eq!(forward(&mut context, "100 == 100n"), "true"); + assert_eq!(forward(&mut context, "100.0 == 100n"), "true"); + assert_eq!(forward(&mut context, "100.5 == 100n"), "false"); + assert_eq!(forward(&mut context, "1005 == 100n"), "false"); assert_eq!( - forward(&mut engine, "10000000000000000 == 10000000000000000n"), + forward(&mut context, "10000000000000000 == 10000000000000000n"), "true" ); } #[test] fn bigint_function_conversion_from_integer() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(forward(&mut engine, "BigInt(1000)"), "1000n"); + assert_eq!(forward(&mut context, "BigInt(1000)"), "1000n"); assert_eq!( - forward(&mut engine, "BigInt(20000000000000000)"), + forward(&mut context, "BigInt(20000000000000000)"), "20000000000000000n" ); assert_eq!( - forward(&mut engine, "BigInt(1000000000000000000000000000000000)"), + forward(&mut context, "BigInt(1000000000000000000000000000000000)"), "999999999999999945575230987042816n" ); } #[test] fn bigint_function_conversion_from_rational() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(forward(&mut engine, "BigInt(0.0)"), "0n"); - assert_eq!(forward(&mut engine, "BigInt(1.0)"), "1n"); - assert_eq!(forward(&mut engine, "BigInt(10000.0)"), "10000n"); + assert_eq!(forward(&mut context, "BigInt(0.0)"), "0n"); + assert_eq!(forward(&mut context, "BigInt(1.0)"), "1n"); + assert_eq!(forward(&mut context, "BigInt(10000.0)"), "10000n"); } #[test] fn bigint_function_conversion_from_rational_with_fractional_part() { - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = r#" try { @@ -89,14 +89,14 @@ fn bigint_function_conversion_from_rational_with_fractional_part() { } "#; assert_eq!( - forward(&mut engine, scenario), + forward(&mut context, scenario), "\"TypeError: The number 0.1 cannot be converted to a BigInt because it is not an integer\"" ); } #[test] fn bigint_function_conversion_from_null() { - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = r#" try { @@ -106,14 +106,14 @@ fn bigint_function_conversion_from_null() { } "#; assert_eq!( - forward(&mut engine, scenario), + forward(&mut context, scenario), "\"TypeError: cannot convert null to a BigInt\"" ); } #[test] fn bigint_function_conversion_from_undefined() { - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = r#" try { @@ -123,178 +123,178 @@ fn bigint_function_conversion_from_undefined() { } "#; assert_eq!( - forward(&mut engine, scenario), + forward(&mut context, scenario), "\"TypeError: cannot convert undefined to a BigInt\"" ); } #[test] fn bigint_function_conversion_from_string() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(forward(&mut engine, "BigInt('')"), "0n"); - assert_eq!(forward(&mut engine, "BigInt(' ')"), "0n"); + assert_eq!(forward(&mut context, "BigInt('')"), "0n"); + assert_eq!(forward(&mut context, "BigInt(' ')"), "0n"); assert_eq!( - forward(&mut engine, "BigInt('200000000000000000')"), + forward(&mut context, "BigInt('200000000000000000')"), "200000000000000000n" ); assert_eq!( - forward(&mut engine, "BigInt('1000000000000000000000000000000000')"), + forward(&mut context, "BigInt('1000000000000000000000000000000000')"), "1000000000000000000000000000000000n" ); - assert_eq!(forward(&mut engine, "BigInt('0b1111')"), "15n"); - assert_eq!(forward(&mut engine, "BigInt('0o70')"), "56n"); - assert_eq!(forward(&mut engine, "BigInt('0xFF')"), "255n"); + assert_eq!(forward(&mut context, "BigInt('0b1111')"), "15n"); + assert_eq!(forward(&mut context, "BigInt('0o70')"), "56n"); + assert_eq!(forward(&mut context, "BigInt('0xFF')"), "255n"); } #[test] fn add() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(forward(&mut engine, "10000n + 1000n"), "11000n"); + assert_eq!(forward(&mut context, "10000n + 1000n"), "11000n"); } #[test] fn sub() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(forward(&mut engine, "10000n - 1000n"), "9000n"); + assert_eq!(forward(&mut context, "10000n - 1000n"), "9000n"); } #[test] fn mul() { - let mut engine = Context::new(); + let mut context = Context::new(); assert_eq!( - forward(&mut engine, "123456789n * 102030n"), + forward(&mut context, "123456789n * 102030n"), "12596296181670n" ); } #[test] fn div() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(forward(&mut engine, "15000n / 50n"), "300n"); + assert_eq!(forward(&mut context, "15000n / 50n"), "300n"); } #[test] fn div_with_truncation() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(forward(&mut engine, "15001n / 50n"), "300n"); + assert_eq!(forward(&mut context, "15001n / 50n"), "300n"); } #[test] fn r#mod() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(forward(&mut engine, "15007n % 10n"), "7n"); + assert_eq!(forward(&mut context, "15007n % 10n"), "7n"); } #[test] fn pow() { - let mut engine = Context::new(); + let mut context = Context::new(); assert_eq!( - forward(&mut engine, "100n ** 10n"), + forward(&mut context, "100n ** 10n"), "100000000000000000000n" ); } #[test] fn pow_negative_exponent() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_throws(&mut engine, "10n ** (-10n)", "RangeError"); + assert_throws(&mut context, "10n ** (-10n)", "RangeError"); } #[test] fn shl() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(forward(&mut engine, "8n << 2n"), "32n"); + assert_eq!(forward(&mut context, "8n << 2n"), "32n"); } #[test] fn shl_out_of_range() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_throws(&mut engine, "1000n << 1000000000000000n", "RangeError"); + assert_throws(&mut context, "1000n << 1000000000000000n", "RangeError"); } #[test] fn shr() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(forward(&mut engine, "8n >> 2n"), "2n"); + assert_eq!(forward(&mut context, "8n >> 2n"), "2n"); } #[test] fn shr_out_of_range() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_throws(&mut engine, "1000n >> 1000000000000000n", "RangeError"); + assert_throws(&mut context, "1000n >> 1000000000000000n", "RangeError"); } #[test] fn to_string() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(forward(&mut engine, "1000n.toString()"), "\"1000\""); - assert_eq!(forward(&mut engine, "1000n.toString(2)"), "\"1111101000\""); - assert_eq!(forward(&mut engine, "255n.toString(16)"), "\"ff\""); - assert_eq!(forward(&mut engine, "1000n.toString(36)"), "\"rs\""); + assert_eq!(forward(&mut context, "1000n.toString()"), "\"1000\""); + assert_eq!(forward(&mut context, "1000n.toString(2)"), "\"1111101000\""); + assert_eq!(forward(&mut context, "255n.toString(16)"), "\"ff\""); + assert_eq!(forward(&mut context, "1000n.toString(36)"), "\"rs\""); } #[test] fn to_string_invalid_radix() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_throws(&mut engine, "10n.toString(null)", "RangeError"); - assert_throws(&mut engine, "10n.toString(-1)", "RangeError"); - assert_throws(&mut engine, "10n.toString(37)", "RangeError"); + assert_throws(&mut context, "10n.toString(null)", "RangeError"); + assert_throws(&mut context, "10n.toString(-1)", "RangeError"); + assert_throws(&mut context, "10n.toString(37)", "RangeError"); } #[test] fn as_int_n() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(forward(&mut engine, "BigInt.asIntN(0, 1n)"), "0n"); - assert_eq!(forward(&mut engine, "BigInt.asIntN(1, 1n)"), "-1n"); - assert_eq!(forward(&mut engine, "BigInt.asIntN(3, 10n)"), "2n"); - assert_eq!(forward(&mut engine, "BigInt.asIntN({}, 1n)"), "0n"); - assert_eq!(forward(&mut engine, "BigInt.asIntN(2, 0n)"), "0n"); - assert_eq!(forward(&mut engine, "BigInt.asIntN(2, -0n)"), "0n"); + assert_eq!(forward(&mut context, "BigInt.asIntN(0, 1n)"), "0n"); + assert_eq!(forward(&mut context, "BigInt.asIntN(1, 1n)"), "-1n"); + assert_eq!(forward(&mut context, "BigInt.asIntN(3, 10n)"), "2n"); + assert_eq!(forward(&mut context, "BigInt.asIntN({}, 1n)"), "0n"); + assert_eq!(forward(&mut context, "BigInt.asIntN(2, 0n)"), "0n"); + assert_eq!(forward(&mut context, "BigInt.asIntN(2, -0n)"), "0n"); assert_eq!( - forward(&mut engine, "BigInt.asIntN(2, -123456789012345678901n)"), + forward(&mut context, "BigInt.asIntN(2, -123456789012345678901n)"), "-1n" ); assert_eq!( - forward(&mut engine, "BigInt.asIntN(2, -123456789012345678900n)"), + forward(&mut context, "BigInt.asIntN(2, -123456789012345678900n)"), "0n" ); assert_eq!( - forward(&mut engine, "BigInt.asIntN(2, 123456789012345678900n)"), + forward(&mut context, "BigInt.asIntN(2, 123456789012345678900n)"), "0n" ); assert_eq!( - forward(&mut engine, "BigInt.asIntN(2, 123456789012345678901n)"), + forward(&mut context, "BigInt.asIntN(2, 123456789012345678901n)"), "1n" ); assert_eq!( forward( - &mut engine, + &mut context, "BigInt.asIntN(200, 0xcffffffffffffffffffffffffffffffffffffffffffffffffffn)" ), "-1n" ); assert_eq!( forward( - &mut engine, + &mut context, "BigInt.asIntN(201, 0xcffffffffffffffffffffffffffffffffffffffffffffffffffn)" ), "1606938044258990275541962092341162602522202993782792835301375n" @@ -302,14 +302,14 @@ fn as_int_n() { assert_eq!( forward( - &mut engine, + &mut context, "BigInt.asIntN(200, 0xc89e081df68b65fedb32cffea660e55df9605650a603ad5fc54n)" ), "-741470203160010616172516490008037905920749803227695190508460n" ); assert_eq!( forward( - &mut engine, + &mut context, "BigInt.asIntN(201, 0xc89e081df68b65fedb32cffea660e55df9605650a603ad5fc54n)" ), "865467841098979659369445602333124696601453190555097644792916n" @@ -318,63 +318,63 @@ fn as_int_n() { #[test] fn as_int_n_errors() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_throws(&mut engine, "BigInt.asIntN(-1, 0n)", "RangeError"); - assert_throws(&mut engine, "BigInt.asIntN(-2.5, 0n)", "RangeError"); + assert_throws(&mut context, "BigInt.asIntN(-1, 0n)", "RangeError"); + assert_throws(&mut context, "BigInt.asIntN(-2.5, 0n)", "RangeError"); assert_throws( - &mut engine, + &mut context, "BigInt.asIntN(9007199254740992, 0n)", "RangeError", ); - assert_throws(&mut engine, "BigInt.asIntN(0n, 0n)", "TypeError"); + assert_throws(&mut context, "BigInt.asIntN(0n, 0n)", "TypeError"); } #[test] fn as_uint_n() { - 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"); - assert_eq!(forward(&mut engine, "BigInt.asUintN(0, 0n)"), "0n"); - assert_eq!(forward(&mut engine, "BigInt.asUintN(0, 1n)"), "0n"); - assert_eq!(forward(&mut engine, "BigInt.asUintN(0, 2n)"), "0n"); - - assert_eq!(forward(&mut engine, "BigInt.asUintN(1, -3n)"), "1n"); - assert_eq!(forward(&mut engine, "BigInt.asUintN(1, -2n)"), "0n"); - assert_eq!(forward(&mut engine, "BigInt.asUintN(1, -1n)"), "1n"); - assert_eq!(forward(&mut engine, "BigInt.asUintN(1, 0n)"), "0n"); - assert_eq!(forward(&mut engine, "BigInt.asUintN(1, 1n)"), "1n"); - assert_eq!(forward(&mut engine, "BigInt.asUintN(1, 2n)"), "0n"); - assert_eq!(forward(&mut engine, "BigInt.asUintN(1, 3n)"), "1n"); + let mut context = Context::new(); + + assert_eq!(forward(&mut context, "BigInt.asUintN(0, -2n)"), "0n"); + assert_eq!(forward(&mut context, "BigInt.asUintN(0, -1n)"), "0n"); + assert_eq!(forward(&mut context, "BigInt.asUintN(0, 0n)"), "0n"); + assert_eq!(forward(&mut context, "BigInt.asUintN(0, 1n)"), "0n"); + assert_eq!(forward(&mut context, "BigInt.asUintN(0, 2n)"), "0n"); + + assert_eq!(forward(&mut context, "BigInt.asUintN(1, -3n)"), "1n"); + assert_eq!(forward(&mut context, "BigInt.asUintN(1, -2n)"), "0n"); + assert_eq!(forward(&mut context, "BigInt.asUintN(1, -1n)"), "1n"); + assert_eq!(forward(&mut context, "BigInt.asUintN(1, 0n)"), "0n"); + assert_eq!(forward(&mut context, "BigInt.asUintN(1, 1n)"), "1n"); + assert_eq!(forward(&mut context, "BigInt.asUintN(1, 2n)"), "0n"); + assert_eq!(forward(&mut context, "BigInt.asUintN(1, 3n)"), "1n"); assert_eq!( - forward(&mut engine, "BigInt.asUintN(1, -123456789012345678901n)"), + forward(&mut context, "BigInt.asUintN(1, -123456789012345678901n)"), "1n" ); assert_eq!( - forward(&mut engine, "BigInt.asUintN(1, -123456789012345678900n)"), + forward(&mut context, "BigInt.asUintN(1, -123456789012345678900n)"), "0n" ); assert_eq!( - forward(&mut engine, "BigInt.asUintN(1, 123456789012345678900n)"), + forward(&mut context, "BigInt.asUintN(1, 123456789012345678900n)"), "0n" ); assert_eq!( - forward(&mut engine, "BigInt.asUintN(1, 123456789012345678901n)"), + forward(&mut context, "BigInt.asUintN(1, 123456789012345678901n)"), "1n" ); assert_eq!( forward( - &mut engine, + &mut context, "BigInt.asUintN(200, 0xbffffffffffffffffffffffffffffffffffffffffffffffffffn)" ), "1606938044258990275541962092341162602522202993782792835301375n" ); assert_eq!( forward( - &mut engine, + &mut context, "BigInt.asUintN(201, 0xbffffffffffffffffffffffffffffffffffffffffffffffffffn)" ), "3213876088517980551083924184682325205044405987565585670602751n" @@ -383,31 +383,31 @@ fn as_uint_n() { #[test] fn as_uint_n_errors() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_throws(&mut engine, "BigInt.asUintN(-1, 0n)", "RangeError"); - assert_throws(&mut engine, "BigInt.asUintN(-2.5, 0n)", "RangeError"); + assert_throws(&mut context, "BigInt.asUintN(-1, 0n)", "RangeError"); + assert_throws(&mut context, "BigInt.asUintN(-2.5, 0n)", "RangeError"); assert_throws( - &mut engine, + &mut context, "BigInt.asUintN(9007199254740992, 0n)", "RangeError", ); - assert_throws(&mut engine, "BigInt.asUintN(0n, 0n)", "TypeError"); + assert_throws(&mut context, "BigInt.asUintN(0n, 0n)", "TypeError"); } -fn assert_throws(engine: &mut Context, src: &str, error_type: &str) { - let result = forward(engine, src); +fn assert_throws(context: &mut Context, src: &str, error_type: &str) { + let result = forward(context, src); assert!(result.contains(error_type)); } #[test] fn division_by_zero() { - let mut engine = Context::new(); - assert_throws(&mut engine, "1n/0n", "RangeError"); + let mut context = Context::new(); + assert_throws(&mut context, "1n/0n", "RangeError"); } #[test] fn remainder_by_zero() { - let mut engine = Context::new(); - assert_throws(&mut engine, "1n % 0n", "RangeError"); + let mut context = Context::new(); + assert_throws(&mut context, "1n % 0n", "RangeError"); } diff --git a/boa/src/builtins/boolean/mod.rs b/boa/src/builtins/boolean/mod.rs index 2a1357c026..297ce4a182 100644 --- a/boa/src/builtins/boolean/mod.rs +++ b/boa/src/builtins/boolean/mod.rs @@ -70,7 +70,7 @@ impl Boolean { /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-thisbooleanvalue - fn this_boolean_value(value: &Value, ctx: &mut Context) -> Result { + fn this_boolean_value(value: &Value, context: &mut Context) -> Result { match value { Value::Boolean(boolean) => return Ok(*boolean), Value::Object(ref object) => { @@ -82,7 +82,7 @@ impl Boolean { _ => {} } - Err(ctx.construct_type_error("'this' is not a boolean")) + Err(context.construct_type_error("'this' is not a boolean")) } /// The `toString()` method returns a string representing the specified `Boolean` object. @@ -94,8 +94,8 @@ 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 Context) -> Result { - let boolean = Self::this_boolean_value(this, ctx)?; + pub(crate) fn to_string(this: &Value, _: &[Value], context: &mut Context) -> Result { + let boolean = Self::this_boolean_value(this, context)?; Ok(Value::from(boolean.to_string())) } @@ -108,7 +108,7 @@ 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 Context) -> Result { - Ok(Value::from(Self::this_boolean_value(this, ctx)?)) + pub(crate) fn value_of(this: &Value, _: &[Value], context: &mut Context) -> Result { + Ok(Value::from(Self::this_boolean_value(this, context)?)) } } diff --git a/boa/src/builtins/boolean/tests.rs b/boa/src/builtins/boolean/tests.rs index 10f5e80ec3..59aaa5f723 100644 --- a/boa/src/builtins/boolean/tests.rs +++ b/boa/src/builtins/boolean/tests.rs @@ -4,14 +4,14 @@ use crate::{forward, forward_val, value::same_value, Context}; #[allow(clippy::unwrap_used)] #[test] fn construct_and_call() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var one = new Boolean(1); var zero = Boolean(0); "#; - eprintln!("{}", forward(&mut engine, init)); - let one = forward_val(&mut engine, "one").unwrap(); - let zero = forward_val(&mut engine, "zero").unwrap(); + eprintln!("{}", forward(&mut context, init)); + let one = forward_val(&mut context, "one").unwrap(); + let zero = forward_val(&mut context, "zero").unwrap(); assert_eq!(one.is_object(), true); assert_eq!(zero.is_boolean(), true); @@ -19,7 +19,7 @@ fn construct_and_call() { #[test] fn constructor_gives_true_instance() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var trueVal = new Boolean(true); var trueNum = new Boolean(1); @@ -27,11 +27,11 @@ fn constructor_gives_true_instance() { var trueBool = new Boolean(trueVal); "#; - eprintln!("{}", forward(&mut engine, init)); - let true_val = forward_val(&mut engine, "trueVal").expect("value expected"); - let true_num = forward_val(&mut engine, "trueNum").expect("value expected"); - let true_string = forward_val(&mut engine, "trueString").expect("value expected"); - let true_bool = forward_val(&mut engine, "trueBool").expect("value expected"); + eprintln!("{}", forward(&mut context, init)); + let true_val = forward_val(&mut context, "trueVal").expect("value expected"); + let true_num = forward_val(&mut context, "trueNum").expect("value expected"); + let true_string = forward_val(&mut context, "trueString").expect("value expected"); + let true_bool = forward_val(&mut context, "trueBool").expect("value expected"); // Values should all be objects assert_eq!(true_val.is_object(), true); @@ -48,15 +48,15 @@ fn constructor_gives_true_instance() { #[test] fn instances_have_correct_proto_set() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var boolInstance = new Boolean(true); var boolProto = Boolean.prototype; "#; - eprintln!("{}", forward(&mut engine, init)); - let bool_instance = forward_val(&mut engine, "boolInstance").expect("value expected"); - let bool_prototype = forward_val(&mut engine, "boolProto").expect("value expected"); + eprintln!("{}", forward(&mut context, init)); + let bool_instance = forward_val(&mut context, "boolInstance").expect("value expected"); + let bool_prototype = forward_val(&mut context, "boolProto").expect("value expected"); assert!(same_value( &bool_instance.as_object().unwrap().prototype_instance(), diff --git a/boa/src/builtins/console/mod.rs b/boa/src/builtins/console/mod.rs index 5a511e0b4b..e96beebe09 100644 --- a/boa/src/builtins/console/mod.rs +++ b/boa/src/builtins/console/mod.rs @@ -58,8 +58,12 @@ pub(crate) fn logger(msg: LogMessage, console_state: &Console) { } /// This represents the `console` formatter. -pub fn formatter(data: &[Value], ctx: &mut Context) -> Result { - let target = data.get(0).cloned().unwrap_or_default().to_string(ctx)?; +pub fn formatter(data: &[Value], context: &mut Context) -> Result { + let target = data + .get(0) + .cloned() + .unwrap_or_default() + .to_string(context)?; match data.len() { 0 => Ok(String::new()), @@ -78,7 +82,7 @@ pub fn formatter(data: &[Value], ctx: &mut Context) -> Result { .get(arg_index) .cloned() .unwrap_or_default() - .to_integer(ctx)?; + .to_integer(context)?; formatted.push_str(&format!("{}", arg)); arg_index += 1; } @@ -88,7 +92,7 @@ pub fn formatter(data: &[Value], ctx: &mut Context) -> Result { .get(arg_index) .cloned() .unwrap_or_default() - .to_number(ctx)?; + .to_number(context)?; formatted.push_str(&format!("{number:.prec$}", number = arg, prec = 6)); arg_index += 1 } @@ -104,7 +108,7 @@ pub fn formatter(data: &[Value], ctx: &mut Context) -> Result { .get(arg_index) .cloned() .unwrap_or_default() - .to_string(ctx)?; + .to_string(context)?; formatted.push_str(&arg); arg_index += 1 } @@ -122,7 +126,7 @@ pub fn formatter(data: &[Value], ctx: &mut Context) -> Result { /* unformatted data */ for rest in data.iter().skip(arg_index) { - formatted.push_str(&format!(" {}", rest.to_string(ctx)?)) + formatted.push_str(&format!(" {}", rest.to_string(context)?)) } Ok(formatted) @@ -188,7 +192,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 Context) -> Result { + pub(crate) fn assert(_: &Value, args: &[Value], context: &mut Context) -> Result { let assertion = get_arg_at_index::(args, 0).unwrap_or_default(); if !assertion { @@ -203,7 +207,10 @@ impl Console { args[0] = Value::from(concat); } - logger(LogMessage::Error(formatter(&args, ctx)?), ctx.console()); + logger( + LogMessage::Error(formatter(&args, context)?), + context.console(), + ); } Ok(Value::undefined()) @@ -219,8 +226,8 @@ 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 Context) -> Result { - ctx.console_mut().groups.clear(); + pub(crate) fn clear(_: &Value, _: &[Value], context: &mut Context) -> Result { + context.console_mut().groups.clear(); Ok(Value::undefined()) } @@ -234,8 +241,11 @@ 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 Context) -> Result { - logger(LogMessage::Log(formatter(args, ctx)?), ctx.console()); + pub(crate) fn debug(_: &Value, args: &[Value], context: &mut Context) -> Result { + logger( + LogMessage::Log(formatter(args, context)?), + context.console(), + ); Ok(Value::undefined()) } @@ -249,8 +259,11 @@ 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 Context) -> Result { - logger(LogMessage::Error(formatter(args, ctx)?), ctx.console()); + pub(crate) fn error(_: &Value, args: &[Value], context: &mut Context) -> Result { + logger( + LogMessage::Error(formatter(args, context)?), + context.console(), + ); Ok(Value::undefined()) } @@ -264,8 +277,11 @@ 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 Context) -> Result { - logger(LogMessage::Info(formatter(args, ctx)?), ctx.console()); + pub(crate) fn info(_: &Value, args: &[Value], context: &mut Context) -> Result { + logger( + LogMessage::Info(formatter(args, context)?), + context.console(), + ); Ok(Value::undefined()) } @@ -279,8 +295,11 @@ 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 Context) -> Result { - logger(LogMessage::Log(formatter(args, ctx)?), ctx.console()); + pub(crate) fn log(_: &Value, args: &[Value], context: &mut Context) -> Result { + logger( + LogMessage::Log(formatter(args, context)?), + context.console(), + ); Ok(Value::undefined()) } @@ -294,14 +313,17 @@ 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 Context) -> Result { + pub(crate) fn trace(_: &Value, args: &[Value], context: &mut Context) -> Result { if !args.is_empty() { - logger(LogMessage::Log(formatter(args, ctx)?), ctx.console()); + logger( + LogMessage::Log(formatter(args, context)?), + context.console(), + ); /* TODO: get and print stack trace */ logger( LogMessage::Log("Not implemented: ".to_string()), - ctx.console(), + context.console(), ) } @@ -318,8 +340,11 @@ 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 Context) -> Result { - logger(LogMessage::Warn(formatter(args, ctx)?), ctx.console()); + pub(crate) fn warn(_: &Value, args: &[Value], context: &mut Context) -> Result { + logger( + LogMessage::Warn(formatter(args, context)?), + context.console(), + ); Ok(Value::undefined()) } @@ -333,17 +358,20 @@ 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 Context) -> Result { + pub(crate) fn count(_: &Value, args: &[Value], context: &mut Context) -> Result { let label = match args.get(0) { - Some(value) => value.to_string(ctx)?, + Some(value) => value.to_string(context)?, None => "default".into(), }; let msg = format!("count {}:", &label); - let c = ctx.console_mut().count_map.entry(label).or_insert(0); + let c = context.console_mut().count_map.entry(label).or_insert(0); *c += 1; - logger(LogMessage::Info(format!("{} {}", msg, c)), ctx.console()); + logger( + LogMessage::Info(format!("{} {}", msg, c)), + context.console(), + ); Ok(Value::undefined()) } @@ -357,17 +385,17 @@ 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 Context) -> Result { + pub(crate) fn count_reset(_: &Value, args: &[Value], context: &mut Context) -> Result { let label = match args.get(0) { - Some(value) => value.to_string(ctx)?, + Some(value) => value.to_string(context)?, None => "default".into(), }; - ctx.console_mut().count_map.remove(&label); + context.console_mut().count_map.remove(&label); logger( LogMessage::Warn(format!("countReset {}", label)), - ctx.console(), + context.console(), ); Ok(Value::undefined()) @@ -391,20 +419,20 @@ 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 Context) -> Result { + pub(crate) fn time(_: &Value, args: &[Value], context: &mut Context) -> Result { let label = match args.get(0) { - Some(value) => value.to_string(ctx)?, + Some(value) => value.to_string(context)?, None => "default".into(), }; - if ctx.console().timer_map.get(&label).is_some() { + if context.console().timer_map.get(&label).is_some() { logger( LogMessage::Warn(format!("Timer '{}' already exist", label)), - ctx.console(), + context.console(), ); } else { let time = Self::system_time_in_ms(); - ctx.console_mut().timer_map.insert(label, time); + context.console_mut().timer_map.insert(label, time); } Ok(Value::undefined()) @@ -420,23 +448,23 @@ 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 Context) -> Result { + pub(crate) fn time_log(_: &Value, args: &[Value], context: &mut Context) -> Result { let label = match args.get(0) { - Some(value) => value.to_string(ctx)?, + Some(value) => value.to_string(context)?, None => "default".into(), }; - if let Some(t) = ctx.console().timer_map.get(&label) { + if let Some(t) = context.console().timer_map.get(&label) { let time = Self::system_time_in_ms(); let mut concat = format!("{}: {} ms", label, time - t); for msg in args.iter().skip(1) { concat = concat + " " + &msg.display().to_string(); } - logger(LogMessage::Log(concat), ctx.console()); + logger(LogMessage::Log(concat), context.console()); } else { logger( LogMessage::Warn(format!("Timer '{}' doesn't exist", label)), - ctx.console(), + context.console(), ); } @@ -453,22 +481,22 @@ 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 Context) -> Result { + pub(crate) fn time_end(_: &Value, args: &[Value], context: &mut Context) -> Result { let label = match args.get(0) { - Some(value) => value.to_string(ctx)?, + Some(value) => value.to_string(context)?, None => "default".into(), }; - if let Some(t) = ctx.console_mut().timer_map.remove(label.as_str()) { + if let Some(t) = context.console_mut().timer_map.remove(label.as_str()) { let time = Self::system_time_in_ms(); logger( LogMessage::Info(format!("{}: {} ms - timer removed", label, time - t)), - ctx.console(), + context.console(), ); } else { logger( LogMessage::Warn(format!("Timer '{}' doesn't exist", label)), - ctx.console(), + context.console(), ); } @@ -485,14 +513,14 @@ 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 Context) -> Result { - let group_label = formatter(args, ctx)?; + pub(crate) fn group(_: &Value, args: &[Value], context: &mut Context) -> Result { + let group_label = formatter(args, context)?; logger( LogMessage::Info(format!("group: {}", &group_label)), - ctx.console(), + context.console(), ); - ctx.console_mut().groups.push(group_label); + context.console_mut().groups.push(group_label); Ok(Value::undefined()) } @@ -507,8 +535,8 @@ 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 Context) -> Result { - ctx.console_mut().groups.pop(); + pub(crate) fn group_end(_: &Value, _: &[Value], context: &mut Context) -> Result { + context.console_mut().groups.pop(); Ok(Value::undefined()) } @@ -523,11 +551,11 @@ 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 Context) -> Result { + pub(crate) fn dir(_: &Value, args: &[Value], context: &mut Context) -> Result { let undefined = Value::undefined(); logger( LogMessage::Info(display_obj(args.get(0).unwrap_or(&undefined), true)), - ctx.console(), + context.console(), ); Ok(Value::undefined()) diff --git a/boa/src/builtins/console/tests.rs b/boa/src/builtins/console/tests.rs index 1a89a3e668..291c71427b 100644 --- a/boa/src/builtins/console/tests.rs +++ b/boa/src/builtins/console/tests.rs @@ -2,41 +2,41 @@ use crate::{builtins::console::formatter, Context, Value}; #[test] fn formatter_no_args_is_empty_string() { - let mut engine = Context::new(); - assert_eq!(formatter(&[], &mut engine).unwrap(), ""); + let mut context = Context::new(); + assert_eq!(formatter(&[], &mut context).unwrap(), ""); } #[test] fn formatter_empty_format_string_is_empty_string() { - let mut engine = Context::new(); + let mut context = Context::new(); let val = Value::string("".to_string()); - assert_eq!(formatter(&[val], &mut engine).unwrap(), ""); + assert_eq!(formatter(&[val], &mut context).unwrap(), ""); } #[test] fn formatter_format_without_args_renders_verbatim() { - let mut engine = Context::new(); + let mut context = Context::new(); let val = [Value::string("%d %s %% %f")]; - let res = formatter(&val, &mut engine).unwrap(); + let res = formatter(&val, &mut context).unwrap(); assert_eq!(res, "%d %s %% %f"); } #[test] fn formatter_empty_format_string_concatenates_rest_of_args() { - let mut engine = Context::new(); + let mut context = Context::new(); let val = [ Value::string(""), Value::string("to powinno zostać"), Value::string("połączone"), ]; - let res = formatter(&val, &mut engine).unwrap(); + let res = formatter(&val, &mut context).unwrap(); assert_eq!(res, " to powinno zostać połączone"); } #[test] fn formatter_utf_8_checks() { - let mut engine = Context::new(); + let mut context = Context::new(); let val = [ Value::string("Są takie chwile %dą %są tu%sów %привет%ź".to_string()), @@ -44,28 +44,28 @@ fn formatter_utf_8_checks() { Value::rational(1.23), Value::string("ł".to_string()), ]; - let res = formatter(&val, &mut engine).unwrap(); + let res = formatter(&val, &mut context).unwrap(); assert_eq!(res, "Są takie chwile 123ą 1.23ą tułów %привет%ź"); } #[test] fn formatter_trailing_format_leader_renders() { - let mut engine = Context::new(); + let mut context = Context::new(); let val = [ Value::string("%%%%%".to_string()), Value::string("|".to_string()), ]; - let res = formatter(&val, &mut engine).unwrap(); + let res = formatter(&val, &mut context).unwrap(); assert_eq!(res, "%%% |"); } #[test] #[allow(clippy::approx_constant)] fn formatter_float_format_works() { - let mut engine = Context::new(); + let mut context = Context::new(); let val = [Value::string("%f".to_string()), Value::rational(3.1415)]; - let res = formatter(&val, &mut engine).unwrap(); + let res = formatter(&val, &mut context).unwrap(); assert_eq!(res, "3.141500"); } diff --git a/boa/src/builtins/date/mod.rs b/boa/src/builtins/date/mod.rs index f604f6a493..e097e5ce4e 100644 --- a/boa/src/builtins/date/mod.rs +++ b/boa/src/builtins/date/mod.rs @@ -3,13 +3,13 @@ mod tests; use crate::{ builtins::BuiltIn, + gc::{empty_trace, Finalize, Trace}, object::{ConstructorBuilder, ObjectData}, property::Attribute, value::{PreferredType, Value}, BoaProfiler, Context, Result, }; use chrono::{prelude::*, Duration, LocalResult}; -use gc::{unsafe_empty_trace, Finalize, Trace}; use std::fmt::Display; const NANOS_IN_MS: f64 = 1_000_000f64; @@ -38,8 +38,8 @@ fn ignore_ambiguity(result: LocalResult) -> Option { macro_rules! getter_method { ($name:ident) => {{ - fn get_value(this: &Value, _: &[Value], ctx: &mut Context) -> Result { - Ok(Value::from(this_time_value(this, ctx)?.$name())) + fn get_value(this: &Value, _: &[Value], context: &mut Context) -> Result { + Ok(Value::from(this_time_value(this, context)?.$name())) } get_value }}; @@ -53,14 +53,14 @@ macro_rules! getter_method { macro_rules! setter_method { ($name:ident($($e:expr),* $(,)?)) => {{ - fn set_value(this: &Value, args: &[Value], ctx: &mut Context) -> Result { - let mut result = this_time_value(this, ctx)?; + fn set_value(this: &Value, args: &[Value], context: &mut Context) -> Result { + let mut result = this_time_value(this, context)?; result.$name( $( args .get($e) .and_then(|value| { - value.to_numeric_number(ctx).map_or_else( + value.to_numeric_number(context).map_or_else( |_| None, |value| { if value == 0f64 || value.is_normal() { @@ -96,7 +96,7 @@ impl Display for Date { unsafe impl Trace for Date { // Date is a stack value, it doesn't require tracing. // only safe if `chrono` never implements `Trace` for `NaiveDateTime` - unsafe_empty_trace!(); + empty_trace!(); } impl Default for Date { @@ -323,15 +323,19 @@ 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 constructor(this: &Value, args: &[Value], ctx: &mut Context) -> Result { + pub(crate) fn constructor( + this: &Value, + args: &[Value], + context: &mut Context, + ) -> Result { if this.is_global() { Self::make_date_string() } else if args.is_empty() { Self::make_date_now(this) } else if args.len() == 1 { - Self::make_date_single(this, args, ctx) + Self::make_date_single(this, args, context) } else { - Self::make_date_multiple(this, args, ctx) + Self::make_date_multiple(this, args, context) } } @@ -378,18 +382,18 @@ impl Date { pub(crate) fn make_date_single( this: &Value, args: &[Value], - ctx: &mut Context, + context: &mut Context, ) -> Result { let value = &args[0]; - let tv = match this_time_value(value, ctx) { + let tv = match this_time_value(value, context) { Ok(dt) => dt.0, - _ => match value.to_primitive(ctx, PreferredType::Default)? { + _ => match value.to_primitive(context, PreferredType::Default)? { Value::String(ref str) => match chrono::DateTime::parse_from_rfc3339(&str) { Ok(dt) => Some(dt.naive_utc()), _ => None, }, tv => { - let tv = tv.to_number(ctx)?; + let tv = tv.to_number(context)?; let secs = (tv / 1_000f64) as i64; let nsecs = ((tv % 1_000f64) * 1_000_000f64) as u32; NaiveDateTime::from_timestamp_opt(secs, nsecs) @@ -415,15 +419,25 @@ impl Date { pub(crate) fn make_date_multiple( this: &Value, args: &[Value], - ctx: &mut Context, + context: &mut Context, ) -> Result { - let year = args[0].to_number(ctx)?; - let month = args[1].to_number(ctx)?; - let day = args.get(2).map_or(Ok(1f64), |value| value.to_number(ctx))?; - let hour = args.get(3).map_or(Ok(0f64), |value| value.to_number(ctx))?; - let min = args.get(4).map_or(Ok(0f64), |value| value.to_number(ctx))?; - let sec = args.get(5).map_or(Ok(0f64), |value| value.to_number(ctx))?; - let milli = args.get(6).map_or(Ok(0f64), |value| value.to_number(ctx))?; + let year = args[0].to_number(context)?; + let month = args[1].to_number(context)?; + let day = args + .get(2) + .map_or(Ok(1f64), |value| value.to_number(context))?; + let hour = args + .get(3) + .map_or(Ok(0f64), |value| value.to_number(context))?; + let min = args + .get(4) + .map_or(Ok(0f64), |value| value.to_number(context))?; + let sec = args + .get(5) + .map_or(Ok(0f64), |value| value.to_number(context))?; + let milli = args + .get(6) + .map_or(Ok(0f64), |value| value.to_number(context))?; // If any of the args are infinity or NaN, return an invalid date. if !check_normal_opt!(year, month, day, hour, min, sec, milli) { @@ -1257,7 +1271,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 Context) -> Result { + pub(crate) fn parse(_: &Value, args: &[Value], context: &mut Context) -> Result { // This method is implementation-defined and discouraged, so we just require the same format as the string // constructor. @@ -1265,7 +1279,7 @@ impl Date { return Ok(Value::number(f64::NAN)); } - match DateTime::parse_from_rfc3339(&args[0].to_string(ctx)?) { + match DateTime::parse_from_rfc3339(&args[0].to_string(context)?) { Ok(v) => Ok(Value::number(v.naive_utc().timestamp_millis() as f64)), _ => Ok(Value::number(f64::NAN)), } @@ -1281,16 +1295,28 @@ 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 Context) -> Result { + pub(crate) fn utc(_: &Value, args: &[Value], context: &mut Context) -> Result { let year = args .get(0) - .map_or(Ok(f64::NAN), |value| value.to_number(ctx))?; - let month = args.get(1).map_or(Ok(1f64), |value| value.to_number(ctx))?; - let day = args.get(2).map_or(Ok(1f64), |value| value.to_number(ctx))?; - let hour = args.get(3).map_or(Ok(0f64), |value| value.to_number(ctx))?; - let min = args.get(4).map_or(Ok(0f64), |value| value.to_number(ctx))?; - let sec = args.get(5).map_or(Ok(0f64), |value| value.to_number(ctx))?; - let milli = args.get(6).map_or(Ok(0f64), |value| value.to_number(ctx))?; + .map_or(Ok(f64::NAN), |value| value.to_number(context))?; + let month = args + .get(1) + .map_or(Ok(1f64), |value| value.to_number(context))?; + let day = args + .get(2) + .map_or(Ok(1f64), |value| value.to_number(context))?; + let hour = args + .get(3) + .map_or(Ok(0f64), |value| value.to_number(context))?; + let min = args + .get(4) + .map_or(Ok(0f64), |value| value.to_number(context))?; + let sec = args + .get(5) + .map_or(Ok(0f64), |value| value.to_number(context))?; + let milli = args + .get(6) + .map_or(Ok(0f64), |value| value.to_number(context))?; if !check_normal_opt!(year, month, day, hour, min, sec, milli) { return Ok(Value::number(f64::NAN)); @@ -1331,11 +1357,11 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-thistimevalue #[inline] -pub fn this_time_value(value: &Value, ctx: &mut Context) -> Result { +pub fn this_time_value(value: &Value, context: &mut Context) -> Result { if let Value::Object(ref object) = value { if let ObjectData::Date(ref date) = object.borrow().data { return Ok(*date); } } - Err(ctx.construct_type_error("'this' is not a Date")) + Err(context.construct_type_error("'this' is not a Date")) } diff --git a/boa/src/builtins/date/tests.rs b/boa/src/builtins/date/tests.rs index 92a813b55d..1d397c92b7 100644 --- a/boa/src/builtins/date/tests.rs +++ b/boa/src/builtins/date/tests.rs @@ -6,8 +6,8 @@ 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 Context, src: &str) -> Option { - let date_time = if let Ok(v) = forward_val(engine, src) { +fn forward_dt_utc(context: &mut Context, src: &str) -> Option { + let date_time = if let Ok(v) = forward_val(context, src) { v } else { panic!("expected success") @@ -24,8 +24,8 @@ fn forward_dt_utc(engine: &mut Context, src: &str) -> Option { } } -fn forward_dt_local(engine: &mut Context, src: &str) -> Option { - let date_time = forward_dt_utc(engine, src); +fn forward_dt_local(context: &mut Context, src: &str) -> Option { + let date_time = forward_dt_utc(context, src); // The timestamp is converted to UTC for internal representation date_time.map(|utc| { @@ -53,10 +53,10 @@ fn date_display() { #[test] fn date_this_time_value() { - let mut engine = Context::new(); + let mut context = Context::new(); let error = forward_val( - &mut engine, + &mut context, "({toString: Date.prototype.toString}).toString()", ) .expect_err("Expected error"); @@ -72,13 +72,13 @@ fn date_this_time_value() { #[test] fn date_call() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); - let dt1 = forward(&mut engine, "Date()"); + let dt1 = forward(&mut context, "Date()"); std::thread::sleep(std::time::Duration::from_millis(1)); - let dt2 = forward(&mut engine, "Date()"); + let dt2 = forward(&mut context, "Date()"); assert_ne!(dt1, dt2); Ok(()) @@ -86,13 +86,13 @@ fn date_call() -> Result<(), Box> { #[test] fn date_ctor_call() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); - let dt1 = forward_dt_local(&mut engine, "new Date()"); + let dt1 = forward_dt_local(&mut context, "new Date()"); std::thread::sleep(std::time::Duration::from_millis(1)); - let dt2 = forward_dt_local(&mut engine, "new Date()"); + let dt2 = forward_dt_local(&mut context, "new Date()"); assert_ne!(dt1, dt2); Ok(()) @@ -100,9 +100,9 @@ fn date_ctor_call() -> Result<(), Box> { #[test] fn date_ctor_call_string() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); - let date_time = forward_dt_utc(&mut engine, "new Date('2020-06-08T09:16:15.779-06:30')"); + let date_time = forward_dt_utc(&mut context, "new Date('2020-06-08T09:16:15.779-06:30')"); // Internal date is expressed as UTC assert_eq!( @@ -114,18 +114,18 @@ fn date_ctor_call_string() -> Result<(), Box> { #[test] fn date_ctor_call_string_invalid() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); - let date_time = forward_dt_local(&mut engine, "new Date('nope')"); + let date_time = forward_dt_local(&mut context, "new Date('nope')"); assert_eq!(None, date_time); Ok(()) } #[test] fn date_ctor_call_number() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); - let date_time = forward_dt_utc(&mut engine, "new Date(1594199775779)"); + let date_time = forward_dt_utc(&mut context, "new Date(1594199775779)"); assert_eq!( Some(NaiveDate::from_ymd(2020, 07, 08).and_hms_milli(09, 16, 15, 779)), date_time @@ -135,9 +135,9 @@ fn date_ctor_call_number() -> Result<(), Box> { #[test] fn date_ctor_call_date() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); - let date_time = forward_dt_utc(&mut engine, "new Date(new Date(1594199775779))"); + let date_time = forward_dt_utc(&mut context, "new Date(new Date(1594199775779))"); assert_eq!( Some(NaiveDate::from_ymd(2020, 07, 08).and_hms_milli(09, 16, 15, 779)), @@ -148,9 +148,9 @@ fn date_ctor_call_date() -> Result<(), Box> { #[test] fn date_ctor_call_multiple() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); - let date_time = forward_dt_local(&mut engine, "new Date(2020, 06, 08, 09, 16, 15, 779)"); + let date_time = forward_dt_local(&mut context, "new Date(2020, 06, 08, 09, 16, 15, 779)"); assert_eq!( Some(NaiveDate::from_ymd(2020, 07, 08).and_hms_milli(09, 16, 15, 779)), @@ -161,9 +161,9 @@ fn date_ctor_call_multiple() -> Result<(), Box> { #[test] fn date_ctor_call_multiple_90s() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); - let date_time = forward_dt_local(&mut engine, "new Date(99, 06, 08, 09, 16, 15, 779)"); + let date_time = forward_dt_local(&mut context, "new Date(99, 06, 08, 09, 16, 15, 779)"); assert_eq!( Some(NaiveDate::from_ymd(1999, 07, 08).and_hms_milli(09, 16, 15, 779)), @@ -175,8 +175,8 @@ fn date_ctor_call_multiple_90s() -> Result<(), Box> { #[test] fn date_ctor_call_multiple_nan() -> Result<(), Box> { fn check(src: &str) { - let mut engine = Context::new(); - let date_time = forward_dt_local(&mut engine, src); + let mut context = Context::new(); + let date_time = forward_dt_local(&mut context, src); assert_eq!(None, date_time); } @@ -193,14 +193,14 @@ fn date_ctor_call_multiple_nan() -> Result<(), Box> { #[test] fn date_ctor_now_call() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); - let date_time = forward(&mut engine, "Date.now()"); + let date_time = forward(&mut context, "Date.now()"); let dt1 = u64::from_str_radix(&date_time, 10)?; std::thread::sleep(std::time::Duration::from_millis(1)); - let date_time = forward(&mut engine, "Date.now()"); + let date_time = forward(&mut context, "Date.now()"); let dt2 = u64::from_str_radix(&date_time, 10)?; assert_ne!(dt1, dt2); @@ -209,9 +209,9 @@ fn date_ctor_now_call() -> Result<(), Box> { #[test] fn date_ctor_parse_call() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); - let date_time = forward_val(&mut engine, "Date.parse('2020-06-08T09:16:15.779-07:30')"); + let date_time = forward_val(&mut context, "Date.parse('2020-06-08T09:16:15.779-07:30')"); assert_eq!(Ok(Value::Rational(1591634775779f64)), date_time); Ok(()) @@ -219,9 +219,9 @@ fn date_ctor_parse_call() -> Result<(), Box> { #[test] fn date_ctor_utc_call() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); - let date_time = forward_val(&mut engine, "Date.UTC(2020, 06, 08, 09, 16, 15, 779)"); + let date_time = forward_val(&mut context, "Date.UTC(2020, 06, 08, 09, 16, 15, 779)"); assert_eq!(Ok(Value::Rational(1594199775779f64)), date_time); Ok(()) @@ -230,8 +230,8 @@ fn date_ctor_utc_call() -> Result<(), Box> { #[test] fn date_ctor_utc_call_nan() -> Result<(), Box> { fn check(src: &str) { - let mut engine = Context::new(); - let date_time = forward_val(&mut engine, src).expect("Expected Success"); + let mut context = Context::new(); + let date_time = forward_val(&mut context, src).expect("Expected Success"); assert_eq!(Value::Rational(f64::NAN), date_time); } @@ -248,15 +248,15 @@ fn date_ctor_utc_call_nan() -> Result<(), Box> { #[test] fn date_proto_get_date_call() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "new Date(2020, 06, 08, 09, 16, 15, 779).getDate()", ); assert_eq!(Ok(Value::Rational(08f64)), actual); - let actual = forward_val(&mut engine, "new Date(1/0).getDate()"); + let actual = forward_val(&mut context, "new Date(1/0).getDate()"); assert_eq!(Ok(Value::Rational(f64::NAN)), actual); Ok(()) @@ -264,90 +264,90 @@ fn date_proto_get_date_call() -> Result<(), Box> { #[test] fn date_proto_get_day_call() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "new Date(2020, 06, 08, 09, 16, 15, 779).getDay()", ); assert_eq!(Ok(Value::Rational(3f64)), actual); - let actual = forward_val(&mut engine, "new Date(1/0).getDay()"); + let actual = forward_val(&mut context, "new Date(1/0).getDay()"); assert_eq!(Ok(Value::Rational(f64::NAN)), actual); Ok(()) } #[test] fn date_proto_get_full_year_call() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "new Date(2020, 06, 08, 09, 16, 15, 779).getFullYear()", ); assert_eq!(Ok(Value::Rational(2020f64)), actual); - let actual = forward_val(&mut engine, "new Date(1/0).getFullYear()"); + let actual = forward_val(&mut context, "new Date(1/0).getFullYear()"); assert_eq!(Ok(Value::Rational(f64::NAN)), actual); Ok(()) } #[test] fn date_proto_get_hours_call() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "new Date(2020, 06, 08, 09, 16, 15, 779).getHours()", ); assert_eq!(Ok(Value::Rational(09f64)), actual); - let actual = forward_val(&mut engine, "new Date(1/0).getHours()"); + let actual = forward_val(&mut context, "new Date(1/0).getHours()"); assert_eq!(Ok(Value::Rational(f64::NAN)), actual); Ok(()) } #[test] fn date_proto_get_milliseconds_call() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "new Date(2020, 06, 08, 09, 16, 15, 779).getMilliseconds()", ); assert_eq!(Ok(Value::Rational(779f64)), actual); - let actual = forward_val(&mut engine, "new Date(1/0).getMilliseconds()"); + let actual = forward_val(&mut context, "new Date(1/0).getMilliseconds()"); assert_eq!(Ok(Value::Rational(f64::NAN)), actual); Ok(()) } #[test] fn date_proto_get_minutes_call() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "new Date(2020, 06, 08, 09, 16, 15, 779).getMinutes()", ); assert_eq!(Ok(Value::Rational(16f64)), actual); - let actual = forward_val(&mut engine, "new Date(1/0).getMinutes()"); + let actual = forward_val(&mut context, "new Date(1/0).getMinutes()"); assert_eq!(Ok(Value::Rational(f64::NAN)), actual); Ok(()) } #[test] fn date_proto_get_month() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "new Date(2020, 06, 08, 09, 16, 15, 779).getMonth()", ); assert_eq!(Ok(Value::Rational(06f64)), actual); - let actual = forward_val(&mut engine, "new Date(1/0).getMonth()"); + let actual = forward_val(&mut context, "new Date(1/0).getMonth()"); assert_eq!(Ok(Value::Rational(f64::NAN)), actual); Ok(()) @@ -355,25 +355,25 @@ fn date_proto_get_month() -> Result<(), Box> { #[test] fn date_proto_get_seconds() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "new Date(2020, 06, 08, 09, 16, 15, 779).getSeconds()", ); assert_eq!(Ok(Value::Rational(15f64)), actual); - let actual = forward_val(&mut engine, "new Date(1/0).getSeconds()"); + let actual = forward_val(&mut context, "new Date(1/0).getSeconds()"); assert_eq!(Ok(Value::Rational(f64::NAN)), actual); Ok(()) } #[test] fn date_proto_get_time() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "new Date(2020, 06, 08, 09, 16, 15, 779).getTime()", ); @@ -383,32 +383,32 @@ fn date_proto_get_time() -> Result<(), Box> { .timestamp_millis() as f64; assert_eq!(Ok(Value::Rational(ts)), actual); - let actual = forward_val(&mut engine, "new Date(1/0).getTime()"); + let actual = forward_val(&mut context, "new Date(1/0).getTime()"); assert_eq!(Ok(Value::Rational(f64::NAN)), actual); Ok(()) } #[test] fn date_proto_get_year() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "new Date(2020, 06, 08, 09, 16, 15, 779).getYear()", ); assert_eq!(Ok(Value::Rational(120f64)), actual); - let actual = forward_val(&mut engine, "new Date(1/0).getYear()"); + let actual = forward_val(&mut context, "new Date(1/0).getYear()"); assert_eq!(Ok(Value::Rational(f64::NAN)), actual); Ok(()) } #[test] fn date_proto_get_timezone_offset() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "new Date('August 19, 1975 23:15:30 GMT+07:00').getTimezoneOffset() === new Date('August 19, 1975 23:15:30 GMT-02:00').getTimezoneOffset()", ); @@ -416,7 +416,7 @@ fn date_proto_get_timezone_offset() -> Result<(), Box> { assert_eq!(Ok(Value::Boolean(true)), actual); let actual = forward_val( - &mut engine, + &mut context, "new Date('August 19, 1975 23:15:30 GMT+07:00').getTimezoneOffset()", ); @@ -426,7 +426,7 @@ fn date_proto_get_timezone_offset() -> Result<(), Box> { assert_eq!(Ok(Value::Rational(offset_minutes)), actual); let actual = forward_val( - &mut engine, + &mut context, "new Date(1/0, 06, 08, 09, 16, 15, 779).getTimezoneOffset()", ); assert_eq!(Ok(Value::Rational(offset_minutes)), actual); @@ -435,15 +435,15 @@ fn date_proto_get_timezone_offset() -> Result<(), Box> { #[test] fn date_proto_get_utc_date_call() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)).getUTCDate()", ); assert_eq!(Ok(Value::Rational(08f64)), actual); - let actual = forward_val(&mut engine, "new Date(1/0).getUTCDate()"); + let actual = forward_val(&mut context, "new Date(1/0).getUTCDate()"); assert_eq!(Ok(Value::Rational(f64::NAN)), actual); Ok(()) @@ -451,90 +451,90 @@ fn date_proto_get_utc_date_call() -> Result<(), Box> { #[test] fn date_proto_get_utc_day_call() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)).getUTCDay()", ); assert_eq!(Ok(Value::Rational(3f64)), actual); - let actual = forward_val(&mut engine, "new Date(1/0).getUTCDay()"); + let actual = forward_val(&mut context, "new Date(1/0).getUTCDay()"); assert_eq!(Ok(Value::Rational(f64::NAN)), actual); Ok(()) } #[test] fn date_proto_get_utc_full_year_call() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)).getUTCFullYear()", ); assert_eq!(Ok(Value::Rational(2020f64)), actual); - let actual = forward_val(&mut engine, "new Date(1/0).getUTCFullYear()"); + let actual = forward_val(&mut context, "new Date(1/0).getUTCFullYear()"); assert_eq!(Ok(Value::Rational(f64::NAN)), actual); Ok(()) } #[test] fn date_proto_get_utc_hours_call() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)).getUTCHours()", ); assert_eq!(Ok(Value::Rational(09f64)), actual); - let actual = forward_val(&mut engine, "new Date(1/0).getUTCHours()"); + let actual = forward_val(&mut context, "new Date(1/0).getUTCHours()"); assert_eq!(Ok(Value::Rational(f64::NAN)), actual); Ok(()) } #[test] fn date_proto_get_utc_milliseconds_call() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)).getUTCMilliseconds()", ); assert_eq!(Ok(Value::Rational(779f64)), actual); - let actual = forward_val(&mut engine, "new Date(1/0).getUTCMilliseconds()"); + let actual = forward_val(&mut context, "new Date(1/0).getUTCMilliseconds()"); assert_eq!(Ok(Value::Rational(f64::NAN)), actual); Ok(()) } #[test] fn date_proto_get_utc_minutes_call() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)).getUTCMinutes()", ); assert_eq!(Ok(Value::Rational(16f64)), actual); - let actual = forward_val(&mut engine, "new Date(1/0).getUTCMinutes()"); + let actual = forward_val(&mut context, "new Date(1/0).getUTCMinutes()"); assert_eq!(Ok(Value::Rational(f64::NAN)), actual); Ok(()) } #[test] fn date_proto_get_utc_month() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)).getUTCMonth()", ); assert_eq!(Ok(Value::Rational(06f64)), actual); - let actual = forward_val(&mut engine, "new Date(1/0).getUTCMonth()"); + let actual = forward_val(&mut context, "new Date(1/0).getUTCMonth()"); assert_eq!(Ok(Value::Rational(f64::NAN)), actual); Ok(()) @@ -542,25 +542,25 @@ fn date_proto_get_utc_month() -> Result<(), Box> { #[test] fn date_proto_get_utc_seconds() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)).getUTCSeconds()", ); assert_eq!(Ok(Value::Rational(15f64)), actual); - let actual = forward_val(&mut engine, "new Date(1/0).getUTCSeconds()"); + let actual = forward_val(&mut context, "new Date(1/0).getUTCSeconds()"); assert_eq!(Ok(Value::Rational(f64::NAN)), actual); Ok(()) } #[test] fn date_proto_set_date() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_dt_local( - &mut engine, + &mut context, "let dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setDate(21); dt", ); assert_eq!( @@ -570,7 +570,7 @@ fn date_proto_set_date() -> Result<(), Box> { // Date wraps to previous month for 0. let actual = forward_dt_local( - &mut engine, + &mut context, "dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setDate(0); dt", ); assert_eq!( @@ -579,7 +579,7 @@ fn date_proto_set_date() -> Result<(), Box> { ); let actual = forward_dt_local( - &mut engine, + &mut context, "dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setDate(1/0); dt", ); assert_eq!(None, actual); @@ -589,10 +589,10 @@ fn date_proto_set_date() -> Result<(), Box> { #[test] fn date_proto_set_full_year() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_dt_local( - &mut engine, + &mut context, "let dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setFullYear(2012); dt", ); assert_eq!( @@ -601,7 +601,7 @@ fn date_proto_set_full_year() -> Result<(), Box> { ); let actual = forward_dt_local( - &mut engine, + &mut context, "dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setFullYear(2012, 8); dt", ); assert_eq!( @@ -610,7 +610,7 @@ fn date_proto_set_full_year() -> Result<(), Box> { ); let actual = forward_dt_local( - &mut engine, + &mut context, "dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setFullYear(2012, 8, 10); dt", ); assert_eq!( @@ -621,7 +621,7 @@ fn date_proto_set_full_year() -> Result<(), Box> { // Out-of-bounds let actual = forward_dt_local( - &mut engine, + &mut context, "dt = new Date(2020, 07, 08, 09, 16, 15, 779); dt.setFullYear(2012, 35); dt", ); assert_eq!( @@ -630,7 +630,7 @@ fn date_proto_set_full_year() -> Result<(), Box> { ); let actual = forward_dt_local( - &mut engine, + &mut context, "dt = new Date(2020, 07, 08, 09, 16, 15, 779); dt.setFullYear(2012, -35); dt", ); assert_eq!( @@ -639,7 +639,7 @@ fn date_proto_set_full_year() -> Result<(), Box> { ); let actual = forward_dt_local( - &mut engine, + &mut context, "dt = new Date(2020, 07, 08, 09, 16, 15, 779); dt.setFullYear(2012, 9, 950); dt", ); assert_eq!( @@ -648,7 +648,7 @@ fn date_proto_set_full_year() -> Result<(), Box> { ); let actual = forward_dt_local( - &mut engine, + &mut context, "dt = new Date(2020, 07, 08, 09, 16, 15, 779); dt.setFullYear(2012, 9, -950); dt", ); assert_eq!( @@ -661,10 +661,10 @@ fn date_proto_set_full_year() -> Result<(), Box> { #[test] fn date_proto_set_hours() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_dt_local( - &mut engine, + &mut context, "let dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setHours(11); dt", ); assert_eq!( @@ -673,7 +673,7 @@ fn date_proto_set_hours() -> Result<(), Box> { ); let actual = forward_dt_local( - &mut engine, + &mut context, "dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setHours(11, 35); dt", ); assert_eq!( @@ -682,7 +682,7 @@ fn date_proto_set_hours() -> Result<(), Box> { ); let actual = forward_dt_local( - &mut engine, + &mut context, "dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setHours(11, 35, 23); dt", ); assert_eq!( @@ -691,7 +691,7 @@ fn date_proto_set_hours() -> Result<(), Box> { ); let actual = forward_dt_local( - &mut engine, + &mut context, "dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setHours(11, 35, 23, 537); dt", ); assert_eq!( @@ -702,7 +702,7 @@ fn date_proto_set_hours() -> Result<(), Box> { // Out-of-bounds let actual = forward_dt_local( - &mut engine, + &mut context, "dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setHours(10000, 20000, 30000, 40123); dt", ); assert_eq!( @@ -715,10 +715,10 @@ fn date_proto_set_hours() -> Result<(), Box> { #[test] fn date_proto_set_milliseconds() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_dt_local( - &mut engine, + &mut context, "let dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setMilliseconds(597); dt", ); assert_eq!( @@ -730,7 +730,7 @@ fn date_proto_set_milliseconds() -> Result<(), Box> { // Thorough tests are done by setHours let actual = forward_dt_local( - &mut engine, + &mut context, "dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setMilliseconds(40123); dt", ); assert_eq!( @@ -743,10 +743,10 @@ fn date_proto_set_milliseconds() -> Result<(), Box> { #[test] fn date_proto_set_minutes() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_dt_local( - &mut engine, + &mut context, "let dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setMinutes(11); dt", ); assert_eq!( @@ -755,7 +755,7 @@ fn date_proto_set_minutes() -> Result<(), Box> { ); let actual = forward_dt_local( - &mut engine, + &mut context, "dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setMinutes(11, 35); dt", ); assert_eq!( @@ -764,7 +764,7 @@ fn date_proto_set_minutes() -> Result<(), Box> { ); let actual = forward_dt_local( - &mut engine, + &mut context, "dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setMinutes(11, 35, 537); dt", ); assert_eq!( @@ -776,7 +776,7 @@ fn date_proto_set_minutes() -> Result<(), Box> { // Thorough tests are done by setHours let actual = forward_dt_local( - &mut engine, + &mut context, "dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setMinutes(600000, 30000, 40123); dt", ); assert_eq!( @@ -789,10 +789,10 @@ fn date_proto_set_minutes() -> Result<(), Box> { #[test] fn date_proto_set_month() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_dt_local( - &mut engine, + &mut context, "let dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setMonth(11); dt", ); assert_eq!( @@ -801,7 +801,7 @@ fn date_proto_set_month() -> Result<(), Box> { ); let actual = forward_dt_local( - &mut engine, + &mut context, "dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setMonth(11, 16); dt", ); assert_eq!( @@ -813,7 +813,7 @@ fn date_proto_set_month() -> Result<(), Box> { // Thorough tests are done by setFullYear let actual = forward_dt_local( - &mut engine, + &mut context, "dt = new Date(2020, 07, 08, 09, 16, 15, 779); dt.setMonth(40, 83); dt", ); assert_eq!( @@ -826,10 +826,10 @@ fn date_proto_set_month() -> Result<(), Box> { #[test] fn date_proto_set_seconds() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_dt_local( - &mut engine, + &mut context, "let dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setSeconds(11); dt", ); assert_eq!( @@ -838,7 +838,7 @@ fn date_proto_set_seconds() -> Result<(), Box> { ); let actual = forward_dt_local( - &mut engine, + &mut context, "dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setSeconds(11, 487); dt", ); assert_eq!( @@ -850,7 +850,7 @@ fn date_proto_set_seconds() -> Result<(), Box> { // Thorough tests are done by setHour let actual = forward_dt_local( - &mut engine, + &mut context, "dt = new Date(2020, 07, 08, 09, 16, 15, 779); dt.setSeconds(40000000, 40123); dt", ); assert_eq!( @@ -863,10 +863,10 @@ fn date_proto_set_seconds() -> Result<(), Box> { #[test] fn set_year() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_dt_local( - &mut engine, + &mut context, "let dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setYear(98); dt", ); assert_eq!( @@ -875,7 +875,7 @@ fn set_year() -> Result<(), Box> { ); let actual = forward_dt_local( - &mut engine, + &mut context, "dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.setYear(2001); dt", ); assert_eq!( @@ -888,10 +888,10 @@ fn set_year() -> Result<(), Box> { #[test] fn date_proto_set_time() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_dt_local( - &mut engine, + &mut context, "let dt = new Date(); dt.setTime(new Date(2020, 06, 08, 09, 16, 15, 779).getTime()); dt", ); assert_eq!( @@ -904,10 +904,10 @@ fn date_proto_set_time() -> Result<(), Box> { #[test] fn date_proto_set_utc_date() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_dt_utc( - &mut engine, + &mut context, "let dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCDate(21); dt", ); assert_eq!( @@ -917,7 +917,7 @@ fn date_proto_set_utc_date() -> Result<(), Box> { // Date wraps to previous month for 0. let actual = forward_dt_utc( - &mut engine, + &mut context, "dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCDate(0); dt", ); assert_eq!( @@ -926,7 +926,7 @@ fn date_proto_set_utc_date() -> Result<(), Box> { ); let actual = forward_dt_utc( - &mut engine, + &mut context, "dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCDate(1/0); dt", ); assert_eq!(None, actual); @@ -936,10 +936,10 @@ fn date_proto_set_utc_date() -> Result<(), Box> { #[test] fn date_proto_set_utc_full_year() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_dt_utc( - &mut engine, + &mut context, "let dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCFullYear(2012); dt", ); assert_eq!( @@ -948,7 +948,7 @@ fn date_proto_set_utc_full_year() -> Result<(), Box> { ); let actual = forward_dt_utc( - &mut engine, + &mut context, "dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCFullYear(2012, 8); dt", ); assert_eq!( @@ -957,7 +957,7 @@ fn date_proto_set_utc_full_year() -> Result<(), Box> { ); let actual = forward_dt_utc( - &mut engine, + &mut context, "dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCFullYear(2012, 8, 10); dt", ); assert_eq!( @@ -968,7 +968,7 @@ fn date_proto_set_utc_full_year() -> Result<(), Box> { // Out-of-bounds let actual = forward_dt_utc( - &mut engine, + &mut context, "dt = new Date(Date.UTC(2020, 07, 08, 09, 16, 15, 779)); dt.setUTCFullYear(2012, 35); dt", ); assert_eq!( @@ -977,7 +977,7 @@ fn date_proto_set_utc_full_year() -> Result<(), Box> { ); let actual = forward_dt_utc( - &mut engine, + &mut context, "dt = new Date(Date.UTC(2020, 07, 08, 09, 16, 15, 779)); dt.setUTCFullYear(2012, -35); dt", ); assert_eq!( @@ -986,7 +986,7 @@ fn date_proto_set_utc_full_year() -> Result<(), Box> { ); let actual = forward_dt_utc( - &mut engine, + &mut context, "dt = new Date(Date.UTC(2020, 07, 08, 09, 16, 15, 779)); dt.setUTCFullYear(2012, 9, 950); dt", ); assert_eq!( @@ -995,7 +995,7 @@ fn date_proto_set_utc_full_year() -> Result<(), Box> { ); let actual = forward_dt_utc( - &mut engine, + &mut context, "dt = new Date(Date.UTC(2020, 07, 08, 09, 16, 15, 779)); dt.setUTCFullYear(2012, 9, -950); dt", ); assert_eq!( @@ -1008,10 +1008,10 @@ fn date_proto_set_utc_full_year() -> Result<(), Box> { #[test] fn date_proto_set_utc_hours() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_dt_utc( - &mut engine, + &mut context, "let dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCHours(11); dt", ); assert_eq!( @@ -1020,7 +1020,7 @@ fn date_proto_set_utc_hours() -> Result<(), Box> { ); let actual = forward_dt_utc( - &mut engine, + &mut context, "dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCHours(11, 35); dt", ); assert_eq!( @@ -1029,7 +1029,7 @@ fn date_proto_set_utc_hours() -> Result<(), Box> { ); let actual = forward_dt_utc( - &mut engine, + &mut context, "dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCHours(11, 35, 23); dt", ); assert_eq!( @@ -1038,7 +1038,7 @@ fn date_proto_set_utc_hours() -> Result<(), Box> { ); let actual = forward_dt_utc( - &mut engine, + &mut context, "dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCHours(11, 35, 23, 537); dt", ); assert_eq!( @@ -1049,7 +1049,7 @@ fn date_proto_set_utc_hours() -> Result<(), Box> { // Out-of-bounds let actual = forward_dt_utc( - &mut engine, + &mut context, "dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCHours(10000, 20000, 30000, 40123); dt", ); assert_eq!( @@ -1062,10 +1062,10 @@ fn date_proto_set_utc_hours() -> Result<(), Box> { #[test] fn date_proto_set_utc_milliseconds() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_dt_utc( - &mut engine, + &mut context, "let dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCMilliseconds(597); dt", ); assert_eq!( @@ -1077,7 +1077,7 @@ fn date_proto_set_utc_milliseconds() -> Result<(), Box> { // Thorough tests are done by setHours let actual = forward_dt_utc( - &mut engine, + &mut context, "dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCMilliseconds(40123); dt", ); assert_eq!( @@ -1090,10 +1090,10 @@ fn date_proto_set_utc_milliseconds() -> Result<(), Box> { #[test] fn date_proto_set_utc_minutes() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_dt_utc( - &mut engine, + &mut context, "let dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCMinutes(11); dt", ); assert_eq!( @@ -1102,7 +1102,7 @@ fn date_proto_set_utc_minutes() -> Result<(), Box> { ); let actual = forward_dt_utc( - &mut engine, + &mut context, "dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCMinutes(11, 35); dt", ); assert_eq!( @@ -1111,7 +1111,7 @@ fn date_proto_set_utc_minutes() -> Result<(), Box> { ); let actual = forward_dt_utc( - &mut engine, + &mut context, "dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCMinutes(11, 35, 537); dt", ); assert_eq!( @@ -1123,7 +1123,7 @@ fn date_proto_set_utc_minutes() -> Result<(), Box> { // Thorough tests are done by setHours let actual = forward_dt_utc( - &mut engine, + &mut context, "dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCMinutes(600000, 30000, 40123); dt", ); assert_eq!( @@ -1136,10 +1136,10 @@ fn date_proto_set_utc_minutes() -> Result<(), Box> { #[test] fn date_proto_set_utc_month() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_dt_utc( - &mut engine, + &mut context, "let dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCMonth(11); dt", ); assert_eq!( @@ -1148,7 +1148,7 @@ fn date_proto_set_utc_month() -> Result<(), Box> { ); let actual = forward_dt_utc( - &mut engine, + &mut context, "dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCMonth(11, 16); dt", ); assert_eq!( @@ -1160,7 +1160,7 @@ fn date_proto_set_utc_month() -> Result<(), Box> { // Thorough tests are done by setFullYear let actual = forward_dt_utc( - &mut engine, + &mut context, "dt = new Date(Date.UTC(2020, 07, 08, 09, 16, 15, 779)); dt.setUTCMonth(40, 83); dt", ); assert_eq!( @@ -1173,10 +1173,10 @@ fn date_proto_set_utc_month() -> Result<(), Box> { #[test] fn date_proto_set_utc_seconds() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_dt_utc( - &mut engine, + &mut context, "let dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCSeconds(11); dt", ); assert_eq!( @@ -1185,7 +1185,7 @@ fn date_proto_set_utc_seconds() -> Result<(), Box> { ); let actual = forward_dt_utc( - &mut engine, + &mut context, "dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.setUTCSeconds(11, 487); dt", ); assert_eq!( @@ -1197,7 +1197,7 @@ fn date_proto_set_utc_seconds() -> Result<(), Box> { // Thorough tests are done by setHour let actual = forward_dt_utc( - &mut engine, + &mut context, "dt = new Date(Date.UTC(2020, 07, 08, 09, 16, 15, 779)); dt.setUTCSeconds(40000000, 40123); dt", ); assert_eq!( @@ -1210,10 +1210,10 @@ fn date_proto_set_utc_seconds() -> Result<(), Box> { #[test] fn date_proto_to_date_string() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "let dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.toDateString()", ) .expect("Successful eval"); @@ -1224,10 +1224,10 @@ fn date_proto_to_date_string() -> Result<(), Box> { #[test] fn date_proto_to_gmt_string() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "let dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.toGMTString()", ) .expect("Successful eval"); @@ -1238,10 +1238,10 @@ fn date_proto_to_gmt_string() -> Result<(), Box> { #[test] fn date_proto_to_iso_string() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "let dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.toISOString()", ) .expect("Successful eval"); @@ -1252,10 +1252,10 @@ fn date_proto_to_iso_string() -> Result<(), Box> { #[test] fn date_proto_to_json() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "let dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.toJSON()", ) .expect("Successful eval"); @@ -1266,10 +1266,10 @@ fn date_proto_to_json() -> Result<(), Box> { #[test] fn date_proto_to_string() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "let dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.toString()", ) .ok(); @@ -1288,10 +1288,10 @@ fn date_proto_to_string() -> Result<(), Box> { #[test] fn date_proto_to_time_string() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "let dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.toTimeString()", ) .ok(); @@ -1308,10 +1308,10 @@ fn date_proto_to_time_string() -> Result<(), Box> { #[test] fn date_proto_to_utc_string() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "let dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.toUTCString()", ) .expect("Successful eval"); @@ -1322,10 +1322,10 @@ fn date_proto_to_utc_string() -> Result<(), Box> { #[test] fn date_proto_value_of() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)).valueOf()", ) .expect("Successful eval"); @@ -1336,10 +1336,10 @@ fn date_proto_value_of() -> Result<(), Box> { #[test] fn date_neg() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "-new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779))", ) .expect("Successful eval"); @@ -1350,10 +1350,10 @@ fn date_neg() -> Result<(), Box> { #[test] fn date_json() -> Result<(), Box> { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward_val( - &mut engine, + &mut context, "JSON.stringify({ date: new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)) })", ) .expect("Successful eval"); diff --git a/boa/src/builtins/error/eval.rs b/boa/src/builtins/error/eval.rs index 6845e8a9d6..fb2d4a6b54 100644 --- a/boa/src/builtins/error/eval.rs +++ b/boa/src/builtins/error/eval.rs @@ -56,9 +56,13 @@ impl EvalError { pub(crate) const LENGTH: usize = 1; /// Create a new error object. - pub(crate) fn constructor(this: &Value, args: &[Value], ctx: &mut Context) -> Result { + pub(crate) fn constructor( + this: &Value, + args: &[Value], + context: &mut Context, + ) -> Result { if let Some(message) = args.get(0) { - this.set_field("message", message.to_string(ctx)?); + this.set_field("message", message.to_string(context)?); } // This value is used by console.log and other routines to match Object type diff --git a/boa/src/builtins/error/mod.rs b/boa/src/builtins/error/mod.rs index 4cb9c7c5ae..a6e4a0af98 100644 --- a/boa/src/builtins/error/mod.rs +++ b/boa/src/builtins/error/mod.rs @@ -73,9 +73,13 @@ impl Error { /// `Error( message )` /// /// Create a new error object. - pub(crate) fn constructor(this: &Value, args: &[Value], ctx: &mut Context) -> Result { + pub(crate) fn constructor( + this: &Value, + args: &[Value], + context: &mut Context, + ) -> Result { if let Some(message) = args.get(0) { - this.set_field("message", message.to_string(ctx)?); + this.set_field("message", message.to_string(context)?); } // This value is used by console.log and other routines to match Object type diff --git a/boa/src/builtins/error/range.rs b/boa/src/builtins/error/range.rs index e4eb1e95bf..55e7776894 100644 --- a/boa/src/builtins/error/range.rs +++ b/boa/src/builtins/error/range.rs @@ -54,9 +54,13 @@ impl RangeError { pub(crate) const LENGTH: usize = 1; /// Create a new error object. - pub(crate) fn constructor(this: &Value, args: &[Value], ctx: &mut Context) -> Result { + pub(crate) fn constructor( + this: &Value, + args: &[Value], + context: &mut Context, + ) -> Result { if let Some(message) = args.get(0) { - this.set_field("message", message.to_string(ctx)?); + this.set_field("message", message.to_string(context)?); } // This value is used by console.log and other routines to match Object type diff --git a/boa/src/builtins/error/reference.rs b/boa/src/builtins/error/reference.rs index fe74caa9f5..d77a9775bd 100644 --- a/boa/src/builtins/error/reference.rs +++ b/boa/src/builtins/error/reference.rs @@ -53,9 +53,13 @@ impl ReferenceError { pub(crate) const LENGTH: usize = 1; /// Create a new error object. - pub(crate) fn constructor(this: &Value, args: &[Value], ctx: &mut Context) -> Result { + pub(crate) fn constructor( + this: &Value, + args: &[Value], + context: &mut Context, + ) -> Result { if let Some(message) = args.get(0) { - this.set_field("message", message.to_string(ctx)?); + this.set_field("message", message.to_string(context)?); } // This value is used by console.log and other routines to match Object type diff --git a/boa/src/builtins/error/syntax.rs b/boa/src/builtins/error/syntax.rs index 1d68b7d170..92ca95d150 100644 --- a/boa/src/builtins/error/syntax.rs +++ b/boa/src/builtins/error/syntax.rs @@ -1,7 +1,7 @@ //! This module implements the global `SyntaxError` object. //! //! The SyntaxError object represents an error when trying to interpret syntactically invalid code. -//! It is thrown when the JavaScript engine encounters tokens or token order that does not conform +//! It is thrown when the JavaScript context encounters tokens or token order that does not conform //! to the syntax of the language when parsing code. //! //! More information: @@ -56,9 +56,13 @@ impl SyntaxError { pub(crate) const LENGTH: usize = 1; /// Create a new error object. - pub(crate) fn constructor(this: &Value, args: &[Value], ctx: &mut Context) -> Result { + pub(crate) fn constructor( + this: &Value, + args: &[Value], + context: &mut Context, + ) -> Result { if let Some(message) = args.get(0) { - this.set_field("message", message.to_string(ctx)?); + this.set_field("message", message.to_string(context)?); } // This value is used by console.log and other routines to match Object type diff --git a/boa/src/builtins/error/tests.rs b/boa/src/builtins/error/tests.rs index 5332f706b0..68c9813ca0 100644 --- a/boa/src/builtins/error/tests.rs +++ b/boa/src/builtins/error/tests.rs @@ -2,7 +2,7 @@ use crate::{forward, Context}; #[test] fn error_to_string() { - let mut ctx = Context::new(); + let mut context = Context::new(); let init = r#" let e = new Error('1'); let name = new Error(); @@ -13,68 +13,74 @@ fn error_to_string() { let syntax_e = new SyntaxError('4'); let type_e = new TypeError('5'); "#; - forward(&mut ctx, init); - assert_eq!(forward(&mut ctx, "e.toString()"), "\"Error: 1\""); - assert_eq!(forward(&mut ctx, "name.toString()"), "\"Error\""); - assert_eq!(forward(&mut ctx, "message.toString()"), "\"message\""); - assert_eq!(forward(&mut ctx, "range_e.toString()"), "\"RangeError: 2\""); + forward(&mut context, init); + assert_eq!(forward(&mut context, "e.toString()"), "\"Error: 1\""); + assert_eq!(forward(&mut context, "name.toString()"), "\"Error\""); + assert_eq!(forward(&mut context, "message.toString()"), "\"message\""); assert_eq!( - forward(&mut ctx, "ref_e.toString()"), + forward(&mut context, "range_e.toString()"), + "\"RangeError: 2\"" + ); + assert_eq!( + forward(&mut context, "ref_e.toString()"), "\"ReferenceError: 3\"" ); assert_eq!( - forward(&mut ctx, "syntax_e.toString()"), + forward(&mut context, "syntax_e.toString()"), "\"SyntaxError: 4\"" ); - assert_eq!(forward(&mut ctx, "type_e.toString()"), "\"TypeError: 5\""); + assert_eq!( + forward(&mut context, "type_e.toString()"), + "\"TypeError: 5\"" + ); } #[test] fn eval_error_name() { - let mut ctx = Context::new(); - assert_eq!(forward(&mut ctx, "EvalError.name"), "\"EvalError\""); + let mut context = Context::new(); + assert_eq!(forward(&mut context, "EvalError.name"), "\"EvalError\""); } #[test] fn eval_error_length() { - let mut ctx = Context::new(); - assert_eq!(forward(&mut ctx, "EvalError.length"), "1"); + let mut context = Context::new(); + assert_eq!(forward(&mut context, "EvalError.length"), "1"); } #[test] fn eval_error_to_string() { - let mut ctx = Context::new(); + let mut context = Context::new(); assert_eq!( - forward(&mut ctx, "new EvalError('hello').toString()"), + forward(&mut context, "new EvalError('hello').toString()"), "\"EvalError: hello\"" ); assert_eq!( - forward(&mut ctx, "new EvalError().toString()"), + forward(&mut context, "new EvalError().toString()"), "\"EvalError\"" ); } #[test] fn uri_error_name() { - let mut ctx = Context::new(); - assert_eq!(forward(&mut ctx, "URIError.name"), "\"URIError\""); + let mut context = Context::new(); + assert_eq!(forward(&mut context, "URIError.name"), "\"URIError\""); } #[test] fn uri_error_length() { - let mut ctx = Context::new(); - assert_eq!(forward(&mut ctx, "URIError.length"), "1"); + let mut context = Context::new(); + assert_eq!(forward(&mut context, "URIError.length"), "1"); } #[test] fn uri_error_to_string() { - let mut ctx = Context::new(); + let mut context = Context::new(); assert_eq!( - forward(&mut ctx, "new URIError('hello').toString()"), + forward(&mut context, "new URIError('hello').toString()"), "\"URIError: hello\"" ); assert_eq!( - forward(&mut ctx, "new URIError().toString()"), + forward(&mut context, "new URIError().toString()"), "\"URIError\"" ); } diff --git a/boa/src/builtins/error/type.rs b/boa/src/builtins/error/type.rs index bc2e6f4f14..f450c607e1 100644 --- a/boa/src/builtins/error/type.rs +++ b/boa/src/builtins/error/type.rs @@ -59,9 +59,13 @@ impl TypeError { pub(crate) const LENGTH: usize = 1; /// Create a new error object. - pub(crate) fn constructor(this: &Value, args: &[Value], ctx: &mut Context) -> Result { + pub(crate) fn constructor( + this: &Value, + args: &[Value], + context: &mut Context, + ) -> Result { if let Some(message) = args.get(0) { - this.set_field("message", message.to_string(ctx)?); + this.set_field("message", message.to_string(context)?); } // This value is used by console.log and other routines to match Object type diff --git a/boa/src/builtins/error/uri.rs b/boa/src/builtins/error/uri.rs index ca8c860328..0fdbc407b7 100644 --- a/boa/src/builtins/error/uri.rs +++ b/boa/src/builtins/error/uri.rs @@ -55,9 +55,13 @@ impl UriError { pub(crate) const LENGTH: usize = 1; /// Create a new error object. - pub(crate) fn constructor(this: &Value, args: &[Value], ctx: &mut Context) -> Result { + pub(crate) fn constructor( + this: &Value, + args: &[Value], + context: &mut Context, + ) -> Result { if let Some(message) = args.get(0) { - this.set_field("message", message.to_string(ctx)?); + this.set_field("message", message.to_string(context)?); } // This value is used by console.log and other routines to match Object type diff --git a/boa/src/builtins/function/mod.rs b/boa/src/builtins/function/mod.rs index 0b4c66bda9..3eea345a58 100644 --- a/boa/src/builtins/function/mod.rs +++ b/boa/src/builtins/function/mod.rs @@ -14,26 +14,26 @@ use crate::{ builtins::{Array, BuiltIn}, environment::lexical_environment::Environment, + gc::{empty_trace, Finalize, Trace}, object::{ConstructorBuilder, FunctionBuilder, GcObject, Object, ObjectData}, property::{Attribute, DataDescriptor}, syntax::ast::node::{FormalParameter, RcStatementList}, BoaProfiler, Context, Result, Value, }; use bitflags::bitflags; -use gc::{unsafe_empty_trace, Finalize, Trace}; use std::fmt::{self, Debug}; #[cfg(test)] mod tests; -/// _fn(this, arguments, ctx) -> ResultValue_ - The signature of a built-in function +/// _fn(this, arguments, context) -> 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); unsafe impl Trace for BuiltInFunction { - unsafe_empty_trace!(); + empty_trace!(); } impl From for BuiltInFunction { @@ -88,7 +88,7 @@ impl FunctionFlags { } unsafe impl Trace for FunctionFlags { - unsafe_empty_trace!(); + empty_trace!(); } /// Boa representation of a Function Object. @@ -114,11 +114,11 @@ impl Function { param: &FormalParameter, index: usize, args_list: &[Value], - interpreter: &mut Context, + context: &mut Context, local_env: &Environment, ) { // Create array of values - let array = Array::new_array(interpreter).unwrap(); + let array = Array::new_array(context).unwrap(); Array::add_to_array_object(&array, &args_list[index..]).unwrap(); // Create binding diff --git a/boa/src/builtins/function/tests.rs b/boa/src/builtins/function/tests.rs index ebc0e9c78b..b130f5b148 100644 --- a/boa/src/builtins/function/tests.rs +++ b/boa/src/builtins/function/tests.rs @@ -3,7 +3,7 @@ use crate::{forward, forward_val, Context}; #[allow(clippy::float_cmp)] #[test] fn arguments_object() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" function jason(a, b) { @@ -12,13 +12,13 @@ fn arguments_object() { var val = jason(100, 6); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let return_val = forward_val(&mut engine, "val").expect("value expected"); + let return_val = forward_val(&mut context, "val").expect("value expected"); assert_eq!(return_val.is_integer(), true); assert_eq!( return_val - .to_i32(&mut engine) + .to_i32(&mut context) .expect("Could not convert value to i32"), 100 ); @@ -26,18 +26,18 @@ fn arguments_object() { #[test] fn self_mutating_function_when_calling() { - let mut engine = Context::new(); + let mut context = Context::new(); let func = r#" function x() { x.y = 3; } x(); "#; - eprintln!("{}", forward(&mut engine, func)); - let y = forward_val(&mut engine, "x.y").expect("value expected"); + eprintln!("{}", forward(&mut context, func)); + let y = forward_val(&mut context, "x.y").expect("value expected"); assert_eq!(y.is_integer(), true); assert_eq!( - y.to_i32(&mut engine) + y.to_i32(&mut context) .expect("Could not convert value to i32"), 3 ); @@ -45,18 +45,18 @@ fn self_mutating_function_when_calling() { #[test] fn self_mutating_function_when_constructing() { - let mut engine = Context::new(); + let mut context = Context::new(); let func = r#" function x() { x.y = 3; } new x(); "#; - eprintln!("{}", forward(&mut engine, func)); - let y = forward_val(&mut engine, "x.y").expect("value expected"); + eprintln!("{}", forward(&mut context, func)); + let y = forward_val(&mut context, "x.y").expect("value expected"); assert_eq!(y.is_integer(), true); assert_eq!( - y.to_i32(&mut engine) + y.to_i32(&mut context) .expect("Could not convert value to i32"), 3 ); @@ -64,41 +64,41 @@ fn self_mutating_function_when_constructing() { #[test] fn call_function_prototype() { - let mut engine = Context::new(); + let mut context = Context::new(); let func = r#" Function.prototype() "#; - let value = forward_val(&mut engine, func).unwrap(); + let value = forward_val(&mut context, func).unwrap(); assert!(value.is_undefined()); } #[test] fn call_function_prototype_with_arguments() { - let mut engine = Context::new(); + let mut context = Context::new(); let func = r#" Function.prototype(1, "", new String("")) "#; - let value = forward_val(&mut engine, func).unwrap(); + let value = forward_val(&mut context, func).unwrap(); assert!(value.is_undefined()); } #[test] fn call_function_prototype_with_new() { - let mut engine = Context::new(); + let mut context = Context::new(); let func = r#" new Function.prototype() "#; - let value = forward_val(&mut engine, func); + let value = forward_val(&mut context, func); assert!(value.is_err()); } #[test] fn function_prototype_name() { - let mut engine = Context::new(); + let mut context = Context::new(); let func = r#" Function.prototype.name "#; - let value = forward_val(&mut engine, func).unwrap(); + let value = forward_val(&mut context, func).unwrap(); assert!(value.is_string()); assert!(value.as_string().unwrap().is_empty()); } @@ -106,43 +106,43 @@ fn function_prototype_name() { #[test] #[allow(clippy::float_cmp)] fn function_prototype_length() { - let mut engine = Context::new(); + let mut context = Context::new(); let func = r#" Function.prototype.length "#; - let value = forward_val(&mut engine, func).unwrap(); + let value = forward_val(&mut context, func).unwrap(); assert!(value.is_number()); assert_eq!(value.as_number().unwrap(), 0.0); } #[test] fn function_prototype_call() { - let mut engine = Context::new(); + let mut context = Context::new(); let func = r#" let e = new Error() Object.prototype.toString.call(e) "#; - let value = forward_val(&mut engine, func).unwrap(); + let value = forward_val(&mut context, func).unwrap(); assert!(value.is_string()); assert_eq!(value.as_string().unwrap(), "[object Error]"); } #[test] fn function_prototype_call_throw() { - let mut engine = Context::new(); + let mut context = Context::new(); let throw = r#" let call = Function.prototype.call; call(call) "#; - let value = forward_val(&mut engine, throw).unwrap_err(); + let value = forward_val(&mut context, throw).unwrap_err(); assert!(value.is_object()); - let string = value.to_string(&mut engine).unwrap(); + let string = value.to_string(&mut context).unwrap(); assert!(string.starts_with("TypeError")) } #[test] fn function_prototype_call_multiple_args() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" function f(a, b) { this.a = a; @@ -151,13 +151,13 @@ fn function_prototype_call_multiple_args() { let o = {a: 0, b: 0}; f.call(o, 1, 2); "#; - forward_val(&mut engine, init).unwrap(); - let boolean = forward_val(&mut engine, "o.a == 1") + forward_val(&mut context, init).unwrap(); + let boolean = forward_val(&mut context, "o.a == 1") .unwrap() .as_boolean() .unwrap(); assert!(boolean); - let boolean = forward_val(&mut engine, "o.b == 2") + let boolean = forward_val(&mut context, "o.b == 2") .unwrap() .as_boolean() .unwrap(); @@ -166,21 +166,21 @@ fn function_prototype_call_multiple_args() { #[test] fn function_prototype_apply() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" const numbers = [6, 7, 3, 4, 2]; const max = Math.max.apply(null, numbers); const min = Math.min.apply(null, numbers); "#; - forward_val(&mut engine, init).unwrap(); + forward_val(&mut context, init).unwrap(); - let boolean = forward_val(&mut engine, "max == 7") + let boolean = forward_val(&mut context, "max == 7") .unwrap() .as_boolean() .unwrap(); assert!(boolean); - let boolean = forward_val(&mut engine, "min == 2") + let boolean = forward_val(&mut context, "min == 2") .unwrap() .as_boolean() .unwrap(); @@ -189,7 +189,7 @@ fn function_prototype_apply() { #[test] fn function_prototype_apply_on_object() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" function f(a, b) { this.a = a; @@ -198,15 +198,15 @@ fn function_prototype_apply_on_object() { let o = {a: 0, b: 0}; f.apply(o, [1, 2]); "#; - forward_val(&mut engine, init).unwrap(); + forward_val(&mut context, init).unwrap(); - let boolean = forward_val(&mut engine, "o.a == 1") + let boolean = forward_val(&mut context, "o.a == 1") .unwrap() .as_boolean() .unwrap(); assert!(boolean); - let boolean = forward_val(&mut engine, "o.b == 2") + let boolean = forward_val(&mut context, "o.b == 2") .unwrap() .as_boolean() .unwrap(); diff --git a/boa/src/builtins/infinity/mod.rs b/boa/src/builtins/infinity/mod.rs index 8691ddc8c7..c04b93afee 100644 --- a/boa/src/builtins/infinity/mod.rs +++ b/boa/src/builtins/infinity/mod.rs @@ -25,7 +25,7 @@ impl BuiltIn for Infinity { Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT } - fn init(_context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(_: &mut Context) -> (&'static str, Value, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); (Self::NAME, f64::INFINITY.into(), Self::attribute()) diff --git a/boa/src/builtins/iterable/mod.rs b/boa/src/builtins/iterable/mod.rs index 8e4c08064a..0609d2b356 100644 --- a/boa/src/builtins/iterable/mod.rs +++ b/boa/src/builtins/iterable/mod.rs @@ -16,32 +16,35 @@ pub struct IteratorPrototypes { } impl IteratorPrototypes { - pub fn init(ctx: &mut Context) -> Self { - let iterator_prototype = create_iterator_prototype(ctx); + pub(crate) fn init(context: &mut Context) -> Self { + let iterator_prototype = create_iterator_prototype(context); Self { iterator_prototype: iterator_prototype .as_object() .expect("Iterator prototype is not an object"), - array_iterator: ArrayIterator::create_prototype(ctx, iterator_prototype.clone()) + array_iterator: ArrayIterator::create_prototype(context, iterator_prototype.clone()) .as_object() .expect("Array Iterator Prototype is not an object"), - string_iterator: StringIterator::create_prototype(ctx, iterator_prototype.clone()) + string_iterator: StringIterator::create_prototype(context, iterator_prototype.clone()) .as_object() .expect("String Iterator Prototype is not an object"), - map_iterator: MapIterator::create_prototype(ctx, iterator_prototype) + map_iterator: MapIterator::create_prototype(context, iterator_prototype) .as_object() .expect("Map Iterator Prototype is not an object"), } } + #[inline] pub fn array_iterator(&self) -> GcObject { self.array_iterator.clone() } + #[inline] pub fn iterator_prototype(&self) -> GcObject { self.iterator_prototype.clone() } + #[inline] pub fn string_iterator(&self) -> GcObject { self.string_iterator.clone() } @@ -54,8 +57,8 @@ impl IteratorPrototypes { /// CreateIterResultObject( value, done ) /// /// Generates an object supporting the IteratorResult interface. -pub fn create_iter_result_object(ctx: &mut Context, value: Value, done: bool) -> Value { - let object = Value::new_object(Some(ctx.global_object())); +pub fn create_iter_result_object(context: &mut Context, value: Value, done: bool) -> Value { + let object = Value::new_object(Some(context.global_object())); // TODO: Fix attributes of value and done let value_property = DataDescriptor::new(value, Attribute::all()); let done_property = DataDescriptor::new(done, Attribute::all()); @@ -65,17 +68,17 @@ pub fn create_iter_result_object(ctx: &mut Context, value: Value, done: bool) -> } /// Get an iterator record -pub fn get_iterator(ctx: &mut Context, iterable: Value) -> Result { +pub fn get_iterator(context: &mut Context, iterable: Value) -> Result { // TODO: Fix the accessor handling let iterator_function = iterable - .get_property(ctx.well_known_symbols().iterator_symbol()) + .get_property(context.well_known_symbols().iterator_symbol()) .map(|p| p.as_data_descriptor().unwrap().value()) - .ok_or_else(|| ctx.construct_type_error("Not an iterable"))?; - let iterator_object = ctx.call(&iterator_function, &iterable, &[])?; + .ok_or_else(|| context.construct_type_error("Not an iterable"))?; + let iterator_object = context.call(&iterator_function, &iterable, &[])?; let next_function = iterator_object .get_property("next") .map(|p| p.as_data_descriptor().unwrap().value()) - .ok_or_else(|| ctx.construct_type_error("Could not find property `next`"))?; + .ok_or_else(|| context.construct_type_error("Could not find property `next`"))?; Ok(IteratorRecord::new(iterator_object, next_function)) } @@ -85,11 +88,11 @@ pub fn get_iterator(ctx: &mut Context, iterable: Value) -> Result Value { +fn create_iterator_prototype(context: &mut Context) -> Value { let _timer = BoaProfiler::global().start_event("Iterator Prototype", "init"); - let symbol_iterator = ctx.well_known_symbols().iterator_symbol(); - let iterator_prototype = ObjectInitializer::new(ctx) + let symbol_iterator = context.well_known_symbols().iterator_symbol(); + let iterator_prototype = ObjectInitializer::new(context) .function( |v, _, _| Ok(v.clone()), (symbol_iterator, "[Symbol.iterator]"), @@ -120,14 +123,14 @@ impl IteratorRecord { /// - [ECMA reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-iteratornext - pub(crate) fn next(&self, ctx: &mut Context) -> Result { - let next = ctx.call(&self.next_function, &self.iterator_object, &[])?; + pub(crate) fn next(&self, context: &mut Context) -> Result { + let next = context.call(&self.next_function, &self.iterator_object, &[])?; // FIXME: handle accessor descriptors let done = next .get_property("done") .map(|p| p.as_data_descriptor().unwrap().value()) .and_then(|v| v.as_boolean()) - .ok_or_else(|| ctx.construct_type_error("Could not find property `done`"))?; + .ok_or_else(|| context.construct_type_error("Could not find property `done`"))?; // FIXME: handle accessor descriptors let next_result = next diff --git a/boa/src/builtins/json/mod.rs b/boa/src/builtins/json/mod.rs index 852c28e8c3..9567bd085c 100644 --- a/boa/src/builtins/json/mod.rs +++ b/boa/src/builtins/json/mod.rs @@ -60,26 +60,26 @@ 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 Context) -> Result { + pub(crate) fn parse(_: &Value, args: &[Value], context: &mut Context) -> Result { let arg = args .get(0) .cloned() .unwrap_or_else(Value::undefined) - .to_string(ctx)?; + .to_string(context)?; match serde_json::from_str::(&arg) { Ok(json) => { - let j = Value::from_json(json, ctx); + let j = Value::from_json(json, context); match args.get(1) { Some(reviver) if reviver.is_function() => { let mut holder = Value::new_object(None); holder.set_field("", j); - Self::walk(reviver, ctx, &mut holder, &PropertyKey::from("")) + Self::walk(reviver, context, &mut holder, &PropertyKey::from("")) } _ => Ok(j), } } - Err(err) => ctx.throw_syntax_error(err.to_string()), + Err(err) => context.throw_syntax_error(err.to_string()), } } @@ -91,7 +91,7 @@ impl Json { /// [polyfill]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse fn walk( reviver: &Value, - ctx: &mut Context, + context: &mut Context, holder: &mut Value, key: &PropertyKey, ) -> Result { @@ -101,7 +101,7 @@ impl Json { let keys: Vec<_> = object.borrow().keys().collect(); for key in keys { - let v = Self::walk(reviver, ctx, &mut value.clone(), &key); + let v = Self::walk(reviver, context, &mut value.clone(), &key); match v { Ok(v) if !v.is_undefined() => { value.set_field(key, v); @@ -113,7 +113,7 @@ impl Json { } } } - ctx.call(reviver, holder, &[key.into(), value]) + context.call(reviver, holder, &[key.into(), value]) } /// `JSON.stringify( value[, replacer[, space]] )` @@ -132,7 +132,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 Context) -> Result { + pub(crate) fn stringify(_: &Value, args: &[Value], context: &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()) @@ -142,7 +142,7 @@ impl Json { }; let replacer = match args.get(1) { Some(replacer) if replacer.is_object() => replacer, - _ => return Ok(Value::from(object.to_json(ctx)?.to_string())), + _ => return Ok(Value::from(object.to_json(context)?.to_string())), }; let replacer_as_object = replacer @@ -163,7 +163,7 @@ impl Json { object_to_return.set_property( key.to_owned(), DataDescriptor::new( - ctx.call( + context.call( replacer, &this_arg, &[Value::from(key.clone()), val.clone()], @@ -172,7 +172,7 @@ impl Json { ), ); } - Ok(Value::from(object_to_return.to_json(ctx)?.to_string())) + Ok(Value::from(object_to_return.to_json(context)?.to_string())) }) .ok_or_else(Value::undefined)? } else if replacer_as_object.is_array() { @@ -187,17 +187,17 @@ impl Json { }); for field in fields { if let Some(value) = object - .get_property(field.to_string(ctx)?) + .get_property(field.to_string(context)?) // FIXME: handle accessor descriptors - .map(|prop| prop.as_data_descriptor().unwrap().value().to_json(ctx)) + .map(|prop| prop.as_data_descriptor().unwrap().value().to_json(context)) .transpose()? { - obj_to_return.insert(field.to_string(ctx)?.to_string(), value); + obj_to_return.insert(field.to_string(context)?.to_string(), value); } } Ok(Value::from(JSONValue::Object(obj_to_return).to_string())) } else { - Ok(Value::from(object.to_json(ctx)?.to_string())) + Ok(Value::from(object.to_json(context)?.to_string())) } } } diff --git a/boa/src/builtins/json/tests.rs b/boa/src/builtins/json/tests.rs index fabb1c83bc..22e06e5dd6 100644 --- a/boa/src/builtins/json/tests.rs +++ b/boa/src/builtins/json/tests.rs @@ -2,14 +2,14 @@ use crate::{forward, forward_val, object::PROTOTYPE, value::same_value, Context} #[test] fn json_sanity() { - let mut engine = Context::new(); + let mut context = Context::new(); assert_eq!( - forward(&mut engine, r#"JSON.parse('{"aaa":"bbb"}').aaa == 'bbb'"#), + forward(&mut context, r#"JSON.parse('{"aaa":"bbb"}').aaa == 'bbb'"#), "true" ); assert_eq!( forward( - &mut engine, + &mut context, r#"JSON.stringify({aaa: 'bbb'}) == '{"aaa":"bbb"}'"# ), "true" @@ -18,10 +18,10 @@ fn json_sanity() { #[test] fn json_stringify_remove_undefined_values_from_objects() { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward( - &mut engine, + &mut context, r#"JSON.stringify({ aaa: undefined, bbb: 'ccc' })"#, ); let expected = r#""{"bbb":"ccc"}""#; @@ -31,10 +31,10 @@ fn json_stringify_remove_undefined_values_from_objects() { #[test] fn json_stringify_remove_function_values_from_objects() { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward( - &mut engine, + &mut context, r#"JSON.stringify({ aaa: () => {}, bbb: 'ccc' })"#, ); let expected = r#""{"bbb":"ccc"}""#; @@ -44,10 +44,10 @@ fn json_stringify_remove_function_values_from_objects() { #[test] fn json_stringify_remove_symbols_from_objects() { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward( - &mut engine, + &mut context, r#"JSON.stringify({ aaa: Symbol(), bbb: 'ccc' })"#, ); let expected = r#""{"bbb":"ccc"}""#; @@ -57,31 +57,31 @@ fn json_stringify_remove_symbols_from_objects() { #[test] fn json_stringify_replacer_array_strings() { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward( - &mut engine, + &mut context, r#"JSON.stringify({aaa: 'bbb', bbb: 'ccc', ccc: 'ddd'}, ['aaa', 'bbb'])"#, ); - let expected = forward(&mut engine, r#"'{"aaa":"bbb","bbb":"ccc"}'"#); + let expected = forward(&mut context, r#"'{"aaa":"bbb","bbb":"ccc"}'"#); assert_eq!(actual, expected); } #[test] fn json_stringify_replacer_array_numbers() { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward( - &mut engine, + &mut context, r#"JSON.stringify({ 0: 'aaa', 1: 'bbb', 2: 'ccc'}, [1, 2])"#, ); - let expected = forward(&mut engine, r#"'{"1":"bbb","2":"ccc"}'"#); + let expected = forward(&mut context, r#"'{"1":"bbb","2":"ccc"}'"#); assert_eq!(actual, expected); } #[test] fn json_stringify_replacer_function() { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward( - &mut engine, + &mut context, r#"JSON.stringify({ aaa: 1, bbb: 2}, (key, value) => { if (key === 'aaa') { return undefined; @@ -90,60 +90,60 @@ fn json_stringify_replacer_function() { return value; })"#, ); - let expected = forward(&mut engine, r#"'{"bbb":2}'"#); + let expected = forward(&mut context, r#"'{"bbb":2}'"#); assert_eq!(actual, expected); } #[test] fn json_stringify_arrays() { - let mut engine = Context::new(); - let actual = forward(&mut engine, r#"JSON.stringify(['a', 'b'])"#); - let expected = forward(&mut engine, r#"'["a","b"]'"#); + let mut context = Context::new(); + let actual = forward(&mut context, r#"JSON.stringify(['a', 'b'])"#); + let expected = forward(&mut context, r#"'["a","b"]'"#); assert_eq!(actual, expected); } #[test] fn json_stringify_object_array() { - 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"}]'"#); + let mut context = Context::new(); + let actual = forward(&mut context, r#"JSON.stringify([{a: 'b'}, {b: 'c'}])"#); + let expected = forward(&mut context, r#"'[{"a":"b"},{"b":"c"}]'"#); assert_eq!(actual, expected); } #[test] fn json_stringify_array_converts_undefined_to_null() { - let mut engine = Context::new(); - let actual = forward(&mut engine, r#"JSON.stringify([undefined])"#); - let expected = forward(&mut engine, r#"'[null]'"#); + let mut context = Context::new(); + let actual = forward(&mut context, r#"JSON.stringify([undefined])"#); + let expected = forward(&mut context, r#"'[null]'"#); assert_eq!(actual, expected); } #[test] fn json_stringify_array_converts_function_to_null() { - let mut engine = Context::new(); - let actual = forward(&mut engine, r#"JSON.stringify([() => {}])"#); - let expected = forward(&mut engine, r#"'[null]'"#); + let mut context = Context::new(); + let actual = forward(&mut context, r#"JSON.stringify([() => {}])"#); + let expected = forward(&mut context, r#"'[null]'"#); assert_eq!(actual, expected); } #[test] fn json_stringify_array_converts_symbol_to_null() { - let mut engine = Context::new(); - let actual = forward(&mut engine, r#"JSON.stringify([Symbol()])"#); - let expected = forward(&mut engine, r#"'[null]'"#); + let mut context = Context::new(); + let actual = forward(&mut context, r#"JSON.stringify([Symbol()])"#); + let expected = forward(&mut context, r#"'[null]'"#); assert_eq!(actual, expected); } #[test] fn json_stringify_function_replacer_propogate_error() { - let mut engine = Context::new(); + let mut context = Context::new(); let actual = forward( - &mut engine, + &mut context, r#" let thrown = 0; try { @@ -154,64 +154,64 @@ fn json_stringify_function_replacer_propogate_error() { thrown "#, ); - let expected = forward(&mut engine, "1"); + let expected = forward(&mut context, "1"); assert_eq!(actual, expected); } #[test] fn json_stringify_function() { - let mut engine = Context::new(); + let mut context = Context::new(); - let actual_function = forward(&mut engine, r#"JSON.stringify(() => {})"#); - let expected = forward(&mut engine, r#"undefined"#); + let actual_function = forward(&mut context, r#"JSON.stringify(() => {})"#); + let expected = forward(&mut context, r#"undefined"#); assert_eq!(actual_function, expected); } #[test] fn json_stringify_undefined() { - let mut engine = Context::new(); - let actual_undefined = forward(&mut engine, r#"JSON.stringify(undefined)"#); - let expected = forward(&mut engine, r#"undefined"#); + let mut context = Context::new(); + let actual_undefined = forward(&mut context, r#"JSON.stringify(undefined)"#); + let expected = forward(&mut context, r#"undefined"#); assert_eq!(actual_undefined, expected); } #[test] fn json_stringify_symbol() { - let mut engine = Context::new(); + let mut context = Context::new(); - let actual_symbol = forward(&mut engine, r#"JSON.stringify(Symbol())"#); - let expected = forward(&mut engine, r#"undefined"#); + let actual_symbol = forward(&mut context, r#"JSON.stringify(Symbol())"#); + let expected = forward(&mut context, r#"undefined"#); assert_eq!(actual_symbol, expected); } #[test] fn json_stringify_no_args() { - let mut engine = Context::new(); + let mut context = Context::new(); - let actual_no_args = forward(&mut engine, r#"JSON.stringify()"#); - let expected = forward(&mut engine, r#"undefined"#); + let actual_no_args = forward(&mut context, r#"JSON.stringify()"#); + let expected = forward(&mut context, r#"undefined"#); assert_eq!(actual_no_args, expected); } #[test] fn json_stringify_fractional_numbers() { - let mut engine = Context::new(); + let mut context = Context::new(); - let actual = forward(&mut engine, r#"JSON.stringify(Math.round(1.0))"#); - let expected = forward(&mut engine, r#""1""#); + let actual = forward(&mut context, r#"JSON.stringify(Math.round(1.0))"#); + let expected = forward(&mut context, r#""1""#); assert_eq!(actual, expected); } #[test] fn json_parse_array_with_reviver() { - let mut engine = Context::new(); + let mut context = Context::new(); let result = forward_val( - &mut engine, + &mut context, r#"JSON.parse('[1,2,3,4]', function(k, v){ if (typeof v == 'number') { return v * 2; @@ -221,28 +221,28 @@ fn json_parse_array_with_reviver() { ) .unwrap(); assert_eq!( - result.get_field("0").to_number(&mut engine).unwrap() as u8, + result.get_field("0").to_number(&mut context).unwrap() as u8, 2u8 ); assert_eq!( - result.get_field("1").to_number(&mut engine).unwrap() as u8, + result.get_field("1").to_number(&mut context).unwrap() as u8, 4u8 ); assert_eq!( - result.get_field("2").to_number(&mut engine).unwrap() as u8, + result.get_field("2").to_number(&mut context).unwrap() as u8, 6u8 ); assert_eq!( - result.get_field("3").to_number(&mut engine).unwrap() as u8, + result.get_field("3").to_number(&mut context).unwrap() as u8, 8u8 ); } #[test] fn json_parse_object_with_reviver() { - let mut engine = Context::new(); + let mut context = Context::new(); let result = forward( - &mut engine, + &mut context, r#" var myObj = new Object(); myObj.firstname = "boa"; @@ -266,7 +266,7 @@ fn json_parse_object_with_reviver() { #[test] fn json_parse_sets_prototypes() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" const jsonString = "{ \"ob\":{\"ject\":1}, @@ -274,22 +274,22 @@ fn json_parse_sets_prototypes() { }"; const jsonObj = JSON.parse(jsonString); "#; - eprintln!("{}", forward(&mut engine, init)); - let object_prototype = forward_val(&mut engine, r#"jsonObj.ob"#) + eprintln!("{}", forward(&mut context, init)); + let object_prototype = forward_val(&mut context, r#"jsonObj.ob"#) .unwrap() .as_object() .unwrap() .prototype_instance(); - let array_prototype = forward_val(&mut engine, r#"jsonObj.arr"#) + let array_prototype = forward_val(&mut context, r#"jsonObj.arr"#) .unwrap() .as_object() .unwrap() .prototype_instance(); - let global_object_prototype = engine + let global_object_prototype = context .global_object() .get_field("Object") .get_field(PROTOTYPE); - let global_array_prototype = engine + let global_array_prototype = context .global_object() .get_field("Array") .get_field(PROTOTYPE); @@ -302,22 +302,22 @@ fn json_parse_sets_prototypes() { #[test] fn json_fields_should_be_enumerable() { - let mut engine = Context::new(); + let mut context = Context::new(); let actual_object = forward( - &mut engine, + &mut context, r#" var a = JSON.parse('{"x":0}'); a.propertyIsEnumerable('x'); "#, ); let actual_array_index = forward( - &mut engine, + &mut context, r#" var b = JSON.parse('[0, 1]'); b.propertyIsEnumerable('0'); "#, ); - let expected = forward(&mut engine, r#"true"#); + let expected = forward(&mut context, r#"true"#); assert_eq!(actual_object, expected); assert_eq!(actual_array_index, expected); @@ -325,7 +325,7 @@ fn json_fields_should_be_enumerable() { #[test] fn json_parse_with_no_args_throws_syntax_error() { - let mut engine = Context::new(); - let result = forward(&mut engine, "JSON.parse();"); + let mut context = Context::new(); + let result = forward(&mut context, "JSON.parse();"); assert!(result.contains("SyntaxError")); } diff --git a/boa/src/builtins/map/map_iterator.rs b/boa/src/builtins/map/map_iterator.rs index 76d955b7f6..63e80f6061 100644 --- a/boa/src/builtins/map/map_iterator.rs +++ b/boa/src/builtins/map/map_iterator.rs @@ -46,16 +46,16 @@ impl MapIterator { /// /// [spec]: https://www.ecma-international.org/ecma-262/11.0/index.html#sec-createmapiterator pub(crate) fn create_map_iterator( - ctx: &Context, + context: &Context, map: Value, kind: MapIterationKind, ) -> Result { - let map_iterator = Value::new_object(Some(ctx.global_object())); + let map_iterator = Value::new_object(Some(context.global_object())); map_iterator.set_data(ObjectData::MapIterator(Self::new(map, kind))); map_iterator .as_object() .expect("map iterator object") - .set_prototype_instance(ctx.iterator_prototypes().map_iterator().into()); + .set_prototype_instance(context.iterator_prototypes().map_iterator().into()); Ok(map_iterator) } @@ -67,7 +67,7 @@ impl MapIterator { /// - [ECMA reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-%mapiteratorprototype%.next - pub(crate) fn next(this: &Value, _args: &[Value], ctx: &mut Context) -> Result { + pub(crate) fn next(this: &Value, _: &[Value], context: &mut Context) -> Result { if let Value::Object(ref object) = this { let mut object = object.borrow_mut(); if let Some(map_iterator) = object.as_map_iterator_mut() { @@ -76,7 +76,7 @@ impl MapIterator { let item_kind = &map_iterator.map_iteration_kind; if map_iterator.iterated_map.is_undefined() { - return Ok(create_iter_result_object(ctx, Value::undefined(), true)); + return Ok(create_iter_result_object(context, Value::undefined(), true)); } if let Value::Object(ref object) = m { @@ -90,42 +90,44 @@ impl MapIterator { match item_kind { MapIterationKind::Key => { return Ok(create_iter_result_object( - ctx, + context, key.clone(), false, )); } MapIterationKind::Value => { return Ok(create_iter_result_object( - ctx, + context, value.clone(), false, )); } MapIterationKind::KeyAndValue => { let result = Array::construct_array( - &Array::new_array(ctx)?, + &Array::new_array(context)?, &[key.clone(), value.clone()], )?; - return Ok(create_iter_result_object(ctx, result, false)); + return Ok(create_iter_result_object( + context, result, false, + )); } } } } } else { - return Err(ctx.construct_type_error("'this' is not a Map")); + return Err(context.construct_type_error("'this' is not a Map")); } } else { - return Err(ctx.construct_type_error("'this' is not a Map")); + return Err(context.construct_type_error("'this' is not a Map")); } map_iterator.iterated_map = Value::undefined(); - Ok(create_iter_result_object(ctx, Value::undefined(), true)) + Ok(create_iter_result_object(context, Value::undefined(), true)) } else { - ctx.throw_type_error("`this` is not an MapIterator") + context.throw_type_error("`this` is not an MapIterator") } } else { - ctx.throw_type_error("`this` is not an MapIterator") + context.throw_type_error("`this` is not an MapIterator") } } @@ -135,19 +137,19 @@ impl MapIterator { /// - [ECMA reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-%mapiteratorprototype%-object - pub(crate) fn create_prototype(ctx: &mut Context, iterator_prototype: Value) -> Value { - let global = ctx.global_object(); + pub(crate) fn create_prototype(context: &mut Context, iterator_prototype: Value) -> Value { + let global = context.global_object(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); // Create prototype let map_iterator = Value::new_object(Some(global)); - make_builtin_fn(Self::next, "next", &map_iterator, 0, ctx); + make_builtin_fn(Self::next, "next", &map_iterator, 0, context); map_iterator .as_object() .expect("map iterator prototype object") .set_prototype_instance(iterator_prototype); - let to_string_tag = ctx.well_known_symbols().to_string_tag_symbol(); + let to_string_tag = context.well_known_symbols().to_string_tag_symbol(); let to_string_tag_property = DataDescriptor::new("Map Iterator", Attribute::CONFIGURABLE); map_iterator.set_property(to_string_tag, to_string_tag_property); map_iterator diff --git a/boa/src/builtins/map/mod.rs b/boa/src/builtins/map/mod.rs index 11d06cfbf6..253d364792 100644 --- a/boa/src/builtins/map/mod.rs +++ b/boa/src/builtins/map/mod.rs @@ -69,9 +69,16 @@ impl Map { pub(crate) const LENGTH: usize = 1; /// Create a new map - pub(crate) fn constructor(this: &Value, args: &[Value], ctx: &mut Context) -> Result { + pub(crate) fn constructor( + this: &Value, + args: &[Value], + context: &mut Context, + ) -> Result { // Set Prototype - let prototype = ctx.global_object().get_field("Map").get_field(PROTOTYPE); + let prototype = context + .global_object() + .get_field("Map") + .get_field(PROTOTYPE); this.as_object() .expect("this is map object") @@ -89,11 +96,11 @@ impl Map { map } else if object.is_array() { let mut map = OrderedMap::new(); - let len = args[0].get_field("length").to_integer(ctx)? as i32; + let len = args[0].get_field("length").to_integer(context)? as i32; for i in 0..len { let val = &args[0].get_field(i.to_string()); let (key, value) = Self::get_key_value(val).ok_or_else(|| { - ctx.construct_type_error( + context.construct_type_error( "iterable for Map should have array-like objects", ) })?; @@ -101,15 +108,14 @@ impl Map { } map } else { - return Err(ctx.construct_type_error( + return Err(context.construct_type_error( "iterable for Map should have array-like objects", )); } } _ => { - return Err( - ctx.construct_type_error("iterable for Map should have array-like objects") - ) + return Err(context + .construct_type_error("iterable for Map should have array-like objects")) } }, }; @@ -132,8 +138,8 @@ impl Map { /// /// [spec]: https://www.ecma-international.org/ecma-262/11.0/index.html#sec-map.prototype.entries /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries - pub(crate) fn entries(this: &Value, _: &[Value], ctx: &mut Context) -> Result { - MapIterator::create_map_iterator(ctx, this.clone(), MapIterationKind::KeyAndValue) + pub(crate) fn entries(this: &Value, _: &[Value], context: &mut Context) -> Result { + MapIterator::create_map_iterator(context, this.clone(), MapIterationKind::KeyAndValue) } /// `Map.prototype.keys()` @@ -146,8 +152,8 @@ impl Map { /// /// [spec]: https://tc39.es/ecma262/#sec-map.prototype.keys /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys - pub(crate) fn keys(this: &Value, _: &[Value], ctx: &mut Context) -> Result { - MapIterator::create_map_iterator(ctx, this.clone(), MapIterationKind::Key) + pub(crate) fn keys(this: &Value, _: &[Value], context: &mut Context) -> Result { + MapIterator::create_map_iterator(context, this.clone(), MapIterationKind::Key) } /// Helper function to set the size property. @@ -170,7 +176,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 Context) -> Result { + pub(crate) fn set(this: &Value, args: &[Value], context: &mut Context) -> Result { let (key, value) = match args.len() { 0 => (Value::Undefined, Value::Undefined), 1 => (args[0].clone(), Value::Undefined), @@ -183,10 +189,10 @@ impl Map { map.insert(key, value); map.len() } else { - return Err(ctx.construct_type_error("'this' is not a Map")); + return Err(context.construct_type_error("'this' is not a Map")); } } else { - return Err(ctx.construct_type_error("'this' is not a Map")); + return Err(context.construct_type_error("'this' is not a Map")); }; Self::set_size(this, size); @@ -203,7 +209,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 Context) -> Result { + pub(crate) fn delete(this: &Value, args: &[Value], context: &mut Context) -> Result { let undefined = Value::Undefined; let key = match args.len() { 0 => &undefined, @@ -216,10 +222,10 @@ impl Map { let deleted = map.remove(key).is_some(); (deleted, map.len()) } else { - return Err(ctx.construct_type_error("'this' is not a Map")); + return Err(context.construct_type_error("'this' is not a Map")); } } else { - return Err(ctx.construct_type_error("'this' is not a Map")); + return Err(context.construct_type_error("'this' is not a Map")); }; Self::set_size(this, size); Ok(deleted.into()) @@ -235,7 +241,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 Context) -> Result { + pub(crate) fn get(this: &Value, args: &[Value], context: &mut Context) -> Result { let undefined = Value::Undefined; let key = match args.len() { 0 => &undefined, @@ -253,7 +259,7 @@ impl Map { } } - Err(ctx.construct_type_error("'this' is not a Map")) + Err(context.construct_type_error("'this' is not a Map")) } /// `Map.prototype.clear( )` @@ -284,7 +290,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 Context) -> Result { + pub(crate) fn has(this: &Value, args: &[Value], context: &mut Context) -> Result { let undefined = Value::Undefined; let key = match args.len() { 0 => &undefined, @@ -298,7 +304,7 @@ impl Map { } } - Err(ctx.construct_type_error("'this' is not a Map")) + Err(context.construct_type_error("'this' is not a Map")) } /// `Map.prototype.forEach( callbackFn [ , thisArg ] )` @@ -311,11 +317,7 @@ impl Map { /// /// [spec]: https://tc39.es/ecma262/#sec-map.prototype.foreach /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach - pub(crate) fn for_each( - this: &Value, - args: &[Value], - interpreter: &mut Context, - ) -> Result { + pub(crate) fn for_each(this: &Value, args: &[Value], context: &mut Context) -> Result { if args.is_empty() { return Err(Value::from("Missing argument for Map.prototype.forEach")); } @@ -329,7 +331,7 @@ impl Map { for (key, value) in map { let arguments = [value, key, this.clone()]; - interpreter.call(callback_arg, &this_arg, &arguments)?; + context.call(callback_arg, &this_arg, &arguments)?; } } } @@ -347,8 +349,8 @@ impl Map { /// /// [spec]: https://tc39.es/ecma262/#sec-map.prototype.values /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values - pub(crate) fn values(this: &Value, _: &[Value], ctx: &mut Context) -> Result { - MapIterator::create_map_iterator(ctx, this.clone(), MapIterationKind::Value) + pub(crate) fn values(this: &Value, _: &[Value], context: &mut Context) -> Result { + MapIterator::create_map_iterator(context, this.clone(), MapIterationKind::Value) } /// Helper function to get a key-value pair from an array. diff --git a/boa/src/builtins/map/ordered_map.rs b/boa/src/builtins/map/ordered_map.rs index e1bbeafc71..195acee55f 100644 --- a/boa/src/builtins/map/ordered_map.rs +++ b/boa/src/builtins/map/ordered_map.rs @@ -1,8 +1,10 @@ -use gc::{custom_trace, Finalize, Trace}; +use crate::gc::{custom_trace, Finalize, Trace}; use indexmap::{map::IntoIter, map::Iter, map::IterMut, IndexMap}; -use std::collections::hash_map::RandomState; -use std::fmt::Debug; -use std::hash::{BuildHasher, Hash}; +use std::{ + collections::hash_map::RandomState, + fmt::Debug, + hash::{BuildHasher, Hash}, +}; /// A newtype wrapping indexmap::IndexMap #[derive(Clone)] diff --git a/boa/src/builtins/map/tests.rs b/boa/src/builtins/map/tests.rs index 1a145cdc31..33158cc5ee 100644 --- a/boa/src/builtins/map/tests.rs +++ b/boa/src/builtins/map/tests.rs @@ -2,50 +2,50 @@ use crate::{forward, Context}; #[test] fn construct_empty() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var empty = new Map(); "#; - forward(&mut engine, init); - let result = forward(&mut engine, "empty.size"); + forward(&mut context, init); + let result = forward(&mut context, "empty.size"); assert_eq!(result, "0"); } #[test] fn construct_from_array() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" let map = new Map([["1", "one"], ["2", "two"]]); "#; - forward(&mut engine, init); - let result = forward(&mut engine, "map.size"); + forward(&mut context, init); + let result = forward(&mut context, "map.size"); assert_eq!(result, "2"); } #[test] fn clone() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" let original = new Map([["1", "one"], ["2", "two"]]); let clone = new Map(original); "#; - forward(&mut engine, init); - let result = forward(&mut engine, "clone.size"); + forward(&mut context, init); + let result = forward(&mut context, "clone.size"); assert_eq!(result, "2"); let result = forward( - &mut engine, + &mut context, r#" original.set("3", "three"); original.size"#, ); assert_eq!(result, "3"); - let result = forward(&mut engine, "clone.size"); + let result = forward(&mut context, "clone.size"); assert_eq!(result, "2"); } #[test] fn symbol_iterator() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" const map1 = new Map(); map1.set('0', 'foo'); @@ -55,33 +55,33 @@ fn symbol_iterator() { let item2 = iterator.next(); let item3 = iterator.next(); "#; - forward(&mut engine, init); - let result = forward(&mut engine, "item1.value.length"); + forward(&mut context, init); + let result = forward(&mut context, "item1.value.length"); assert_eq!(result, "2"); - let result = forward(&mut engine, "item1.value[0]"); + let result = forward(&mut context, "item1.value[0]"); assert_eq!(result, "\"0\""); - let result = forward(&mut engine, "item1.value[1]"); + let result = forward(&mut context, "item1.value[1]"); assert_eq!(result, "\"foo\""); - let result = forward(&mut engine, "item1.done"); + let result = forward(&mut context, "item1.done"); assert_eq!(result, "false"); - let result = forward(&mut engine, "item2.value.length"); + let result = forward(&mut context, "item2.value.length"); assert_eq!(result, "2"); - let result = forward(&mut engine, "item2.value[0]"); + let result = forward(&mut context, "item2.value[0]"); assert_eq!(result, "1"); - let result = forward(&mut engine, "item2.value[1]"); + let result = forward(&mut context, "item2.value[1]"); assert_eq!(result, "\"bar\""); - let result = forward(&mut engine, "item2.done"); + let result = forward(&mut context, "item2.done"); assert_eq!(result, "false"); - let result = forward(&mut engine, "item3.value"); + let result = forward(&mut context, "item3.value"); assert_eq!(result, "undefined"); - let result = forward(&mut engine, "item3.done"); + let result = forward(&mut context, "item3.done"); assert_eq!(result, "true"); } // Should behave the same as symbol_iterator #[test] fn entries() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" const map1 = new Map(); map1.set('0', 'foo'); @@ -91,32 +91,32 @@ fn entries() { let item2 = entriesIterator.next(); let item3 = entriesIterator.next(); "#; - forward(&mut engine, init); - let result = forward(&mut engine, "item1.value.length"); + forward(&mut context, init); + let result = forward(&mut context, "item1.value.length"); assert_eq!(result, "2"); - let result = forward(&mut engine, "item1.value[0]"); + let result = forward(&mut context, "item1.value[0]"); assert_eq!(result, "\"0\""); - let result = forward(&mut engine, "item1.value[1]"); + let result = forward(&mut context, "item1.value[1]"); assert_eq!(result, "\"foo\""); - let result = forward(&mut engine, "item1.done"); + let result = forward(&mut context, "item1.done"); assert_eq!(result, "false"); - let result = forward(&mut engine, "item2.value.length"); + let result = forward(&mut context, "item2.value.length"); assert_eq!(result, "2"); - let result = forward(&mut engine, "item2.value[0]"); + let result = forward(&mut context, "item2.value[0]"); assert_eq!(result, "1"); - let result = forward(&mut engine, "item2.value[1]"); + let result = forward(&mut context, "item2.value[1]"); assert_eq!(result, "\"bar\""); - let result = forward(&mut engine, "item2.done"); + let result = forward(&mut context, "item2.done"); assert_eq!(result, "false"); - let result = forward(&mut engine, "item3.value"); + let result = forward(&mut context, "item3.value"); assert_eq!(result, "undefined"); - let result = forward(&mut engine, "item3.done"); + let result = forward(&mut context, "item3.done"); assert_eq!(result, "true"); } #[test] fn merge() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" let first = new Map([["1", "one"], ["2", "two"]]); let second = new Map([["2", "second two"], ["3", "three"]]); @@ -124,44 +124,44 @@ fn merge() { let merged1 = new Map([...first, ...second]); let merged2 = new Map([...second, ...third]); "#; - forward(&mut engine, init); - let result = forward(&mut engine, "merged1.size"); + forward(&mut context, init); + let result = forward(&mut context, "merged1.size"); assert_eq!(result, "3"); - let result = forward(&mut engine, "merged1.get('2')"); + let result = forward(&mut context, "merged1.get('2')"); assert_eq!(result, "\"second two\""); - let result = forward(&mut engine, "merged2.size"); + let result = forward(&mut context, "merged2.size"); assert_eq!(result, "4"); } #[test] fn get() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" let map = new Map([["1", "one"], ["2", "two"]]); "#; - forward(&mut engine, init); - let result = forward(&mut engine, "map.get('1')"); + forward(&mut context, init); + let result = forward(&mut context, "map.get('1')"); assert_eq!(result, "\"one\""); - let result = forward(&mut engine, "map.get('2')"); + let result = forward(&mut context, "map.get('2')"); assert_eq!(result, "\"two\""); - let result = forward(&mut engine, "map.get('3')"); + let result = forward(&mut context, "map.get('3')"); assert_eq!(result, "undefined"); - let result = forward(&mut engine, "map.get()"); + let result = forward(&mut context, "map.get()"); assert_eq!(result, "undefined"); } #[test] fn set() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" let map = new Map(); "#; - forward(&mut engine, init); - let result = forward(&mut engine, "map.set()"); + forward(&mut context, init); + let result = forward(&mut context, "map.set()"); assert_eq!(result, "Map { undefined → undefined }"); - let result = forward(&mut engine, "map.set('1', 'one')"); + let result = forward(&mut context, "map.set('1', 'one')"); assert_eq!(result, "Map { undefined → undefined, \"1\" → \"one\" }"); - let result = forward(&mut engine, "map.set('2')"); + let result = forward(&mut context, "map.set('2')"); assert_eq!( result, "Map { undefined → undefined, \"1\" → \"one\", \"2\" → undefined }" @@ -170,49 +170,49 @@ fn set() { #[test] fn clear() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" let map = new Map([["1", "one"], ["2", "two"]]); map.clear(); "#; - forward(&mut engine, init); - let result = forward(&mut engine, "map.size"); + forward(&mut context, init); + let result = forward(&mut context, "map.size"); assert_eq!(result, "0"); } #[test] fn delete() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" let map = new Map([["1", "one"], ["2", "two"]]); "#; - forward(&mut engine, init); - let result = forward(&mut engine, "map.delete('1')"); + forward(&mut context, init); + let result = forward(&mut context, "map.delete('1')"); assert_eq!(result, "true"); - let result = forward(&mut engine, "map.size"); + let result = forward(&mut context, "map.size"); assert_eq!(result, "1"); - let result = forward(&mut engine, "map.delete('1')"); + let result = forward(&mut context, "map.delete('1')"); assert_eq!(result, "false"); } #[test] fn has() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" let map = new Map([["1", "one"]]); "#; - forward(&mut engine, init); - let result = forward(&mut engine, "map.has()"); + forward(&mut context, init); + let result = forward(&mut context, "map.has()"); assert_eq!(result, "false"); - let result = forward(&mut engine, "map.has('1')"); + let result = forward(&mut context, "map.has('1')"); assert_eq!(result, "true"); - let result = forward(&mut engine, "map.has('2')"); + let result = forward(&mut context, "map.has('2')"); assert_eq!(result, "false"); } #[test] fn keys() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" const map1 = new Map(); map1.set('0', 'foo'); @@ -222,24 +222,24 @@ fn keys() { let item2 = keysIterator.next(); let item3 = keysIterator.next(); "#; - forward(&mut engine, init); - let result = forward(&mut engine, "item1.value"); + forward(&mut context, init); + let result = forward(&mut context, "item1.value"); assert_eq!(result, "\"0\""); - let result = forward(&mut engine, "item1.done"); + let result = forward(&mut context, "item1.done"); assert_eq!(result, "false"); - let result = forward(&mut engine, "item2.value"); + let result = forward(&mut context, "item2.value"); assert_eq!(result, "1"); - let result = forward(&mut engine, "item2.done"); + let result = forward(&mut context, "item2.done"); assert_eq!(result, "false"); - let result = forward(&mut engine, "item3.value"); + let result = forward(&mut context, "item3.value"); assert_eq!(result, "undefined"); - let result = forward(&mut engine, "item3.done"); + let result = forward(&mut context, "item3.done"); assert_eq!(result, "true"); } #[test] fn for_each() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" let map = new Map([[1, 5], [2, 10], [3, 15]]); let valueSum = 0; @@ -252,15 +252,15 @@ fn for_each() { } map.forEach(callingCallback); "#; - forward(&mut engine, init); - assert_eq!(forward(&mut engine, "valueSum"), "30"); - assert_eq!(forward(&mut engine, "keySum"), "6"); - assert_eq!(forward(&mut engine, "sizeSum"), "9"); + forward(&mut context, init); + assert_eq!(forward(&mut context, "valueSum"), "30"); + assert_eq!(forward(&mut context, "keySum"), "6"); + assert_eq!(forward(&mut context, "sizeSum"), "9"); } #[test] fn values() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" const map1 = new Map(); map1.set('0', 'foo'); @@ -270,54 +270,54 @@ fn values() { let item2 = valuesIterator.next(); let item3 = valuesIterator.next(); "#; - forward(&mut engine, init); - let result = forward(&mut engine, "item1.value"); + forward(&mut context, init); + let result = forward(&mut context, "item1.value"); assert_eq!(result, "\"foo\""); - let result = forward(&mut engine, "item1.done"); + let result = forward(&mut context, "item1.done"); assert_eq!(result, "false"); - let result = forward(&mut engine, "item2.value"); + let result = forward(&mut context, "item2.value"); assert_eq!(result, "\"bar\""); - let result = forward(&mut engine, "item2.done"); + let result = forward(&mut context, "item2.done"); assert_eq!(result, "false"); - let result = forward(&mut engine, "item3.value"); + let result = forward(&mut context, "item3.value"); assert_eq!(result, "undefined"); - let result = forward(&mut engine, "item3.done"); + let result = forward(&mut context, "item3.done"); assert_eq!(result, "true"); } #[test] fn modify_key() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" let obj = new Object(); let map = new Map([[obj, "one"]]); obj.field = "Value"; "#; - forward(&mut engine, init); - let result = forward(&mut engine, "map.get(obj)"); + forward(&mut context, init); + let result = forward(&mut context, "map.get(obj)"); assert_eq!(result, "\"one\""); } #[test] fn order() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" let map = new Map([[1, "one"]]); map.set(2, "two"); "#; - forward(&mut engine, init); - let result = forward(&mut engine, "map"); + forward(&mut context, init); + let result = forward(&mut context, "map"); assert_eq!(result, "Map { 1 → \"one\", 2 → \"two\" }"); - let result = forward(&mut engine, "map.set(1, \"five\");map"); + let result = forward(&mut context, "map.set(1, \"five\");map"); assert_eq!(result, "Map { 1 → \"five\", 2 → \"two\" }"); - let result = forward(&mut engine, "map.set();map"); + let result = forward(&mut context, "map.set();map"); assert_eq!( result, "Map { 1 → \"five\", 2 → \"two\", undefined → undefined }" ); - let result = forward(&mut engine, "map.delete(2);map"); + let result = forward(&mut context, "map.delete(2);map"); assert_eq!(result, "Map { 1 → \"five\", undefined → undefined }"); - let result = forward(&mut engine, "map.set(2, \"two\");map"); + let result = forward(&mut context, "map.set(2, \"two\");map"); assert_eq!( result, "Map { 1 → \"five\", undefined → undefined, 2 → \"two\" }" @@ -326,22 +326,22 @@ fn order() { #[test] fn recursive_display() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" let map = new Map(); let array = new Array([map]); map.set("y", map); "#; - forward(&mut engine, init); - let result = forward(&mut engine, "map"); + forward(&mut context, init); + let result = forward(&mut context, "map"); assert_eq!(result, "Map { \"y\" → Map(1) }"); - let result = forward(&mut engine, "map.set(\"z\", array)"); + let result = forward(&mut context, "map.set(\"z\", array)"); assert_eq!(result, "Map { \"y\" → Map(2), \"z\" → Array(1) }"); } #[test] fn not_a_function() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r" try { let map = Map() @@ -350,7 +350,7 @@ fn not_a_function() { } "; assert_eq!( - forward(&mut engine, init), + forward(&mut context, init), "\"TypeError: function object is not callable\"" ); } diff --git a/boa/src/builtins/math/mod.rs b/boa/src/builtins/math/mod.rs index e4167efe15..ed177fef3a 100644 --- a/boa/src/builtins/math/mod.rs +++ b/boa/src/builtins/math/mod.rs @@ -94,10 +94,10 @@ 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 Context) -> Result { + pub(crate) fn abs(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::abs) .into()) @@ -111,10 +111,10 @@ 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 Context) -> Result { + pub(crate) fn acos(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::acos) .into()) @@ -128,10 +128,10 @@ 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 Context) -> Result { + pub(crate) fn acosh(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::acosh) .into()) @@ -145,10 +145,10 @@ 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 Context) -> Result { + pub(crate) fn asin(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::asin) .into()) @@ -162,10 +162,10 @@ 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 Context) -> Result { + pub(crate) fn asinh(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::asinh) .into()) @@ -179,10 +179,10 @@ 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 Context) -> Result { + pub(crate) fn atan(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::atan) .into()) @@ -196,10 +196,10 @@ 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 Context) -> Result { + pub(crate) fn atanh(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::atanh) .into()) @@ -213,10 +213,10 @@ 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 Context) -> Result { + pub(crate) fn atan2(_: &Value, args: &[Value], context: &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()?, + args.get(0).map(|x| x.to_number(context)).transpose()?, + args.get(1).map(|x| x.to_number(context)).transpose()?, ) { (Some(x), Some(y)) => x.atan2(y), (_, _) => f64::NAN, @@ -232,10 +232,10 @@ 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 Context) -> Result { + pub(crate) fn cbrt(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::cbrt) .into()) @@ -249,10 +249,10 @@ 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 Context) -> Result { + pub(crate) fn ceil(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::ceil) .into()) @@ -266,10 +266,10 @@ 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 Context) -> Result { + pub(crate) fn clz32(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_u32(ctx)) + .map(|x| x.to_u32(context)) .transpose()? .map(u32::leading_zeros) .unwrap_or(32) @@ -284,10 +284,10 @@ 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 Context) -> Result { + pub(crate) fn cos(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::cos) .into()) @@ -301,10 +301,10 @@ 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 Context) -> Result { + pub(crate) fn cosh(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::cosh) .into()) @@ -318,10 +318,10 @@ 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 Context) -> Result { + pub(crate) fn exp(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::exp) .into()) @@ -337,10 +337,10 @@ 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 Context) -> Result { + pub(crate) fn expm1(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::exp_m1) .into()) @@ -354,10 +354,10 @@ 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 Context) -> Result { + pub(crate) fn floor(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::floor) .into()) @@ -371,10 +371,10 @@ 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 Context) -> Result { + pub(crate) fn fround(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, |x| (x as f32) as f64) .into()) @@ -388,10 +388,10 @@ 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 Context) -> Result { + pub(crate) fn hypot(_: &Value, args: &[Value], context: &mut Context) -> Result { let mut result = 0f64; for arg in args { - let x = arg.to_number(ctx)?; + let x = arg.to_number(context)?; result = result.hypot(x); } Ok(result.into()) @@ -405,10 +405,10 @@ 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 Context) -> Result { + pub(crate) fn imul(_: &Value, args: &[Value], context: &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()?, + args.get(0).map(|x| x.to_u32(context)).transpose()?, + args.get(1).map(|x| x.to_u32(context)).transpose()?, ) { (Some(x), Some(y)) => x.wrapping_mul(y) as i32, (_, _) => 0, @@ -424,10 +424,10 @@ 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 Context) -> Result { + pub(crate) fn log(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, |x| if x <= 0.0 { f64::NAN } else { x.ln() }) .into()) @@ -441,10 +441,10 @@ 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 Context) -> Result { + pub(crate) fn log1p(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::ln_1p) .into()) @@ -458,10 +458,10 @@ 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 Context) -> Result { + pub(crate) fn log10(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, |x| if x <= 0.0 { f64::NAN } else { x.log10() }) .into()) @@ -475,10 +475,10 @@ 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 Context) -> Result { + pub(crate) fn log2(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, |x| if x <= 0.0 { f64::NAN } else { x.log2() }) .into()) @@ -492,10 +492,10 @@ 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 Context) -> Result { + pub(crate) fn max(_: &Value, args: &[Value], context: &mut Context) -> Result { let mut max = f64::NEG_INFINITY; for arg in args { - let num = arg.to_number(ctx)?; + let num = arg.to_number(context)?; max = max.max(num); } Ok(max.into()) @@ -509,10 +509,10 @@ 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 Context) -> Result { + pub(crate) fn min(_: &Value, args: &[Value], context: &mut Context) -> Result { let mut min = f64::INFINITY; for arg in args { - let num = arg.to_number(ctx)?; + let num = arg.to_number(context)?; min = min.min(num); } Ok(min.into()) @@ -526,10 +526,10 @@ 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 Context) -> Result { + pub(crate) fn pow(_: &Value, args: &[Value], context: &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()?, + args.get(0).map(|x| x.to_number(context)).transpose()?, + args.get(1).map(|x| x.to_number(context)).transpose()?, ) { (Some(x), Some(y)) => x.powf(y), (_, _) => f64::NAN, @@ -557,10 +557,10 @@ 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 Context) -> Result { + pub(crate) fn round(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::round) .into()) @@ -574,10 +574,10 @@ 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 Context) -> Result { + pub(crate) fn sign(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or( f64::NAN, @@ -600,10 +600,10 @@ 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 Context) -> Result { + pub(crate) fn sin(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::sin) .into()) @@ -617,10 +617,10 @@ 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 Context) -> Result { + pub(crate) fn sinh(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::sinh) .into()) @@ -634,10 +634,10 @@ 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 Context) -> Result { + pub(crate) fn sqrt(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::sqrt) .into()) @@ -651,10 +651,10 @@ 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 Context) -> Result { + pub(crate) fn tan(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::tan) .into()) @@ -668,10 +668,10 @@ 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 Context) -> Result { + pub(crate) fn tanh(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::tanh) .into()) @@ -685,10 +685,10 @@ 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 Context) -> Result { + pub(crate) fn trunc(_: &Value, args: &[Value], context: &mut Context) -> Result { Ok(args .get(0) - .map(|x| x.to_number(ctx)) + .map(|x| x.to_number(context)) .transpose()? .map_or(f64::NAN, f64::trunc) .into()) diff --git a/boa/src/builtins/math/tests.rs b/boa/src/builtins/math/tests.rs index 80b5bd01ad..4a81b232d2 100644 --- a/boa/src/builtins/math/tests.rs +++ b/boa/src/builtins/math/tests.rs @@ -5,24 +5,24 @@ use std::f64; #[test] fn abs() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.abs(3 - 5); var b = Math.abs(1.23456 - 7.89012); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 2.0); - assert_eq!(b.to_number(&mut engine).unwrap(), 6.655_559_999_999_999_5); + assert_eq!(a.to_number(&mut context).unwrap(), 2.0); + assert_eq!(b.to_number(&mut context).unwrap(), 6.655_559_999_999_999_5); } #[test] fn acos() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.acos(8 / 10); var b = Math.acos(5 / 3); @@ -30,154 +30,154 @@ fn acos() { var d = Math.acos(2); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward(&mut engine, "b"); - let c = forward_val(&mut engine, "c").unwrap(); - let d = forward(&mut engine, "d"); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward(&mut context, "b"); + let c = forward_val(&mut context, "c").unwrap(); + let d = forward(&mut context, "d"); - assert_eq!(a.to_number(&mut engine).unwrap(), 0.643_501_108_793_284_3); + assert_eq!(a.to_number(&mut context).unwrap(), 0.643_501_108_793_284_3); assert_eq!(b, "NaN"); - assert_eq!(c.to_number(&mut engine).unwrap(), 0_f64); + assert_eq!(c.to_number(&mut context).unwrap(), 0_f64); assert_eq!(d, "NaN"); } #[test] fn acosh() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.acosh(2); var b = Math.acosh(-1); var c = Math.acosh(0.5); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward(&mut engine, "b"); - let c = forward(&mut engine, "c"); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward(&mut context, "b"); + let c = forward(&mut context, "c"); - assert_eq!(a.to_number(&mut engine).unwrap(), 1.316_957_896_924_816_6); + assert_eq!(a.to_number(&mut context).unwrap(), 1.316_957_896_924_816_6); assert_eq!(b, "NaN"); assert_eq!(c, "NaN"); } #[test] fn asin() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.asin(6 / 10); var b = Math.asin(5 / 3); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward(&mut engine, "b"); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward(&mut context, "b"); - assert_eq!(a.to_number(&mut engine).unwrap(), 0.643_501_108_793_284_4); + assert_eq!(a.to_number(&mut context).unwrap(), 0.643_501_108_793_284_4); assert_eq!(b, String::from("NaN")); } #[test] fn asinh() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.asinh(1); var b = Math.asinh(0); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 0.881_373_587_019_542_9); - assert_eq!(b.to_number(&mut engine).unwrap(), 0_f64); + assert_eq!(a.to_number(&mut context).unwrap(), 0.881_373_587_019_542_9); + assert_eq!(b.to_number(&mut context).unwrap(), 0_f64); } #[test] fn atan() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.atan(1); var b = Math.atan(0); var c = Math.atan(-0); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); - let c = forward_val(&mut engine, "c").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); + let c = forward_val(&mut context, "c").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), f64::consts::FRAC_PI_4); - assert_eq!(b.to_number(&mut engine).unwrap(), 0_f64); - assert_eq!(c.to_number(&mut engine).unwrap(), f64::from(-0)); + assert_eq!(a.to_number(&mut context).unwrap(), f64::consts::FRAC_PI_4); + assert_eq!(b.to_number(&mut context).unwrap(), 0_f64); + assert_eq!(c.to_number(&mut context).unwrap(), f64::from(-0)); } #[test] fn atan2() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.atan2(90, 15); var b = Math.atan2(15, 90); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 1.405_647_649_380_269_9); - assert_eq!(b.to_number(&mut engine).unwrap(), 0.165_148_677_414_626_83); + assert_eq!(a.to_number(&mut context).unwrap(), 1.405_647_649_380_269_9); + assert_eq!(b.to_number(&mut context).unwrap(), 0.165_148_677_414_626_83); } #[test] fn cbrt() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.cbrt(64); var b = Math.cbrt(-1); var c = Math.cbrt(1); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); - let c = forward_val(&mut engine, "c").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); + let c = forward_val(&mut context, "c").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 4_f64); - assert_eq!(b.to_number(&mut engine).unwrap(), -1_f64); - assert_eq!(c.to_number(&mut engine).unwrap(), 1_f64); + assert_eq!(a.to_number(&mut context).unwrap(), 4_f64); + assert_eq!(b.to_number(&mut context).unwrap(), -1_f64); + assert_eq!(c.to_number(&mut context).unwrap(), 1_f64); } #[test] fn ceil() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.ceil(1.95); var b = Math.ceil(4); var c = Math.ceil(-7.004); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); - let c = forward_val(&mut engine, "c").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); + let c = forward_val(&mut context, "c").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 2_f64); - assert_eq!(b.to_number(&mut engine).unwrap(), 4_f64); - assert_eq!(c.to_number(&mut engine).unwrap(), -7_f64); + assert_eq!(a.to_number(&mut context).unwrap(), 2_f64); + assert_eq!(b.to_number(&mut context).unwrap(), 4_f64); + assert_eq!(c.to_number(&mut context).unwrap(), -7_f64); } #[test] #[allow(clippy::many_single_char_names)] fn clz32() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.clz32(); var b = Math.clz32({}); @@ -189,88 +189,88 @@ fn clz32() { var h = Math.clz32(0); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); - let c = forward_val(&mut engine, "c").unwrap(); - let d = forward_val(&mut engine, "d").unwrap(); - let e = forward_val(&mut engine, "e").unwrap(); - let f = forward_val(&mut engine, "f").unwrap(); - let g = forward_val(&mut engine, "g").unwrap(); - let h = forward_val(&mut engine, "h").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); + let c = forward_val(&mut context, "c").unwrap(); + let d = forward_val(&mut context, "d").unwrap(); + let e = forward_val(&mut context, "e").unwrap(); + let f = forward_val(&mut context, "f").unwrap(); + let g = forward_val(&mut context, "g").unwrap(); + let h = forward_val(&mut context, "h").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 32_f64); - assert_eq!(b.to_number(&mut engine).unwrap(), 32_f64); - assert_eq!(c.to_number(&mut engine).unwrap(), 0_f64); - assert_eq!(d.to_number(&mut engine).unwrap(), 31_f64); - assert_eq!(e.to_number(&mut engine).unwrap(), 1_f64); - assert_eq!(f.to_number(&mut engine).unwrap(), 32_f64); - assert_eq!(g.to_number(&mut engine).unwrap(), 31_f64); - assert_eq!(h.to_number(&mut engine).unwrap(), 32_f64); + assert_eq!(a.to_number(&mut context).unwrap(), 32_f64); + assert_eq!(b.to_number(&mut context).unwrap(), 32_f64); + assert_eq!(c.to_number(&mut context).unwrap(), 0_f64); + assert_eq!(d.to_number(&mut context).unwrap(), 31_f64); + assert_eq!(e.to_number(&mut context).unwrap(), 1_f64); + assert_eq!(f.to_number(&mut context).unwrap(), 32_f64); + assert_eq!(g.to_number(&mut context).unwrap(), 31_f64); + assert_eq!(h.to_number(&mut context).unwrap(), 32_f64); } #[test] fn cos() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.cos(0); var b = Math.cos(1); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 1_f64); - assert_eq!(b.to_number(&mut engine).unwrap(), 0.540_302_305_868_139_8); + assert_eq!(a.to_number(&mut context).unwrap(), 1_f64); + assert_eq!(b.to_number(&mut context).unwrap(), 0.540_302_305_868_139_8); } #[test] fn cosh() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.cosh(0); var b = Math.cosh(1); var c = Math.cosh(-1); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); - let c = forward_val(&mut engine, "c").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); + let c = forward_val(&mut context, "c").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 1_f64); - assert_eq!(b.to_number(&mut engine).unwrap(), 1.543_080_634_815_243_7); - assert_eq!(c.to_number(&mut engine).unwrap(), 1.543_080_634_815_243_7); + assert_eq!(a.to_number(&mut context).unwrap(), 1_f64); + assert_eq!(b.to_number(&mut context).unwrap(), 1.543_080_634_815_243_7); + assert_eq!(c.to_number(&mut context).unwrap(), 1.543_080_634_815_243_7); } #[test] fn exp() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.exp(0); var b = Math.exp(-1); var c = Math.exp(2); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); - let c = forward_val(&mut engine, "c").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); + let c = forward_val(&mut context, "c").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 1_f64); - assert_eq!(b.to_number(&mut engine).unwrap(), 0.367_879_441_171_442_33); - assert_eq!(c.to_number(&mut engine).unwrap(), 7.389_056_098_930_65); + assert_eq!(a.to_number(&mut context).unwrap(), 1_f64); + assert_eq!(b.to_number(&mut context).unwrap(), 0.367_879_441_171_442_33); + assert_eq!(c.to_number(&mut context).unwrap(), 7.389_056_098_930_65); } #[test] #[allow(clippy::many_single_char_names)] fn expm1() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.expm1(); var b = Math.expm1({}); @@ -280,63 +280,63 @@ fn expm1() { var f = Math.expm1(2); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward(&mut engine, "a"); - let b = forward(&mut engine, "b"); - let c = forward_val(&mut engine, "c").unwrap(); - let d = forward_val(&mut engine, "d").unwrap(); - let e = forward_val(&mut engine, "e").unwrap(); - let f = forward_val(&mut engine, "f").unwrap(); + let a = forward(&mut context, "a"); + let b = forward(&mut context, "b"); + let c = forward_val(&mut context, "c").unwrap(); + let d = forward_val(&mut context, "d").unwrap(); + let e = forward_val(&mut context, "e").unwrap(); + let f = forward_val(&mut context, "f").unwrap(); assert_eq!(a, String::from("NaN")); assert_eq!(b, String::from("NaN")); assert!(float_cmp::approx_eq!( f64, - c.to_number(&mut engine).unwrap(), + c.to_number(&mut context).unwrap(), 1.718_281_828_459_045 )); assert!(float_cmp::approx_eq!( f64, - d.to_number(&mut engine).unwrap(), + d.to_number(&mut context).unwrap(), -0.632_120_558_828_557_7 )); assert!(float_cmp::approx_eq!( f64, - e.to_number(&mut engine).unwrap(), + e.to_number(&mut context).unwrap(), 0_f64 )); assert!(float_cmp::approx_eq!( f64, - f.to_number(&mut engine).unwrap(), + f.to_number(&mut context).unwrap(), 6.389_056_098_930_65 )); } #[test] fn floor() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.floor(1.95); var b = Math.floor(-3.01); var c = Math.floor(3.01); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); - let c = forward_val(&mut engine, "c").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); + let c = forward_val(&mut context, "c").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 1_f64); - assert_eq!(b.to_number(&mut engine).unwrap(), -4_f64); - assert_eq!(c.to_number(&mut engine).unwrap(), 3_f64); + assert_eq!(a.to_number(&mut context).unwrap(), 1_f64); + assert_eq!(b.to_number(&mut context).unwrap(), -4_f64); + assert_eq!(c.to_number(&mut context).unwrap(), 3_f64); } #[test] #[allow(clippy::many_single_char_names)] fn fround() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.fround(NaN); var b = Math.fround(Infinity); @@ -347,29 +347,29 @@ fn fround() { var g = Math.fround(); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward(&mut engine, "a"); - let b = forward(&mut engine, "b"); - let c = forward_val(&mut engine, "c").unwrap(); - let d = forward_val(&mut engine, "d").unwrap(); - let e = forward_val(&mut engine, "e").unwrap(); - let f = forward_val(&mut engine, "f").unwrap(); - let g = forward(&mut engine, "g"); + let a = forward(&mut context, "a"); + let b = forward(&mut context, "b"); + let c = forward_val(&mut context, "c").unwrap(); + let d = forward_val(&mut context, "d").unwrap(); + let e = forward_val(&mut context, "e").unwrap(); + let f = forward_val(&mut context, "f").unwrap(); + let g = forward(&mut context, "g"); assert_eq!(a, String::from("NaN")); assert_eq!(b, String::from("Infinity")); - assert_eq!(c.to_number(&mut engine).unwrap(), 5f64); - assert_eq!(d.to_number(&mut engine).unwrap(), 5.5f64); - assert_eq!(e.to_number(&mut engine).unwrap(), 5.050_000_190_734_863); - assert_eq!(f.to_number(&mut engine).unwrap(), -5.050_000_190_734_863); + assert_eq!(c.to_number(&mut context).unwrap(), 5f64); + assert_eq!(d.to_number(&mut context).unwrap(), 5.5f64); + assert_eq!(e.to_number(&mut context).unwrap(), 5.050_000_190_734_863); + assert_eq!(f.to_number(&mut context).unwrap(), -5.050_000_190_734_863); assert_eq!(g, String::from("NaN")); } #[test] #[allow(clippy::many_single_char_names)] fn hypot() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.hypot(); var b = Math.hypot(3, 4); @@ -380,29 +380,29 @@ fn hypot() { var g = Math.hypot(12); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); - let c = forward_val(&mut engine, "c").unwrap(); - let d = forward_val(&mut engine, "d").unwrap(); - let e = forward_val(&mut engine, "e").unwrap(); - let f = forward_val(&mut engine, "f").unwrap(); - let g = forward_val(&mut engine, "g").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); + let c = forward_val(&mut context, "c").unwrap(); + let d = forward_val(&mut context, "d").unwrap(); + let e = forward_val(&mut context, "e").unwrap(); + let f = forward_val(&mut context, "f").unwrap(); + let g = forward_val(&mut context, "g").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 0f64); - assert_eq!(b.to_number(&mut engine).unwrap(), 5f64); - assert_eq!(c.to_number(&mut engine).unwrap(), 13f64); - assert_eq!(d.to_number(&mut engine).unwrap(), 7.071_067_811_865_475_5); - assert_eq!(e.to_number(&mut engine).unwrap(), 8.774964387392123); - assert!(f.to_number(&mut engine).unwrap().is_infinite()); - assert_eq!(g.to_number(&mut engine).unwrap(), 12f64); + assert_eq!(a.to_number(&mut context).unwrap(), 0f64); + assert_eq!(b.to_number(&mut context).unwrap(), 5f64); + assert_eq!(c.to_number(&mut context).unwrap(), 13f64); + assert_eq!(d.to_number(&mut context).unwrap(), 7.071_067_811_865_475_5); + assert_eq!(e.to_number(&mut context).unwrap(), 8.774964387392123); + assert!(f.to_number(&mut context).unwrap().is_infinite()); + assert_eq!(g.to_number(&mut context).unwrap(), 12f64); } #[test] #[allow(clippy::many_single_char_names)] fn imul() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.imul(3, 4); var b = Math.imul(-5, 12); @@ -412,47 +412,47 @@ fn imul() { var f = Math.imul(); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); - let c = forward_val(&mut engine, "c").unwrap(); - let d = forward_val(&mut engine, "d").unwrap(); - let e = forward_val(&mut engine, "e").unwrap(); - let f = forward_val(&mut engine, "f").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); + let c = forward_val(&mut context, "c").unwrap(); + let d = forward_val(&mut context, "d").unwrap(); + let e = forward_val(&mut context, "e").unwrap(); + let f = forward_val(&mut context, "f").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 12f64); - assert_eq!(b.to_number(&mut engine).unwrap(), -60f64); - assert_eq!(c.to_number(&mut engine).unwrap(), -5f64); - assert_eq!(d.to_number(&mut engine).unwrap(), -10f64); - assert_eq!(e.to_number(&mut engine).unwrap(), 0f64); - assert_eq!(f.to_number(&mut engine).unwrap(), 0f64); + assert_eq!(a.to_number(&mut context).unwrap(), 12f64); + assert_eq!(b.to_number(&mut context).unwrap(), -60f64); + assert_eq!(c.to_number(&mut context).unwrap(), -5f64); + assert_eq!(d.to_number(&mut context).unwrap(), -10f64); + assert_eq!(e.to_number(&mut context).unwrap(), 0f64); + assert_eq!(f.to_number(&mut context).unwrap(), 0f64); } #[test] fn log() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.log(1); var b = Math.log(10); var c = Math.log(-1); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); - let c = forward(&mut engine, "c"); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); + let c = forward(&mut context, "c"); - assert_eq!(a.to_number(&mut engine).unwrap(), 0_f64); - assert_eq!(b.to_number(&mut engine).unwrap(), f64::consts::LN_10); + assert_eq!(a.to_number(&mut context).unwrap(), 0_f64); + assert_eq!(b.to_number(&mut context).unwrap(), f64::consts::LN_10); assert_eq!(c, String::from("NaN")); } #[test] #[allow(clippy::many_single_char_names)] fn log1p() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.log1p(1); var b = Math.log1p(0); @@ -463,19 +463,19 @@ fn log1p() { var g = Math.log1p(); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); - let c = forward_val(&mut engine, "c").unwrap(); - let d = forward(&mut engine, "d"); - let e = forward(&mut engine, "e"); - let f = forward(&mut engine, "f"); - let g = forward(&mut engine, "g"); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); + let c = forward_val(&mut context, "c").unwrap(); + let d = forward(&mut context, "d"); + let e = forward(&mut context, "e"); + let f = forward(&mut context, "f"); + let g = forward(&mut context, "g"); - assert_eq!(a.to_number(&mut engine).unwrap(), f64::consts::LN_2); - assert_eq!(b.to_number(&mut engine).unwrap(), 0f64); - assert_eq!(c.to_number(&mut engine).unwrap(), -36.736_800_569_677_1); + assert_eq!(a.to_number(&mut context).unwrap(), f64::consts::LN_2); + assert_eq!(b.to_number(&mut context).unwrap(), 0f64); + assert_eq!(c.to_number(&mut context).unwrap(), -36.736_800_569_677_1); assert_eq!(d, "-Infinity"); assert_eq!(e, String::from("NaN")); assert_eq!(f, String::from("NaN")); @@ -484,87 +484,87 @@ fn log1p() { #[test] fn log10() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.log10(2); var b = Math.log10(1); var c = Math.log10(-2); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); - let c = forward(&mut engine, "c"); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); + let c = forward(&mut context, "c"); - assert_eq!(a.to_number(&mut engine).unwrap(), f64::consts::LOG10_2); - assert_eq!(b.to_number(&mut engine).unwrap(), 0_f64); + assert_eq!(a.to_number(&mut context).unwrap(), f64::consts::LOG10_2); + assert_eq!(b.to_number(&mut context).unwrap(), 0_f64); assert_eq!(c, String::from("NaN")); } #[test] fn log2() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.log2(3); var b = Math.log2(1); var c = Math.log2(-2); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); - let c = forward(&mut engine, "c"); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); + let c = forward(&mut context, "c"); - assert_eq!(a.to_number(&mut engine).unwrap(), 1.584_962_500_721_156); - assert_eq!(b.to_number(&mut engine).unwrap(), 0_f64); + assert_eq!(a.to_number(&mut context).unwrap(), 1.584_962_500_721_156); + assert_eq!(b.to_number(&mut context).unwrap(), 0_f64); assert_eq!(c, String::from("NaN")); } #[test] fn max() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.max(10, 20); var b = Math.max(-10, -20); var c = Math.max(-10, 20); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); - let c = forward_val(&mut engine, "c").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); + let c = forward_val(&mut context, "c").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 20_f64); - assert_eq!(b.to_number(&mut engine).unwrap(), -10_f64); - assert_eq!(c.to_number(&mut engine).unwrap(), 20_f64); + assert_eq!(a.to_number(&mut context).unwrap(), 20_f64); + assert_eq!(b.to_number(&mut context).unwrap(), -10_f64); + assert_eq!(c.to_number(&mut context).unwrap(), 20_f64); } #[test] fn min() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.min(10, 20); var b = Math.min(-10, -20); var c = Math.min(-10, 20); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); - let c = forward_val(&mut engine, "c").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); + let c = forward_val(&mut context, "c").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 10_f64); - assert_eq!(b.to_number(&mut engine).unwrap(), -20_f64); - assert_eq!(c.to_number(&mut engine).unwrap(), -10_f64); + assert_eq!(a.to_number(&mut context).unwrap(), 10_f64); + assert_eq!(b.to_number(&mut context).unwrap(), -20_f64); + assert_eq!(c.to_number(&mut context).unwrap(), -10_f64); } #[test] fn pow() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.pow(2, 10); var b = Math.pow(-7, 2); @@ -572,158 +572,158 @@ fn pow() { var d = Math.pow(7, -2); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); - let c = forward_val(&mut engine, "c").unwrap(); - let d = forward_val(&mut engine, "d").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); + let c = forward_val(&mut context, "c").unwrap(); + let d = forward_val(&mut context, "d").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 1_024_f64); - assert_eq!(b.to_number(&mut engine).unwrap(), 49_f64); - assert_eq!(c.to_number(&mut engine).unwrap(), 2.0); - assert_eq!(d.to_number(&mut engine).unwrap(), 0.020_408_163_265_306_12); + assert_eq!(a.to_number(&mut context).unwrap(), 1_024_f64); + assert_eq!(b.to_number(&mut context).unwrap(), 49_f64); + assert_eq!(c.to_number(&mut context).unwrap(), 2.0); + assert_eq!(d.to_number(&mut context).unwrap(), 0.020_408_163_265_306_12); } #[test] fn round() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.round(20.5); var b = Math.round(-20.3); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 21.0); - assert_eq!(b.to_number(&mut engine).unwrap(), -20.0); + assert_eq!(a.to_number(&mut context).unwrap(), 21.0); + assert_eq!(b.to_number(&mut context).unwrap(), -20.0); } #[test] fn sign() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.sign(3); var b = Math.sign(-3); var c = Math.sign(0); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); - let c = forward_val(&mut engine, "c").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); + let c = forward_val(&mut context, "c").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 1_f64); - assert_eq!(b.to_number(&mut engine).unwrap(), -1_f64); - assert_eq!(c.to_number(&mut engine).unwrap(), 0_f64); + assert_eq!(a.to_number(&mut context).unwrap(), 1_f64); + assert_eq!(b.to_number(&mut context).unwrap(), -1_f64); + assert_eq!(c.to_number(&mut context).unwrap(), 0_f64); } #[test] fn sin() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.sin(0); var b = Math.sin(1); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 0_f64); - assert_eq!(b.to_number(&mut engine).unwrap(), 0.841_470_984_807_896_5); + assert_eq!(a.to_number(&mut context).unwrap(), 0_f64); + assert_eq!(b.to_number(&mut context).unwrap(), 0.841_470_984_807_896_5); } #[test] fn sinh() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.sinh(0); var b = Math.sinh(1); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 0_f64); - assert_eq!(b.to_number(&mut engine).unwrap(), 1.175_201_193_643_801_4); + assert_eq!(a.to_number(&mut context).unwrap(), 0_f64); + assert_eq!(b.to_number(&mut context).unwrap(), 1.175_201_193_643_801_4); } #[test] fn sqrt() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.sqrt(0); var b = Math.sqrt(2); var c = Math.sqrt(9); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); - let c = forward_val(&mut engine, "c").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); + let c = forward_val(&mut context, "c").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 0_f64); - assert_eq!(b.to_number(&mut engine).unwrap(), f64::consts::SQRT_2); - assert_eq!(c.to_number(&mut engine).unwrap(), 3_f64); + assert_eq!(a.to_number(&mut context).unwrap(), 0_f64); + assert_eq!(b.to_number(&mut context).unwrap(), f64::consts::SQRT_2); + assert_eq!(c.to_number(&mut context).unwrap(), 3_f64); } #[test] fn tan() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.tan(1.1); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); assert!(float_cmp::approx_eq!( f64, - a.to_number(&mut engine).unwrap(), + a.to_number(&mut context).unwrap(), 1.964_759_657_248_652_5 )); } #[test] fn tanh() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.tanh(1); var b = Math.tanh(0); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 0.761_594_155_955_764_9); - assert_eq!(b.to_number(&mut engine).unwrap(), 0_f64); + assert_eq!(a.to_number(&mut context).unwrap(), 0.761_594_155_955_764_9); + assert_eq!(b.to_number(&mut context).unwrap(), 0_f64); } #[test] fn trunc() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = Math.trunc(13.37); var b = Math.trunc(0.123); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward_val(&mut engine, "a").unwrap(); - let b = forward_val(&mut engine, "b").unwrap(); + let a = forward_val(&mut context, "a").unwrap(); + let b = forward_val(&mut context, "b").unwrap(); - assert_eq!(a.to_number(&mut engine).unwrap(), 13_f64); - assert_eq!(b.to_number(&mut engine).unwrap(), 0_f64); + assert_eq!(a.to_number(&mut context).unwrap(), 13_f64); + assert_eq!(b.to_number(&mut context).unwrap(), 0_f64); } diff --git a/boa/src/builtins/nan/mod.rs b/boa/src/builtins/nan/mod.rs index 5c5b419451..b374c37e38 100644 --- a/boa/src/builtins/nan/mod.rs +++ b/boa/src/builtins/nan/mod.rs @@ -26,7 +26,7 @@ impl BuiltIn for NaN { Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT } - fn init(_context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(_: &mut Context) -> (&'static str, Value, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); (Self::NAME, f64::NAN.into(), Self::attribute()) diff --git a/boa/src/builtins/number/mod.rs b/boa/src/builtins/number/mod.rs index 41970e8a35..9b1da76c11 100644 --- a/boa/src/builtins/number/mod.rs +++ b/boa/src/builtins/number/mod.rs @@ -153,9 +153,13 @@ impl Number { pub(crate) const MIN_VALUE: f64 = f64::MIN; /// `Number( value )` - pub(crate) fn constructor(this: &Value, args: &[Value], ctx: &mut Context) -> Result { + pub(crate) fn constructor( + this: &Value, + args: &[Value], + context: &mut Context, + ) -> Result { let data = match args.get(0) { - Some(ref value) => value.to_numeric_number(ctx)?, + Some(ref value) => value.to_numeric_number(context)?, None => 0.0, }; this.set_data(ObjectData::Number(data)); @@ -172,7 +176,7 @@ impl Number { /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-thisnumbervalue - fn this_number_value(value: &Value, ctx: &mut Context) -> Result { + fn this_number_value(value: &Value, context: &mut Context) -> Result { match *value { Value::Integer(integer) => return Ok(f64::from(integer)), Value::Rational(rational) => return Ok(rational), @@ -184,7 +188,7 @@ impl Number { _ => {} } - Err(ctx.construct_type_error("'this' is not a number")) + Err(context.construct_type_error("'this' is not a number")) } /// Helper function that formats a float as a ES6-style exponential number string. @@ -209,10 +213,10 @@ impl Number { #[allow(clippy::wrong_self_convention)] pub(crate) fn to_exponential( this: &Value, - _args: &[Value], - ctx: &mut Context, + _: &[Value], + context: &mut Context, ) -> Result { - let this_num = Self::this_number_value(this, ctx)?; + let this_num = Self::this_number_value(this, context)?; let this_str_num = Self::num_to_exponential(this_num); Ok(Value::from(this_str_num)) } @@ -228,11 +232,11 @@ 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 Context) -> Result { - let this_num = Self::this_number_value(this, ctx)?; + pub(crate) fn to_fixed(this: &Value, args: &[Value], context: &mut Context) -> Result { + let this_num = Self::this_number_value(this, context)?; let precision = match args.get(0) { - Some(n) => match n.to_integer(ctx)? as i32 { - x if x > 0 => n.to_integer(ctx)? as usize, + Some(n) => match n.to_integer(context)? as i32 { + x if x > 0 => n.to_integer(context)? as usize, _ => 0, }, None => 0, @@ -257,10 +261,10 @@ impl Number { #[allow(clippy::wrong_self_convention)] pub(crate) fn to_locale_string( this: &Value, - _args: &[Value], - ctx: &mut Context, + _: &[Value], + context: &mut Context, ) -> Result { - let this_num = Self::this_number_value(this, ctx)?; + let this_num = Self::this_number_value(this, context)?; let this_str_num = format!("{}", this_num); Ok(Value::from(this_str_num)) } @@ -276,12 +280,16 @@ 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 Context) -> Result { - let this_num = Self::this_number_value(this, ctx)?; + pub(crate) fn to_precision( + this: &Value, + args: &[Value], + context: &mut Context, + ) -> Result { + let this_num = Self::this_number_value(this, context)?; let _num_str_len = format!("{}", this_num).len(); let _precision = match args.get(0) { - Some(n) => match n.to_integer(ctx)? as i32 { - x if x > 0 => n.to_integer(ctx)? as usize, + Some(n) => match n.to_integer(context)? as i32 { + x if x > 0 => n.to_integer(context)? as usize, _ => 0, }, None => 0, @@ -430,21 +438,21 @@ 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 Context) -> Result { + pub(crate) fn to_string(this: &Value, args: &[Value], context: &mut Context) -> Result { // 1. Let x be ? thisNumberValue(this value). - let x = Self::this_number_value(this, ctx)?; + let x = Self::this_number_value(this, context)?; // 2. If radix is undefined, let radixNumber be 10. // 3. Else, let radixNumber be ? ToInteger(radix). let radix = args .get(0) - .map(|arg| arg.to_integer(ctx)) + .map(|arg| arg.to_integer(context)) .transpose()? .map_or(10, |radix| radix as u8); // 4. If radixNumber < 2 or radixNumber > 36, throw a RangeError exception. if radix < 2 || radix > 36 { - return ctx + return context .throw_range_error("radix must be an integer at least 2 and no greater than 36"); } @@ -485,8 +493,8 @@ 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 Context) -> Result { - Ok(Value::from(Self::this_number_value(this, ctx)?)) + pub(crate) fn value_of(this: &Value, _: &[Value], context: &mut Context) -> Result { + Ok(Value::from(Self::this_number_value(this, context)?)) } /// Builtin javascript 'parseInt(str, radix)' function. @@ -503,7 +511,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 Context) -> Result { + pub(crate) fn parse_int(_: &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 { @@ -569,7 +577,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 Context) -> Result { + pub(crate) fn parse_float(_: &Value, args: &[Value], _ctx: &mut Context) -> Result { if let Some(val) = args.get(0) { match val { Value::String(s) => { @@ -612,12 +620,12 @@ impl Number { /// [spec]: https://tc39.es/ecma262/#sec-isfinite-number /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite pub(crate) fn global_is_finite( - _this: &Value, + _: &Value, args: &[Value], - ctx: &mut Context, + context: &mut Context, ) -> Result { if let Some(value) = args.get(0) { - let number = value.to_number(ctx)?; + let number = value.to_number(context)?; Ok(number.is_finite().into()) } else { Ok(false.into()) @@ -638,9 +646,9 @@ 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 Context) -> Result { + pub(crate) fn global_is_nan(_: &Value, args: &[Value], context: &mut Context) -> Result { if let Some(value) = args.get(0) { - let number = value.to_number(ctx)?; + let number = value.to_number(context)?; Ok(number.is_nan().into()) } else { Ok(true.into()) @@ -661,11 +669,7 @@ impl Number { /// /// [spec]: https://tc39.es/ecma262/#sec-number.isfinite /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite - pub(crate) fn number_is_finite( - _this: &Value, - args: &[Value], - _ctx: &mut Context, - ) -> Result { + pub(crate) fn number_is_finite(_: &Value, args: &[Value], _ctx: &mut Context) -> Result { Ok(Value::from(if let Some(val) = args.get(0) { match val { Value::Integer(_) => true, @@ -688,7 +692,7 @@ impl Number { /// [spec]: https://tc39.es/ecma262/#sec-number.isinteger /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger pub(crate) fn number_is_integer( - _this: &Value, + _: &Value, args: &[Value], _ctx: &mut Context, ) -> Result { @@ -709,11 +713,7 @@ impl Number { /// /// [spec]: https://tc39.es/ecma262/#sec-isnan-number /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN - pub(crate) fn number_is_nan( - _this: &Value, - args: &[Value], - _ctx: &mut Context, - ) -> Result { + pub(crate) fn number_is_nan(_: &Value, args: &[Value], _ctx: &mut Context) -> Result { Ok(Value::from(if let Some(val) = args.get(0) { match val { Value::Integer(_) => false, @@ -739,11 +739,7 @@ impl Number { /// /// [spec]: https://tc39.es/ecma262/#sec-isnan-number /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN - pub(crate) fn is_safe_integer( - _this: &Value, - args: &[Value], - _ctx: &mut Context, - ) -> Result { + pub(crate) fn is_safe_integer(_: &Value, args: &[Value], _ctx: &mut Context) -> Result { Ok(Value::from(match args.get(0) { Some(Value::Integer(_)) => true, Some(Value::Rational(number)) if Self::is_float_integer(*number) => { diff --git a/boa/src/builtins/number/tests.rs b/boa/src/builtins/number/tests.rs index 055b6d55a2..b53ddf5ea0 100644 --- a/boa/src/builtins/number/tests.rs +++ b/boa/src/builtins/number/tests.rs @@ -4,18 +4,18 @@ use crate::{builtins::Number, forward, forward_val, Context}; #[test] fn integer_number_primitive_to_number_object() { - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = r#" (100).toString() === "100" "#; - assert_eq!(forward(&mut engine, scenario), "true"); + assert_eq!(forward(&mut context, scenario), "true"); } #[test] fn call_number() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var default_zero = Number(); var int_one = Number(1); @@ -27,29 +27,29 @@ fn call_number() { var from_exp = Number("2.34e+2"); "#; - eprintln!("{}", forward(&mut engine, init)); - let default_zero = forward_val(&mut engine, "default_zero").unwrap(); - let int_one = forward_val(&mut engine, "int_one").unwrap(); - let float_two = forward_val(&mut engine, "float_two").unwrap(); - let str_three = forward_val(&mut engine, "str_three").unwrap(); - let bool_one = forward_val(&mut engine, "bool_one").unwrap(); - let bool_zero = forward_val(&mut engine, "bool_zero").unwrap(); - let invalid_nan = forward_val(&mut engine, "invalid_nan").unwrap(); - let from_exp = forward_val(&mut engine, "from_exp").unwrap(); + eprintln!("{}", forward(&mut context, init)); + let default_zero = forward_val(&mut context, "default_zero").unwrap(); + let int_one = forward_val(&mut context, "int_one").unwrap(); + let float_two = forward_val(&mut context, "float_two").unwrap(); + let str_three = forward_val(&mut context, "str_three").unwrap(); + let bool_one = forward_val(&mut context, "bool_one").unwrap(); + let bool_zero = forward_val(&mut context, "bool_zero").unwrap(); + let invalid_nan = forward_val(&mut context, "invalid_nan").unwrap(); + let from_exp = forward_val(&mut context, "from_exp").unwrap(); - assert_eq!(default_zero.to_number(&mut engine).unwrap(), 0_f64); - assert_eq!(int_one.to_number(&mut engine).unwrap(), 1_f64); - assert_eq!(float_two.to_number(&mut engine).unwrap(), 2.1); - assert_eq!(str_three.to_number(&mut engine).unwrap(), 3.2); - assert_eq!(bool_one.to_number(&mut engine).unwrap(), 1_f64); - assert!(invalid_nan.to_number(&mut engine).unwrap().is_nan()); - assert_eq!(bool_zero.to_number(&mut engine).unwrap(), 0_f64); - assert_eq!(from_exp.to_number(&mut engine).unwrap(), 234_f64); + assert_eq!(default_zero.to_number(&mut context).unwrap(), 0_f64); + assert_eq!(int_one.to_number(&mut context).unwrap(), 1_f64); + assert_eq!(float_two.to_number(&mut context).unwrap(), 2.1); + assert_eq!(str_three.to_number(&mut context).unwrap(), 3.2); + assert_eq!(bool_one.to_number(&mut context).unwrap(), 1_f64); + assert!(invalid_nan.to_number(&mut context).unwrap().is_nan()); + assert_eq!(bool_zero.to_number(&mut context).unwrap(), 0_f64); + assert_eq!(from_exp.to_number(&mut context).unwrap(), 234_f64); } #[test] fn to_exponential() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var default_exp = Number().toExponential(); var int_exp = Number(5).toExponential(); @@ -59,13 +59,13 @@ fn to_exponential() { var noop_exp = Number("1.23e+2").toExponential(); "#; - eprintln!("{}", forward(&mut engine, init)); - let default_exp = forward(&mut engine, "default_exp"); - let int_exp = forward(&mut engine, "int_exp"); - let float_exp = forward(&mut engine, "float_exp"); - let big_exp = forward(&mut engine, "big_exp"); - let nan_exp = forward(&mut engine, "nan_exp"); - let noop_exp = forward(&mut engine, "noop_exp"); + eprintln!("{}", forward(&mut context, init)); + let default_exp = forward(&mut context, "default_exp"); + let int_exp = forward(&mut context, "int_exp"); + let float_exp = forward(&mut context, "float_exp"); + let big_exp = forward(&mut context, "big_exp"); + let nan_exp = forward(&mut context, "nan_exp"); + let noop_exp = forward(&mut context, "noop_exp"); assert_eq!(default_exp, "\"0e+0\""); assert_eq!(int_exp, "\"5e+0\""); @@ -77,7 +77,7 @@ fn to_exponential() { #[test] fn to_fixed() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var default_fixed = Number().toFixed(); var pos_fixed = Number("3.456e+4").toFixed(); @@ -86,12 +86,12 @@ fn to_fixed() { var nan_fixed = Number("I am not a number").toFixed(); "#; - eprintln!("{}", forward(&mut engine, init)); - let default_fixed = forward(&mut engine, "default_fixed"); - let pos_fixed = forward(&mut engine, "pos_fixed"); - let neg_fixed = forward(&mut engine, "neg_fixed"); - let noop_fixed = forward(&mut engine, "noop_fixed"); - let nan_fixed = forward(&mut engine, "nan_fixed"); + eprintln!("{}", forward(&mut context, init)); + let default_fixed = forward(&mut context, "default_fixed"); + let pos_fixed = forward(&mut context, "pos_fixed"); + let neg_fixed = forward(&mut context, "neg_fixed"); + let noop_fixed = forward(&mut context, "noop_fixed"); + let nan_fixed = forward(&mut context, "nan_fixed"); assert_eq!(default_fixed, "\"0\""); assert_eq!(pos_fixed, "\"34560\""); @@ -102,7 +102,7 @@ fn to_fixed() { #[test] fn to_locale_string() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var default_locale = Number().toLocaleString(); var small_locale = Number(5).toLocaleString(); @@ -113,11 +113,11 @@ fn to_locale_string() { // TODO: We don't actually do any locale checking here // To honor the spec we should print numbers according to user locale. - eprintln!("{}", forward(&mut engine, init)); - let default_locale = forward(&mut engine, "default_locale"); - let small_locale = forward(&mut engine, "small_locale"); - let big_locale = forward(&mut engine, "big_locale"); - let neg_locale = forward(&mut engine, "neg_locale"); + eprintln!("{}", forward(&mut context, init)); + let default_locale = forward(&mut context, "default_locale"); + let small_locale = forward(&mut context, "small_locale"); + let big_locale = forward(&mut context, "big_locale"); + let neg_locale = forward(&mut context, "neg_locale"); assert_eq!(default_locale, "\"0\""); assert_eq!(small_locale, "\"5\""); @@ -128,7 +128,7 @@ fn to_locale_string() { #[test] #[ignore] fn to_precision() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var default_precision = Number().toPrecision(); var low_precision = Number(123456789).toPrecision(1); @@ -138,13 +138,13 @@ fn to_precision() { var neg_precision = Number(-123456789).toPrecision(4); "#; - eprintln!("{}", forward(&mut engine, init)); - let default_precision = forward(&mut engine, "default_precision"); - let low_precision = forward(&mut engine, "low_precision"); - let more_precision = forward(&mut engine, "more_precision"); - let exact_precision = forward(&mut engine, "exact_precision"); - let over_precision = forward(&mut engine, "over_precision"); - let neg_precision = forward(&mut engine, "neg_precision"); + eprintln!("{}", forward(&mut context, init)); + let default_precision = forward(&mut context, "default_precision"); + let low_precision = forward(&mut context, "low_precision"); + let more_precision = forward(&mut context, "more_precision"); + let exact_precision = forward(&mut context, "exact_precision"); + let over_precision = forward(&mut context, "over_precision"); + let neg_precision = forward(&mut context, "neg_precision"); assert_eq!(default_precision, String::from("0")); assert_eq!(low_precision, String::from("1e+8")); @@ -159,217 +159,229 @@ fn to_precision() { #[test] fn to_string() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!("\"NaN\"", &forward(&mut engine, "Number(NaN).toString()")); + assert_eq!("\"NaN\"", &forward(&mut context, "Number(NaN).toString()")); assert_eq!( "\"Infinity\"", - &forward(&mut engine, "Number(1/0).toString()") + &forward(&mut context, "Number(1/0).toString()") ); assert_eq!( "\"-Infinity\"", - &forward(&mut engine, "Number(-1/0).toString()") + &forward(&mut context, "Number(-1/0).toString()") ); - assert_eq!("\"0\"", &forward(&mut engine, "Number(0).toString()")); - assert_eq!("\"9\"", &forward(&mut engine, "Number(9).toString()")); - assert_eq!("\"90\"", &forward(&mut engine, "Number(90).toString()")); + assert_eq!("\"0\"", &forward(&mut context, "Number(0).toString()")); + assert_eq!("\"9\"", &forward(&mut context, "Number(9).toString()")); + assert_eq!("\"90\"", &forward(&mut context, "Number(90).toString()")); assert_eq!( "\"90.12\"", - &forward(&mut engine, "Number(90.12).toString()") + &forward(&mut context, "Number(90.12).toString()") + ); + assert_eq!("\"0.1\"", &forward(&mut context, "Number(0.1).toString()")); + assert_eq!( + "\"0.01\"", + &forward(&mut context, "Number(0.01).toString()") ); - assert_eq!("\"0.1\"", &forward(&mut engine, "Number(0.1).toString()")); - assert_eq!("\"0.01\"", &forward(&mut engine, "Number(0.01).toString()")); assert_eq!( "\"0.0123\"", - &forward(&mut engine, "Number(0.0123).toString()") + &forward(&mut context, "Number(0.0123).toString()") ); assert_eq!( "\"0.00001\"", - &forward(&mut engine, "Number(0.00001).toString()") + &forward(&mut context, "Number(0.00001).toString()") ); assert_eq!( "\"0.000001\"", - &forward(&mut engine, "Number(0.000001).toString()") + &forward(&mut context, "Number(0.000001).toString()") + ); + assert_eq!( + "\"NaN\"", + &forward(&mut context, "Number(NaN).toString(16)") ); - assert_eq!("\"NaN\"", &forward(&mut engine, "Number(NaN).toString(16)")); assert_eq!( "\"Infinity\"", - &forward(&mut engine, "Number(1/0).toString(16)") + &forward(&mut context, "Number(1/0).toString(16)") ); assert_eq!( "\"-Infinity\"", - &forward(&mut engine, "Number(-1/0).toString(16)") + &forward(&mut context, "Number(-1/0).toString(16)") ); - assert_eq!("\"0\"", &forward(&mut engine, "Number(0).toString(16)")); - assert_eq!("\"9\"", &forward(&mut engine, "Number(9).toString(16)")); - assert_eq!("\"5a\"", &forward(&mut engine, "Number(90).toString(16)")); + assert_eq!("\"0\"", &forward(&mut context, "Number(0).toString(16)")); + assert_eq!("\"9\"", &forward(&mut context, "Number(9).toString(16)")); + assert_eq!("\"5a\"", &forward(&mut context, "Number(90).toString(16)")); assert_eq!( "\"5a.1eb851eb852\"", - &forward(&mut engine, "Number(90.12).toString(16)") + &forward(&mut context, "Number(90.12).toString(16)") ); assert_eq!( "\"0.1999999999999a\"", - &forward(&mut engine, "Number(0.1).toString(16)") + &forward(&mut context, "Number(0.1).toString(16)") ); assert_eq!( "\"0.028f5c28f5c28f6\"", - &forward(&mut engine, "Number(0.01).toString(16)") + &forward(&mut context, "Number(0.01).toString(16)") ); assert_eq!( "\"0.032617c1bda511a\"", - &forward(&mut engine, "Number(0.0123).toString(16)") + &forward(&mut context, "Number(0.0123).toString(16)") ); assert_eq!( "\"605f9f6dd18bc8000\"", - &forward(&mut engine, "Number(111111111111111111111).toString(16)") + &forward(&mut context, "Number(111111111111111111111).toString(16)") ); assert_eq!( "\"3c3bc3a4a2f75c0000\"", - &forward(&mut engine, "Number(1111111111111111111111).toString(16)") + &forward(&mut context, "Number(1111111111111111111111).toString(16)") ); assert_eq!( "\"25a55a46e5da9a00000\"", - &forward(&mut engine, "Number(11111111111111111111111).toString(16)") + &forward(&mut context, "Number(11111111111111111111111).toString(16)") ); assert_eq!( "\"0.0000a7c5ac471b4788\"", - &forward(&mut engine, "Number(0.00001).toString(16)") + &forward(&mut context, "Number(0.00001).toString(16)") ); assert_eq!( "\"0.000010c6f7a0b5ed8d\"", - &forward(&mut engine, "Number(0.000001).toString(16)") + &forward(&mut context, "Number(0.000001).toString(16)") ); assert_eq!( "\"0.000001ad7f29abcaf48\"", - &forward(&mut engine, "Number(0.0000001).toString(16)") + &forward(&mut context, "Number(0.0000001).toString(16)") ); assert_eq!( "\"0.000002036565348d256\"", - &forward(&mut engine, "Number(0.00000012).toString(16)") + &forward(&mut context, "Number(0.00000012).toString(16)") ); assert_eq!( "\"0.0000021047ee22aa466\"", - &forward(&mut engine, "Number(0.000000123).toString(16)") + &forward(&mut context, "Number(0.000000123).toString(16)") ); assert_eq!( "\"0.0000002af31dc4611874\"", - &forward(&mut engine, "Number(0.00000001).toString(16)") + &forward(&mut context, "Number(0.00000001).toString(16)") ); assert_eq!( "\"0.000000338a23b87483be\"", - &forward(&mut engine, "Number(0.000000012).toString(16)") + &forward(&mut context, "Number(0.000000012).toString(16)") ); assert_eq!( "\"0.00000034d3fe36aaa0a2\"", - &forward(&mut engine, "Number(0.0000000123).toString(16)") + &forward(&mut context, "Number(0.0000000123).toString(16)") ); - assert_eq!("\"0\"", &forward(&mut engine, "Number(-0).toString(16)")); - assert_eq!("\"-9\"", &forward(&mut engine, "Number(-9).toString(16)")); - assert_eq!("\"-5a\"", &forward(&mut engine, "Number(-90).toString(16)")); + assert_eq!("\"0\"", &forward(&mut context, "Number(-0).toString(16)")); + assert_eq!("\"-9\"", &forward(&mut context, "Number(-9).toString(16)")); + assert_eq!( + "\"-5a\"", + &forward(&mut context, "Number(-90).toString(16)") + ); assert_eq!( "\"-5a.1eb851eb852\"", - &forward(&mut engine, "Number(-90.12).toString(16)") + &forward(&mut context, "Number(-90.12).toString(16)") ); assert_eq!( "\"-0.1999999999999a\"", - &forward(&mut engine, "Number(-0.1).toString(16)") + &forward(&mut context, "Number(-0.1).toString(16)") ); assert_eq!( "\"-0.028f5c28f5c28f6\"", - &forward(&mut engine, "Number(-0.01).toString(16)") + &forward(&mut context, "Number(-0.01).toString(16)") ); assert_eq!( "\"-0.032617c1bda511a\"", - &forward(&mut engine, "Number(-0.0123).toString(16)") + &forward(&mut context, "Number(-0.0123).toString(16)") ); assert_eq!( "\"-605f9f6dd18bc8000\"", - &forward(&mut engine, "Number(-111111111111111111111).toString(16)") + &forward(&mut context, "Number(-111111111111111111111).toString(16)") ); assert_eq!( "\"-3c3bc3a4a2f75c0000\"", - &forward(&mut engine, "Number(-1111111111111111111111).toString(16)") + &forward(&mut context, "Number(-1111111111111111111111).toString(16)") ); assert_eq!( "\"-25a55a46e5da9a00000\"", - &forward(&mut engine, "Number(-11111111111111111111111).toString(16)") + &forward( + &mut context, + "Number(-11111111111111111111111).toString(16)" + ) ); assert_eq!( "\"-0.0000a7c5ac471b4788\"", - &forward(&mut engine, "Number(-0.00001).toString(16)") + &forward(&mut context, "Number(-0.00001).toString(16)") ); assert_eq!( "\"-0.000010c6f7a0b5ed8d\"", - &forward(&mut engine, "Number(-0.000001).toString(16)") + &forward(&mut context, "Number(-0.000001).toString(16)") ); assert_eq!( "\"-0.000001ad7f29abcaf48\"", - &forward(&mut engine, "Number(-0.0000001).toString(16)") + &forward(&mut context, "Number(-0.0000001).toString(16)") ); assert_eq!( "\"-0.000002036565348d256\"", - &forward(&mut engine, "Number(-0.00000012).toString(16)") + &forward(&mut context, "Number(-0.00000012).toString(16)") ); assert_eq!( "\"-0.0000021047ee22aa466\"", - &forward(&mut engine, "Number(-0.000000123).toString(16)") + &forward(&mut context, "Number(-0.000000123).toString(16)") ); assert_eq!( "\"-0.0000002af31dc4611874\"", - &forward(&mut engine, "Number(-0.00000001).toString(16)") + &forward(&mut context, "Number(-0.00000001).toString(16)") ); assert_eq!( "\"-0.000000338a23b87483be\"", - &forward(&mut engine, "Number(-0.000000012).toString(16)") + &forward(&mut context, "Number(-0.000000012).toString(16)") ); assert_eq!( "\"-0.00000034d3fe36aaa0a2\"", - &forward(&mut engine, "Number(-0.0000000123).toString(16)") + &forward(&mut context, "Number(-0.0000000123).toString(16)") ); } #[test] fn num_to_string_exponential() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!("\"0\"", forward(&mut engine, "(0).toString()")); - assert_eq!("\"0\"", forward(&mut engine, "(-0).toString()")); + assert_eq!("\"0\"", forward(&mut context, "(0).toString()")); + assert_eq!("\"0\"", forward(&mut context, "(-0).toString()")); assert_eq!( "\"111111111111111110000\"", - forward(&mut engine, "(111111111111111111111).toString()") + forward(&mut context, "(111111111111111111111).toString()") ); assert_eq!( "\"1.1111111111111111e+21\"", - forward(&mut engine, "(1111111111111111111111).toString()") + forward(&mut context, "(1111111111111111111111).toString()") ); assert_eq!( "\"1.1111111111111111e+22\"", - forward(&mut engine, "(11111111111111111111111).toString()") + forward(&mut context, "(11111111111111111111111).toString()") ); - assert_eq!("\"1e-7\"", forward(&mut engine, "(0.0000001).toString()")); + assert_eq!("\"1e-7\"", forward(&mut context, "(0.0000001).toString()")); assert_eq!( "\"1.2e-7\"", - forward(&mut engine, "(0.00000012).toString()") + forward(&mut context, "(0.00000012).toString()") ); assert_eq!( "\"1.23e-7\"", - forward(&mut engine, "(0.000000123).toString()") + forward(&mut context, "(0.000000123).toString()") ); - assert_eq!("\"1e-8\"", forward(&mut engine, "(0.00000001).toString()")); + assert_eq!("\"1e-8\"", forward(&mut context, "(0.00000001).toString()")); assert_eq!( "\"1.2e-8\"", - forward(&mut engine, "(0.000000012).toString()") + forward(&mut context, "(0.000000012).toString()") ); assert_eq!( "\"1.23e-8\"", - forward(&mut engine, "(0.0000000123).toString()") + forward(&mut context, "(0.0000000123).toString()") ); } #[test] fn value_of() { - let mut engine = Context::new(); + let mut context = 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#" @@ -380,18 +392,18 @@ fn value_of() { var neg_val = Number("-1.2e+4").valueOf() "#; - eprintln!("{}", forward(&mut engine, init)); - let default_val = forward_val(&mut engine, "default_val").unwrap(); - let int_val = forward_val(&mut engine, "int_val").unwrap(); - let float_val = forward_val(&mut engine, "float_val").unwrap(); - let exp_val = forward_val(&mut engine, "exp_val").unwrap(); - let neg_val = forward_val(&mut engine, "neg_val").unwrap(); + eprintln!("{}", forward(&mut context, init)); + let default_val = forward_val(&mut context, "default_val").unwrap(); + let int_val = forward_val(&mut context, "int_val").unwrap(); + let float_val = forward_val(&mut context, "float_val").unwrap(); + let exp_val = forward_val(&mut context, "exp_val").unwrap(); + let neg_val = forward_val(&mut context, "neg_val").unwrap(); - assert_eq!(default_val.to_number(&mut engine).unwrap(), 0_f64); - assert_eq!(int_val.to_number(&mut engine).unwrap(), 123_f64); - assert_eq!(float_val.to_number(&mut engine).unwrap(), 1.234); - assert_eq!(exp_val.to_number(&mut engine).unwrap(), 12_000_f64); - assert_eq!(neg_val.to_number(&mut engine).unwrap(), -12_000_f64); + assert_eq!(default_val.to_number(&mut context).unwrap(), 0_f64); + assert_eq!(int_val.to_number(&mut context).unwrap(), 123_f64); + assert_eq!(float_val.to_number(&mut context).unwrap(), 1.234); + assert_eq!(exp_val.to_number(&mut context).unwrap(), 12_000_f64); + assert_eq!(neg_val.to_number(&mut context).unwrap(), -12_000_f64); } #[test] @@ -427,95 +439,95 @@ fn same_value_zero() { #[test] fn from_bigint() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(&forward(&mut engine, "Number(0n)"), "0",); - assert_eq!(&forward(&mut engine, "Number(100000n)"), "100000",); - assert_eq!(&forward(&mut engine, "Number(100000n)"), "100000",); - assert_eq!(&forward(&mut engine, "Number(1n << 1240n)"), "Infinity",); + assert_eq!(&forward(&mut context, "Number(0n)"), "0",); + assert_eq!(&forward(&mut context, "Number(100000n)"), "100000",); + assert_eq!(&forward(&mut context, "Number(100000n)"), "100000",); + assert_eq!(&forward(&mut context, "Number(1n << 1240n)"), "Infinity",); } #[test] fn number_constants() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert!(!forward_val(&mut engine, "Number.EPSILON") + assert!(!forward_val(&mut context, "Number.EPSILON") .unwrap() .is_null_or_undefined()); - assert!(!forward_val(&mut engine, "Number.MAX_SAFE_INTEGER") + assert!(!forward_val(&mut context, "Number.MAX_SAFE_INTEGER") .unwrap() .is_null_or_undefined()); - assert!(!forward_val(&mut engine, "Number.MIN_SAFE_INTEGER") + assert!(!forward_val(&mut context, "Number.MIN_SAFE_INTEGER") .unwrap() .is_null_or_undefined()); - assert!(!forward_val(&mut engine, "Number.MAX_VALUE") + assert!(!forward_val(&mut context, "Number.MAX_VALUE") .unwrap() .is_null_or_undefined()); - assert!(!forward_val(&mut engine, "Number.MIN_VALUE") + assert!(!forward_val(&mut context, "Number.MIN_VALUE") .unwrap() .is_null_or_undefined()); - assert!(!forward_val(&mut engine, "Number.NEGATIVE_INFINITY") + assert!(!forward_val(&mut context, "Number.NEGATIVE_INFINITY") .unwrap() .is_null_or_undefined()); - assert!(!forward_val(&mut engine, "Number.POSITIVE_INFINITY") + assert!(!forward_val(&mut context, "Number.POSITIVE_INFINITY") .unwrap() .is_null_or_undefined()); } #[test] fn parse_int_simple() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(&forward(&mut engine, "parseInt(\"6\")"), "6"); + assert_eq!(&forward(&mut context, "parseInt(\"6\")"), "6"); } #[test] fn parse_int_negative() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(&forward(&mut engine, "parseInt(\"-9\")"), "-9"); + assert_eq!(&forward(&mut context, "parseInt(\"-9\")"), "-9"); } #[test] fn parse_int_already_int() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(&forward(&mut engine, "parseInt(100)"), "100"); + assert_eq!(&forward(&mut context, "parseInt(100)"), "100"); } #[test] fn parse_int_float() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(&forward(&mut engine, "parseInt(100.5)"), "100"); + assert_eq!(&forward(&mut context, "parseInt(100.5)"), "100"); } #[test] fn parse_int_float_str() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(&forward(&mut engine, "parseInt(\"100.5\")"), "NaN"); + assert_eq!(&forward(&mut context, "parseInt(\"100.5\")"), "NaN"); } #[test] fn parse_int_inferred_hex() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(&forward(&mut engine, "parseInt(\"0xA\")"), "10"); + assert_eq!(&forward(&mut context, "parseInt(\"0xA\")"), "10"); } /// This test demonstrates that this version of parseInt treats strings starting with 0 to be parsed with /// a radix 10 if no radix is specified. Some alternative implementations default to a radix of 8. #[test] fn parse_int_zero_start() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(&forward(&mut engine, "parseInt(\"018\")"), "18"); + assert_eq!(&forward(&mut context, "parseInt(\"018\")"), "18"); } #[test] fn parse_int_varying_radix() { - let mut engine = Context::new(); + let mut context = Context::new(); let base_str = "1000"; @@ -524,7 +536,7 @@ fn parse_int_varying_radix() { assert_eq!( forward( - &mut engine, + &mut context, &format!("parseInt(\"{}\", {} )", base_str, radix) ), expected.to_string() @@ -534,7 +546,7 @@ fn parse_int_varying_radix() { #[test] fn parse_int_negative_varying_radix() { - let mut engine = Context::new(); + let mut context = Context::new(); let base_str = "-1000"; @@ -543,7 +555,7 @@ fn parse_int_negative_varying_radix() { assert_eq!( forward( - &mut engine, + &mut context, &format!("parseInt(\"{}\", {} )", base_str, radix) ), expected.to_string() @@ -553,265 +565,274 @@ fn parse_int_negative_varying_radix() { #[test] fn parse_int_malformed_str() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(&forward(&mut engine, "parseInt(\"hello\")"), "NaN"); + assert_eq!(&forward(&mut context, "parseInt(\"hello\")"), "NaN"); } #[test] fn parse_int_undefined() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(&forward(&mut engine, "parseInt(undefined)"), "NaN"); + assert_eq!(&forward(&mut context, "parseInt(undefined)"), "NaN"); } /// Shows that no arguments to parseInt is treated the same as if undefined was /// passed as the first argument. #[test] fn parse_int_no_args() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(&forward(&mut engine, "parseInt()"), "NaN"); + assert_eq!(&forward(&mut context, "parseInt()"), "NaN"); } /// Shows that extra arguments to parseInt are ignored. #[test] fn parse_int_too_many_args() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(&forward(&mut engine, "parseInt(\"100\", 10, 10)"), "100"); + assert_eq!(&forward(&mut context, "parseInt(\"100\", 10, 10)"), "100"); } #[test] fn parse_float_simple() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(&forward(&mut engine, "parseFloat(\"6.5\")"), "6.5"); + assert_eq!(&forward(&mut context, "parseFloat(\"6.5\")"), "6.5"); } #[test] fn parse_float_int() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(&forward(&mut engine, "parseFloat(10)"), "10"); + assert_eq!(&forward(&mut context, "parseFloat(10)"), "10"); } #[test] fn parse_float_int_str() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(&forward(&mut engine, "parseFloat(\"8\")"), "8"); + assert_eq!(&forward(&mut context, "parseFloat(\"8\")"), "8"); } #[test] fn parse_float_already_float() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(&forward(&mut engine, "parseFloat(17.5)"), "17.5"); + assert_eq!(&forward(&mut context, "parseFloat(17.5)"), "17.5"); } #[test] fn parse_float_negative() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(&forward(&mut engine, "parseFloat(\"-99.7\")"), "-99.7"); + assert_eq!(&forward(&mut context, "parseFloat(\"-99.7\")"), "-99.7"); } #[test] fn parse_float_malformed_str() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(&forward(&mut engine, "parseFloat(\"hello\")"), "NaN"); + assert_eq!(&forward(&mut context, "parseFloat(\"hello\")"), "NaN"); } #[test] fn parse_float_undefined() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(&forward(&mut engine, "parseFloat(undefined)"), "NaN"); + assert_eq!(&forward(&mut context, "parseFloat(undefined)"), "NaN"); } /// No arguments to parseFloat is treated the same as passing undefined as the first argument. #[test] fn parse_float_no_args() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(&forward(&mut engine, "parseFloat()"), "NaN"); + assert_eq!(&forward(&mut context, "parseFloat()"), "NaN"); } /// Shows that the parseFloat function ignores extra arguments. #[test] fn parse_float_too_many_args() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(&forward(&mut engine, "parseFloat(\"100.5\", 10)"), "100.5"); + assert_eq!(&forward(&mut context, "parseFloat(\"100.5\", 10)"), "100.5"); } #[test] fn global_is_finite() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!("false", &forward(&mut engine, "isFinite(Infinity)")); - assert_eq!("false", &forward(&mut engine, "isFinite(NaN)")); - assert_eq!("false", &forward(&mut engine, "isFinite(-Infinity)")); - assert_eq!("true", &forward(&mut engine, "isFinite(0)")); - assert_eq!("true", &forward(&mut engine, "isFinite(2e64)")); - assert_eq!("true", &forward(&mut engine, "isFinite(910)")); - assert_eq!("true", &forward(&mut engine, "isFinite(null)")); - assert_eq!("true", &forward(&mut engine, "isFinite('0')")); - assert_eq!("false", &forward(&mut engine, "isFinite()")); + assert_eq!("false", &forward(&mut context, "isFinite(Infinity)")); + assert_eq!("false", &forward(&mut context, "isFinite(NaN)")); + assert_eq!("false", &forward(&mut context, "isFinite(-Infinity)")); + assert_eq!("true", &forward(&mut context, "isFinite(0)")); + assert_eq!("true", &forward(&mut context, "isFinite(2e64)")); + assert_eq!("true", &forward(&mut context, "isFinite(910)")); + assert_eq!("true", &forward(&mut context, "isFinite(null)")); + assert_eq!("true", &forward(&mut context, "isFinite('0')")); + assert_eq!("false", &forward(&mut context, "isFinite()")); } #[test] fn global_is_nan() { - let mut engine = Context::new(); - - assert_eq!("true", &forward(&mut engine, "isNaN(NaN)")); - assert_eq!("true", &forward(&mut engine, "isNaN('NaN')")); - assert_eq!("true", &forward(&mut engine, "isNaN(undefined)")); - assert_eq!("true", &forward(&mut engine, "isNaN({})")); - assert_eq!("false", &forward(&mut engine, "isNaN(true)")); - assert_eq!("false", &forward(&mut engine, "isNaN(null)")); - assert_eq!("false", &forward(&mut engine, "isNaN(37)")); - assert_eq!("false", &forward(&mut engine, "isNaN('37')")); - assert_eq!("false", &forward(&mut engine, "isNaN('37.37')")); - assert_eq!("true", &forward(&mut engine, "isNaN('37,5')")); - assert_eq!("true", &forward(&mut engine, "isNaN('123ABC')")); + let mut context = Context::new(); + + assert_eq!("true", &forward(&mut context, "isNaN(NaN)")); + assert_eq!("true", &forward(&mut context, "isNaN('NaN')")); + assert_eq!("true", &forward(&mut context, "isNaN(undefined)")); + assert_eq!("true", &forward(&mut context, "isNaN({})")); + assert_eq!("false", &forward(&mut context, "isNaN(true)")); + assert_eq!("false", &forward(&mut context, "isNaN(null)")); + assert_eq!("false", &forward(&mut context, "isNaN(37)")); + assert_eq!("false", &forward(&mut context, "isNaN('37')")); + assert_eq!("false", &forward(&mut context, "isNaN('37.37')")); + assert_eq!("true", &forward(&mut context, "isNaN('37,5')")); + assert_eq!("true", &forward(&mut context, "isNaN('123ABC')")); // Incorrect due to ToNumber implementation inconsistencies. - //assert_eq!("false", &forward(&mut engine, "isNaN('')")); - //assert_eq!("false", &forward(&mut engine, "isNaN(' ')")); - assert_eq!("true", &forward(&mut engine, "isNaN('blabla')")); + //assert_eq!("false", &forward(&mut context, "isNaN('')")); + //assert_eq!("false", &forward(&mut context, "isNaN(' ')")); + assert_eq!("true", &forward(&mut context, "isNaN('blabla')")); } #[test] fn number_is_finite() { - let mut engine = Context::new(); - - assert_eq!("false", &forward(&mut engine, "Number.isFinite(Infinity)")); - assert_eq!("false", &forward(&mut engine, "Number.isFinite(NaN)")); - assert_eq!("false", &forward(&mut engine, "Number.isFinite(-Infinity)")); - assert_eq!("true", &forward(&mut engine, "Number.isFinite(0)")); - assert_eq!("true", &forward(&mut engine, "Number.isFinite(2e64)")); - assert_eq!("true", &forward(&mut engine, "Number.isFinite(910)")); - assert_eq!("false", &forward(&mut engine, "Number.isFinite(null)")); - assert_eq!("false", &forward(&mut engine, "Number.isFinite('0')")); - assert_eq!("false", &forward(&mut engine, "Number.isFinite()")); - assert_eq!("false", &forward(&mut engine, "Number.isFinite({})")); - assert_eq!("true", &forward(&mut engine, "Number.isFinite(Number(5))")); + let mut context = Context::new(); + + assert_eq!("false", &forward(&mut context, "Number.isFinite(Infinity)")); + assert_eq!("false", &forward(&mut context, "Number.isFinite(NaN)")); + assert_eq!( + "false", + &forward(&mut context, "Number.isFinite(-Infinity)") + ); + assert_eq!("true", &forward(&mut context, "Number.isFinite(0)")); + assert_eq!("true", &forward(&mut context, "Number.isFinite(2e64)")); + assert_eq!("true", &forward(&mut context, "Number.isFinite(910)")); + assert_eq!("false", &forward(&mut context, "Number.isFinite(null)")); + assert_eq!("false", &forward(&mut context, "Number.isFinite('0')")); + assert_eq!("false", &forward(&mut context, "Number.isFinite()")); + assert_eq!("false", &forward(&mut context, "Number.isFinite({})")); + assert_eq!("true", &forward(&mut context, "Number.isFinite(Number(5))")); + assert_eq!( + "false", + &forward(&mut context, "Number.isFinite(new Number(5))") + ); assert_eq!( "false", - &forward(&mut engine, "Number.isFinite(new Number(5))") + &forward(&mut context, "Number.isFinite(new Number(NaN))") ); assert_eq!( "false", - &forward(&mut engine, "Number.isFinite(new Number(NaN))") + &forward(&mut context, "Number.isFinite(BigInt(5))") ); - assert_eq!("false", &forward(&mut engine, "Number.isFinite(BigInt(5))")); } #[test] fn number_is_integer() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!("true", &forward(&mut engine, "Number.isInteger(0)")); - assert_eq!("true", &forward(&mut engine, "Number.isInteger(1)")); - assert_eq!("true", &forward(&mut engine, "Number.isInteger(-100000)")); + assert_eq!("true", &forward(&mut context, "Number.isInteger(0)")); + assert_eq!("true", &forward(&mut context, "Number.isInteger(1)")); + assert_eq!("true", &forward(&mut context, "Number.isInteger(-100000)")); assert_eq!( "true", - &forward(&mut engine, "Number.isInteger(99999999999999999999999)") + &forward(&mut context, "Number.isInteger(99999999999999999999999)") + ); + assert_eq!("false", &forward(&mut context, "Number.isInteger(0.1)")); + assert_eq!("false", &forward(&mut context, "Number.isInteger(Math.PI)")); + assert_eq!("false", &forward(&mut context, "Number.isInteger(NaN)")); + assert_eq!( + "false", + &forward(&mut context, "Number.isInteger(Infinity)") ); - assert_eq!("false", &forward(&mut engine, "Number.isInteger(0.1)")); - assert_eq!("false", &forward(&mut engine, "Number.isInteger(Math.PI)")); - assert_eq!("false", &forward(&mut engine, "Number.isInteger(NaN)")); - assert_eq!("false", &forward(&mut engine, "Number.isInteger(Infinity)")); assert_eq!( "false", - &forward(&mut engine, "Number.isInteger(-Infinity)") + &forward(&mut context, "Number.isInteger(-Infinity)") ); - assert_eq!("false", &forward(&mut engine, "Number.isInteger('10')")); - assert_eq!("false", &forward(&mut engine, "Number.isInteger(true)")); - assert_eq!("false", &forward(&mut engine, "Number.isInteger(false)")); - assert_eq!("false", &forward(&mut engine, "Number.isInteger([1])")); - assert_eq!("true", &forward(&mut engine, "Number.isInteger(5.0)")); + assert_eq!("false", &forward(&mut context, "Number.isInteger('10')")); + assert_eq!("false", &forward(&mut context, "Number.isInteger(true)")); + assert_eq!("false", &forward(&mut context, "Number.isInteger(false)")); + assert_eq!("false", &forward(&mut context, "Number.isInteger([1])")); + assert_eq!("true", &forward(&mut context, "Number.isInteger(5.0)")); assert_eq!( "false", - &forward(&mut engine, "Number.isInteger(5.000000000000001)") + &forward(&mut context, "Number.isInteger(5.000000000000001)") ); assert_eq!( "true", - &forward(&mut engine, "Number.isInteger(5.0000000000000001)") + &forward(&mut context, "Number.isInteger(5.0000000000000001)") ); assert_eq!( "false", - &forward(&mut engine, "Number.isInteger(Number(5.000000000000001))") + &forward(&mut context, "Number.isInteger(Number(5.000000000000001))") ); assert_eq!( "true", - &forward(&mut engine, "Number.isInteger(Number(5.0000000000000001))") + &forward(&mut context, "Number.isInteger(Number(5.0000000000000001))") ); - assert_eq!("false", &forward(&mut engine, "Number.isInteger()")); + assert_eq!("false", &forward(&mut context, "Number.isInteger()")); assert_eq!( "false", - &forward(&mut engine, "Number.isInteger(new Number(5))") + &forward(&mut context, "Number.isInteger(new Number(5))") ); } #[test] fn number_is_nan() { - let mut engine = Context::new(); - - assert_eq!("true", &forward(&mut engine, "Number.isNaN(NaN)")); - assert_eq!("true", &forward(&mut engine, "Number.isNaN(Number.NaN)")); - assert_eq!("true", &forward(&mut engine, "Number.isNaN(0 / 0)")); - assert_eq!("false", &forward(&mut engine, "Number.isNaN(undefined)")); - assert_eq!("false", &forward(&mut engine, "Number.isNaN({})")); - assert_eq!("false", &forward(&mut engine, "Number.isNaN(true)")); - assert_eq!("false", &forward(&mut engine, "Number.isNaN(null)")); - assert_eq!("false", &forward(&mut engine, "Number.isNaN(37)")); - assert_eq!("false", &forward(&mut engine, "Number.isNaN('37')")); - assert_eq!("false", &forward(&mut engine, "Number.isNaN('37.37')")); - assert_eq!("false", &forward(&mut engine, "Number.isNaN('37,5')")); - assert_eq!("false", &forward(&mut engine, "Number.isNaN('123ABC')")); + let mut context = Context::new(); + + assert_eq!("true", &forward(&mut context, "Number.isNaN(NaN)")); + assert_eq!("true", &forward(&mut context, "Number.isNaN(Number.NaN)")); + assert_eq!("true", &forward(&mut context, "Number.isNaN(0 / 0)")); + assert_eq!("false", &forward(&mut context, "Number.isNaN(undefined)")); + assert_eq!("false", &forward(&mut context, "Number.isNaN({})")); + assert_eq!("false", &forward(&mut context, "Number.isNaN(true)")); + assert_eq!("false", &forward(&mut context, "Number.isNaN(null)")); + assert_eq!("false", &forward(&mut context, "Number.isNaN(37)")); + assert_eq!("false", &forward(&mut context, "Number.isNaN('37')")); + assert_eq!("false", &forward(&mut context, "Number.isNaN('37.37')")); + assert_eq!("false", &forward(&mut context, "Number.isNaN('37,5')")); + assert_eq!("false", &forward(&mut context, "Number.isNaN('123ABC')")); // Incorrect due to ToNumber implementation inconsistencies. - //assert_eq!("false", &forward(&mut engine, "Number.isNaN('')")); - //assert_eq!("false", &forward(&mut engine, "Number.isNaN(' ')")); - assert_eq!("false", &forward(&mut engine, "Number.isNaN('blabla')")); - assert_eq!("false", &forward(&mut engine, "Number.isNaN(Number(5))")); - assert_eq!("true", &forward(&mut engine, "Number.isNaN(Number(NaN))")); - assert_eq!("false", &forward(&mut engine, "Number.isNaN(BigInt(5))")); + //assert_eq!("false", &forward(&mut context, "Number.isNaN('')")); + //assert_eq!("false", &forward(&mut context, "Number.isNaN(' ')")); + assert_eq!("false", &forward(&mut context, "Number.isNaN('blabla')")); + assert_eq!("false", &forward(&mut context, "Number.isNaN(Number(5))")); + assert_eq!("true", &forward(&mut context, "Number.isNaN(Number(NaN))")); + assert_eq!("false", &forward(&mut context, "Number.isNaN(BigInt(5))")); assert_eq!( "false", - &forward(&mut engine, "Number.isNaN(new Number(5))") + &forward(&mut context, "Number.isNaN(new Number(5))") ); assert_eq!( "false", - &forward(&mut engine, "Number.isNaN(new Number(NaN))") + &forward(&mut context, "Number.isNaN(new Number(NaN))") ); } #[test] fn number_is_safe_integer() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!("true", &forward(&mut engine, "Number.isSafeInteger(3)")); + assert_eq!("true", &forward(&mut context, "Number.isSafeInteger(3)")); assert_eq!( "false", - &forward(&mut engine, "Number.isSafeInteger(Math.pow(2, 53))") + &forward(&mut context, "Number.isSafeInteger(Math.pow(2, 53))") ); assert_eq!( "true", - &forward(&mut engine, "Number.isSafeInteger(Math.pow(2, 53) - 1)") + &forward(&mut context, "Number.isSafeInteger(Math.pow(2, 53) - 1)") ); - assert_eq!("false", &forward(&mut engine, "Number.isSafeInteger(NaN)")); + assert_eq!("false", &forward(&mut context, "Number.isSafeInteger(NaN)")); assert_eq!( "false", - &forward(&mut engine, "Number.isSafeInteger(Infinity)") + &forward(&mut context, "Number.isSafeInteger(Infinity)") ); - assert_eq!("false", &forward(&mut engine, "Number.isSafeInteger('3')")); - assert_eq!("false", &forward(&mut engine, "Number.isSafeInteger(3.1)")); - assert_eq!("true", &forward(&mut engine, "Number.isSafeInteger(3.0)")); + assert_eq!("false", &forward(&mut context, "Number.isSafeInteger('3')")); + assert_eq!("false", &forward(&mut context, "Number.isSafeInteger(3.1)")); + assert_eq!("true", &forward(&mut context, "Number.isSafeInteger(3.0)")); assert_eq!( "false", - &forward(&mut engine, "Number.isSafeInteger(new Number(5))") + &forward(&mut context, "Number.isSafeInteger(new Number(5))") ); } diff --git a/boa/src/builtins/object/mod.rs b/boa/src/builtins/object/mod.rs index 85f91e75a3..31de4a7e5a 100644 --- a/boa/src/builtins/object/mod.rs +++ b/boa/src/builtins/object/mod.rs @@ -97,7 +97,7 @@ impl Object { /// /// [spec]: https://tc39.es/ecma262/#sec-object.create /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create - pub fn create(_: &Value, args: &[Value], ctx: &mut Context) -> Result { + pub fn create(_: &Value, args: &[Value], context: &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); @@ -107,7 +107,7 @@ impl Object { ObjectData::Ordinary, )), _ => { - return ctx.throw_type_error(format!( + return context.throw_type_error(format!( "Object prototype may only be an Object or null: {}", prototype.display() )) @@ -115,7 +115,7 @@ impl Object { }; if !properties.is_undefined() { - return Object::define_properties(&Value::Undefined, &[obj, properties], ctx); + return Object::define_properties(&Value::Undefined, &[obj, properties], context); } Ok(obj) @@ -134,14 +134,17 @@ impl Object { pub fn get_own_property_descriptor( _: &Value, args: &[Value], - ctx: &mut Context, + context: &mut Context, ) -> Result { - let object = args.get(0).unwrap_or(&Value::undefined()).to_object(ctx)?; + let object = args + .get(0) + .unwrap_or(&Value::undefined()) + .to_object(context)?; if let Some(key) = args.get(1) { - let key = key.to_property_key(ctx)?; + let key = key.to_property_key(context)?; if let Some(desc) = object.get_own_property(&key) { - return Ok(Self::from_property_descriptor(desc, ctx)?); + return Ok(Self::from_property_descriptor(desc, context)?); } } @@ -161,17 +164,20 @@ impl Object { pub fn get_own_property_descriptors( _: &Value, args: &[Value], - ctx: &mut Context, + context: &mut Context, ) -> Result { - let object = args.get(0).unwrap_or(&Value::undefined()).to_object(ctx)?; - let descriptors = ctx.construct_object(); + let object = args + .get(0) + .unwrap_or(&Value::undefined()) + .to_object(context)?; + let descriptors = context.construct_object(); for key in object.borrow().keys() { let descriptor = { let desc = object .get_own_property(&key) .expect("Expected property to be on object."); - Self::from_property_descriptor(desc, ctx)? + Self::from_property_descriptor(desc, context)? }; if !descriptor.is_undefined() { @@ -189,8 +195,8 @@ impl Object { /// /// [ECMAScript reference][spec] /// [spec]: https://tc39.es/ecma262/#sec-frompropertydescriptor - fn from_property_descriptor(desc: PropertyDescriptor, ctx: &mut Context) -> Result { - let mut descriptor = ObjectInitializer::new(ctx); + fn from_property_descriptor(desc: PropertyDescriptor, context: &mut Context) -> Result { + let mut descriptor = ObjectInitializer::new(context); if let PropertyDescriptor::Data(data_desc) = &desc { descriptor.property("value", data_desc.value(), Attribute::all()); @@ -278,15 +284,15 @@ impl Object { /// /// [spec]: https://tc39.es/ecma262/#sec-object.defineproperties /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties - pub fn define_properties(_: &Value, args: &[Value], ctx: &mut Context) -> Result { + pub fn define_properties(_: &Value, args: &[Value], context: &mut Context) -> Result { let arg = args.get(0).cloned().unwrap_or_default(); let arg_obj = arg.as_object(); if let Some(mut obj) = arg_obj { let props = args.get(1).cloned().unwrap_or_else(Value::undefined); - obj.define_properties(props, ctx)?; + obj.define_properties(props, context)?; Ok(arg) } else { - ctx.throw_type_error("Expected an object") + context.throw_type_error("Expected an object") } } /// `Object.prototype.toString()` @@ -300,13 +306,13 @@ impl Object { /// [spec]: https://tc39.es/ecma262/#sec-object.prototype.tostring /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString #[allow(clippy::wrong_self_convention)] - pub fn to_string(this: &Value, _: &[Value], ctx: &mut Context) -> Result { + pub fn to_string(this: &Value, _: &[Value], context: &mut Context) -> Result { if this.is_undefined() { Ok("[object Undefined]".into()) } else if this.is_null() { Ok("[object Null]".into()) } else { - let o = this.to_object(ctx)?; + let o = this.to_object(context)?; let builtin_tag = { let o = o.borrow(); match &o.data { @@ -323,7 +329,7 @@ impl Object { } }; - let tag = o.get(&ctx.well_known_symbols().to_string_tag_symbol().into()); + let tag = o.get(&context.well_known_symbols().to_string_tag_symbol().into()); let tag_str = tag.as_string().map(|s| s.as_str()).unwrap_or(builtin_tag); @@ -342,11 +348,11 @@ impl Object { /// /// [spec]: https://tc39.es/ecma262/#sec-object.prototype.hasownproperty /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty - pub fn has_own_property(this: &Value, args: &[Value], ctx: &mut Context) -> Result { + pub fn has_own_property(this: &Value, args: &[Value], context: &mut Context) -> Result { let prop = if args.is_empty() { None } else { - Some(args.get(0).expect("Cannot get object").to_string(ctx)?) + Some(args.get(0).expect("Cannot get object").to_string(context)?) }; let own_property = this .as_object() @@ -362,15 +368,15 @@ impl Object { pub fn property_is_enumerable( this: &Value, args: &[Value], - ctx: &mut Context, + context: &mut Context, ) -> Result { let key = match args.get(0) { None => return Ok(Value::from(false)), Some(key) => key, }; - let key = key.to_property_key(ctx)?; - let own_property = this.to_object(ctx)?.get_own_property(&key); + let key = key.to_property_key(context)?; + let own_property = this.to_object(context)?.get_own_property(&key); Ok(own_property.map_or(Value::from(false), |own_prop| { Value::from(own_prop.enumerable()) diff --git a/boa/src/builtins/object/tests.rs b/boa/src/builtins/object/tests.rs index 287ca54032..5ab9b313a9 100644 --- a/boa/src/builtins/object/tests.rs +++ b/boa/src/builtins/object/tests.rs @@ -2,22 +2,22 @@ use crate::{forward, Context, Value}; #[test] fn object_create_with_regular_object() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" const foo = { a: 5 }; const bar = Object.create(foo); "#; - forward(&mut engine, init); + forward(&mut context, init); - assert_eq!(forward(&mut engine, "bar.a"), "5"); - assert_eq!(forward(&mut engine, "Object.create.length"), "2"); + assert_eq!(forward(&mut context, "bar.a"), "5"); + assert_eq!(forward(&mut context, "Object.create.length"), "2"); } #[test] fn object_create_with_undefined() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" try { @@ -27,7 +27,7 @@ fn object_create_with_undefined() { } "#; - let result = forward(&mut engine, init); + let result = forward(&mut context, init); assert_eq!( result, "\"TypeError: Object prototype may only be an Object or null: undefined\"" @@ -36,7 +36,7 @@ fn object_create_with_undefined() { #[test] fn object_create_with_number() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" try { @@ -46,7 +46,7 @@ fn object_create_with_number() { } "#; - let result = forward(&mut engine, init); + let result = forward(&mut context, init); assert_eq!( result, "\"TypeError: Object prototype may only be an Object or null: 5\"" @@ -57,7 +57,7 @@ fn object_create_with_number() { #[ignore] // TODO: to test on __proto__ somehow. __proto__ getter is not working as expected currently fn object_create_with_function() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" const x = function (){}; @@ -65,80 +65,89 @@ fn object_create_with_function() { bar.__proto__ "#; - let result = forward(&mut engine, init); + let result = forward(&mut context, init); assert_eq!(result, "...something on __proto__..."); } #[test] fn object_is() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var foo = { a: 1}; var bar = { a: 1}; "#; - forward(&mut engine, init); - - assert_eq!(forward(&mut engine, "Object.is('foo', 'foo')"), "true"); - assert_eq!(forward(&mut engine, "Object.is('foo', 'bar')"), "false"); - assert_eq!(forward(&mut engine, "Object.is([], [])"), "false"); - assert_eq!(forward(&mut engine, "Object.is(foo, foo)"), "true"); - assert_eq!(forward(&mut engine, "Object.is(foo, bar)"), "false"); - assert_eq!(forward(&mut engine, "Object.is(null, null)"), "true"); - assert_eq!(forward(&mut engine, "Object.is(0, -0)"), "false"); - assert_eq!(forward(&mut engine, "Object.is(-0, -0)"), "true"); - 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.global_object().is_global()); - assert!(!engine.global_object().get_field("Object").is_global()); + forward(&mut context, init); + + assert_eq!(forward(&mut context, "Object.is('foo', 'foo')"), "true"); + assert_eq!(forward(&mut context, "Object.is('foo', 'bar')"), "false"); + assert_eq!(forward(&mut context, "Object.is([], [])"), "false"); + assert_eq!(forward(&mut context, "Object.is(foo, foo)"), "true"); + assert_eq!(forward(&mut context, "Object.is(foo, bar)"), "false"); + assert_eq!(forward(&mut context, "Object.is(null, null)"), "true"); + assert_eq!(forward(&mut context, "Object.is(0, -0)"), "false"); + assert_eq!(forward(&mut context, "Object.is(-0, -0)"), "true"); + assert_eq!(forward(&mut context, "Object.is(NaN, 0/0)"), "true"); + assert_eq!(forward(&mut context, "Object.is()"), "true"); + assert_eq!(forward(&mut context, "Object.is(undefined)"), "true"); + assert!(context.global_object().is_global()); + assert!(!context.global_object().get_field("Object").is_global()); } #[test] fn object_has_own_property() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" let x = { someProp: 1, undefinedProp: undefined, nullProp: null }; "#; - eprintln!("{}", forward(&mut engine, init)); - assert_eq!(forward(&mut engine, "x.hasOwnProperty('someProp')"), "true"); + eprintln!("{}", forward(&mut context, init)); assert_eq!( - forward(&mut engine, "x.hasOwnProperty('undefinedProp')"), + forward(&mut context, "x.hasOwnProperty('someProp')"), "true" ); - assert_eq!(forward(&mut engine, "x.hasOwnProperty('nullProp')"), "true"); assert_eq!( - forward(&mut engine, "x.hasOwnProperty('hasOwnProperty')"), + forward(&mut context, "x.hasOwnProperty('undefinedProp')"), + "true" + ); + assert_eq!( + forward(&mut context, "x.hasOwnProperty('nullProp')"), + "true" + ); + assert_eq!( + forward(&mut context, "x.hasOwnProperty('hasOwnProperty')"), "false" ); } #[test] fn object_property_is_enumerable() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" let x = { enumerableProp: 'yes' }; "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); assert_eq!( - forward(&mut engine, r#"x.propertyIsEnumerable('enumerableProp')"#), + forward(&mut context, r#"x.propertyIsEnumerable('enumerableProp')"#), "true" ); assert_eq!( - forward(&mut engine, r#"x.propertyIsEnumerable('hasOwnProperty')"#), + forward(&mut context, r#"x.propertyIsEnumerable('hasOwnProperty')"#), "false" ); assert_eq!( - forward(&mut engine, r#"x.propertyIsEnumerable('not_here')"#), + forward(&mut context, r#"x.propertyIsEnumerable('not_here')"#), "false", ); - assert_eq!(forward(&mut engine, r#"x.propertyIsEnumerable()"#), "false",) + assert_eq!( + forward(&mut context, r#"x.propertyIsEnumerable()"#), + "false", + ) } #[test] fn object_to_string() { - let mut ctx = Context::new(); + let mut context = Context::new(); let init = r#" let u = undefined; let n = null; @@ -160,92 +169,101 @@ fn object_to_string() { RegExp.prototype.toString = Object.prototype.toString; let o = Object(); "#; - eprintln!("{}", forward(&mut ctx, init)); + eprintln!("{}", forward(&mut context, init)); assert_eq!( - forward(&mut ctx, "Object.prototype.toString.call(u)"), + forward(&mut context, "Object.prototype.toString.call(u)"), "\"[object Undefined]\"" ); assert_eq!( - forward(&mut ctx, "Object.prototype.toString.call(n)"), + forward(&mut context, "Object.prototype.toString.call(n)"), "\"[object Null]\"" ); - assert_eq!(forward(&mut ctx, "a.toString()"), "\"[object Array]\""); - assert_eq!(forward(&mut ctx, "f.toString()"), "\"[object Function]\""); - assert_eq!(forward(&mut ctx, "e.toString()"), "\"[object Error]\""); - assert_eq!(forward(&mut ctx, "b.toString()"), "\"[object Boolean]\""); - assert_eq!(forward(&mut ctx, "i.toString()"), "\"[object Number]\""); - assert_eq!(forward(&mut ctx, "s.toString()"), "\"[object String]\""); - assert_eq!(forward(&mut ctx, "d.toString()"), "\"[object Date]\""); - assert_eq!(forward(&mut ctx, "re.toString()"), "\"[object RegExp]\""); - assert_eq!(forward(&mut ctx, "o.toString()"), "\"[object Object]\""); + assert_eq!(forward(&mut context, "a.toString()"), "\"[object Array]\""); + assert_eq!( + forward(&mut context, "f.toString()"), + "\"[object Function]\"" + ); + assert_eq!(forward(&mut context, "e.toString()"), "\"[object Error]\""); + assert_eq!( + forward(&mut context, "b.toString()"), + "\"[object Boolean]\"" + ); + assert_eq!(forward(&mut context, "i.toString()"), "\"[object Number]\""); + assert_eq!(forward(&mut context, "s.toString()"), "\"[object String]\""); + assert_eq!(forward(&mut context, "d.toString()"), "\"[object Date]\""); + assert_eq!( + forward(&mut context, "re.toString()"), + "\"[object RegExp]\"" + ); + assert_eq!(forward(&mut context, "o.toString()"), "\"[object Object]\""); } #[test] fn define_symbol_property() { - let mut ctx = Context::new(); + let mut context = Context::new(); let init = r#" let obj = {}; let sym = Symbol("key"); Object.defineProperty(obj, sym, { value: "val" }); "#; - eprintln!("{}", forward(&mut ctx, init)); + eprintln!("{}", forward(&mut context, init)); - assert_eq!(forward(&mut ctx, "obj[sym]"), "\"val\""); + assert_eq!(forward(&mut context, "obj[sym]"), "\"val\""); } #[test] fn get_own_property_descriptor_1_arg_returns_undefined() { - let mut ctx = Context::new(); + let mut context = Context::new(); let code = r#" let obj = {a: 2}; Object.getOwnPropertyDescriptor(obj) "#; - assert_eq!(ctx.eval(code).unwrap(), Value::undefined()); + assert_eq!(context.eval(code).unwrap(), Value::undefined()); } #[test] fn get_own_property_descriptor() { - let mut ctx = Context::new(); + let mut context = Context::new(); forward( - &mut ctx, + &mut context, r#" let obj = {a: 2}; let result = Object.getOwnPropertyDescriptor(obj, "a"); "#, ); - assert_eq!(forward(&mut ctx, "result.enumerable"), "true"); - assert_eq!(forward(&mut ctx, "result.writable"), "true"); - assert_eq!(forward(&mut ctx, "result.configurable"), "true"); - assert_eq!(forward(&mut ctx, "result.value"), "2"); + assert_eq!(forward(&mut context, "result.enumerable"), "true"); + assert_eq!(forward(&mut context, "result.writable"), "true"); + assert_eq!(forward(&mut context, "result.configurable"), "true"); + assert_eq!(forward(&mut context, "result.value"), "2"); } #[test] fn get_own_property_descriptors() { - let mut ctx = Context::new(); + let mut context = Context::new(); forward( - &mut ctx, + &mut context, r#" let obj = {a: 1, b: 2}; let result = Object.getOwnPropertyDescriptors(obj); "#, ); - assert_eq!(forward(&mut ctx, "result.a.enumerable"), "true"); - assert_eq!(forward(&mut ctx, "result.a.writable"), "true"); - assert_eq!(forward(&mut ctx, "result.a.configurable"), "true"); - assert_eq!(forward(&mut ctx, "result.a.value"), "1"); + assert_eq!(forward(&mut context, "result.a.enumerable"), "true"); + assert_eq!(forward(&mut context, "result.a.writable"), "true"); + assert_eq!(forward(&mut context, "result.a.configurable"), "true"); + assert_eq!(forward(&mut context, "result.a.value"), "1"); - assert_eq!(forward(&mut ctx, "result.b.enumerable"), "true"); - assert_eq!(forward(&mut ctx, "result.b.writable"), "true"); - assert_eq!(forward(&mut ctx, "result.b.configurable"), "true"); - assert_eq!(forward(&mut ctx, "result.b.value"), "2"); + assert_eq!(forward(&mut context, "result.b.enumerable"), "true"); + assert_eq!(forward(&mut context, "result.b.writable"), "true"); + assert_eq!(forward(&mut context, "result.b.configurable"), "true"); + assert_eq!(forward(&mut context, "result.b.value"), "2"); } #[test] fn object_define_properties() { - let mut ctx = Context::new(); + let mut context = Context::new(); let init = r#" const obj = {}; @@ -257,7 +275,7 @@ fn object_define_properties() { } }); "#; - eprintln!("{}", forward(&mut ctx, init)); + eprintln!("{}", forward(&mut context, init)); - assert_eq!(forward(&mut ctx, "obj.p"), "42"); + assert_eq!(forward(&mut context, "obj.p"), "42"); } diff --git a/boa/src/builtins/regexp/mod.rs b/boa/src/builtins/regexp/mod.rs index 2f489a7ed1..934251a8fe 100644 --- a/boa/src/builtins/regexp/mod.rs +++ b/boa/src/builtins/regexp/mod.rs @@ -309,12 +309,12 @@ 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 Context) -> Result { + pub(crate) fn test(this: &Value, args: &[Value], context: &mut Context) -> Result { let arg_str = args .get(0) .expect("could not get argument") - .to_string(ctx)?; - let mut last_index = this.get_field("lastIndex").to_index(ctx)?; + .to_string(context)?; + let mut last_index = this.get_field("lastIndex").to_index(context)?; let result = if let Some(object) = this.as_object() { let object = object.borrow(); let regex = object.as_regexp().unwrap(); @@ -350,12 +350,12 @@ 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 Context) -> Result { + pub(crate) fn exec(this: &Value, args: &[Value], context: &mut Context) -> Result { let arg_str = args .get(0) .expect("could not get argument") - .to_string(ctx)?; - let mut last_index = this.get_field("lastIndex").to_index(ctx)?; + .to_string(context)?; + let mut last_index = this.get_field("lastIndex").to_index(context)?; let result = if let Some(object) = this.as_object() { let object = object.borrow(); let regex = object.as_regexp().unwrap(); @@ -405,7 +405,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 Context) -> Result { + pub(crate) fn r#match(this: &Value, arg: RcString, context: &mut Context) -> Result { let (matcher, flags) = if let Some(object) = this.as_object() { let object = object.borrow(); let regex = object.as_regexp().unwrap(); @@ -423,7 +423,7 @@ impl RegExp { } Ok(Value::from(matches)) } else { - Self::exec(this, &[Value::from(arg)], ctx) + Self::exec(this, &[Value::from(arg)], context) } } diff --git a/boa/src/builtins/regexp/tests.rs b/boa/src/builtins/regexp/tests.rs index a1a4450065..a07041ca29 100644 --- a/boa/src/builtins/regexp/tests.rs +++ b/boa/src/builtins/regexp/tests.rs @@ -2,99 +2,99 @@ use crate::{forward, Context}; #[test] fn constructors() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var constructed = new RegExp("[0-9]+(\\.[0-9]+)?"); var literal = /[0-9]+(\.[0-9]+)?/; var ctor_literal = new RegExp(/[0-9]+(\.[0-9]+)?/); "#; - eprintln!("{}", forward(&mut engine, init)); - assert_eq!(forward(&mut engine, "constructed.test('1.0')"), "true"); - assert_eq!(forward(&mut engine, "literal.test('1.0')"), "true"); - assert_eq!(forward(&mut engine, "ctor_literal.test('1.0')"), "true"); + eprintln!("{}", forward(&mut context, init)); + assert_eq!(forward(&mut context, "constructed.test('1.0')"), "true"); + assert_eq!(forward(&mut context, "literal.test('1.0')"), "true"); + assert_eq!(forward(&mut context, "ctor_literal.test('1.0')"), "true"); } // TODO: uncomment this test when property getters are supported // #[test] // fn flags() { -// let mut engine = Context::new(); +// let mut context = Context::new(); // let init = r#" // var re_gi = /test/gi; // var re_sm = /test/sm; // "#; // -// eprintln!("{}", forward(&mut engine, init)); -// assert_eq!(forward(&mut engine, "re_gi.global"), "true"); -// assert_eq!(forward(&mut engine, "re_gi.ignoreCase"), "true"); -// assert_eq!(forward(&mut engine, "re_gi.multiline"), "false"); -// assert_eq!(forward(&mut engine, "re_gi.dotAll"), "false"); -// assert_eq!(forward(&mut engine, "re_gi.unicode"), "false"); -// assert_eq!(forward(&mut engine, "re_gi.sticky"), "false"); -// assert_eq!(forward(&mut engine, "re_gi.flags"), "gi"); +// eprintln!("{}", forward(&mut context, init)); +// assert_eq!(forward(&mut context, "re_gi.global"), "true"); +// assert_eq!(forward(&mut context, "re_gi.ignoreCase"), "true"); +// assert_eq!(forward(&mut context, "re_gi.multiline"), "false"); +// assert_eq!(forward(&mut context, "re_gi.dotAll"), "false"); +// assert_eq!(forward(&mut context, "re_gi.unicode"), "false"); +// assert_eq!(forward(&mut context, "re_gi.sticky"), "false"); +// assert_eq!(forward(&mut context, "re_gi.flags"), "gi"); // -// assert_eq!(forward(&mut engine, "re_sm.global"), "false"); -// assert_eq!(forward(&mut engine, "re_sm.ignoreCase"), "false"); -// assert_eq!(forward(&mut engine, "re_sm.multiline"), "true"); -// assert_eq!(forward(&mut engine, "re_sm.dotAll"), "true"); -// assert_eq!(forward(&mut engine, "re_sm.unicode"), "false"); -// assert_eq!(forward(&mut engine, "re_sm.sticky"), "false"); -// assert_eq!(forward(&mut engine, "re_sm.flags"), "ms"); +// assert_eq!(forward(&mut context, "re_sm.global"), "false"); +// assert_eq!(forward(&mut context, "re_sm.ignoreCase"), "false"); +// assert_eq!(forward(&mut context, "re_sm.multiline"), "true"); +// assert_eq!(forward(&mut context, "re_sm.dotAll"), "true"); +// assert_eq!(forward(&mut context, "re_sm.unicode"), "false"); +// assert_eq!(forward(&mut context, "re_sm.sticky"), "false"); +// assert_eq!(forward(&mut context, "re_sm.flags"), "ms"); // } #[test] fn last_index() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var regex = /[0-9]+(\.[0-9]+)?/g; "#; - eprintln!("{}", forward(&mut engine, init)); - assert_eq!(forward(&mut engine, "regex.lastIndex"), "0"); - assert_eq!(forward(&mut engine, "regex.test('1.0foo')"), "true"); - assert_eq!(forward(&mut engine, "regex.lastIndex"), "3"); - assert_eq!(forward(&mut engine, "regex.test('1.0foo')"), "false"); - assert_eq!(forward(&mut engine, "regex.lastIndex"), "0"); + eprintln!("{}", forward(&mut context, init)); + assert_eq!(forward(&mut context, "regex.lastIndex"), "0"); + assert_eq!(forward(&mut context, "regex.test('1.0foo')"), "true"); + assert_eq!(forward(&mut context, "regex.lastIndex"), "3"); + assert_eq!(forward(&mut context, "regex.test('1.0foo')"), "false"); + assert_eq!(forward(&mut context, "regex.lastIndex"), "0"); } #[test] fn exec() { - let mut engine = Context::new(); + let mut context = 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'); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); assert_eq!( - forward(&mut engine, "result[0]"), + forward(&mut context, "result[0]"), "\"Quick Brown Fox Jumps\"" ); - assert_eq!(forward(&mut engine, "result[1]"), "\"Brown\""); - assert_eq!(forward(&mut engine, "result[2]"), "\"Jumps\""); - assert_eq!(forward(&mut engine, "result.index"), "4"); + assert_eq!(forward(&mut context, "result[1]"), "\"Brown\""); + assert_eq!(forward(&mut context, "result[2]"), "\"Jumps\""); + assert_eq!(forward(&mut context, "result.index"), "4"); assert_eq!( - forward(&mut engine, "result.input"), + forward(&mut context, "result.input"), "\"The Quick Brown Fox Jumps Over The Lazy Dog\"" ); } #[test] fn to_string() { - let mut engine = Context::new(); + let mut context = Context::new(); assert_eq!( - forward(&mut engine, "(new RegExp('a+b+c')).toString()"), + forward(&mut context, "(new RegExp('a+b+c')).toString()"), "\"/a+b+c/\"" ); assert_eq!( - forward(&mut engine, "(new RegExp('bar', 'g')).toString()"), + forward(&mut context, "(new RegExp('bar', 'g')).toString()"), "\"/bar/g\"" ); assert_eq!( - forward(&mut engine, "(new RegExp('\\\\n', 'g')).toString()"), + forward(&mut context, "(new RegExp('\\\\n', 'g')).toString()"), "\"/\\n/g\"" ); - assert_eq!(forward(&mut engine, "/\\n/g.toString()"), "\"/\\n/g\""); + assert_eq!(forward(&mut context, "/\\n/g.toString()"), "\"/\\n/g\""); } diff --git a/boa/src/builtins/string/mod.rs b/boa/src/builtins/string/mod.rs index 992f8ee237..c0aebe5c78 100644 --- a/boa/src/builtins/string/mod.rs +++ b/boa/src/builtins/string/mod.rs @@ -127,11 +127,15 @@ impl String { /// `String( value )` /// /// - pub(crate) fn constructor(this: &Value, args: &[Value], ctx: &mut Context) -> Result { + pub(crate) fn constructor( + this: &Value, + args: &[Value], + context: &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) { - Some(ref value) => value.to_string(ctx)?, + Some(ref value) => value.to_string(context)?, None => RcString::default(), }; @@ -144,7 +148,7 @@ impl String { Ok(Value::from(string)) } - fn this_string_value(this: &Value, ctx: &mut Context) -> Result { + fn this_string_value(this: &Value, context: &mut Context) -> Result { match this { Value::String(ref string) => return Ok(string.clone()), Value::Object(ref object) => { @@ -156,15 +160,15 @@ impl String { _ => {} } - Err(ctx.construct_type_error("'this' is not a string")) + Err(context.construct_type_error("'this' is not a 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 Context) -> Result { + pub(crate) fn to_string(this: &Value, _: &[Value], context: &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)?)) + Ok(Value::from(Self::this_string_value(this, context)?)) } /// `String.prototype.charAt( index )` @@ -183,15 +187,15 @@ 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 Context) -> Result { - // First we get it the actual string a private field stored on the object only the engine has access to. + pub(crate) fn char_at(this: &Value, args: &[Value], context: &mut Context) -> Result { + // First we get it the actual string a private field stored on the object only the context has access to. // Then we convert it into a Rust String by wrapping it in from_value - let primitive_val = this.to_string(ctx)?; + let primitive_val = this.to_string(context)?; let pos = args .get(0) .cloned() .unwrap_or_else(Value::undefined) - .to_integer(ctx)? as i32; + .to_integer(context)? as i32; // Calling .len() on a string would give the wrong result, as they are bytes not the number of // unicode code points @@ -226,10 +230,14 @@ 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 Context) -> Result { - // First we get it the actual string a private field stored on the object only the engine has access to. + pub(crate) fn char_code_at( + this: &Value, + args: &[Value], + context: &mut Context, + ) -> Result { + // First we get it the actual string a private field stored on the object only the context has access to. // Then we convert it into a Rust String by wrapping it in from_value - let primitive_val = this.to_string(ctx)?; + let primitive_val = this.to_string(context)?; // Calling .len() on a string would give the wrong result, as they are bytes not the number of unicode code points // Note that this is an O(N) operation (because UTF-8 is complex) while getting the number of bytes is an O(1) operation. @@ -238,7 +246,7 @@ impl String { .get(0) .cloned() .unwrap_or_else(Value::undefined) - .to_integer(ctx)? as i32; + .to_integer(context)? as i32; if pos >= length as i32 || pos < 0 { return Ok(Value::from(NAN)); @@ -266,12 +274,12 @@ 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 Context) -> Result { - let object = this.require_object_coercible(ctx)?; - let mut string = object.to_string(ctx)?.to_string(); + pub(crate) fn concat(this: &Value, args: &[Value], context: &mut Context) -> Result { + let object = this.require_object_coercible(context)?; + let mut string = object.to_string(context)?.to_string(); for arg in args { - string.push_str(&arg.to_string(ctx)?); + string.push_str(&arg.to_string(context)?); } Ok(Value::from(string)) @@ -288,22 +296,22 @@ 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 Context) -> Result { - let object = this.require_object_coercible(ctx)?; - let string = object.to_string(ctx)?; + pub(crate) fn repeat(this: &Value, args: &[Value], context: &mut Context) -> Result { + let object = this.require_object_coercible(context)?; + let string = object.to_string(context)?; if let Some(arg) = args.get(0) { - let n = arg.to_integer(ctx)?; + let n = arg.to_integer(context)?; if n < 0.0 { - return ctx.throw_range_error("repeat count cannot be a negative number"); + return context.throw_range_error("repeat count cannot be a negative number"); } if n.is_infinite() { - return ctx.throw_range_error("repeat count cannot be infinity"); + return context.throw_range_error("repeat count cannot be infinity"); } if n * (string.len() as f64) > Self::MAX_STRING_LENGTH { - return ctx + return context .throw_range_error("repeat count must not overflow maximum string length"); } Ok(string.repeat(n as usize).into()) @@ -322,10 +330,10 @@ 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 Context) -> Result { - // First we get it the actual string a private field stored on the object only the engine has access to. + pub(crate) fn slice(this: &Value, args: &[Value], context: &mut Context) -> Result { + // First we get it the actual string a private field stored on the object only the context has access to. // Then we convert it into a Rust String by wrapping it in from_value - let primitive_val = this.to_string(ctx)?; + let primitive_val = this.to_string(context)?; // Calling .len() on a string would give the wrong result, as they are bytes not the number of unicode code points // Note that this is an O(N) operation (because UTF-8 is complex) while getting the number of bytes is an O(1) operation. @@ -335,12 +343,12 @@ impl String { .get(0) .cloned() .unwrap_or_else(Value::undefined) - .to_integer(ctx)? as i32; + .to_integer(context)? as i32; let end = args .get(1) .cloned() .unwrap_or_else(|| Value::integer(length)) - .to_integer(ctx)? as i32; + .to_integer(context)? as i32; let from = if start < 0 { max(length.wrapping_add(start), 0) @@ -373,20 +381,24 @@ 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 Context) -> Result { - // First we get it the actual string a private field stored on the object only the engine has access to. + pub(crate) fn starts_with( + this: &Value, + args: &[Value], + context: &mut Context, + ) -> Result { + // First we get it the actual string a private field stored on the object only the context has access to. // Then we convert it into a Rust String by wrapping it in from_value - let primitive_val = this.to_string(ctx)?; + let primitive_val = this.to_string(context)?; let arg = args.get(0).cloned().unwrap_or_else(Value::undefined); if Self::is_regexp_object(&arg) { - ctx.throw_type_error( + context.throw_type_error( "First argument to String.prototype.startsWith must not be a regular expression", )?; } - let search_string = arg.to_string(ctx)?; + let search_string = arg.to_string(context)?; let length = primitive_val.chars().count() as i32; let search_length = search_string.chars().count() as i32; @@ -395,7 +407,9 @@ impl String { let position = if args.len() < 2 { 0 } else { - args.get(1).expect("failed to get arg").to_integer(ctx)? as i32 + args.get(1) + .expect("failed to get arg") + .to_integer(context)? as i32 }; let start = min(max(position, 0), length); @@ -420,20 +434,20 @@ 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 Context) -> Result { - // First we get it the actual string a private field stored on the object only the engine has access to. + pub(crate) fn ends_with(this: &Value, args: &[Value], context: &mut Context) -> Result { + // First we get it the actual string a private field stored on the object only the context has access to. // Then we convert it into a Rust String by wrapping it in from_value - let primitive_val = this.to_string(ctx)?; + let primitive_val = this.to_string(context)?; let arg = args.get(0).cloned().unwrap_or_else(Value::undefined); if Self::is_regexp_object(&arg) { - ctx.throw_type_error( + context.throw_type_error( "First argument to String.prototype.endsWith must not be a regular expression", )?; } - let search_string = arg.to_string(ctx)?; + let search_string = arg.to_string(context)?; let length = primitive_val.chars().count() as i32; let search_length = search_string.chars().count() as i32; @@ -445,7 +459,7 @@ impl String { } else { args.get(1) .expect("Could not get argumetn") - .to_integer(ctx)? as i32 + .to_integer(context)? as i32 }; let end = min(max(end_position, 0), length); @@ -470,20 +484,20 @@ 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 Context) -> Result { - // First we get it the actual string a private field stored on the object only the engine has access to. + pub(crate) fn includes(this: &Value, args: &[Value], context: &mut Context) -> Result { + // First we get it the actual string a private field stored on the object only the context has access to. // Then we convert it into a Rust String by wrapping it in from_value - let primitive_val = this.to_string(ctx)?; + let primitive_val = this.to_string(context)?; let arg = args.get(0).cloned().unwrap_or_else(Value::undefined); if Self::is_regexp_object(&arg) { - ctx.throw_type_error( + context.throw_type_error( "First argument to String.prototype.includes must not be a regular expression", )?; } - let search_string = arg.to_string(ctx)?; + let search_string = arg.to_string(context)?; let length = primitive_val.chars().count() as i32; @@ -493,7 +507,7 @@ impl String { } else { args.get(1) .expect("Could not get argument") - .to_integer(ctx)? as i32 + .to_integer(context)? as i32 }; let start = min(max(position, 0), length); @@ -543,9 +557,9 @@ 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 Context) -> Result { + pub(crate) fn replace(this: &Value, args: &[Value], context: &mut Context) -> Result { // TODO: Support Symbol replacer - let primitive_val = this.to_string(ctx)?; + let primitive_val = this.to_string(context)?; if args.is_empty() { return Ok(Value::from(primitive_val)); } @@ -671,9 +685,9 @@ impl String { // Push the whole string being examined results.push(Value::from(primitive_val.to_string())); - let result = ctx.call(&replace_object, this, &results)?; + let result = context.call(&replace_object, this, &results)?; - result.to_string(ctx)?.to_string() + result.to_string(context)?.to_string() } _ => "undefined".to_string(), } @@ -701,20 +715,20 @@ 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 Context) -> Result { - let this = this.require_object_coercible(ctx)?; - let string = this.to_string(ctx)?; + pub(crate) fn index_of(this: &Value, args: &[Value], context: &mut Context) -> Result { + let this = this.require_object_coercible(context)?; + let string = this.to_string(context)?; let search_string = args .get(0) .cloned() .unwrap_or_else(Value::undefined) - .to_string(ctx)?; + .to_string(context)?; let length = string.chars().count(); let start = args .get(1) - .map(|position| position.to_integer(ctx)) + .map(|position| position.to_integer(context)) .transpose()? .map_or(0, |position| position.max(0.0).min(length as f64) as usize); @@ -744,20 +758,24 @@ 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 Context) -> Result { - let this = this.require_object_coercible(ctx)?; - let string = this.to_string(ctx)?; + pub(crate) fn last_index_of( + this: &Value, + args: &[Value], + context: &mut Context, + ) -> Result { + let this = this.require_object_coercible(context)?; + let string = this.to_string(context)?; let search_string = args .get(0) .cloned() .unwrap_or_else(Value::undefined) - .to_string(ctx)?; + .to_string(context)?; let length = string.chars().count(); let start = args .get(1) - .map(|position| position.to_integer(ctx)) + .map(|position| position.to_integer(context)) .transpose()? .map_or(0, |position| position.max(0.0).min(length as f64) as usize); @@ -785,9 +803,9 @@ 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 Context) -> Result { - let re = RegExp::constructor(&Value::from(Object::default()), &[args[0].clone()], ctx)?; - RegExp::r#match(&re, this.to_string(ctx)?, ctx) + pub(crate) fn r#match(this: &Value, args: &[Value], context: &mut Context) -> Result { + let re = RegExp::constructor(&Value::from(Object::default()), &[args[0].clone()], context)?; + RegExp::r#match(&re, this.to_string(context)?, context) } /// Abstract method `StringPad`. @@ -836,17 +854,17 @@ 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 Context) -> Result { - let primitive = this.to_string(ctx)?; + pub(crate) fn pad_end(this: &Value, args: &[Value], context: &mut Context) -> Result { + let primitive = this.to_string(context)?; if args.is_empty() { return Err(Value::from("padEnd requires maxLength argument")); } let max_length = args .get(0) .expect("failed to get argument for String method") - .to_integer(ctx)? as i32; + .to_integer(context)? as i32; - let fill_string = args.get(1).map(|arg| arg.to_string(ctx)).transpose()?; + let fill_string = args.get(1).map(|arg| arg.to_string(context)).transpose()?; Self::string_pad(primitive, max_length, fill_string, false) } @@ -863,17 +881,17 @@ 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 Context) -> Result { - let primitive = this.to_string(ctx)?; + pub(crate) fn pad_start(this: &Value, args: &[Value], context: &mut Context) -> Result { + let primitive = this.to_string(context)?; if args.is_empty() { return Err(Value::from("padStart requires maxLength argument")); } let max_length = args .get(0) .expect("failed to get argument for String method") - .to_integer(ctx)? as i32; + .to_integer(context)? as i32; - let fill_string = args.get(1).map(|arg| arg.to_string(ctx)).transpose()?; + let fill_string = args.get(1).map(|arg| arg.to_string(context)).transpose()?; Self::string_pad(primitive, max_length, fill_string, true) } @@ -911,9 +929,9 @@ 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 Context) -> Result { - let this = this.require_object_coercible(ctx)?; - let string = this.to_string(ctx)?; + pub(crate) fn trim(this: &Value, _: &[Value], context: &mut Context) -> Result { + let this = this.require_object_coercible(context)?; + let string = this.to_string(context)?; Ok(Value::from( string.trim_matches(Self::is_trimmable_whitespace), )) @@ -931,8 +949,8 @@ 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 Context) -> Result { - let string = this.to_string(ctx)?; + pub(crate) fn trim_start(this: &Value, _: &[Value], context: &mut Context) -> Result { + let string = this.to_string(context)?; Ok(Value::from( string.trim_start_matches(Self::is_trimmable_whitespace), )) @@ -950,9 +968,9 @@ 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 Context) -> Result { - let this = this.require_object_coercible(ctx)?; - let string = this.to_string(ctx)?; + pub(crate) fn trim_end(this: &Value, _: &[Value], context: &mut Context) -> Result { + let this = this.require_object_coercible(context)?; + let string = this.to_string(context)?; Ok(Value::from( string.trim_end_matches(Self::is_trimmable_whitespace), )) @@ -969,10 +987,10 @@ 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 Context) -> Result { - // First we get it the actual string a private field stored on the object only the engine has access to. + pub(crate) fn to_lowercase(this: &Value, _: &[Value], context: &mut Context) -> Result { + // First we get it the actual string a private field stored on the object only the context has access to. // Then we convert it into a Rust String by wrapping it in from_value - let this_str = this.to_string(ctx)?; + let this_str = this.to_string(context)?; // The Rust String is mapped to uppercase using the builtin .to_lowercase(). // There might be corner cases where it does not behave exactly like Javascript expects Ok(Value::from(this_str.to_lowercase())) @@ -991,10 +1009,10 @@ 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 Context) -> Result { - // First we get it the actual string a private field stored on the object only the engine has access to. + pub(crate) fn to_uppercase(this: &Value, _: &[Value], context: &mut Context) -> Result { + // First we get it the actual string a private field stored on the object only the context has access to. // Then we convert it into a Rust String by wrapping it in from_value - let this_str = this.to_string(ctx)?; + let this_str = this.to_string(context)?; // The Rust String is mapped to uppercase using the builtin .to_uppercase(). // There might be corner cases where it does not behave exactly like Javascript expects Ok(Value::from(this_str.to_uppercase())) @@ -1010,17 +1028,17 @@ 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 Context) -> Result { - // First we get it the actual string a private field stored on the object only the engine has access to. + pub(crate) fn substring(this: &Value, args: &[Value], context: &mut Context) -> Result { + // First we get it the actual string a private field stored on the object only the context has access to. // Then we convert it into a Rust String by wrapping it in from_value - let primitive_val = this.to_string(ctx)?; + let primitive_val = this.to_string(context)?; // If no args are specified, start is 'undefined', defaults to 0 let start = if args.is_empty() { 0 } else { args.get(0) .expect("failed to get argument for String method") - .to_integer(ctx)? as i32 + .to_integer(context)? as i32 }; let length = primitive_val.encode_utf16().count() as i32; // If less than 2 args specified, end is the length of the this object converted to a String @@ -1029,7 +1047,7 @@ impl String { } else { args.get(1) .expect("Could not get argument") - .to_integer(ctx)? as i32 + .to_integer(context)? as i32 }; // Both start and end args replaced by 0 if they were negative // or by the length of the String if they were greater @@ -1061,17 +1079,17 @@ 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 Context) -> Result { - // First we get it the actual string a private field stored on the object only the engine has access to. + pub(crate) fn substr(this: &Value, args: &[Value], context: &mut Context) -> Result { + // First we get it the actual string a private field stored on the object only the context has access to. // Then we convert it into a Rust String by wrapping it in from_value - let primitive_val = this.to_string(ctx)?; + let primitive_val = this.to_string(context)?; // If no args are specified, start is 'undefined', defaults to 0 let mut start = if args.is_empty() { 0 } else { args.get(0) .expect("failed to get argument for String method") - .to_integer(ctx)? as i32 + .to_integer(context)? as i32 }; let length = primitive_val.chars().count() as i32; // If less than 2 args specified, end is +infinity, the maximum number value. @@ -1083,7 +1101,7 @@ impl String { } else { args.get(1) .expect("Could not get argument") - .to_integer(ctx)? as i32 + .to_integer(context)? as i32 }; // If start is negative it become the number of code units from the end of the string if start < 0 { @@ -1117,9 +1135,9 @@ 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 Context) -> Result { + pub(crate) fn value_of(this: &Value, args: &[Value], context: &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) + Self::to_string(this, args, context) } /// `String.prototype.matchAll( regexp )` @@ -1135,20 +1153,20 @@ 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 Context) -> Result { + pub(crate) fn match_all(this: &Value, args: &[Value], context: &mut Context) -> Result { let re: Value = match args.get(0) { Some(arg) => { if arg.is_null() { RegExp::constructor( &Value::from(Object::default()), - &[Value::from(arg.to_string(ctx)?), Value::from("g")], - ctx, + &[Value::from(arg.to_string(context)?), Value::from("g")], + context, ) } else if arg.is_undefined() { RegExp::constructor( &Value::from(Object::default()), &[Value::undefined(), Value::from("g")], - ctx, + context, ) } else { Ok(arg.clone()) @@ -1157,14 +1175,14 @@ impl String { None => RegExp::constructor( &Value::from(Object::default()), &[Value::from(""), Value::from("g")], - ctx, + context, ), }?; - RegExp::match_all(&re, this.to_string(ctx)?.to_string()) + RegExp::match_all(&re, this.to_string(context)?.to_string()) } - pub(crate) fn iterator(this: &Value, _args: &[Value], ctx: &mut Context) -> Result { - StringIterator::create_string_iterator(ctx, this.clone()) + pub(crate) fn iterator(this: &Value, _: &[Value], context: &mut Context) -> Result { + StringIterator::create_string_iterator(context, this.clone()) } } diff --git a/boa/src/builtins/string/string_iterator.rs b/boa/src/builtins/string/string_iterator.rs index 4cefb10dbf..12bb25f662 100644 --- a/boa/src/builtins/string/string_iterator.rs +++ b/boa/src/builtins/string/string_iterator.rs @@ -1,11 +1,12 @@ -use crate::builtins::string::code_point_at; use crate::{ - builtins::{function::make_builtin_fn, iterable::create_iter_result_object}, + builtins::{ + function::make_builtin_fn, iterable::create_iter_result_object, string::code_point_at, + }, + gc::{Finalize, Trace}, object::ObjectData, property::{Attribute, DataDescriptor}, BoaProfiler, Context, Result, Value, }; -use gc::{Finalize, Trace}; #[derive(Debug, Clone, Finalize, Trace)] pub struct StringIterator { @@ -21,29 +22,29 @@ impl StringIterator { } } - pub fn create_string_iterator(ctx: &mut Context, string: Value) -> Result { - let string_iterator = Value::new_object(Some(ctx.global_object())); + pub fn create_string_iterator(context: &mut Context, string: Value) -> Result { + let string_iterator = Value::new_object(Some(context.global_object())); string_iterator.set_data(ObjectData::StringIterator(Self::new(string))); string_iterator .as_object() .expect("array iterator object") - .set_prototype_instance(ctx.iterator_prototypes().string_iterator().into()); + .set_prototype_instance(context.iterator_prototypes().string_iterator().into()); Ok(string_iterator) } - pub fn next(this: &Value, _args: &[Value], ctx: &mut Context) -> Result { + pub fn next(this: &Value, _: &[Value], context: &mut Context) -> Result { if let Value::Object(ref object) = this { let mut object = object.borrow_mut(); if let Some(string_iterator) = object.as_string_iterator_mut() { if string_iterator.string.is_undefined() { - return Ok(create_iter_result_object(ctx, Value::undefined(), true)); + return Ok(create_iter_result_object(context, Value::undefined(), true)); } - let native_string = string_iterator.string.to_string(ctx)?; + let native_string = string_iterator.string.to_string(context)?; let len = native_string.encode_utf16().count() as i32; let position = string_iterator.next_index; if position >= len { string_iterator.string = Value::undefined(); - return Ok(create_iter_result_object(ctx, Value::undefined(), true)); + return Ok(create_iter_result_object(context, Value::undefined(), true)); } let (_, code_unit_count, _) = code_point_at(native_string, position).expect("Invalid code point position"); @@ -51,14 +52,14 @@ impl StringIterator { let result_string = crate::builtins::string::String::substring( &string_iterator.string, &[position.into(), string_iterator.next_index.into()], - ctx, + context, )?; - Ok(create_iter_result_object(ctx, result_string, false)) + Ok(create_iter_result_object(context, result_string, false)) } else { - ctx.throw_type_error("`this` is not an ArrayIterator") + context.throw_type_error("`this` is not an ArrayIterator") } } else { - ctx.throw_type_error("`this` is not an ArrayIterator") + context.throw_type_error("`this` is not an ArrayIterator") } } @@ -68,19 +69,19 @@ impl StringIterator { /// - [ECMA reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-%arrayiteratorprototype%-object - pub(crate) fn create_prototype(ctx: &mut Context, iterator_prototype: Value) -> Value { - let global = ctx.global_object(); + pub(crate) fn create_prototype(context: &mut Context, iterator_prototype: Value) -> Value { + let global = context.global_object(); let _timer = BoaProfiler::global().start_event("String Iterator", "init"); // Create prototype let array_iterator = Value::new_object(Some(global)); - make_builtin_fn(Self::next, "next", &array_iterator, 0, ctx); + make_builtin_fn(Self::next, "next", &array_iterator, 0, context); array_iterator .as_object() .expect("array iterator prototype object") .set_prototype_instance(iterator_prototype); - let to_string_tag = ctx.well_known_symbols().to_string_tag_symbol(); + let to_string_tag = context.well_known_symbols().to_string_tag_symbol(); let to_string_tag_property = DataDescriptor::new("String Iterator", Attribute::CONFIGURABLE); array_iterator.set_property(to_string_tag, to_string_tag_property); diff --git a/boa/src/builtins/string/tests.rs b/boa/src/builtins/string/tests.rs index eeb9922013..3ff349381c 100644 --- a/boa/src/builtins/string/tests.rs +++ b/boa/src/builtins/string/tests.rs @@ -5,79 +5,79 @@ use crate::{forward, forward_val, Context}; #[ignore] fn length() { //TEST262: https://github.com/tc39/test262/blob/master/test/built-ins/String/length.js - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" const a = new String(' '); const b = new String('\ud834\udf06'); const c = new String(' \b '); const d = new String('中文长度') "#; - eprintln!("{}", forward(&mut engine, init)); - let a = forward(&mut engine, "a.length"); + eprintln!("{}", forward(&mut context, init)); + let a = forward(&mut context, "a.length"); assert_eq!(a, "1"); - let b = forward(&mut engine, "b.length"); + let b = forward(&mut context, "b.length"); // TODO: fix this // unicode surrogate pair length should be 1 // utf16/usc2 length should be 2 // utf8 length should be 4 assert_eq!(b, "2"); - let c = forward(&mut engine, "c.length"); + let c = forward(&mut context, "c.length"); assert_eq!(c, "3"); - let d = forward(&mut engine, "d.length"); + let d = forward(&mut context, "d.length"); assert_eq!(d, "4"); } #[test] fn new_string_has_length() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" let a = new String("1234"); a "#; - forward(&mut engine, init); - assert_eq!(forward(&mut engine, "a.length"), "4"); + forward(&mut context, init); + assert_eq!(forward(&mut context, "a.length"), "4"); } #[test] fn new_utf8_string_has_length() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" let a = new String("中文"); a "#; - forward(&mut engine, init); - assert_eq!(forward(&mut engine, "a.length"), "2"); + forward(&mut context, init); + assert_eq!(forward(&mut context, "a.length"), "2"); } #[test] fn concat() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var hello = new String('Hello, '); var world = new String('world! '); var nice = new String('Have a nice day.'); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward(&mut engine, "hello.concat(world, nice)"); + let a = forward(&mut context, "hello.concat(world, nice)"); assert_eq!(a, "\"Hello, world! Have a nice day.\""); - let b = forward(&mut engine, "hello + world + nice"); + let b = forward(&mut context, "hello + world + nice"); assert_eq!(b, "\"Hello, world! Have a nice day.\""); } #[test] fn generic_concat() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" Number.prototype.concat = String.prototype.concat; let number = new Number(100); "#; - eprintln!("{}", forward(&mut engine, init)); + eprintln!("{}", forward(&mut context, init)); - let a = forward(&mut engine, "number.concat(' - 50', ' = 50')"); + let a = forward(&mut context, "number.concat(' - 50', ' = 50')"); assert_eq!(a, "\"100 - 50 = 50\""); } @@ -85,16 +85,16 @@ fn generic_concat() { #[test] /// Test the correct type is returned from call and construct fn construct_and_call() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var hello = new String('Hello'); var world = String('world'); "#; - forward(&mut engine, init); + forward(&mut context, init); - let hello = forward_val(&mut engine, "hello").unwrap(); - let world = forward_val(&mut engine, "world").unwrap(); + let hello = forward_val(&mut context, "hello").unwrap(); + let world = forward_val(&mut context, "world").unwrap(); assert_eq!(hello.is_object(), true); assert_eq!(world.is_string(), true); @@ -102,32 +102,32 @@ fn construct_and_call() { #[test] fn repeat() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var empty = new String(''); var en = new String('english'); var zh = new String('中文'); "#; - forward(&mut engine, init); + forward(&mut context, init); - assert_eq!(forward(&mut engine, "empty.repeat(0)"), "\"\""); - assert_eq!(forward(&mut engine, "empty.repeat(1)"), "\"\""); + assert_eq!(forward(&mut context, "empty.repeat(0)"), "\"\""); + assert_eq!(forward(&mut context, "empty.repeat(1)"), "\"\""); - assert_eq!(forward(&mut engine, "en.repeat(0)"), "\"\""); - assert_eq!(forward(&mut engine, "zh.repeat(0)"), "\"\""); + assert_eq!(forward(&mut context, "en.repeat(0)"), "\"\""); + assert_eq!(forward(&mut context, "zh.repeat(0)"), "\"\""); - assert_eq!(forward(&mut engine, "en.repeat(1)"), "\"english\""); - assert_eq!(forward(&mut engine, "zh.repeat(2)"), "\"中文中文\""); + assert_eq!(forward(&mut context, "en.repeat(1)"), "\"english\""); + assert_eq!(forward(&mut context, "zh.repeat(2)"), "\"中文中文\""); } #[test] fn repeat_throws_when_count_is_negative() { - let mut engine = Context::new(); + let mut context = Context::new(); assert_eq!( forward( - &mut engine, + &mut context, r#" try { 'x'.repeat(-1) @@ -142,11 +142,11 @@ fn repeat_throws_when_count_is_negative() { #[test] fn repeat_throws_when_count_is_infinity() { - let mut engine = Context::new(); + let mut context = Context::new(); assert_eq!( forward( - &mut engine, + &mut context, r#" try { 'x'.repeat(Infinity) @@ -161,11 +161,11 @@ fn repeat_throws_when_count_is_infinity() { #[test] fn repeat_throws_when_count_overflows_max_length() { - let mut engine = Context::new(); + let mut context = Context::new(); assert_eq!( forward( - &mut engine, + &mut context, r#" try { 'x'.repeat(2 ** 64) @@ -180,48 +180,48 @@ fn repeat_throws_when_count_overflows_max_length() { #[test] fn repeat_generic() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = "Number.prototype.repeat = String.prototype.repeat;"; - forward(&mut engine, init); + forward(&mut context, init); - assert_eq!(forward(&mut engine, "(0).repeat(0)"), "\"\""); - assert_eq!(forward(&mut engine, "(1).repeat(1)"), "\"1\""); + assert_eq!(forward(&mut context, "(0).repeat(0)"), "\"\""); + assert_eq!(forward(&mut context, "(1).repeat(1)"), "\"1\""); - assert_eq!(forward(&mut engine, "(1).repeat(5)"), "\"11111\""); - assert_eq!(forward(&mut engine, "(12).repeat(3)"), "\"121212\""); + assert_eq!(forward(&mut context, "(1).repeat(5)"), "\"11111\""); + assert_eq!(forward(&mut context, "(12).repeat(3)"), "\"121212\""); } #[test] fn replace() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = "abc"; a = a.replace("a", "2"); a "#; - forward(&mut engine, init); + forward(&mut context, init); - assert_eq!(forward(&mut engine, "a"), "\"2bc\""); + assert_eq!(forward(&mut context, "a"), "\"2bc\""); } #[test] fn replace_no_match() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = "abc"; a = a.replace(/d/, "$&$&"); "#; - forward(&mut engine, init); + forward(&mut context, init); - assert_eq!(forward(&mut engine, "a"), "\"abc\""); + assert_eq!(forward(&mut context, "a"), "\"abc\""); } #[test] fn replace_with_capture_groups() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var re = /(\w+)\s(\w+)/; var a = "John Smith"; @@ -229,28 +229,28 @@ fn replace_with_capture_groups() { a "#; - forward(&mut engine, init); + forward(&mut context, init); - assert_eq!(forward(&mut engine, "a"), "\"Smith, John\""); + assert_eq!(forward(&mut context, "a"), "\"Smith, John\""); } #[test] fn replace_with_tenth_capture_group() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var re = /(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)/; var a = "0123456789"; let res = a.replace(re, '$10'); "#; - forward(&mut engine, init); + forward(&mut context, init); - assert_eq!(forward(&mut engine, "res"), "\"9\""); + assert_eq!(forward(&mut context, "res"), "\"9\""); } #[test] fn replace_substitutions() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var re = / two /; var a = "one two three"; @@ -261,18 +261,18 @@ fn replace_substitutions() { var no_sub = a.replace(re, " $_ "); "#; - forward(&mut engine, init); + forward(&mut context, init); - assert_eq!(forward(&mut engine, "dollar"), "\"one $ three\""); - assert_eq!(forward(&mut engine, "matched"), "\"one two two three\""); - assert_eq!(forward(&mut engine, "start"), "\"one one three\""); - assert_eq!(forward(&mut engine, "end"), "\"one three three\""); - assert_eq!(forward(&mut engine, "no_sub"), "\"one $_ three\""); + assert_eq!(forward(&mut context, "dollar"), "\"one $ three\""); + assert_eq!(forward(&mut context, "matched"), "\"one two two three\""); + assert_eq!(forward(&mut context, "start"), "\"one one three\""); + assert_eq!(forward(&mut context, "end"), "\"one three three\""); + assert_eq!(forward(&mut context, "no_sub"), "\"one $_ three\""); } #[test] fn replace_with_function() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var a = "ecmascript is cool"; var p1, p2, p3, length; @@ -288,19 +288,19 @@ fn replace_with_function() { a; "#; - forward(&mut engine, init); + forward(&mut context, init); - assert_eq!(forward(&mut engine, "a"), "\"ecmascript is awesome!\""); + assert_eq!(forward(&mut context, "a"), "\"ecmascript is awesome!\""); - assert_eq!(forward(&mut engine, "p1"), "\"o\""); - assert_eq!(forward(&mut engine, "p2"), "\"o\""); - assert_eq!(forward(&mut engine, "p3"), "\"l\""); - assert_eq!(forward(&mut engine, "length"), "14"); + assert_eq!(forward(&mut context, "p1"), "\"o\""); + assert_eq!(forward(&mut context, "p2"), "\"o\""); + assert_eq!(forward(&mut context, "p3"), "\"l\""); + assert_eq!(forward(&mut context, "length"), "14"); } #[test] fn starts_with() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var empty = new String(''); var en = new String('english'); @@ -311,20 +311,20 @@ fn starts_with() { var zhLiteral = '中文'; "#; - forward(&mut engine, init); + forward(&mut context, init); - assert_eq!(forward(&mut engine, "empty.startsWith('')"), "true"); - assert_eq!(forward(&mut engine, "en.startsWith('e')"), "true"); - assert_eq!(forward(&mut engine, "zh.startsWith('中')"), "true"); + assert_eq!(forward(&mut context, "empty.startsWith('')"), "true"); + assert_eq!(forward(&mut context, "en.startsWith('e')"), "true"); + assert_eq!(forward(&mut context, "zh.startsWith('中')"), "true"); - assert_eq!(forward(&mut engine, "emptyLiteral.startsWith('')"), "true"); - assert_eq!(forward(&mut engine, "enLiteral.startsWith('e')"), "true"); - assert_eq!(forward(&mut engine, "zhLiteral.startsWith('中')"), "true"); + assert_eq!(forward(&mut context, "emptyLiteral.startsWith('')"), "true"); + assert_eq!(forward(&mut context, "enLiteral.startsWith('e')"), "true"); + assert_eq!(forward(&mut context, "zhLiteral.startsWith('中')"), "true"); } #[test] fn starts_with_with_regex_arg() { - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = r#" try { @@ -336,7 +336,7 @@ fn starts_with_with_regex_arg() { assert_eq!( forward( - &mut engine, scenario + &mut context, scenario ), "\"TypeError: First argument to String.prototype.startsWith must not be a regular expression\"" ) @@ -344,7 +344,7 @@ fn starts_with_with_regex_arg() { #[test] fn ends_with() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var empty = new String(''); var en = new String('english'); @@ -355,20 +355,20 @@ fn ends_with() { var zhLiteral = '中文'; "#; - forward(&mut engine, init); + forward(&mut context, init); - assert_eq!(forward(&mut engine, "empty.endsWith('')"), "true"); - assert_eq!(forward(&mut engine, "en.endsWith('h')"), "true"); - assert_eq!(forward(&mut engine, "zh.endsWith('文')"), "true"); + assert_eq!(forward(&mut context, "empty.endsWith('')"), "true"); + assert_eq!(forward(&mut context, "en.endsWith('h')"), "true"); + assert_eq!(forward(&mut context, "zh.endsWith('文')"), "true"); - assert_eq!(forward(&mut engine, "emptyLiteral.endsWith('')"), "true"); - assert_eq!(forward(&mut engine, "enLiteral.endsWith('h')"), "true"); - assert_eq!(forward(&mut engine, "zhLiteral.endsWith('文')"), "true"); + assert_eq!(forward(&mut context, "emptyLiteral.endsWith('')"), "true"); + assert_eq!(forward(&mut context, "enLiteral.endsWith('h')"), "true"); + assert_eq!(forward(&mut context, "zhLiteral.endsWith('文')"), "true"); } #[test] fn ends_with_with_regex_arg() { - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = r#" try { @@ -380,7 +380,7 @@ fn ends_with_with_regex_arg() { assert_eq!( forward( - &mut engine, scenario + &mut context, scenario ), "\"TypeError: First argument to String.prototype.endsWith must not be a regular expression\"" ) @@ -388,7 +388,7 @@ fn ends_with_with_regex_arg() { #[test] fn includes() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var empty = new String(''); var en = new String('english'); @@ -399,20 +399,20 @@ fn includes() { var zhLiteral = '中文'; "#; - forward(&mut engine, init); + forward(&mut context, init); - assert_eq!(forward(&mut engine, "empty.includes('')"), "true"); - assert_eq!(forward(&mut engine, "en.includes('g')"), "true"); - assert_eq!(forward(&mut engine, "zh.includes('文')"), "true"); + assert_eq!(forward(&mut context, "empty.includes('')"), "true"); + assert_eq!(forward(&mut context, "en.includes('g')"), "true"); + assert_eq!(forward(&mut context, "zh.includes('文')"), "true"); - assert_eq!(forward(&mut engine, "emptyLiteral.includes('')"), "true"); - assert_eq!(forward(&mut engine, "enLiteral.includes('g')"), "true"); - assert_eq!(forward(&mut engine, "zhLiteral.includes('文')"), "true"); + assert_eq!(forward(&mut context, "emptyLiteral.includes('')"), "true"); + assert_eq!(forward(&mut context, "enLiteral.includes('g')"), "true"); + assert_eq!(forward(&mut context, "zhLiteral.includes('文')"), "true"); } #[test] fn includes_with_regex_arg() { - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = r#" try { @@ -424,7 +424,7 @@ fn includes_with_regex_arg() { assert_eq!( forward( - &mut engine, scenario + &mut context, scenario ), "\"TypeError: First argument to String.prototype.includes must not be a regular expression\"" ) @@ -432,27 +432,27 @@ fn includes_with_regex_arg() { #[test] fn match_all() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(forward(&mut engine, "'aa'.matchAll(null).length"), "0"); - assert_eq!(forward(&mut engine, "'aa'.matchAll(/b/).length"), "0"); - assert_eq!(forward(&mut engine, "'aa'.matchAll(/a/).length"), "1"); - assert_eq!(forward(&mut engine, "'aa'.matchAll(/a/g).length"), "2"); + assert_eq!(forward(&mut context, "'aa'.matchAll(null).length"), "0"); + assert_eq!(forward(&mut context, "'aa'.matchAll(/b/).length"), "0"); + assert_eq!(forward(&mut context, "'aa'.matchAll(/a/).length"), "1"); + assert_eq!(forward(&mut context, "'aa'.matchAll(/a/g).length"), "2"); forward( - &mut engine, + &mut context, "var groupMatches = 'test1test2'.matchAll(/t(e)(st(\\d?))/g)", ); - assert_eq!(forward(&mut engine, "groupMatches.length"), "2"); - assert_eq!(forward(&mut engine, "groupMatches[0][1]"), "\"e\""); - assert_eq!(forward(&mut engine, "groupMatches[0][2]"), "\"st1\""); - assert_eq!(forward(&mut engine, "groupMatches[0][3]"), "\"1\""); - assert_eq!(forward(&mut engine, "groupMatches[1][3]"), "\"2\""); + assert_eq!(forward(&mut context, "groupMatches.length"), "2"); + assert_eq!(forward(&mut context, "groupMatches[0][1]"), "\"e\""); + assert_eq!(forward(&mut context, "groupMatches[0][2]"), "\"st1\""); + assert_eq!(forward(&mut context, "groupMatches[0][3]"), "\"1\""); + assert_eq!(forward(&mut context, "groupMatches[1][3]"), "\"2\""); assert_eq!( forward( - &mut engine, + &mut context, "'test1test2'.matchAll(/t(e)(st(\\d?))/).length" ), "1" @@ -464,17 +464,17 @@ fn match_all() { var matches = str.matchAll(regexp); "#; - forward(&mut engine, init); + forward(&mut context, init); - assert_eq!(forward(&mut engine, "matches[0][0]"), "\"football\""); - assert_eq!(forward(&mut engine, "matches[0].index"), "6"); - assert_eq!(forward(&mut engine, "matches[1][0]"), "\"foosball\""); - assert_eq!(forward(&mut engine, "matches[1].index"), "16"); + assert_eq!(forward(&mut context, "matches[0][0]"), "\"football\""); + assert_eq!(forward(&mut context, "matches[0].index"), "6"); + assert_eq!(forward(&mut context, "matches[1][0]"), "\"foosball\""); + assert_eq!(forward(&mut context, "matches[1].index"), "16"); } #[test] fn test_match() { - let mut engine = Context::new(); + let mut context = 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); @@ -483,206 +483,209 @@ fn test_match() { var result4 = str.match(RegExp("B", 'g')); "#; - forward(&mut engine, init); + forward(&mut context, init); assert_eq!( - forward(&mut engine, "result1[0]"), + forward(&mut context, "result1[0]"), "\"Quick Brown Fox Jumps\"" ); - assert_eq!(forward(&mut engine, "result1[1]"), "\"Brown\""); - assert_eq!(forward(&mut engine, "result1[2]"), "\"Jumps\""); - assert_eq!(forward(&mut engine, "result1.index"), "4"); + assert_eq!(forward(&mut context, "result1[1]"), "\"Brown\""); + assert_eq!(forward(&mut context, "result1[2]"), "\"Jumps\""); + assert_eq!(forward(&mut context, "result1.index"), "4"); assert_eq!( - forward(&mut engine, "result1.input"), + forward(&mut context, "result1.input"), "\"The Quick Brown Fox Jumps Over The Lazy Dog\"" ); - assert_eq!(forward(&mut engine, "result2[0]"), "\"T\""); - assert_eq!(forward(&mut engine, "result2[1]"), "\"Q\""); - assert_eq!(forward(&mut engine, "result2[2]"), "\"B\""); - assert_eq!(forward(&mut engine, "result2[3]"), "\"F\""); - assert_eq!(forward(&mut engine, "result2[4]"), "\"J\""); - assert_eq!(forward(&mut engine, "result2[5]"), "\"O\""); - assert_eq!(forward(&mut engine, "result2[6]"), "\"T\""); - assert_eq!(forward(&mut engine, "result2[7]"), "\"L\""); - assert_eq!(forward(&mut engine, "result2[8]"), "\"D\""); - - assert_eq!(forward(&mut engine, "result3[0]"), "\"T\""); - assert_eq!(forward(&mut engine, "result3.index"), "0"); + assert_eq!(forward(&mut context, "result2[0]"), "\"T\""); + assert_eq!(forward(&mut context, "result2[1]"), "\"Q\""); + assert_eq!(forward(&mut context, "result2[2]"), "\"B\""); + assert_eq!(forward(&mut context, "result2[3]"), "\"F\""); + assert_eq!(forward(&mut context, "result2[4]"), "\"J\""); + assert_eq!(forward(&mut context, "result2[5]"), "\"O\""); + assert_eq!(forward(&mut context, "result2[6]"), "\"T\""); + assert_eq!(forward(&mut context, "result2[7]"), "\"L\""); + assert_eq!(forward(&mut context, "result2[8]"), "\"D\""); + + assert_eq!(forward(&mut context, "result3[0]"), "\"T\""); + assert_eq!(forward(&mut context, "result3.index"), "0"); assert_eq!( - forward(&mut engine, "result3.input"), + forward(&mut context, "result3.input"), "\"The Quick Brown Fox Jumps Over The Lazy Dog\"" ); - assert_eq!(forward(&mut engine, "result4[0]"), "\"B\""); + assert_eq!(forward(&mut context, "result4[0]"), "\"B\""); } #[test] fn trim() { - 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\""); - assert_eq!(forward(&mut engine, "' Hello '.trim()"), "\"Hello\""); + let mut context = Context::new(); + assert_eq!(forward(&mut context, "'Hello'.trim()"), "\"Hello\""); + assert_eq!(forward(&mut context, "' \nHello'.trim()"), "\"Hello\""); + assert_eq!(forward(&mut context, "'Hello \n\r'.trim()"), "\"Hello\""); + assert_eq!(forward(&mut context, "' Hello '.trim()"), "\"Hello\""); } #[test] fn trim_start() { - let mut engine = Context::new(); - assert_eq!(forward(&mut engine, "'Hello'.trimStart()"), "\"Hello\""); - assert_eq!(forward(&mut engine, "' \nHello'.trimStart()"), "\"Hello\""); + let mut context = Context::new(); + assert_eq!(forward(&mut context, "'Hello'.trimStart()"), "\"Hello\""); + assert_eq!(forward(&mut context, "' \nHello'.trimStart()"), "\"Hello\""); assert_eq!( - forward(&mut engine, "'Hello \n'.trimStart()"), + forward(&mut context, "'Hello \n'.trimStart()"), "\"Hello \n\"" ); - assert_eq!(forward(&mut engine, "' Hello '.trimStart()"), "\"Hello \""); + assert_eq!(forward(&mut context, "' Hello '.trimStart()"), "\"Hello \""); } #[test] fn trim_end() { - 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\""); - assert_eq!(forward(&mut engine, "' Hello '.trimEnd()"), "\" Hello\""); + let mut context = Context::new(); + assert_eq!(forward(&mut context, "'Hello'.trimEnd()"), "\"Hello\""); + assert_eq!( + forward(&mut context, "' \nHello'.trimEnd()"), + "\" \nHello\"" + ); + assert_eq!(forward(&mut context, "'Hello \n'.trimEnd()"), "\"Hello\""); + assert_eq!(forward(&mut context, "' Hello '.trimEnd()"), "\" Hello\""); } #[test] fn index_of_with_no_arguments() { - 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"); - assert_eq!(forward(&mut engine, "'a1undefined1a'.indexOf()"), "2"); - assert_eq!(forward(&mut engine, "'µµµundefined'.indexOf()"), "3"); - assert_eq!(forward(&mut engine, "'µµµundefinedµµµ'.indexOf()"), "3"); + let mut context = Context::new(); + assert_eq!(forward(&mut context, "''.indexOf()"), "-1"); + assert_eq!(forward(&mut context, "'undefined'.indexOf()"), "0"); + assert_eq!(forward(&mut context, "'a1undefined'.indexOf()"), "2"); + assert_eq!(forward(&mut context, "'a1undefined1a'.indexOf()"), "2"); + assert_eq!(forward(&mut context, "'µµµundefined'.indexOf()"), "3"); + assert_eq!(forward(&mut context, "'µµµundefinedµµµ'.indexOf()"), "3"); } #[test] fn index_of_with_string_search_string_argument() { - let mut engine = Context::new(); - assert_eq!(forward(&mut engine, "''.indexOf('hello')"), "-1"); + let mut context = Context::new(); + assert_eq!(forward(&mut context, "''.indexOf('hello')"), "-1"); assert_eq!( - forward(&mut engine, "'undefined'.indexOf('undefined')"), + forward(&mut context, "'undefined'.indexOf('undefined')"), "0" ); assert_eq!( - forward(&mut engine, "'a1undefined'.indexOf('undefined')"), + forward(&mut context, "'a1undefined'.indexOf('undefined')"), "2" ); assert_eq!( - forward(&mut engine, "'a1undefined1a'.indexOf('undefined')"), + forward(&mut context, "'a1undefined1a'.indexOf('undefined')"), "2" ); assert_eq!( - forward(&mut engine, "'µµµundefined'.indexOf('undefined')"), + forward(&mut context, "'µµµundefined'.indexOf('undefined')"), "3" ); assert_eq!( - forward(&mut engine, "'µµµundefinedµµµ'.indexOf('undefined')"), + forward(&mut context, "'µµµundefinedµµµ'.indexOf('undefined')"), "3" ); } #[test] fn index_of_with_non_string_search_string_argument() { - 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"); - assert_eq!(forward(&mut engine, "'ab100ba'.indexOf(100)"), "2"); - assert_eq!(forward(&mut engine, "'µµµfalse'.indexOf(true)"), "-1"); - assert_eq!(forward(&mut engine, "'µµµ5µµµ'.indexOf(5)"), "3"); + let mut context = Context::new(); + assert_eq!(forward(&mut context, "''.indexOf(1)"), "-1"); + assert_eq!(forward(&mut context, "'1'.indexOf(1)"), "0"); + assert_eq!(forward(&mut context, "'true'.indexOf(true)"), "0"); + assert_eq!(forward(&mut context, "'ab100ba'.indexOf(100)"), "2"); + assert_eq!(forward(&mut context, "'µµµfalse'.indexOf(true)"), "-1"); + assert_eq!(forward(&mut context, "'µµµ5µµµ'.indexOf(5)"), "3"); } #[test] fn index_of_with_from_index_argument() { - 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"); - assert_eq!(forward(&mut engine, "'x'.indexOf('x', 2)"), "-1"); - assert_eq!(forward(&mut engine, "'µµµxµµµ'.indexOf('x', 2)"), "3"); + let mut context = Context::new(); + assert_eq!(forward(&mut context, "''.indexOf('x', 2)"), "-1"); + assert_eq!(forward(&mut context, "'x'.indexOf('x', 2)"), "-1"); + assert_eq!(forward(&mut context, "'abcx'.indexOf('x', 2)"), "3"); + assert_eq!(forward(&mut context, "'x'.indexOf('x', 2)"), "-1"); + assert_eq!(forward(&mut context, "'µµµxµµµ'.indexOf('x', 2)"), "3"); assert_eq!( - forward(&mut engine, "'µµµxµµµ'.indexOf('x', 10000000)"), + forward(&mut context, "'µµµxµµµ'.indexOf('x', 10000000)"), "-1" ); } #[test] fn generic_index_of() { - let mut engine = Context::new(); + let mut context = Context::new(); forward_val( - &mut engine, + &mut context, "Number.prototype.indexOf = String.prototype.indexOf", ) .unwrap(); - assert_eq!(forward(&mut engine, "(10).indexOf(9)"), "-1"); - assert_eq!(forward(&mut engine, "(10).indexOf(0)"), "1"); - assert_eq!(forward(&mut engine, "(10).indexOf('0')"), "1"); + assert_eq!(forward(&mut context, "(10).indexOf(9)"), "-1"); + assert_eq!(forward(&mut context, "(10).indexOf(0)"), "1"); + assert_eq!(forward(&mut context, "(10).indexOf('0')"), "1"); } #[test] fn index_of_empty_search_string() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(forward(&mut engine, "''.indexOf('')"), "0"); - assert_eq!(forward(&mut engine, "''.indexOf('', 10)"), "0"); - assert_eq!(forward(&mut engine, "'ABC'.indexOf('', 1)"), "1"); - assert_eq!(forward(&mut engine, "'ABC'.indexOf('', 2)"), "2"); - assert_eq!(forward(&mut engine, "'ABC'.indexOf('', 10)"), "3"); + assert_eq!(forward(&mut context, "''.indexOf('')"), "0"); + assert_eq!(forward(&mut context, "''.indexOf('', 10)"), "0"); + assert_eq!(forward(&mut context, "'ABC'.indexOf('', 1)"), "1"); + assert_eq!(forward(&mut context, "'ABC'.indexOf('', 2)"), "2"); + assert_eq!(forward(&mut context, "'ABC'.indexOf('', 10)"), "3"); } #[test] fn last_index_of_with_no_arguments() { - 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"); + let mut context = Context::new(); + assert_eq!(forward(&mut context, "''.lastIndexOf()"), "-1"); + assert_eq!(forward(&mut context, "'undefined'.lastIndexOf()"), "0"); + assert_eq!(forward(&mut context, "'a1undefined'.lastIndexOf()"), "2"); assert_eq!( - forward(&mut engine, "'a1undefined1aundefined'.lastIndexOf()"), + forward(&mut context, "'a1undefined1aundefined'.lastIndexOf()"), "13" ); assert_eq!( - forward(&mut engine, "'µµµundefinedundefined'.lastIndexOf()"), + forward(&mut context, "'µµµundefinedundefined'.lastIndexOf()"), "12" ); assert_eq!( - forward(&mut engine, "'µµµundefinedµµµundefined'.lastIndexOf()"), + forward(&mut context, "'µµµundefinedµµµundefined'.lastIndexOf()"), "15" ); } #[test] fn last_index_of_with_string_search_string_argument() { - let mut engine = Context::new(); - assert_eq!(forward(&mut engine, "''.lastIndexOf('hello')"), "-1"); + let mut context = Context::new(); + assert_eq!(forward(&mut context, "''.lastIndexOf('hello')"), "-1"); assert_eq!( - forward(&mut engine, "'undefined'.lastIndexOf('undefined')"), + forward(&mut context, "'undefined'.lastIndexOf('undefined')"), "0" ); assert_eq!( - forward(&mut engine, "'a1undefined'.lastIndexOf('undefined')"), + forward(&mut context, "'a1undefined'.lastIndexOf('undefined')"), "2" ); assert_eq!( forward( - &mut engine, + &mut context, "'a1undefined1aundefined'.lastIndexOf('undefined')" ), "13" ); assert_eq!( forward( - &mut engine, + &mut context, "'µµµundefinedundefined'.lastIndexOf('undefined')" ), "12" ); assert_eq!( forward( - &mut engine, + &mut context, "'µµµundefinedµµµundefined'.lastIndexOf('undefined')" ), "15" @@ -691,204 +694,207 @@ fn last_index_of_with_string_search_string_argument() { #[test] fn last_index_of_with_non_string_search_string_argument() { - 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"); + let mut context = Context::new(); + assert_eq!(forward(&mut context, "''.lastIndexOf(1)"), "-1"); + assert_eq!(forward(&mut context, "'1'.lastIndexOf(1)"), "0"); + assert_eq!(forward(&mut context, "'11'.lastIndexOf(1)"), "1"); assert_eq!( - forward(&mut engine, "'truefalsetrue'.lastIndexOf(true)"), + forward(&mut context, "'truefalsetrue'.lastIndexOf(true)"), "9" ); - assert_eq!(forward(&mut engine, "'ab100ba'.lastIndexOf(100)"), "2"); - assert_eq!(forward(&mut engine, "'µµµfalse'.lastIndexOf(true)"), "-1"); - assert_eq!(forward(&mut engine, "'µµµ5µµµ65µ'.lastIndexOf(5)"), "8"); + assert_eq!(forward(&mut context, "'ab100ba'.lastIndexOf(100)"), "2"); + assert_eq!(forward(&mut context, "'µµµfalse'.lastIndexOf(true)"), "-1"); + assert_eq!(forward(&mut context, "'µµµ5µµµ65µ'.lastIndexOf(5)"), "8"); } #[test] fn last_index_of_with_from_index_argument() { - 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"); - assert_eq!(forward(&mut engine, "'x'.lastIndexOf('x', 2)"), "-1"); - assert_eq!(forward(&mut engine, "'µµµxµµµ'.lastIndexOf('x', 2)"), "3"); + let mut context = Context::new(); + assert_eq!(forward(&mut context, "''.lastIndexOf('x', 2)"), "-1"); + assert_eq!(forward(&mut context, "'x'.lastIndexOf('x', 2)"), "-1"); + assert_eq!(forward(&mut context, "'abcxx'.lastIndexOf('x', 2)"), "4"); + assert_eq!(forward(&mut context, "'x'.lastIndexOf('x', 2)"), "-1"); + assert_eq!(forward(&mut context, "'µµµxµµµ'.lastIndexOf('x', 2)"), "3"); assert_eq!( - forward(&mut engine, "'µµµxµµµ'.lastIndexOf('x', 10000000)"), + forward(&mut context, "'µµµxµµµ'.lastIndexOf('x', 10000000)"), "-1" ); } #[test] fn last_index_with_empty_search_string() { - 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"); - assert_eq!(forward(&mut engine, "'µµµxµµµ'.lastIndexOf('', 2)"), "2"); + let mut context = Context::new(); + assert_eq!(forward(&mut context, "''.lastIndexOf('')"), "0"); + assert_eq!(forward(&mut context, "'x'.lastIndexOf('', 2)"), "1"); + assert_eq!(forward(&mut context, "'abcxx'.lastIndexOf('', 4)"), "4"); + assert_eq!(forward(&mut context, "'µµµxµµµ'.lastIndexOf('', 2)"), "2"); - assert_eq!(forward(&mut engine, "'abc'.lastIndexOf('', 10000000)"), "3"); + assert_eq!( + forward(&mut context, "'abc'.lastIndexOf('', 10000000)"), + "3" + ); } #[test] fn generic_last_index_of() { - let mut engine = Context::new(); + let mut context = Context::new(); forward_val( - &mut engine, + &mut context, "Number.prototype.lastIndexOf = String.prototype.lastIndexOf", ) .unwrap(); - assert_eq!(forward(&mut engine, "(1001).lastIndexOf(9)"), "-1"); - assert_eq!(forward(&mut engine, "(1001).lastIndexOf(0)"), "2"); - assert_eq!(forward(&mut engine, "(1001).lastIndexOf('0')"), "2"); + assert_eq!(forward(&mut context, "(1001).lastIndexOf(9)"), "-1"); + assert_eq!(forward(&mut context, "(1001).lastIndexOf(0)"), "2"); + assert_eq!(forward(&mut context, "(1001).lastIndexOf('0')"), "2"); } #[test] fn last_index_non_integer_position_argument() { - let mut engine = Context::new(); + let mut context = Context::new(); assert_eq!( - forward(&mut engine, "''.lastIndexOf('x', new Number(4))"), + forward(&mut context, "''.lastIndexOf('x', new Number(4))"), "-1" ); assert_eq!( - forward(&mut engine, "'abc'.lastIndexOf('b', new Number(1))"), + forward(&mut context, "'abc'.lastIndexOf('b', new Number(1))"), "1" ); assert_eq!( - forward(&mut engine, "'abcx'.lastIndexOf('x', new String('1'))"), + forward(&mut context, "'abcx'.lastIndexOf('x', new String('1'))"), "3" ); assert_eq!( - forward(&mut engine, "'abcx'.lastIndexOf('x', new String('100'))"), + forward(&mut context, "'abcx'.lastIndexOf('x', new String('100'))"), "-1" ); - assert_eq!(forward(&mut engine, "'abcx'.lastIndexOf('x', null)"), "3"); + assert_eq!(forward(&mut context, "'abcx'.lastIndexOf('x', null)"), "3"); } #[test] fn char_at() { - let mut engine = Context::new(); - assert_eq!(forward(&mut engine, "'abc'.charAt(1)"), "\"b\""); - assert_eq!(forward(&mut engine, "'abc'.charAt(9)"), "\"\""); - assert_eq!(forward(&mut engine, "'abc'.charAt()"), "\"a\""); - assert_eq!(forward(&mut engine, "'abc'.charAt(null)"), "\"a\""); + let mut context = Context::new(); + assert_eq!(forward(&mut context, "'abc'.charAt(1)"), "\"b\""); + assert_eq!(forward(&mut context, "'abc'.charAt(9)"), "\"\""); + assert_eq!(forward(&mut context, "'abc'.charAt()"), "\"a\""); + assert_eq!(forward(&mut context, "'abc'.charAt(null)"), "\"a\""); } #[test] fn char_code_at() { - let mut engine = Context::new(); - assert_eq!(forward(&mut engine, "'abc'.charCodeAt(1)"), "98"); - assert_eq!(forward(&mut engine, "'abc'.charCodeAt(9)"), "NaN"); - assert_eq!(forward(&mut engine, "'abc'.charCodeAt()"), "97"); - assert_eq!(forward(&mut engine, "'abc'.charCodeAt(null)"), "97"); + let mut context = Context::new(); + assert_eq!(forward(&mut context, "'abc'.charCodeAt(1)"), "98"); + assert_eq!(forward(&mut context, "'abc'.charCodeAt(9)"), "NaN"); + assert_eq!(forward(&mut context, "'abc'.charCodeAt()"), "97"); + assert_eq!(forward(&mut context, "'abc'.charCodeAt(null)"), "97"); } #[test] fn slice() { - let mut engine = Context::new(); - assert_eq!(forward(&mut engine, "'abc'.slice()"), "\"abc\""); - assert_eq!(forward(&mut engine, "'abc'.slice(1)"), "\"bc\""); - assert_eq!(forward(&mut engine, "'abc'.slice(-1)"), "\"c\""); - assert_eq!(forward(&mut engine, "'abc'.slice(0, 9)"), "\"abc\""); - assert_eq!(forward(&mut engine, "'abc'.slice(9, 10)"), "\"\""); + let mut context = Context::new(); + assert_eq!(forward(&mut context, "'abc'.slice()"), "\"abc\""); + assert_eq!(forward(&mut context, "'abc'.slice(1)"), "\"bc\""); + assert_eq!(forward(&mut context, "'abc'.slice(-1)"), "\"c\""); + assert_eq!(forward(&mut context, "'abc'.slice(0, 9)"), "\"abc\""); + assert_eq!(forward(&mut context, "'abc'.slice(9, 10)"), "\"\""); } #[test] fn empty_iter() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" let iter = new String()[Symbol.iterator](); let next = iter.next(); "#; - forward(&mut engine, init); - assert_eq!(forward(&mut engine, "next.value"), "undefined"); - assert_eq!(forward(&mut engine, "next.done"), "true"); + forward(&mut context, init); + assert_eq!(forward(&mut context, "next.value"), "undefined"); + assert_eq!(forward(&mut context, "next.done"), "true"); } #[test] fn ascii_iter() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" let iter = new String("Hello World")[Symbol.iterator](); let next = iter.next(); "#; - forward(&mut engine, init); - assert_eq!(forward(&mut engine, "next.value"), "\"H\""); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iter.next()"); - assert_eq!(forward(&mut engine, "next.value"), "\"e\""); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iter.next()"); - assert_eq!(forward(&mut engine, "next.value"), "\"l\""); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iter.next()"); - assert_eq!(forward(&mut engine, "next.value"), "\"l\""); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iter.next()"); - assert_eq!(forward(&mut engine, "next.value"), "\"o\""); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iter.next()"); - assert_eq!(forward(&mut engine, "next.value"), "\" \""); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iter.next()"); - assert_eq!(forward(&mut engine, "next.value"), "\"W\""); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iter.next()"); - assert_eq!(forward(&mut engine, "next.value"), "\"o\""); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iter.next()"); - assert_eq!(forward(&mut engine, "next.value"), "\"r\""); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iter.next()"); - assert_eq!(forward(&mut engine, "next.value"), "\"l\""); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iter.next()"); - assert_eq!(forward(&mut engine, "next.value"), "\"d\""); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iter.next()"); - assert_eq!(forward(&mut engine, "next.value"), "undefined"); - assert_eq!(forward(&mut engine, "next.done"), "true"); + forward(&mut context, init); + assert_eq!(forward(&mut context, "next.value"), "\"H\""); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iter.next()"); + assert_eq!(forward(&mut context, "next.value"), "\"e\""); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iter.next()"); + assert_eq!(forward(&mut context, "next.value"), "\"l\""); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iter.next()"); + assert_eq!(forward(&mut context, "next.value"), "\"l\""); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iter.next()"); + assert_eq!(forward(&mut context, "next.value"), "\"o\""); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iter.next()"); + assert_eq!(forward(&mut context, "next.value"), "\" \""); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iter.next()"); + assert_eq!(forward(&mut context, "next.value"), "\"W\""); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iter.next()"); + assert_eq!(forward(&mut context, "next.value"), "\"o\""); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iter.next()"); + assert_eq!(forward(&mut context, "next.value"), "\"r\""); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iter.next()"); + assert_eq!(forward(&mut context, "next.value"), "\"l\""); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iter.next()"); + assert_eq!(forward(&mut context, "next.value"), "\"d\""); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iter.next()"); + assert_eq!(forward(&mut context, "next.value"), "undefined"); + assert_eq!(forward(&mut context, "next.done"), "true"); } #[test] fn unicode_iter() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" let iter = new String("C🙂🙂l W🙂rld")[Symbol.iterator](); let next = iter.next(); "#; - forward(&mut engine, init); - assert_eq!(forward(&mut engine, "next.value"), "\"C\""); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iter.next()"); - assert_eq!(forward(&mut engine, "next.value"), "\"🙂\""); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iter.next()"); - assert_eq!(forward(&mut engine, "next.value"), "\"🙂\""); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iter.next()"); - assert_eq!(forward(&mut engine, "next.value"), "\"l\""); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iter.next()"); - assert_eq!(forward(&mut engine, "next.value"), "\" \""); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iter.next()"); - assert_eq!(forward(&mut engine, "next.value"), "\"W\""); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iter.next()"); - assert_eq!(forward(&mut engine, "next.value"), "\"🙂\""); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iter.next()"); - assert_eq!(forward(&mut engine, "next.value"), "\"r\""); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iter.next()"); - assert_eq!(forward(&mut engine, "next.value"), "\"l\""); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iter.next()"); - assert_eq!(forward(&mut engine, "next.value"), "\"d\""); - assert_eq!(forward(&mut engine, "next.done"), "false"); - forward(&mut engine, "next = iter.next()"); - assert_eq!(forward(&mut engine, "next.value"), "undefined"); - assert_eq!(forward(&mut engine, "next.done"), "true"); + forward(&mut context, init); + assert_eq!(forward(&mut context, "next.value"), "\"C\""); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iter.next()"); + assert_eq!(forward(&mut context, "next.value"), "\"🙂\""); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iter.next()"); + assert_eq!(forward(&mut context, "next.value"), "\"🙂\""); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iter.next()"); + assert_eq!(forward(&mut context, "next.value"), "\"l\""); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iter.next()"); + assert_eq!(forward(&mut context, "next.value"), "\" \""); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iter.next()"); + assert_eq!(forward(&mut context, "next.value"), "\"W\""); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iter.next()"); + assert_eq!(forward(&mut context, "next.value"), "\"🙂\""); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iter.next()"); + assert_eq!(forward(&mut context, "next.value"), "\"r\""); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iter.next()"); + assert_eq!(forward(&mut context, "next.value"), "\"l\""); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iter.next()"); + assert_eq!(forward(&mut context, "next.value"), "\"d\""); + assert_eq!(forward(&mut context, "next.done"), "false"); + forward(&mut context, "next = iter.next()"); + assert_eq!(forward(&mut context, "next.value"), "undefined"); + assert_eq!(forward(&mut context, "next.done"), "true"); } diff --git a/boa/src/builtins/symbol/mod.rs b/boa/src/builtins/symbol/mod.rs index c15ce59f0f..a7897bf85b 100644 --- a/boa/src/builtins/symbol/mod.rs +++ b/boa/src/builtins/symbol/mod.rs @@ -315,16 +315,16 @@ 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 constructor(_: &Value, args: &[Value], ctx: &mut Context) -> Result { + pub(crate) fn constructor(_: &Value, args: &[Value], context: &mut Context) -> Result { let description = match args.get(0) { - Some(ref value) if !value.is_undefined() => Some(value.to_string(ctx)?), + Some(ref value) if !value.is_undefined() => Some(value.to_string(context)?), _ => None, }; - Ok(ctx.construct_symbol(description).into()) + Ok(context.construct_symbol(description).into()) } - fn this_symbol_value(value: &Value, ctx: &mut Context) -> Result { + fn this_symbol_value(value: &Value, context: &mut Context) -> Result { match value { Value::Symbol(ref symbol) => return Ok(symbol.clone()), Value::Object(ref object) => { @@ -336,7 +336,7 @@ impl Symbol { _ => {} } - Err(ctx.construct_type_error("'this' is not a Symbol")) + Err(context.construct_type_error("'this' is not a Symbol")) } /// `Symbol.prototype.toString()` @@ -350,8 +350,8 @@ 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 Context) -> Result { - let symbol = Self::this_symbol_value(this, ctx)?; + pub(crate) fn to_string(this: &Value, _: &[Value], context: &mut Context) -> Result { + let symbol = Self::this_symbol_value(this, context)?; let description = symbol.description().unwrap_or(""); Ok(Value::from(format!("Symbol({})", description))) } diff --git a/boa/src/builtins/symbol/tests.rs b/boa/src/builtins/symbol/tests.rs index 9f3bfee68a..f311d29c5e 100644 --- a/boa/src/builtins/symbol/tests.rs +++ b/boa/src/builtins/symbol/tests.rs @@ -2,29 +2,29 @@ use crate::{forward, forward_val, Context}; #[test] fn call_symbol_and_check_return_type() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var sym = Symbol(); "#; - eprintln!("{}", forward(&mut engine, init)); - let sym = forward_val(&mut engine, "sym").unwrap(); + eprintln!("{}", forward(&mut context, init)); + let sym = forward_val(&mut context, "sym").unwrap(); assert_eq!(sym.is_symbol(), true); } #[test] fn print_symbol_expect_description() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var sym = Symbol("Hello"); "#; - eprintln!("{}", forward(&mut engine, init)); - let sym = forward_val(&mut engine, "sym.toString()").unwrap(); + eprintln!("{}", forward(&mut context, init)); + let sym = forward_val(&mut context, "sym.toString()").unwrap(); assert_eq!(sym.display().to_string(), "\"Symbol(Hello)\""); } #[test] fn symbol_access() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var x = {}; var sym1 = Symbol("Hello"); @@ -32,8 +32,8 @@ fn symbol_access() { x[sym1] = 10; x[sym2] = 20; "#; - forward_val(&mut engine, init).unwrap(); - assert_eq!(forward(&mut engine, "x[sym1]"), "10"); - assert_eq!(forward(&mut engine, "x[sym2]"), "20"); - assert_eq!(forward(&mut engine, "x['Symbol(Hello)']"), "undefined"); + forward_val(&mut context, init).unwrap(); + assert_eq!(forward(&mut context, "x[sym1]"), "10"); + assert_eq!(forward(&mut context, "x[sym2]"), "20"); + assert_eq!(forward(&mut context, "x['Symbol(Hello)']"), "undefined"); } diff --git a/boa/src/builtins/undefined/mod.rs b/boa/src/builtins/undefined/mod.rs index 4f389a1e6c..91760b427a 100644 --- a/boa/src/builtins/undefined/mod.rs +++ b/boa/src/builtins/undefined/mod.rs @@ -25,7 +25,7 @@ impl BuiltIn for Undefined { Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT } - fn init(_context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(_: &mut Context) -> (&'static str, Value, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); (Self::NAME, Value::undefined(), Self::attribute()) diff --git a/boa/src/class.rs b/boa/src/class.rs index bff30c0cbd..6f33c154f3 100644 --- a/boa/src/class.rs +++ b/boa/src/class.rs @@ -25,9 +25,9 @@ //! const LENGTH: usize = 1; //! //! // This is what is called when we do `new Animal()` -//! fn constructor(_this: &Value, args: &[Value], ctx: &mut Context) -> Result { +//! fn constructor(_this: &Value, args: &[Value], context: &mut Context) -> Result { //! // This is equivalent to `String(arg)`. -//! let kind = args.get(0).cloned().unwrap_or_default().to_string(ctx)?; +//! let kind = args.get(0).cloned().unwrap_or_default().to_string(context)?; //! //! let animal = match kind.as_str() { //! "cat" => Self::Cat, @@ -77,7 +77,7 @@ pub trait Class: NativeObject + Sized { const ATTRIBUTE: Attribute = Attribute::all(); /// The constructor of the class. - fn constructor(this: &Value, args: &[Value], ctx: &mut Context) -> Result; + fn constructor(this: &Value, args: &[Value], context: &mut Context) -> Result; /// Initializes the internals and the methods of the class. fn init(class: &mut ClassBuilder<'_>) -> Result<()>; @@ -88,17 +88,17 @@ 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 Context) -> Result + fn raw_constructor(this: &Value, args: &[Value], context: &mut Context) -> Result where Self: Sized; } impl ClassConstructor for T { - fn raw_constructor(this: &Value, args: &[Value], ctx: &mut Context) -> Result + fn raw_constructor(this: &Value, args: &[Value], context: &mut Context) -> Result where Self: Sized, { - let object_instance = Self::constructor(this, args, ctx)?; + let object_instance = Self::constructor(this, args, context)?; this.set_data(ObjectData::NativeObject(Box::new(object_instance))); Ok(this.clone()) } diff --git a/boa/src/context.rs b/boa/src/context.rs index c504ad219e..a3f7289a71 100644 --- a/boa/src/context.rs +++ b/boa/src/context.rs @@ -225,18 +225,22 @@ impl Default for Context { impl Context { /// Create a new `Context`. + #[inline] pub fn new() -> Self { Default::default() } + #[inline] pub fn realm(&self) -> &Realm { &self.realm } + #[inline] pub fn realm_mut(&mut self) -> &mut Realm { &mut self.realm } + #[inline] pub fn executor(&mut self) -> &mut Interpreter { &mut self.executor } @@ -249,11 +253,13 @@ impl Context { /// A helper function for getting a mutable reference to the `console` object. #[cfg(feature = "console")] + #[inline] pub(crate) fn console_mut(&mut self) -> &mut Console { &mut self.console } /// Sets up the default global objects within Global + #[inline] fn create_intrinsics(&mut self) { let _timer = BoaProfiler::global().start_event("create_intrinsics", "interpreter"); // Create intrinsics, add global objects here @@ -287,6 +293,7 @@ impl Context { } /// + #[inline] pub(crate) fn call(&mut self, f: &Value, this: &Value, args: &[Value]) -> Result { match *f { Value::Object(ref object) => object.call(this, args, self), @@ -295,11 +302,13 @@ impl Context { } /// Return the global object. + #[inline] pub fn global_object(&self) -> &Value { - &self.realm.global_obj + &self.realm().global_object } /// Constructs a `RangeError` with the specified message. + #[inline] pub fn construct_range_error(&mut self, message: M) -> Value where M: Into, @@ -314,6 +323,7 @@ impl Context { } /// Throws a `RangeError` with the specified message. + #[inline] pub fn throw_range_error(&mut self, message: M) -> Result where M: Into, @@ -322,6 +332,7 @@ impl Context { } /// Constructs a `TypeError` with the specified message. + #[inline] pub fn construct_type_error(&mut self, message: M) -> Value where M: Into, @@ -336,6 +347,7 @@ impl Context { } /// Throws a `TypeError` with the specified message. + #[inline] pub fn throw_type_error(&mut self, message: M) -> Result where M: Into, @@ -344,6 +356,7 @@ impl Context { } /// Constructs a `ReferenceError` with the specified message. + #[inline] pub fn construct_reference_error(&mut self, message: M) -> Value where M: Into, @@ -357,6 +370,7 @@ impl Context { } /// Throws a `ReferenceError` with the specified message. + #[inline] pub fn throw_reference_error(&mut self, message: M) -> Result where M: Into, @@ -365,6 +379,7 @@ impl Context { } /// Constructs a `SyntaxError` with the specified message. + #[inline] pub fn construct_syntax_error(&mut self, message: M) -> Value where M: Into, @@ -378,6 +393,7 @@ impl Context { } /// Throws a `SyntaxError` with the specified message. + #[inline] pub fn throw_syntax_error(&mut self, message: M) -> Result where M: Into, @@ -494,6 +510,7 @@ impl Context { } /// Register a global function. + #[inline] pub fn register_global_function( &mut self, name: &str, @@ -556,6 +573,7 @@ impl Context { } /// https://tc39.es/ecma262/#sec-hasproperty + #[inline] pub(crate) fn has_property(&self, obj: &Value, key: &PropertyKey) -> bool { if let Some(obj) = obj.as_object() { obj.has_property(key) @@ -564,6 +582,7 @@ impl Context { } } + #[inline] pub(crate) fn set_value(&mut self, node: &Node, value: Value) -> Result { match node { Node::Identifier(ref name) => { @@ -598,6 +617,7 @@ impl Context { /// /// context.register_global_class::(); /// ``` + #[inline] pub fn register_global_class(&mut self) -> Result<()> where T: Class, @@ -630,6 +650,7 @@ impl Context { /// .build(); /// context.register_global_property("myObjectProperty", object, Attribute::all()); /// ``` + #[inline] pub fn register_global_property(&mut self, key: K, value: V, attribute: Attribute) where K: Into, @@ -655,6 +676,7 @@ impl Context { /// assert_eq!(value.as_number().unwrap(), 4.0); /// ``` #[allow(clippy::unit_arg, clippy::drop_copy)] + #[inline] pub fn eval(&mut self, src: &str) -> Result { let main_timer = BoaProfiler::global().start_event("Main", "Main"); diff --git a/boa/src/environment/declarative_environment_record.rs b/boa/src/environment/declarative_environment_record.rs index 99b8eaebc4..656ad26027 100644 --- a/boa/src/environment/declarative_environment_record.rs +++ b/boa/src/environment/declarative_environment_record.rs @@ -10,9 +10,9 @@ use crate::{ environment_record_trait::EnvironmentRecordTrait, lexical_environment::{Environment, EnvironmentType}, }, + gc::{Finalize, Trace}, Value, }; -use gc::{Finalize, Trace}; use rustc_hash::FxHashMap; /// Declarative Bindings have a few properties for book keeping purposes, such as mutability (const vs let). diff --git a/boa/src/environment/environment_record_trait.rs b/boa/src/environment/environment_record_trait.rs index 7e304d018e..cde825aed2 100644 --- a/boa/src/environment/environment_record_trait.rs +++ b/boa/src/environment/environment_record_trait.rs @@ -10,9 +10,9 @@ //! use crate::{ environment::lexical_environment::{Environment, EnvironmentType}, + gc::{Finalize, Trace}, Value, }; -use gc::{Finalize, Trace}; use std::fmt::Debug; /// diff --git a/boa/src/environment/function_environment_record.rs b/boa/src/environment/function_environment_record.rs index af4a1b9ba6..5c81b08d87 100644 --- a/boa/src/environment/function_environment_record.rs +++ b/boa/src/environment/function_environment_record.rs @@ -14,10 +14,10 @@ use crate::{ environment_record_trait::EnvironmentRecordTrait, lexical_environment::{Environment, EnvironmentType}, }, + gc::{empty_trace, Finalize, Trace}, object::GcObject, Value, }; -use gc::{unsafe_empty_trace, Finalize, Trace}; use rustc_hash::FxHashMap; /// Different binding status for `this`. @@ -33,7 +33,7 @@ pub enum BindingStatus { } unsafe impl Trace for BindingStatus { - unsafe_empty_trace!(); + empty_trace!(); } /// diff --git a/boa/src/environment/global_environment_record.rs b/boa/src/environment/global_environment_record.rs index 11c4176539..c2739d7cb5 100644 --- a/boa/src/environment/global_environment_record.rs +++ b/boa/src/environment/global_environment_record.rs @@ -14,10 +14,10 @@ use crate::{ lexical_environment::{Environment, EnvironmentType}, object_environment_record::ObjectEnvironmentRecord, }, + gc::{Finalize, Trace}, property::{Attribute, DataDescriptor}, Value, }; -use gc::{Finalize, Trace}; use rustc_hash::FxHashSet; #[derive(Debug, Trace, Finalize, Clone)] diff --git a/boa/src/environment/object_environment_record.rs b/boa/src/environment/object_environment_record.rs index 760371ce53..cad73cfb93 100644 --- a/boa/src/environment/object_environment_record.rs +++ b/boa/src/environment/object_environment_record.rs @@ -11,10 +11,10 @@ use crate::{ environment_record_trait::EnvironmentRecordTrait, lexical_environment::{Environment, EnvironmentType}, }, + gc::{Finalize, Trace}, property::{Attribute, DataDescriptor}, Value, }; -use gc::{Finalize, Trace}; #[derive(Debug, Trace, Finalize, Clone)] pub struct ObjectEnvironmentRecord { diff --git a/boa/src/exec/mod.rs b/boa/src/exec/mod.rs index 6bf5e0cc17..737de76461 100644 --- a/boa/src/exec/mod.rs +++ b/boa/src/exec/mod.rs @@ -7,7 +7,7 @@ use crate::{Context, Result, Value}; pub trait Executable { /// Runs this executable in the given context. - fn run(&self, interpreter: &mut Context) -> Result; + fn run(&self, context: &mut Context) -> Result; } #[derive(Debug, Eq, PartialEq)] diff --git a/boa/src/exec/tests.rs b/boa/src/exec/tests.rs index 21901b287a..7cf7b0da2f 100644 --- a/boa/src/exec/tests.rs +++ b/boa/src/exec/tests.rs @@ -118,7 +118,7 @@ fn object_field_set() { #[test] fn spread_with_arguments() { - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = r#" const a = [1, "test", 3, 4]; @@ -128,30 +128,30 @@ fn spread_with_arguments() { var result = foo(...a); "#; - forward(&mut engine, scenario); - let one = forward(&mut engine, "result[0]"); + forward(&mut context, scenario); + let one = forward(&mut context, "result[0]"); assert_eq!(one, String::from("1")); - let two = forward(&mut engine, "result[1]"); + let two = forward(&mut context, "result[1]"); assert_eq!(two, String::from("\"test\"")); - let three = forward(&mut engine, "result[2]"); + let three = forward(&mut context, "result[2]"); assert_eq!(three, String::from("3")); - let four = forward(&mut engine, "result[3]"); + let four = forward(&mut context, "result[3]"); assert_eq!(four, String::from("4")); } #[test] fn array_rest_with_arguments() { - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = r#" var b = [4, 5, 6] var a = [1, 2, 3, ...b]; "#; - forward(&mut engine, scenario); - let one = forward(&mut engine, "a"); + forward(&mut context, scenario); + let one = forward(&mut context, "a"); assert_eq!(one, String::from("[ 1, 2, 3, 4, 5, 6 ]")); } @@ -722,7 +722,7 @@ mod in_operator { #[test] fn should_type_error_when_rhs_not_object() { - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = r#" var x = false; @@ -733,13 +733,13 @@ mod in_operator { } "#; - forward(&mut engine, scenario); - assert_eq!(forward(&mut engine, "x"), "true"); + forward(&mut context, scenario); + assert_eq!(forward(&mut context, "x"), "true"); } #[test] fn should_set_this_value() { - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = r#" function Foo() { @@ -749,37 +749,37 @@ mod in_operator { var bar = new Foo(); "#; - forward(&mut engine, scenario); - assert_eq!(forward(&mut engine, "bar.a"), "\"a\""); - assert_eq!(forward(&mut engine, "bar.b"), "\"b\""); + forward(&mut context, scenario); + assert_eq!(forward(&mut context, "bar.a"), "\"a\""); + assert_eq!(forward(&mut context, "bar.b"), "\"b\""); } #[test] fn should_type_error_when_new_is_not_constructor() { - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = r#" const a = ""; new a(); "#; - let result = forward(&mut engine, scenario); + let result = forward(&mut context, scenario); assert_eq!(result, "Uncaught \"TypeError\": \"a is not a constructor\""); } #[test] fn new_instance_should_point_to_prototype() { // A new instance should point to a prototype object created with the constructor function - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = r#" function Foo() {} var bar = new Foo(); "#; - forward(&mut engine, scenario); - let bar_val = forward_val(&mut engine, "bar").unwrap(); + forward(&mut context, scenario); + let bar_val = forward_val(&mut context, "bar").unwrap(); let bar_obj = bar_val.as_object().unwrap(); - let foo_val = forward_val(&mut engine, "Foo").unwrap(); + let foo_val = forward_val(&mut context, "Foo").unwrap(); assert!(bar_obj .prototype_instance() .strict_equals(&foo_val.get_field("prototype"))); @@ -897,98 +897,100 @@ fn function_decl_hoisting() { #[test] fn to_bigint() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert!(Value::null().to_bigint(&mut engine).is_err()); - assert!(Value::undefined().to_bigint(&mut engine).is_err()); - assert!(Value::integer(55).to_bigint(&mut engine).is_ok()); - assert!(Value::rational(10.0).to_bigint(&mut engine).is_ok()); - assert!(Value::string("100").to_bigint(&mut engine).is_ok()); + assert!(Value::null().to_bigint(&mut context).is_err()); + assert!(Value::undefined().to_bigint(&mut context).is_err()); + assert!(Value::integer(55).to_bigint(&mut context).is_ok()); + assert!(Value::rational(10.0).to_bigint(&mut context).is_ok()); + assert!(Value::string("100").to_bigint(&mut context).is_ok()); } #[test] fn to_index() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(Value::undefined().to_index(&mut engine).unwrap(), 0); - assert!(Value::integer(-1).to_index(&mut engine).is_err()); + assert_eq!(Value::undefined().to_index(&mut context).unwrap(), 0); + assert!(Value::integer(-1).to_index(&mut context).is_err()); } #[test] fn to_integer() { - let mut engine = Context::new(); + let mut context = Context::new(); assert!(Number::equal( - Value::number(f64::NAN).to_integer(&mut engine).unwrap(), + Value::number(f64::NAN).to_integer(&mut context).unwrap(), 0.0 )); assert!(Number::equal( Value::number(f64::NEG_INFINITY) - .to_integer(&mut engine) + .to_integer(&mut context) .unwrap(), f64::NEG_INFINITY )); assert!(Number::equal( Value::number(f64::INFINITY) - .to_integer(&mut engine) + .to_integer(&mut context) .unwrap(), f64::INFINITY )); assert!(Number::equal( - Value::number(0.0).to_integer(&mut engine).unwrap(), + Value::number(0.0).to_integer(&mut context).unwrap(), 0.0 )); - let number = Value::number(-0.0).to_integer(&mut engine).unwrap(); + let number = Value::number(-0.0).to_integer(&mut context).unwrap(); assert!(!number.is_sign_negative()); assert!(Number::equal(number, 0.0)); assert!(Number::equal( - Value::number(20.9).to_integer(&mut engine).unwrap(), + Value::number(20.9).to_integer(&mut context).unwrap(), 20.0 )); assert!(Number::equal( - Value::number(-20.9).to_integer(&mut engine).unwrap(), + Value::number(-20.9).to_integer(&mut context).unwrap(), -20.0 )); } #[test] fn to_length() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(Value::number(f64::NAN).to_length(&mut engine).unwrap(), 0); + assert_eq!(Value::number(f64::NAN).to_length(&mut context).unwrap(), 0); assert_eq!( Value::number(f64::NEG_INFINITY) - .to_length(&mut engine) + .to_length(&mut context) .unwrap(), 0 ); assert_eq!( - Value::number(f64::INFINITY).to_length(&mut engine).unwrap(), + Value::number(f64::INFINITY) + .to_length(&mut context) + .unwrap(), Number::MAX_SAFE_INTEGER as usize ); - assert_eq!(Value::number(0.0).to_length(&mut engine).unwrap(), 0); - assert_eq!(Value::number(-0.0).to_length(&mut engine).unwrap(), 0); - assert_eq!(Value::number(20.9).to_length(&mut engine).unwrap(), 20); - assert_eq!(Value::number(-20.9).to_length(&mut engine).unwrap(), 0); + assert_eq!(Value::number(0.0).to_length(&mut context).unwrap(), 0); + assert_eq!(Value::number(-0.0).to_length(&mut context).unwrap(), 0); + assert_eq!(Value::number(20.9).to_length(&mut context).unwrap(), 20); + assert_eq!(Value::number(-20.9).to_length(&mut context).unwrap(), 0); assert_eq!( Value::number(100000000000.0) - .to_length(&mut engine) + .to_length(&mut context) .unwrap() as u64, 100000000000 ); assert_eq!( - Value::number(4010101101.0).to_length(&mut engine).unwrap(), + Value::number(4010101101.0).to_length(&mut context).unwrap(), 4010101101 ); } #[test] fn to_int32() { - let mut engine = Context::new(); + let mut context = Context::new(); macro_rules! check_to_int32 { ($from:expr => $to:expr) => { - assert_eq!(Value::from($from).to_i32(&mut engine).unwrap(), $to); + assert_eq!(Value::from($from).to_i32(&mut context).unwrap(), $to); }; }; @@ -1097,24 +1099,24 @@ fn to_int32() { #[test] fn to_string() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert_eq!(Value::null().to_string(&mut engine).unwrap(), "null"); + assert_eq!(Value::null().to_string(&mut context).unwrap(), "null"); assert_eq!( - Value::undefined().to_string(&mut engine).unwrap(), + Value::undefined().to_string(&mut context).unwrap(), "undefined" ); - assert_eq!(Value::integer(55).to_string(&mut engine).unwrap(), "55"); - assert_eq!(Value::rational(55.0).to_string(&mut engine).unwrap(), "55"); + assert_eq!(Value::integer(55).to_string(&mut context).unwrap(), "55"); + assert_eq!(Value::rational(55.0).to_string(&mut context).unwrap(), "55"); assert_eq!( - Value::string("hello").to_string(&mut engine).unwrap(), + Value::string("hello").to_string(&mut context).unwrap(), "hello" ); } #[test] fn calling_function_with_unspecified_arguments() { - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = r#" function test(a, b) { return b; @@ -1123,26 +1125,26 @@ fn calling_function_with_unspecified_arguments() { test(10) "#; - assert_eq!(forward(&mut engine, scenario), "undefined"); + assert_eq!(forward(&mut context, scenario), "undefined"); } #[test] fn to_object() { - let mut engine = Context::new(); + let mut context = Context::new(); assert!(Value::undefined() - .to_object(&mut engine) + .to_object(&mut context) .unwrap_err() .is_object()); assert!(Value::null() - .to_object(&mut engine) + .to_object(&mut context) .unwrap_err() .is_object()); } #[test] fn check_this_binding_in_object_literal() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" var foo = { a: 3, @@ -1152,12 +1154,12 @@ fn check_this_binding_in_object_literal() { foo.bar() "#; - assert_eq!(forward(&mut engine, init), "8"); + assert_eq!(forward(&mut context, init), "8"); } #[test] fn array_creation_benchmark() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" (function(){ let testArr = []; @@ -1169,12 +1171,12 @@ fn array_creation_benchmark() { })(); "#; - assert_eq!(forward(&mut engine, init), "[ \"p0\", \"p1\", \"p2\", \"p3\", \"p4\", \"p5\", \"p6\", \"p7\", \"p8\", \"p9\", \"p10\", \"p11\", \"p12\", \"p13\", \"p14\", \"p15\", \"p16\", \"p17\", \"p18\", \"p19\", \"p20\", \"p21\", \"p22\", \"p23\", \"p24\", \"p25\", \"p26\", \"p27\", \"p28\", \"p29\", \"p30\", \"p31\", \"p32\", \"p33\", \"p34\", \"p35\", \"p36\", \"p37\", \"p38\", \"p39\", \"p40\", \"p41\", \"p42\", \"p43\", \"p44\", \"p45\", \"p46\", \"p47\", \"p48\", \"p49\", \"p50\", \"p51\", \"p52\", \"p53\", \"p54\", \"p55\", \"p56\", \"p57\", \"p58\", \"p59\", \"p60\", \"p61\", \"p62\", \"p63\", \"p64\", \"p65\", \"p66\", \"p67\", \"p68\", \"p69\", \"p70\", \"p71\", \"p72\", \"p73\", \"p74\", \"p75\", \"p76\", \"p77\", \"p78\", \"p79\", \"p80\", \"p81\", \"p82\", \"p83\", \"p84\", \"p85\", \"p86\", \"p87\", \"p88\", \"p89\", \"p90\", \"p91\", \"p92\", \"p93\", \"p94\", \"p95\", \"p96\", \"p97\", \"p98\", \"p99\", \"p100\", \"p101\", \"p102\", \"p103\", \"p104\", \"p105\", \"p106\", \"p107\", \"p108\", \"p109\", \"p110\", \"p111\", \"p112\", \"p113\", \"p114\", \"p115\", \"p116\", \"p117\", \"p118\", \"p119\", \"p120\", \"p121\", \"p122\", \"p123\", \"p124\", \"p125\", \"p126\", \"p127\", \"p128\", \"p129\", \"p130\", \"p131\", \"p132\", \"p133\", \"p134\", \"p135\", \"p136\", \"p137\", \"p138\", \"p139\", \"p140\", \"p141\", \"p142\", \"p143\", \"p144\", \"p145\", \"p146\", \"p147\", \"p148\", \"p149\", \"p150\", \"p151\", \"p152\", \"p153\", \"p154\", \"p155\", \"p156\", \"p157\", \"p158\", \"p159\", \"p160\", \"p161\", \"p162\", \"p163\", \"p164\", \"p165\", \"p166\", \"p167\", \"p168\", \"p169\", \"p170\", \"p171\", \"p172\", \"p173\", \"p174\", \"p175\", \"p176\", \"p177\", \"p178\", \"p179\", \"p180\", \"p181\", \"p182\", \"p183\", \"p184\", \"p185\", \"p186\", \"p187\", \"p188\", \"p189\", \"p190\", \"p191\", \"p192\", \"p193\", \"p194\", \"p195\", \"p196\", \"p197\", \"p198\", \"p199\", \"p200\", \"p201\", \"p202\", \"p203\", \"p204\", \"p205\", \"p206\", \"p207\", \"p208\", \"p209\", \"p210\", \"p211\", \"p212\", \"p213\", \"p214\", \"p215\", \"p216\", \"p217\", \"p218\", \"p219\", \"p220\", \"p221\", \"p222\", \"p223\", \"p224\", \"p225\", \"p226\", \"p227\", \"p228\", \"p229\", \"p230\", \"p231\", \"p232\", \"p233\", \"p234\", \"p235\", \"p236\", \"p237\", \"p238\", \"p239\", \"p240\", \"p241\", \"p242\", \"p243\", \"p244\", \"p245\", \"p246\", \"p247\", \"p248\", \"p249\", \"p250\", \"p251\", \"p252\", \"p253\", \"p254\", \"p255\", \"p256\", \"p257\", \"p258\", \"p259\", \"p260\", \"p261\", \"p262\", \"p263\", \"p264\", \"p265\", \"p266\", \"p267\", \"p268\", \"p269\", \"p270\", \"p271\", \"p272\", \"p273\", \"p274\", \"p275\", \"p276\", \"p277\", \"p278\", \"p279\", \"p280\", \"p281\", \"p282\", \"p283\", \"p284\", \"p285\", \"p286\", \"p287\", \"p288\", \"p289\", \"p290\", \"p291\", \"p292\", \"p293\", \"p294\", \"p295\", \"p296\", \"p297\", \"p298\", \"p299\", \"p300\", \"p301\", \"p302\", \"p303\", \"p304\", \"p305\", \"p306\", \"p307\", \"p308\", \"p309\", \"p310\", \"p311\", \"p312\", \"p313\", \"p314\", \"p315\", \"p316\", \"p317\", \"p318\", \"p319\", \"p320\", \"p321\", \"p322\", \"p323\", \"p324\", \"p325\", \"p326\", \"p327\", \"p328\", \"p329\", \"p330\", \"p331\", \"p332\", \"p333\", \"p334\", \"p335\", \"p336\", \"p337\", \"p338\", \"p339\", \"p340\", \"p341\", \"p342\", \"p343\", \"p344\", \"p345\", \"p346\", \"p347\", \"p348\", \"p349\", \"p350\", \"p351\", \"p352\", \"p353\", \"p354\", \"p355\", \"p356\", \"p357\", \"p358\", \"p359\", \"p360\", \"p361\", \"p362\", \"p363\", \"p364\", \"p365\", \"p366\", \"p367\", \"p368\", \"p369\", \"p370\", \"p371\", \"p372\", \"p373\", \"p374\", \"p375\", \"p376\", \"p377\", \"p378\", \"p379\", \"p380\", \"p381\", \"p382\", \"p383\", \"p384\", \"p385\", \"p386\", \"p387\", \"p388\", \"p389\", \"p390\", \"p391\", \"p392\", \"p393\", \"p394\", \"p395\", \"p396\", \"p397\", \"p398\", \"p399\", \"p400\", \"p401\", \"p402\", \"p403\", \"p404\", \"p405\", \"p406\", \"p407\", \"p408\", \"p409\", \"p410\", \"p411\", \"p412\", \"p413\", \"p414\", \"p415\", \"p416\", \"p417\", \"p418\", \"p419\", \"p420\", \"p421\", \"p422\", \"p423\", \"p424\", \"p425\", \"p426\", \"p427\", \"p428\", \"p429\", \"p430\", \"p431\", \"p432\", \"p433\", \"p434\", \"p435\", \"p436\", \"p437\", \"p438\", \"p439\", \"p440\", \"p441\", \"p442\", \"p443\", \"p444\", \"p445\", \"p446\", \"p447\", \"p448\", \"p449\", \"p450\", \"p451\", \"p452\", \"p453\", \"p454\", \"p455\", \"p456\", \"p457\", \"p458\", \"p459\", \"p460\", \"p461\", \"p462\", \"p463\", \"p464\", \"p465\", \"p466\", \"p467\", \"p468\", \"p469\", \"p470\", \"p471\", \"p472\", \"p473\", \"p474\", \"p475\", \"p476\", \"p477\", \"p478\", \"p479\", \"p480\", \"p481\", \"p482\", \"p483\", \"p484\", \"p485\", \"p486\", \"p487\", \"p488\", \"p489\", \"p490\", \"p491\", \"p492\", \"p493\", \"p494\", \"p495\", \"p496\", \"p497\", \"p498\", \"p499\", \"p500\" ]"); + assert_eq!(forward(&mut context, init), "[ \"p0\", \"p1\", \"p2\", \"p3\", \"p4\", \"p5\", \"p6\", \"p7\", \"p8\", \"p9\", \"p10\", \"p11\", \"p12\", \"p13\", \"p14\", \"p15\", \"p16\", \"p17\", \"p18\", \"p19\", \"p20\", \"p21\", \"p22\", \"p23\", \"p24\", \"p25\", \"p26\", \"p27\", \"p28\", \"p29\", \"p30\", \"p31\", \"p32\", \"p33\", \"p34\", \"p35\", \"p36\", \"p37\", \"p38\", \"p39\", \"p40\", \"p41\", \"p42\", \"p43\", \"p44\", \"p45\", \"p46\", \"p47\", \"p48\", \"p49\", \"p50\", \"p51\", \"p52\", \"p53\", \"p54\", \"p55\", \"p56\", \"p57\", \"p58\", \"p59\", \"p60\", \"p61\", \"p62\", \"p63\", \"p64\", \"p65\", \"p66\", \"p67\", \"p68\", \"p69\", \"p70\", \"p71\", \"p72\", \"p73\", \"p74\", \"p75\", \"p76\", \"p77\", \"p78\", \"p79\", \"p80\", \"p81\", \"p82\", \"p83\", \"p84\", \"p85\", \"p86\", \"p87\", \"p88\", \"p89\", \"p90\", \"p91\", \"p92\", \"p93\", \"p94\", \"p95\", \"p96\", \"p97\", \"p98\", \"p99\", \"p100\", \"p101\", \"p102\", \"p103\", \"p104\", \"p105\", \"p106\", \"p107\", \"p108\", \"p109\", \"p110\", \"p111\", \"p112\", \"p113\", \"p114\", \"p115\", \"p116\", \"p117\", \"p118\", \"p119\", \"p120\", \"p121\", \"p122\", \"p123\", \"p124\", \"p125\", \"p126\", \"p127\", \"p128\", \"p129\", \"p130\", \"p131\", \"p132\", \"p133\", \"p134\", \"p135\", \"p136\", \"p137\", \"p138\", \"p139\", \"p140\", \"p141\", \"p142\", \"p143\", \"p144\", \"p145\", \"p146\", \"p147\", \"p148\", \"p149\", \"p150\", \"p151\", \"p152\", \"p153\", \"p154\", \"p155\", \"p156\", \"p157\", \"p158\", \"p159\", \"p160\", \"p161\", \"p162\", \"p163\", \"p164\", \"p165\", \"p166\", \"p167\", \"p168\", \"p169\", \"p170\", \"p171\", \"p172\", \"p173\", \"p174\", \"p175\", \"p176\", \"p177\", \"p178\", \"p179\", \"p180\", \"p181\", \"p182\", \"p183\", \"p184\", \"p185\", \"p186\", \"p187\", \"p188\", \"p189\", \"p190\", \"p191\", \"p192\", \"p193\", \"p194\", \"p195\", \"p196\", \"p197\", \"p198\", \"p199\", \"p200\", \"p201\", \"p202\", \"p203\", \"p204\", \"p205\", \"p206\", \"p207\", \"p208\", \"p209\", \"p210\", \"p211\", \"p212\", \"p213\", \"p214\", \"p215\", \"p216\", \"p217\", \"p218\", \"p219\", \"p220\", \"p221\", \"p222\", \"p223\", \"p224\", \"p225\", \"p226\", \"p227\", \"p228\", \"p229\", \"p230\", \"p231\", \"p232\", \"p233\", \"p234\", \"p235\", \"p236\", \"p237\", \"p238\", \"p239\", \"p240\", \"p241\", \"p242\", \"p243\", \"p244\", \"p245\", \"p246\", \"p247\", \"p248\", \"p249\", \"p250\", \"p251\", \"p252\", \"p253\", \"p254\", \"p255\", \"p256\", \"p257\", \"p258\", \"p259\", \"p260\", \"p261\", \"p262\", \"p263\", \"p264\", \"p265\", \"p266\", \"p267\", \"p268\", \"p269\", \"p270\", \"p271\", \"p272\", \"p273\", \"p274\", \"p275\", \"p276\", \"p277\", \"p278\", \"p279\", \"p280\", \"p281\", \"p282\", \"p283\", \"p284\", \"p285\", \"p286\", \"p287\", \"p288\", \"p289\", \"p290\", \"p291\", \"p292\", \"p293\", \"p294\", \"p295\", \"p296\", \"p297\", \"p298\", \"p299\", \"p300\", \"p301\", \"p302\", \"p303\", \"p304\", \"p305\", \"p306\", \"p307\", \"p308\", \"p309\", \"p310\", \"p311\", \"p312\", \"p313\", \"p314\", \"p315\", \"p316\", \"p317\", \"p318\", \"p319\", \"p320\", \"p321\", \"p322\", \"p323\", \"p324\", \"p325\", \"p326\", \"p327\", \"p328\", \"p329\", \"p330\", \"p331\", \"p332\", \"p333\", \"p334\", \"p335\", \"p336\", \"p337\", \"p338\", \"p339\", \"p340\", \"p341\", \"p342\", \"p343\", \"p344\", \"p345\", \"p346\", \"p347\", \"p348\", \"p349\", \"p350\", \"p351\", \"p352\", \"p353\", \"p354\", \"p355\", \"p356\", \"p357\", \"p358\", \"p359\", \"p360\", \"p361\", \"p362\", \"p363\", \"p364\", \"p365\", \"p366\", \"p367\", \"p368\", \"p369\", \"p370\", \"p371\", \"p372\", \"p373\", \"p374\", \"p375\", \"p376\", \"p377\", \"p378\", \"p379\", \"p380\", \"p381\", \"p382\", \"p383\", \"p384\", \"p385\", \"p386\", \"p387\", \"p388\", \"p389\", \"p390\", \"p391\", \"p392\", \"p393\", \"p394\", \"p395\", \"p396\", \"p397\", \"p398\", \"p399\", \"p400\", \"p401\", \"p402\", \"p403\", \"p404\", \"p405\", \"p406\", \"p407\", \"p408\", \"p409\", \"p410\", \"p411\", \"p412\", \"p413\", \"p414\", \"p415\", \"p416\", \"p417\", \"p418\", \"p419\", \"p420\", \"p421\", \"p422\", \"p423\", \"p424\", \"p425\", \"p426\", \"p427\", \"p428\", \"p429\", \"p430\", \"p431\", \"p432\", \"p433\", \"p434\", \"p435\", \"p436\", \"p437\", \"p438\", \"p439\", \"p440\", \"p441\", \"p442\", \"p443\", \"p444\", \"p445\", \"p446\", \"p447\", \"p448\", \"p449\", \"p450\", \"p451\", \"p452\", \"p453\", \"p454\", \"p455\", \"p456\", \"p457\", \"p458\", \"p459\", \"p460\", \"p461\", \"p462\", \"p463\", \"p464\", \"p465\", \"p466\", \"p467\", \"p468\", \"p469\", \"p470\", \"p471\", \"p472\", \"p473\", \"p474\", \"p475\", \"p476\", \"p477\", \"p478\", \"p479\", \"p480\", \"p481\", \"p482\", \"p483\", \"p484\", \"p485\", \"p486\", \"p487\", \"p488\", \"p489\", \"p490\", \"p491\", \"p492\", \"p493\", \"p494\", \"p495\", \"p496\", \"p497\", \"p498\", \"p499\", \"p500\" ]"); } #[test] fn array_pop_benchmark() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" (function(){ let testArray = [83, 93, 27, 29, 2828, 234, 23, 56, 32, 56, 67, 77, 32, @@ -1202,12 +1204,12 @@ fn array_pop_benchmark() { })(); "#; - assert_eq!(forward(&mut engine, init), "[]"); + assert_eq!(forward(&mut context, init), "[]"); } #[test] fn number_object_access_benchmark() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" new Number( new Number( @@ -1218,17 +1220,17 @@ fn number_object_access_benchmark() { ) "#; - assert!(forward_val(&mut engine, init).is_ok()); + assert!(forward_val(&mut context, init).is_ok()); } #[test] fn not_a_function() { - let mut engine = Context::new(); + let mut context = Context::new(); let init = r#" let a = {}; let b = true; "#; - forward(&mut engine, init); + forward(&mut context, init); let scenario = r#" try { a(); @@ -1237,7 +1239,7 @@ fn not_a_function() { } "#; assert_eq!( - forward(&mut engine, scenario), + forward(&mut context, scenario), "\"TypeError: not a function\"" ); let scenario = r#" @@ -1248,7 +1250,7 @@ fn not_a_function() { } "#; assert_eq!( - forward(&mut engine, scenario), + forward(&mut context, scenario), "\"TypeError: not a function\"" ); let scenario = r#" @@ -1259,7 +1261,7 @@ fn not_a_function() { } "#; assert_eq!( - forward(&mut engine, scenario), + forward(&mut context, scenario), "\"TypeError: not a function\"" ); } @@ -1287,7 +1289,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 mut engine = Context::new(); + let mut context = Context::new(); // Tests all assignment operators as per [spec] and [mdn] // @@ -1298,7 +1300,7 @@ fn assignment_to_non_assignable() { ]; for case in test_cases.iter() { - let string = forward(&mut engine, case); + let string = forward(&mut context, case); assert!(string.starts_with("Uncaught \"SyntaxError\": ")); assert!(string.contains("1:3")); @@ -1309,12 +1311,12 @@ 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 mut engine = Context::new(); + let mut context = Context::new(); let test_cases = ["3 **= 5", "3 <<= 5", "3 >>= 5"]; for case in test_cases.iter() { - let string = dbg!(forward(&mut engine, case)); + let string = dbg!(forward(&mut context, case)); assert!(string.starts_with("Uncaught \"SyntaxError\": ")); assert!(string.contains("1:3")); @@ -1324,13 +1326,13 @@ fn multicharacter_assignment_to_non_assignable() { #[test] #[ignore] fn multicharacter_bitwise_assignment_to_non_assignable() { - let mut engine = Context::new(); + let mut context = Context::new(); // Disabled - awaiting implementation. let test_cases = ["3 >>>= 5", "3 &&= 5", "3 ||= 5", "3 ??= 5"]; for case in test_cases.iter() { - let string = dbg!(forward(&mut engine, case)); + let string = dbg!(forward(&mut context, case)); assert!(string.starts_with("Uncaught \"SyntaxError\": ")); assert!(string.contains("1:3")); @@ -1339,22 +1341,22 @@ fn multicharacter_bitwise_assignment_to_non_assignable() { #[test] fn assign_to_array_decl() { - let mut engine = Context::new(); + let mut context = Context::new(); - assert!(forward(&mut engine, "[1] = [2]").starts_with("Uncaught \"SyntaxError\": ")); - assert!(forward(&mut engine, "[3, 5] = [7, 8]").starts_with("Uncaught \"SyntaxError\": ")); - assert!(forward(&mut engine, "[6, 8] = [2]").starts_with("Uncaught \"SyntaxError\": ")); - assert!(forward(&mut engine, "[6] = [2, 9]").starts_with("Uncaught \"SyntaxError\": ")); + assert!(forward(&mut context, "[1] = [2]").starts_with("Uncaught \"SyntaxError\": ")); + assert!(forward(&mut context, "[3, 5] = [7, 8]").starts_with("Uncaught \"SyntaxError\": ")); + assert!(forward(&mut context, "[6, 8] = [2]").starts_with("Uncaught \"SyntaxError\": ")); + assert!(forward(&mut context, "[6] = [2, 9]").starts_with("Uncaught \"SyntaxError\": ")); } #[test] fn assign_to_object_decl() { - let mut engine = Context::new(); + let mut context = Context::new(); const ERR_MSG: &str = "Uncaught \"SyntaxError\": \"unexpected token '=', primary expression at line 1, col 8\""; - assert_eq!(forward(&mut engine, "{a: 3} = {a: 5};"), ERR_MSG); + assert_eq!(forward(&mut context, "{a: 3} = {a: 5};"), ERR_MSG); } #[test] @@ -1407,9 +1409,9 @@ fn test_strict_mode_octal() { var n = 023; "#; - let mut engine = Context::new(); + let mut context = Context::new(); - let string = dbg!(forward(&mut engine, scenario)); + let string = dbg!(forward(&mut context, scenario)); assert!(string.starts_with("Uncaught \"SyntaxError\": ")); } @@ -1428,9 +1430,9 @@ fn test_strict_mode_with() { } "#; - let mut engine = Context::new(); + let mut context = Context::new(); - let string = dbg!(forward(&mut engine, scenario)); + let string = dbg!(forward(&mut context, scenario)); assert!(string.starts_with("Uncaught \"SyntaxError\": ")); } @@ -1446,9 +1448,9 @@ fn test_strict_mode_delete() { delete x; "#; - let mut engine = Context::new(); + let mut context = Context::new(); - let string = dbg!(forward(&mut engine, scenario)); + let string = dbg!(forward(&mut context, scenario)); assert!(string.starts_with("Uncaught \"SyntaxError\": ")); } @@ -1473,10 +1475,10 @@ fn test_strict_mode_reserved_name() { ]; for case in test_cases.iter() { - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = format!("'use strict'; \n {}", case); - let string = dbg!(forward(&mut engine, &scenario)); + let string = dbg!(forward(&mut context, &scenario)); assert!(string.starts_with("Uncaught \"SyntaxError\": ")); } @@ -1494,9 +1496,9 @@ fn test_strict_mode_func_decl_in_block() { if (a < b) { function f() {} } "#; - let mut engine = Context::new(); + let mut context = Context::new(); - let string = dbg!(forward(&mut engine, scenario)); + let string = dbg!(forward(&mut context, scenario)); assert!(string.starts_with("Uncaught \"SyntaxError\": ")); } @@ -1511,9 +1513,9 @@ fn test_strict_mode_dup_func_parameters() { function f(a, b, b) {} "#; - let mut engine = Context::new(); + let mut context = Context::new(); - let string = dbg!(forward(&mut engine, scenario)); + let string = dbg!(forward(&mut context, scenario)); assert!(string.starts_with("Uncaught \"SyntaxError\": ")); } diff --git a/boa/src/lib.rs b/boa/src/lib.rs index eb191730ab..6244593c11 100644 --- a/boa/src/lib.rs +++ b/boa/src/lib.rs @@ -85,21 +85,21 @@ pub fn parse(src: &str, strict_mode: bool) -> StdResult String { +pub(crate) fn forward(context: &mut Context, src: &str) -> String { // Setup executor let expr = match parse(src, false) { Ok(res) => res, Err(e) => { return format!( "Uncaught {}", - engine + context .throw_syntax_error(e.to_string()) .expect_err("interpreter.throw_syntax_error() did not return an error") .display() ); } }; - expr.run(engine).map_or_else( + expr.run(context).map_or_else( |e| format!("Uncaught {}", e.display()), |v| v.display().to_string(), ) @@ -111,16 +111,16 @@ pub(crate) fn forward(engine: &mut Context, src: &str) -> String { /// If the interpreter fails parsing an error value is returned instead (error object) #[allow(clippy::unit_arg, clippy::drop_copy)] #[cfg(test)] -pub(crate) fn forward_val(engine: &mut Context, src: &str) -> Result { +pub(crate) fn forward_val(context: &mut Context, src: &str) -> Result { let main_timer = BoaProfiler::global().start_event("Main", "Main"); // Setup executor let result = parse(src, false) .map_err(|e| { - engine + context .throw_syntax_error(e.to_string()) .expect_err("interpreter.throw_syntax_error() did not return an error") }) - .and_then(|expr| expr.run(engine)); + .and_then(|expr| expr.run(context)); // The main_timer needs to be dropped before the BoaProfiler is. drop(main_timer); diff --git a/boa/src/object/gcobject.rs b/boa/src/object/gcobject.rs index 361fb92a91..a6d4f25d33 100644 --- a/boa/src/object/gcobject.rs +++ b/boa/src/object/gcobject.rs @@ -114,7 +114,7 @@ impl GcObject { // // #[track_caller] - pub fn call(&self, this: &Value, args: &[Value], ctx: &mut Context) -> Result { + pub fn call(&self, this: &Value, args: &[Value], context: &mut Context) -> Result { let this_function_object = self.clone(); let f_body = if let Some(function) = self.borrow().as_function() { if function.is_callable() { @@ -150,7 +150,7 @@ impl GcObject { for (i, param) in params.iter().enumerate() { // Rest Parameters if param.is_rest_param() { - function.add_rest_param(param, i, args, ctx, &local_env); + function.add_rest_param(param, i, args, context, &local_env); break; } @@ -167,23 +167,23 @@ impl GcObject { .borrow_mut() .initialize_binding("arguments", arguments_obj); - ctx.realm_mut().environment.push(local_env); + context.realm_mut().environment.push(local_env); FunctionBody::Ordinary(body.clone()) } } } else { - return ctx.throw_type_error("function object is not callable"); + return context.throw_type_error("function object is not callable"); } } else { - return ctx.throw_type_error("not a function"); + return context.throw_type_error("not a function"); }; match f_body { - FunctionBody::BuiltIn(func) => func(this, args, ctx), + FunctionBody::BuiltIn(func) => func(this, args, context), FunctionBody::Ordinary(body) => { - let result = body.run(ctx); - ctx.realm_mut().environment.pop(); + let result = body.run(context); + context.realm_mut().environment.pop(); result } @@ -197,7 +197,7 @@ impl GcObject { /// Panics if the object is currently mutably borrowed. // #[track_caller] - pub fn construct(&self, args: &[Value], ctx: &mut Context) -> Result { + pub fn construct(&self, args: &[Value], context: &mut Context) -> Result { let this: Value = Object::create(self.get(&PROTOTYPE.into())).into(); let this_function_object = self.clone(); @@ -231,7 +231,7 @@ impl GcObject { for (i, param) in params.iter().enumerate() { // Rest Parameters if param.is_rest_param() { - function.add_rest_param(param, i, args, ctx, &local_env); + function.add_rest_param(param, i, args, context, &local_env); break; } @@ -248,29 +248,29 @@ impl GcObject { .borrow_mut() .initialize_binding("arguments", arguments_obj); - ctx.realm_mut().environment.push(local_env); + context.realm_mut().environment.push(local_env); FunctionBody::Ordinary(body.clone()) } } } else { let name = this.get_field("name").display().to_string(); - return ctx.throw_type_error(format!("{} is not a constructor", name)); + return context.throw_type_error(format!("{} is not a constructor", name)); } } else { - return ctx.throw_type_error("not a function"); + return context.throw_type_error("not a function"); }; match body { FunctionBody::BuiltIn(function) => { - function(&this, args, ctx)?; + function(&this, args, context)?; Ok(this) } FunctionBody::Ordinary(body) => { - let _ = body.run(ctx); + let _ = body.run(context); // local_env gets dropped here, its no longer needed - let binding = ctx.realm_mut().environment.get_this_binding(); + let binding = context.realm_mut().environment.get_this_binding(); Ok(binding) } } @@ -296,7 +296,7 @@ impl GcObject { /// [spec]: https://tc39.es/ecma262/#sec-ordinarytoprimitive pub(crate) fn ordinary_to_primitive( &self, - interpreter: &mut Context, + context: &mut Context, hint: PreferredType, ) -> Result { // 1. Assert: Type(O) is Object. @@ -336,7 +336,7 @@ impl GcObject { // b. If IsCallable(method) is true, then if method.is_function() { // i. Let result be ? Call(method, O). - let result = interpreter.call(&method, &this, &[])?; + let result = context.call(&method, &this, &[])?; // ii. If Type(result) is not Object, return result. if !result.is_object() { return Ok(result); @@ -345,14 +345,14 @@ impl GcObject { } // 6. Throw a TypeError exception. - interpreter.throw_type_error("cannot convert object to primitive value") + context.throw_type_error("cannot convert object to primitive value") } /// Converts an object to JSON, checking for reference cycles and throwing a TypeError if one is found - pub(crate) fn to_json(&self, interpreter: &mut Context) -> Result { + pub(crate) fn to_json(&self, context: &mut Context) -> Result { let rec_limiter = RecursionLimiter::new(self); if rec_limiter.live { - Err(interpreter.construct_type_error("cyclic object value")) + Err(context.construct_type_error("cyclic object value")) } else if self.is_array() { let mut keys: Vec = self.borrow().index_property_keys().cloned().collect(); keys.sort_unstable(); @@ -363,7 +363,7 @@ impl GcObject { if value.is_undefined() || value.is_function() || value.is_symbol() { arr.push(JSONValue::Null); } else { - arr.push(value.to_json(interpreter)?); + arr.push(value.to_json(context)?); } } Ok(JSONValue::Array(arr)) @@ -374,7 +374,7 @@ impl GcObject { let key = k.clone(); let value = this.get_field(k.to_string()); if !value.is_undefined() && !value.is_function() && !value.is_symbol() { - new_obj.insert(key.to_string(), value.to_json(interpreter)?); + new_obj.insert(key.to_string(), value.to_json(context)?); } } Ok(JSONValue::Object(new_obj)) diff --git a/boa/src/object/internal_methods.rs b/boa/src/object/internal_methods.rs index eda1e4feb8..ce131a1f59 100644 --- a/boa/src/object/internal_methods.rs +++ b/boa/src/object/internal_methods.rs @@ -252,8 +252,8 @@ impl GcObject { /// /// [spec]: https://tc39.es/ecma262/#sec-object.defineproperties #[inline] - pub fn define_properties(&mut self, props: Value, ctx: &mut Context) -> Result<()> { - let props = props.to_object(ctx)?; + pub fn define_properties(&mut self, props: Value, context: &mut Context) -> Result<()> { + let props = props.to_object(context)?; let keys = props.own_property_keys(); let mut descriptors: Vec<(PropertyKey, PropertyDescriptor)> = Vec::new(); @@ -261,7 +261,7 @@ impl GcObject { if let Some(prop_desc) = props.get_own_property(&next_key) { if prop_desc.enumerable() { let desc_obj = props.get(&next_key); - let desc = desc_obj.to_property_descriptor(ctx)?; + let desc = desc_obj.to_property_descriptor(context)?; descriptors.push((next_key, desc)); } } diff --git a/boa/src/property/attribute/mod.rs b/boa/src/property/attribute/mod.rs index d6c00c4241..875db40c7b 100644 --- a/boa/src/property/attribute/mod.rs +++ b/boa/src/property/attribute/mod.rs @@ -1,7 +1,7 @@ //! This module implements the `Attribute` struct which contains the attibutes for property descriptors. +use crate::gc::{empty_trace, Finalize, Trace}; use bitflags::bitflags; -use gc::{unsafe_empty_trace, Finalize, Trace}; #[cfg(test)] mod tests; @@ -44,7 +44,7 @@ bitflags! { // SAFETY: The `Attribute` struct only contains an `u8` // and therefore it should be safe to implement an empty trace. unsafe impl Trace for Attribute { - unsafe_empty_trace!(); + empty_trace!(); } impl Attribute { diff --git a/boa/src/realm.rs b/boa/src/realm.rs index b6785dde13..ef8e87f0c8 100644 --- a/boa/src/realm.rs +++ b/boa/src/realm.rs @@ -21,7 +21,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; /// In the specification these are called Realm Records. #[derive(Debug)] pub struct Realm { - pub global_obj: Value, + pub global_object: Value, pub global_env: Gc>, pub environment: LexicalEnvironment, } @@ -40,7 +40,7 @@ impl Realm { let global_env = new_global_environment(global.clone(), global.clone()); Self { - global_obj: global.clone(), + global_object: global.clone(), global_env, environment: LexicalEnvironment::new(global), } diff --git a/boa/src/syntax/ast/constant.rs b/boa/src/syntax/ast/constant.rs index 07b1fc2777..4d10dd62aa 100644 --- a/boa/src/syntax/ast/constant.rs +++ b/boa/src/syntax/ast/constant.rs @@ -7,8 +7,10 @@ //! [spec]: https://tc39.es/ecma262/#sec-primary-expression-literals //! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Literals -use crate::builtins::bigint::BigInt; -use gc::{Finalize, Trace}; +use crate::{ + builtins::bigint::BigInt, + gc::{Finalize, Trace}, +}; use std::fmt::{Display, Formatter, Result}; #[cfg(feature = "serde")] diff --git a/boa/src/syntax/ast/node/array/mod.rs b/boa/src/syntax/ast/node/array/mod.rs index 02dda7badd..4749777c65 100644 --- a/boa/src/syntax/ast/node/array/mod.rs +++ b/boa/src/syntax/ast/node/array/mod.rs @@ -4,9 +4,9 @@ use super::{join_nodes, Node}; use crate::{ builtins::{iterable, Array}, exec::Executable, + gc::{Finalize, Trace}, BoaProfiler, Context, Result, Value, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -36,19 +36,19 @@ pub struct ArrayDecl { } impl Executable for ArrayDecl { - fn run(&self, interpreter: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("ArrayDecl", "exec"); - let array = Array::new_array(interpreter)?; + let array = Array::new_array(context)?; let mut elements = Vec::new(); for elem in self.as_ref() { if let Node::Spread(ref x) = elem { - let val = x.run(interpreter)?; - let iterator_record = iterable::get_iterator(interpreter, val)?; + let val = x.run(context)?; + let iterator_record = iterable::get_iterator(context, val)?; // TODO after proper internal Array representation as per https://github.com/boa-dev/boa/pull/811#discussion_r502460858 // next_index variable should be utilized here as per https://tc39.es/ecma262/#sec-runtime-semantics-arrayaccumulation // let mut next_index = 0; loop { - let next = iterator_record.next(interpreter)?; + let next = iterator_record.next(context)?; if next.is_done() { break; } @@ -57,7 +57,7 @@ impl Executable for ArrayDecl { elements.push(next_value.clone()); } } else { - elements.push(elem.run(interpreter)?); + elements.push(elem.run(context)?); } } diff --git a/boa/src/syntax/ast/node/block/mod.rs b/boa/src/syntax/ast/node/block/mod.rs index 2520865312..f7144b6753 100644 --- a/boa/src/syntax/ast/node/block/mod.rs +++ b/boa/src/syntax/ast/node/block/mod.rs @@ -2,10 +2,12 @@ use super::{Node, StatementList}; use crate::{ - environment::lexical_environment::new_declarative_environment, exec::Executable, - exec::InterpreterState, BoaProfiler, Context, Result, Value, + environment::lexical_environment::new_declarative_environment, + exec::Executable, + exec::InterpreterState, + gc::{Finalize, Trace}, + BoaProfiler, Context, Result, Value, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -49,10 +51,10 @@ impl Block { } impl Executable for Block { - fn run(&self, interpreter: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("Block", "exec"); { - let env = &mut interpreter.realm_mut().environment; + let env = &mut context.realm_mut().environment; env.push(new_declarative_environment(Some( env.get_current_environment_ref().clone(), ))); @@ -62,9 +64,9 @@ impl Executable for Block { // The return value is uninitialized, which means it defaults to Value::Undefined let mut obj = Value::default(); for statement in self.statements() { - obj = statement.run(interpreter)?; + obj = statement.run(context)?; - match interpreter.executor().get_current_state() { + match context.executor().get_current_state() { InterpreterState::Return => { // Early return. break; @@ -86,7 +88,7 @@ impl Executable for Block { } // pop the block env - let _ = interpreter.realm_mut().environment.pop(); + let _ = context.realm_mut().environment.pop(); Ok(obj) } diff --git a/boa/src/syntax/ast/node/break_node/mod.rs b/boa/src/syntax/ast/node/break_node/mod.rs index 8b7f723aae..178d09b212 100644 --- a/boa/src/syntax/ast/node/break_node/mod.rs +++ b/boa/src/syntax/ast/node/break_node/mod.rs @@ -1,6 +1,10 @@ use super::Node; -use crate::{exec::Executable, exec::InterpreterState, Context, Result, Value}; -use gc::{Finalize, Trace}; +use crate::{ + exec::Executable, + exec::InterpreterState, + gc::{Finalize, Trace}, + Context, Result, Value, +}; use std::fmt; #[cfg(feature = "serde")] @@ -48,8 +52,8 @@ impl Break { } impl Executable for Break { - fn run(&self, interpreter: &mut Context) -> Result { - interpreter + fn run(&self, context: &mut Context) -> Result { + context .executor() .set_current_state(InterpreterState::Break(self.label().map(Box::from))); diff --git a/boa/src/syntax/ast/node/break_node/tests.rs b/boa/src/syntax/ast/node/break_node/tests.rs index b1ae0b4dd8..194c22c2b8 100644 --- a/boa/src/syntax/ast/node/break_node/tests.rs +++ b/boa/src/syntax/ast/node/break_node/tests.rs @@ -6,14 +6,14 @@ use crate::{ #[test] fn check_post_state() { - let mut engine = Context::new(); + let mut context = Context::new(); let brk: Break = Break::new("label"); - brk.run(&mut engine).unwrap(); + brk.run(&mut context).unwrap(); assert_eq!( - engine.executor().get_current_state(), + context.executor().get_current_state(), &InterpreterState::Break(Some("label".into())) ); } diff --git a/boa/src/syntax/ast/node/call/mod.rs b/boa/src/syntax/ast/node/call/mod.rs index 60321ed8e0..11a25ea641 100644 --- a/boa/src/syntax/ast/node/call/mod.rs +++ b/boa/src/syntax/ast/node/call/mod.rs @@ -1,11 +1,11 @@ use crate::{ exec::Executable, exec::InterpreterState, + gc::{Finalize, Trace}, syntax::ast::node::{join_nodes, Node}, value::{Type, Value}, BoaProfiler, Context, Result, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -57,45 +57,39 @@ impl Call { } impl Executable for Call { - fn run(&self, interpreter: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("Call", "exec"); let (this, func) = match self.expr() { Node::GetConstField(ref get_const_field) => { - let mut obj = get_const_field.obj().run(interpreter)?; + let mut obj = get_const_field.obj().run(context)?; if obj.get_type() != Type::Object { - obj = Value::Object(obj.to_object(interpreter)?); + obj = Value::Object(obj.to_object(context)?); } (obj.clone(), obj.get_field(get_const_field.field())) } Node::GetField(ref get_field) => { - let obj = get_field.obj().run(interpreter)?; - let field = get_field.field().run(interpreter)?; - ( - obj.clone(), - obj.get_field(field.to_property_key(interpreter)?), - ) + let obj = get_field.obj().run(context)?; + let field = get_field.field().run(context)?; + (obj.clone(), obj.get_field(field.to_property_key(context)?)) } - _ => ( - interpreter.realm().global_obj.clone(), - self.expr().run(interpreter)?, - ), // 'this' binding should come from the function's self-contained environment + _ => (context.global_object().clone(), self.expr().run(context)?), // 'this' binding should come from the function's self-contained environment }; let mut v_args = Vec::with_capacity(self.args().len()); for arg in self.args() { if let Node::Spread(ref x) = arg { - let val = x.run(interpreter)?; - let mut vals = interpreter.extract_array_properties(&val).unwrap(); + let val = x.run(context)?; + let mut vals = context.extract_array_properties(&val).unwrap(); v_args.append(&mut vals); break; // after spread we don't accept any new arguments } - v_args.push(arg.run(interpreter)?); + v_args.push(arg.run(context)?); } // execute the function call itself - let fnct_result = interpreter.call(&func, &this, &v_args); + let fnct_result = context.call(&func, &this, &v_args); // unset the early return flag - interpreter + context .executor() .set_current_state(InterpreterState::Executing); diff --git a/boa/src/syntax/ast/node/conditional/conditional_op/mod.rs b/boa/src/syntax/ast/node/conditional/conditional_op/mod.rs index ee7a6a7f85..5d24c23334 100644 --- a/boa/src/syntax/ast/node/conditional/conditional_op/mod.rs +++ b/boa/src/syntax/ast/node/conditional/conditional_op/mod.rs @@ -1,5 +1,9 @@ -use crate::{exec::Executable, syntax::ast::node::Node, Context, Result, Value}; -use gc::{Finalize, Trace}; +use crate::{ + exec::Executable, + gc::{Finalize, Trace}, + syntax::ast::node::Node, + Context, Result, Value, +}; use std::fmt; #[cfg(feature = "serde")] @@ -56,11 +60,11 @@ impl ConditionalOp { } impl Executable for ConditionalOp { - fn run(&self, interpreter: &mut Context) -> Result { - Ok(if self.cond().run(interpreter)?.to_boolean() { - self.if_true().run(interpreter)? + fn run(&self, context: &mut Context) -> Result { + Ok(if self.cond().run(context)?.to_boolean() { + self.if_true().run(context)? } else { - self.if_false().run(interpreter)? + self.if_false().run(context)? }) } } diff --git a/boa/src/syntax/ast/node/conditional/if_node/mod.rs b/boa/src/syntax/ast/node/conditional/if_node/mod.rs index 6257d7d841..d6f376ad1e 100644 --- a/boa/src/syntax/ast/node/conditional/if_node/mod.rs +++ b/boa/src/syntax/ast/node/conditional/if_node/mod.rs @@ -1,5 +1,9 @@ -use crate::{exec::Executable, syntax::ast::node::Node, Context, Result, Value}; -use gc::{Finalize, Trace}; +use crate::{ + exec::Executable, + gc::{Finalize, Trace}, + syntax::ast::node::Node, + Context, Result, Value, +}; use std::fmt; #[cfg(feature = "serde")] @@ -75,11 +79,11 @@ impl If { } impl Executable for If { - fn run(&self, interpreter: &mut Context) -> Result { - Ok(if self.cond().run(interpreter)?.to_boolean() { - self.body().run(interpreter)? + fn run(&self, context: &mut Context) -> Result { + Ok(if self.cond().run(context)?.to_boolean() { + self.body().run(context)? } else if let Some(ref else_e) = self.else_node() { - else_e.run(interpreter)? + else_e.run(context)? } else { Value::undefined() }) diff --git a/boa/src/syntax/ast/node/declaration/arrow_function_decl/mod.rs b/boa/src/syntax/ast/node/declaration/arrow_function_decl/mod.rs index b7db3d6e06..aee34dc19e 100644 --- a/boa/src/syntax/ast/node/declaration/arrow_function_decl/mod.rs +++ b/boa/src/syntax/ast/node/declaration/arrow_function_decl/mod.rs @@ -1,10 +1,10 @@ use crate::{ builtins::function::FunctionFlags, exec::Executable, + gc::{Finalize, Trace}, syntax::ast::node::{join_nodes, FormalParameter, Node, StatementList}, Context, Result, Value, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -67,8 +67,8 @@ impl ArrowFunctionDecl { } impl Executable for ArrowFunctionDecl { - fn run(&self, interpreter: &mut Context) -> Result { - Ok(interpreter.create_function( + fn run(&self, context: &mut Context) -> Result { + Ok(context.create_function( self.params().to_vec(), self.body().to_vec(), FunctionFlags::CALLABLE diff --git a/boa/src/syntax/ast/node/declaration/const_decl_list/mod.rs b/boa/src/syntax/ast/node/declaration/const_decl_list/mod.rs index 103d4de69e..205bc7e364 100644 --- a/boa/src/syntax/ast/node/declaration/const_decl_list/mod.rs +++ b/boa/src/syntax/ast/node/declaration/const_decl_list/mod.rs @@ -1,10 +1,10 @@ use crate::{ environment::lexical_environment::VariableScope, exec::Executable, + gc::{Finalize, Trace}, syntax::ast::node::{join_nodes, Identifier, Node}, Context, Result, Value, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -36,20 +36,21 @@ pub struct ConstDeclList { } impl Executable for ConstDeclList { - fn run(&self, interpreter: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { for decl in self.as_ref() { let val = if let Some(init) = decl.init() { - init.run(interpreter)? + init.run(context)? } else { - return interpreter.throw_syntax_error("missing = in const declaration"); + return context.throw_syntax_error("missing = in const declaration"); }; - interpreter - .realm_mut() - .environment - .create_immutable_binding(decl.name().to_owned(), false, VariableScope::Block); + context.realm_mut().environment.create_immutable_binding( + decl.name().to_owned(), + false, + VariableScope::Block, + ); - interpreter + context .realm_mut() .environment .initialize_binding(decl.name(), val); diff --git a/boa/src/syntax/ast/node/declaration/function_decl/mod.rs b/boa/src/syntax/ast/node/declaration/function_decl/mod.rs index 14c55adaf8..f3e39c0592 100644 --- a/boa/src/syntax/ast/node/declaration/function_decl/mod.rs +++ b/boa/src/syntax/ast/node/declaration/function_decl/mod.rs @@ -2,10 +2,10 @@ use crate::{ builtins::function::FunctionFlags, environment::lexical_environment::VariableScope, exec::Executable, + gc::{Finalize, Trace}, syntax::ast::node::{join_nodes, FormalParameter, Node, StatementList}, BoaProfiler, Context, Result, Value, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -84,9 +84,9 @@ impl FunctionDecl { } impl Executable for FunctionDecl { - fn run(&self, interpreter: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("FunctionDecl", "exec"); - let val = interpreter.create_function( + let val = context.create_function( self.parameters().to_vec(), self.body().to_vec(), FunctionFlags::CALLABLE | FunctionFlags::CONSTRUCTABLE, @@ -94,13 +94,13 @@ impl Executable for FunctionDecl { // Set the name and assign it in the current environment val.set_field("name", self.name()); - interpreter.realm_mut().environment.create_mutable_binding( + context.realm_mut().environment.create_mutable_binding( self.name().to_owned(), false, VariableScope::Function, ); - interpreter + context .realm_mut() .environment .initialize_binding(self.name(), val); diff --git a/boa/src/syntax/ast/node/declaration/function_expr/mod.rs b/boa/src/syntax/ast/node/declaration/function_expr/mod.rs index d2749b9a95..0b40157a2c 100644 --- a/boa/src/syntax/ast/node/declaration/function_expr/mod.rs +++ b/boa/src/syntax/ast/node/declaration/function_expr/mod.rs @@ -1,10 +1,10 @@ use crate::{ builtins::function::FunctionFlags, exec::Executable, + gc::{Finalize, Trace}, syntax::ast::node::{join_nodes, FormalParameter, Node, StatementList}, Context, Result, Value, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -85,8 +85,8 @@ impl FunctionExpr { } impl Executable for FunctionExpr { - fn run(&self, interpreter: &mut Context) -> Result { - let val = interpreter.create_function( + fn run(&self, context: &mut Context) -> Result { + let val = context.create_function( self.parameters().to_vec(), self.body().to_vec(), FunctionFlags::CALLABLE | FunctionFlags::CONSTRUCTABLE, diff --git a/boa/src/syntax/ast/node/declaration/let_decl_list/mod.rs b/boa/src/syntax/ast/node/declaration/let_decl_list/mod.rs index 064492611a..d505305ca6 100644 --- a/boa/src/syntax/ast/node/declaration/let_decl_list/mod.rs +++ b/boa/src/syntax/ast/node/declaration/let_decl_list/mod.rs @@ -1,10 +1,10 @@ use crate::{ environment::lexical_environment::VariableScope, exec::Executable, + gc::{Finalize, Trace}, syntax::ast::node::{join_nodes, Identifier, Node}, Context, Result, Value, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -35,18 +35,18 @@ pub struct LetDeclList { } impl Executable for LetDeclList { - fn run(&self, interpreter: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { for var in self.as_ref() { let val = match var.init() { - Some(v) => v.run(interpreter)?, + Some(v) => v.run(context)?, None => Value::undefined(), }; - interpreter.realm_mut().environment.create_mutable_binding( + context.realm_mut().environment.create_mutable_binding( var.name().to_owned(), false, VariableScope::Block, ); - interpreter + context .realm_mut() .environment .initialize_binding(var.name(), val); diff --git a/boa/src/syntax/ast/node/declaration/var_decl_list/mod.rs b/boa/src/syntax/ast/node/declaration/var_decl_list/mod.rs index 07023293d8..3f79348e1a 100644 --- a/boa/src/syntax/ast/node/declaration/var_decl_list/mod.rs +++ b/boa/src/syntax/ast/node/declaration/var_decl_list/mod.rs @@ -1,10 +1,10 @@ use crate::{ environment::lexical_environment::VariableScope, exec::Executable, + gc::{Finalize, Trace}, syntax::ast::node::{join_nodes, Identifier, Node}, Context, Result, Value, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -36,13 +36,13 @@ pub struct VarDeclList { } impl Executable for VarDeclList { - fn run(&self, interpreter: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { for var in self.as_ref() { let val = match var.init() { - Some(v) => v.run(interpreter)?, + Some(v) => v.run(context)?, None => Value::undefined(), }; - let environment = &mut interpreter.realm_mut().environment; + let environment = &mut context.realm_mut().environment; if environment.has_binding(var.name()) { if var.init().is_some() { diff --git a/boa/src/syntax/ast/node/field/get_const_field/mod.rs b/boa/src/syntax/ast/node/field/get_const_field/mod.rs index daa8c5e540..48be278b33 100644 --- a/boa/src/syntax/ast/node/field/get_const_field/mod.rs +++ b/boa/src/syntax/ast/node/field/get_const_field/mod.rs @@ -1,10 +1,10 @@ use crate::{ exec::Executable, + gc::{Finalize, Trace}, syntax::ast::node::Node, value::{Type, Value}, Context, Result, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -63,10 +63,10 @@ impl GetConstField { } impl Executable for GetConstField { - fn run(&self, interpreter: &mut Context) -> Result { - let mut obj = self.obj().run(interpreter)?; + fn run(&self, context: &mut Context) -> Result { + let mut obj = self.obj().run(context)?; if obj.get_type() != Type::Object { - obj = Value::Object(obj.to_object(interpreter)?); + obj = Value::Object(obj.to_object(context)?); } Ok(obj.get_field(self.field())) diff --git a/boa/src/syntax/ast/node/field/get_field/mod.rs b/boa/src/syntax/ast/node/field/get_field/mod.rs index b418e46efc..d8a118ab1a 100644 --- a/boa/src/syntax/ast/node/field/get_field/mod.rs +++ b/boa/src/syntax/ast/node/field/get_field/mod.rs @@ -1,10 +1,10 @@ use crate::{ exec::Executable, + gc::{Finalize, Trace}, syntax::ast::node::Node, value::{Type, Value}, Context, Result, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -62,14 +62,14 @@ impl GetField { } impl Executable for GetField { - fn run(&self, interpreter: &mut Context) -> Result { - let mut obj = self.obj().run(interpreter)?; + fn run(&self, context: &mut Context) -> Result { + let mut obj = self.obj().run(context)?; if obj.get_type() != Type::Object { - obj = Value::Object(obj.to_object(interpreter)?); + obj = Value::Object(obj.to_object(context)?); } - let field = self.field().run(interpreter)?; + let field = self.field().run(context)?; - Ok(obj.get_field(field.to_property_key(interpreter)?)) + Ok(obj.get_field(field.to_property_key(context)?)) } } diff --git a/boa/src/syntax/ast/node/identifier/mod.rs b/boa/src/syntax/ast/node/identifier/mod.rs index fe0378d1b6..0b89d21552 100644 --- a/boa/src/syntax/ast/node/identifier/mod.rs +++ b/boa/src/syntax/ast/node/identifier/mod.rs @@ -1,7 +1,11 @@ //! Local identifier node. -use crate::{exec::Executable, syntax::ast::node::Node, Context, Result, Value}; -use gc::{Finalize, Trace}; +use crate::{ + exec::Executable, + gc::{Finalize, Trace}, + syntax::ast::node::Node, + Context, Result, Value, +}; use std::fmt; #[cfg(feature = "serde")] @@ -31,12 +35,12 @@ pub struct Identifier { } impl Executable for Identifier { - fn run(&self, interpreter: &mut Context) -> Result { - interpreter + fn run(&self, context: &mut Context) -> Result { + context .realm() .environment .get_binding_value(self.as_ref()) - .ok_or_else(|| interpreter.construct_reference_error(self.as_ref())) + .ok_or_else(|| context.construct_reference_error(self.as_ref())) } } diff --git a/boa/src/syntax/ast/node/iteration/continue_node/mod.rs b/boa/src/syntax/ast/node/iteration/continue_node/mod.rs index a551ccdb16..9b2434d390 100644 --- a/boa/src/syntax/ast/node/iteration/continue_node/mod.rs +++ b/boa/src/syntax/ast/node/iteration/continue_node/mod.rs @@ -1,9 +1,9 @@ use crate::{ exec::{Executable, InterpreterState}, + gc::{Finalize, Trace}, syntax::ast::node::Node, Context, Result, Value, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -46,8 +46,8 @@ impl Continue { } impl Executable for Continue { - fn run(&self, interpreter: &mut Context) -> Result { - interpreter + fn run(&self, context: &mut Context) -> Result { + context .executor() .set_current_state(InterpreterState::Continue(self.label().map(Box::from))); diff --git a/boa/src/syntax/ast/node/iteration/do_while_loop/mod.rs b/boa/src/syntax/ast/node/iteration/do_while_loop/mod.rs index 9ebf49f702..4c7c17cde3 100644 --- a/boa/src/syntax/ast/node/iteration/do_while_loop/mod.rs +++ b/boa/src/syntax/ast/node/iteration/do_while_loop/mod.rs @@ -1,9 +1,9 @@ use crate::{ exec::{Executable, InterpreterState}, + gc::{Finalize, Trace}, syntax::ast::node::Node, Context, Result, Value, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -67,21 +67,21 @@ impl DoWhileLoop { } impl Executable for DoWhileLoop { - fn run(&self, interpreter: &mut Context) -> Result { - let mut result = self.body().run(interpreter)?; - match interpreter.executor().get_current_state() { + fn run(&self, context: &mut Context) -> Result { + let mut result = self.body().run(context)?; + match context.executor().get_current_state() { InterpreterState::Break(_label) => { // TODO break to label. // Loops 'consume' breaks. - interpreter + context .executor() .set_current_state(InterpreterState::Executing); return Ok(result); } InterpreterState::Continue(_label) => { // TODO continue to label; - interpreter + context .executor() .set_current_state(InterpreterState::Executing); // after breaking out of the block, continue execution of the loop @@ -94,21 +94,21 @@ impl Executable for DoWhileLoop { } } - while self.cond().run(interpreter)?.to_boolean() { - result = self.body().run(interpreter)?; - match interpreter.executor().get_current_state() { + while self.cond().run(context)?.to_boolean() { + result = self.body().run(context)?; + match context.executor().get_current_state() { InterpreterState::Break(_label) => { // TODO break to label. // Loops 'consume' breaks. - interpreter + context .executor() .set_current_state(InterpreterState::Executing); break; } InterpreterState::Continue(_label) => { // TODO continue to label. - interpreter + context .executor() .set_current_state(InterpreterState::Executing); // after breaking out of the block, continue execution of the loop diff --git a/boa/src/syntax/ast/node/iteration/for_loop/mod.rs b/boa/src/syntax/ast/node/iteration/for_loop/mod.rs index 8a8da1abed..4908ebb162 100644 --- a/boa/src/syntax/ast/node/iteration/for_loop/mod.rs +++ b/boa/src/syntax/ast/node/iteration/for_loop/mod.rs @@ -1,10 +1,10 @@ use crate::{ environment::lexical_environment::new_declarative_environment, exec::{Executable, InterpreterState}, + gc::{Finalize, Trace}, syntax::ast::node::Node, BoaProfiler, Context, Result, Value, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -98,35 +98,35 @@ impl ForLoop { } impl Executable for ForLoop { - fn run(&self, interpreter: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { // Create the block environment. let _timer = BoaProfiler::global().start_event("ForLoop", "exec"); { - let env = &mut interpreter.realm_mut().environment; + let env = &mut context.realm_mut().environment; env.push(new_declarative_environment(Some( env.get_current_environment_ref().clone(), ))); } if let Some(init) = self.init() { - init.run(interpreter)?; + init.run(context)?; } while self .condition() - .map(|cond| cond.run(interpreter).map(|v| v.to_boolean())) + .map(|cond| cond.run(context).map(|v| v.to_boolean())) .transpose()? .unwrap_or(true) { - let result = self.body().run(interpreter)?; + let result = self.body().run(context)?; - match interpreter.executor().get_current_state() { + match context.executor().get_current_state() { InterpreterState::Break(label) => { - handle_state_with_labels!(self, label, interpreter, break); + handle_state_with_labels!(self, label, context, break); break; } InterpreterState::Continue(label) => { - handle_state_with_labels!(self, label, interpreter, continue); + handle_state_with_labels!(self, label, context, continue); } InterpreterState::Return => { @@ -138,12 +138,12 @@ impl Executable for ForLoop { } if let Some(final_expr) = self.final_expr() { - final_expr.run(interpreter)?; + final_expr.run(context)?; } } // pop the block env - let _ = interpreter.realm_mut().environment.pop(); + let _ = context.realm_mut().environment.pop(); Ok(Value::undefined()) } diff --git a/boa/src/syntax/ast/node/iteration/for_of_loop/mod.rs b/boa/src/syntax/ast/node/iteration/for_of_loop/mod.rs index f076786bae..cc1b92ca5c 100644 --- a/boa/src/syntax/ast/node/iteration/for_of_loop/mod.rs +++ b/boa/src/syntax/ast/node/iteration/for_of_loop/mod.rs @@ -2,10 +2,10 @@ use crate::{ builtins::iterable::get_iterator, environment::lexical_environment::{new_declarative_environment, VariableScope}, exec::{Executable, InterpreterState}, + gc::{Finalize, Trace}, syntax::ast::node::Node, BoaProfiler, Context, Result, Value, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -65,20 +65,20 @@ impl From for Node { } impl Executable for ForOfLoop { - fn run(&self, interpreter: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("ForOf", "exec"); - let iterable = self.iterable().run(interpreter)?; - let iterator = get_iterator(interpreter, iterable)?; + let iterable = self.iterable().run(context)?; + let iterator = get_iterator(context, iterable)?; let mut result = Value::undefined(); loop { { - let env = &mut interpreter.realm_mut().environment; + let env = &mut context.realm_mut().environment; env.push(new_declarative_environment(Some( env.get_current_environment_ref().clone(), ))); } - let iterator_result = iterator.next(interpreter)?; + let iterator_result = iterator.next(context)?; if iterator_result.is_done() { break; } @@ -86,7 +86,7 @@ impl Executable for ForOfLoop { match self.variable() { Node::Identifier(ref name) => { - let environment = &mut interpreter.realm_mut().environment; + let environment = &mut context.realm_mut().environment; if environment.has_binding(name.as_ref()) { // Binding already exists @@ -102,10 +102,10 @@ impl Executable for ForOfLoop { } Node::VarDeclList(ref list) => match list.as_ref() { [var] => { - let environment = &mut interpreter.realm_mut().environment; + let environment = &mut context.realm_mut().environment; if var.init().is_some() { - return interpreter.throw_syntax_error("a declaration in the head of a for-of loop can't have an initializer"); + return context.throw_syntax_error("a declaration in the head of a for-of loop can't have an initializer"); } if environment.has_binding(var.name()) { @@ -120,17 +120,17 @@ impl Executable for ForOfLoop { } } _ => { - return interpreter.throw_syntax_error( + return context.throw_syntax_error( "only one variable can be declared in the head of a for-of loop", ) } }, Node::LetDeclList(ref list) => match list.as_ref() { [var] => { - let environment = &mut interpreter.realm_mut().environment; + let environment = &mut context.realm_mut().environment; if var.init().is_some() { - return interpreter.throw_syntax_error("a declaration in the head of a for-of loop can't have an initializer"); + return context.throw_syntax_error("a declaration in the head of a for-of loop can't have an initializer"); } environment.create_mutable_binding( @@ -141,17 +141,17 @@ impl Executable for ForOfLoop { environment.initialize_binding(var.name(), next_result); } _ => { - return interpreter.throw_syntax_error( + return context.throw_syntax_error( "only one variable can be declared in the head of a for-of loop", ) } }, Node::ConstDeclList(ref list) => match list.as_ref() { [var] => { - let environment = &mut interpreter.realm_mut().environment; + let environment = &mut context.realm_mut().environment; if var.init().is_some() { - return interpreter.throw_syntax_error("a declaration in the head of a for-of loop can't have an initializer"); + return context.throw_syntax_error("a declaration in the head of a for-of loop can't have an initializer"); } environment.create_immutable_binding( @@ -162,36 +162,36 @@ impl Executable for ForOfLoop { environment.initialize_binding(var.name(), next_result); } _ => { - return interpreter.throw_syntax_error( + return context.throw_syntax_error( "only one variable can be declared in the head of a for-of loop", ) } }, Node::Assign(_) => { - return interpreter.throw_syntax_error( + return context.throw_syntax_error( "a declaration in the head of a for-of loop can't have an initializer", ); } _ => { - return interpreter + return context .throw_syntax_error("unknown left hand side in head of for-of loop") } } - result = self.body().run(interpreter)?; - match interpreter.executor().get_current_state() { + result = self.body().run(context)?; + match context.executor().get_current_state() { InterpreterState::Break(_label) => { // TODO break to label. // Loops 'consume' breaks. - interpreter + context .executor() .set_current_state(InterpreterState::Executing); break; } InterpreterState::Continue(_label) => { // TODO continue to label. - interpreter + context .executor() .set_current_state(InterpreterState::Executing); // after breaking out of the block, continue execution of the loop @@ -201,7 +201,7 @@ impl Executable for ForOfLoop { // Continue execution. } } - let _ = interpreter.realm_mut().environment.pop(); + let _ = context.realm_mut().environment.pop(); } Ok(result) } diff --git a/boa/src/syntax/ast/node/iteration/tests.rs b/boa/src/syntax/ast/node/iteration/tests.rs index 7340eb3ce4..0cbaa55947 100644 --- a/boa/src/syntax/ast/node/iteration/tests.rs +++ b/boa/src/syntax/ast/node/iteration/tests.rs @@ -194,46 +194,46 @@ fn do_while_loop_continue() { #[test] fn for_of_loop_declaration() { - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = r#" var result = 0; for (i of [1, 2, 3]) { result = i; } "#; - engine.eval(scenario).unwrap(); - assert_eq!(&forward(&mut engine, "result"), "3"); - assert_eq!(&forward(&mut engine, "i"), "3"); + context.eval(scenario).unwrap(); + assert_eq!(&forward(&mut context, "result"), "3"); + assert_eq!(&forward(&mut context, "i"), "3"); } #[test] fn for_of_loop_var() { - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = r#" var result = 0; for (var i of [1, 2, 3]) { result = i; } "#; - engine.eval(scenario).unwrap(); - assert_eq!(&forward(&mut engine, "result"), "3"); - assert_eq!(&forward(&mut engine, "i"), "3"); + context.eval(scenario).unwrap(); + assert_eq!(&forward(&mut context, "result"), "3"); + assert_eq!(&forward(&mut context, "i"), "3"); } #[test] fn for_of_loop_let() { - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = r#" var result = 0; for (let i of [1, 2, 3]) { result = i; } "#; - engine.eval(scenario).unwrap(); - assert_eq!(&forward(&mut engine, "result"), "3"); + context.eval(scenario).unwrap(); + assert_eq!(&forward(&mut context, "result"), "3"); assert_eq!( &forward( - &mut engine, + &mut context, r#" try { i @@ -248,18 +248,18 @@ fn for_of_loop_let() { #[test] fn for_of_loop_const() { - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = r#" var result = 0; for (let i of [1, 2, 3]) { result = i; } "#; - engine.eval(scenario).unwrap(); - assert_eq!(&forward(&mut engine, "result"), "3"); + context.eval(scenario).unwrap(); + assert_eq!(&forward(&mut context, "result"), "3"); assert_eq!( &forward( - &mut engine, + &mut context, r#" try { i @@ -274,7 +274,7 @@ fn for_of_loop_const() { #[test] fn for_of_loop_break() { - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = r#" var result = 0; for (var i of [1, 2, 3]) { @@ -283,14 +283,14 @@ fn for_of_loop_break() { result = i } "#; - engine.eval(scenario).unwrap(); - assert_eq!(&forward(&mut engine, "result"), "1"); - assert_eq!(&forward(&mut engine, "i"), "2"); + context.eval(scenario).unwrap(); + assert_eq!(&forward(&mut context, "result"), "1"); + assert_eq!(&forward(&mut context, "i"), "2"); } #[test] fn for_of_loop_continue() { - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = r#" var result = 0; for (var i of [1, 2, 3]) { @@ -299,14 +299,14 @@ fn for_of_loop_continue() { result = i } "#; - engine.eval(scenario).unwrap(); - assert_eq!(&forward(&mut engine, "result"), "2"); - assert_eq!(&forward(&mut engine, "i"), "3"); + context.eval(scenario).unwrap(); + assert_eq!(&forward(&mut context, "result"), "2"); + assert_eq!(&forward(&mut context, "i"), "3"); } #[test] fn for_of_loop_return() { - let mut engine = Context::new(); + let mut context = Context::new(); let scenario = r#" function foo() { for (i of [1, 2, 3]) { @@ -315,8 +315,8 @@ fn for_of_loop_return() { } } "#; - engine.eval(scenario).unwrap(); - assert_eq!(&forward(&mut engine, "foo()"), "2"); + context.eval(scenario).unwrap(); + assert_eq!(&forward(&mut context, "foo()"), "2"); } #[test] diff --git a/boa/src/syntax/ast/node/iteration/while_loop/mod.rs b/boa/src/syntax/ast/node/iteration/while_loop/mod.rs index eb266f3742..ccd09ba8b9 100644 --- a/boa/src/syntax/ast/node/iteration/while_loop/mod.rs +++ b/boa/src/syntax/ast/node/iteration/while_loop/mod.rs @@ -1,9 +1,9 @@ use crate::{ exec::{Executable, InterpreterState}, + gc::{Finalize, Trace}, syntax::ast::node::Node, Context, Result, Value, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -65,17 +65,17 @@ impl WhileLoop { } impl Executable for WhileLoop { - fn run(&self, interpreter: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let mut result = Value::undefined(); - while self.cond().run(interpreter)?.to_boolean() { - result = self.expr().run(interpreter)?; - match interpreter.executor().get_current_state() { + while self.cond().run(context)?.to_boolean() { + result = self.expr().run(context)?; + match context.executor().get_current_state() { InterpreterState::Break(label) => { - handle_state_with_labels!(self, label, interpreter, break); + handle_state_with_labels!(self, label, context, break); break; } InterpreterState::Continue(label) => { - handle_state_with_labels!(self, label, interpreter, continue) + handle_state_with_labels!(self, label, context, continue) } InterpreterState::Return => { return Ok(result); diff --git a/boa/src/syntax/ast/node/mod.rs b/boa/src/syntax/ast/node/mod.rs index 70515bf144..760679165c 100644 --- a/boa/src/syntax/ast/node/mod.rs +++ b/boa/src/syntax/ast/node/mod.rs @@ -45,8 +45,11 @@ pub use self::{ try_node::{Catch, Finally, Try}, }; use super::Const; -use crate::{exec::Executable, BoaProfiler, Context, Result, Value}; -use gc::{unsafe_empty_trace, Finalize, Trace}; +use crate::{ + exec::Executable, + gc::{empty_trace, Finalize, Trace}, + BoaProfiler, Context, Result, Value, +}; use std::{ cmp::Ordering, fmt::{self, Display}, @@ -262,13 +265,13 @@ impl Node { } impl Executable for Node { - fn run(&self, interpreter: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("Executable", "exec"); match *self { - Node::AsyncFunctionDecl(ref decl) => decl.run(interpreter), - Node::AsyncFunctionExpr(ref function_expr) => function_expr.run(interpreter), - Node::AwaitExpr(ref expr) => expr.run(interpreter), - Node::Call(ref call) => call.run(interpreter), + Node::AsyncFunctionDecl(ref decl) => decl.run(context), + Node::AsyncFunctionExpr(ref function_expr) => function_expr.run(context), + Node::AwaitExpr(ref expr) => expr.run(context), + Node::Call(ref call) => call.run(context), Node::Const(Const::Null) => Ok(Value::null()), Node::Const(Const::Num(num)) => Ok(Value::rational(num)), Node::Const(Const::Int(num)) => Ok(Value::integer(num)), @@ -279,41 +282,41 @@ impl Executable for Node { // Do Const values need to be garbage collected? We no longer need them once we've generated Values Node::Const(Const::String(ref value)) => Ok(Value::string(value.to_string())), Node::Const(Const::Bool(value)) => Ok(Value::boolean(value)), - Node::Block(ref block) => block.run(interpreter), - Node::Identifier(ref identifier) => identifier.run(interpreter), - Node::GetConstField(ref get_const_field_node) => get_const_field_node.run(interpreter), - Node::GetField(ref get_field) => get_field.run(interpreter), - Node::WhileLoop(ref while_loop) => while_loop.run(interpreter), - Node::DoWhileLoop(ref do_while) => do_while.run(interpreter), - Node::ForLoop(ref for_loop) => for_loop.run(interpreter), - Node::ForOfLoop(ref for_of_loop) => for_of_loop.run(interpreter), - Node::If(ref if_smt) => if_smt.run(interpreter), - Node::ConditionalOp(ref op) => op.run(interpreter), - Node::Switch(ref switch) => switch.run(interpreter), - Node::Object(ref obj) => obj.run(interpreter), - Node::ArrayDecl(ref arr) => arr.run(interpreter), + Node::Block(ref block) => block.run(context), + Node::Identifier(ref identifier) => identifier.run(context), + Node::GetConstField(ref get_const_field_node) => get_const_field_node.run(context), + Node::GetField(ref get_field) => get_field.run(context), + Node::WhileLoop(ref while_loop) => while_loop.run(context), + Node::DoWhileLoop(ref do_while) => do_while.run(context), + Node::ForLoop(ref for_loop) => for_loop.run(context), + Node::ForOfLoop(ref for_of_loop) => for_of_loop.run(context), + Node::If(ref if_smt) => if_smt.run(context), + Node::ConditionalOp(ref op) => op.run(context), + Node::Switch(ref switch) => switch.run(context), + Node::Object(ref obj) => obj.run(context), + Node::ArrayDecl(ref arr) => arr.run(context), // - Node::FunctionDecl(ref decl) => decl.run(interpreter), + Node::FunctionDecl(ref decl) => decl.run(context), // - Node::FunctionExpr(ref function_expr) => function_expr.run(interpreter), - Node::ArrowFunctionDecl(ref decl) => decl.run(interpreter), - Node::BinOp(ref op) => op.run(interpreter), - Node::UnaryOp(ref op) => op.run(interpreter), - Node::New(ref call) => call.run(interpreter), - Node::Return(ref ret) => ret.run(interpreter), - Node::Throw(ref throw) => throw.run(interpreter), - Node::Assign(ref op) => op.run(interpreter), - Node::VarDeclList(ref decl) => decl.run(interpreter), - Node::LetDeclList(ref decl) => decl.run(interpreter), - Node::ConstDeclList(ref decl) => decl.run(interpreter), - Node::Spread(ref spread) => spread.run(interpreter), + Node::FunctionExpr(ref function_expr) => function_expr.run(context), + Node::ArrowFunctionDecl(ref decl) => decl.run(context), + Node::BinOp(ref op) => op.run(context), + Node::UnaryOp(ref op) => op.run(context), + Node::New(ref call) => call.run(context), + Node::Return(ref ret) => ret.run(context), + Node::Throw(ref throw) => throw.run(context), + Node::Assign(ref op) => op.run(context), + Node::VarDeclList(ref decl) => decl.run(context), + Node::LetDeclList(ref decl) => decl.run(context), + Node::ConstDeclList(ref decl) => decl.run(context), + Node::Spread(ref spread) => spread.run(context), Node::This => { // Will either return `this` binding or undefined - Ok(interpreter.realm().environment.get_this_binding()) + Ok(context.realm().environment.get_this_binding()) } - Node::Try(ref try_node) => try_node.run(interpreter), - Node::Break(ref break_node) => break_node.run(interpreter), - Node::Continue(ref continue_node) => continue_node.run(interpreter), + Node::Try(ref try_node) => try_node.run(context), + Node::Break(ref break_node) => break_node.run(context), + Node::Continue(ref continue_node) => continue_node.run(context), } } } @@ -552,5 +555,5 @@ pub enum MethodDefinitionKind { } unsafe impl Trace for MethodDefinitionKind { - unsafe_empty_trace!(); + empty_trace!(); } diff --git a/boa/src/syntax/ast/node/new/mod.rs b/boa/src/syntax/ast/node/new/mod.rs index 4a1d57a61f..5778d2e339 100644 --- a/boa/src/syntax/ast/node/new/mod.rs +++ b/boa/src/syntax/ast/node/new/mod.rs @@ -1,10 +1,10 @@ use crate::{ exec::Executable, + gc::{Finalize, Trace}, syntax::ast::node::{Call, Node}, value::Value, BoaProfiler, Context, Result, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -44,18 +44,18 @@ impl New { } impl Executable for New { - fn run(&self, interpreter: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("New", "exec"); - let func_object = self.expr().run(interpreter)?; + let func_object = self.expr().run(context)?; let mut v_args = Vec::with_capacity(self.args().len()); for arg in self.args() { - v_args.push(arg.run(interpreter)?); + v_args.push(arg.run(context)?); } match func_object { - Value::Object(ref object) => object.construct(&v_args, interpreter), - _ => interpreter + Value::Object(ref object) => object.construct(&v_args, context), + _ => context .throw_type_error(format!("{} is not a constructor", self.expr().to_string(),)), } } diff --git a/boa/src/syntax/ast/node/object/mod.rs b/boa/src/syntax/ast/node/object/mod.rs index aeab27f06a..4567dabb11 100644 --- a/boa/src/syntax/ast/node/object/mod.rs +++ b/boa/src/syntax/ast/node/object/mod.rs @@ -2,10 +2,10 @@ use crate::{ exec::Executable, + gc::{Finalize, Trace}, syntax::ast::node::{MethodDefinitionKind, Node, PropertyDefinition}, Context, Result, Value, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -71,8 +71,8 @@ impl Object { } impl Executable for Object { - fn run(&self, interpreter: &mut Context) -> Result { - let global_val = &interpreter + fn run(&self, context: &mut Context) -> Result { + let global_val = &context .realm() .environment .get_global_object() @@ -83,11 +83,11 @@ impl Executable for Object { for property in self.properties().iter() { match property { PropertyDefinition::Property(key, value) => { - obj.set_field(key.clone(), value.run(interpreter)?); + obj.set_field(key.clone(), value.run(context)?); } PropertyDefinition::MethodDefinition(kind, name, func) => { if let MethodDefinitionKind::Ordinary = kind { - obj.set_field(name.clone(), func.run(interpreter)?); + obj.set_field(name.clone(), func.run(context)?); } else { // TODO: Implement other types of MethodDefinitionKinds. //unimplemented!("other types of property method definitions."); diff --git a/boa/src/syntax/ast/node/operator/assign/mod.rs b/boa/src/syntax/ast/node/operator/assign/mod.rs index 6676f4829a..7c6332888a 100644 --- a/boa/src/syntax/ast/node/operator/assign/mod.rs +++ b/boa/src/syntax/ast/node/operator/assign/mod.rs @@ -1,8 +1,10 @@ use crate::{ - environment::lexical_environment::VariableScope, exec::Executable, syntax::ast::node::Node, + environment::lexical_environment::VariableScope, + exec::Executable, + gc::{Finalize, Trace}, + syntax::ast::node::Node, BoaProfiler, Context, Result, Value, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -51,12 +53,12 @@ impl Assign { } impl Executable for Assign { - fn run(&self, interpreter: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("Assign", "exec"); - let val = self.rhs().run(interpreter)?; + let val = self.rhs().run(context)?; match self.lhs() { Node::Identifier(ref name) => { - let environment = &mut interpreter.realm_mut().environment; + let environment = &mut context.realm_mut().environment; if environment.has_binding(name.as_ref()) { // Binding already exists @@ -71,13 +73,13 @@ impl Executable for Assign { } } Node::GetConstField(ref get_const_field) => { - let val_obj = get_const_field.obj().run(interpreter)?; + let val_obj = get_const_field.obj().run(context)?; val_obj.set_field(get_const_field.field(), val.clone()); } Node::GetField(ref get_field) => { - let object = get_field.obj().run(interpreter)?; - let field = get_field.field().run(interpreter)?; - let key = field.to_property_key(interpreter)?; + let object = get_field.obj().run(context)?; + let field = get_field.field().run(context)?; + let key = field.to_property_key(context)?; object.set_field(key, val.clone()); } _ => (), diff --git a/boa/src/syntax/ast/node/operator/bin_op/mod.rs b/boa/src/syntax/ast/node/operator/bin_op/mod.rs index 13d8de3c1f..4dffec0b60 100644 --- a/boa/src/syntax/ast/node/operator/bin_op/mod.rs +++ b/boa/src/syntax/ast/node/operator/bin_op/mod.rs @@ -1,12 +1,12 @@ use crate::{ exec::Executable, + gc::{Finalize, Trace}, syntax::ast::{ node::Node, op::{self, AssignOp, BitOp, CompOp, LogOp, NumOp}, }, Context, Result, Value, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -57,92 +57,92 @@ impl BinOp { } /// Runs the assignment operators. - fn run_assign(op: AssignOp, x: Value, y: Value, interpreter: &mut Context) -> Result { + fn run_assign(op: AssignOp, x: Value, y: Value, context: &mut Context) -> Result { match op { - AssignOp::Add => x.add(&y, interpreter), - AssignOp::Sub => x.sub(&y, interpreter), - AssignOp::Mul => x.mul(&y, interpreter), - AssignOp::Exp => x.pow(&y, interpreter), - AssignOp::Div => x.div(&y, interpreter), - AssignOp::Mod => x.rem(&y, interpreter), - AssignOp::And => x.bitand(&y, interpreter), - AssignOp::Or => x.bitor(&y, interpreter), - AssignOp::Xor => x.bitxor(&y, interpreter), - AssignOp::Shl => x.shl(&y, interpreter), - AssignOp::Shr => x.shr(&y, interpreter), - AssignOp::Ushr => x.ushr(&y, interpreter), + AssignOp::Add => x.add(&y, context), + AssignOp::Sub => x.sub(&y, context), + AssignOp::Mul => x.mul(&y, context), + AssignOp::Exp => x.pow(&y, context), + AssignOp::Div => x.div(&y, context), + AssignOp::Mod => x.rem(&y, context), + AssignOp::And => x.bitand(&y, context), + AssignOp::Or => x.bitor(&y, context), + AssignOp::Xor => x.bitxor(&y, context), + AssignOp::Shl => x.shl(&y, context), + AssignOp::Shr => x.shr(&y, context), + AssignOp::Ushr => x.ushr(&y, context), } } } impl Executable for BinOp { - fn run(&self, interpreter: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { match self.op() { op::BinOp::Num(op) => { - let x = self.lhs().run(interpreter)?; - let y = self.rhs().run(interpreter)?; + let x = self.lhs().run(context)?; + let y = self.rhs().run(context)?; match op { - NumOp::Add => x.add(&y, interpreter), - NumOp::Sub => x.sub(&y, interpreter), - NumOp::Mul => x.mul(&y, interpreter), - NumOp::Exp => x.pow(&y, interpreter), - NumOp::Div => x.div(&y, interpreter), - NumOp::Mod => x.rem(&y, interpreter), + NumOp::Add => x.add(&y, context), + NumOp::Sub => x.sub(&y, context), + NumOp::Mul => x.mul(&y, context), + NumOp::Exp => x.pow(&y, context), + NumOp::Div => x.div(&y, context), + NumOp::Mod => x.rem(&y, context), } } op::BinOp::Bit(op) => { - let x = self.lhs().run(interpreter)?; - let y = self.rhs().run(interpreter)?; + let x = self.lhs().run(context)?; + let y = self.rhs().run(context)?; match op { - BitOp::And => x.bitand(&y, interpreter), - BitOp::Or => x.bitor(&y, interpreter), - BitOp::Xor => x.bitxor(&y, interpreter), - BitOp::Shl => x.shl(&y, interpreter), - BitOp::Shr => x.shr(&y, interpreter), - BitOp::UShr => x.ushr(&y, interpreter), + BitOp::And => x.bitand(&y, context), + BitOp::Or => x.bitor(&y, context), + BitOp::Xor => x.bitxor(&y, context), + BitOp::Shl => x.shl(&y, context), + BitOp::Shr => x.shr(&y, context), + BitOp::UShr => x.ushr(&y, context), } } op::BinOp::Comp(op) => { - let x = self.lhs().run(interpreter)?; - let y = self.rhs().run(interpreter)?; + let x = self.lhs().run(context)?; + let y = self.rhs().run(context)?; Ok(Value::from(match op { - CompOp::Equal => x.equals(&y, interpreter)?, - CompOp::NotEqual => !x.equals(&y, interpreter)?, + CompOp::Equal => x.equals(&y, context)?, + CompOp::NotEqual => !x.equals(&y, context)?, CompOp::StrictEqual => x.strict_equals(&y), CompOp::StrictNotEqual => !x.strict_equals(&y), - CompOp::GreaterThan => x.gt(&y, interpreter)?, - CompOp::GreaterThanOrEqual => x.ge(&y, interpreter)?, - CompOp::LessThan => x.lt(&y, interpreter)?, - CompOp::LessThanOrEqual => x.le(&y, interpreter)?, + CompOp::GreaterThan => x.gt(&y, context)?, + CompOp::GreaterThanOrEqual => x.ge(&y, context)?, + CompOp::LessThan => x.lt(&y, context)?, + CompOp::LessThanOrEqual => x.le(&y, context)?, CompOp::In => { if !y.is_object() { - return interpreter.throw_type_error(format!( + return context.throw_type_error(format!( "right-hand side of 'in' should be an object, got {}", y.get_type().as_str() )); } - let key = x.to_property_key(interpreter)?; - interpreter.has_property(&y, &key) + let key = x.to_property_key(context)?; + context.has_property(&y, &key) } CompOp::InstanceOf => { if let Some(object) = y.as_object() { - let key = interpreter.well_known_symbols().has_instance_symbol(); + let key = context.well_known_symbols().has_instance_symbol(); - match object.get_method(interpreter, key)? { - Some(instance_of_handler) => instance_of_handler - .call(&y, &[x], interpreter)? - .to_boolean(), + match object.get_method(context, key)? { + Some(instance_of_handler) => { + instance_of_handler.call(&y, &[x], context)?.to_boolean() + } None if object.is_callable() => { - object.ordinary_has_instance(interpreter, &x)? + object.ordinary_has_instance(context, &x)? } None => { - return interpreter.throw_type_error( + return context.throw_type_error( "right-hand side of 'instanceof' is not callable", ); } } } else { - return interpreter.throw_type_error(format!( + return context.throw_type_error(format!( "right-hand side of 'instanceof' should be an object, got {}", y.get_type().as_str() )); @@ -155,25 +155,23 @@ impl Executable for BinOp { let to_bool = |value| bool::from(&value); Ok(match op { LogOp::And => Value::from( - to_bool(self.lhs().run(interpreter)?) - && to_bool(self.rhs().run(interpreter)?), + to_bool(self.lhs().run(context)?) && to_bool(self.rhs().run(context)?), ), LogOp::Or => Value::from( - to_bool(self.lhs().run(interpreter)?) - || to_bool(self.rhs().run(interpreter)?), + to_bool(self.lhs().run(context)?) || to_bool(self.rhs().run(context)?), ), }) } op::BinOp::Assign(op) => match self.lhs() { Node::Identifier(ref name) => { - let v_a = interpreter + let v_a = context .realm() .environment .get_binding_value(name.as_ref()) - .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_mut().environment.set_mutable_binding( + .ok_or_else(|| context.construct_reference_error(name.as_ref()))?; + let v_b = self.rhs().run(context)?; + let value = Self::run_assign(op, v_a, v_b, context)?; + context.realm_mut().environment.set_mutable_binding( name.as_ref(), value.clone(), true, @@ -181,18 +179,18 @@ impl Executable for BinOp { Ok(value) } Node::GetConstField(ref get_const_field) => { - let v_r_a = get_const_field.obj().run(interpreter)?; + let v_r_a = get_const_field.obj().run(context)?; let v_a = v_r_a.get_field(get_const_field.field()); - let v_b = self.rhs().run(interpreter)?; - let value = Self::run_assign(op, v_a, v_b, interpreter)?; + let v_b = self.rhs().run(context)?; + let value = Self::run_assign(op, v_a, v_b, context)?; v_r_a.set_field(get_const_field.field(), value.clone()); Ok(value) } _ => Ok(Value::undefined()), }, op::BinOp::Comma => { - self.lhs().run(interpreter)?; - Ok(self.rhs().run(interpreter)?) + self.lhs().run(context)?; + Ok(self.rhs().run(context)?) } } } diff --git a/boa/src/syntax/ast/node/operator/unary_op/mod.rs b/boa/src/syntax/ast/node/operator/unary_op/mod.rs index ec4931eb1c..9eb2b7feba 100644 --- a/boa/src/syntax/ast/node/operator/unary_op/mod.rs +++ b/boa/src/syntax/ast/node/operator/unary_op/mod.rs @@ -1,9 +1,9 @@ use crate::{ exec::Executable, + gc::{Finalize, Trace}, syntax::ast::{node::Node, op}, Context, Result, Value, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -48,35 +48,35 @@ impl UnaryOp { } impl Executable for UnaryOp { - fn run(&self, interpreter: &mut Context) -> Result { - let x = self.target().run(interpreter)?; + fn run(&self, context: &mut Context) -> Result { + let x = self.target().run(context)?; Ok(match self.op() { - op::UnaryOp::Minus => x.neg(interpreter)?, - op::UnaryOp::Plus => Value::from(x.to_number(interpreter)?), + op::UnaryOp::Minus => x.neg(context)?, + op::UnaryOp::Plus => Value::from(x.to_number(context)?), op::UnaryOp::IncrementPost => { let ret = x.clone(); - let result = x.to_number(interpreter)? + 1.0; - interpreter.set_value(self.target(), result.into())?; + let result = x.to_number(context)? + 1.0; + context.set_value(self.target(), result.into())?; ret } op::UnaryOp::IncrementPre => { - let result = x.to_number(interpreter)? + 1.0; - interpreter.set_value(self.target(), result.into())? + let result = x.to_number(context)? + 1.0; + context.set_value(self.target(), result.into())? } op::UnaryOp::DecrementPost => { let ret = x.clone(); - let result = x.to_number(interpreter)? - 1.0; - interpreter.set_value(self.target(), result.into())?; + let result = x.to_number(context)? - 1.0; + context.set_value(self.target(), result.into())?; ret } op::UnaryOp::DecrementPre => { - let result = x.to_number(interpreter)? - 1.0; - interpreter.set_value(self.target(), result.into())? + let result = x.to_number(context)? - 1.0; + context.set_value(self.target(), result.into())? } - op::UnaryOp::Not => x.not(interpreter)?.into(), + op::UnaryOp::Not => x.not(context)?.into(), op::UnaryOp::Tilde => { - let num_v_a = x.to_number(interpreter)?; + let num_v_a = x.to_number(context)?; Value::from(if num_v_a.is_nan() { -1 } else { @@ -89,13 +89,13 @@ impl Executable for UnaryOp { Node::GetConstField(ref get_const_field) => Value::boolean( get_const_field .obj() - .run(interpreter)? + .run(context)? .remove_property(get_const_field.field()), ), Node::GetField(ref get_field) => { - let obj = get_field.obj().run(interpreter)?; - let field = &get_field.field().run(interpreter)?; - let res = obj.remove_property(field.to_string(interpreter)?.as_str()); + let obj = get_field.obj().run(context)?; + let field = &get_field.field().run(context)?; + let res = obj.remove_property(field.to_string(context)?.as_str()); return Ok(Value::boolean(res)); } Node::Identifier(_) => Value::boolean(false), diff --git a/boa/src/syntax/ast/node/return_smt/mod.rs b/boa/src/syntax/ast/node/return_smt/mod.rs index d77f53a5ae..52eb7e19ef 100644 --- a/boa/src/syntax/ast/node/return_smt/mod.rs +++ b/boa/src/syntax/ast/node/return_smt/mod.rs @@ -1,9 +1,9 @@ use crate::{ exec::{Executable, InterpreterState}, + gc::{Finalize, Trace}, syntax::ast::node::Node, Context, Result, Value, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -58,13 +58,13 @@ impl Return { } impl Executable for Return { - fn run(&self, interpreter: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let result = match self.expr() { - Some(ref v) => v.run(interpreter), + Some(ref v) => v.run(context), None => Ok(Value::undefined()), }; // Set flag for return - interpreter + context .executor() .set_current_state(InterpreterState::Return); result diff --git a/boa/src/syntax/ast/node/spread/mod.rs b/boa/src/syntax/ast/node/spread/mod.rs index b07aef0dbe..7b49d46dd2 100644 --- a/boa/src/syntax/ast/node/spread/mod.rs +++ b/boa/src/syntax/ast/node/spread/mod.rs @@ -1,5 +1,9 @@ -use crate::{exec::Executable, syntax::ast::node::Node, Context, Result, Value}; -use gc::{Finalize, Trace}; +use crate::{ + exec::Executable, + gc::{Finalize, Trace}, + syntax::ast::node::Node, + Context, Result, Value, +}; use std::fmt; #[cfg(feature = "serde")] @@ -45,9 +49,9 @@ impl Spread { } impl Executable for Spread { - fn run(&self, interpreter: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { // TODO: for now we can do nothing but return the value as-is - self.val().run(interpreter) + self.val().run(context) } } diff --git a/boa/src/syntax/ast/node/statement_list/mod.rs b/boa/src/syntax/ast/node/statement_list/mod.rs index 4c8ab7cd27..1a09d642fd 100644 --- a/boa/src/syntax/ast/node/statement_list/mod.rs +++ b/boa/src/syntax/ast/node/statement_list/mod.rs @@ -2,13 +2,11 @@ use crate::{ exec::{Executable, InterpreterState}, + gc::{empty_trace, Finalize, Trace}, syntax::ast::node::Node, BoaProfiler, Context, Result, Value, }; -use gc::{unsafe_empty_trace, Finalize, Trace}; -use std::fmt; -use std::ops::Deref; -use std::rc::Rc; +use std::{fmt, ops::Deref, rc::Rc}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -57,18 +55,18 @@ impl StatementList { } impl Executable for StatementList { - fn run(&self, interpreter: &mut Context) -> Result { + fn run(&self, context: &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 + context .executor() .set_current_state(InterpreterState::Executing); for (i, item) in self.statements().iter().enumerate() { - let val = item.run(interpreter)?; - match interpreter.executor().get_current_state() { + let val = item.run(context)?; + match context.executor().get_current_state() { InterpreterState::Return => { // Early return. obj = val; @@ -133,5 +131,5 @@ impl From for RcStatementList { // SAFETY: This is safe for types not containing any `Trace` types. unsafe impl Trace for RcStatementList { - unsafe_empty_trace!(); + empty_trace!(); } diff --git a/boa/src/syntax/ast/node/switch/mod.rs b/boa/src/syntax/ast/node/switch/mod.rs index 42d1f9df7a..913032fc85 100644 --- a/boa/src/syntax/ast/node/switch/mod.rs +++ b/boa/src/syntax/ast/node/switch/mod.rs @@ -2,10 +2,10 @@ //! use crate::{ exec::{Executable, InterpreterState}, + gc::{Finalize, Trace}, syntax::ast::node::Node, Context, Result, Value, }; -use gc::{Finalize, Trace}; use std::fmt; use crate::syntax::ast::node::StatementList; @@ -122,11 +122,11 @@ impl Switch { } impl Executable for Switch { - fn run(&self, interpreter: &mut Context) -> Result { - let val = self.val().run(interpreter)?; + fn run(&self, context: &mut Context) -> Result { + let val = self.val().run(context)?; let mut result = Value::null(); let mut matched = false; - interpreter + context .executor() .set_current_state(InterpreterState::Executing); @@ -137,10 +137,10 @@ impl Executable for Switch { for case in self.cases().iter() { let cond = case.condition(); let block = case.body(); - if fall_through || val.strict_equals(&cond.run(interpreter)?) { + if fall_through || val.strict_equals(&cond.run(context)?) { matched = true; - let result = block.run(interpreter)?; - match interpreter.executor().get_current_state() { + let result = block.run(context)?; + match context.executor().get_current_state() { InterpreterState::Return => { // Early return. return Ok(result); @@ -148,7 +148,7 @@ impl Executable for Switch { InterpreterState::Break(_label) => { // TODO, break to a label. // Break statement encountered so therefore end switch statement. - interpreter + context .executor() .set_current_state(InterpreterState::Executing); break; @@ -167,12 +167,12 @@ impl Executable for Switch { if !matched { if let Some(default) = self.default() { - interpreter + context .executor() .set_current_state(InterpreterState::Executing); for (i, item) in default.iter().enumerate() { - let val = item.run(interpreter)?; - match interpreter.executor().get_current_state() { + let val = item.run(context)?; + match context.executor().get_current_state() { InterpreterState::Return => { // Early return. result = val; diff --git a/boa/src/syntax/ast/node/throw/mod.rs b/boa/src/syntax/ast/node/throw/mod.rs index 38d04ce2bc..beef352a7d 100644 --- a/boa/src/syntax/ast/node/throw/mod.rs +++ b/boa/src/syntax/ast/node/throw/mod.rs @@ -1,5 +1,9 @@ -use crate::{exec::Executable, syntax::ast::node::Node, Context, Result, Value}; -use gc::{Finalize, Trace}; +use crate::{ + exec::Executable, + gc::{Finalize, Trace}, + syntax::ast::node::Node, + Context, Result, Value, +}; use std::fmt; #[cfg(feature = "serde")] @@ -43,8 +47,8 @@ impl Throw { impl Executable for Throw { #[inline] - fn run(&self, interpreter: &mut Context) -> Result { - Err(self.expr().run(interpreter)?) + fn run(&self, context: &mut Context) -> Result { + Err(self.expr().run(context)?) } } diff --git a/boa/src/syntax/ast/node/try_node/mod.rs b/boa/src/syntax/ast/node/try_node/mod.rs index 77cca0b4a5..8071b5784e 100644 --- a/boa/src/syntax/ast/node/try_node/mod.rs +++ b/boa/src/syntax/ast/node/try_node/mod.rs @@ -1,10 +1,10 @@ use crate::{ environment::lexical_environment::{new_declarative_environment, VariableScope}, exec::Executable, + gc::{Finalize, Trace}, syntax::ast::node::{Block, Identifier, Node}, BoaProfiler, Context, Result, Value, }; -use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] @@ -92,13 +92,13 @@ impl Try { } impl Executable for Try { - fn run(&self, interpreter: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("Try", "exec"); - let res = self.block().run(interpreter).map_or_else( + let res = self.block().run(context).map_or_else( |err| { if let Some(catch) = self.catch() { { - let env = &mut interpreter.realm_mut().environment; + let env = &mut context.realm_mut().environment; env.push(new_declarative_environment(Some( env.get_current_environment_ref().clone(), ))); @@ -114,10 +114,10 @@ impl Executable for Try { } } - let res = catch.block().run(interpreter); + let res = catch.block().run(context); // pop the block env - let _ = interpreter.realm_mut().environment.pop(); + let _ = context.realm_mut().environment.pop(); res } else { @@ -128,7 +128,7 @@ impl Executable for Try { ); if let Some(finally) = self.finally() { - finally.run(interpreter)?; + finally.run(context)?; } res diff --git a/boa/src/syntax/ast/op.rs b/boa/src/syntax/ast/op.rs index ba49caff36..a1d3a084c3 100644 --- a/boa/src/syntax/ast/op.rs +++ b/boa/src/syntax/ast/op.rs @@ -1,6 +1,6 @@ //! This module implements various structure for logic handling. -use gc::{unsafe_empty_trace, Finalize, Trace}; +use crate::gc::{empty_trace, Finalize, Trace}; use std::fmt::{Display, Formatter, Result}; #[cfg(feature = "serde")] @@ -113,7 +113,7 @@ impl Display for NumOp { } unsafe impl Trace for NumOp { - unsafe_empty_trace!(); + empty_trace!(); } /// A unary operator is one that takes a single operand/argument and performs an operation. @@ -329,7 +329,7 @@ impl Display for UnaryOp { } unsafe impl Trace for UnaryOp { - unsafe_empty_trace!(); + empty_trace!(); } /// A bitwise operator is an operator used to perform bitwise operations @@ -444,7 +444,7 @@ impl Display for BitOp { } unsafe impl Trace for BitOp { - unsafe_empty_trace!(); + empty_trace!(); } /// A comparison operator compares its operands and returns a logical value based on whether the comparison is true. @@ -641,7 +641,7 @@ impl Display for CompOp { } unsafe impl Trace for CompOp { - unsafe_empty_trace!(); + empty_trace!(); } /// Logical operators are typically used with Boolean (logical) values; when they are, they return a Boolean value. @@ -699,7 +699,7 @@ impl Display for LogOp { } unsafe impl Trace for LogOp { - unsafe_empty_trace!(); + empty_trace!(); } /// This represents a binary operation between two values. @@ -783,7 +783,7 @@ impl Display for BinOp { } unsafe impl Trace for BinOp { - unsafe_empty_trace!(); + empty_trace!(); } /// An assignment operator assigns a value to its left operand based on the value of its right operand. @@ -953,7 +953,7 @@ pub enum AssignOp { } unsafe impl Trace for AssignOp { - unsafe_empty_trace!(); + empty_trace!(); } impl Display for AssignOp { diff --git a/boa/src/value/equality.rs b/boa/src/value/equality.rs index 7cb09bf5e7..86b8adbe17 100644 --- a/boa/src/value/equality.rs +++ b/boa/src/value/equality.rs @@ -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 Context) -> Result { + pub fn equals(&self, other: &Self, context: &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() { @@ -59,8 +59,8 @@ impl Value { | (Self::String(_), Self::Rational(_)) | (Self::Rational(_), Self::Boolean(_)) | (Self::Integer(_), Self::Boolean(_)) => { - let x = self.to_number(interpreter)?; - let y = other.to_number(interpreter)?; + let x = self.to_number(context)?; + let y = other.to_number(context)?; Number::equal(x, y) } @@ -80,23 +80,23 @@ impl Value { }, // 8. If Type(x) is Boolean, return the result of the comparison ! ToNumber(x) == y. - (Self::Boolean(x), _) => return other.equals(&Value::from(*x as i32), interpreter), + (Self::Boolean(x), _) => return other.equals(&Value::from(*x as i32), context), // 9. If Type(y) is Boolean, return the result of the comparison x == ! ToNumber(y). - (_, Self::Boolean(y)) => return self.equals(&Value::from(*y as i32), interpreter), + (_, Self::Boolean(y)) => return self.equals(&Value::from(*y as i32), context), // 10. If Type(x) is either String, Number, BigInt, or Symbol and Type(y) is Object, return the result // of the comparison x == ? ToPrimitive(y). (Self::Object(_), _) => { - let primitive = self.to_primitive(interpreter, PreferredType::Default)?; - return primitive.equals(other, interpreter); + let primitive = self.to_primitive(context, PreferredType::Default)?; + return primitive.equals(other, context); } // 11. If Type(x) is Object and Type(y) is either String, Number, BigInt, or Symbol, return the result // of the comparison ? ToPrimitive(x) == y. (_, Self::Object(_)) => { - let primitive = other.to_primitive(interpreter, PreferredType::Default)?; - return primitive.equals(self, interpreter); + let primitive = other.to_primitive(context, PreferredType::Default)?; + return primitive.equals(self, context); } // 12. If Type(x) is BigInt and Type(y) is Number, or if Type(x) is Number and Type(y) is BigInt, then diff --git a/boa/src/value/mod.rs b/boa/src/value/mod.rs index b5e9832c6f..1793e55acb 100644 --- a/boa/src/value/mod.rs +++ b/boa/src/value/mod.rs @@ -215,24 +215,24 @@ impl Value { } /// Converts the `Value` to `JSON`. - pub fn to_json(&self, interpreter: &mut Context) -> Result { + pub fn to_json(&self, context: &mut Context) -> Result { let to_json = self.get_field("toJSON"); if to_json.is_function() { - let json_value = interpreter.call(&to_json, self, &[])?; - return json_value.to_json(interpreter); + let json_value = context.call(&to_json, self, &[])?; + return json_value.to_json(context); } match *self { Self::Null => Ok(JSONValue::Null), Self::Boolean(b) => Ok(JSONValue::Bool(b)), - Self::Object(ref obj) => obj.to_json(interpreter), + Self::Object(ref obj) => obj.to_json(context), Self::String(ref str) => Ok(JSONValue::String(str.to_string())), Self::Rational(num) => Ok(JSONValue::Number( JSONNumber::from_str(&Number::to_native_string(num)).unwrap(), )), Self::Integer(val) => Ok(JSONValue::Number(JSONNumber::from(val))), Self::BigInt(_) => { - Err(interpreter.construct_type_error("BigInt value can't be serialized in JSON")) + Err(context.construct_type_error("BigInt value can't be serialized in JSON")) } Self::Symbol(_) | Self::Undefined => { unreachable!("Symbols and Undefined JSON Values depend on parent type"); @@ -523,7 +523,11 @@ impl Value { /// The abstract operation ToPrimitive takes an input argument and an optional argument PreferredType. /// /// - pub fn to_primitive(&self, ctx: &mut Context, preferred_type: PreferredType) -> Result { + pub fn to_primitive( + &self, + context: &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(obj) = self { @@ -537,7 +541,7 @@ impl Value { }; // g. Return ? OrdinaryToPrimitive(input, hint). - obj.ordinary_to_primitive(ctx, hint) + obj.ordinary_to_primitive(context, hint) } else { // 3. Return input. Ok(self.clone()) @@ -547,13 +551,13 @@ impl Value { /// Converts the value to a `BigInt`. /// /// This function is equivelent to `BigInt(value)` in JavaScript. - pub fn to_bigint(&self, ctx: &mut Context) -> Result { + pub fn to_bigint(&self, context: &mut Context) -> Result { match self { - Value::Null => Err(ctx.construct_type_error("cannot convert null to a BigInt")), + Value::Null => Err(context.construct_type_error("cannot convert null to a BigInt")), Value::Undefined => { - Err(ctx.construct_type_error("cannot convert undefined to a BigInt")) + Err(context.construct_type_error("cannot convert undefined to a BigInt")) } - Value::String(ref string) => Ok(RcBigInt::from(BigInt::from_string(string, ctx)?)), + Value::String(ref string) => Ok(RcBigInt::from(BigInt::from_string(string, context)?)), Value::Boolean(true) => Ok(RcBigInt::from(BigInt::from(1))), Value::Boolean(false) => Ok(RcBigInt::from(BigInt::from(0))), Value::Integer(num) => Ok(RcBigInt::from(BigInt::from(*num))), @@ -561,17 +565,19 @@ impl Value { if let Ok(bigint) = BigInt::try_from(*num) { return Ok(RcBigInt::from(bigint)); } - Err(ctx.construct_type_error(format!( + Err(context.construct_type_error(format!( "The number {} cannot be converted to a BigInt because it is not an integer", num ))) } Value::BigInt(b) => Ok(b.clone()), Value::Object(_) => { - let primitive = self.to_primitive(ctx, PreferredType::Number)?; - primitive.to_bigint(ctx) + let primitive = self.to_primitive(context, PreferredType::Number)?; + primitive.to_bigint(context) + } + Value::Symbol(_) => { + Err(context.construct_type_error("cannot convert Symbol to a BigInt")) } - Value::Symbol(_) => Err(ctx.construct_type_error("cannot convert Symbol to a BigInt")), } } @@ -594,7 +600,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 Context) -> Result { + pub fn to_string(&self, context: &mut Context) -> Result { match self { Value::Null => Ok("null".into()), Value::Undefined => Ok("undefined".into()), @@ -602,11 +608,11 @@ impl Value { Value::Rational(rational) => Ok(Number::to_native_string(*rational).into()), Value::Integer(integer) => Ok(integer.to_string().into()), Value::String(string) => Ok(string.clone()), - Value::Symbol(_) => Err(ctx.construct_type_error("can't convert symbol to string")), + Value::Symbol(_) => Err(context.construct_type_error("can't convert symbol to string")), Value::BigInt(ref bigint) => Ok(bigint.to_string().into()), Value::Object(_) => { - let primitive = self.to_primitive(ctx, PreferredType::String)?; - primitive.to_string(ctx) + let primitive = self.to_primitive(context, PreferredType::String)?; + primitive.to_string(context) } } } @@ -616,34 +622,34 @@ impl Value { /// This function is equivalent to `Object(value)` in JavaScript /// /// See: - pub fn to_object(&self, ctx: &mut Context) -> Result { + pub fn to_object(&self, context: &mut Context) -> Result { match self { Value::Undefined | Value::Null => { - Err(ctx.construct_type_error("cannot convert 'null' or 'undefined' to object")) + Err(context.construct_type_error("cannot convert 'null' or 'undefined' to object")) } Value::Boolean(boolean) => { - let prototype = ctx.standard_objects().boolean_object().prototype(); + let prototype = context.standard_objects().boolean_object().prototype(); Ok(GcObject::new(Object::with_prototype( prototype.into(), ObjectData::Boolean(*boolean), ))) } Value::Integer(integer) => { - let prototype = ctx.standard_objects().number_object().prototype(); + let prototype = context.standard_objects().number_object().prototype(); Ok(GcObject::new(Object::with_prototype( prototype.into(), ObjectData::Number(f64::from(*integer)), ))) } Value::Rational(rational) => { - let prototype = ctx.standard_objects().number_object().prototype(); + let prototype = context.standard_objects().number_object().prototype(); Ok(GcObject::new(Object::with_prototype( prototype.into(), ObjectData::Number(*rational), ))) } Value::String(ref string) => { - let prototype = ctx.standard_objects().string_object().prototype(); + let prototype = context.standard_objects().string_object().prototype(); let mut object = GcObject::new(Object::with_prototype( prototype.into(), @@ -654,14 +660,14 @@ impl Value { Ok(object) } Value::Symbol(ref symbol) => { - let prototype = ctx.standard_objects().symbol_object().prototype(); + let prototype = context.standard_objects().symbol_object().prototype(); Ok(GcObject::new(Object::with_prototype( prototype.into(), ObjectData::Symbol(symbol.clone()), ))) } Value::BigInt(ref bigint) => { - let prototype = ctx.standard_objects().bigint_object().prototype(); + let prototype = context.standard_objects().bigint_object().prototype(); Ok(GcObject::new(Object::with_prototype( prototype.into(), ObjectData::BigInt(bigint.clone()), @@ -674,16 +680,16 @@ 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 Context) -> Result { + pub fn to_property_key(&self, context: &mut Context) -> Result { Ok(match self { // Fast path: Value::String(string) => string.clone().into(), Value::Symbol(symbol) => symbol.clone().into(), // Slow path: - _ => match self.to_primitive(ctx, PreferredType::String)? { + _ => match self.to_primitive(context, PreferredType::String)? { Value::String(ref string) => string.clone().into(), Value::Symbol(ref symbol) => symbol.clone().into(), - primitive => primitive.to_string(ctx)?.into(), + primitive => primitive.to_string(context)?.into(), }, }) } @@ -691,12 +697,12 @@ impl Value { /// It returns value converted to a numeric value of type `Number` or `BigInt`. /// /// See: - pub fn to_numeric(&self, ctx: &mut Context) -> Result { - let primitive = self.to_primitive(ctx, PreferredType::Number)?; + pub fn to_numeric(&self, context: &mut Context) -> Result { + let primitive = self.to_primitive(context, PreferredType::Number)?; if let Some(bigint) = primitive.as_bigint() { return Ok(bigint.clone().into()); } - Ok(self.to_number(ctx)?.into()) + Ok(self.to_number(context)?.into()) } /// Converts a value to an integral 32 bit unsigned integer. @@ -704,12 +710,12 @@ impl Value { /// This function is equivalent to `value | 0` in JavaScript /// /// See: - pub fn to_u32(&self, ctx: &mut Context) -> Result { + pub fn to_u32(&self, context: &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); } - let number = self.to_number(ctx)?; + let number = self.to_number(context)?; Ok(f64_to_uint32(number)) } @@ -717,12 +723,12 @@ impl Value { /// Converts a value to an integral 32 bit signed integer. /// /// See: - pub fn to_i32(&self, ctx: &mut Context) -> Result { + pub fn to_i32(&self, context: &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); } - let number = self.to_number(ctx)?; + let number = self.to_number(context)?; Ok(f64_to_int32(number)) } @@ -730,19 +736,21 @@ 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 Context) -> Result { + pub fn to_index(&self, context: &mut Context) -> Result { if self.is_undefined() { return Ok(0); } - let integer_index = self.to_integer(ctx)?; + let integer_index = self.to_integer(context)?; if integer_index < 0.0 { - return Err(ctx.construct_range_error("Integer index must be >= 0")); + return Err(context.construct_range_error("Integer index must be >= 0")); } if integer_index > Number::MAX_SAFE_INTEGER { - return Err(ctx.construct_range_error("Integer index must be less than 2**(53) - 1")); + return Err( + context.construct_range_error("Integer index must be less than 2**(53) - 1") + ); } Ok(integer_index as usize) @@ -751,9 +759,9 @@ 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 Context) -> Result { + pub fn to_length(&self, context: &mut Context) -> Result { // 1. Let len be ? ToInteger(argument). - let len = self.to_integer(ctx)?; + let len = self.to_integer(context)?; // 2. If len ≤ +0, return +0. if len < 0.0 { @@ -767,9 +775,9 @@ impl Value { /// Converts a value to an integral Number value. /// /// See: - pub fn to_integer(&self, ctx: &mut Context) -> Result { + pub fn to_integer(&self, context: &mut Context) -> Result { // 1. Let number be ? ToNumber(argument). - let number = self.to_number(ctx)?; + let number = self.to_number(context)?; // 2. If number is +∞ or -∞, return number. if !number.is_finite() { @@ -791,7 +799,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 Context) -> Result { + pub fn to_number(&self, context: &mut Context) -> Result { match *self { Value::Null => Ok(0.0), Value::Undefined => Ok(f64::NAN), @@ -805,11 +813,11 @@ impl Value { } Value::Rational(number) => Ok(number), Value::Integer(integer) => Ok(f64::from(integer)), - Value::Symbol(_) => Err(ctx.construct_type_error("argument must not be a symbol")), - Value::BigInt(_) => Err(ctx.construct_type_error("argument must not be a bigint")), + Value::Symbol(_) => Err(context.construct_type_error("argument must not be a symbol")), + Value::BigInt(_) => Err(context.construct_type_error("argument must not be a bigint")), Value::Object(_) => { - let primitive = self.to_primitive(ctx, PreferredType::Number)?; - primitive.to_number(ctx) + let primitive = self.to_primitive(context, PreferredType::Number)?; + primitive.to_number(context) } } } @@ -819,12 +827,12 @@ impl Value { /// This function is equivalent to `Number(value)` in JavaScript /// /// See: - pub fn to_numeric_number(&self, ctx: &mut Context) -> Result { - let primitive = self.to_primitive(ctx, PreferredType::Number)?; + pub fn to_numeric_number(&self, context: &mut Context) -> Result { + let primitive = self.to_primitive(context, PreferredType::Number)?; if let Some(ref bigint) = primitive.as_bigint() { return Ok(bigint.to_f64()); } - primitive.to_number(ctx) + primitive.to_number(context) } /// Check if the `Value` can be converted to an `Object` @@ -839,9 +847,9 @@ impl Value { /// [table]: https://tc39.es/ecma262/#table-14 /// [spec]: https://tc39.es/ecma262/#sec-requireobjectcoercible #[inline] - pub fn require_object_coercible(&self, ctx: &mut Context) -> Result<&Value> { + pub fn require_object_coercible(&self, context: &mut Context) -> Result<&Value> { if self.is_null_or_undefined() { - Err(ctx.construct_type_error("cannot convert null or undefined to Object")) + Err(context.construct_type_error("cannot convert null or undefined to Object")) } else { Ok(self) } diff --git a/boa/src/value/operations.rs b/boa/src/value/operations.rs index 6bfa8aa371..73edf9ae99 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 Context) -> Result { + pub fn add(&self, other: &Self, context: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::rational(f64::from(*x) + f64::from(*y)), @@ -12,26 +12,30 @@ impl Value { (Self::Rational(x), Self::Integer(y)) => Self::rational(x + f64::from(*y)), (Self::String(ref x), Self::String(ref y)) => Self::string(format!("{}{}", x, y)), - (Self::String(ref x), ref y) => Self::string(format!("{}{}", x, y.to_string(ctx)?)), - (ref x, Self::String(ref y)) => Self::string(format!("{}{}", x.to_string(ctx)?, y)), + (Self::String(ref x), ref y) => Self::string(format!("{}{}", x, y.to_string(context)?)), + (ref x, Self::String(ref y)) => Self::string(format!("{}{}", x.to_string(context)?, y)), (Self::BigInt(ref n1), Self::BigInt(ref n2)) => { Self::bigint(n1.as_inner().clone() + n2.as_inner().clone()) } // Slow path: (_, _) => match ( - self.to_primitive(ctx, PreferredType::Default)?, - other.to_primitive(ctx, PreferredType::Default)?, + self.to_primitive(context, PreferredType::Default)?, + other.to_primitive(context, PreferredType::Default)?, ) { - (Self::String(ref x), ref y) => Self::string(format!("{}{}", x, y.to_string(ctx)?)), - (ref x, Self::String(ref y)) => Self::string(format!("{}{}", x.to_string(ctx)?, y)), - (x, y) => match (x.to_numeric(ctx)?, y.to_numeric(ctx)?) { + (Self::String(ref x), ref y) => { + Self::string(format!("{}{}", x, y.to_string(context)?)) + } + (ref x, Self::String(ref y)) => { + Self::string(format!("{}{}", x.to_string(context)?, y)) + } + (x, y) => match (x.to_numeric(context)?, y.to_numeric(context)?) { (Numeric::Number(x), Numeric::Number(y)) => Self::rational(x + y), (Numeric::BigInt(ref n1), Numeric::BigInt(ref n2)) => { Self::bigint(n1.as_inner().clone() + n2.as_inner().clone()) } (_, _) => { - return ctx.throw_type_error( + return context.throw_type_error( "cannot mix BigInt and other types, use explicit conversions", ) } @@ -41,7 +45,7 @@ impl Value { } #[inline] - pub fn sub(&self, other: &Self, ctx: &mut Context) -> Result { + pub fn sub(&self, other: &Self, context: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::rational(f64::from(*x) - f64::from(*y)), @@ -54,13 +58,13 @@ impl Value { } // Slow path: - (_, _) => match (self.to_numeric(ctx)?, other.to_numeric(ctx)?) { + (_, _) => match (self.to_numeric(context)?, other.to_numeric(context)?) { (Numeric::Number(a), Numeric::Number(b)) => Self::rational(a - b), (Numeric::BigInt(ref a), Numeric::BigInt(ref b)) => { Self::bigint(a.as_inner().clone() - b.as_inner().clone()) } (_, _) => { - return ctx.throw_type_error( + return context.throw_type_error( "cannot mix BigInt and other types, use explicit conversions", ); } @@ -69,7 +73,7 @@ impl Value { } #[inline] - pub fn mul(&self, other: &Self, ctx: &mut Context) -> Result { + pub fn mul(&self, other: &Self, context: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::rational(f64::from(*x) * f64::from(*y)), @@ -82,13 +86,13 @@ impl Value { } // Slow path: - (_, _) => match (self.to_numeric(ctx)?, other.to_numeric(ctx)?) { + (_, _) => match (self.to_numeric(context)?, other.to_numeric(context)?) { (Numeric::Number(a), Numeric::Number(b)) => Self::rational(a * b), (Numeric::BigInt(ref a), Numeric::BigInt(ref b)) => { Self::bigint(a.as_inner().clone() * b.as_inner().clone()) } (_, _) => { - return ctx.throw_type_error( + return context.throw_type_error( "cannot mix BigInt and other types, use explicit conversions", ); } @@ -97,7 +101,7 @@ impl Value { } #[inline] - pub fn div(&self, other: &Self, ctx: &mut Context) -> Result { + pub fn div(&self, other: &Self, context: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::rational(f64::from(*x) / f64::from(*y)), @@ -107,22 +111,22 @@ impl Value { (Self::BigInt(ref a), Self::BigInt(ref b)) => { if *b.as_inner() == BigInt::from(0) { - return ctx.throw_range_error("BigInt division by zero"); + return context.throw_range_error("BigInt division by zero"); } Self::bigint(a.as_inner().clone() / b.as_inner().clone()) } // Slow path: - (_, _) => match (self.to_numeric(ctx)?, other.to_numeric(ctx)?) { + (_, _) => match (self.to_numeric(context)?, other.to_numeric(context)?) { (Numeric::Number(a), Numeric::Number(b)) => Self::rational(a / b), (Numeric::BigInt(ref a), Numeric::BigInt(ref b)) => { if *b.as_inner() == BigInt::from(0) { - return ctx.throw_range_error("BigInt division by zero"); + return context.throw_range_error("BigInt division by zero"); } Self::bigint(a.as_inner().clone() / b.as_inner().clone()) } (_, _) => { - return ctx.throw_type_error( + return context.throw_type_error( "cannot mix BigInt and other types, use explicit conversions", ); } @@ -131,7 +135,7 @@ impl Value { } #[inline] - pub fn rem(&self, other: &Self, ctx: &mut Context) -> Result { + pub fn rem(&self, other: &Self, context: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => { @@ -147,19 +151,19 @@ impl Value { (Self::BigInt(ref a), Self::BigInt(ref b)) => { if *b.as_inner() == BigInt::from(0) { - return ctx.throw_range_error("BigInt division by zero"); + return context.throw_range_error("BigInt division by zero"); } Self::bigint(a.as_inner().clone() % b.as_inner().clone()) } // Slow path: - (_, _) => match (self.to_numeric(ctx)?, other.to_numeric(ctx)?) { + (_, _) => match (self.to_numeric(context)?, other.to_numeric(context)?) { (Numeric::Number(a), Numeric::Number(b)) => Self::rational(a % b), (Numeric::BigInt(ref a), Numeric::BigInt(ref b)) => { Self::bigint(a.as_inner().clone() % b.as_inner().clone()) } (_, _) => { - return ctx.throw_type_error( + return context.throw_type_error( "cannot mix BigInt and other types, use explicit conversions", ); } @@ -168,7 +172,7 @@ impl Value { } #[inline] - pub fn pow(&self, other: &Self, ctx: &mut Context) -> Result { + pub fn pow(&self, other: &Self, context: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::rational(f64::from(*x).powi(*y)), @@ -180,20 +184,20 @@ impl Value { a.as_inner() .clone() .pow(b) - .map_err(|msg| ctx.construct_range_error(msg))?, + .map_err(|msg| context.construct_range_error(msg))?, ), // Slow path: - (_, _) => match (self.to_numeric(ctx)?, other.to_numeric(ctx)?) { + (_, _) => match (self.to_numeric(context)?, other.to_numeric(context)?) { (Numeric::Number(a), Numeric::Number(b)) => Self::rational(a.powf(b)), (Numeric::BigInt(ref a), Numeric::BigInt(ref b)) => Self::bigint( a.as_inner() .clone() .pow(b) - .map_err(|msg| ctx.construct_range_error(msg))?, + .map_err(|msg| context.construct_range_error(msg))?, ), (_, _) => { - return ctx.throw_type_error( + return context.throw_type_error( "cannot mix BigInt and other types, use explicit conversions", ); } @@ -202,7 +206,7 @@ impl Value { } #[inline] - pub fn bitand(&self, other: &Self, ctx: &mut Context) -> Result { + pub fn bitand(&self, other: &Self, context: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::integer(x & y), @@ -217,7 +221,7 @@ impl Value { } // Slow path: - (_, _) => match (self.to_numeric(ctx)?, other.to_numeric(ctx)?) { + (_, _) => match (self.to_numeric(context)?, other.to_numeric(context)?) { (Numeric::Number(a), Numeric::Number(b)) => { Self::integer(f64_to_int32(a) & f64_to_int32(b)) } @@ -225,7 +229,7 @@ impl Value { Self::bigint(a.as_inner().clone() & b.as_inner().clone()) } (_, _) => { - return ctx.throw_type_error( + return context.throw_type_error( "cannot mix BigInt and other types, use explicit conversions", ); } @@ -234,7 +238,7 @@ impl Value { } #[inline] - pub fn bitor(&self, other: &Self, ctx: &mut Context) -> Result { + pub fn bitor(&self, other: &Self, context: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::integer(x | y), @@ -249,7 +253,7 @@ impl Value { } // Slow path: - (_, _) => match (self.to_numeric(ctx)?, other.to_numeric(ctx)?) { + (_, _) => match (self.to_numeric(context)?, other.to_numeric(context)?) { (Numeric::Number(a), Numeric::Number(b)) => { Self::integer(f64_to_int32(a) | f64_to_int32(b)) } @@ -257,7 +261,7 @@ impl Value { Self::bigint(a.as_inner().clone() | b.as_inner().clone()) } (_, _) => { - return ctx.throw_type_error( + return context.throw_type_error( "cannot mix BigInt and other types, use explicit conversions", ); } @@ -266,7 +270,7 @@ impl Value { } #[inline] - pub fn bitxor(&self, other: &Self, ctx: &mut Context) -> Result { + pub fn bitxor(&self, other: &Self, context: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::integer(x ^ y), @@ -281,7 +285,7 @@ impl Value { } // Slow path: - (_, _) => match (self.to_numeric(ctx)?, other.to_numeric(ctx)?) { + (_, _) => match (self.to_numeric(context)?, other.to_numeric(context)?) { (Numeric::Number(a), Numeric::Number(b)) => { Self::integer(f64_to_int32(a) ^ f64_to_int32(b)) } @@ -289,7 +293,7 @@ impl Value { Self::bigint(a.as_inner().clone() ^ b.as_inner().clone()) } (_, _) => { - return ctx.throw_type_error( + return context.throw_type_error( "cannot mix BigInt and other types, use explicit conversions", ); } @@ -298,7 +302,7 @@ impl Value { } #[inline] - pub fn shl(&self, other: &Self, ctx: &mut Context) -> Result { + pub fn shl(&self, other: &Self, context: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::integer(x.wrapping_shl(*y as u32)), @@ -316,11 +320,11 @@ impl Value { a.as_inner() .clone() .shift_left(b.as_inner().clone()) - .map_err(|msg| ctx.construct_range_error(&msg))?, + .map_err(|msg| context.construct_range_error(&msg))?, ), // Slow path: - (_, _) => match (self.to_numeric(ctx)?, other.to_numeric(ctx)?) { + (_, _) => match (self.to_numeric(context)?, other.to_numeric(context)?) { (Numeric::Number(x), Numeric::Number(y)) => { Self::integer(f64_to_int32(x).wrapping_shl(f64_to_uint32(y))) } @@ -328,10 +332,10 @@ impl Value { x.as_inner() .clone() .shift_left(y.as_inner().clone()) - .map_err(|msg| ctx.construct_range_error(&msg))?, + .map_err(|msg| context.construct_range_error(&msg))?, ), (_, _) => { - return ctx.throw_type_error( + return context.throw_type_error( "cannot mix BigInt and other types, use explicit conversions", ); } @@ -340,7 +344,7 @@ impl Value { } #[inline] - pub fn shr(&self, other: &Self, ctx: &mut Context) -> Result { + pub fn shr(&self, other: &Self, context: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => Self::integer(x.wrapping_shr(*y as u32)), @@ -358,11 +362,11 @@ impl Value { a.as_inner() .clone() .shift_right(b.as_inner().clone()) - .map_err(|msg| ctx.construct_range_error(&msg))?, + .map_err(|msg| context.construct_range_error(&msg))?, ), // Slow path: - (_, _) => match (self.to_numeric(ctx)?, other.to_numeric(ctx)?) { + (_, _) => match (self.to_numeric(context)?, other.to_numeric(context)?) { (Numeric::Number(x), Numeric::Number(y)) => { Self::integer(f64_to_int32(x).wrapping_shr(f64_to_uint32(y))) } @@ -370,10 +374,10 @@ impl Value { x.as_inner() .clone() .shift_right(y.as_inner().clone()) - .map_err(|msg| ctx.construct_range_error(&msg))?, + .map_err(|msg| context.construct_range_error(&msg))?, ), (_, _) => { - return ctx.throw_type_error( + return context.throw_type_error( "cannot mix BigInt and other types, use explicit conversions", ); } @@ -382,7 +386,7 @@ impl Value { } #[inline] - pub fn ushr(&self, other: &Self, ctx: &mut Context) -> Result { + pub fn ushr(&self, other: &Self, context: &mut Context) -> Result { Ok(match (self, other) { // Fast path: (Self::Integer(x), Self::Integer(y)) => { @@ -399,16 +403,16 @@ impl Value { } // Slow path: - (_, _) => match (self.to_numeric(ctx)?, other.to_numeric(ctx)?) { + (_, _) => match (self.to_numeric(context)?, other.to_numeric(context)?) { (Numeric::Number(x), Numeric::Number(y)) => { Self::rational(f64_to_uint32(x).wrapping_shr(f64_to_uint32(y))) } (Numeric::BigInt(_), Numeric::BigInt(_)) => { - return ctx + return context .throw_type_error("BigInts have no unsigned right shift, use >> instead"); } (_, _) => { - return ctx.throw_type_error( + return context.throw_type_error( "cannot mix BigInt and other types, use explicit conversions", ); } @@ -417,10 +421,10 @@ impl Value { } #[inline] - pub fn neg(&self, interpreter: &mut Context) -> Result { + pub fn neg(&self, context: &mut Context) -> Result { Ok(match *self { Self::Symbol(_) | Self::Undefined => Self::rational(NAN), - Self::Object(_) => Self::rational(match self.to_numeric_number(interpreter) { + Self::Object(_) => Self::rational(match self.to_numeric_number(context) { Ok(num) => -num, Err(_) => NAN, }), @@ -462,7 +466,7 @@ impl Value { &self, other: &Self, left_first: bool, - ctx: &mut Context, + context: &mut Context, ) -> Result { Ok(match (self, other) { // Fast path (for some common operations): @@ -475,13 +479,13 @@ impl Value { // Slow path: (_, _) => { let (px, py) = if left_first { - let px = self.to_primitive(ctx, PreferredType::Number)?; - let py = other.to_primitive(ctx, PreferredType::Number)?; + let px = self.to_primitive(context, PreferredType::Number)?; + let py = other.to_primitive(context, PreferredType::Number)?; (px, py) } else { // NOTE: The order of evaluation needs to be reversed to preserve left to right evaluation. - let py = other.to_primitive(ctx, PreferredType::Number)?; - let px = self.to_primitive(ctx, PreferredType::Number)?; + let py = other.to_primitive(context, PreferredType::Number)?; + let px = self.to_primitive(context, PreferredType::Number)?; (px, py) }; @@ -514,7 +518,7 @@ impl Value { AbstractRelation::Undefined } } - (px, py) => match (px.to_numeric(ctx)?, py.to_numeric(ctx)?) { + (px, py) => match (px.to_numeric(context)?, py.to_numeric(context)?) { (Numeric::Number(x), Numeric::Number(y)) => Number::less_than(x, y), (Numeric::BigInt(ref x), Numeric::BigInt(ref y)) => (x < y).into(), (Numeric::BigInt(ref x), Numeric::Number(y)) => { @@ -561,8 +565,8 @@ 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 Context) -> Result { - match self.abstract_relation(other, true, ctx)? { + pub fn lt(&self, other: &Self, context: &mut Context) -> Result { + match self.abstract_relation(other, true, context)? { AbstractRelation::True => Ok(true), AbstractRelation::False | AbstractRelation::Undefined => Ok(false), } @@ -578,8 +582,8 @@ 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 Context) -> Result { - match other.abstract_relation(self, false, ctx)? { + pub fn le(&self, other: &Self, context: &mut Context) -> Result { + match other.abstract_relation(self, false, context)? { AbstractRelation::False => Ok(true), AbstractRelation::True | AbstractRelation::Undefined => Ok(false), } @@ -595,8 +599,8 @@ 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 Context) -> Result { - match other.abstract_relation(self, false, ctx)? { + pub fn gt(&self, other: &Self, context: &mut Context) -> Result { + match other.abstract_relation(self, false, context)? { AbstractRelation::True => Ok(true), AbstractRelation::False | AbstractRelation::Undefined => Ok(false), } @@ -612,8 +616,8 @@ 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 Context) -> Result { - match self.abstract_relation(other, true, ctx)? { + pub fn ge(&self, other: &Self, context: &mut Context) -> Result { + match self.abstract_relation(other, true, context)? { AbstractRelation::False => Ok(true), AbstractRelation::True | AbstractRelation::Undefined => Ok(false), } diff --git a/boa/src/value/rcbigint.rs b/boa/src/value/rcbigint.rs index 3bf8ce6e26..94f9465165 100644 --- a/boa/src/value/rcbigint.rs +++ b/boa/src/value/rcbigint.rs @@ -1,16 +1,19 @@ -use crate::builtins::BigInt; +use crate::{ + builtins::BigInt, + gc::{empty_trace, Finalize, Trace}, +}; -use std::fmt::{self, Display}; -use std::ops::Deref; -use std::rc::Rc; - -use gc::{unsafe_empty_trace, Finalize, Trace}; +use std::{ + fmt::{self, Display}, + ops::Deref, + rc::Rc, +}; #[derive(Debug, Finalize, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct RcBigInt(Rc); unsafe impl Trace for RcBigInt { - unsafe_empty_trace!(); + empty_trace!(); } impl RcBigInt { diff --git a/boa/src/value/rcstring.rs b/boa/src/value/rcstring.rs index 7ac39ea763..987d7a7a39 100644 --- a/boa/src/value/rcstring.rs +++ b/boa/src/value/rcstring.rs @@ -1,15 +1,17 @@ -use std::borrow::Borrow; -use std::fmt::{self, Display}; -use std::ops::Deref; -use std::rc::Rc; +use crate::gc::{empty_trace, Finalize, Trace}; -use gc::{unsafe_empty_trace, Finalize, Trace}; +use std::{ + borrow::Borrow, + fmt::{self, Display}, + ops::Deref, + rc::Rc, +}; #[derive(Debug, Finalize, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct RcString(Rc); unsafe impl Trace for RcString { - unsafe_empty_trace!(); + empty_trace!(); } impl RcString { diff --git a/boa/src/value/rcsymbol.rs b/boa/src/value/rcsymbol.rs index 7fa1288d42..827bcd5d03 100644 --- a/boa/src/value/rcsymbol.rs +++ b/boa/src/value/rcsymbol.rs @@ -1,16 +1,19 @@ -use crate::builtins::Symbol; +use crate::{ + builtins::Symbol, + gc::{empty_trace, Finalize, Trace}, +}; -use std::fmt::{self, Display}; -use std::ops::Deref; -use std::rc::Rc; - -use gc::{unsafe_empty_trace, Finalize, Trace}; +use std::{ + fmt::{self, Display}, + ops::Deref, + rc::Rc, +}; #[derive(Debug, Finalize, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct RcSymbol(Rc); unsafe impl Trace for RcSymbol { - unsafe_empty_trace!(); + empty_trace!(); } impl Display for RcSymbol { diff --git a/boa/src/value/tests.rs b/boa/src/value/tests.rs index 647ee55263..0d8420cd6d 100644 --- a/boa/src/value/tests.rs +++ b/boa/src/value/tests.rs @@ -56,56 +56,59 @@ fn number_is_true() { // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness #[test] fn abstract_equality_comparison() { - let mut engine = Context::new(); - - assert_eq!(forward(&mut engine, "undefined == undefined"), "true"); - assert_eq!(forward(&mut engine, "null == null"), "true"); - assert_eq!(forward(&mut engine, "true == true"), "true"); - assert_eq!(forward(&mut engine, "false == false"), "true"); - assert_eq!(forward(&mut engine, "'foo' == 'foo'"), "true"); - assert_eq!(forward(&mut engine, "0 == 0"), "true"); - assert_eq!(forward(&mut engine, "+0 == -0"), "true"); - assert_eq!(forward(&mut engine, "+0 == 0"), "true"); - assert_eq!(forward(&mut engine, "-0 == 0"), "true"); - assert_eq!(forward(&mut engine, "0 == false"), "true"); - assert_eq!(forward(&mut engine, "'' == false"), "true"); - assert_eq!(forward(&mut engine, "'' == 0"), "true"); - assert_eq!(forward(&mut engine, "'17' == 17"), "true"); - assert_eq!(forward(&mut engine, "[1,2] == '1,2'"), "true"); - assert_eq!(forward(&mut engine, "new String('foo') == 'foo'"), "true"); - assert_eq!(forward(&mut engine, "null == undefined"), "true"); - assert_eq!(forward(&mut engine, "undefined == null"), "true"); - assert_eq!(forward(&mut engine, "null == false"), "false"); - assert_eq!(forward(&mut engine, "[] == ![]"), "true"); + let mut context = Context::new(); + + assert_eq!(forward(&mut context, "undefined == undefined"), "true"); + assert_eq!(forward(&mut context, "null == null"), "true"); + assert_eq!(forward(&mut context, "true == true"), "true"); + assert_eq!(forward(&mut context, "false == false"), "true"); + assert_eq!(forward(&mut context, "'foo' == 'foo'"), "true"); + assert_eq!(forward(&mut context, "0 == 0"), "true"); + assert_eq!(forward(&mut context, "+0 == -0"), "true"); + assert_eq!(forward(&mut context, "+0 == 0"), "true"); + assert_eq!(forward(&mut context, "-0 == 0"), "true"); + assert_eq!(forward(&mut context, "0 == false"), "true"); + assert_eq!(forward(&mut context, "'' == false"), "true"); + assert_eq!(forward(&mut context, "'' == 0"), "true"); + assert_eq!(forward(&mut context, "'17' == 17"), "true"); + assert_eq!(forward(&mut context, "[1,2] == '1,2'"), "true"); + assert_eq!(forward(&mut context, "new String('foo') == 'foo'"), "true"); + assert_eq!(forward(&mut context, "null == undefined"), "true"); + assert_eq!(forward(&mut context, "undefined == null"), "true"); + assert_eq!(forward(&mut context, "null == false"), "false"); + assert_eq!(forward(&mut context, "[] == ![]"), "true"); assert_eq!( - forward(&mut engine, "a = { foo: 'bar' }; b = { foo: 'bar'}; a == b"), + forward( + &mut context, + "a = { foo: 'bar' }; b = { foo: 'bar'}; a == b" + ), "false" ); assert_eq!( - forward(&mut engine, "new String('foo') == new String('foo')"), + forward(&mut context, "new String('foo') == new String('foo')"), "false" ); - assert_eq!(forward(&mut engine, "0 == null"), "false"); + assert_eq!(forward(&mut context, "0 == null"), "false"); - assert_eq!(forward(&mut engine, "0 == '-0'"), "true"); - assert_eq!(forward(&mut engine, "0 == '+0'"), "true"); - assert_eq!(forward(&mut engine, "'+0' == 0"), "true"); - assert_eq!(forward(&mut engine, "'-0' == 0"), "true"); + assert_eq!(forward(&mut context, "0 == '-0'"), "true"); + assert_eq!(forward(&mut context, "0 == '+0'"), "true"); + assert_eq!(forward(&mut context, "'+0' == 0"), "true"); + assert_eq!(forward(&mut context, "'-0' == 0"), "true"); - assert_eq!(forward(&mut engine, "0 == NaN"), "false"); - assert_eq!(forward(&mut engine, "'foo' == NaN"), "false"); - assert_eq!(forward(&mut engine, "NaN == NaN"), "false"); + assert_eq!(forward(&mut context, "0 == NaN"), "false"); + assert_eq!(forward(&mut context, "'foo' == NaN"), "false"); + assert_eq!(forward(&mut context, "NaN == NaN"), "false"); assert_eq!( forward( - &mut engine, + &mut context, "Number.POSITIVE_INFINITY === Number.POSITIVE_INFINITY" ), "true" ); assert_eq!( forward( - &mut engine, + &mut context, "Number.NEGAVIVE_INFINITY === Number.NEGAVIVE_INFINITY" ), "true" @@ -160,56 +163,56 @@ fn hash_object() { #[test] fn get_types() { - let mut engine = Context::new(); + let mut context = Context::new(); assert_eq!( - forward_val(&mut engine, "undefined").unwrap().get_type(), + forward_val(&mut context, "undefined").unwrap().get_type(), Type::Undefined ); assert_eq!( - forward_val(&mut engine, "1").unwrap().get_type(), + forward_val(&mut context, "1").unwrap().get_type(), Type::Number ); assert_eq!( - forward_val(&mut engine, "1.5").unwrap().get_type(), + forward_val(&mut context, "1.5").unwrap().get_type(), Type::Number ); assert_eq!( - forward_val(&mut engine, "BigInt(\"123442424242424424242424242\")") + forward_val(&mut context, "BigInt(\"123442424242424424242424242\")") .unwrap() .get_type(), Type::BigInt ); assert_eq!( - forward_val(&mut engine, "true").unwrap().get_type(), + forward_val(&mut context, "true").unwrap().get_type(), Type::Boolean ); assert_eq!( - forward_val(&mut engine, "false").unwrap().get_type(), + forward_val(&mut context, "false").unwrap().get_type(), Type::Boolean ); assert_eq!( - forward_val(&mut engine, "function foo() {console.log(\"foo\");}") + forward_val(&mut context, "function foo() {console.log(\"foo\");}") .unwrap() .get_type(), Type::Undefined ); assert_eq!( - forward_val(&mut engine, "null").unwrap().get_type(), + forward_val(&mut context, "null").unwrap().get_type(), Type::Null ); assert_eq!( - forward_val(&mut engine, "var x = {arg: \"hi\", foo: \"hello\"}; x") + forward_val(&mut context, "var x = {arg: \"hi\", foo: \"hello\"}; x") .unwrap() .get_type(), Type::Object ); assert_eq!( - forward_val(&mut engine, "\"Hi\"").unwrap().get_type(), + forward_val(&mut context, "\"Hi\"").unwrap().get_type(), Type::String ); assert_eq!( - forward_val(&mut engine, "Symbol()").unwrap().get_type(), + forward_val(&mut context, "Symbol()").unwrap().get_type(), Type::Symbol ); } @@ -250,146 +253,146 @@ fn to_string() { #[test] fn add_number_and_number() { - let mut engine = Context::new(); + let mut context = Context::new(); - let value = forward_val(&mut engine, "1 + 2").unwrap(); - let value = value.to_i32(&mut engine).unwrap(); + let value = forward_val(&mut context, "1 + 2").unwrap(); + let value = value.to_i32(&mut context).unwrap(); assert_eq!(value, 3); } #[test] fn add_number_and_string() { - let mut engine = Context::new(); + let mut context = Context::new(); - let value = forward_val(&mut engine, "1 + \" + 2 = 3\"").unwrap(); - let value = value.to_string(&mut engine).unwrap(); + let value = forward_val(&mut context, "1 + \" + 2 = 3\"").unwrap(); + let value = value.to_string(&mut context).unwrap(); assert_eq!(value, "1 + 2 = 3"); } #[test] fn add_string_and_string() { - let mut engine = Context::new(); + let mut context = Context::new(); - let value = forward_val(&mut engine, "\"Hello\" + \", world\"").unwrap(); - let value = value.to_string(&mut engine).unwrap(); + let value = forward_val(&mut context, "\"Hello\" + \", world\"").unwrap(); + let value = value.to_string(&mut context).unwrap(); assert_eq!(value, "Hello, world"); } #[test] fn add_number_object_and_number() { - let mut engine = Context::new(); + let mut context = Context::new(); - let value = forward_val(&mut engine, "new Number(10) + 6").unwrap(); - let value = value.to_i32(&mut engine).unwrap(); + let value = forward_val(&mut context, "new Number(10) + 6").unwrap(); + let value = value.to_i32(&mut context).unwrap(); assert_eq!(value, 16); } #[test] fn add_number_object_and_string_object() { - let mut engine = Context::new(); + let mut context = Context::new(); - let value = forward_val(&mut engine, "new Number(10) + new String(\"0\")").unwrap(); - let value = value.to_string(&mut engine).unwrap(); + let value = forward_val(&mut context, "new Number(10) + new String(\"0\")").unwrap(); + let value = value.to_string(&mut context).unwrap(); assert_eq!(value, "100"); } #[test] fn sub_number_and_number() { - let mut engine = Context::new(); + let mut context = Context::new(); - let value = forward_val(&mut engine, "1 - 999").unwrap(); - let value = value.to_i32(&mut engine).unwrap(); + let value = forward_val(&mut context, "1 - 999").unwrap(); + let value = value.to_i32(&mut context).unwrap(); assert_eq!(value, -998); } #[test] fn sub_number_object_and_number_object() { - let mut engine = Context::new(); + let mut context = Context::new(); - let value = forward_val(&mut engine, "new Number(1) - new Number(999)").unwrap(); - let value = value.to_i32(&mut engine).unwrap(); + let value = forward_val(&mut context, "new Number(1) - new Number(999)").unwrap(); + let value = value.to_i32(&mut context).unwrap(); assert_eq!(value, -998); } #[test] fn sub_string_and_number_object() { - let mut engine = Context::new(); + let mut context = Context::new(); - let value = forward_val(&mut engine, "'Hello' - new Number(999)").unwrap(); - let value = value.to_number(&mut engine).unwrap(); + let value = forward_val(&mut context, "'Hello' - new Number(999)").unwrap(); + let value = value.to_number(&mut context).unwrap(); assert!(value.is_nan()); } #[test] fn div_by_zero() { - let mut engine = Context::new(); + let mut context = Context::new(); - let value = forward_val(&mut engine, "1 / 0").unwrap(); - let value = value.to_number(&mut engine).unwrap(); + let value = forward_val(&mut context, "1 / 0").unwrap(); + let value = value.to_number(&mut context).unwrap(); assert!(value.is_infinite()); } #[test] fn rem_by_zero() { - let mut engine = Context::new(); + let mut context = Context::new(); - let value = forward_val(&mut engine, "1 % 0").unwrap(); - let value = value.to_number(&mut engine).unwrap(); + let value = forward_val(&mut context, "1 % 0").unwrap(); + let value = value.to_number(&mut context).unwrap(); assert!(value.is_nan()); } #[test] fn bitand_integer_and_integer() { - let mut engine = Context::new(); + let mut context = Context::new(); - let value = forward_val(&mut engine, "0xFFFF & 0xFF").unwrap(); - let value = value.to_i32(&mut engine).unwrap(); + let value = forward_val(&mut context, "0xFFFF & 0xFF").unwrap(); + let value = value.to_i32(&mut context).unwrap(); assert_eq!(value, 255); } #[test] fn bitand_integer_and_rational() { - let mut engine = Context::new(); + let mut context = Context::new(); - let value = forward_val(&mut engine, "0xFFFF & 255.5").unwrap(); - let value = value.to_i32(&mut engine).unwrap(); + let value = forward_val(&mut context, "0xFFFF & 255.5").unwrap(); + let value = value.to_i32(&mut context).unwrap(); assert_eq!(value, 255); } #[test] fn bitand_rational_and_rational() { - let mut engine = Context::new(); + let mut context = Context::new(); - let value = forward_val(&mut engine, "255.772 & 255.5").unwrap(); - let value = value.to_i32(&mut engine).unwrap(); + let value = forward_val(&mut context, "255.772 & 255.5").unwrap(); + let value = value.to_i32(&mut context).unwrap(); assert_eq!(value, 255); } #[test] #[allow(clippy::float_cmp)] fn pow_number_and_number() { - let mut engine = Context::new(); + let mut context = Context::new(); - let value = forward_val(&mut engine, "3 ** 3").unwrap(); - let value = value.to_number(&mut engine).unwrap(); + let value = forward_val(&mut context, "3 ** 3").unwrap(); + let value = value.to_number(&mut context).unwrap(); assert_eq!(value, 27.0); } #[test] fn pow_number_and_string() { - let mut engine = Context::new(); + let mut context = Context::new(); - let value = forward_val(&mut engine, "3 ** 'Hello'").unwrap(); - let value = value.to_number(&mut engine).unwrap(); + let value = forward_val(&mut context, "3 ** 'Hello'").unwrap(); + let value = value.to_number(&mut context).unwrap(); assert!(value.is_nan()); } #[test] fn assign_pow_number_and_string() { - let mut engine = Context::new(); + let mut context = Context::new(); let value = forward_val( - &mut engine, + &mut context, r" let a = 3; a **= 'Hello' @@ -397,7 +400,7 @@ fn assign_pow_number_and_string() { ", ) .unwrap(); - let value = value.to_number(&mut engine).unwrap(); + let value = value.to_number(&mut context).unwrap(); assert!(value.is_nan()); } @@ -410,49 +413,49 @@ fn display_string() { #[test] fn display_array_string() { - let mut engine = Context::new(); + let mut context = Context::new(); - let value = forward_val(&mut engine, "[\"Hello\"]").unwrap(); + let value = forward_val(&mut context, "[\"Hello\"]").unwrap(); assert_eq!(value.display().to_string(), "[ \"Hello\" ]"); } #[test] fn display_boolean_object() { - let mut engine = Context::new(); + let mut context = Context::new(); let d_obj = r#" let bool = new Boolean(0); bool "#; - let value = forward_val(&mut engine, d_obj).unwrap(); + let value = forward_val(&mut context, d_obj).unwrap(); assert_eq!(value.display().to_string(), "Boolean { false }") } #[test] fn display_number_object() { - let mut engine = Context::new(); + let mut context = Context::new(); let d_obj = r#" let num = new Number(3.14); num "#; - let value = forward_val(&mut engine, d_obj).unwrap(); + let value = forward_val(&mut context, d_obj).unwrap(); assert_eq!(value.display().to_string(), "Number { 3.14 }") } #[test] fn display_negative_zero_object() { - let mut engine = Context::new(); + let mut context = Context::new(); let d_obj = r#" let num = new Number(-0); num "#; - let value = forward_val(&mut engine, d_obj).unwrap(); + let value = forward_val(&mut context, d_obj).unwrap(); assert_eq!(value.display().to_string(), "Number { -0 }") } #[test] fn debug_object() { - let mut engine = Context::new(); - let value = forward_val(&mut engine, "new Array([new Date()])").unwrap(); + let mut context = Context::new(); + let value = forward_val(&mut context, "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 // added, this would cause a stack overflow, so executing Debug::fmt is the assertion. @@ -465,12 +468,12 @@ 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 mut engine = Context::new(); + let mut context = Context::new(); let d_obj = r#" let o = {a: 'a'}; o "#; - let value = forward_val(&mut engine, d_obj).unwrap(); + let value = forward_val(&mut context, d_obj).unwrap(); assert_eq!( value.display().to_string(), r#"{ @@ -524,7 +527,7 @@ mod cyclic_conversions { #[test] fn to_json_cyclic() { - let mut engine = Context::new(); + let mut context = Context::new(); let src = r#" let a = []; a[0] = a; @@ -532,21 +535,21 @@ mod cyclic_conversions { "#; assert_eq!( - forward(&mut engine, src), + forward(&mut context, src), r#"Uncaught "TypeError": "cyclic object value""#, ); } #[test] fn to_json_noncyclic() { - let mut engine = Context::new(); + let mut context = Context::new(); let src = r#" let b = []; let a = [b, b]; JSON.stringify(a) "#; - let value = forward_val(&mut engine, src).unwrap(); + let value = forward_val(&mut context, src).unwrap(); let result = value.as_string().unwrap(); assert_eq!(result, "[[],[]]",); } @@ -554,28 +557,28 @@ mod cyclic_conversions { // These tests don't throw errors. Instead we mirror Chrome / Firefox behavior for these conversions #[test] fn to_string_cyclic() { - let mut engine = Context::new(); + let mut context = Context::new(); let src = r#" let a = []; a[0] = a; a.toString() "#; - let value = forward_val(&mut engine, src).unwrap(); + let value = forward_val(&mut context, src).unwrap(); let result = value.as_string().unwrap(); assert_eq!(result, ""); } #[test] fn to_number_cyclic() { - let mut engine = Context::new(); + let mut context = Context::new(); let src = r#" let a = []; a[0] = a; +a "#; - let value = forward_val(&mut engine, src).unwrap(); + let value = forward_val(&mut context, src).unwrap(); let result = value.as_number().unwrap(); assert_eq!(result, 0.0); } @@ -583,56 +586,56 @@ mod cyclic_conversions { #[test] fn to_boolean_cyclic() { // this already worked before the mitigation, but we don't want to cause a regression - let mut engine = Context::new(); + let mut context = Context::new(); let src = r#" let a = []; a[0] = a; !!a "#; - let value = forward_val(&mut engine, src).unwrap(); + let value = forward_val(&mut context, src).unwrap(); // There isn't an as_boolean function for some reason? assert_eq!(value, Value::Boolean(true)); } #[test] fn to_bigint_cyclic() { - let mut engine = Context::new(); + let mut context = Context::new(); let src = r#" let a = []; a[0] = a; BigInt(a) "#; - let value = forward_val(&mut engine, src).unwrap(); + let value = forward_val(&mut context, src).unwrap(); let result = value.as_bigint().unwrap().to_f64(); assert_eq!(result, 0.); } #[test] fn to_u32_cyclic() { - let mut engine = Context::new(); + let mut context = Context::new(); let src = r#" let a = []; a[0] = a; a | 0 "#; - let value = forward_val(&mut engine, src).unwrap(); + let value = forward_val(&mut context, src).unwrap(); let result = value.as_number().unwrap(); assert_eq!(result, 0.); } #[test] fn console_log_cyclic() { - let mut engine = Context::new(); + let mut context = Context::new(); let src = r#" let a = [1]; a[1] = a; console.log(a); "#; - let _ = forward(&mut engine, src); + let _ = forward(&mut context, src); // Should not stack overflow } } @@ -640,9 +643,9 @@ mod cyclic_conversions { mod abstract_relational_comparison { use super::*; macro_rules! check_comparison { - ($engine:ident, $string:expr => $expect:expr) => { + ($context:ident, $string:expr => $expect:expr) => { assert_eq!( - forward_val(&mut $engine, $string).unwrap().to_boolean(), + forward_val(&mut $context, $string).unwrap().to_boolean(), $expect ); }; @@ -650,589 +653,589 @@ mod abstract_relational_comparison { #[test] fn number_less_than_number() { - let mut engine = Context::new(); - check_comparison!(engine, "1 < 2" => true); - check_comparison!(engine, "2 < 2" => false); - check_comparison!(engine, "3 < 2" => false); - check_comparison!(engine, "2 < 2.5" => true); - check_comparison!(engine, "2.5 < 2" => false); + let mut context = Context::new(); + check_comparison!(context, "1 < 2" => true); + check_comparison!(context, "2 < 2" => false); + check_comparison!(context, "3 < 2" => false); + check_comparison!(context, "2 < 2.5" => true); + check_comparison!(context, "2.5 < 2" => false); } #[test] fn string_less_than_number() { - let mut engine = Context::new(); - check_comparison!(engine, "'1' < 2" => true); - check_comparison!(engine, "'2' < 2" => false); - check_comparison!(engine, "'3' < 2" => false); - check_comparison!(engine, "'2' < 2.5" => true); - check_comparison!(engine, "'2.5' < 2" => false); + let mut context = Context::new(); + check_comparison!(context, "'1' < 2" => true); + check_comparison!(context, "'2' < 2" => false); + check_comparison!(context, "'3' < 2" => false); + check_comparison!(context, "'2' < 2.5" => true); + check_comparison!(context, "'2.5' < 2" => false); } #[test] fn number_less_than_string() { - let mut engine = Context::new(); - check_comparison!(engine, "1 < '2'" => true); - check_comparison!(engine, "2 < '2'" => false); - check_comparison!(engine, "3 < '2'" => false); - check_comparison!(engine, "2 < '2.5'" => true); - check_comparison!(engine, "2.5 < '2'" => false); + let mut context = Context::new(); + check_comparison!(context, "1 < '2'" => true); + check_comparison!(context, "2 < '2'" => false); + check_comparison!(context, "3 < '2'" => false); + check_comparison!(context, "2 < '2.5'" => true); + check_comparison!(context, "2.5 < '2'" => false); } #[test] fn number_object_less_than_number() { - 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); - check_comparison!(engine, "new Number(2) < '2.5'" => true); - check_comparison!(engine, "new Number(2.5) < '2'" => false); + let mut context = Context::new(); + check_comparison!(context, "new Number(1) < '2'" => true); + check_comparison!(context, "new Number(2) < '2'" => false); + check_comparison!(context, "new Number(3) < '2'" => false); + check_comparison!(context, "new Number(2) < '2.5'" => true); + check_comparison!(context, "new Number(2.5) < '2'" => false); } #[test] fn number_object_less_than_number_object() { - 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); - check_comparison!(engine, "new Number(2) < new Number(2.5)" => true); - check_comparison!(engine, "new Number(2.5) < new Number(2)" => false); + let mut context = Context::new(); + check_comparison!(context, "new Number(1) < new Number(2)" => true); + check_comparison!(context, "new Number(2) < new Number(2)" => false); + check_comparison!(context, "new Number(3) < new Number(2)" => false); + check_comparison!(context, "new Number(2) < new Number(2.5)" => true); + check_comparison!(context, "new Number(2.5) < new Number(2)" => false); } #[test] fn string_less_than_string() { - let mut engine = Context::new(); - check_comparison!(engine, "'hello' < 'hello'" => false); - check_comparison!(engine, "'hell' < 'hello'" => true); - check_comparison!(engine, "'hello, world' < 'world'" => true); - check_comparison!(engine, "'aa' < 'ab'" => true); + let mut context = Context::new(); + check_comparison!(context, "'hello' < 'hello'" => false); + check_comparison!(context, "'hell' < 'hello'" => true); + check_comparison!(context, "'hello, world' < 'world'" => true); + check_comparison!(context, "'aa' < 'ab'" => true); } #[test] fn string_object_less_than_string() { - 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); - check_comparison!(engine, "new String('aa') < 'ab'" => true); + let mut context = Context::new(); + check_comparison!(context, "new String('hello') < 'hello'" => false); + check_comparison!(context, "new String('hell') < 'hello'" => true); + check_comparison!(context, "new String('hello, world') < 'world'" => true); + check_comparison!(context, "new String('aa') < 'ab'" => true); } #[test] fn string_object_less_than_string_object() { - 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); - check_comparison!(engine, "new String('aa') < new String('ab')" => true); + let mut context = Context::new(); + check_comparison!(context, "new String('hello') < new String('hello')" => false); + check_comparison!(context, "new String('hell') < new String('hello')" => true); + check_comparison!(context, "new String('hello, world') < new String('world')" => true); + check_comparison!(context, "new String('aa') < new String('ab')" => true); } #[test] fn bigint_less_than_number() { - let mut engine = Context::new(); - check_comparison!(engine, "1n < 10" => true); - check_comparison!(engine, "10n < 10" => false); - check_comparison!(engine, "100n < 10" => false); - check_comparison!(engine, "10n < 10.9" => true); + let mut context = Context::new(); + check_comparison!(context, "1n < 10" => true); + check_comparison!(context, "10n < 10" => false); + check_comparison!(context, "100n < 10" => false); + check_comparison!(context, "10n < 10.9" => true); } #[test] fn number_less_than_bigint() { - let mut engine = Context::new(); - check_comparison!(engine, "10 < 1n" => false); - check_comparison!(engine, "1 < 1n" => false); - check_comparison!(engine, "-1 < -1n" => false); - check_comparison!(engine, "-1.9 < -1n" => true); + let mut context = Context::new(); + check_comparison!(context, "10 < 1n" => false); + check_comparison!(context, "1 < 1n" => false); + check_comparison!(context, "-1 < -1n" => false); + check_comparison!(context, "-1.9 < -1n" => true); } #[test] fn negative_infnity_less_than_bigint() { - let mut engine = Context::new(); - check_comparison!(engine, "-Infinity < -10000000000n" => true); - check_comparison!(engine, "-Infinity < (-1n << 100n)" => true); + let mut context = Context::new(); + check_comparison!(context, "-Infinity < -10000000000n" => true); + check_comparison!(context, "-Infinity < (-1n << 100n)" => true); } #[test] fn bigint_less_than_infinity() { - let mut engine = Context::new(); - check_comparison!(engine, "1000n < NaN" => false); - check_comparison!(engine, "(1n << 100n) < NaN" => false); + let mut context = Context::new(); + check_comparison!(context, "1000n < NaN" => false); + check_comparison!(context, "(1n << 100n) < NaN" => false); } #[test] fn nan_less_than_bigint() { - let mut engine = Context::new(); - check_comparison!(engine, "NaN < -10000000000n" => false); - check_comparison!(engine, "NaN < (-1n << 100n)" => false); + let mut context = Context::new(); + check_comparison!(context, "NaN < -10000000000n" => false); + check_comparison!(context, "NaN < (-1n << 100n)" => false); } #[test] fn bigint_less_than_nan() { - let mut engine = Context::new(); - check_comparison!(engine, "1000n < Infinity" => true); - check_comparison!(engine, "(1n << 100n) < Infinity" => true); + let mut context = Context::new(); + check_comparison!(context, "1000n < Infinity" => true); + check_comparison!(context, "(1n << 100n) < Infinity" => true); } #[test] fn bigint_less_than_string() { - let mut engine = Context::new(); - check_comparison!(engine, "1000n < '1000'" => false); - check_comparison!(engine, "1000n < '2000'" => true); - check_comparison!(engine, "1n < '-1'" => false); - check_comparison!(engine, "2n < '-1'" => false); - check_comparison!(engine, "-100n < 'InvalidBigInt'" => false); + let mut context = Context::new(); + check_comparison!(context, "1000n < '1000'" => false); + check_comparison!(context, "1000n < '2000'" => true); + check_comparison!(context, "1n < '-1'" => false); + check_comparison!(context, "2n < '-1'" => false); + check_comparison!(context, "-100n < 'InvalidBigInt'" => false); } #[test] fn string_less_than_bigint() { - let mut engine = Context::new(); - check_comparison!(engine, "'1000' < 1000n" => false); - check_comparison!(engine, "'2000' < 1000n" => false); - check_comparison!(engine, "'500' < 1000n" => true); - check_comparison!(engine, "'-1' < 1n" => true); - check_comparison!(engine, "'-1' < 2n" => true); - check_comparison!(engine, "'InvalidBigInt' < -100n" => false); + let mut context = Context::new(); + check_comparison!(context, "'1000' < 1000n" => false); + check_comparison!(context, "'2000' < 1000n" => false); + check_comparison!(context, "'500' < 1000n" => true); + check_comparison!(context, "'-1' < 1n" => true); + check_comparison!(context, "'-1' < 2n" => true); + check_comparison!(context, "'InvalidBigInt' < -100n" => false); } // ------------------------------------------- #[test] fn number_less_than_or_equal_number() { - let mut engine = Context::new(); - check_comparison!(engine, "1 <= 2" => true); - check_comparison!(engine, "2 <= 2" => true); - check_comparison!(engine, "3 <= 2" => false); - check_comparison!(engine, "2 <= 2.5" => true); - check_comparison!(engine, "2.5 <= 2" => false); + let mut context = Context::new(); + check_comparison!(context, "1 <= 2" => true); + check_comparison!(context, "2 <= 2" => true); + check_comparison!(context, "3 <= 2" => false); + check_comparison!(context, "2 <= 2.5" => true); + check_comparison!(context, "2.5 <= 2" => false); } #[test] fn string_less_than_or_equal_number() { - let mut engine = Context::new(); - check_comparison!(engine, "'1' <= 2" => true); - check_comparison!(engine, "'2' <= 2" => true); - check_comparison!(engine, "'3' <= 2" => false); - check_comparison!(engine, "'2' <= 2.5" => true); - check_comparison!(engine, "'2.5' < 2" => false); + let mut context = Context::new(); + check_comparison!(context, "'1' <= 2" => true); + check_comparison!(context, "'2' <= 2" => true); + check_comparison!(context, "'3' <= 2" => false); + check_comparison!(context, "'2' <= 2.5" => true); + check_comparison!(context, "'2.5' < 2" => false); } #[test] fn number_less_than_or_equal_string() { - let mut engine = Context::new(); - check_comparison!(engine, "1 <= '2'" => true); - check_comparison!(engine, "2 <= '2'" => true); - check_comparison!(engine, "3 <= '2'" => false); - check_comparison!(engine, "2 <= '2.5'" => true); - check_comparison!(engine, "2.5 <= '2'" => false); + let mut context = Context::new(); + check_comparison!(context, "1 <= '2'" => true); + check_comparison!(context, "2 <= '2'" => true); + check_comparison!(context, "3 <= '2'" => false); + check_comparison!(context, "2 <= '2.5'" => true); + check_comparison!(context, "2.5 <= '2'" => false); } #[test] fn number_object_less_than_or_equal_number() { - 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); - check_comparison!(engine, "new Number(2) <= '2.5'" => true); - check_comparison!(engine, "new Number(2.5) <= '2'" => false); + let mut context = Context::new(); + check_comparison!(context, "new Number(1) <= '2'" => true); + check_comparison!(context, "new Number(2) <= '2'" => true); + check_comparison!(context, "new Number(3) <= '2'" => false); + check_comparison!(context, "new Number(2) <= '2.5'" => true); + check_comparison!(context, "new Number(2.5) <= '2'" => false); } #[test] fn number_object_less_than_number_or_equal_object() { - 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); - check_comparison!(engine, "new Number(2) <= new Number(2.5)" => true); - check_comparison!(engine, "new Number(2.5) <= new Number(2)" => false); + let mut context = Context::new(); + check_comparison!(context, "new Number(1) <= new Number(2)" => true); + check_comparison!(context, "new Number(2) <= new Number(2)" => true); + check_comparison!(context, "new Number(3) <= new Number(2)" => false); + check_comparison!(context, "new Number(2) <= new Number(2.5)" => true); + check_comparison!(context, "new Number(2.5) <= new Number(2)" => false); } #[test] fn string_less_than_or_equal_string() { - let mut engine = Context::new(); - check_comparison!(engine, "'hello' <= 'hello'" => true); - check_comparison!(engine, "'hell' <= 'hello'" => true); - check_comparison!(engine, "'hello, world' <= 'world'" => true); - check_comparison!(engine, "'aa' <= 'ab'" => true); + let mut context = Context::new(); + check_comparison!(context, "'hello' <= 'hello'" => true); + check_comparison!(context, "'hell' <= 'hello'" => true); + check_comparison!(context, "'hello, world' <= 'world'" => true); + check_comparison!(context, "'aa' <= 'ab'" => true); } #[test] fn string_object_less_than_or_equal_string() { - 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); - check_comparison!(engine, "new String('aa') <= 'ab'" => true); + let mut context = Context::new(); + check_comparison!(context, "new String('hello') <= 'hello'" => true); + check_comparison!(context, "new String('hell') <= 'hello'" => true); + check_comparison!(context, "new String('hello, world') <= 'world'" => true); + check_comparison!(context, "new String('aa') <= 'ab'" => true); } #[test] fn string_object_less_than_string_or_equal_object() { - 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); - check_comparison!(engine, "new String('aa') <= new String('ab')" => true); + let mut context = Context::new(); + check_comparison!(context, "new String('hello') <= new String('hello')" => true); + check_comparison!(context, "new String('hell') <= new String('hello')" => true); + check_comparison!(context, "new String('hello, world') <= new String('world')" => true); + check_comparison!(context, "new String('aa') <= new String('ab')" => true); } #[test] fn bigint_less_than_or_equal_number() { - let mut engine = Context::new(); - check_comparison!(engine, "1n <= 10" => true); - check_comparison!(engine, "10n <= 10" => true); - check_comparison!(engine, "100n <= 10" => false); - check_comparison!(engine, "10n <= 10.9" => true); + let mut context = Context::new(); + check_comparison!(context, "1n <= 10" => true); + check_comparison!(context, "10n <= 10" => true); + check_comparison!(context, "100n <= 10" => false); + check_comparison!(context, "10n <= 10.9" => true); } #[test] fn number_less_than_or_equal_bigint() { - let mut engine = Context::new(); - check_comparison!(engine, "10 <= 1n" => false); - check_comparison!(engine, "1 <= 1n" => true); - check_comparison!(engine, "-1 <= -1n" => true); - check_comparison!(engine, "-1.9 <= -1n" => true); + let mut context = Context::new(); + check_comparison!(context, "10 <= 1n" => false); + check_comparison!(context, "1 <= 1n" => true); + check_comparison!(context, "-1 <= -1n" => true); + check_comparison!(context, "-1.9 <= -1n" => true); } #[test] fn negative_infnity_less_than_or_equal_bigint() { - let mut engine = Context::new(); - check_comparison!(engine, "-Infinity <= -10000000000n" => true); - check_comparison!(engine, "-Infinity <= (-1n << 100n)" => true); + let mut context = Context::new(); + check_comparison!(context, "-Infinity <= -10000000000n" => true); + check_comparison!(context, "-Infinity <= (-1n << 100n)" => true); } #[test] fn bigint_less_than_or_equal_infinity() { - let mut engine = Context::new(); - check_comparison!(engine, "1000n <= NaN" => false); - check_comparison!(engine, "(1n << 100n) <= NaN" => false); + let mut context = Context::new(); + check_comparison!(context, "1000n <= NaN" => false); + check_comparison!(context, "(1n << 100n) <= NaN" => false); } #[test] fn nan_less_than_or_equal_bigint() { - let mut engine = Context::new(); - check_comparison!(engine, "NaN <= -10000000000n" => false); - check_comparison!(engine, "NaN <= (-1n << 100n)" => false); + let mut context = Context::new(); + check_comparison!(context, "NaN <= -10000000000n" => false); + check_comparison!(context, "NaN <= (-1n << 100n)" => false); } #[test] fn bigint_less_than_or_equal_nan() { - let mut engine = Context::new(); - check_comparison!(engine, "1000n <= Infinity" => true); - check_comparison!(engine, "(1n << 100n) <= Infinity" => true); + let mut context = Context::new(); + check_comparison!(context, "1000n <= Infinity" => true); + check_comparison!(context, "(1n << 100n) <= Infinity" => true); } #[test] fn bigint_less_than_or_equal_string() { - let mut engine = Context::new(); - check_comparison!(engine, "1000n <= '1000'" => true); - check_comparison!(engine, "1000n <= '2000'" => true); - check_comparison!(engine, "1n <= '-1'" => false); - check_comparison!(engine, "2n <= '-1'" => false); - check_comparison!(engine, "-100n <= 'InvalidBigInt'" => false); + let mut context = Context::new(); + check_comparison!(context, "1000n <= '1000'" => true); + check_comparison!(context, "1000n <= '2000'" => true); + check_comparison!(context, "1n <= '-1'" => false); + check_comparison!(context, "2n <= '-1'" => false); + check_comparison!(context, "-100n <= 'InvalidBigInt'" => false); } #[test] fn string_less_than_or_equal_bigint() { - let mut engine = Context::new(); - check_comparison!(engine, "'1000' <= 1000n" => true); - check_comparison!(engine, "'2000' <= 1000n" => false); - check_comparison!(engine, "'500' <= 1000n" => true); - check_comparison!(engine, "'-1' <= 1n" => true); - check_comparison!(engine, "'-1' <= 2n" => true); - check_comparison!(engine, "'InvalidBigInt' <= -100n" => false); + let mut context = Context::new(); + check_comparison!(context, "'1000' <= 1000n" => true); + check_comparison!(context, "'2000' <= 1000n" => false); + check_comparison!(context, "'500' <= 1000n" => true); + check_comparison!(context, "'-1' <= 1n" => true); + check_comparison!(context, "'-1' <= 2n" => true); + check_comparison!(context, "'InvalidBigInt' <= -100n" => false); } // ------------------------------------------- #[test] fn number_greater_than_number() { - let mut engine = Context::new(); - check_comparison!(engine, "1 > 2" => false); - check_comparison!(engine, "2 > 2" => false); - check_comparison!(engine, "3 > 2" => true); - check_comparison!(engine, "2 > 2.5" => false); - check_comparison!(engine, "2.5 > 2" => true); + let mut context = Context::new(); + check_comparison!(context, "1 > 2" => false); + check_comparison!(context, "2 > 2" => false); + check_comparison!(context, "3 > 2" => true); + check_comparison!(context, "2 > 2.5" => false); + check_comparison!(context, "2.5 > 2" => true); } #[test] fn string_greater_than_number() { - let mut engine = Context::new(); - check_comparison!(engine, "'1' > 2" => false); - check_comparison!(engine, "'2' > 2" => false); - check_comparison!(engine, "'3' > 2" => true); - check_comparison!(engine, "'2' > 2.5" => false); - check_comparison!(engine, "'2.5' > 2" => true); + let mut context = Context::new(); + check_comparison!(context, "'1' > 2" => false); + check_comparison!(context, "'2' > 2" => false); + check_comparison!(context, "'3' > 2" => true); + check_comparison!(context, "'2' > 2.5" => false); + check_comparison!(context, "'2.5' > 2" => true); } #[test] fn number_less_greater_string() { - let mut engine = Context::new(); - check_comparison!(engine, "1 > '2'" => false); - check_comparison!(engine, "2 > '2'" => false); - check_comparison!(engine, "3 > '2'" => true); - check_comparison!(engine, "2 > '2.5'" => false); - check_comparison!(engine, "2.5 > '2'" => true); + let mut context = Context::new(); + check_comparison!(context, "1 > '2'" => false); + check_comparison!(context, "2 > '2'" => false); + check_comparison!(context, "3 > '2'" => true); + check_comparison!(context, "2 > '2.5'" => false); + check_comparison!(context, "2.5 > '2'" => true); } #[test] fn number_object_greater_than_number() { - 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); - check_comparison!(engine, "new Number(2) > '2.5'" => false); - check_comparison!(engine, "new Number(2.5) > '2'" => true); + let mut context = Context::new(); + check_comparison!(context, "new Number(1) > '2'" => false); + check_comparison!(context, "new Number(2) > '2'" => false); + check_comparison!(context, "new Number(3) > '2'" => true); + check_comparison!(context, "new Number(2) > '2.5'" => false); + check_comparison!(context, "new Number(2.5) > '2'" => true); } #[test] fn number_object_greater_than_number_object() { - 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); - check_comparison!(engine, "new Number(2) > new Number(2.5)" => false); - check_comparison!(engine, "new Number(2.5) > new Number(2)" => true); + let mut context = Context::new(); + check_comparison!(context, "new Number(1) > new Number(2)" => false); + check_comparison!(context, "new Number(2) > new Number(2)" => false); + check_comparison!(context, "new Number(3) > new Number(2)" => true); + check_comparison!(context, "new Number(2) > new Number(2.5)" => false); + check_comparison!(context, "new Number(2.5) > new Number(2)" => true); } #[test] fn string_greater_than_string() { - let mut engine = Context::new(); - check_comparison!(engine, "'hello' > 'hello'" => false); - check_comparison!(engine, "'hell' > 'hello'" => false); - check_comparison!(engine, "'hello, world' > 'world'" => false); - check_comparison!(engine, "'aa' > 'ab'" => false); - check_comparison!(engine, "'ab' > 'aa'" => true); + let mut context = Context::new(); + check_comparison!(context, "'hello' > 'hello'" => false); + check_comparison!(context, "'hell' > 'hello'" => false); + check_comparison!(context, "'hello, world' > 'world'" => false); + check_comparison!(context, "'aa' > 'ab'" => false); + check_comparison!(context, "'ab' > 'aa'" => true); } #[test] fn string_object_greater_than_string() { - 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); - check_comparison!(engine, "new String('aa') > 'ab'" => false); - check_comparison!(engine, "new String('ab') > 'aa'" => true); + let mut context = Context::new(); + check_comparison!(context, "new String('hello') > 'hello'" => false); + check_comparison!(context, "new String('hell') > 'hello'" => false); + check_comparison!(context, "new String('hello, world') > 'world'" => false); + check_comparison!(context, "new String('aa') > 'ab'" => false); + check_comparison!(context, "new String('ab') > 'aa'" => true); } #[test] fn string_object_greater_than_string_object() { - 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); - check_comparison!(engine, "new String('aa') > new String('ab')" => false); - check_comparison!(engine, "new String('ab') > new String('aa')" => true); + let mut context = Context::new(); + check_comparison!(context, "new String('hello') > new String('hello')" => false); + check_comparison!(context, "new String('hell') > new String('hello')" => false); + check_comparison!(context, "new String('hello, world') > new String('world')" => false); + check_comparison!(context, "new String('aa') > new String('ab')" => false); + check_comparison!(context, "new String('ab') > new String('aa')" => true); } #[test] fn bigint_greater_than_number() { - let mut engine = Context::new(); - check_comparison!(engine, "1n > 10" => false); - check_comparison!(engine, "10n > 10" => false); - check_comparison!(engine, "100n > 10" => true); - check_comparison!(engine, "10n > 10.9" => false); + let mut context = Context::new(); + check_comparison!(context, "1n > 10" => false); + check_comparison!(context, "10n > 10" => false); + check_comparison!(context, "100n > 10" => true); + check_comparison!(context, "10n > 10.9" => false); } #[test] fn number_greater_than_bigint() { - let mut engine = Context::new(); - check_comparison!(engine, "10 > 1n" => true); - check_comparison!(engine, "1 > 1n" => false); - check_comparison!(engine, "-1 > -1n" => false); - check_comparison!(engine, "-1.9 > -1n" => false); + let mut context = Context::new(); + check_comparison!(context, "10 > 1n" => true); + check_comparison!(context, "1 > 1n" => false); + check_comparison!(context, "-1 > -1n" => false); + check_comparison!(context, "-1.9 > -1n" => false); } #[test] fn negative_infnity_greater_than_bigint() { - let mut engine = Context::new(); - check_comparison!(engine, "-Infinity > -10000000000n" => false); - check_comparison!(engine, "-Infinity > (-1n << 100n)" => false); + let mut context = Context::new(); + check_comparison!(context, "-Infinity > -10000000000n" => false); + check_comparison!(context, "-Infinity > (-1n << 100n)" => false); } #[test] fn bigint_greater_than_infinity() { - let mut engine = Context::new(); - check_comparison!(engine, "1000n > NaN" => false); - check_comparison!(engine, "(1n << 100n) > NaN" => false); + let mut context = Context::new(); + check_comparison!(context, "1000n > NaN" => false); + check_comparison!(context, "(1n << 100n) > NaN" => false); } #[test] fn nan_greater_than_bigint() { - let mut engine = Context::new(); - check_comparison!(engine, "NaN > -10000000000n" => false); - check_comparison!(engine, "NaN > (-1n << 100n)" => false); + let mut context = Context::new(); + check_comparison!(context, "NaN > -10000000000n" => false); + check_comparison!(context, "NaN > (-1n << 100n)" => false); } #[test] fn bigint_greater_than_nan() { - let mut engine = Context::new(); - check_comparison!(engine, "1000n > Infinity" => false); - check_comparison!(engine, "(1n << 100n) > Infinity" => false); + let mut context = Context::new(); + check_comparison!(context, "1000n > Infinity" => false); + check_comparison!(context, "(1n << 100n) > Infinity" => false); } #[test] fn bigint_greater_than_string() { - let mut engine = Context::new(); - check_comparison!(engine, "1000n > '1000'" => false); - check_comparison!(engine, "1000n > '2000'" => false); - check_comparison!(engine, "1n > '-1'" => true); - check_comparison!(engine, "2n > '-1'" => true); - check_comparison!(engine, "-100n > 'InvalidBigInt'" => false); + let mut context = Context::new(); + check_comparison!(context, "1000n > '1000'" => false); + check_comparison!(context, "1000n > '2000'" => false); + check_comparison!(context, "1n > '-1'" => true); + check_comparison!(context, "2n > '-1'" => true); + check_comparison!(context, "-100n > 'InvalidBigInt'" => false); } #[test] fn string_greater_than_bigint() { - let mut engine = Context::new(); - check_comparison!(engine, "'1000' > 1000n" => false); - check_comparison!(engine, "'2000' > 1000n" => true); - check_comparison!(engine, "'500' > 1000n" => false); - check_comparison!(engine, "'-1' > 1n" => false); - check_comparison!(engine, "'-1' > 2n" => false); - check_comparison!(engine, "'InvalidBigInt' > -100n" => false); + let mut context = Context::new(); + check_comparison!(context, "'1000' > 1000n" => false); + check_comparison!(context, "'2000' > 1000n" => true); + check_comparison!(context, "'500' > 1000n" => false); + check_comparison!(context, "'-1' > 1n" => false); + check_comparison!(context, "'-1' > 2n" => false); + check_comparison!(context, "'InvalidBigInt' > -100n" => false); } // ---------------------------------------------- #[test] fn number_greater_than_or_equal_number() { - let mut engine = Context::new(); - check_comparison!(engine, "1 >= 2" => false); - check_comparison!(engine, "2 >= 2" => true); - check_comparison!(engine, "3 >= 2" => true); - check_comparison!(engine, "2 >= 2.5" => false); - check_comparison!(engine, "2.5 >= 2" => true); + let mut context = Context::new(); + check_comparison!(context, "1 >= 2" => false); + check_comparison!(context, "2 >= 2" => true); + check_comparison!(context, "3 >= 2" => true); + check_comparison!(context, "2 >= 2.5" => false); + check_comparison!(context, "2.5 >= 2" => true); } #[test] fn string_greater_than_or_equal_number() { - let mut engine = Context::new(); - check_comparison!(engine, "'1' >= 2" => false); - check_comparison!(engine, "'2' >= 2" => true); - check_comparison!(engine, "'3' >= 2" => true); - check_comparison!(engine, "'2' >= 2.5" => false); - check_comparison!(engine, "'2.5' >= 2" => true); + let mut context = Context::new(); + check_comparison!(context, "'1' >= 2" => false); + check_comparison!(context, "'2' >= 2" => true); + check_comparison!(context, "'3' >= 2" => true); + check_comparison!(context, "'2' >= 2.5" => false); + check_comparison!(context, "'2.5' >= 2" => true); } #[test] fn number_less_greater_or_equal_string() { - let mut engine = Context::new(); - check_comparison!(engine, "1 >= '2'" => false); - check_comparison!(engine, "2 >= '2'" => true); - check_comparison!(engine, "3 >= '2'" => true); - check_comparison!(engine, "2 >= '2.5'" => false); - check_comparison!(engine, "2.5 >= '2'" => true); + let mut context = Context::new(); + check_comparison!(context, "1 >= '2'" => false); + check_comparison!(context, "2 >= '2'" => true); + check_comparison!(context, "3 >= '2'" => true); + check_comparison!(context, "2 >= '2.5'" => false); + check_comparison!(context, "2.5 >= '2'" => true); } #[test] fn number_object_greater_than_or_equal_number() { - 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); - check_comparison!(engine, "new Number(2) >= '2.5'" => false); - check_comparison!(engine, "new Number(2.5) >= '2'" => true); + let mut context = Context::new(); + check_comparison!(context, "new Number(1) >= '2'" => false); + check_comparison!(context, "new Number(2) >= '2'" => true); + check_comparison!(context, "new Number(3) >= '2'" => true); + check_comparison!(context, "new Number(2) >= '2.5'" => false); + check_comparison!(context, "new Number(2.5) >= '2'" => true); } #[test] fn number_object_greater_than_or_equal_number_object() { - 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); - check_comparison!(engine, "new Number(2) >= new Number(2.5)" => false); - check_comparison!(engine, "new Number(2.5) >= new Number(2)" => true); + let mut context = Context::new(); + check_comparison!(context, "new Number(1) >= new Number(2)" => false); + check_comparison!(context, "new Number(2) >= new Number(2)" => true); + check_comparison!(context, "new Number(3) >= new Number(2)" => true); + check_comparison!(context, "new Number(2) >= new Number(2.5)" => false); + check_comparison!(context, "new Number(2.5) >= new Number(2)" => true); } #[test] fn string_greater_than_or_equal_string() { - let mut engine = Context::new(); - check_comparison!(engine, "'hello' >= 'hello'" => true); - check_comparison!(engine, "'hell' >= 'hello'" => false); - check_comparison!(engine, "'hello, world' >= 'world'" => false); - check_comparison!(engine, "'aa' >= 'ab'" => false); - check_comparison!(engine, "'ab' >= 'aa'" => true); + let mut context = Context::new(); + check_comparison!(context, "'hello' >= 'hello'" => true); + check_comparison!(context, "'hell' >= 'hello'" => false); + check_comparison!(context, "'hello, world' >= 'world'" => false); + check_comparison!(context, "'aa' >= 'ab'" => false); + check_comparison!(context, "'ab' >= 'aa'" => true); } #[test] fn string_object_greater_or_equal_than_string() { - 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); - check_comparison!(engine, "new String('aa') >= 'ab'" => false); - check_comparison!(engine, "new String('ab') >= 'aa'" => true); + let mut context = Context::new(); + check_comparison!(context, "new String('hello') >= 'hello'" => true); + check_comparison!(context, "new String('hell') >= 'hello'" => false); + check_comparison!(context, "new String('hello, world') >= 'world'" => false); + check_comparison!(context, "new String('aa') >= 'ab'" => false); + check_comparison!(context, "new String('ab') >= 'aa'" => true); } #[test] fn string_object_greater_than_or_equal_string_object() { - 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); - check_comparison!(engine, "new String('aa') >= new String('ab')" => false); - check_comparison!(engine, "new String('ab') >= new String('aa')" => true); + let mut context = Context::new(); + check_comparison!(context, "new String('hello') >= new String('hello')" => true); + check_comparison!(context, "new String('hell') >= new String('hello')" => false); + check_comparison!(context, "new String('hello, world') >= new String('world')" => false); + check_comparison!(context, "new String('aa') >= new String('ab')" => false); + check_comparison!(context, "new String('ab') >= new String('aa')" => true); } #[test] fn bigint_greater_than_or_equal_number() { - let mut engine = Context::new(); - check_comparison!(engine, "1n >= 10" => false); - check_comparison!(engine, "10n >= 10" => true); - check_comparison!(engine, "100n >= 10" => true); - check_comparison!(engine, "10n >= 10.9" => false); + let mut context = Context::new(); + check_comparison!(context, "1n >= 10" => false); + check_comparison!(context, "10n >= 10" => true); + check_comparison!(context, "100n >= 10" => true); + check_comparison!(context, "10n >= 10.9" => false); } #[test] fn number_greater_than_or_equal_bigint() { - let mut engine = Context::new(); - check_comparison!(engine, "10 >= 1n" => true); - check_comparison!(engine, "1 >= 1n" => true); - check_comparison!(engine, "-1 >= -1n" => true); - check_comparison!(engine, "-1.9 >= -1n" => false); + let mut context = Context::new(); + check_comparison!(context, "10 >= 1n" => true); + check_comparison!(context, "1 >= 1n" => true); + check_comparison!(context, "-1 >= -1n" => true); + check_comparison!(context, "-1.9 >= -1n" => false); } #[test] fn negative_infnity_greater_or_equal_than_bigint() { - let mut engine = Context::new(); - check_comparison!(engine, "-Infinity >= -10000000000n" => false); - check_comparison!(engine, "-Infinity >= (-1n << 100n)" => false); + let mut context = Context::new(); + check_comparison!(context, "-Infinity >= -10000000000n" => false); + check_comparison!(context, "-Infinity >= (-1n << 100n)" => false); } #[test] fn bigint_greater_than_or_equal_infinity() { - let mut engine = Context::new(); - check_comparison!(engine, "1000n >= NaN" => false); - check_comparison!(engine, "(1n << 100n) >= NaN" => false); + let mut context = Context::new(); + check_comparison!(context, "1000n >= NaN" => false); + check_comparison!(context, "(1n << 100n) >= NaN" => false); } #[test] fn nan_greater_than_or_equal_bigint() { - let mut engine = Context::new(); - check_comparison!(engine, "NaN >= -10000000000n" => false); - check_comparison!(engine, "NaN >= (-1n << 100n)" => false); + let mut context = Context::new(); + check_comparison!(context, "NaN >= -10000000000n" => false); + check_comparison!(context, "NaN >= (-1n << 100n)" => false); } #[test] fn bigint_greater_than_or_equal_nan() { - let mut engine = Context::new(); - check_comparison!(engine, "1000n >= Infinity" => false); - check_comparison!(engine, "(1n << 100n) >= Infinity" => false); + let mut context = Context::new(); + check_comparison!(context, "1000n >= Infinity" => false); + check_comparison!(context, "(1n << 100n) >= Infinity" => false); } #[test] fn bigint_greater_than_or_equal_string() { - let mut engine = Context::new(); - check_comparison!(engine, "1000n >= '1000'" => true); - check_comparison!(engine, "1000n >= '2000'" => false); - check_comparison!(engine, "1n >= '-1'" => true); - check_comparison!(engine, "2n >= '-1'" => true); - check_comparison!(engine, "-100n >= 'InvalidBigInt'" => false); + let mut context = Context::new(); + check_comparison!(context, "1000n >= '1000'" => true); + check_comparison!(context, "1000n >= '2000'" => false); + check_comparison!(context, "1n >= '-1'" => true); + check_comparison!(context, "2n >= '-1'" => true); + check_comparison!(context, "-100n >= 'InvalidBigInt'" => false); } #[test] fn string_greater_than_or_equal_bigint() { - let mut engine = Context::new(); - check_comparison!(engine, "'1000' >= 1000n" => true); - check_comparison!(engine, "'2000' >= 1000n" => true); - check_comparison!(engine, "'500' >= 1000n" => false); - check_comparison!(engine, "'-1' >= 1n" => false); - check_comparison!(engine, "'-1' >= 2n" => false); - check_comparison!(engine, "'InvalidBigInt' >= -100n" => false); + let mut context = Context::new(); + check_comparison!(context, "'1000' >= 1000n" => true); + check_comparison!(context, "'2000' >= 1000n" => true); + check_comparison!(context, "'500' >= 1000n" => false); + check_comparison!(context, "'-1' >= 1n" => false); + check_comparison!(context, "'-1' >= 2n" => false); + check_comparison!(context, "'InvalidBigInt' >= -100n" => false); } } diff --git a/boa_cli/src/helper.rs b/boa_cli/src/helper.rs index 80567a121a..8806e33f90 100644 --- a/boa_cli/src/helper.rs +++ b/boa_cli/src/helper.rs @@ -41,8 +41,11 @@ impl RLHelper { } impl Validator for RLHelper { - fn validate(&self, ctx: &mut ValidationContext<'_>) -> Result { - self.validator.validate(ctx) + fn validate( + &self, + context: &mut ValidationContext<'_>, + ) -> Result { + self.validator.validate(context) } fn validate_while_typing(&self) -> bool { diff --git a/boa_cli/src/main.rs b/boa_cli/src/main.rs index 7b8264eef1..db776d1fb5 100644 --- a/boa_cli/src/main.rs +++ b/boa_cli/src/main.rs @@ -139,7 +139,7 @@ fn dump(src: &str, args: &Opt) -> Result<(), String> { pub fn main() -> Result<(), std::io::Error> { let args = Opt::from_args(); - let mut engine = Context::new(); + let mut context = Context::new(); for file in &args.files { let buffer = read_to_string(file)?; @@ -149,7 +149,7 @@ pub fn main() -> Result<(), std::io::Error> { eprintln!("{}", e); } } else { - match engine.eval(&buffer) { + match context.eval(&buffer) { Ok(v) => println!("{}", v.display()), Err(v) => eprintln!("Uncaught {}", v.display()), } @@ -185,7 +185,7 @@ pub fn main() -> Result<(), std::io::Error> { eprintln!("{}", e); } } else { - match engine.eval(line.trim_end()) { + match context.eval(line.trim_end()) { Ok(v) => println!("{}", v.display()), Err(v) => { eprintln!("{}: {}", "Uncaught".red(), v.display().to_string().red()) diff --git a/boa_tester/src/exec.rs b/boa_tester/src/exec.rs index 7eb45d271f..5ac6f5a0d2 100644 --- a/boa_tester/src/exec.rs +++ b/boa_tester/src/exec.rs @@ -127,8 +127,8 @@ impl Test { // TODO: implement async and add `harness/doneprintHandle.js` to the includes. match self.set_up_env(&harness, strict) { - Ok(mut engine) => { - let res = engine.eval(&self.content); + Ok(mut context) => { + let res = context.eval(&self.content); let passed = res.is_ok(); let text = match res { @@ -173,7 +173,7 @@ impl Test { (false, format!("Uncaught {}", e)) } else { match self.set_up_env(&harness, strict) { - Ok(mut engine) => match engine.eval(&self.content) { + Ok(mut context) => match context.eval(&self.content) { Ok(res) => (false, format!("{}", res.display())), Err(e) => { let passed = @@ -251,10 +251,10 @@ impl Test { fn set_up_env(&self, harness: &Harness, strict: bool) -> Result { // Create new Realm // TODO: in parallel. - let mut engine = Context::new(); + let mut context = Context::new(); // Register the print() function. - engine + context .register_global_function("print", 1, test262_print) .map_err(|e| { format!( @@ -265,20 +265,20 @@ impl Test { // TODO: add the $262 object. if strict { - engine + context .eval(r#""use strict";"#) .map_err(|e| format!("could not set strict mode:\n{}", e.display()))?; } - engine + context .eval(&harness.assert) .map_err(|e| format!("could not run assert.js:\n{}", e.display()))?; - engine + context .eval(&harness.sta) .map_err(|e| format!("could not run sta.js:\n{}", e.display()))?; for include in self.includes.iter() { - engine + context .eval( &harness .includes @@ -294,11 +294,11 @@ impl Test { })?; } - Ok(engine) + Ok(context) } } /// `print()` function required by the test262 suite. -fn test262_print(_this: &Value, _args: &[Value], _context: &mut Context) -> boa::Result { +fn test262_print(_this: &Value, _: &[Value], _context: &mut Context) -> boa::Result { todo!("print() function"); } diff --git a/boa_tester/src/main.rs b/boa_tester/src/main.rs index d6aaf1e2ac..f9cb8dab8c 100644 --- a/boa_tester/src/main.rs +++ b/boa_tester/src/main.rs @@ -1,7 +1,7 @@ //! Test262 test runner //! //! This crate will run the full ECMAScript test suite (Test262) and report compliance of the -//! `boa` engine. +//! `boa` context. #![doc( html_logo_url = "https://raw.githubusercontent.com/jasonwilliams/boa/master/assets/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/jasonwilliams/boa/master/assets/logo.svg" diff --git a/boa_wasm/src/lib.rs b/boa_wasm/src/lib.rs index b995c7396e..1b90a1f54b 100644 --- a/boa_wasm/src/lib.rs +++ b/boa_wasm/src/lib.rs @@ -4,14 +4,14 @@ use wasm_bindgen::prelude::*; #[wasm_bindgen] pub fn evaluate(src: &str) -> Result { // Setup executor - let mut engine = Context::new(); + let mut context = Context::new(); let expr = match parse(src, false) { Ok(res) => res, Err(e) => { return Err(format!( "Uncaught {}", - engine + context .throw_syntax_error(e.to_string()) .expect_err("interpreter.throw_syntax_error() did not return an error") .display() @@ -19,7 +19,7 @@ pub fn evaluate(src: &str) -> Result { .into()); } }; - expr.run(&mut engine) + expr.run(&mut context) .map_err(|e| JsValue::from(format!("Uncaught {}", e.display()))) .map(|v| v.display().to_string()) } diff --git a/test262 b/test262 index 0e7319c015..0001489473 160000 --- a/test262 +++ b/test262 @@ -1 +1 @@ -Subproject commit 0e7319c015fe935594f8bcafaedb0c94f7fec1df +Subproject commit 00014894735c3bee62bed234594abf387ea0c57b