From 62ad20cfde0a545f35d8af07c36cd5d32a7479f4 Mon Sep 17 00:00:00 2001 From: Halid Odat Date: Thu, 12 Aug 2021 02:03:19 +0200 Subject: [PATCH] Rename `Value` to `JsValue` (#1457) --- boa/examples/classes.rs | 8 +- boa/examples/closures.rs | 4 +- boa/src/bigint.rs | 8 +- boa/src/builtins/array/array_iterator.rs | 34 +- boa/src/builtins/array/mod.rs | 258 +++++++++------ boa/src/builtins/array/tests.rs | 80 ++--- boa/src/builtins/bigint/mod.rs | 52 ++- boa/src/builtins/boolean/mod.rs | 36 +- boa/src/builtins/boolean/tests.rs | 4 +- boa/src/builtins/console/mod.rs | 94 +++--- boa/src/builtins/console/tests.rs | 27 +- boa/src/builtins/date/mod.rs | 64 ++-- boa/src/builtins/date/tests.rs | 110 +++--- boa/src/builtins/error/eval.rs | 12 +- boa/src/builtins/error/mod.rs | 18 +- boa/src/builtins/error/range.rs | 12 +- boa/src/builtins/error/reference.rs | 12 +- boa/src/builtins/error/syntax.rs | 12 +- boa/src/builtins/error/type.rs | 12 +- boa/src/builtins/error/uri.rs | 12 +- boa/src/builtins/function/mod.rs | 32 +- boa/src/builtins/global_this/mod.rs | 4 +- boa/src/builtins/infinity/mod.rs | 4 +- boa/src/builtins/iterable/mod.rs | 24 +- boa/src/builtins/json/mod.rs | 60 ++-- boa/src/builtins/json/tests.rs | 13 +- boa/src/builtins/map/map_iterator.rs | 34 +- boa/src/builtins/map/mod.rs | 106 +++--- boa/src/builtins/map/ordered_map.rs | 18 +- boa/src/builtins/math/mod.rs | 74 ++--- boa/src/builtins/mod.rs | 4 +- boa/src/builtins/nan/mod.rs | 4 +- boa/src/builtins/number/mod.rs | 184 ++++++----- boa/src/builtins/object/for_in_iterator.rs | 26 +- boa/src/builtins/object/mod.rs | 122 ++++--- boa/src/builtins/object/tests.rs | 6 +- boa/src/builtins/reflect/mod.rs | 86 ++--- boa/src/builtins/regexp/mod.rs | 185 +++++++---- .../builtins/regexp/regexp_string_iterator.rs | 30 +- boa/src/builtins/set/mod.rs | 70 ++-- boa/src/builtins/set/set_iterator.rs | 34 +- boa/src/builtins/string/mod.rs | 312 ++++++++++++------ boa/src/builtins/string/string_iterator.rs | 30 +- boa/src/builtins/symbol/mod.rs | 36 +- boa/src/builtins/undefined/mod.rs | 6 +- boa/src/bytecompiler.rs | 6 +- boa/src/class.rs | 18 +- boa/src/context.rs | 53 +-- .../declarative_environment_record.rs | 19 +- .../environment/environment_record_trait.rs | 21 +- .../function_environment_record.rs | 35 +- .../environment/global_environment_record.rs | 25 +- boa/src/environment/lexical_environment.rs | 10 +- .../environment/object_environment_record.rs | 27 +- boa/src/exec/mod.rs | 4 +- boa/src/exec/tests.rs | 66 ++-- boa/src/lib.rs | 6 +- boa/src/object/gcobject.rs | 50 +-- boa/src/object/internal_methods.rs | 46 +-- boa/src/object/mod.rs | 56 ++-- boa/src/property/mod.rs | 56 ++-- boa/src/syntax/ast/node/array/mod.rs | 4 +- boa/src/syntax/ast/node/await_expr/mod.rs | 6 +- boa/src/syntax/ast/node/block/mod.rs | 6 +- boa/src/syntax/ast/node/break_node/mod.rs | 6 +- boa/src/syntax/ast/node/call/mod.rs | 9 +- .../node/conditional/conditional_op/mod.rs | 4 +- .../ast/node/conditional/if_node/mod.rs | 6 +- .../declaration/arrow_function_decl/mod.rs | 4 +- .../declaration/async_function_decl/mod.rs | 6 +- .../declaration/async_function_expr/mod.rs | 6 +- .../ast/node/declaration/function_decl/mod.rs | 6 +- .../ast/node/declaration/function_expr/mod.rs | 4 +- boa/src/syntax/ast/node/declaration/mod.rs | 8 +- .../ast/node/field/get_const_field/mod.rs | 7 +- .../syntax/ast/node/field/get_field/mod.rs | 7 +- boa/src/syntax/ast/node/identifier/mod.rs | 4 +- .../ast/node/iteration/continue_node/mod.rs | 6 +- .../ast/node/iteration/do_while_loop/mod.rs | 4 +- .../ast/node/iteration/for_in_loop/mod.rs | 8 +- .../syntax/ast/node/iteration/for_loop/mod.rs | 6 +- .../ast/node/iteration/for_of_loop/mod.rs | 6 +- .../ast/node/iteration/while_loop/mod.rs | 6 +- boa/src/syntax/ast/node/mod.rs | 20 +- boa/src/syntax/ast/node/new/mod.rs | 8 +- boa/src/syntax/ast/node/object/mod.rs | 6 +- .../syntax/ast/node/operator/assign/mod.rs | 4 +- .../syntax/ast/node/operator/bin_op/mod.rs | 10 +- .../syntax/ast/node/operator/unary_op/mod.rs | 22 +- boa/src/syntax/ast/node/return_smt/mod.rs | 6 +- boa/src/syntax/ast/node/spread/mod.rs | 4 +- boa/src/syntax/ast/node/statement_list/mod.rs | 6 +- boa/src/syntax/ast/node/switch/mod.rs | 6 +- boa/src/syntax/ast/node/template/mod.rs | 14 +- boa/src/syntax/ast/node/throw/mod.rs | 4 +- boa/src/syntax/ast/node/try_node/mod.rs | 4 +- boa/src/value/conversions.rs | 132 ++++---- boa/src/value/display.rs | 40 +-- boa/src/value/equality.rs | 46 +-- boa/src/value/hash.rs | 6 +- boa/src/value/mod.rs | 216 +++++------- boa/src/value/operations.rs | 257 +++++++-------- boa/src/value/tests.rs | 76 ++--- boa/src/value/type.rs | 4 +- boa/src/vm/code_block.rs | 4 +- boa/src/vm/mod.rs | 26 +- boa_tester/src/exec/js262.rs | 14 +- boa_tester/src/exec/mod.rs | 4 +- 108 files changed, 2121 insertions(+), 1818 deletions(-) diff --git a/boa/examples/classes.rs b/boa/examples/classes.rs index 475ce17b5b..be857f6b71 100644 --- a/boa/examples/classes.rs +++ b/boa/examples/classes.rs @@ -2,7 +2,7 @@ use boa::{ class::{Class, ClassBuilder}, gc::{Finalize, Trace}, property::Attribute, - Context, Result, Value, + Context, JsValue, Result, }; // We create a new struct that is going to represent a person. @@ -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], context: &mut Context) -> Result { + fn say_hello(this: &JsValue, _: &[JsValue], 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`. @@ -37,7 +37,7 @@ impl Person { person.name, person.age // Here we can access the native rust fields of Person struct. ); - return Ok(Value::undefined()); + return Ok(JsValue::undefined()); } } // If `this` was not an object or the type was not an native object `Person`, @@ -57,7 +57,7 @@ impl Class for Person { const LENGTH: usize = 2; // This is what is called when we do `new Person()` - fn constructor(_this: &Value, args: &[Value], context: &mut Context) -> Result { + fn constructor(_this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { // We get the first argument. If it is unavailable we get `undefined`. And, then call `to_string()`. // // This is equivalent to `String(arg)`. diff --git a/boa/examples/closures.rs b/boa/examples/closures.rs index 37f7c355ae..4760e41d76 100644 --- a/boa/examples/closures.rs +++ b/boa/examples/closures.rs @@ -1,6 +1,6 @@ -use boa::{Context, JsString, Value}; +use boa::{Context, JsString, JsValue}; -fn main() -> Result<(), Value> { +fn main() -> Result<(), JsValue> { let mut context = Context::new(); let variable = JsString::new("I am a captured variable"); diff --git a/boa/src/bigint.rs b/boa/src/bigint.rs index fc86fc75fd..c6330d20ab 100644 --- a/boa/src/bigint.rs +++ b/boa/src/bigint.rs @@ -3,7 +3,7 @@ use crate::{ builtins::Number, gc::{empty_trace, Finalize, Trace}, - Context, Value, + Context, JsValue, }; use std::{ @@ -162,7 +162,7 @@ impl JsBigInt { } #[inline] - pub fn pow(x: &Self, y: &Self, context: &mut Context) -> Result { + pub fn pow(x: &Self, y: &Self, context: &mut Context) -> Result { let y = if let Some(y) = y.inner.to_biguint() { y } else { @@ -173,7 +173,7 @@ impl JsBigInt { } #[inline] - pub fn shift_right(x: &Self, y: &Self, context: &mut Context) -> Result { + pub fn shift_right(x: &Self, y: &Self, context: &mut Context) -> Result { if let Some(n) = y.inner.to_i32() { let inner = if n > 0 { x.inner.as_ref().clone().shr(n as usize) @@ -188,7 +188,7 @@ impl JsBigInt { } #[inline] - pub fn shift_left(x: &Self, y: &Self, context: &mut Context) -> Result { + pub fn shift_left(x: &Self, y: &Self, context: &mut Context) -> Result { if let Some(n) = y.inner.to_i32() { let inner = if n > 0 { x.inner.as_ref().clone().shl(n as usize) diff --git a/boa/src/builtins/array/array_iterator.rs b/boa/src/builtins/array/array_iterator.rs index d0a12d30db..e7ff7385d3 100644 --- a/boa/src/builtins/array/array_iterator.rs +++ b/boa/src/builtins/array/array_iterator.rs @@ -1,5 +1,5 @@ use crate::{ - builtins::{function::make_builtin_fn, iterable::create_iter_result_object, Array, Value}, + builtins::{function::make_builtin_fn, iterable::create_iter_result_object, Array, JsValue}, gc::{Finalize, Trace}, object::{GcObject, ObjectData}, property::PropertyDescriptor, @@ -22,7 +22,7 @@ pub enum ArrayIterationKind { /// [spec]: https://tc39.es/ecma262/#sec-array-iterator-objects #[derive(Debug, Clone, Finalize, Trace)] pub struct ArrayIterator { - array: Value, + array: JsValue, next_index: u32, kind: ArrayIterationKind, } @@ -30,7 +30,7 @@ pub struct ArrayIterator { impl ArrayIterator { pub(crate) const NAME: &'static str = "ArrayIterator"; - fn new(array: Value, kind: ArrayIterationKind) -> Self { + fn new(array: JsValue, kind: ArrayIterationKind) -> Self { ArrayIterator { array, kind, @@ -48,10 +48,10 @@ impl ArrayIterator { /// [spec]: https://tc39.es/ecma262/#sec-createarrayiterator pub(crate) fn create_array_iterator( context: &Context, - array: Value, + array: JsValue, kind: ArrayIterationKind, - ) -> Value { - let array_iterator = Value::new_object(context); + ) -> JsValue { + let array_iterator = JsValue::new_object(context); array_iterator.set_data(ObjectData::ArrayIterator(Self::new(array, kind))); array_iterator .as_object() @@ -68,13 +68,17 @@ impl ArrayIterator { /// - [ECMA reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-%arrayiteratorprototype%.next - pub(crate) fn next(this: &Value, _: &[Value], context: &mut Context) -> Result { - if let Value::Object(ref object) = this { + pub(crate) fn next(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { + if let JsValue::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(context, Value::undefined(), true)); + return Ok(create_iter_result_object( + context, + JsValue::undefined(), + true, + )); } let len = array_iterator .array @@ -83,8 +87,12 @@ impl ArrayIterator { .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(context, Value::undefined(), true)); + array_iterator.array = JsValue::undefined(); + return Ok(create_iter_result_object( + context, + JsValue::undefined(), + true, + )); } array_iterator.next_index = index + 1; match array_iterator.kind { @@ -98,7 +106,7 @@ impl ArrayIterator { ArrayIterationKind::KeyAndValue => { let element_value = array_iterator.array.get_field(index, context)?; let result = Array::constructor( - &Value::new_object(context), + &JsValue::new_object(context), &[index.into(), element_value], context, )?; @@ -119,7 +127,7 @@ impl ArrayIterator { /// - [ECMA reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-%arrayiteratorprototype%-object - pub(crate) fn create_prototype(context: &mut Context, iterator_prototype: Value) -> GcObject { + pub(crate) fn create_prototype(context: &mut Context, iterator_prototype: JsValue) -> GcObject { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); // Create prototype diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index 756ed1b180..77e167b65a 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -20,7 +20,7 @@ use crate::{ object::{ConstructorBuilder, FunctionBuilder, GcObject, ObjectData, PROTOTYPE}, property::{Attribute, PropertyDescriptor}, symbol::WellKnownSymbols, - value::{IntegerOrInfinity, Value}, + value::{IntegerOrInfinity, JsValue}, BoaProfiler, Context, JsString, Result, }; use std::cmp::{max, min}; @@ -36,7 +36,7 @@ impl BuiltIn for Array { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let symbol_iterator = WellKnownSymbols::iterator(); @@ -119,7 +119,11 @@ impl BuiltIn for Array { impl Array { const LENGTH: usize = 1; - fn constructor(new_target: &Value, args: &[Value], context: &mut Context) -> Result { + fn constructor( + new_target: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget. // 2. Let proto be ? GetPrototypeFromConstructor(newTarget, "%Array.prototype%"). let prototype = new_target @@ -160,7 +164,7 @@ impl Array { // i. Let intLen be ! ToUint32(len). let int_len = len.to_u32(context).unwrap(); // ii. If SameValueZero(intLen, len) is false, throw a RangeError exception. - if !Value::same_value_zero(&int_len.into(), len) { + if !JsValue::same_value_zero(&int_len.into(), len) { return Err(context.construct_range_error("invalid array length")); } int_len @@ -240,8 +244,8 @@ impl Array { } /// Creates a new `Array` instance. - pub(crate) fn new_array(context: &Context) -> Value { - let array = Value::new_object(context); + pub(crate) fn new_array(context: &Context) -> JsValue { + let array = JsValue::new_object(context); array.set_data(ObjectData::Array); array .as_object() @@ -264,10 +268,10 @@ impl Array { /// `array_obj` can be any array with prototype already set (it will be wiped and /// recreated from `array_contents`) pub(crate) fn construct_array( - array_obj: &Value, - array_contents: &[Value], + array_obj: &JsValue, + array_contents: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { let array_obj_ptr = array_obj.clone(); // Wipe existing contents of the array object @@ -305,7 +309,7 @@ impl Array { /// Returns a Boolean valued property that if `true` indicates that /// an object should be flattened to its array elements /// by `Array.prototype.concat`. - fn is_concat_spreadable(this: &Value, context: &mut Context) -> Result { + fn is_concat_spreadable(this: &JsValue, context: &mut Context) -> Result { // 1. If Type(O) is not Object, return false. if !this.is_object() { return Ok(false); @@ -334,7 +338,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-get-array-@@species /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/@@species - fn get_species(this: &Value, _: &[Value], _: &mut Context) -> Result { + fn get_species(this: &JsValue, _: &[JsValue], _: &mut Context) -> Result { // 1. Return the this value. Ok(this.clone()) } @@ -369,7 +373,7 @@ impl Array { let c = c.get(WellKnownSymbols::species(), context)?; // 5.b. If C is null, set C to undefined. if c.is_null_or_undefined() { - Value::undefined() + JsValue::undefined() } else { c } @@ -389,7 +393,7 @@ impl Array { } // 8. Return ? Construct(C, ยซ ๐”ฝ(length) ยป). Ok( - c.construct(&[Value::from(length)], &c.clone().into(), context)? + c.construct(&[JsValue::new(length)], &c.clone().into(), context)? .as_object() .unwrap(), ) @@ -401,10 +405,10 @@ impl Array { /// Utility function which takes an existing array object and puts additional /// values on the end, correctly rewriting the length pub(crate) fn add_to_array_object( - array_ptr: &Value, - add_values: &[Value], + array_ptr: &JsValue, + add_values: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { let orig_length = array_ptr.get_field("length", context)?.to_length(context)?; for (n, value) in add_values.iter().enumerate() { @@ -421,7 +425,7 @@ impl Array { array_ptr.set_field( "length", - Value::from(orig_length.wrapping_add(add_values.len())), + JsValue::new(orig_length.wrapping_add(add_values.len())), false, context, )?; @@ -440,10 +444,10 @@ 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(_: &Value, args: &[Value], _: &mut Context) -> Result { + pub(crate) fn is_array(_: &JsValue, args: &[JsValue], _: &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)), + Some(object) => Ok(JsValue::new(object.borrow().is_array())), + None => Ok(JsValue::new(false)), } } @@ -458,7 +462,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.of /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of - pub(crate) fn of(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn of(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { // 1. Let len be the number of elements in items. // 2. Let lenNumber be ๐”ฝ(len). let len = args.len(); @@ -505,7 +509,11 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.concat /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat - pub(crate) fn concat(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn concat( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let O be ? ToObject(this value). let obj = this.to_object(context)?; // 2. Let A be ? ArraySpeciesCreate(O, 0). @@ -514,7 +522,7 @@ impl Array { let mut n = 0; // 4. Prepend O to items. // 5. For each element E of items, do - for item in [Value::from(obj)].iter().chain(args.iter()) { + for item in [JsValue::new(obj)].iter().chain(args.iter()) { // a. Let spreadable be ? IsConcatSpreadable(E). let spreadable = Self::is_concat_spreadable(item, context)?; // b. If spreadable is true, then @@ -565,7 +573,7 @@ impl Array { arr.set("length", n, true, context)?; // 7. Return A. - Ok(Value::from(arr)) + Ok(JsValue::new(arr)) } /// `Array.prototype.push( ...items )` @@ -580,7 +588,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.push /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push - pub(crate) fn push(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn push(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { // 1. Let O be ? ToObject(this value). let o = this.to_object(context)?; // 2. Let len be ? LengthOfArrayLike(O). @@ -616,7 +624,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.pop /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop - pub(crate) fn pop(this: &Value, _: &[Value], context: &mut Context) -> Result { + pub(crate) fn pop(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { // 1. Let O be ? ToObject(this value). let o = this.to_object(context)?; // 2. Let len be ? LengthOfArrayLike(O). @@ -626,7 +634,7 @@ impl Array { // a. Perform ? Set(O, "length", +0๐”ฝ, true). o.set("length", 0, true, context)?; // b. Return undefined. - Ok(Value::undefined()) + Ok(JsValue::undefined()) // 4. Else, } else { // a. Assert: len > 0. @@ -655,7 +663,11 @@ 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], context: &mut Context) -> Result { + pub(crate) fn for_each( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let O be ? ToObject(this value). let o = this.to_object(context)?; // 2. Let len be ? LengthOfArrayLike(O). @@ -663,7 +675,7 @@ impl Array { // 3. If IsCallable(callbackfn) is false, throw a TypeError exception. let callback = if let Some(arg) = args .get(0) - .and_then(Value::as_object) + .and_then(JsValue::as_object) .filter(GcObject::is_callable) { arg @@ -682,13 +694,13 @@ impl Array { // i. Let kValue be ? Get(O, Pk). let k_value = o.get(pk, context)?; // ii. Perform ? Call(callbackfn, thisArg, ยซ kValue, ๐”ฝ(k), O ยป). - let this_arg = args.get(1).cloned().unwrap_or_else(Value::undefined); + let this_arg = args.get(1).cloned().unwrap_or_else(JsValue::undefined); callback.call(&this_arg, &[k_value, k.into(), o.clone().into()], context)?; } // d. Set k to k + 1. } // 6. Return undefined. - Ok(Value::undefined()) + Ok(JsValue::undefined()) } /// `Array.prototype.join( separator )` @@ -703,7 +715,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.join /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join - pub(crate) fn join(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn join(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { // 1. Let O be ? ToObject(this value). let o = this.to_object(context)?; // 2. Let len be ? LengthOfArrayLike(O). @@ -754,7 +766,11 @@ 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, _: &[Value], context: &mut Context) -> Result { + pub(crate) fn to_string( + this: &JsValue, + _: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let array be ? ToObject(this value). let array = this.to_object(context)?; // 2. Let func be ? Get(array, "join"). @@ -780,7 +796,7 @@ impl Array { /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.reverse /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse #[allow(clippy::else_if_without_else)] - pub(crate) fn reverse(this: &Value, _: &[Value], context: &mut Context) -> Result { + pub(crate) fn reverse(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { // 1. Let O be ? ToObject(this value). let o = this.to_object(context)?; // 2. Let len be ? LengthOfArrayLike(O). @@ -798,7 +814,7 @@ impl Array { // d. Let lowerExists be ? HasProperty(O, lowerP). let lower_exists = o.has_property(lower, context)?; // e. If lowerExists is true, then - let mut lower_value = Value::undefined(); + let mut lower_value = JsValue::undefined(); if lower_exists { // i. Let lowerValue be ? Get(O, lowerP). lower_value = o.get(lower, context)?; @@ -806,7 +822,7 @@ impl Array { // f. Let upperExists be ? HasProperty(O, upperP). let upper_exists = o.has_property(upper, context)?; // g. If upperExists is true, then - let mut upper_value = Value::undefined(); + let mut upper_value = JsValue::undefined(); if upper_exists { // i. Let upperValue be ? Get(O, upperP). upper_value = o.get(upper, context)?; @@ -857,7 +873,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.shift /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift - pub(crate) fn shift(this: &Value, _: &[Value], context: &mut Context) -> Result { + pub(crate) fn shift(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { // 1. Let O be ? ToObject(this value). let o = this.to_object(context)?; // 2. Let len be ? LengthOfArrayLike(O). @@ -867,7 +883,7 @@ impl Array { // a. Perform ? Set(O, "length", +0๐”ฝ, true). o.set("length", 0, true, context)?; // b. Return undefined. - return Ok(Value::undefined()); + return Ok(JsValue::undefined()); } // 4. Let first be ? Get(O, "0"). let first = o.get(0, context)?; @@ -914,7 +930,11 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.unshift /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift - pub(crate) fn unshift(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn unshift( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let O be ? ToObject(this value). let o = this.to_object(context)?; // 2. Let len be ? LengthOfArrayLike(O). @@ -981,7 +1001,11 @@ 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], context: &mut Context) -> Result { + pub(crate) fn every( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let O be ? ToObject(this value). let o = this.to_object(context)?; // 2. Let len be ? LengthOfArrayLike(O). @@ -989,7 +1013,7 @@ impl Array { // 3. If IsCallable(callbackfn) is false, throw a TypeError exception. let callback = if let Some(arg) = args .get(0) - .and_then(Value::as_object) + .and_then(JsValue::as_object) .filter(GcObject::is_callable) { arg @@ -1015,13 +1039,13 @@ impl Array { .to_boolean(); // iii. If testResult is false, return false. if !test_result { - return Ok(Value::from(false)); + return Ok(JsValue::new(false)); } } // d. Set k to k + 1. } // 6. Return true. - Ok(Value::from(true)) + Ok(JsValue::new(true)) } /// `Array.prototype.map( callback, [ thisArg ] )` @@ -1035,7 +1059,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.map /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map - pub(crate) fn map(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn map(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { // 1. Let O be ? ToObject(this value). let o = this.to_object(context)?; // 2. Let len be ? LengthOfArrayLike(O). @@ -1081,7 +1105,11 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.indexof /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf - pub(crate) fn index_of(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn index_of( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let O be ? ToObject(this value). let o = this.to_object(context)?; @@ -1090,7 +1118,7 @@ impl Array { // 3. If len is 0, return -1๐”ฝ. if len == 0 { - return Ok(Value::from(-1)); + return Ok(JsValue::new(-1)); } // 4. Let n be ? ToIntegerOrInfinity(fromIndex). @@ -1102,7 +1130,7 @@ impl Array { // 5. Assert: If fromIndex is undefined, then n is 0. let n = match n { // 6. If n is +โˆž, return -1๐”ฝ. - IntegerOrInfinity::PositiveInfinity => return Ok(Value::from(-1)), + IntegerOrInfinity::PositiveInfinity => return Ok(JsValue::new(-1)), // 7. Else if n is -โˆž, set n to 0. IntegerOrInfinity::NegativeInfinity => 0, IntegerOrInfinity::Integer(value) => value, @@ -1136,14 +1164,14 @@ impl Array { // ii. Let same be IsStrictlyEqual(searchElement, elementK). // iii. If same is true, return ๐”ฝ(k). if search_element.strict_equals(&element_k) { - return Ok(Value::from(k)); + return Ok(JsValue::new(k)); } } // c. Set k to k + 1. k += 1; } // 11. Return -1๐”ฝ. - Ok(Value::from(-1)) + Ok(JsValue::new(-1)) } /// `Array.prototype.lastIndexOf( searchElement[, fromIndex ] )` @@ -1165,10 +1193,10 @@ impl Array { /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.lastindexof /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf pub(crate) fn last_index_of( - this: &Value, - args: &[Value], + this: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { // 1. Let O be ? ToObject(this value). let o = this.to_object(context)?; @@ -1177,7 +1205,7 @@ impl Array { // 3. If len is 0, return -1๐”ฝ. if len == 0 { - return Ok(Value::from(-1)); + return Ok(JsValue::new(-1)); } // 4. If fromIndex is present, let n be ? ToIntegerOrInfinity(fromIndex); else let n be len - 1. @@ -1189,7 +1217,7 @@ impl Array { let mut k = match n { // 5. If n is -โˆž, return -1๐”ฝ. - IntegerOrInfinity::NegativeInfinity => return Ok(Value::from(-1)), + IntegerOrInfinity::NegativeInfinity => return Ok(JsValue::new(-1)), // 6. If n โ‰ฅ 0, then // a. Let k be min(n, len - 1). IntegerOrInfinity::Integer(n) if n >= 0 => min(n, len - 1), @@ -1211,15 +1239,15 @@ impl Array { let element_k = o.get(k, context)?; // ii. Let same be IsStrictlyEqual(searchElement, elementK). // iii. If same is true, return ๐”ฝ(k). - if Value::strict_equals(&search_element, &element_k) { - return Ok(Value::from(k)); + if JsValue::strict_equals(&search_element, &element_k) { + return Ok(JsValue::new(k)); } } // c. Set k to k - 1. k -= 1; } // 9. Return -1๐”ฝ. - Ok(Value::from(-1)) + Ok(JsValue::new(-1)) } /// `Array.prototype.find( callback, [thisArg] )` @@ -1234,7 +1262,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], context: &mut Context) -> Result { + pub(crate) fn find(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { // 1. Let O be ? ToObject(this value). let o = this.to_object(context)?; @@ -1242,7 +1270,7 @@ impl Array { let len = o.length_of_array_like(context)?; // 3. If IsCallable(predicate) is false, throw a TypeError exception. - let predicate = match args.get(0).and_then(Value::as_object) { + let predicate = match args.get(0).and_then(JsValue::as_object) { Some(predicate) if predicate.is_callable() => predicate, _ => { return context.throw_type_error("Array.prototype.find: predicate is not callable") @@ -1275,7 +1303,7 @@ impl Array { k += 1; } // 6. Return undefined. - Ok(Value::undefined()) + Ok(JsValue::undefined()) } /// `Array.prototype.findIndex( predicate [ , thisArg ] )` @@ -1290,7 +1318,11 @@ 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], context: &mut Context) -> Result { + pub(crate) fn find_index( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let O be ? ToObject(this value). let o = this.to_object(context)?; @@ -1298,7 +1330,7 @@ impl Array { let len = o.length_of_array_like(context)?; // 3. If IsCallable(predicate) is false, throw a TypeError exception. - let predicate = match args.get(0).and_then(Value::as_object) { + let predicate = match args.get(0).and_then(JsValue::as_object) { Some(predicate) if predicate.is_callable() => predicate, _ => { return context @@ -1322,13 +1354,13 @@ impl Array { .to_boolean(); // d. If testResult is true, return ๐”ฝ(k). if test_result { - return Ok(Value::from(k)); + return Ok(JsValue::new(k)); } // e. Set k to k + 1. k += 1; } // 6. Return -1๐”ฝ. - Ok(Value::from(-1)) + Ok(JsValue::new(-1)) } /// `Array.prototype.flat( [depth] )` @@ -1342,7 +1374,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.flat /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat - pub(crate) fn flat(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn flat(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { // 1. Let O be ToObject(this value) let o = this.to_object(context)?; @@ -1374,7 +1406,7 @@ impl Array { 0, depth_num, None, - &Value::undefined(), + &JsValue::undefined(), context, )?; @@ -1394,7 +1426,11 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.flatMap /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap - pub(crate) fn flat_map(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn flat_map( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let O be ToObject(this value) let o = this.to_object(context)?; @@ -1440,7 +1476,7 @@ impl Array { start: u64, depth: u64, mapper_function: Option, - this_arg: &Value, + this_arg: &JsValue, context: &mut Context, ) -> Result { // 1. Assert target is Object @@ -1512,7 +1548,7 @@ impl Array { target_index, new_depth, None, - &Value::undefined(), + &JsValue::undefined(), context, )?; @@ -1550,7 +1586,7 @@ impl Array { /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.fill /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill - pub(crate) fn fill(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn fill(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { // 1. Let O be ? ToObject(this value). let o = this.to_object(context)?; @@ -1595,10 +1631,10 @@ impl Array { /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.includes /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes pub(crate) fn includes_value( - this: &Value, - args: &[Value], + this: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { // 1. Let O be ? ToObject(this value). let o = this.to_object(context)?; @@ -1607,7 +1643,7 @@ impl Array { // 3. If len is 0, return false. if len == 0 { - return Ok(Value::from(false)); + return Ok(JsValue::new(false)); } // 4. Let n be ? ToIntegerOrInfinity(fromIndex). @@ -1620,7 +1656,7 @@ impl Array { // 6. If n is +โˆž, return false. // 7. Else if n is -โˆž, set n to 0. let n = match n { - IntegerOrInfinity::PositiveInfinity => return Ok(Value::from(false)), + IntegerOrInfinity::PositiveInfinity => return Ok(JsValue::new(false)), IntegerOrInfinity::NegativeInfinity => 0, IntegerOrInfinity::Integer(value) => value, }; @@ -1647,14 +1683,14 @@ impl Array { // a. Let elementK be ? Get(O, ! ToString(๐”ฝ(k))). let element_k = o.get(k, context)?; // b. If SameValueZero(searchElement, elementK) is true, return true. - if Value::same_value_zero(&search_element, &element_k) { - return Ok(Value::from(true)); + if JsValue::same_value_zero(&search_element, &element_k) { + return Ok(JsValue::new(true)); } // c. Set k to k + 1. k += 1; } // 11. Return false. - Ok(Value::from(false)) + Ok(JsValue::new(false)) } /// `Array.prototype.slice( [begin[, end]] )` @@ -1671,7 +1707,11 @@ 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], context: &mut Context) -> Result { + pub(crate) fn slice( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let O be ? ToObject(this value). let o = this.to_object(context)?; @@ -1735,7 +1775,11 @@ 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], context: &mut Context) -> Result { + pub(crate) fn filter( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let O be ? ToObject(this value). let o = this.to_object(context)?; @@ -1752,7 +1796,7 @@ impl Array { "missing argument 0 when calling function Array.prototype.filter", ) })?; - let this_val = args.get(1).cloned().unwrap_or_else(Value::undefined); + let this_val = args.get(1).cloned().unwrap_or_else(JsValue::undefined); if !callback.is_callable() { return context.throw_type_error("the callback must be callable"); @@ -1773,7 +1817,7 @@ impl Array { // i. Let kValue be ? Get(O, Pk). let element = o.get(idx, context)?; - let args = [element.clone(), Value::from(idx), Value::from(o.clone())]; + let args = [element.clone(), JsValue::new(idx), JsValue::new(o.clone())]; // ii. Let selected be ! ToBoolean(? Call(callbackfn, thisArg, ยซ kValue, ๐”ฝ(k), O ยป)). let selected = callback.call(&this_val, &args, context)?.to_boolean(); @@ -1807,7 +1851,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], context: &mut Context) -> Result { + pub(crate) fn some(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { // 1. Let O be ? ToObject(this value). let o = this.to_object(context)?; // 2. Let len be ? LengthOfArrayLike(O). @@ -1815,7 +1859,7 @@ impl Array { // 3. If IsCallable(callbackfn) is false, throw a TypeError exception. let callback = if let Some(arg) = args .get(0) - .and_then(Value::as_object) + .and_then(JsValue::as_object) .filter(GcObject::is_callable) { arg @@ -1840,13 +1884,13 @@ impl Array { .to_boolean(); // iii. If testResult is true, return true. if test_result { - return Ok(Value::from(true)); + return Ok(JsValue::new(true)); } } // d. Set k to k + 1. } // 6. Return false. - Ok(Value::from(false)) + Ok(JsValue::new(false)) } /// `Array.prototype.reduce( callbackFn [ , initialValue ] )` @@ -1857,7 +1901,11 @@ 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], context: &mut Context) -> Result { + pub(crate) fn reduce( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let O be ? ToObject(this value). let o = this.to_object(context)?; @@ -1865,7 +1913,7 @@ impl Array { let len = o.length_of_array_like(context)?; // 3. If IsCallable(callbackfn) is false, throw a TypeError exception. - let callback = match args.get(0).and_then(Value::as_object) { + let callback = match args.get(0).and_then(JsValue::as_object) { Some(callback) if callback.is_callable() => callback, _ => { return context @@ -1883,7 +1931,7 @@ impl Array { // 5. Let k be 0. let mut k = 0; // 6. Let accumulator be undefined. - let mut accumulator = Value::undefined(); + let mut accumulator = JsValue::undefined(); // 7. If initialValue is present, then if let Some(initial_value) = args.get(1) { @@ -1927,7 +1975,7 @@ impl Array { let k_value = o.get(pk, context)?; // ii. Set accumulator to ? Call(callbackfn, undefined, ยซ accumulator, kValue, ๐”ฝ(k), O ยป). accumulator = callback.call( - &Value::undefined(), + &JsValue::undefined(), &[accumulator, k_value, k.into(), o.clone().into()], context, )?; @@ -1952,10 +2000,10 @@ impl Array { /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.reduceright /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight pub(crate) fn reduce_right( - this: &Value, - args: &[Value], + this: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { // 1. Let O be ? ToObject(this value). let o = this.to_object(context)?; @@ -1963,7 +2011,7 @@ impl Array { let len = o.length_of_array_like(context)?; // 3. If IsCallable(callbackfn) is false, throw a TypeError exception. - let callback = match args.get(0).and_then(Value::as_object) { + let callback = match args.get(0).and_then(JsValue::as_object) { Some(callback) if callback.is_callable() => callback, _ => { return context.throw_type_error( @@ -1982,7 +2030,7 @@ impl Array { // 5. Let k be len - 1. let mut k = len as i64 - 1; // 6. Let accumulator be undefined. - let mut accumulator = Value::undefined(); + let mut accumulator = JsValue::undefined(); // 7. If initialValue is present, then if let Some(initial_value) = args.get(1) { // a. Set accumulator to initialValue. @@ -2025,7 +2073,7 @@ impl Array { let k_value = o.get(pk, context)?; // ii. Set accumulator to ? Call(callbackfn, undefined, ยซ accumulator, kValue, ๐”ฝ(k), O ยป). accumulator = callback.call( - &Value::undefined(), + &JsValue::undefined(), &[accumulator.clone(), k_value, k.into(), o.clone().into()], context, )?; @@ -2050,10 +2098,10 @@ impl Array { /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.copywithin /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin pub(crate) fn copy_within( - this: &Value, - args: &[Value], + this: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { // 1. Let O be ? ToObject(this value). let o = this.to_object(context)?; @@ -2139,7 +2187,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 values(this: &Value, _: &[Value], context: &mut Context) -> Result { + pub(crate) fn values(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { Ok(ArrayIterator::create_array_iterator( context, this.clone(), @@ -2157,7 +2205,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 keys(this: &Value, _: &[Value], context: &mut Context) -> Result { + pub(crate) fn keys(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { Ok(ArrayIterator::create_array_iterator( context, this.clone(), @@ -2175,7 +2223,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], context: &mut Context) -> Result { + pub(crate) fn entries(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { Ok(ArrayIterator::create_array_iterator( context, this.clone(), @@ -2186,7 +2234,7 @@ impl Array { /// Represents the algorithm to calculate `relativeStart` (or `k`) in array functions. pub(super) fn get_relative_start( context: &mut Context, - arg: Option<&Value>, + arg: Option<&JsValue>, len: usize, ) -> Result { // 1. Let relativeStart be ? ToIntegerOrInfinity(start). @@ -2211,10 +2259,10 @@ impl Array { /// Represents the algorithm to calculate `relativeEnd` (or `final`) in array functions. pub(super) fn get_relative_end( context: &mut Context, - arg: Option<&Value>, + arg: Option<&JsValue>, len: usize, ) -> Result { - let default_value = Value::undefined(); + let default_value = JsValue::undefined(); let value = arg.unwrap_or(&default_value); // 1. If end is undefined, let relativeEnd be len [and return it] if value.is_undefined() { diff --git a/boa/src/builtins/array/tests.rs b/boa/src/builtins/array/tests.rs index 4e9fa67667..b43ed4c6bf 100644 --- a/boa/src/builtins/array/tests.rs +++ b/boa/src/builtins/array/tests.rs @@ -1,6 +1,6 @@ use super::Array; use crate::builtins::Number; -use crate::{forward, Context, Value}; +use crate::{forward, Context, JsValue}; #[test] fn is_array() { @@ -13,58 +13,58 @@ fn is_array() { context.eval(init).unwrap(); assert_eq!( context.eval("Array.isArray(empty)").unwrap(), - Value::Boolean(true) + JsValue::new(true) ); assert_eq!( context.eval("Array.isArray(new_arr)").unwrap(), - Value::Boolean(true) + JsValue::new(true) ); assert_eq!( context.eval("Array.isArray(many)").unwrap(), - Value::Boolean(true) + JsValue::new(true) ); assert_eq!( context.eval("Array.isArray([1, 2, 3])").unwrap(), - Value::Boolean(true) + JsValue::new(true) ); assert_eq!( context.eval("Array.isArray([])").unwrap(), - Value::Boolean(true) + JsValue::new(true) ); assert_eq!( context.eval("Array.isArray({})").unwrap(), - Value::Boolean(false) + JsValue::new(false) ); // assert_eq!(context.eval("Array.isArray(new Array)"), "true"); assert_eq!( context.eval("Array.isArray()").unwrap(), - Value::Boolean(false) + JsValue::new(false) ); assert_eq!( context .eval("Array.isArray({ constructor: Array })") .unwrap(), - Value::Boolean(false) + JsValue::new(false) ); assert_eq!( context .eval("Array.isArray({ push: Array.prototype.push, concat: Array.prototype.concat })") .unwrap(), - Value::Boolean(false) + JsValue::new(false) ); assert_eq!( context.eval("Array.isArray(17)").unwrap(), - Value::Boolean(false) + JsValue::new(false) ); assert_eq!( context .eval("Array.isArray({ __proto__: Array.prototype })") .unwrap(), - Value::Boolean(false) + JsValue::new(false) ); assert_eq!( context.eval("Array.isArray({ length: 0 })").unwrap(), - Value::Boolean(false) + JsValue::new(false) ); } @@ -109,12 +109,12 @@ fn of() { .unwrap(); assert_eq!( context.eval("a instanceof Date").unwrap(), - Value::from(true) + JsValue::new(true) ); - assert_eq!(context.eval("a[0]").unwrap(), Value::from("a")); - assert_eq!(context.eval("a[1]").unwrap(), Value::undefined()); - assert_eq!(context.eval("a[2]").unwrap(), Value::from(3)); - assert_eq!(context.eval("a.length").unwrap(), Value::from(3)); + assert_eq!(context.eval("a[0]").unwrap(), JsValue::new("a")); + assert_eq!(context.eval("a[1]").unwrap(), JsValue::undefined()); + assert_eq!(context.eval("a[2]").unwrap(), JsValue::new(3)); + assert_eq!(context.eval("a.length").unwrap(), JsValue::new(3)); } #[ignore] @@ -1424,47 +1424,47 @@ fn get_relative_start() { assert_eq!(Array::get_relative_start(&mut context, None, 10), Ok(0)); assert_eq!( - Array::get_relative_start(&mut context, Some(&Value::undefined()), 10), + Array::get_relative_start(&mut context, Some(&JsValue::undefined()), 10), Ok(0) ); assert_eq!( - Array::get_relative_start(&mut context, Some(&Value::from(f64::NEG_INFINITY)), 10), + Array::get_relative_start(&mut context, Some(&JsValue::new(f64::NEG_INFINITY)), 10), Ok(0) ); assert_eq!( - Array::get_relative_start(&mut context, Some(&Value::from(f64::INFINITY)), 10), + Array::get_relative_start(&mut context, Some(&JsValue::new(f64::INFINITY)), 10), Ok(10) ); assert_eq!( - Array::get_relative_start(&mut context, Some(&Value::from(-1)), 10), + Array::get_relative_start(&mut context, Some(&JsValue::new(-1)), 10), Ok(9) ); assert_eq!( - Array::get_relative_start(&mut context, Some(&Value::from(1)), 10), + Array::get_relative_start(&mut context, Some(&JsValue::new(1)), 10), Ok(1) ); assert_eq!( - Array::get_relative_start(&mut context, Some(&Value::from(-11)), 10), + Array::get_relative_start(&mut context, Some(&JsValue::new(-11)), 10), Ok(0) ); assert_eq!( - Array::get_relative_start(&mut context, Some(&Value::from(11)), 10), + Array::get_relative_start(&mut context, Some(&JsValue::new(11)), 10), Ok(10) ); assert_eq!( - Array::get_relative_start(&mut context, Some(&Value::from(f64::MIN)), 10), + Array::get_relative_start(&mut context, Some(&JsValue::new(f64::MIN)), 10), Ok(0) ); assert_eq!( Array::get_relative_start( &mut context, - Some(&Value::from(Number::MIN_SAFE_INTEGER)), + Some(&JsValue::new(Number::MIN_SAFE_INTEGER)), 10 ), Ok(0) ); assert_eq!( - Array::get_relative_start(&mut context, Some(&Value::from(f64::MAX)), 10), + Array::get_relative_start(&mut context, Some(&JsValue::new(f64::MAX)), 10), Ok(10) ); @@ -1472,7 +1472,7 @@ fn get_relative_start() { assert_eq!( Array::get_relative_start( &mut context, - Some(&Value::from(Number::MAX_SAFE_INTEGER)), + Some(&JsValue::new(Number::MAX_SAFE_INTEGER)), 10 ), Ok(10) @@ -1485,47 +1485,47 @@ fn get_relative_end() { assert_eq!(Array::get_relative_end(&mut context, None, 10), Ok(10)); assert_eq!( - Array::get_relative_end(&mut context, Some(&Value::undefined()), 10), + Array::get_relative_end(&mut context, Some(&JsValue::undefined()), 10), Ok(10) ); assert_eq!( - Array::get_relative_end(&mut context, Some(&Value::from(f64::NEG_INFINITY)), 10), + Array::get_relative_end(&mut context, Some(&JsValue::new(f64::NEG_INFINITY)), 10), Ok(0) ); assert_eq!( - Array::get_relative_end(&mut context, Some(&Value::from(f64::INFINITY)), 10), + Array::get_relative_end(&mut context, Some(&JsValue::new(f64::INFINITY)), 10), Ok(10) ); assert_eq!( - Array::get_relative_end(&mut context, Some(&Value::from(-1)), 10), + Array::get_relative_end(&mut context, Some(&JsValue::new(-1)), 10), Ok(9) ); assert_eq!( - Array::get_relative_end(&mut context, Some(&Value::from(1)), 10), + Array::get_relative_end(&mut context, Some(&JsValue::new(1)), 10), Ok(1) ); assert_eq!( - Array::get_relative_end(&mut context, Some(&Value::from(-11)), 10), + Array::get_relative_end(&mut context, Some(&JsValue::new(-11)), 10), Ok(0) ); assert_eq!( - Array::get_relative_end(&mut context, Some(&Value::from(11)), 10), + Array::get_relative_end(&mut context, Some(&JsValue::new(11)), 10), Ok(10) ); assert_eq!( - Array::get_relative_end(&mut context, Some(&Value::from(f64::MIN)), 10), + Array::get_relative_end(&mut context, Some(&JsValue::new(f64::MIN)), 10), Ok(0) ); assert_eq!( Array::get_relative_end( &mut context, - Some(&Value::from(Number::MIN_SAFE_INTEGER)), + Some(&JsValue::new(Number::MIN_SAFE_INTEGER)), 10 ), Ok(0) ); assert_eq!( - Array::get_relative_end(&mut context, Some(&Value::from(f64::MAX)), 10), + Array::get_relative_end(&mut context, Some(&JsValue::new(f64::MAX)), 10), Ok(10) ); @@ -1533,7 +1533,7 @@ fn get_relative_end() { assert_eq!( Array::get_relative_end( &mut context, - Some(&Value::from(Number::MAX_SAFE_INTEGER)), + Some(&JsValue::new(Number::MAX_SAFE_INTEGER)), 10 ), Ok(10) diff --git a/boa/src/builtins/bigint/mod.rs b/boa/src/builtins/bigint/mod.rs index 7840b71e77..5da0d460d8 100644 --- a/boa/src/builtins/bigint/mod.rs +++ b/boa/src/builtins/bigint/mod.rs @@ -17,7 +17,7 @@ use crate::{ object::{ConstructorBuilder, ObjectData}, property::Attribute, symbol::WellKnownSymbols, - BoaProfiler, Context, JsBigInt, Result, Value, + BoaProfiler, Context, JsBigInt, JsValue, Result, }; #[cfg(test)] mod tests; @@ -33,7 +33,7 @@ impl BuiltIn for BigInt { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let to_string_tag = WellKnownSymbols::to_string_tag(); @@ -76,12 +76,12 @@ impl BigInt { /// /// [spec]: https://tc39.es/ecma262/#sec-bigint-objects /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/BigInt - fn constructor(_: &Value, args: &[Value], context: &mut Context) -> Result { + fn constructor(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { let data = match args.get(0) { Some(value) => value.to_bigint(context)?, None => JsBigInt::zero(), }; - Ok(Value::from(data)) + Ok(JsValue::new(data)) } /// The abstract operation thisBigIntValue takes argument value. @@ -95,15 +95,15 @@ impl BigInt { /// /// [spec]: https://tc39.es/ecma262/#sec-thisbigintvalue #[inline] - fn this_bigint_value(value: &Value, context: &mut Context) -> Result { + fn this_bigint_value(value: &JsValue, context: &mut Context) -> Result { match value { // 1. If Type(value) is BigInt, return value. - Value::BigInt(ref bigint) => return Ok(bigint.clone()), + JsValue::BigInt(ref bigint) => return Ok(bigint.clone()), // 2. If Type(value) is Object and value has a [[BigIntData]] internal slot, then // a. Assert: Type(value.[[BigIntData]]) is BigInt. // b. Return value.[[BigIntData]]. - Value::Object(ref object) => { + JsValue::Object(ref object) => { if let ObjectData::BigInt(ref bigint) = object.borrow().data { return Ok(bigint.clone()); } @@ -126,7 +126,11 @@ 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], context: &mut Context) -> Result { + pub(crate) fn to_string( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { let radix = if !args.is_empty() { args[0].to_integer(context)? as i32 } else { @@ -136,7 +140,7 @@ impl BigInt { return context .throw_range_error("radix must be an integer at least 2 and no greater than 36"); } - Ok(Value::from( + Ok(JsValue::new( Self::this_bigint_value(this, context)?.to_string_radix(radix as u32), )) } @@ -151,8 +155,12 @@ 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, _: &[Value], context: &mut Context) -> Result { - Ok(Value::from(Self::this_bigint_value(this, context)?)) + pub(crate) fn value_of( + this: &JsValue, + _: &[JsValue], + context: &mut Context, + ) -> Result { + Ok(JsValue::new(Self::this_bigint_value(this, context)?)) } /// `BigInt.asIntN()` @@ -162,18 +170,22 @@ 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(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn as_int_n( + _: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { let (modulo, bits) = Self::calculate_as_uint_n(args, context)?; if bits > 0 && modulo >= JsBigInt::pow(&JsBigInt::new(2), &JsBigInt::new(bits as i64 - 1), context)? { - Ok(Value::from(JsBigInt::sub( + Ok(JsValue::new(JsBigInt::sub( &modulo, &JsBigInt::pow(&JsBigInt::new(2), &JsBigInt::new(bits as i64), context)?, ))) } else { - Ok(Value::from(modulo)) + Ok(JsValue::new(modulo)) } } @@ -184,10 +196,14 @@ 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(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn as_uint_n( + _: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { let (modulo, _) = Self::calculate_as_uint_n(args, context)?; - Ok(Value::from(modulo)) + Ok(JsValue::new(modulo)) } /// Helper function to wrap the value of a `BigInt` to an unsigned integer. @@ -195,10 +211,10 @@ 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], context: &mut Context) -> Result<(JsBigInt, u32)> { + fn calculate_as_uint_n(args: &[JsValue], context: &mut Context) -> Result<(JsBigInt, u32)> { use std::convert::TryFrom; - let undefined_value = Value::undefined(); + let undefined_value = JsValue::undefined(); let bits_arg = args.get(0).unwrap_or(&undefined_value); let bigint_arg = args.get(1).unwrap_or(&undefined_value); diff --git a/boa/src/builtins/boolean/mod.rs b/boa/src/builtins/boolean/mod.rs index 8dc1af259d..25abe7bf85 100644 --- a/boa/src/builtins/boolean/mod.rs +++ b/boa/src/builtins/boolean/mod.rs @@ -16,7 +16,7 @@ use crate::{ builtins::BuiltIn, object::{ConstructorBuilder, ObjectData, PROTOTYPE}, property::Attribute, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; /// Boolean implementation. @@ -31,7 +31,7 @@ impl BuiltIn for Boolean { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let boolean_object = ConstructorBuilder::with_standard_object( @@ -57,14 +57,14 @@ impl Boolean { /// /// `[[Call]]` Creates a new boolean primitive pub(crate) fn constructor( - new_target: &Value, - args: &[Value], + new_target: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { // Get the argument, if any let data = args.get(0).map(|x| x.to_boolean()).unwrap_or(false); if new_target.is_undefined() { - return Ok(Value::from(data)); + return Ok(JsValue::new(data)); } let prototype = new_target .as_object() @@ -75,7 +75,7 @@ impl Boolean { }) .transpose()? .unwrap_or_else(|| context.standard_objects().object_object().prototype()); - let boolean = Value::new_object(context); + let boolean = JsValue::new_object(context); boolean .as_object() @@ -92,10 +92,10 @@ impl Boolean { /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-thisbooleanvalue - fn this_boolean_value(value: &Value, context: &mut Context) -> Result { + fn this_boolean_value(value: &JsValue, context: &mut Context) -> Result { match value { - Value::Boolean(boolean) => return Ok(*boolean), - Value::Object(ref object) => { + JsValue::Boolean(boolean) => return Ok(*boolean), + JsValue::Object(ref object) => { let object = object.borrow(); if let Some(boolean) = object.as_boolean() { return Ok(boolean); @@ -116,9 +116,13 @@ 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], context: &mut Context) -> Result { + pub(crate) fn to_string( + this: &JsValue, + _: &[JsValue], + context: &mut Context, + ) -> Result { let boolean = Self::this_boolean_value(this, context)?; - Ok(Value::from(boolean.to_string())) + Ok(JsValue::new(boolean.to_string())) } /// The valueOf() method returns the primitive value of a `Boolean` object. @@ -130,7 +134,11 @@ 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], context: &mut Context) -> Result { - Ok(Value::from(Self::this_boolean_value(this, context)?)) + pub(crate) fn value_of( + this: &JsValue, + _: &[JsValue], + context: &mut Context, + ) -> Result { + Ok(JsValue::new(Self::this_boolean_value(this, context)?)) } } diff --git a/boa/src/builtins/boolean/tests.rs b/boa/src/builtins/boolean/tests.rs index 82a9b19511..b97fa65ea3 100644 --- a/boa/src/builtins/boolean/tests.rs +++ b/boa/src/builtins/boolean/tests.rs @@ -1,4 +1,4 @@ -use crate::{forward, forward_val, Context, Value}; +use crate::{forward, forward_val, Context, JsValue}; /// Test the correct type is returned from call and construct #[allow(clippy::unwrap_used)] @@ -58,7 +58,7 @@ fn instances_have_correct_proto_set() { let bool_instance = forward_val(&mut context, "boolInstance").expect("value expected"); let bool_prototype = forward_val(&mut context, "boolProto").expect("value expected"); - assert!(Value::same_value( + assert!(JsValue::same_value( &bool_instance.as_object().unwrap().prototype_instance(), &bool_prototype )); diff --git a/boa/src/builtins/console/mod.rs b/boa/src/builtins/console/mod.rs index 9eae0298cb..5cd14d401c 100644 --- a/boa/src/builtins/console/mod.rs +++ b/boa/src/builtins/console/mod.rs @@ -20,7 +20,7 @@ use crate::{ builtins::BuiltIn, object::ObjectInitializer, property::Attribute, - value::{display::display_obj, Value}, + value::{display::display_obj, JsValue}, BoaProfiler, Context, JsString, Result, }; use rustc_hash::FxHashMap; @@ -50,7 +50,7 @@ pub(crate) fn logger(msg: LogMessage, console_state: &Console) { } /// This represents the `console` formatter. -pub fn formatter(data: &[Value], context: &mut Context) -> Result { +pub fn formatter(data: &[JsValue], context: &mut Context) -> Result { let target = data .get(0) .cloned() @@ -141,7 +141,7 @@ impl BuiltIn for Console { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let console = ObjectInitializer::new(context) .function(Self::assert, "assert", 0) @@ -184,19 +184,19 @@ 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], context: &mut Context) -> Result { - let assertion = args.get(0).map(Value::to_boolean).unwrap_or(false); + pub(crate) fn assert(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { + let assertion = args.get(0).map(JsValue::to_boolean).unwrap_or(false); if !assertion { - let mut args: Vec = args.iter().skip(1).cloned().collect(); + let mut args: Vec = args.iter().skip(1).cloned().collect(); let message = "Assertion failed".to_string(); if args.is_empty() { - args.push(Value::from(message)); + args.push(JsValue::new(message)); } else if !args[0].is_string() { - args.insert(0, Value::from(message)); + args.insert(0, JsValue::new(message)); } else { let concat = format!("{}: {}", message, args[0].display()); - args[0] = Value::from(concat); + args[0] = JsValue::new(concat); } logger( @@ -205,7 +205,7 @@ impl Console { ); } - Ok(Value::undefined()) + Ok(JsValue::undefined()) } /// `console.clear()` @@ -218,9 +218,9 @@ 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], context: &mut Context) -> Result { + pub(crate) fn clear(_: &JsValue, _: &[JsValue], context: &mut Context) -> Result { context.console_mut().groups.clear(); - Ok(Value::undefined()) + Ok(JsValue::undefined()) } /// `console.debug(...data)` @@ -233,12 +233,12 @@ 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], context: &mut Context) -> Result { + pub(crate) fn debug(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { logger( LogMessage::Log(formatter(args, context)?), context.console(), ); - Ok(Value::undefined()) + Ok(JsValue::undefined()) } /// `console.error(...data)` @@ -251,12 +251,12 @@ 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], context: &mut Context) -> Result { + pub(crate) fn error(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { logger( LogMessage::Error(formatter(args, context)?), context.console(), ); - Ok(Value::undefined()) + Ok(JsValue::undefined()) } /// `console.info(...data)` @@ -269,12 +269,12 @@ 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], context: &mut Context) -> Result { + pub(crate) fn info(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { logger( LogMessage::Info(formatter(args, context)?), context.console(), ); - Ok(Value::undefined()) + Ok(JsValue::undefined()) } /// `console.log(...data)` @@ -287,12 +287,12 @@ 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], context: &mut Context) -> Result { + pub(crate) fn log(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { logger( LogMessage::Log(formatter(args, context)?), context.console(), ); - Ok(Value::undefined()) + Ok(JsValue::undefined()) } /// `console.trace(...data)` @@ -305,7 +305,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#trace /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/trace - pub(crate) fn trace(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn trace(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { if !args.is_empty() { logger( LogMessage::Log(formatter(args, context)?), @@ -319,7 +319,7 @@ impl Console { ) } - Ok(Value::undefined()) + Ok(JsValue::undefined()) } /// `console.warn(...data)` @@ -332,12 +332,12 @@ 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], context: &mut Context) -> Result { + pub(crate) fn warn(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { logger( LogMessage::Warn(formatter(args, context)?), context.console(), ); - Ok(Value::undefined()) + Ok(JsValue::undefined()) } /// `console.count(label)` @@ -350,7 +350,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#count /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/count - pub(crate) fn count(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn count(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { let label = match args.get(0) { Some(value) => value.to_string(context)?, None => "default".into(), @@ -364,7 +364,7 @@ impl Console { LogMessage::Info(format!("{} {}", msg, c)), context.console(), ); - Ok(Value::undefined()) + Ok(JsValue::undefined()) } /// `console.countReset(label)` @@ -377,7 +377,11 @@ 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], context: &mut Context) -> Result { + pub(crate) fn count_reset( + _: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { let label = match args.get(0) { Some(value) => value.to_string(context)?, None => "default".into(), @@ -390,7 +394,7 @@ impl Console { context.console(), ); - Ok(Value::undefined()) + Ok(JsValue::undefined()) } /// Returns current system time in ms. @@ -411,7 +415,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#time /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/time - pub(crate) fn time(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn time(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { let label = match args.get(0) { Some(value) => value.to_string(context)?, None => "default".into(), @@ -427,7 +431,7 @@ impl Console { context.console_mut().timer_map.insert(label, time); } - Ok(Value::undefined()) + Ok(JsValue::undefined()) } /// `console.timeLog(label, ...data)` @@ -440,7 +444,11 @@ 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], context: &mut Context) -> Result { + pub(crate) fn time_log( + _: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { let label = match args.get(0) { Some(value) => value.to_string(context)?, None => "default".into(), @@ -460,7 +468,7 @@ impl Console { ); } - Ok(Value::undefined()) + Ok(JsValue::undefined()) } /// `console.timeEnd(label)` @@ -473,7 +481,11 @@ 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], context: &mut Context) -> Result { + pub(crate) fn time_end( + _: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { let label = match args.get(0) { Some(value) => value.to_string(context)?, None => "default".into(), @@ -492,7 +504,7 @@ impl Console { ); } - Ok(Value::undefined()) + Ok(JsValue::undefined()) } /// `console.group(...data)` @@ -505,7 +517,7 @@ impl Console { /// /// [spec]: https://console.spec.whatwg.org/#group /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/group - pub(crate) fn group(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn group(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { let group_label = formatter(args, context)?; logger( @@ -514,7 +526,7 @@ impl Console { ); context.console_mut().groups.push(group_label); - Ok(Value::undefined()) + Ok(JsValue::undefined()) } /// `console.groupEnd(label)` @@ -527,10 +539,10 @@ 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], context: &mut Context) -> Result { + pub(crate) fn group_end(_: &JsValue, _: &[JsValue], context: &mut Context) -> Result { context.console_mut().groups.pop(); - Ok(Value::undefined()) + Ok(JsValue::undefined()) } /// `console.dir(item, options)` @@ -543,13 +555,13 @@ 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], context: &mut Context) -> Result { - let undefined = Value::undefined(); + pub(crate) fn dir(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { + let undefined = JsValue::undefined(); logger( LogMessage::Info(display_obj(args.get(0).unwrap_or(&undefined), true)), context.console(), ); - Ok(Value::undefined()) + Ok(JsValue::undefined()) } } diff --git a/boa/src/builtins/console/tests.rs b/boa/src/builtins/console/tests.rs index 291c71427b..3a2f9c49d4 100644 --- a/boa/src/builtins/console/tests.rs +++ b/boa/src/builtins/console/tests.rs @@ -1,4 +1,4 @@ -use crate::{builtins::console::formatter, Context, Value}; +use crate::{builtins::console::formatter, Context, JsValue}; #[test] fn formatter_no_args_is_empty_string() { @@ -9,14 +9,14 @@ fn formatter_no_args_is_empty_string() { #[test] fn formatter_empty_format_string_is_empty_string() { let mut context = Context::new(); - let val = Value::string("".to_string()); + let val = JsValue::new(""); assert_eq!(formatter(&[val], &mut context).unwrap(), ""); } #[test] fn formatter_format_without_args_renders_verbatim() { let mut context = Context::new(); - let val = [Value::string("%d %s %% %f")]; + let val = [JsValue::new("%d %s %% %f")]; let res = formatter(&val, &mut context).unwrap(); assert_eq!(res, "%d %s %% %f"); } @@ -26,9 +26,9 @@ fn formatter_empty_format_string_concatenates_rest_of_args() { let mut context = Context::new(); let val = [ - Value::string(""), - Value::string("to powinno zostaฤ‡"), - Value::string("poล‚ฤ…czone"), + JsValue::new(""), + JsValue::new("to powinno zostaฤ‡"), + JsValue::new("poล‚ฤ…czone"), ]; let res = formatter(&val, &mut context).unwrap(); assert_eq!(res, " to powinno zostaฤ‡ poล‚ฤ…czone"); @@ -39,10 +39,10 @@ fn formatter_utf_8_checks() { let mut context = Context::new(); let val = [ - Value::string("Sฤ… takie chwile %dฤ… %sฤ… tu%sรณw %ะฟั€ะธะฒะตั‚%ลบ".to_string()), - Value::integer(123), - Value::rational(1.23), - Value::string("ล‚".to_string()), + JsValue::new("Sฤ… takie chwile %dฤ… %sฤ… tu%sรณw %ะฟั€ะธะฒะตั‚%ลบ".to_string()), + JsValue::new(123), + JsValue::new(1.23), + JsValue::new("ล‚"), ]; let res = formatter(&val, &mut context).unwrap(); assert_eq!(res, "Sฤ… takie chwile 123ฤ… 1.23ฤ… tuล‚รณw %ะฟั€ะธะฒะตั‚%ลบ"); @@ -52,10 +52,7 @@ fn formatter_utf_8_checks() { fn formatter_trailing_format_leader_renders() { let mut context = Context::new(); - let val = [ - Value::string("%%%%%".to_string()), - Value::string("|".to_string()), - ]; + let val = [JsValue::new("%%%%%"), JsValue::new("|")]; let res = formatter(&val, &mut context).unwrap(); assert_eq!(res, "%%% |"); } @@ -65,7 +62,7 @@ fn formatter_trailing_format_leader_renders() { fn formatter_float_format_works() { let mut context = Context::new(); - let val = [Value::string("%f".to_string()), Value::rational(3.1415)]; + let val = [JsValue::new("%f"), JsValue::new(3.1415)]; 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 3d39bf4667..89a9d92ee1 100644 --- a/boa/src/builtins/date/mod.rs +++ b/boa/src/builtins/date/mod.rs @@ -6,7 +6,7 @@ use crate::{ gc::{empty_trace, Finalize, Trace}, object::{ConstructorBuilder, ObjectData, PROTOTYPE}, property::Attribute, - value::{PreferredType, Value}, + value::{JsValue, PreferredType}, BoaProfiler, Context, Result, }; use chrono::{prelude::*, Duration, LocalResult}; @@ -45,14 +45,14 @@ fn ignore_ambiguity(result: LocalResult) -> Option { macro_rules! getter_method { ($name:ident) => {{ - fn get_value(this: &Value, _: &[Value], context: &mut Context) -> Result { - Ok(Value::from(this_time_value(this, context)?.$name())) + fn get_value(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { + Ok(JsValue::new(this_time_value(this, context)?.$name())) } get_value }}; (Self::$name:ident) => {{ - fn get_value(_: &Value, _: &[Value], _: &mut Context) -> Result { - Ok(Value::from(Date::$name())) + fn get_value(_: &JsValue, _: &[JsValue], _: &mut Context) -> Result { + Ok(JsValue::new(Date::$name())) } get_value }}; @@ -60,7 +60,7 @@ macro_rules! getter_method { macro_rules! setter_method { ($name:ident($($e:expr),* $(,)?)) => {{ - fn set_value(this: &Value, args: &[Value], context: &mut Context) -> Result { + fn set_value(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { let mut result = this_time_value(this, context)?; result.$name( $( @@ -82,7 +82,7 @@ macro_rules! setter_method { ); this.set_data(ObjectData::Date(result)); - Ok(Value::from(result.get_time())) + Ok(JsValue::new(result.get_time())) } set_value }}; @@ -119,7 +119,7 @@ impl BuiltIn for Date { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let date_object = ConstructorBuilder::new(context, Self::constructor) @@ -366,10 +366,10 @@ 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( - new_target: &Value, - args: &[Value], + new_target: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { if new_target.is_undefined() { Ok(Self::make_date_string()) } else { @@ -405,8 +405,8 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date-constructor /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date - pub(crate) fn make_date_string() -> Value { - Value::from(Local::now().to_rfc3339()) + pub(crate) fn make_date_string() -> JsValue { + JsValue::new(Local::now().to_rfc3339()) } /// `Date()` @@ -419,7 +419,7 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date-constructor /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date - pub(crate) fn make_date_now(this: &Value) -> Value { + pub(crate) fn make_date_now(this: &JsValue) -> JsValue { let date = Date::default(); this.set_data(ObjectData::Date(date)); this.clone() @@ -436,15 +436,15 @@ impl Date { /// [spec]: https://tc39.es/ecma262/#sec-date-constructor /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date pub(crate) fn make_date_single( - this: &Value, - args: &[Value], + this: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { let value = &args[0]; let tv = match this_time_value(value, context) { Ok(dt) => dt.0, _ => match value.to_primitive(context, PreferredType::Default)? { - Value::String(ref str) => match chrono::DateTime::parse_from_rfc3339(str) { + JsValue::String(ref str) => match chrono::DateTime::parse_from_rfc3339(str) { Ok(dt) => Some(dt.naive_utc()), _ => None, }, @@ -474,10 +474,10 @@ impl Date { /// [spec]: https://tc39.es/ecma262/#sec-date-constructor /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date pub(crate) fn make_date_multiple( - this: &Value, - args: &[Value], + this: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { let year = args[0].to_number(context)?; let month = args[1].to_number(context)?; let day = args @@ -1313,8 +1313,8 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.now /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now - pub(crate) fn now(_: &Value, _: &[Value], _: &mut Context) -> Result { - Ok(Value::from(Utc::now().timestamp_millis() as f64)) + pub(crate) fn now(_: &JsValue, _: &[JsValue], _: &mut Context) -> Result { + Ok(JsValue::new(Utc::now().timestamp_millis() as f64)) } /// `Date.parse()` @@ -1329,17 +1329,17 @@ 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], context: &mut Context) -> Result { + pub(crate) fn parse(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { // This method is implementation-defined and discouraged, so we just require the same format as the string // constructor. if args.is_empty() { - return Ok(Value::number(f64::NAN)); + return Ok(JsValue::nan()); } 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)), + Ok(v) => Ok(JsValue::new(v.naive_utc().timestamp_millis() as f64)), + _ => Ok(JsValue::new(f64::NAN)), } } @@ -1353,7 +1353,7 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.utc /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC - pub(crate) fn utc(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn utc(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { let year = args .get(0) .map_or(Ok(f64::NAN), |value| value.to_number(context))?; @@ -1377,7 +1377,7 @@ impl Date { .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)); + return Ok(JsValue::nan()); } let year = year as i32; @@ -1397,7 +1397,7 @@ impl Date { NaiveDate::from_ymd_opt(year, month + 1, day) .and_then(|f| f.and_hms_milli_opt(hour, min, sec, milli)) .and_then(|f| Self::time_clip(f.timestamp_millis() as f64)) - .map_or(Ok(Value::number(f64::NAN)), |time| Ok(Value::number(time))) + .map_or(Ok(JsValue::nan()), |time| Ok(JsValue::new(time))) } } @@ -1414,8 +1414,8 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-thistimevalue #[inline] -pub fn this_time_value(value: &Value, context: &mut Context) -> Result { - if let Value::Object(ref object) = value { +pub fn this_time_value(value: &JsValue, context: &mut Context) -> Result { + if let JsValue::Object(ref object) = value { if let ObjectData::Date(ref date) = object.borrow().data { return Ok(*date); } diff --git a/boa/src/builtins/date/tests.rs b/boa/src/builtins/date/tests.rs index bf78e129e8..1f48d22e96 100644 --- a/boa/src/builtins/date/tests.rs +++ b/boa/src/builtins/date/tests.rs @@ -1,6 +1,6 @@ #![allow(clippy::zero_prefixed_literal)] -use crate::{forward, forward_val, object::ObjectData, Context, Value}; +use crate::{forward, forward_val, object::ObjectData, Context, JsValue}; use chrono::prelude::*; // NOTE: Javascript Uses 0-based months, where chrono uses 1-based months. Many of the assertions look wrong because of @@ -13,7 +13,7 @@ fn forward_dt_utc(context: &mut Context, src: &str) -> Option { panic!("expected success") }; - if let Value::Object(ref date_time) = date_time { + if let JsValue::Object(ref date_time) = date_time { if let ObjectData::Date(ref date_time) = date_time.borrow().data { date_time.0 } else { @@ -66,7 +66,7 @@ fn date_this_time_value() { .expect_value() .clone(); - assert_eq!(Value::string("\'this\' is not a Date"), *message_property); + assert_eq!(JsValue::new("\'this\' is not a Date"), *message_property); } #[test] @@ -212,7 +212,7 @@ fn date_ctor_parse_call() -> Result<(), Box> { 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); + assert_eq!(Ok(JsValue::new(1591634775779f64)), date_time); Ok(()) } @@ -222,7 +222,7 @@ fn date_ctor_utc_call() -> Result<(), Box> { let date_time = forward_val(&mut context, "Date.UTC(2020, 06, 08, 09, 16, 15, 779)"); - assert_eq!(Ok(Value::Rational(1594199775779f64)), date_time); + assert_eq!(Ok(JsValue::new(1594199775779f64)), date_time); Ok(()) } @@ -231,7 +231,7 @@ fn date_ctor_utc_call_nan() -> Result<(), Box> { fn check(src: &str) { let mut context = Context::new(); let date_time = forward_val(&mut context, src).expect("Expected Success"); - assert_eq!(Value::Rational(f64::NAN), date_time); + assert_eq!(JsValue::nan(), date_time); } check("Date.UTC(1/0, 06, 08, 09, 16, 15, 779)"); @@ -253,10 +253,10 @@ fn date_proto_get_date_call() -> Result<(), Box> { &mut context, "new Date(2020, 06, 08, 09, 16, 15, 779).getDate()", ); - assert_eq!(Ok(Value::Rational(08f64)), actual); + assert_eq!(Ok(JsValue::new(08f64)), actual); let actual = forward_val(&mut context, "new Date(1/0).getDate()"); - assert_eq!(Ok(Value::Rational(f64::NAN)), actual); + assert_eq!(Ok(JsValue::nan()), actual); Ok(()) } @@ -269,10 +269,10 @@ fn date_proto_get_day_call() -> Result<(), Box> { &mut context, "new Date(2020, 06, 08, 09, 16, 15, 779).getDay()", ); - assert_eq!(Ok(Value::Rational(3f64)), actual); + assert_eq!(Ok(JsValue::new(3f64)), actual); let actual = forward_val(&mut context, "new Date(1/0).getDay()"); - assert_eq!(Ok(Value::Rational(f64::NAN)), actual); + assert_eq!(Ok(JsValue::nan()), actual); Ok(()) } @@ -284,10 +284,10 @@ fn date_proto_get_full_year_call() -> Result<(), Box> { &mut context, "new Date(2020, 06, 08, 09, 16, 15, 779).getFullYear()", ); - assert_eq!(Ok(Value::Rational(2020f64)), actual); + assert_eq!(Ok(JsValue::new(2020f64)), actual); let actual = forward_val(&mut context, "new Date(1/0).getFullYear()"); - assert_eq!(Ok(Value::Rational(f64::NAN)), actual); + assert_eq!(Ok(JsValue::nan()), actual); Ok(()) } @@ -299,10 +299,10 @@ fn date_proto_get_hours_call() -> Result<(), Box> { &mut context, "new Date(2020, 06, 08, 09, 16, 15, 779).getHours()", ); - assert_eq!(Ok(Value::Rational(09f64)), actual); + assert_eq!(Ok(JsValue::new(09f64)), actual); let actual = forward_val(&mut context, "new Date(1/0).getHours()"); - assert_eq!(Ok(Value::Rational(f64::NAN)), actual); + assert_eq!(Ok(JsValue::nan()), actual); Ok(()) } @@ -314,10 +314,10 @@ fn date_proto_get_milliseconds_call() -> Result<(), Box> &mut context, "new Date(2020, 06, 08, 09, 16, 15, 779).getMilliseconds()", ); - assert_eq!(Ok(Value::Rational(779f64)), actual); + assert_eq!(Ok(JsValue::new(779f64)), actual); let actual = forward_val(&mut context, "new Date(1/0).getMilliseconds()"); - assert_eq!(Ok(Value::Rational(f64::NAN)), actual); + assert_eq!(Ok(JsValue::nan()), actual); Ok(()) } @@ -329,10 +329,10 @@ fn date_proto_get_minutes_call() -> Result<(), Box> { &mut context, "new Date(2020, 06, 08, 09, 16, 15, 779).getMinutes()", ); - assert_eq!(Ok(Value::Rational(16f64)), actual); + assert_eq!(Ok(JsValue::new(16f64)), actual); let actual = forward_val(&mut context, "new Date(1/0).getMinutes()"); - assert_eq!(Ok(Value::Rational(f64::NAN)), actual); + assert_eq!(Ok(JsValue::nan()), actual); Ok(()) } @@ -344,10 +344,10 @@ fn date_proto_get_month() -> Result<(), Box> { &mut context, "new Date(2020, 06, 08, 09, 16, 15, 779).getMonth()", ); - assert_eq!(Ok(Value::Rational(06f64)), actual); + assert_eq!(Ok(JsValue::new(06f64)), actual); let actual = forward_val(&mut context, "new Date(1/0).getMonth()"); - assert_eq!(Ok(Value::Rational(f64::NAN)), actual); + assert_eq!(Ok(JsValue::nan()), actual); Ok(()) } @@ -360,10 +360,10 @@ fn date_proto_get_seconds() -> Result<(), Box> { &mut context, "new Date(2020, 06, 08, 09, 16, 15, 779).getSeconds()", ); - assert_eq!(Ok(Value::Rational(15f64)), actual); + assert_eq!(Ok(JsValue::new(15f64)), actual); let actual = forward_val(&mut context, "new Date(1/0).getSeconds()"); - assert_eq!(Ok(Value::Rational(f64::NAN)), actual); + assert_eq!(Ok(JsValue::nan()), actual); Ok(()) } @@ -380,10 +380,10 @@ fn date_proto_get_time() -> Result<(), Box> { .ymd(2020, 07, 08) .and_hms_milli(09, 16, 15, 779) .timestamp_millis() as f64; - assert_eq!(Ok(Value::Rational(ts)), actual); + assert_eq!(Ok(JsValue::new(ts)), actual); let actual = forward_val(&mut context, "new Date(1/0).getTime()"); - assert_eq!(Ok(Value::Rational(f64::NAN)), actual); + assert_eq!(Ok(JsValue::nan()), actual); Ok(()) } @@ -395,10 +395,10 @@ fn date_proto_get_year() -> Result<(), Box> { &mut context, "new Date(2020, 06, 08, 09, 16, 15, 779).getYear()", ); - assert_eq!(Ok(Value::Rational(120f64)), actual); + assert_eq!(Ok(JsValue::new(120f64)), actual); let actual = forward_val(&mut context, "new Date(1/0).getYear()"); - assert_eq!(Ok(Value::Rational(f64::NAN)), actual); + assert_eq!(Ok(JsValue::nan()), actual); Ok(()) } @@ -412,7 +412,7 @@ fn date_proto_get_timezone_offset() -> Result<(), Box> { ); // NB: Host Settings, not TZ specified in the DateTime. - assert_eq!(Ok(Value::Boolean(true)), actual); + assert_eq!(Ok(JsValue::new(true)), actual); let actual = forward_val( &mut context, @@ -422,13 +422,13 @@ fn date_proto_get_timezone_offset() -> Result<(), Box> { // The value of now().offset() depends on the host machine, so we have to replicate the method code here. let offset_seconds = chrono::Local::now().offset().local_minus_utc() as f64; let offset_minutes = offset_seconds / 60f64; - assert_eq!(Ok(Value::Rational(offset_minutes)), actual); + assert_eq!(Ok(JsValue::new(offset_minutes)), actual); let actual = forward_val( &mut context, "new Date(1/0, 06, 08, 09, 16, 15, 779).getTimezoneOffset()", ); - assert_eq!(Ok(Value::Rational(offset_minutes)), actual); + assert_eq!(Ok(JsValue::new(offset_minutes)), actual); Ok(()) } @@ -440,10 +440,10 @@ fn date_proto_get_utc_date_call() -> Result<(), Box> { &mut context, "new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)).getUTCDate()", ); - assert_eq!(Ok(Value::Rational(08f64)), actual); + assert_eq!(Ok(JsValue::new(08f64)), actual); let actual = forward_val(&mut context, "new Date(1/0).getUTCDate()"); - assert_eq!(Ok(Value::Rational(f64::NAN)), actual); + assert_eq!(Ok(JsValue::nan()), actual); Ok(()) } @@ -456,10 +456,10 @@ fn date_proto_get_utc_day_call() -> Result<(), Box> { &mut context, "new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)).getUTCDay()", ); - assert_eq!(Ok(Value::Rational(3f64)), actual); + assert_eq!(Ok(JsValue::new(3f64)), actual); let actual = forward_val(&mut context, "new Date(1/0).getUTCDay()"); - assert_eq!(Ok(Value::Rational(f64::NAN)), actual); + assert_eq!(Ok(JsValue::nan()), actual); Ok(()) } @@ -471,10 +471,10 @@ fn date_proto_get_utc_full_year_call() -> Result<(), Box> &mut context, "new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)).getUTCFullYear()", ); - assert_eq!(Ok(Value::Rational(2020f64)), actual); + assert_eq!(Ok(JsValue::new(2020f64)), actual); let actual = forward_val(&mut context, "new Date(1/0).getUTCFullYear()"); - assert_eq!(Ok(Value::Rational(f64::NAN)), actual); + assert_eq!(Ok(JsValue::nan()), actual); Ok(()) } @@ -486,10 +486,10 @@ fn date_proto_get_utc_hours_call() -> Result<(), Box> { &mut context, "new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)).getUTCHours()", ); - assert_eq!(Ok(Value::Rational(09f64)), actual); + assert_eq!(Ok(JsValue::new(09f64)), actual); let actual = forward_val(&mut context, "new Date(1/0).getUTCHours()"); - assert_eq!(Ok(Value::Rational(f64::NAN)), actual); + assert_eq!(Ok(JsValue::nan()), actual); Ok(()) } @@ -501,10 +501,10 @@ fn date_proto_get_utc_milliseconds_call() -> Result<(), Box Result<(), Box> { &mut context, "new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)).getUTCMinutes()", ); - assert_eq!(Ok(Value::Rational(16f64)), actual); + assert_eq!(Ok(JsValue::new(16f64)), actual); let actual = forward_val(&mut context, "new Date(1/0).getUTCMinutes()"); - assert_eq!(Ok(Value::Rational(f64::NAN)), actual); + assert_eq!(Ok(JsValue::nan()), actual); Ok(()) } @@ -531,10 +531,10 @@ fn date_proto_get_utc_month() -> Result<(), Box> { &mut context, "new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)).getUTCMonth()", ); - assert_eq!(Ok(Value::Rational(06f64)), actual); + assert_eq!(Ok(JsValue::new(06f64)), actual); let actual = forward_val(&mut context, "new Date(1/0).getUTCMonth()"); - assert_eq!(Ok(Value::Rational(f64::NAN)), actual); + assert_eq!(Ok(JsValue::nan()), actual); Ok(()) } @@ -547,10 +547,10 @@ fn date_proto_get_utc_seconds() -> Result<(), Box> { &mut context, "new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)).getUTCSeconds()", ); - assert_eq!(Ok(Value::Rational(15f64)), actual); + assert_eq!(Ok(JsValue::new(15f64)), actual); let actual = forward_val(&mut context, "new Date(1/0).getUTCSeconds()"); - assert_eq!(Ok(Value::Rational(f64::NAN)), actual); + assert_eq!(Ok(JsValue::nan()), actual); Ok(()) } @@ -1216,7 +1216,7 @@ fn date_proto_to_date_string() -> Result<(), Box> { "let dt = new Date(2020, 06, 08, 09, 16, 15, 779); dt.toDateString()", ) .expect("Successful eval"); - assert_eq!(Value::string("Wed Jul 08 2020"), actual); + assert_eq!(JsValue::new("Wed Jul 08 2020"), actual); Ok(()) } @@ -1230,7 +1230,7 @@ fn date_proto_to_gmt_string() -> Result<(), Box> { "let dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.toGMTString()", ) .expect("Successful eval"); - assert_eq!(Value::string("Wed, 08 Jul 2020 09:16:15 GMT"), actual); + assert_eq!(JsValue::new("Wed, 08 Jul 2020 09:16:15 GMT"), actual); Ok(()) } @@ -1244,7 +1244,7 @@ fn date_proto_to_iso_string() -> Result<(), Box> { "let dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.toISOString()", ) .expect("Successful eval"); - assert_eq!(Value::string("2020-07-08T09:16:15.779Z"), actual); + assert_eq!(JsValue::new("2020-07-08T09:16:15.779Z"), actual); Ok(()) } @@ -1258,7 +1258,7 @@ fn date_proto_to_json() -> Result<(), Box> { "let dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.toJSON()", ) .expect("Successful eval"); - assert_eq!(Value::string("2020-07-08T09:16:15.779Z"), actual); + assert_eq!(JsValue::new("2020-07-08T09:16:15.779Z"), actual); Ok(()) } @@ -1274,7 +1274,7 @@ fn date_proto_to_string() -> Result<(), Box> { .ok(); assert_eq!( - Some(Value::string( + Some(JsValue::new( Local .from_local_datetime(&NaiveDateTime::new( NaiveDate::from_ymd(2020, 6, 8), @@ -1302,7 +1302,7 @@ fn date_proto_to_time_string() -> Result<(), Box> { .ok(); assert_eq!( - Some(Value::string( + Some(JsValue::new( Local .from_local_datetime(&NaiveDateTime::new( NaiveDate::from_ymd(2020, 6, 8), @@ -1328,7 +1328,7 @@ fn date_proto_to_utc_string() -> Result<(), Box> { "let dt = new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)); dt.toUTCString()", ) .expect("Successful eval"); - assert_eq!(Value::string("Wed, 08 Jul 2020 09:16:15 GMT"), actual); + assert_eq!(JsValue::new("Wed, 08 Jul 2020 09:16:15 GMT"), actual); Ok(()) } @@ -1342,7 +1342,7 @@ fn date_proto_value_of() -> Result<(), Box> { "new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779)).valueOf()", ) .expect("Successful eval"); - assert_eq!(Value::number(1594199775779f64), actual); + assert_eq!(JsValue::new(1594199775779f64), actual); Ok(()) } @@ -1356,7 +1356,7 @@ fn date_neg() -> Result<(), Box> { "-new Date(Date.UTC(2020, 06, 08, 09, 16, 15, 779))", ) .expect("Successful eval"); - assert_eq!(Value::number(-1594199775779f64), actual); + assert_eq!(JsValue::new(-1594199775779f64), actual); Ok(()) } @@ -1371,7 +1371,7 @@ fn date_json() -> Result<(), Box> { ) .expect("Successful eval"); assert_eq!( - Value::string(r#"{"date":"2020-07-08T09:16:15.779Z"}"#), + JsValue::new(r#"{"date":"2020-07-08T09:16:15.779Z"}"#), actual ); diff --git a/boa/src/builtins/error/eval.rs b/boa/src/builtins/error/eval.rs index b65dbe8685..fcc8e3f650 100644 --- a/boa/src/builtins/error/eval.rs +++ b/boa/src/builtins/error/eval.rs @@ -17,7 +17,7 @@ use crate::{ object::{ConstructorBuilder, ObjectData}, profiler::BoaProfiler, property::Attribute, - Context, Result, Value, + Context, JsValue, Result, }; /// JavaScript `EvalError` impleentation. @@ -31,7 +31,7 @@ impl BuiltIn for EvalError { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let error_prototype = context.standard_objects().error_object().prototype(); @@ -58,10 +58,10 @@ impl EvalError { /// Create a new error object. pub(crate) fn constructor( - new_target: &Value, - args: &[Value], + new_target: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { let prototype = new_target .as_object() .and_then(|obj| { @@ -73,7 +73,7 @@ impl EvalError { .unwrap_or_else(|| context.standard_objects().error_object().prototype()); let obj = context.construct_object(); obj.set_prototype_instance(prototype.into()); - let this = Value::from(obj); + let this = JsValue::new(obj); if let Some(message) = args.get(0) { if !message.is_undefined() { this.set_field("message", message.to_string(context)?, false, context)?; diff --git a/boa/src/builtins/error/mod.rs b/boa/src/builtins/error/mod.rs index 48be4ad6e0..cb04a5af3f 100644 --- a/boa/src/builtins/error/mod.rs +++ b/boa/src/builtins/error/mod.rs @@ -15,7 +15,7 @@ use crate::{ object::{ConstructorBuilder, ObjectData, PROTOTYPE}, profiler::BoaProfiler, property::Attribute, - Context, Result, Value, + Context, JsValue, Result, }; pub(crate) mod eval; @@ -46,7 +46,7 @@ impl BuiltIn for Error { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let attribute = Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE; @@ -74,10 +74,10 @@ impl Error { /// /// Create a new error object. pub(crate) fn constructor( - new_target: &Value, - args: &[Value], + new_target: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { let prototype = new_target .as_object() .and_then(|obj| { @@ -89,7 +89,7 @@ impl Error { .unwrap_or_else(|| context.standard_objects().error_object().prototype()); let obj = context.construct_object(); obj.set_prototype_instance(prototype.into()); - let this = Value::from(obj); + let this = JsValue::new(obj); if let Some(message) = args.get(0) { if !message.is_undefined() { this.set_field("message", message.to_string(context)?, false, context)?; @@ -113,7 +113,11 @@ impl Error { /// [spec]: https://tc39.es/ecma262/#sec-error.prototype.tostring /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/toString #[allow(clippy::wrong_self_convention)] - pub(crate) fn to_string(this: &Value, _: &[Value], context: &mut Context) -> Result { + pub(crate) fn to_string( + this: &JsValue, + _: &[JsValue], + context: &mut Context, + ) -> Result { if !this.is_object() { return context.throw_type_error("'this' is not an Object"); } diff --git a/boa/src/builtins/error/range.rs b/boa/src/builtins/error/range.rs index c2c4e046e1..ea688719d5 100644 --- a/boa/src/builtins/error/range.rs +++ b/boa/src/builtins/error/range.rs @@ -14,7 +14,7 @@ use crate::{ object::{ConstructorBuilder, ObjectData, PROTOTYPE}, profiler::BoaProfiler, property::Attribute, - Context, Result, Value, + Context, JsValue, Result, }; /// JavaScript `RangeError` implementation. @@ -28,7 +28,7 @@ impl BuiltIn for RangeError { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let error_prototype = context.standard_objects().error_object().prototype(); @@ -55,10 +55,10 @@ impl RangeError { /// Create a new error object. pub(crate) fn constructor( - new_target: &Value, - args: &[Value], + new_target: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { let prototype = new_target .as_object() .and_then(|obj| { @@ -70,7 +70,7 @@ impl RangeError { .unwrap_or_else(|| context.standard_objects().error_object().prototype()); let obj = context.construct_object(); obj.set_prototype_instance(prototype.into()); - let this = Value::from(obj); + let this = JsValue::new(obj); if let Some(message) = args.get(0) { if !message.is_undefined() { this.set_field("message", message.to_string(context)?, false, context)?; diff --git a/boa/src/builtins/error/reference.rs b/boa/src/builtins/error/reference.rs index 47e9cd525d..3c23bc6d11 100644 --- a/boa/src/builtins/error/reference.rs +++ b/boa/src/builtins/error/reference.rs @@ -14,7 +14,7 @@ use crate::{ object::{ConstructorBuilder, ObjectData, PROTOTYPE}, profiler::BoaProfiler, property::Attribute, - Context, Result, Value, + Context, JsValue, Result, }; #[derive(Debug, Clone, Copy)] @@ -27,7 +27,7 @@ impl BuiltIn for ReferenceError { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let error_prototype = context.standard_objects().error_object().prototype(); @@ -54,10 +54,10 @@ impl ReferenceError { /// Create a new error object. pub(crate) fn constructor( - new_target: &Value, - args: &[Value], + new_target: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { let prototype = new_target .as_object() .and_then(|obj| { @@ -69,7 +69,7 @@ impl ReferenceError { .unwrap_or_else(|| context.standard_objects().error_object().prototype()); let obj = context.construct_object(); obj.set_prototype_instance(prototype.into()); - let this = Value::from(obj); + let this = JsValue::new(obj); if let Some(message) = args.get(0) { if !message.is_undefined() { this.set_field("message", message.to_string(context)?, false, context)?; diff --git a/boa/src/builtins/error/syntax.rs b/boa/src/builtins/error/syntax.rs index 2fc96af041..b2f4701a80 100644 --- a/boa/src/builtins/error/syntax.rs +++ b/boa/src/builtins/error/syntax.rs @@ -16,7 +16,7 @@ use crate::{ object::{ConstructorBuilder, ObjectData, PROTOTYPE}, profiler::BoaProfiler, property::Attribute, - Context, Result, Value, + Context, JsValue, Result, }; /// JavaScript `SyntaxError` impleentation. @@ -30,7 +30,7 @@ impl BuiltIn for SyntaxError { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let error_prototype = context.standard_objects().error_object().prototype(); @@ -57,10 +57,10 @@ impl SyntaxError { /// Create a new error object. pub(crate) fn constructor( - new_target: &Value, - args: &[Value], + new_target: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { let prototype = new_target .as_object() .and_then(|obj| { @@ -72,7 +72,7 @@ impl SyntaxError { .unwrap_or_else(|| context.standard_objects().error_object().prototype()); let obj = context.construct_object(); obj.set_prototype_instance(prototype.into()); - let this = Value::from(obj); + let this = JsValue::new(obj); if let Some(message) = args.get(0) { if !message.is_undefined() { this.set_field("message", message.to_string(context)?, false, context)?; diff --git a/boa/src/builtins/error/type.rs b/boa/src/builtins/error/type.rs index e1069d5a1e..02c9378c0b 100644 --- a/boa/src/builtins/error/type.rs +++ b/boa/src/builtins/error/type.rs @@ -19,7 +19,7 @@ use crate::{ builtins::BuiltIn, object::{ConstructorBuilder, ObjectData, PROTOTYPE}, property::Attribute, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; /// JavaScript `TypeError` implementation. @@ -33,7 +33,7 @@ impl BuiltIn for TypeError { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let error_prototype = context.standard_objects().error_object().prototype(); @@ -60,10 +60,10 @@ impl TypeError { /// Create a new error object. pub(crate) fn constructor( - new_target: &Value, - args: &[Value], + new_target: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { let prototype = new_target .as_object() .and_then(|obj| { @@ -75,7 +75,7 @@ impl TypeError { .unwrap_or_else(|| context.standard_objects().error_object().prototype()); let obj = context.construct_object(); obj.set_prototype_instance(prototype.into()); - let this = Value::from(obj); + let this = JsValue::new(obj); if let Some(message) = args.get(0) { if !message.is_undefined() { this.set_field("message", message.to_string(context)?, false, context)?; diff --git a/boa/src/builtins/error/uri.rs b/boa/src/builtins/error/uri.rs index aabe628404..5b86d0d6d4 100644 --- a/boa/src/builtins/error/uri.rs +++ b/boa/src/builtins/error/uri.rs @@ -15,7 +15,7 @@ use crate::{ object::{ConstructorBuilder, ObjectData, PROTOTYPE}, profiler::BoaProfiler, property::Attribute, - Context, Result, Value, + Context, JsValue, Result, }; /// JavaScript `URIError` impleentation. @@ -29,7 +29,7 @@ impl BuiltIn for UriError { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let error_prototype = context.standard_objects().error_object().prototype(); @@ -56,10 +56,10 @@ impl UriError { /// Create a new error object. pub(crate) fn constructor( - new_target: &Value, - args: &[Value], + new_target: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { let prototype = new_target .as_object() .and_then(|obj| { @@ -71,7 +71,7 @@ impl UriError { .unwrap_or_else(|| context.standard_objects().error_object().prototype()); let obj = context.construct_object(); obj.set_prototype_instance(prototype.into()); - let this = Value::from(obj); + let this = JsValue::new(obj); if let Some(message) = args.get(0) { if !message.is_undefined() { this.set_field("message", message.to_string(context)?, false, context)?; diff --git a/boa/src/builtins/function/mod.rs b/boa/src/builtins/function/mod.rs index 2d74eeddd7..0f2dab96bd 100644 --- a/boa/src/builtins/function/mod.rs +++ b/boa/src/builtins/function/mod.rs @@ -19,7 +19,7 @@ use crate::{ object::{ConstructorBuilder, FunctionBuilder, GcObject, Object, ObjectData}, property::{Attribute, PropertyDescriptor}, syntax::ast::node::{FormalParameter, RcStatementList}, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; use bitflags::bitflags; use std::fmt::{self, Debug}; @@ -29,10 +29,10 @@ use std::rc::Rc; mod tests; /// _fn(this, arguments, context) -> ResultValue_ - The signature of a native built-in function -pub type NativeFunction = fn(&Value, &[Value], &mut Context) -> Result; +pub type NativeFunction = fn(&JsValue, &[JsValue], &mut Context) -> Result; /// _fn(this, arguments, context) -> ResultValue_ - The signature of a closure built-in function -pub type ClosureFunction = dyn Fn(&Value, &[Value], &mut Context) -> Result; +pub type ClosureFunction = dyn Fn(&JsValue, &[JsValue], &mut Context) -> Result; #[derive(Clone, Copy, Finalize)] pub struct BuiltInFunction(pub(crate) NativeFunction); @@ -124,7 +124,7 @@ impl Function { &self, param: &FormalParameter, index: usize, - args_list: &[Value], + args_list: &[JsValue], context: &mut Context, local_env: &Environment, ) { @@ -149,7 +149,7 @@ impl Function { pub(crate) fn add_arguments_to_environment( &self, param: &FormalParameter, - value: Value, + value: JsValue, local_env: &Environment, context: &mut Context, ) { @@ -177,7 +177,7 @@ impl Function { /// Arguments. /// /// -pub fn create_unmapped_arguments_object(arguments_list: &[Value]) -> Value { +pub fn create_unmapped_arguments_object(arguments_list: &[JsValue]) -> JsValue { let len = arguments_list.len(); let obj = GcObject::new(Object::default()); // Set length @@ -201,7 +201,7 @@ pub fn create_unmapped_arguments_object(arguments_list: &[Value]) -> Value { index += 1; } - Value::from(obj) + JsValue::new(obj) } /// Creates a new member function of a `Object` or `prototype`. @@ -268,7 +268,7 @@ pub struct BuiltInFunctionObject; impl BuiltInFunctionObject { pub const LENGTH: usize = 1; - fn constructor(new_target: &Value, _: &[Value], context: &mut Context) -> Result { + fn constructor(new_target: &JsValue, _: &[JsValue], context: &mut Context) -> Result { let prototype = new_target .as_object() .and_then(|obj| { @@ -278,21 +278,21 @@ impl BuiltInFunctionObject { }) .transpose()? .unwrap_or_else(|| context.standard_objects().object_object().prototype()); - let this = Value::new_object(context); + let this = JsValue::new_object(context); this.as_object() .expect("this should be an object") .set_prototype_instance(prototype.into()); this.set_data(ObjectData::Function(Function::Native { - function: BuiltInFunction(|_, _, _| Ok(Value::undefined())), + function: BuiltInFunction(|_, _, _| Ok(JsValue::undefined())), constructable: true, })); Ok(this) } - fn prototype(_: &Value, _: &[Value], _: &mut Context) -> Result { - Ok(Value::undefined()) + fn prototype(_: &JsValue, _: &[JsValue], _: &mut Context) -> Result { + Ok(JsValue::undefined()) } /// `Function.prototype.call` @@ -305,11 +305,11 @@ impl BuiltInFunctionObject { /// /// [spec]: https://tc39.es/ecma262/#sec-function.prototype.call /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call - fn call(this: &Value, args: &[Value], context: &mut Context) -> Result { + fn call(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { if !this.is_function() { return context.throw_type_error(format!("{} is not a function", this.display())); } - let this_arg: Value = args.get(0).cloned().unwrap_or_default(); + let this_arg: JsValue = args.get(0).cloned().unwrap_or_default(); // TODO?: 3. Perform PrepareForTailCall let start = if !args.is_empty() { 1 } else { 0 }; context.call(this, &this_arg, &args[start..]) @@ -326,7 +326,7 @@ impl BuiltInFunctionObject { /// /// [spec]: https://tc39.es/ecma262/#sec-function.prototype.apply /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply - fn apply(this: &Value, args: &[Value], context: &mut Context) -> Result { + fn apply(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { if !this.is_function() { return context.throw_type_error(format!("{} is not a function", this.display())); } @@ -352,7 +352,7 @@ impl BuiltIn for BuiltInFunctionObject { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event("function", "init"); let function_prototype = context.standard_objects().function_object().prototype(); diff --git a/boa/src/builtins/global_this/mod.rs b/boa/src/builtins/global_this/mod.rs index ea4a266e6e..3ccf2b98c1 100644 --- a/boa/src/builtins/global_this/mod.rs +++ b/boa/src/builtins/global_this/mod.rs @@ -10,7 +10,7 @@ //! [spec]: https://tc39.es/ecma262/#sec-globalthis //! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis -use crate::{builtins::BuiltIn, property::Attribute, BoaProfiler, Context, Value}; +use crate::{builtins::BuiltIn, property::Attribute, BoaProfiler, Context, JsValue}; #[cfg(test)] mod tests; @@ -25,7 +25,7 @@ impl BuiltIn for GlobalThis { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); ( diff --git a/boa/src/builtins/infinity/mod.rs b/boa/src/builtins/infinity/mod.rs index c04b93afee..99cbbaeb13 100644 --- a/boa/src/builtins/infinity/mod.rs +++ b/boa/src/builtins/infinity/mod.rs @@ -12,7 +12,7 @@ #[cfg(test)] mod tests; -use crate::{builtins::BuiltIn, property::Attribute, BoaProfiler, Context, Value}; +use crate::{builtins::BuiltIn, property::Attribute, BoaProfiler, Context, JsValue}; /// JavaScript global `Infinity` property. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -25,7 +25,7 @@ impl BuiltIn for Infinity { Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT } - fn init(_: &mut Context) -> (&'static str, Value, Attribute) { + fn init(_: &mut Context) -> (&'static str, JsValue, 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 387346936c..fb012b2aa6 100644 --- a/boa/src/builtins/iterable/mod.rs +++ b/boa/src/builtins/iterable/mod.rs @@ -6,7 +6,7 @@ use crate::{ }, object::{GcObject, ObjectInitializer}, symbol::WellKnownSymbols, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; #[derive(Debug, Default)] @@ -85,7 +85,7 @@ impl IteratorPrototypes { /// CreateIterResultObject( value, done ) /// /// Generates an object supporting the IteratorResult interface. -pub fn create_iter_result_object(context: &mut Context, value: Value, done: bool) -> Value { +pub fn create_iter_result_object(context: &mut Context, value: JsValue, done: bool) -> JsValue { // 1. Assert: Type(done) is Boolean. // 2. Let obj be ! OrdinaryObjectCreate(%Object.prototype%). let obj = context.construct_object(); @@ -101,7 +101,7 @@ pub fn create_iter_result_object(context: &mut Context, value: Value, done: bool } /// Get an iterator record -pub fn get_iterator(context: &mut Context, iterable: Value) -> Result { +pub fn get_iterator(context: &mut Context, iterable: JsValue) -> Result { let iterator_function = iterable.get_field(WellKnownSymbols::iterator(), context)?; if iterator_function.is_null_or_undefined() { return Err(context.construct_type_error("Not an iterable")); @@ -136,12 +136,12 @@ fn create_iterator_prototype(context: &mut Context) -> GcObject { #[derive(Debug)] pub struct IteratorRecord { - iterator_object: Value, - next_function: Value, + iterator_object: JsValue, + next_function: JsValue, } impl IteratorRecord { - pub fn new(iterator_object: Value, next_function: Value) -> Self { + pub fn new(iterator_object: JsValue, next_function: JsValue) -> Self { Self { iterator_object, next_function, @@ -168,7 +168,11 @@ impl IteratorRecord { /// - [ECMA reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-iteratorclose - pub(crate) fn close(&self, completion: Result, context: &mut Context) -> Result { + pub(crate) fn close( + &self, + completion: Result, + context: &mut Context, + ) -> Result { let mut inner_result = self.iterator_object.get_field("return", context); // 5 @@ -199,12 +203,12 @@ impl IteratorRecord { #[derive(Debug)] pub struct IteratorResult { - value: Value, + value: JsValue, done: bool, } impl IteratorResult { - fn new(value: Value, done: bool) -> Self { + fn new(value: JsValue, done: bool) -> Self { Self { value, done } } @@ -212,7 +216,7 @@ impl IteratorResult { self.done } - pub fn value(self) -> Value { + pub fn value(self) -> JsValue { self.value } } diff --git a/boa/src/builtins/json/mod.rs b/boa/src/builtins/json/mod.rs index f5918a6513..b8e04614b7 100644 --- a/boa/src/builtins/json/mod.rs +++ b/boa/src/builtins/json/mod.rs @@ -20,7 +20,7 @@ use crate::{ property::{Attribute, PropertyDescriptor, PropertyKey}, symbol::WellKnownSymbols, value::IntegerOrInfinity, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; use serde::Serialize; use serde_json::{self, ser::PrettyFormatter, Serializer, Value as JSONValue}; @@ -39,7 +39,7 @@ impl BuiltIn for Json { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let to_string_tag = WellKnownSymbols::to_string_tag(); @@ -68,19 +68,19 @@ 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], context: &mut Context) -> Result { + pub(crate) fn parse(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { let arg = args .get(0) .cloned() - .unwrap_or_else(Value::undefined) + .unwrap_or_else(JsValue::undefined) .to_string(context)?; match serde_json::from_str::(&arg) { Ok(json) => { - let j = Value::from_json(json, context); + let j = JsValue::from_json(json, context); match args.get(1) { Some(reviver) if reviver.is_function() => { - let mut holder = Value::object(Object::default()); + let mut holder: JsValue = context.construct_object().into(); holder.set_field("", j, true, context)?; Self::walk(reviver, context, &mut holder, &PropertyKey::from("")) } @@ -98,14 +98,14 @@ impl Json { /// /// [polyfill]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse fn walk( - reviver: &Value, + reviver: &JsValue, context: &mut Context, - holder: &mut Value, + holder: &mut JsValue, key: &PropertyKey, - ) -> Result { + ) -> Result { let value = holder.get_field(key.clone(), context)?; - if let Value::Object(ref object) = value { + if let JsValue::Object(ref object) = value { let keys: Vec<_> = object.borrow().properties().keys().collect(); for key in keys { @@ -140,18 +140,22 @@ 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], context: &mut Context) -> Result { + pub(crate) fn stringify( + _: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { let object = match args.get(0) { - None => return Ok(Value::undefined()), + None => return Ok(JsValue::undefined()), Some(obj) => obj, }; const SPACE_INDENT: &str = " "; let gap = if let Some(space) = args.get(2) { let space = if let Some(space_obj) = space.as_object() { if let Some(space) = space_obj.borrow().as_number() { - Value::from(space) + JsValue::new(space) } else if let Some(space) = space_obj.borrow().as_string() { - Value::from(space) + JsValue::new(space) } else { space.clone() } @@ -165,14 +169,14 @@ impl Json { IntegerOrInfinity::Integer(i) if i < 1 => 0, IntegerOrInfinity::Integer(i) => std::cmp::min(i, 10) as usize, }; - Value::from(&SPACE_INDENT[..space_mv]) + JsValue::new(&SPACE_INDENT[..space_mv]) } else if let Some(string) = space.as_string() { - Value::from(&string[..std::cmp::min(string.len(), 10)]) + JsValue::new(&string[..std::cmp::min(string.len(), 10)]) } else { - Value::from("") + JsValue::new("") } } else { - Value::from("") + JsValue::new("") }; let gap = &gap.to_string(context)?; @@ -181,9 +185,9 @@ impl Json { Some(replacer) if replacer.is_object() => replacer, _ => { if let Some(value) = object.to_json(context)? { - return Ok(Value::from(json_to_pretty_string(&value, gap))); + return Ok(JsValue::new(json_to_pretty_string(&value, gap))); } else { - return Ok(Value::undefined()); + return Ok(JsValue::undefined()); } } }; @@ -195,7 +199,7 @@ impl Json { object .as_object() .map(|obj| { - let object_to_return = Value::object(Object::default()); + let object_to_return = JsValue::new(Object::default()); for key in obj.borrow().properties().keys() { let val = obj.__get__(&key, obj.clone().into(), context)?; let this_arg = object.clone(); @@ -205,7 +209,7 @@ impl Json { .value(context.call( replacer, &this_arg, - &[Value::from(key.clone()), val.clone()], + &[JsValue::new(key.clone()), val.clone()], )?) .writable(true) .enumerable(true) @@ -213,12 +217,12 @@ impl Json { ) } if let Some(value) = object_to_return.to_json(context)? { - Ok(Value::from(json_to_pretty_string(&value, gap))) + Ok(JsValue::new(json_to_pretty_string(&value, gap))) } else { - Ok(Value::undefined()) + Ok(JsValue::undefined()) } }) - .ok_or_else(Value::undefined)? + .ok_or_else(JsValue::undefined)? } else if replacer_as_object.is_array() { let mut obj_to_return = serde_json::Map::new(); let replacer_as_object = replacer_as_object.borrow(); @@ -245,14 +249,14 @@ impl Json { } } } - Ok(Value::from(json_to_pretty_string( + Ok(JsValue::new(json_to_pretty_string( &JSONValue::Object(obj_to_return), gap, ))) } else if let Some(value) = object.to_json(context)? { - Ok(Value::from(json_to_pretty_string(&value, gap))) + Ok(JsValue::new(json_to_pretty_string(&value, gap))) } else { - Ok(Value::undefined()) + Ok(JsValue::undefined()) } } } diff --git a/boa/src/builtins/json/tests.rs b/boa/src/builtins/json/tests.rs index 8d6351f357..d09eff8c28 100644 --- a/boa/src/builtins/json/tests.rs +++ b/boa/src/builtins/json/tests.rs @@ -1,4 +1,4 @@ -use crate::{forward, forward_val, Context, Value}; +use crate::{forward, forward_val, Context, JsValue}; #[test] fn json_sanity() { @@ -418,18 +418,21 @@ fn json_parse_sets_prototypes() { .as_object() .unwrap() .prototype_instance(); - let global_object_prototype: Value = context + let global_object_prototype: JsValue = context .standard_objects() .object_object() .prototype() .into(); - let global_array_prototype: Value = + let global_array_prototype: JsValue = context.standard_objects().array_object().prototype().into(); - assert!(Value::same_value( + assert!(JsValue::same_value( &object_prototype, &global_object_prototype )); - assert!(Value::same_value(&array_prototype, &global_array_prototype)); + assert!(JsValue::same_value( + &array_prototype, + &global_array_prototype + )); } #[test] diff --git a/boa/src/builtins/map/map_iterator.rs b/boa/src/builtins/map/map_iterator.rs index 7231337543..b8f16cffd7 100644 --- a/boa/src/builtins/map/map_iterator.rs +++ b/boa/src/builtins/map/map_iterator.rs @@ -1,5 +1,5 @@ use crate::{ - builtins::{function::make_builtin_fn, iterable::create_iter_result_object, Array, Value}, + builtins::{function::make_builtin_fn, iterable::create_iter_result_object, Array, JsValue}, object::{GcObject, ObjectData}, property::PropertyDescriptor, symbol::WellKnownSymbols, @@ -24,7 +24,7 @@ pub enum MapIterationKind { /// [spec]: https://tc39.es/ecma262/#sec-array-iterator-objects #[derive(Debug, Clone, Finalize, Trace)] pub struct MapIterator { - iterated_map: Value, + iterated_map: JsValue, map_next_index: usize, map_iteration_kind: MapIterationKind, lock: MapLock, @@ -34,7 +34,7 @@ impl MapIterator { pub(crate) const NAME: &'static str = "MapIterator"; /// Constructs a new `MapIterator`, that will iterate over `map`, starting at index 0 - fn new(map: Value, kind: MapIterationKind, context: &mut Context) -> Result { + fn new(map: JsValue, kind: MapIterationKind, context: &mut Context) -> Result { let lock = Map::lock(&map, context)?; Ok(MapIterator { iterated_map: map, @@ -54,10 +54,10 @@ impl MapIterator { /// [spec]: https://www.ecma-international.org/ecma-262/11.0/index.html#sec-createmapiterator pub(crate) fn create_map_iterator( context: &mut Context, - map: Value, + map: JsValue, kind: MapIterationKind, - ) -> Result { - let map_iterator = Value::new_object(context); + ) -> Result { + let map_iterator = JsValue::new_object(context); map_iterator.set_data(ObjectData::MapIterator(Self::new(map, kind, context)?)); map_iterator .as_object() @@ -74,8 +74,8 @@ impl MapIterator { /// - [ECMA reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-%mapiteratorprototype%.next - pub(crate) fn next(this: &Value, _: &[Value], context: &mut Context) -> Result { - if let Value::Object(ref object) = this { + pub(crate) fn next(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { + if let JsValue::Object(ref object) = this { let mut object = object.borrow_mut(); if let Some(map_iterator) = object.as_map_iterator_mut() { let m = &map_iterator.iterated_map; @@ -83,10 +83,14 @@ impl MapIterator { let item_kind = &map_iterator.map_iteration_kind; if map_iterator.iterated_map.is_undefined() { - return Ok(create_iter_result_object(context, Value::undefined(), true)); + return Ok(create_iter_result_object( + context, + JsValue::undefined(), + true, + )); } - if let Value::Object(ref object) = m { + if let JsValue::Object(ref object) = m { if let Some(entries) = object.borrow().as_map_ref() { let num_entries = entries.full_len(); while index < num_entries { @@ -129,8 +133,12 @@ impl MapIterator { return Err(context.construct_type_error("'this' is not a Map")); } - map_iterator.iterated_map = Value::undefined(); - Ok(create_iter_result_object(context, Value::undefined(), true)) + map_iterator.iterated_map = JsValue::undefined(); + Ok(create_iter_result_object( + context, + JsValue::undefined(), + true, + )) } else { context.throw_type_error("`this` is not an MapIterator") } @@ -145,7 +153,7 @@ impl MapIterator { /// - [ECMA reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-%mapiteratorprototype%-object - pub(crate) fn create_prototype(context: &mut Context, iterator_prototype: Value) -> GcObject { + pub(crate) fn create_prototype(context: &mut Context, iterator_prototype: JsValue) -> GcObject { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); // Create prototype diff --git a/boa/src/builtins/map/mod.rs b/boa/src/builtins/map/mod.rs index aed07c7413..fc9eaf3dcd 100644 --- a/boa/src/builtins/map/mod.rs +++ b/boa/src/builtins/map/mod.rs @@ -17,7 +17,7 @@ use crate::{ object::{ConstructorBuilder, FunctionBuilder, ObjectData, PROTOTYPE}, property::{Attribute, PropertyDescriptor}, symbol::WellKnownSymbols, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; use ordered_map::OrderedMap; @@ -31,7 +31,7 @@ pub mod ordered_map; mod tests; #[derive(Debug, Clone)] -pub(crate) struct Map(OrderedMap); +pub(crate) struct Map(OrderedMap); impl BuiltIn for Map { const NAME: &'static str = "Map"; @@ -40,7 +40,7 @@ impl BuiltIn for Map { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let to_string_tag = WellKnownSymbols::to_string_tag(); @@ -104,10 +104,10 @@ impl Map { /// Create a new map pub(crate) fn constructor( - new_target: &Value, - args: &[Value], + new_target: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { if new_target.is_undefined() { return context .throw_type_error("calling a builtin Map constructor without new is forbidden"); @@ -125,13 +125,13 @@ impl Map { let obj = context.construct_object(); obj.set_prototype_instance(prototype.into()); - let this = Value::from(obj); + let this = JsValue::new(obj); // add our arguments in let data = match args.len() { 0 => OrderedMap::new(), _ => match &args[0] { - Value::Object(object) => { + JsValue::Object(object) => { let object = object.borrow(); if let Some(map) = object.as_map_ref().cloned() { map @@ -182,7 +182,7 @@ impl Map { /// /// [spec]: https://tc39.es/ecma262/#sec-get-map-@@species /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/@@species - fn get_species(this: &Value, _: &[Value], _: &mut Context) -> Result { + fn get_species(this: &JsValue, _: &[JsValue], _: &mut Context) -> Result { // 1. Return the this value. Ok(this.clone()) } @@ -197,7 +197,7 @@ 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], context: &mut Context) -> Result { + pub(crate) fn entries(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { MapIterator::create_map_iterator(context, this.clone(), MapIterationKind::KeyAndValue) } @@ -211,12 +211,12 @@ 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], context: &mut Context) -> Result { + pub(crate) fn keys(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { MapIterator::create_map_iterator(context, this.clone(), MapIterationKind::Key) } /// Helper function to set the size property. - fn set_size(this: &Value, size: usize) { + fn set_size(this: &JsValue, size: usize) { let size = PropertyDescriptor::builder() .value(size) .writable(false) @@ -236,10 +236,10 @@ 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], context: &mut Context) -> Result { + pub(crate) fn set(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { let (key, value) = match args.len() { - 0 => (Value::Undefined, Value::Undefined), - 1 => (args[0].clone(), Value::Undefined), + 0 => (JsValue::undefined(), JsValue::undefined()), + 1 => (args[0].clone(), JsValue::undefined()), _ => (args[0].clone(), args[1].clone()), }; @@ -268,16 +268,16 @@ 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], context: &mut Context) -> Result { - let undefined = Value::Undefined; - let key = match args.len() { - 0 => &undefined, - _ => &args[0], - }; + pub(crate) fn delete( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { + let key = args.get(0).cloned().unwrap_or_default(); let (deleted, size) = if let Some(object) = this.as_object() { if let Some(map) = object.borrow_mut().as_map_mut() { - let deleted = map.remove(key).is_some(); + let deleted = map.remove(&key).is_some(); (deleted, map.len()) } else { return Err(context.construct_type_error("'this' is not a Map")); @@ -299,20 +299,16 @@ 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], context: &mut Context) -> Result { - let undefined = Value::Undefined; - let key = match args.len() { - 0 => &undefined, - _ => &args[0], - }; + pub(crate) fn get(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { + let key = args.get(0).cloned().unwrap_or_default(); - if let Value::Object(ref object) = this { + if let JsValue::Object(ref object) = this { let object = object.borrow(); if let Some(map) = object.as_map_ref() { - return Ok(if let Some(result) = map.get(key) { + return Ok(if let Some(result) = map.get(&key) { result.clone() } else { - Value::Undefined + JsValue::undefined() }); } } @@ -330,12 +326,12 @@ impl Map { /// /// [spec]: https://tc39.es/ecma262/#sec-map.prototype.clear /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear - pub(crate) fn clear(this: &Value, _: &[Value], _: &mut Context) -> Result { + pub(crate) fn clear(this: &JsValue, _: &[JsValue], _: &mut Context) -> Result { this.set_data(ObjectData::Map(OrderedMap::new())); Self::set_size(this, 0); - Ok(Value::Undefined) + Ok(JsValue::undefined()) } /// `Map.prototype.has( key )` @@ -348,17 +344,13 @@ 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], context: &mut Context) -> Result { - let undefined = Value::Undefined; - let key = match args.len() { - 0 => &undefined, - _ => &args[0], - }; + pub(crate) fn has(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { + let key = args.get(0).cloned().unwrap_or_default(); - if let Value::Object(ref object) = this { + if let JsValue::Object(ref object) = this { let object = object.borrow(); if let Some(map) = object.as_map_ref() { - return Ok(map.contains_key(key).into()); + return Ok(map.contains_key(&key).into()); } } @@ -375,20 +367,24 @@ 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], context: &mut Context) -> Result { + pub(crate) fn for_each( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { if args.is_empty() { - return Err(Value::from("Missing argument for Map.prototype.forEach")); + return Err(JsValue::new("Missing argument for Map.prototype.forEach")); } let callback_arg = &args[0]; - let this_arg = args.get(1).cloned().unwrap_or_else(Value::undefined); + let this_arg = args.get(1).cloned().unwrap_or_else(JsValue::undefined); let mut index = 0; let lock = Map::lock(this, context)?; while index < Map::get_full_len(this, context)? { - let arguments = if let Value::Object(ref object) = this { + let arguments = if let JsValue::Object(ref object) = this { let object = object.borrow(); if let Some(map) = object.as_map_ref() { if let Some((key, value)) = map.get_index(index) { @@ -412,12 +408,12 @@ impl Map { drop(lock); - Ok(Value::Undefined) + Ok(JsValue::undefined()) } /// Helper function to get the full size of the map. - fn get_full_len(map: &Value, context: &mut Context) -> Result { - if let Value::Object(ref object) = map { + fn get_full_len(map: &JsValue, context: &mut Context) -> Result { + if let JsValue::Object(ref object) = map { let object = object.borrow(); if let Some(map) = object.as_map_ref() { Ok(map.full_len()) @@ -430,8 +426,8 @@ impl Map { } /// Helper function to lock the map. - fn lock(map: &Value, context: &mut Context) -> Result { - if let Value::Object(ref object) = map { + fn lock(map: &JsValue, context: &mut Context) -> Result { + if let JsValue::Object(ref object) = map { let mut map = object.borrow_mut(); if let Some(map) = map.as_map_mut() { Ok(map.lock(object.clone())) @@ -453,18 +449,18 @@ 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], context: &mut Context) -> Result { + pub(crate) fn values(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { MapIterator::create_map_iterator(context, this.clone(), MapIterationKind::Value) } /// Helper function to get a key-value pair from an array. - fn get_key_value(value: &Value, context: &mut Context) -> Result> { - if let Value::Object(object) = value { + fn get_key_value(value: &JsValue, context: &mut Context) -> Result> { + if let JsValue::Object(object) = value { if object.is_array() { let (key, value) = match value.get_field("length", context)?.as_number().unwrap() as i32 { - 0 => (Value::Undefined, Value::Undefined), - 1 => (value.get_field("0", context)?, Value::Undefined), + 0 => (JsValue::undefined(), JsValue::undefined()), + 1 => (value.get_field("0", context)?, JsValue::undefined()), _ => ( value.get_field("0", context)?, value.get_field("1", context)?, diff --git a/boa/src/builtins/map/ordered_map.rs b/boa/src/builtins/map/ordered_map.rs index 4a92e5edee..c2581a9d5f 100644 --- a/boa/src/builtins/map/ordered_map.rs +++ b/boa/src/builtins/map/ordered_map.rs @@ -1,7 +1,7 @@ use crate::{ gc::{custom_trace, Finalize, Trace}, object::GcObject, - Value, + JsValue, }; use indexmap::{Equivalent, IndexMap}; use std::{ @@ -12,7 +12,7 @@ use std::{ #[derive(PartialEq, Eq, Clone, Debug)] enum MapKey { - Key(Value), + Key(JsValue), Empty(usize), // Necessary to ensure empty keys are still unique. } @@ -27,7 +27,7 @@ impl Hash for MapKey { } } -impl Equivalent for Value { +impl Equivalent for JsValue { fn equivalent(&self, key: &MapKey) -> bool { match key { MapKey::Key(v) => v == self, @@ -116,7 +116,7 @@ impl OrderedMap { /// inserted, last in order, and `None` is returned. /// /// Computes in **O(1)** time (amortized average). - pub fn insert(&mut self, key: Value, value: V) -> Option { + pub fn insert(&mut self, key: JsValue, value: V) -> Option { self.map.insert(MapKey::Key(key), Some(value)).flatten() } @@ -130,7 +130,7 @@ impl OrderedMap { /// Return `None` if `key` is not in map. /// /// Computes in **O(n)** time (average). - pub fn remove(&mut self, key: &Value) -> Option { + pub fn remove(&mut self, key: &JsValue) -> Option { if self.lock == 0 { self.map.shift_remove(key).flatten() } else if self.map.contains_key(key) { @@ -146,14 +146,14 @@ impl OrderedMap { /// else `None`. /// /// Computes in **O(1)** time (average). - pub fn get(&self, key: &Value) -> Option<&V> { + pub fn get(&self, key: &JsValue) -> Option<&V> { self.map.get(key).map(Option::as_ref).flatten() } /// Get a key-value pair by index /// Valid indices are 0 <= index < self.full_len() /// Computes in O(1) time. - pub fn get_index(&self, index: usize) -> Option<(&Value, &V)> { + pub fn get_index(&self, index: usize) -> Option<(&JsValue, &V)> { if let (MapKey::Key(key), Some(value)) = self.map.get_index(index)? { Some((key, value)) } else { @@ -162,7 +162,7 @@ impl OrderedMap { } /// Return an iterator over the key-value pairs of the map, in their order - pub fn iter(&self) -> impl Iterator { + pub fn iter(&self) -> impl Iterator { self.map.iter().filter_map(|o| { if let (MapKey::Key(key), Some(value)) = o { Some((key, value)) @@ -175,7 +175,7 @@ impl OrderedMap { /// Return `true` if an equivalent to `key` exists in the map. /// /// Computes in **O(1)** time (average). - pub fn contains_key(&self, key: &Value) -> bool { + pub fn contains_key(&self, key: &JsValue) -> bool { self.map.contains_key(key) } diff --git a/boa/src/builtins/math/mod.rs b/boa/src/builtins/math/mod.rs index 0a01945752..cc64a59374 100644 --- a/boa/src/builtins/math/mod.rs +++ b/boa/src/builtins/math/mod.rs @@ -13,7 +13,7 @@ use crate::{ builtins::BuiltIn, object::ObjectInitializer, property::Attribute, symbol::WellKnownSymbols, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; #[cfg(test)] @@ -30,7 +30,7 @@ impl BuiltIn for Math { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let attribute = Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT; @@ -99,7 +99,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.abs /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/abs - pub(crate) fn abs(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn abs(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -116,7 +116,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.acos /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acos - pub(crate) fn acos(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn acos(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -133,7 +133,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.acosh /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acosh - pub(crate) fn acosh(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn acosh(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -150,7 +150,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.asin /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asin - pub(crate) fn asin(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn asin(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -167,7 +167,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.asinh /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asinh - pub(crate) fn asinh(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn asinh(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -184,7 +184,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.atan /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan - pub(crate) fn atan(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn atan(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -201,7 +201,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.atanh /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atanh - pub(crate) fn atanh(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn atanh(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -218,7 +218,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.atan2 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2 - pub(crate) fn atan2(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn atan2(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(match ( args.get(0).map(|x| x.to_number(context)).transpose()?, args.get(1).map(|x| x.to_number(context)).transpose()?, @@ -237,7 +237,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.cbrt /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cbrt - pub(crate) fn cbrt(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn cbrt(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -254,7 +254,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.ceil /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil - pub(crate) fn ceil(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn ceil(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -271,7 +271,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.clz32 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 - pub(crate) fn clz32(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn clz32(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_u32(context)) @@ -289,7 +289,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.cos /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cos - pub(crate) fn cos(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn cos(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -306,7 +306,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.cosh /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cosh - pub(crate) fn cosh(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn cosh(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -323,7 +323,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.exp /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/exp - pub(crate) fn exp(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn exp(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -342,7 +342,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.expm1 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/expm1 - pub(crate) fn expm1(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn expm1(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -359,7 +359,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.floor /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor - pub(crate) fn floor(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn floor(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -376,7 +376,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.fround /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround - pub(crate) fn fround(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn fround(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -393,7 +393,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.hypot /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/hypot - pub(crate) fn hypot(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn hypot(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { let mut result = 0f64; for arg in args { let x = arg.to_number(context)?; @@ -410,7 +410,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.imul /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul - pub(crate) fn imul(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn imul(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(match ( args.get(0).map(|x| x.to_u32(context)).transpose()?, args.get(1).map(|x| x.to_u32(context)).transpose()?, @@ -429,7 +429,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.log /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log - pub(crate) fn log(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn log(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -446,7 +446,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.log1p /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log1p - pub(crate) fn log1p(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn log1p(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -463,7 +463,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.log10 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log10 - pub(crate) fn log10(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn log10(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -480,7 +480,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.log2 /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log2 - pub(crate) fn log2(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn log2(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -497,7 +497,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.max /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max - pub(crate) fn max(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn max(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { let mut max = f64::NEG_INFINITY; for arg in args { let num = arg.to_number(context)?; @@ -514,7 +514,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.min /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min - pub(crate) fn min(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn min(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { let mut min = f64::INFINITY; for arg in args { let num = arg.to_number(context)?; @@ -531,7 +531,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.pow /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/pow - pub(crate) fn pow(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn pow(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(match ( args.get(0).map(|x| x.to_number(context)).transpose()?, args.get(1).map(|x| x.to_number(context)).transpose()?, @@ -550,7 +550,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.random /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random - pub(crate) fn random(_: &Value, _: &[Value], _: &mut Context) -> Result { + pub(crate) fn random(_: &JsValue, _: &[JsValue], _: &mut Context) -> Result { Ok(rand::random::().into()) } @@ -562,7 +562,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.round /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round - pub(crate) fn round(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn round(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -579,7 +579,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.sign /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign - pub(crate) fn sign(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn sign(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -605,7 +605,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.sin /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sin - pub(crate) fn sin(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn sin(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -622,7 +622,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.sinh /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sinh - pub(crate) fn sinh(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn sinh(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -639,7 +639,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.sqrt /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sqrt - pub(crate) fn sqrt(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn sqrt(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -656,7 +656,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.tan /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/tan - pub(crate) fn tan(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn tan(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -673,7 +673,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.tanh /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/tanh - pub(crate) fn tanh(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn tanh(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) @@ -690,7 +690,7 @@ impl Math { /// /// [spec]: https://tc39.es/ecma262/#sec-math.trunc /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc - pub(crate) fn trunc(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn trunc(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { Ok(args .get(0) .map(|x| x.to_number(context)) diff --git a/boa/src/builtins/mod.rs b/boa/src/builtins/mod.rs index 7652c513c5..bf921f53ab 100644 --- a/boa/src/builtins/mod.rs +++ b/boa/src/builtins/mod.rs @@ -54,7 +54,7 @@ pub(crate) use self::{ }; use crate::{ property::{Attribute, PropertyDescriptor}, - Context, Value, + Context, JsValue, }; pub(crate) trait BuiltIn { @@ -62,7 +62,7 @@ pub(crate) trait BuiltIn { const NAME: &'static str; fn attribute() -> Attribute; - fn init(context: &mut Context) -> (&'static str, Value, Attribute); + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute); } /// Initializes builtin objects and functions diff --git a/boa/src/builtins/nan/mod.rs b/boa/src/builtins/nan/mod.rs index b374c37e38..077702f612 100644 --- a/boa/src/builtins/nan/mod.rs +++ b/boa/src/builtins/nan/mod.rs @@ -13,7 +13,7 @@ #[cfg(test)] mod tests; -use crate::{builtins::BuiltIn, property::Attribute, BoaProfiler, Context, Value}; +use crate::{builtins::BuiltIn, property::Attribute, BoaProfiler, Context, JsValue}; /// JavaScript global `NaN` property. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -26,7 +26,7 @@ impl BuiltIn for NaN { Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT } - fn init(_: &mut Context) -> (&'static str, Value, Attribute) { + fn init(_: &mut Context) -> (&'static str, JsValue, 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 1ece3cb16c..21ccaee2a0 100644 --- a/boa/src/builtins/number/mod.rs +++ b/boa/src/builtins/number/mod.rs @@ -19,7 +19,7 @@ use crate::{ builtins::BuiltIn, object::{ConstructorBuilder, ObjectData, PROTOTYPE}, property::Attribute, - value::{AbstractRelation, IntegerOrInfinity, Value}, + value::{AbstractRelation, IntegerOrInfinity, JsValue}, BoaProfiler, Context, Result, }; use num_traits::{float::FloatCore, Num}; @@ -50,7 +50,7 @@ impl BuiltIn for Number { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let attribute = Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT; @@ -155,16 +155,16 @@ impl Number { /// `Number( value )` pub(crate) fn constructor( - new_target: &Value, - args: &[Value], + new_target: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { let data = match args.get(0) { Some(value) => value.to_numeric_number(context)?, None => 0.0, }; if new_target.is_undefined() { - return Ok(Value::from(data)); + return Ok(JsValue::new(data)); } let prototype = new_target .as_object() @@ -175,7 +175,7 @@ impl Number { }) .transpose()? .unwrap_or_else(|| context.standard_objects().object_object().prototype()); - let this = Value::new_object(context); + let this = JsValue::new_object(context); this.as_object() .expect("this should be an object") .set_prototype_instance(prototype.into()); @@ -193,11 +193,11 @@ impl Number { /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-thisnumbervalue - fn this_number_value(value: &Value, context: &mut Context) -> Result { + fn this_number_value(value: &JsValue, context: &mut Context) -> Result { match *value { - Value::Integer(integer) => return Ok(f64::from(integer)), - Value::Rational(rational) => return Ok(rational), - Value::Object(ref object) => { + JsValue::Integer(integer) => return Ok(f64::from(integer)), + JsValue::Rational(rational) => return Ok(rational), + JsValue::Object(ref object) => { if let Some(number) = object.borrow().as_number() { return Ok(number); } @@ -229,13 +229,13 @@ impl Number { /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toExponential #[allow(clippy::wrong_self_convention)] pub(crate) fn to_exponential( - this: &Value, - _: &[Value], + this: &JsValue, + _: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { 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)) + Ok(JsValue::new(this_str_num)) } /// `Number.prototype.toFixed( [digits] )` @@ -249,7 +249,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], context: &mut Context) -> Result { + pub(crate) fn to_fixed( + this: &JsValue, + args: &[JsValue], + 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(context)? as i32 { @@ -259,7 +263,7 @@ impl Number { None => 0, }; let this_fixed_num = format!("{:.*}", precision, this_num); - Ok(Value::from(this_fixed_num)) + Ok(JsValue::new(this_fixed_num)) } /// `Number.prototype.toLocaleString( [locales [, options]] )` @@ -277,13 +281,13 @@ impl Number { /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString #[allow(clippy::wrong_self_convention)] pub(crate) fn to_locale_string( - this: &Value, - _: &[Value], + this: &JsValue, + _: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { let this_num = Self::this_number_value(this, context)?; let this_str_num = format!("{}", this_num); - Ok(Value::from(this_str_num)) + Ok(JsValue::new(this_str_num)) } /// flt_str_to_exp - used in to_precision @@ -384,16 +388,16 @@ impl Number { /// [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], + this: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { let precision = args.get(0).cloned().unwrap_or_default(); // 1 & 6 let mut this_num = Self::this_number_value(this, context)?; // 2 - if precision == Value::undefined() { + if precision == JsValue::undefined() { return Self::to_string(this, &[], context); } @@ -467,14 +471,14 @@ impl Number { // iv, v suffix.push_str(&exponent.to_string()); - return Ok(Value::from(prefix + &suffix)); + return Ok(JsValue::new(prefix + &suffix)); } } // 11 let e_inc = exponent + 1; if e_inc == precision_i32 { - return Ok(Value::from(prefix + &suffix)); + return Ok(JsValue::new(prefix + &suffix)); } // 12 @@ -488,7 +492,7 @@ impl Number { } // 14 - Ok(Value::from(prefix + &suffix)) + Ok(JsValue::new(prefix + &suffix)) } // https://golang.org/src/math/nextafter.go @@ -630,7 +634,11 @@ 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], context: &mut Context) -> Result { + pub(crate) fn to_string( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let x be ? thisNumberValue(this value). let x = Self::this_number_value(this, context)?; @@ -650,17 +658,17 @@ impl Number { // 5. If radixNumber = 10, return ! ToString(x). if radix == 10 { - return Ok(Value::from(Self::to_native_string(x))); + return Ok(JsValue::new(Self::to_native_string(x))); } if x == -0. { - return Ok(Value::from("0")); + return Ok(JsValue::new("0")); } else if x.is_nan() { - return Ok(Value::from("NaN")); + return Ok(JsValue::new("NaN")); } else if x.is_infinite() && x.is_sign_positive() { - return Ok(Value::from("Infinity")); + return Ok(JsValue::new("Infinity")); } else if x.is_infinite() && x.is_sign_negative() { - return Ok(Value::from("-Infinity")); + return Ok(JsValue::new("-Infinity")); } // This is a Optimization from the v8 source code to print values that can fit in a single character @@ -672,7 +680,7 @@ impl Number { // } // 6. Return the String representation of this Number value using the radix specified by radixNumber. - Ok(Value::from(Self::to_native_string_radix(x, radix))) + Ok(JsValue::new(Self::to_native_string_radix(x, radix))) } /// `Number.prototype.toString()` @@ -685,8 +693,12 @@ 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, _: &[Value], context: &mut Context) -> Result { - Ok(Value::from(Self::this_number_value(this, context)?)) + pub(crate) fn value_of( + this: &JsValue, + _: &[JsValue], + context: &mut Context, + ) -> Result { + Ok(JsValue::new(Self::this_number_value(this, context)?)) } /// Builtin javascript 'parseInt(str, radix)' function. @@ -703,7 +715,11 @@ 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(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn parse_int( + _: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { if let (Some(val), radix) = (args.get(0), args.get(1)) { // 1. Let inputString be ? ToString(string). let input_string = val.to_string(context)?; @@ -738,7 +754,7 @@ impl Number { if var_r != 0 { // a. If R < 2 or R > 36, return NaN. if !(2..=36).contains(&var_r) { - return Ok(Value::nan()); + return Ok(JsValue::nan()); } // b. If R โ‰  16, set stripPrefix to false. @@ -777,7 +793,7 @@ impl Number { // 13. If Z is empty, return NaN. if var_z.is_empty() { - return Ok(Value::nan()); + return Ok(JsValue::nan()); } // 14. Let mathInt be the integer value that is represented by Z in radix-R notation, using the @@ -796,17 +812,17 @@ impl Number { // b. Return +0๐”ฝ. if math_int == 0_f64 { if sign == -1 { - return Ok(Value::rational(-0_f64)); + return Ok(JsValue::new(-0_f64)); } else { - return Ok(Value::rational(0_f64)); + return Ok(JsValue::new(0_f64)); } } // 16. Return ๐”ฝ(sign ร— mathInt). - Ok(Value::rational(f64::from(sign) * math_int)) + Ok(JsValue::new(f64::from(sign) * math_int)) } else { // Not enough arguments to parseInt. - Ok(Value::nan()) + Ok(JsValue::nan()) } } @@ -825,7 +841,11 @@ 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(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn parse_float( + _: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { if let Some(val) = args.get(0) { let input_string = val.to_string(context)?; let s = input_string.trim_start_matches(is_trimmable_whitespace); @@ -833,29 +853,29 @@ impl Number { // TODO: write our own lexer to match syntax StrDecimalLiteral if s.starts_with("Infinity") || s.starts_with("+Infinity") { - Ok(Value::from(f64::INFINITY)) + Ok(JsValue::new(f64::INFINITY)) } else if s.starts_with("-Infinity") { - Ok(Value::from(f64::NEG_INFINITY)) + Ok(JsValue::new(f64::NEG_INFINITY)) } else if s_prefix_lower.starts_with("inf") || s_prefix_lower.starts_with("+inf") || s_prefix_lower.starts_with("-inf") { // Prevent fast_float from parsing "inf", "+inf" as Infinity and "-inf" as -Infinity - Ok(Value::nan()) + Ok(JsValue::nan()) } else { Ok(fast_float::parse_partial::(s) .map(|(f, len)| { if len > 0 { - Value::rational(f) + JsValue::new(f) } else { - Value::nan() + JsValue::nan() } }) - .unwrap_or_else(|_| Value::nan())) + .unwrap_or_else(|_| JsValue::nan())) } } else { // Not enough arguments to parseFloat. - Ok(Value::nan()) + Ok(JsValue::nan()) } } @@ -874,10 +894,10 @@ 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( - _: &Value, - args: &[Value], + _: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { if let Some(value) = args.get(0) { let number = value.to_number(context)?; Ok(number.is_finite().into()) @@ -900,7 +920,11 @@ 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(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn global_is_nan( + _: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { if let Some(value) = args.get(0) { let number = value.to_number(context)?; Ok(number.is_nan().into()) @@ -923,11 +947,15 @@ 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(_: &Value, args: &[Value], _ctx: &mut Context) -> Result { - Ok(Value::from(if let Some(val) = args.get(0) { + pub(crate) fn number_is_finite( + _: &JsValue, + args: &[JsValue], + _ctx: &mut Context, + ) -> Result { + Ok(JsValue::new(if let Some(val) = args.get(0) { match val { - Value::Integer(_) => true, - Value::Rational(number) => number.is_finite(), + JsValue::Integer(_) => true, + JsValue::Rational(number) => number.is_finite(), _ => false, } } else { @@ -946,10 +974,10 @@ 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( - _: &Value, - args: &[Value], + _: &JsValue, + args: &[JsValue], _ctx: &mut Context, - ) -> Result { + ) -> Result { Ok(args.get(0).map_or(false, Self::is_integer).into()) } @@ -967,11 +995,15 @@ 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(_: &Value, args: &[Value], _ctx: &mut Context) -> Result { - Ok(Value::from(if let Some(val) = args.get(0) { + pub(crate) fn number_is_nan( + _: &JsValue, + args: &[JsValue], + _ctx: &mut Context, + ) -> Result { + Ok(JsValue::new(if let Some(val) = args.get(0) { match val { - Value::Integer(_) => false, - Value::Rational(number) => number.is_nan(), + JsValue::Integer(_) => false, + JsValue::Rational(number) => number.is_nan(), _ => false, } } else { @@ -993,10 +1025,14 @@ 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(_: &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) => { + pub(crate) fn is_safe_integer( + _: &JsValue, + args: &[JsValue], + _ctx: &mut Context, + ) -> Result { + Ok(JsValue::new(match args.get(0) { + Some(JsValue::Integer(_)) => true, + Some(JsValue::Rational(number)) if Self::is_float_integer(*number) => { number.abs() <= Number::MAX_SAFE_INTEGER } _ => false, @@ -1010,10 +1046,10 @@ impl Number { /// /// [spec]: https://tc39.es/ecma262/#sec-isinteger #[inline] - pub(crate) fn is_integer(val: &Value) -> bool { + pub(crate) fn is_integer(val: &JsValue) -> bool { match val { - Value::Integer(_) => true, - Value::Rational(number) => Number::is_float_integer(*number), + JsValue::Integer(_) => true, + JsValue::Rational(number) => Number::is_float_integer(*number), _ => false, } } diff --git a/boa/src/builtins/object/for_in_iterator.rs b/boa/src/builtins/object/for_in_iterator.rs index 7449d6b4ef..eaede65e72 100644 --- a/boa/src/builtins/object/for_in_iterator.rs +++ b/boa/src/builtins/object/for_in_iterator.rs @@ -5,7 +5,7 @@ use crate::{ property::PropertyDescriptor, property::PropertyKey, symbol::WellKnownSymbols, - BoaProfiler, Context, JsString, Result, Value, + BoaProfiler, Context, JsString, JsValue, Result, }; use rustc_hash::FxHashSet; use std::collections::VecDeque; @@ -19,7 +19,7 @@ use std::collections::VecDeque; /// [spec]: https://tc39.es/ecma262/#sec-for-in-iterator-objects #[derive(Debug, Clone, Finalize, Trace)] pub struct ForInIterator { - object: Value, + object: JsValue, visited_keys: FxHashSet, remaining_keys: VecDeque, object_was_visited: bool, @@ -28,7 +28,7 @@ pub struct ForInIterator { impl ForInIterator { pub(crate) const NAME: &'static str = "ForInIterator"; - fn new(object: Value) -> Self { + fn new(object: JsValue) -> Self { ForInIterator { object, visited_keys: FxHashSet::default(), @@ -45,8 +45,8 @@ impl ForInIterator { /// - [ECMA reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-createforiniterator - pub(crate) fn create_for_in_iterator(context: &Context, object: Value) -> Value { - let for_in_iterator = Value::new_object(context); + pub(crate) fn create_for_in_iterator(context: &Context, object: JsValue) -> JsValue { + let for_in_iterator = JsValue::new_object(context); for_in_iterator.set_data(ObjectData::ForInIterator(Self::new(object))); for_in_iterator .as_object() @@ -63,8 +63,8 @@ impl ForInIterator { /// - [ECMA reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-%foriniteratorprototype%.next - pub(crate) fn next(this: &Value, _: &[Value], context: &mut Context) -> Result { - if let Value::Object(ref o) = this { + pub(crate) fn next(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { + if let JsValue::Object(ref o) = this { let mut for_in_iterator = o.borrow_mut(); if let Some(iterator) = for_in_iterator.as_for_in_iterator_mut() { let mut object = iterator.object.to_object(context)?; @@ -93,7 +93,7 @@ impl ForInIterator { if desc.expect_enumerable() { return Ok(create_iter_result_object( context, - Value::from(r.to_string()), + JsValue::new(r.to_string()), false, )); } @@ -105,10 +105,14 @@ impl ForInIterator { object = o; } _ => { - return Ok(create_iter_result_object(context, Value::undefined(), true)) + return Ok(create_iter_result_object( + context, + JsValue::undefined(), + true, + )) } } - iterator.object = Value::from(object.clone()); + iterator.object = JsValue::new(object.clone()); iterator.object_was_visited = false; } } else { @@ -125,7 +129,7 @@ impl ForInIterator { /// - [ECMA reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-%foriniteratorprototype%-object - pub(crate) fn create_prototype(context: &mut Context, iterator_prototype: Value) -> GcObject { + pub(crate) fn create_prototype(context: &mut Context, iterator_prototype: JsValue) -> GcObject { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); // Create prototype diff --git a/boa/src/builtins/object/mod.rs b/boa/src/builtins/object/mod.rs index ddf20f2bdc..61165faa41 100644 --- a/boa/src/builtins/object/mod.rs +++ b/boa/src/builtins/object/mod.rs @@ -20,7 +20,7 @@ use crate::{ }, property::{Attribute, DescriptorKind, PropertyDescriptor}, symbol::WellKnownSymbols, - value::{Type, Value}, + value::{JsValue, Type}, BoaProfiler, Context, Result, }; @@ -39,7 +39,7 @@ impl BuiltIn for Object { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let object = ConstructorBuilder::with_standard_object( @@ -49,7 +49,7 @@ impl BuiltIn for Object { ) .name(Self::NAME) .length(Self::LENGTH) - .inherit(Value::null()) + .inherit(JsValue::null()) .method(Self::has_own_property, "hasOwnProperty", 0) .method(Self::property_is_enumerable, "propertyIsEnumerable", 0) .method(Self::to_string, "toString", 0) @@ -80,7 +80,11 @@ impl BuiltIn for Object { impl Object { const LENGTH: usize = 1; - fn constructor(new_target: &Value, args: &[Value], context: &mut Context) -> Result { + fn constructor( + new_target: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { if !new_target.is_undefined() { let prototype = new_target .as_object() @@ -91,7 +95,7 @@ impl Object { }) .transpose()? .unwrap_or_else(|| context.standard_objects().object_object().prototype()); - let object = Value::new_object(context); + let object = JsValue::new_object(context); object .as_object() @@ -104,7 +108,7 @@ impl Object { return Ok(arg.to_object(context)?.into()); } } - Ok(Value::new_object(context)) + Ok(JsValue::new_object(context)) } /// `Object.create( proto, [propertiesObject] )` @@ -117,12 +121,12 @@ 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], 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); + pub fn create(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { + let prototype = args.get(0).cloned().unwrap_or_else(JsValue::undefined); + let properties = args.get(1).cloned().unwrap_or_else(JsValue::undefined); let obj = match prototype { - Value::Object(_) | Value::Null => Value::object(BuiltinObject::with_prototype( + JsValue::Object(_) | JsValue::Null => JsValue::new(BuiltinObject::with_prototype( prototype, ObjectData::Ordinary, )), @@ -135,7 +139,7 @@ impl Object { }; if !properties.is_undefined() { - return Object::define_properties(&Value::Undefined, &[obj, properties], context); + return Object::define_properties(&JsValue::undefined(), &[obj, properties], context); } Ok(obj) @@ -152,13 +156,13 @@ impl Object { /// [spec]: https://tc39.es/ecma262/#sec-object.getownpropertydescriptor /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor pub fn get_own_property_descriptor( - _: &Value, - args: &[Value], + _: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { let object = args .get(0) - .unwrap_or(&Value::undefined()) + .unwrap_or(&JsValue::undefined()) .to_object(context)?; if let Some(key) = args.get(1) { let key = key.to_property_key(context)?; @@ -168,7 +172,7 @@ impl Object { } } - Ok(Value::undefined()) + Ok(JsValue::undefined()) } /// `Object.getOwnPropertyDescriptors( object )` @@ -182,13 +186,13 @@ impl Object { /// [spec]: https://tc39.es/ecma262/#sec-object.getownpropertydescriptors /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors pub fn get_own_property_descriptors( - _: &Value, - args: &[Value], + _: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { let object = args .get(0) - .unwrap_or(&Value::undefined()) + .unwrap_or(&JsValue::undefined()) .to_object(context)?; let descriptors = context.construct_object(); @@ -212,7 +216,7 @@ impl Object { } } - Ok(Value::Object(descriptors)) + Ok(JsValue::Object(descriptors)) } /// The abstract operation `FromPropertyDescriptor`. @@ -220,7 +224,7 @@ impl Object { /// [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-frompropertydescriptor - fn from_property_descriptor(desc: PropertyDescriptor, context: &mut Context) -> Value { + fn from_property_descriptor(desc: PropertyDescriptor, context: &mut Context) -> JsValue { let mut descriptor = ObjectInitializer::new(context); // TODO: use CreateDataPropertyOrThrow @@ -257,15 +261,15 @@ impl Object { } /// Uses the SameValue algorithm to check equality of objects - pub fn is(_: &Value, args: &[Value], _: &mut Context) -> Result { - let x = args.get(0).cloned().unwrap_or_else(Value::undefined); - let y = args.get(1).cloned().unwrap_or_else(Value::undefined); + pub fn is(_: &JsValue, args: &[JsValue], _: &mut Context) -> Result { + let x = args.get(0).cloned().unwrap_or_else(JsValue::undefined); + let y = args.get(1).cloned().unwrap_or_else(JsValue::undefined); - Ok(Value::same_value(&x, &y).into()) + Ok(JsValue::same_value(&x, &y).into()) } /// Get the `prototype` of an object. - pub fn get_prototype_of(_: &Value, args: &[Value], ctx: &mut Context) -> Result { + pub fn get_prototype_of(_: &JsValue, args: &[JsValue], ctx: &mut Context) -> Result { if args.is_empty() { return ctx.throw_type_error( "Object.getPrototypeOf: At least 1 argument required, but only 0 passed", @@ -284,7 +288,7 @@ impl Object { /// [More information][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-object.setprototypeof - pub fn set_prototype_of(_: &Value, args: &[Value], ctx: &mut Context) -> Result { + pub fn set_prototype_of(_: &JsValue, args: &[JsValue], ctx: &mut Context) -> Result { if args.len() < 2 { return ctx.throw_type_error(format!( "Object.setPrototypeOf: At least 2 arguments required, but only {} passed", @@ -339,35 +343,43 @@ impl Object { /// /// [spec]: https://tc39.es/ecma262/#sec-object.prototype.isprototypeof /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isPrototypeOf - pub fn is_prototype_of(this: &Value, args: &[Value], context: &mut Context) -> Result { - let undefined = Value::undefined(); + pub fn is_prototype_of( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { + let undefined = JsValue::undefined(); let mut v = args.get(0).unwrap_or(&undefined).clone(); if !v.is_object() { - return Ok(Value::Boolean(false)); + return Ok(JsValue::new(false)); } - let o = Value::from(this.to_object(context)?); + let o = JsValue::new(this.to_object(context)?); loop { v = Self::get_prototype_of(this, &[v], context)?; if v.is_null() { - return Ok(Value::Boolean(false)); + return Ok(JsValue::new(false)); } - if Value::same_value(&o, &v) { - return Ok(Value::Boolean(true)); + if JsValue::same_value(&o, &v) { + return Ok(JsValue::new(true)); } } } /// Define a property in an object - pub fn define_property(_: &Value, args: &[Value], context: &mut Context) -> Result { - let object = args.get(0).cloned().unwrap_or_else(Value::undefined); + pub fn define_property( + _: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { + let object = args.get(0).cloned().unwrap_or_else(JsValue::undefined); if let Some(object) = object.as_object() { let key = args .get(1) - .unwrap_or(&Value::Undefined) + .unwrap_or(&JsValue::Undefined) .to_property_key(context)?; let desc = args .get(2) - .unwrap_or(&Value::Undefined) + .unwrap_or(&JsValue::Undefined) .to_property_descriptor(context)?; object.define_property_or_throw(key, desc, context)?; @@ -388,11 +400,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], context: &mut Context) -> Result { + pub fn define_properties( + _: &JsValue, + args: &[JsValue], + 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); + let props = args.get(1).cloned().unwrap_or_else(JsValue::undefined); obj.define_properties(props, context)?; Ok(arg) } else { @@ -410,7 +426,7 @@ 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], context: &mut Context) -> Result { + pub fn to_string(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { // 1. If the this value is undefined, return "[object Undefined]". if this.is_undefined() { return Ok("[object Undefined]".into()); @@ -470,10 +486,14 @@ 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], context: &mut Context) -> Result { + pub fn has_own_property( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { let key = args .get(0) - .unwrap_or(&Value::undefined()) + .unwrap_or(&JsValue::undefined()) .to_property_key(context)?; let object = this.to_object(context)?; @@ -492,20 +512,20 @@ impl Object { /// [spec]: https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable pub fn property_is_enumerable( - this: &Value, - args: &[Value], + this: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { let key = match args.get(0) { - None => return Ok(Value::from(false)), + None => return Ok(JsValue::new(false)), Some(key) => 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()) + Ok(own_property.map_or(JsValue::new(false), |own_prop| { + JsValue::new(own_prop.enumerable()) })) } @@ -520,7 +540,7 @@ impl Object { /// /// [spec]: https://tc39.es/ecma262/#sec-object.assign /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign - pub fn assign(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub fn assign(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { // // // 1. Let to be ? ToObject(target). diff --git a/boa/src/builtins/object/tests.rs b/boa/src/builtins/object/tests.rs index 3ef47a30d2..6fb4bd8e80 100644 --- a/boa/src/builtins/object/tests.rs +++ b/boa/src/builtins/object/tests.rs @@ -1,4 +1,4 @@ -use crate::{forward, Context, Value}; +use crate::{forward, Context, JsValue}; #[test] fn object_create_with_regular_object() { @@ -218,7 +218,7 @@ fn get_own_property_descriptor_1_arg_returns_undefined() { let obj = {a: 2}; Object.getOwnPropertyDescriptor(obj) "#; - assert_eq!(context.eval(code).unwrap(), Value::undefined()); + assert_eq!(context.eval(code).unwrap(), JsValue::undefined()); } #[test] @@ -287,5 +287,5 @@ fn object_is_prototype_of() { Object.prototype.isPrototypeOf(String.prototype) "#; - assert_eq!(context.eval(init).unwrap(), Value::boolean(true)); + assert_eq!(context.eval(init).unwrap(), JsValue::new(true)); } diff --git a/boa/src/builtins/reflect/mod.rs b/boa/src/builtins/reflect/mod.rs index 4848cc367f..ac1265f85f 100644 --- a/boa/src/builtins/reflect/mod.rs +++ b/boa/src/builtins/reflect/mod.rs @@ -15,7 +15,7 @@ use crate::{ object::{Object, ObjectData, ObjectInitializer}, property::{Attribute, PropertyDescriptor}, symbol::WellKnownSymbols, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; #[cfg(test)] @@ -32,7 +32,7 @@ impl BuiltIn for Reflect { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let to_string_tag = WellKnownSymbols::to_string_tag(); @@ -74,8 +74,8 @@ impl Reflect { /// /// [spec]: https://tc39.es/ecma262/#sec-reflect.apply /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/apply - pub(crate) fn apply(_: &Value, args: &[Value], context: &mut Context) -> Result { - let undefined = Value::undefined(); + pub(crate) fn apply(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { + let undefined = JsValue::undefined(); let target = args .get(0) .and_then(|v| v.as_object()) @@ -101,7 +101,11 @@ impl Reflect { /// /// [spec]: https://tc39.es/ecma262/#sec-reflect.construct /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/construct - pub(crate) fn construct(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn construct( + _: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { let target = args .get(0) .and_then(|v| v.as_object()) @@ -137,17 +141,17 @@ impl Reflect { /// [spec]: https://tc39.es/ecma262/#sec-reflect.defineProperty /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/defineProperty pub(crate) fn define_property( - _: &Value, - args: &[Value], + _: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { - let undefined = Value::undefined(); + ) -> Result { + let undefined = JsValue::undefined(); let target = args .get(0) .and_then(|v| v.as_object()) .ok_or_else(|| context.construct_type_error("target must be an object"))?; let key = args.get(1).unwrap_or(&undefined).to_property_key(context)?; - let prop_desc: Value = args + let prop_desc: JsValue = args .get(2) .and_then(|v| v.as_object()) .ok_or_else(|| context.construct_type_error("property descriptor must be an object"))? @@ -167,11 +171,11 @@ impl Reflect { /// [spec]: https://tc39.es/ecma262/#sec-reflect.deleteproperty /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/deleteProperty pub(crate) fn delete_property( - _: &Value, - args: &[Value], + _: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { - let undefined = Value::undefined(); + ) -> Result { + let undefined = JsValue::undefined(); let target = args .get(0) .and_then(|v| v.as_object()) @@ -189,8 +193,8 @@ impl Reflect { /// /// [spec]: https://tc39.es/ecma262/#sec-reflect.get /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/get - pub(crate) fn get(_: &Value, args: &[Value], context: &mut Context) -> Result { - let undefined = Value::undefined(); + pub(crate) fn get(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { + let undefined = JsValue::undefined(); // 1. If Type(target) is not Object, throw a TypeError exception. let target = args .get(0) @@ -218,17 +222,17 @@ impl Reflect { /// [spec]: https://tc39.es/ecma262/#sec-reflect.getownpropertydescriptor /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/getOwnPropertyDescriptor pub(crate) fn get_own_property_descriptor( - _: &Value, - args: &[Value], + _: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { match args.get(0) { Some(v) if v.is_object() => (), _ => return context.throw_type_error("target must be an object"), } // This function is the same as Object.prototype.getOwnPropertyDescriptor, that why // it is invoked here. - builtins::object::Object::get_own_property_descriptor(&Value::undefined(), args, context) + builtins::object::Object::get_own_property_descriptor(&JsValue::undefined(), args, context) } /// Gets the prototype of an object. @@ -240,10 +244,10 @@ impl Reflect { /// [spec]: https://tc39.es/ecma262/#sec-reflect.getprototypeof /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/getPrototypeOf pub(crate) fn get_prototype_of( - _: &Value, - args: &[Value], + _: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { let target = args .get(0) .and_then(|v| v.as_object()) @@ -259,14 +263,14 @@ impl Reflect { /// /// [spec]: https://tc39.es/ecma262/#sec-reflect.has /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/has - pub(crate) fn has(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn has(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { let target = args .get(0) .and_then(|v| v.as_object()) .ok_or_else(|| context.construct_type_error("target must be an object"))?; let key = args .get(1) - .unwrap_or(&Value::undefined()) + .unwrap_or(&JsValue::undefined()) .to_property_key(context)?; Ok(target.__has_property__(&key).into()) } @@ -279,7 +283,11 @@ impl Reflect { /// /// [spec]: https://tc39.es/ecma262/#sec-reflect.isextensible /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/isExtensible - pub(crate) fn is_extensible(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn is_extensible( + _: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { let target = args .get(0) .and_then(|v| v.as_object()) @@ -295,13 +303,17 @@ impl Reflect { /// /// [spec]: https://tc39.es/ecma262/#sec-reflect.ownkeys /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/ownKeys - pub(crate) fn own_keys(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn own_keys( + _: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { let target = args .get(0) .and_then(|v| v.as_object()) .ok_or_else(|| context.construct_type_error("target must be an object"))?; let array_prototype = context.standard_objects().array_object().prototype(); - let result: Value = + let result: JsValue = Object::with_prototype(array_prototype.into(), ObjectData::Array).into(); result.set_property( "length", @@ -329,10 +341,10 @@ impl Reflect { /// [spec]: https://tc39.es/ecma262/#sec-reflect.preventextensions /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/preventExtensions pub(crate) fn prevent_extensions( - _: &Value, - args: &[Value], + _: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { let mut target = args .get(0) .and_then(|v| v.as_object()) @@ -349,8 +361,8 @@ impl Reflect { /// /// [spec]: https://tc39.es/ecma262/#sec-reflect.set /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/set - pub(crate) fn set(_: &Value, args: &[Value], context: &mut Context) -> Result { - let undefined = Value::undefined(); + pub(crate) fn set(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { + let undefined = JsValue::undefined(); let target = args .get(0) .and_then(|v| v.as_object()) @@ -376,11 +388,11 @@ impl Reflect { /// [spec]: https://tc39.es/ecma262/#sec-reflect.setprototypeof /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/setPrototypeOf pub(crate) fn set_prototype_of( - _: &Value, - args: &[Value], + _: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { - let undefined = Value::undefined(); + ) -> Result { + let undefined = JsValue::undefined(); let mut target = args .get(0) .and_then(|v| v.as_object()) diff --git a/boa/src/builtins/regexp/mod.rs b/boa/src/builtins/regexp/mod.rs index 5c1d6f82b9..37c3e0437e 100644 --- a/boa/src/builtins/regexp/mod.rs +++ b/boa/src/builtins/regexp/mod.rs @@ -17,7 +17,7 @@ use crate::{ object::{ConstructorBuilder, FunctionBuilder, GcObject, Object, ObjectData, PROTOTYPE}, property::Attribute, symbol::WellKnownSymbols, - value::{IntegerOrInfinity, Value}, + value::{IntegerOrInfinity, JsValue}, BoaProfiler, Context, JsString, Result, }; use regexp_string_iterator::RegExpStringIterator; @@ -69,7 +69,7 @@ impl BuiltIn for RegExp { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let get_species = FunctionBuilder::native(context, Self::get_species) @@ -183,15 +183,15 @@ impl RegExp { /// /// [spec]: https://tc39.es/ecma262/#sec-regexp-pattern-flags pub(crate) fn constructor( - new_target: &Value, - args: &[Value], + new_target: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { - let pattern = args.get(0).cloned().unwrap_or_else(Value::undefined); - let flags = args.get(1).cloned().unwrap_or_else(Value::undefined); + ) -> Result { + let pattern = args.get(0).cloned().unwrap_or_else(JsValue::undefined); + let flags = args.get(1).cloned().unwrap_or_else(JsValue::undefined); // 1. Let patternIsRegExp be ? IsRegExp(pattern). - let pattern_is_regexp = if let Value::Object(obj) = &pattern { + let pattern_is_regexp = if let JsValue::Object(obj) = &pattern { if obj.is_regexp() { Some(obj) } else { @@ -211,7 +211,7 @@ impl RegExp { // i. Let patternConstructor be ? Get(pattern, "constructor"). let pattern_constructor = pattern.get("constructor", context)?; // ii. If SameValue(newTarget, patternConstructor) is true, return pattern. - if Value::same_value(new_target, &pattern_constructor) { + if JsValue::same_value(new_target, &pattern_constructor) { return Ok(pattern.clone().into()); } } @@ -229,11 +229,11 @@ impl RegExp { // c. Else, let F be flags. if flags.is_undefined() { ( - Value::from(regexp.original_source.clone()), - Value::from(regexp.original_flags.clone()), + JsValue::new(regexp.original_source.clone()), + JsValue::new(regexp.original_flags.clone()), ) } else { - (Value::from(regexp.original_source.clone()), flags) + (JsValue::new(regexp.original_source.clone()), flags) } } else { // a. Let P be pattern. @@ -254,7 +254,7 @@ impl RegExp { /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-regexpalloc - fn alloc(this: &Value, _: &[Value], context: &mut Context) -> Result { + fn alloc(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { let proto = if let Some(obj) = this.as_object() { obj.get(PROTOTYPE, context)? } else { @@ -274,9 +274,9 @@ impl RegExp { /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-regexpinitialize - fn initialize(this: &Value, args: &[Value], context: &mut Context) -> Result { - let pattern = args.get(0).cloned().unwrap_or_else(Value::undefined); - let flags = args.get(1).cloned().unwrap_or_else(Value::undefined); + fn initialize(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { + let pattern = args.get(0).cloned().unwrap_or_else(JsValue::undefined); + let flags = args.get(1).cloned().unwrap_or_else(JsValue::undefined); // 1. If pattern is undefined, let P be the empty String. // 2. Else, let P be ? ToString(pattern). @@ -373,7 +373,7 @@ impl RegExp { /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-regexpcreate - pub(crate) fn create(p: Value, f: Value, context: &mut Context) -> Result { + pub(crate) fn create(p: JsValue, f: JsValue, context: &mut Context) -> Result { // 1. Let obj be ? RegExpAlloc(%RegExp%). let obj = RegExp::alloc( &context.global_object().get(RegExp::NAME, context)?, @@ -395,16 +395,16 @@ impl RegExp { /// /// [spec]: https://tc39.es/ecma262/#sec-get-regexp-@@species /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@species - fn get_species(this: &Value, _: &[Value], _: &mut Context) -> Result { + fn get_species(this: &JsValue, _: &[JsValue], _: &mut Context) -> Result { // 1. Return the this value. Ok(this.clone()) } #[inline] - fn regexp_has_flag(this: &Value, flag: char, context: &mut Context) -> Result { + fn regexp_has_flag(this: &JsValue, flag: char, context: &mut Context) -> Result { if let Some(object) = this.as_object() { if let Some(regexp) = object.borrow().as_regexp() { - return Ok(Value::boolean(match flag { + return Ok(JsValue::new(match flag { 'g' => regexp.global, 'm' => regexp.multiline, 's' => regexp.dot_all, @@ -419,7 +419,7 @@ impl RegExp { &object, &context.standard_objects().regexp_object().prototype, ) { - return Ok(Value::undefined()); + return Ok(JsValue::undefined()); } } @@ -449,7 +449,11 @@ impl RegExp { /// /// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.global /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/global - pub(crate) fn get_global(this: &Value, _: &[Value], context: &mut Context) -> Result { + pub(crate) fn get_global( + this: &JsValue, + _: &[JsValue], + context: &mut Context, + ) -> Result { Self::regexp_has_flag(this, 'g', context) } @@ -464,10 +468,10 @@ impl RegExp { /// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.ignorecase /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/ignoreCase pub(crate) fn get_ignore_case( - this: &Value, - _: &[Value], + this: &JsValue, + _: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { Self::regexp_has_flag(this, 'i', context) } @@ -481,7 +485,11 @@ impl RegExp { /// /// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.multiline /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/multiline - pub(crate) fn get_multiline(this: &Value, _: &[Value], context: &mut Context) -> Result { + pub(crate) fn get_multiline( + this: &JsValue, + _: &[JsValue], + context: &mut Context, + ) -> Result { Self::regexp_has_flag(this, 'm', context) } @@ -495,7 +503,11 @@ impl RegExp { /// /// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.dotAll /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/dotAll - pub(crate) fn get_dot_all(this: &Value, _: &[Value], context: &mut Context) -> Result { + pub(crate) fn get_dot_all( + this: &JsValue, + _: &[JsValue], + context: &mut Context, + ) -> Result { Self::regexp_has_flag(this, 's', context) } @@ -510,7 +522,11 @@ impl RegExp { /// /// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.unicode /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/unicode - pub(crate) fn get_unicode(this: &Value, _: &[Value], context: &mut Context) -> Result { + pub(crate) fn get_unicode( + this: &JsValue, + _: &[JsValue], + context: &mut Context, + ) -> Result { Self::regexp_has_flag(this, 'u', context) } @@ -525,7 +541,11 @@ impl RegExp { /// /// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.sticky /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky - pub(crate) fn get_sticky(this: &Value, _: &[Value], context: &mut Context) -> Result { + pub(crate) fn get_sticky( + this: &JsValue, + _: &[JsValue], + context: &mut Context, + ) -> Result { Self::regexp_has_flag(this, 'y', context) } @@ -540,7 +560,11 @@ impl RegExp { /// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.flags /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/flags /// [flags]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Advanced_searching_with_flags_2 - pub(crate) fn get_flags(this: &Value, _: &[Value], context: &mut Context) -> Result { + pub(crate) fn get_flags( + this: &JsValue, + _: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let R be the this value. // 2. If Type(R) is not Object, throw a TypeError exception. if let Some(object) = this.as_object() { @@ -598,7 +622,11 @@ impl RegExp { /// /// [spec]: https://tc39.es/ecma262/#sec-get-regexp.prototype.source /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/source - pub(crate) fn get_source(this: &Value, _: &[Value], context: &mut Context) -> Result { + pub(crate) fn get_source( + this: &JsValue, + _: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let R be the this value. // 2. If Type(R) is not Object, throw a TypeError exception. if let Some(object) = this.as_object() { @@ -609,11 +637,11 @@ impl RegExp { None => { // a. If SameValue(R, %RegExp.prototype%) is true, return "(?:)". // b. Otherwise, throw a TypeError exception. - if Value::same_value( + if JsValue::same_value( this, - &Value::from(context.standard_objects().regexp_object().prototype()), + &JsValue::new(context.standard_objects().regexp_object().prototype()), ) { - Ok(Value::from("(?:)")) + Ok(JsValue::new("(?:)")) } else { context.throw_type_error( "RegExp.prototype.source method called on incompatible value", @@ -639,9 +667,9 @@ impl RegExp { /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-escaperegexppattern - fn escape_pattern(src: &str, _flags: &str) -> Result { + fn escape_pattern(src: &str, _flags: &str) -> Result { if src.is_empty() { - Ok(Value::from("(?:)")) + Ok(JsValue::new("(?:)")) } else { let mut s = String::from(""); @@ -654,7 +682,7 @@ impl RegExp { } } - Ok(Value::from(s)) + Ok(JsValue::new(s)) } } @@ -670,7 +698,7 @@ impl RegExp { /// /// [spec]: https://tc39.es/ecma262/#sec-regexp.prototype.test /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test - pub(crate) fn test(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn test(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { // 1. Let R be the this value. // 2. If Type(R) is not Object, throw a TypeError exception. if !this.is_object() { @@ -690,9 +718,9 @@ impl RegExp { // 5. If match is not null, return true; else return false. if m.is_some() { - Ok(Value::Boolean(true)) + Ok(JsValue::new(true)) } else { - Ok(Value::Boolean(false)) + Ok(JsValue::new(false)) } } @@ -708,7 +736,7 @@ impl RegExp { /// /// [spec]: https://tc39.es/ecma262/#sec-regexp.prototype.exec /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec - pub(crate) fn exec(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn exec(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { // 1. Let R be the this value. // 2. Perform ? RequireInternalSlot(R, [[RegExpMatcher]]). let obj = this.as_object().unwrap_or_default(); @@ -729,7 +757,7 @@ impl RegExp { if let Some(v) = Self::abstract_builtin_exec(obj, arg_str, context)? { Ok(v.into()) } else { - Ok(Value::null()) + Ok(JsValue::null()) } } @@ -740,7 +768,7 @@ impl RegExp { /// /// [spec]: https://tc39.es/ecma262/#sec-regexpexec pub(crate) fn abstract_exec( - this: &Value, + this: &JsValue, input: JsString, context: &mut Context, ) -> Result> { @@ -949,7 +977,7 @@ impl RegExp { let named_groups = match_value.named_groups(); let groups = if named_groups.clone().count() > 0 { // a. Let groups be ! OrdinaryObjectCreate(null). - let groups = Value::new_object(context); + let groups = JsValue::new_object(context); // Perform 27.f here // f. If the ith capture of R was defined with a GroupName, then @@ -972,7 +1000,7 @@ impl RegExp { groups } else { // a. Let groups be undefined. - Value::undefined() + JsValue::undefined() }; // 26. Perform ! CreateDataPropertyOrThrow(A, "groups", groups). @@ -986,7 +1014,7 @@ impl RegExp { let captured_value = match capture { // b. If captureI is undefined, let capturedValue be undefined. - None => Value::undefined(), + None => JsValue::undefined(), // c. Else if fullUnicode is true, then // d. Else, Some(range) => { @@ -1017,7 +1045,11 @@ 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, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn r#match( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let rx be the this value. // 2. If Type(rx) is not Object, throw a TypeError exception. let rx = if let Some(rx) = this.as_object() { @@ -1042,10 +1074,10 @@ impl RegExp { // 6. Else, if !global { // a. Return ? RegExpExec(rx, S). - if let Some(v) = Self::abstract_exec(&Value::from(rx), arg_str, context)? { + if let Some(v) = Self::abstract_exec(&JsValue::new(rx), arg_str, context)? { Ok(v.into()) } else { - Ok(Value::null()) + Ok(JsValue::null()) } } else { // a. Assert: global is true. @@ -1066,7 +1098,7 @@ impl RegExp { loop { // i. Let result be ? RegExpExec(rx, S). let result = - Self::abstract_exec(&Value::from(rx.clone()), arg_str.clone(), context)?; + Self::abstract_exec(&JsValue::new(rx.clone()), arg_str.clone(), context)?; // ii. If result is null, then // iii. Else, @@ -1087,7 +1119,7 @@ impl RegExp { let next_index = advance_string_index(arg_str.clone(), this_index, unicode); // c. Perform ? Set(rx, "lastIndex", ๐”ฝ(nextIndex), true). - rx.set("lastIndex", Value::from(next_index), true, context)?; + rx.set("lastIndex", JsValue::new(next_index), true, context)?; } // 4. Set n to n + 1. @@ -1096,7 +1128,7 @@ impl RegExp { // 1. If n = 0, return null. // 2. Return A. if n == 0 { - return Ok(Value::null()); + return Ok(JsValue::null()); } else { return Ok(a.into()); } @@ -1116,7 +1148,11 @@ impl RegExp { /// [spec]: https://tc39.es/ecma262/#sec-regexp.prototype.tostring /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/toString #[allow(clippy::wrong_self_convention)] - pub(crate) fn to_string(this: &Value, _: &[Value], context: &mut Context) -> Result { + pub(crate) fn to_string( + this: &JsValue, + _: &[JsValue], + context: &mut Context, + ) -> Result { let (body, flags) = if let Some(object) = this.as_object() { let object = object.borrow(); let regex = object.as_regexp().ok_or_else(|| { @@ -1145,7 +1181,11 @@ impl RegExp { /// /// [spec]: https://tc39.es/ecma262/#sec-regexp-prototype-matchall /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@matchAll - pub(crate) fn match_all(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn match_all( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let R be the this value. // 2. If Type(R) is not Object, throw a TypeError exception. if !this.is_object() { @@ -1205,7 +1245,11 @@ impl RegExp { /// /// [spec]: https://tc39.es/ecma262/#sec-regexp.prototype-@@replace /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@replace - pub(crate) fn replace(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn replace( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let rx be the this value. // 2. If Type(rx) is not Object, throw a TypeError exception. let rx = if let Some(rx) = this.as_object() { @@ -1256,7 +1300,7 @@ impl RegExp { // 11. Repeat, while done is false, loop { // a. Let result be ? RegExpExec(rx, S). - let result = Self::abstract_exec(&Value::from(rx.clone()), arg_str.clone(), context)?; + let result = Self::abstract_exec(&JsValue::new(rx.clone()), arg_str.clone(), context)?; // b. If result is null, set done to true. // c. Else, @@ -1281,7 +1325,7 @@ impl RegExp { let next_index = advance_string_index(arg_str.clone(), this_index, unicode); // c. Perform ? Set(rx, "lastIndex", ๐”ฝ(nextIndex), true). - rx.set("lastIndex", Value::from(next_index), true, context)?; + rx.set("lastIndex", JsValue::new(next_index), true, context)?; } } } else { @@ -1359,7 +1403,7 @@ impl RegExp { let replacement: JsString; if functional_replace { // i. Let replacerArgs be ยซ matched ยป. - let mut replacer_args = vec![Value::from(matched)]; + let mut replacer_args = vec![JsValue::new(matched)]; // ii. Append in List order the elements of captures to the end of the List replacerArgs. replacer_args.extend(captures); @@ -1375,7 +1419,8 @@ impl RegExp { } // v. Let replValue be ? Call(replaceValue, undefined, replacerArgs). - let repl_value = context.call(&replace_value, &Value::Undefined, &replacer_args)?; + let repl_value = + context.call(&replace_value, &JsValue::undefined(), &replacer_args)?; // vi. Let replacement be ? ToString(replValue). replacement = repl_value.to_string(context)?; @@ -1443,7 +1488,11 @@ impl RegExp { /// /// [spec]: https://tc39.es/ecma262/#sec-regexp.prototype-@@search /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@search - pub(crate) fn search(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn search( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let rx be the this value. // 2. If Type(rx) is not Object, throw a TypeError exception. let rx = if let Some(rx) = this.as_object() { @@ -1465,19 +1514,19 @@ impl RegExp { let previous_last_index = rx.get("lastIndex", context)?; // 5. If SameValue(previousLastIndex, +0๐”ฝ) is false, then - if !Value::same_value(&previous_last_index, &Value::from(0)) { + if !JsValue::same_value(&previous_last_index, &JsValue::new(0)) { // a. Perform ? Set(rx, "lastIndex", +0๐”ฝ, true). rx.set("lastIndex", 0, true, context)?; } // 6. Let result be ? RegExpExec(rx, S). - let result = Self::abstract_exec(&Value::from(rx.clone()), arg_str, context)?; + let result = Self::abstract_exec(&JsValue::new(rx.clone()), arg_str, context)?; // 7. Let currentLastIndex be ? Get(rx, "lastIndex"). let current_last_index = rx.get("lastIndex", context)?; // 8. If SameValue(currentLastIndex, previousLastIndex) is false, then - if !Value::same_value(¤t_last_index, &previous_last_index) { + if !JsValue::same_value(¤t_last_index, &previous_last_index) { // a. Perform ? Set(rx, "lastIndex", previousLastIndex, true). rx.set("lastIndex", previous_last_index, true, context)?; } @@ -1487,7 +1536,7 @@ impl RegExp { if let Some(result) = result { result.get("index", context) } else { - Ok(Value::from(-1)) + Ok(JsValue::new(-1)) } } @@ -1501,7 +1550,11 @@ impl RegExp { /// /// [spec]: https://tc39.es/ecma262/#sec-regexp.prototype-@@split /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@split - pub(crate) fn split(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn split( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let rx be the this value. // 2. If Type(rx) is not Object, throw a TypeError exception. let rx = if let Some(rx) = this.as_object() { @@ -1590,7 +1643,7 @@ impl RegExp { // 19. Repeat, while q < size, while q < size { // a. Perform ? Set(splitter, "lastIndex", ๐”ฝ(q), true). - splitter.set_field("lastIndex", Value::from(q), true, context)?; + splitter.set_field("lastIndex", JsValue::new(q), true, context)?; // b. Let z be ? RegExpExec(splitter, S). let result = Self::abstract_exec(&splitter, arg_str.clone(), context)?; diff --git a/boa/src/builtins/regexp/regexp_string_iterator.rs b/boa/src/builtins/regexp/regexp_string_iterator.rs index f076c39510..a349a22929 100644 --- a/boa/src/builtins/regexp/regexp_string_iterator.rs +++ b/boa/src/builtins/regexp/regexp_string_iterator.rs @@ -17,13 +17,13 @@ use crate::{ object::{GcObject, ObjectData}, property::PropertyDescriptor, symbol::WellKnownSymbols, - BoaProfiler, Context, JsString, Result, Value, + BoaProfiler, Context, JsString, JsValue, Result, }; // TODO: See todos in create_regexp_string_iterator and next. #[derive(Debug, Clone, Finalize, Trace)] pub struct RegExpStringIterator { - matcher: Value, + matcher: JsValue, string: JsString, global: bool, unicode: bool, @@ -32,7 +32,7 @@ pub struct RegExpStringIterator { // TODO: See todos in create_regexp_string_iterator and next. impl RegExpStringIterator { - fn new(matcher: Value, string: JsString, global: bool, unicode: bool) -> Self { + fn new(matcher: JsValue, string: JsString, global: bool, unicode: bool) -> Self { Self { matcher, string, @@ -49,12 +49,12 @@ impl RegExpStringIterator { /// /// [spec]: https://tc39.es/ecma262/#sec-createregexpstringiterator pub(crate) fn create_regexp_string_iterator( - matcher: &Value, + matcher: &JsValue, string: JsString, global: bool, unicode: bool, context: &mut Context, - ) -> Result { + ) -> Result { // TODO: Implement this with closures and generators. // For now all values of the closure are stored in RegExpStringIterator and the actual closure execution is in `.next()`. @@ -66,7 +66,7 @@ impl RegExpStringIterator { // and fullUnicode and performs the following steps when called: // 5. Return ! CreateIteratorFromClosure(closure, "%RegExpStringIteratorPrototype%", %RegExpStringIteratorPrototype%). - let regexp_string_iterator = Value::new_object(context); + let regexp_string_iterator = JsValue::new_object(context); regexp_string_iterator.set_data(ObjectData::RegExpStringIterator(Self::new( matcher.clone(), string, @@ -86,12 +86,16 @@ impl RegExpStringIterator { Ok(regexp_string_iterator) } - pub fn next(this: &Value, _: &[Value], context: &mut Context) -> Result { - if let Value::Object(ref object) = this { + pub fn next(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { + if let JsValue::Object(ref object) = this { let mut object = object.borrow_mut(); if let Some(iterator) = object.as_regexp_string_iterator_mut() { if iterator.completed { - return Ok(create_iter_result_object(context, Value::undefined(), true)); + return Ok(create_iter_result_object( + context, + JsValue::undefined(), + true, + )); } // TODO: This is the code that should be created as a closure in create_regexp_string_iterator. @@ -137,7 +141,11 @@ impl RegExpStringIterator { } else { // ii. If match is null, return undefined. iterator.completed = true; - Ok(create_iter_result_object(context, Value::undefined(), true)) + Ok(create_iter_result_object( + context, + JsValue::undefined(), + true, + )) } } else { context.throw_type_error("`this` is not a RegExpStringIterator") @@ -153,7 +161,7 @@ impl RegExpStringIterator { /// - [ECMA reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-%arrayiteratorprototype%-object - pub(crate) fn create_prototype(context: &mut Context, iterator_prototype: Value) -> GcObject { + pub(crate) fn create_prototype(context: &mut Context, iterator_prototype: JsValue) -> GcObject { let _timer = BoaProfiler::global().start_event("RegExp String Iterator", "init"); // Create prototype diff --git a/boa/src/builtins/set/mod.rs b/boa/src/builtins/set/mod.rs index 4c6c296614..01bd4d4cae 100644 --- a/boa/src/builtins/set/mod.rs +++ b/boa/src/builtins/set/mod.rs @@ -15,7 +15,7 @@ use crate::{ object::{ConstructorBuilder, FunctionBuilder, ObjectData, PROTOTYPE}, property::Attribute, symbol::WellKnownSymbols, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; use ordered_set::OrderedSet; @@ -27,7 +27,7 @@ pub mod ordered_set; mod tests; #[derive(Debug, Clone)] -pub(crate) struct Set(OrderedSet); +pub(crate) struct Set(OrderedSet); impl BuiltIn for Set { const NAME: &'static str = "Set"; @@ -36,7 +36,7 @@ impl BuiltIn for Set { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let get_species = FunctionBuilder::native(context, Self::get_species) @@ -110,10 +110,10 @@ impl Set { /// Create a new set pub(crate) fn constructor( - new_target: &Value, - args: &[Value], + new_target: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { // 1 if new_target.is_undefined() { return context @@ -135,7 +135,7 @@ impl Set { let obj = context.construct_object(); obj.set_prototype_instance(prototype.into()); - let set = Value::from(obj); + let set = JsValue::new(obj); // 3 set.set_data(ObjectData::Set(OrderedSet::default())); @@ -186,7 +186,7 @@ impl Set { /// /// [spec]: https://tc39.es/ecma262/#sec-get-set-@@species /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/@@species - fn get_species(this: &Value, _: &[Value], _: &mut Context) -> Result { + fn get_species(this: &JsValue, _: &[JsValue], _: &mut Context) -> Result { // 1. Return the this value. Ok(this.clone()) } @@ -201,13 +201,13 @@ impl Set { /// /// [spec]: https://tc39.es/ecma262/#sec-set.prototype.add /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/add - pub(crate) fn add(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn add(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { let mut value = args.get(0).cloned().unwrap_or_default(); if let Some(object) = this.as_object() { if let Some(set) = object.borrow_mut().as_set_mut() { if value.as_number().map(|n| n == -0f64).unwrap_or(false) { - value = Value::Integer(0); + value = JsValue::Integer(0); } set.add(value); } else { @@ -230,11 +230,11 @@ impl Set { /// /// [spec]: https://tc39.es/ecma262/#sec-set.prototype.clear /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/clear - pub(crate) fn clear(this: &Value, _: &[Value], context: &mut Context) -> Result { + pub(crate) fn clear(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { if let Some(object) = this.as_object() { if object.borrow().is_set() { this.set_data(ObjectData::Set(OrderedSet::new())); - Ok(Value::Undefined) + Ok(JsValue::undefined()) } else { context.throw_type_error("'this' is not a Set") } @@ -254,7 +254,11 @@ impl Set { /// /// [spec]: https://tc39.es/ecma262/#sec-set.prototype.delete /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/delete - pub(crate) fn delete(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn delete( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { let value = args.get(0).cloned().unwrap_or_default(); let res = if let Some(object) = this.as_object() { @@ -280,7 +284,7 @@ impl Set { /// /// [spec]: https://tc39.es/ecma262/#sec-set.prototype.entries /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries - pub(crate) fn entries(this: &Value, _: &[Value], context: &mut Context) -> Result { + pub(crate) fn entries(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { if let Some(object) = this.as_object() { let object = object.borrow(); if !object.is_set() { @@ -310,16 +314,20 @@ impl Set { /// /// [spec]: https://tc39.es/ecma262/#sec-set.prototype.foreach /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/foreach - pub(crate) fn for_each(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn for_each( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { if args.is_empty() { - return Err(Value::from("Missing argument for Set.prototype.forEach")); + return Err(JsValue::new("Missing argument for Set.prototype.forEach")); } let callback_arg = &args[0]; - let this_arg = args.get(1).cloned().unwrap_or_else(Value::undefined); + let this_arg = args.get(1).cloned().unwrap_or_else(JsValue::undefined); // TODO: if condition should also check that we are not in strict mode let this_arg = if this_arg.is_undefined() { - Value::Object(context.global_object()) + JsValue::Object(context.global_object()) } else { this_arg }; @@ -327,7 +335,7 @@ impl Set { let mut index = 0; while index < Set::get_size(this, context)? { - let arguments = if let Value::Object(ref object) = this { + let arguments = if let JsValue::Object(ref object) = this { let object = object.borrow(); if let Some(set) = object.as_set_ref() { set.get_index(index) @@ -346,7 +354,7 @@ impl Set { index += 1; } - Ok(Value::Undefined) + Ok(JsValue::Undefined) } /// `Map.prototype.has( key )` @@ -359,17 +367,13 @@ impl Set { /// /// [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], context: &mut Context) -> Result { - let undefined = Value::Undefined; - let value = match args.len() { - 0 => &undefined, - _ => &args[0], - }; + pub(crate) fn has(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { + let value = args.get(0).cloned().unwrap_or_default(); - if let Value::Object(ref object) = this { + if let JsValue::Object(ref object) = this { let object = object.borrow(); if let Some(set) = object.as_set_ref() { - return Ok(set.contains(value).into()); + return Ok(set.contains(&value).into()); } } @@ -386,7 +390,7 @@ impl Set { /// /// [spec]: https://tc39.es/ecma262/#sec-set.prototype.values /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values - pub(crate) fn values(this: &Value, _: &[Value], context: &mut Context) -> Result { + pub(crate) fn values(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { if let Some(object) = this.as_object() { let object = object.borrow(); if !object.is_set() { @@ -406,13 +410,13 @@ impl Set { )) } - fn size_getter(this: &Value, _: &[Value], context: &mut Context) -> Result { - Set::get_size(this, context).map(Value::from) + fn size_getter(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { + Set::get_size(this, context).map(JsValue::from) } /// Helper function to get the size of the set. - fn get_size(set: &Value, context: &mut Context) -> Result { - if let Value::Object(ref object) = set { + fn get_size(set: &JsValue, context: &mut Context) -> Result { + if let JsValue::Object(ref object) = set { let object = object.borrow(); if let Some(set) = object.as_set_ref() { Ok(set.size()) diff --git a/boa/src/builtins/set/set_iterator.rs b/boa/src/builtins/set/set_iterator.rs index 185aa73275..f0e6a019fc 100644 --- a/boa/src/builtins/set/set_iterator.rs +++ b/boa/src/builtins/set/set_iterator.rs @@ -2,7 +2,7 @@ use crate::{ builtins::function::make_builtin_fn, builtins::iterable::create_iter_result_object, builtins::Array, - builtins::Value, + builtins::JsValue, object::{GcObject, ObjectData}, property::PropertyDescriptor, symbol::WellKnownSymbols, @@ -24,7 +24,7 @@ pub enum SetIterationKind { /// [spec]: https://tc39.es/ecma262/#sec-set-iterator-objects #[derive(Debug, Clone, Finalize, Trace)] pub struct SetIterator { - iterated_set: Value, + iterated_set: JsValue, next_index: usize, iteration_kind: SetIterationKind, } @@ -33,7 +33,7 @@ impl SetIterator { pub(crate) const NAME: &'static str = "SetIterator"; /// Constructs a new `SetIterator`, that will iterate over `set`, starting at index 0 - fn new(set: Value, kind: SetIterationKind) -> Self { + fn new(set: JsValue, kind: SetIterationKind) -> Self { SetIterator { iterated_set: set, next_index: 0, @@ -51,10 +51,10 @@ impl SetIterator { /// [spec]: https://www.ecma-international.org/ecma-262/11.0/index.html#sec-createsetiterator pub(crate) fn create_set_iterator( context: &Context, - set: Value, + set: JsValue, kind: SetIterationKind, - ) -> Value { - let set_iterator = Value::new_object(context); + ) -> JsValue { + let set_iterator = JsValue::new_object(context); set_iterator.set_data(ObjectData::SetIterator(Self::new(set, kind))); set_iterator .as_object() @@ -71,8 +71,8 @@ impl SetIterator { /// - [ECMA reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-%setiteratorprototype%.next - pub(crate) fn next(this: &Value, _: &[Value], context: &mut Context) -> Result { - if let Value::Object(ref object) = this { + pub(crate) fn next(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { + if let JsValue::Object(ref object) = this { let mut object = object.borrow_mut(); if let Some(set_iterator) = object.as_set_iterator_mut() { let m = &set_iterator.iterated_set; @@ -80,10 +80,14 @@ impl SetIterator { let item_kind = &set_iterator.iteration_kind; if set_iterator.iterated_set.is_undefined() { - return Ok(create_iter_result_object(context, Value::undefined(), true)); + return Ok(create_iter_result_object( + context, + JsValue::undefined(), + true, + )); } - if let Value::Object(ref object) = m { + if let JsValue::Object(ref object) = m { if let Some(entries) = object.borrow().as_set_ref() { let num_entries = entries.size(); while index < num_entries { @@ -119,8 +123,12 @@ impl SetIterator { return Err(context.construct_type_error("'this' is not a Set")); } - set_iterator.iterated_set = Value::undefined(); - Ok(create_iter_result_object(context, Value::undefined(), true)) + set_iterator.iterated_set = JsValue::undefined(); + Ok(create_iter_result_object( + context, + JsValue::undefined(), + true, + )) } else { context.throw_type_error("`this` is not an SetIterator") } @@ -135,7 +143,7 @@ impl SetIterator { /// - [ECMA reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-%setiteratorprototype%-object - pub(crate) fn create_prototype(context: &mut Context, iterator_prototype: Value) -> GcObject { + pub(crate) fn create_prototype(context: &mut Context, iterator_prototype: JsValue) -> GcObject { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); // Create prototype diff --git a/boa/src/builtins/string/mod.rs b/boa/src/builtins/string/mod.rs index 873df40f71..04c3e22927 100644 --- a/boa/src/builtins/string/mod.rs +++ b/boa/src/builtins/string/mod.rs @@ -20,7 +20,7 @@ use crate::{ object::{ConstructorBuilder, ObjectData}, property::{Attribute, PropertyDescriptor}, symbol::WellKnownSymbols, - BoaProfiler, Context, JsString, Result, Value, + BoaProfiler, Context, JsString, JsValue, Result, }; use std::{ char::{decode_utf16, from_u32}, @@ -90,7 +90,7 @@ impl BuiltIn for String { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let symbol_iterator = WellKnownSymbols::iterator(); @@ -155,10 +155,10 @@ impl String { /// /// pub(crate) fn constructor( - new_target: &Value, - args: &[Value], + new_target: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { // This value is used by console.log and other routines to match Object type // to its Javascript Identifier (global constructor method name) let string = match args.get(0) { @@ -184,7 +184,7 @@ impl String { }) .transpose()? .unwrap_or_else(|| context.standard_objects().object_object().prototype()); - let this = Value::new_object(context); + let this = JsValue::new_object(context); this.as_object() .expect("this should be an object") @@ -204,10 +204,10 @@ impl String { Ok(this) } - fn this_string_value(this: &Value, context: &mut Context) -> Result { + fn this_string_value(this: &JsValue, context: &mut Context) -> Result { match this { - Value::String(ref string) => return Ok(string.clone()), - Value::Object(ref object) => { + JsValue::String(ref string) => return Ok(string.clone()), + JsValue::Object(ref object) => { let object = object.borrow(); if let Some(string) = object.as_string() { return Ok(string); @@ -222,9 +222,13 @@ impl String { /// Get the string value to a primitive string #[allow(clippy::wrong_self_convention)] #[inline] - pub(crate) fn to_string(this: &Value, _: &[Value], context: &mut Context) -> Result { + pub(crate) fn to_string( + this: &JsValue, + _: &[JsValue], + 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, context)?)) + Ok(JsValue::new(Self::this_string_value(this, context)?)) } /// `String.prototype.charAt( index )` @@ -243,14 +247,18 @@ 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], context: &mut Context) -> Result { + pub(crate) fn char_at( + this: &JsValue, + args: &[JsValue], + 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(context)?; let pos = args .get(0) .cloned() - .unwrap_or_else(Value::undefined) + .unwrap_or_else(JsValue::undefined) .to_integer(context)? as i32; // Fast path returning empty string when pos is obviously out of range @@ -263,7 +271,7 @@ impl String { // Note that this is an O(N) operation (because UTF-8 is complex) while getting the number of // bytes is an O(1) operation. if let Some(utf16_val) = primitive_val.encode_utf16().nth(pos as usize) { - Ok(Value::from(from_u32(utf16_val as u32).unwrap())) + Ok(JsValue::new(from_u32(utf16_val as u32).unwrap())) } else { Ok("".into()) } @@ -280,7 +288,7 @@ impl String { /// /// [spec]: https://tc39.es/proposal-relative-indexing-method/#sec-string.prototype.at /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/at - pub(crate) fn at(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn at(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { let this = this.require_object_coercible(context)?; let s = this.to_string(context)?; let len = s.encode_utf16().count(); @@ -296,11 +304,11 @@ impl String { }; if let Some(utf16_val) = s.encode_utf16().nth(k) { - Ok(Value::from( + Ok(JsValue::new( from_u32(u32::from(utf16_val)).expect("invalid utf-16 character"), )) } else { - Ok(Value::undefined()) + Ok(JsValue::undefined()) } } @@ -319,28 +327,28 @@ impl String { /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.codepointat /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt pub(crate) fn code_point_at( - this: &Value, - args: &[Value], + this: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> 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(context)?; let pos = args .get(0) .cloned() - .unwrap_or_else(Value::undefined) + .unwrap_or_else(JsValue::undefined) .to_integer(context)? as i32; // Fast path returning undefined when pos is obviously out of range if pos < 0 || pos >= primitive_val.len() as i32 { - return Ok(Value::undefined()); + return Ok(JsValue::undefined()); } if let Some((code_point, _, _)) = code_point_at(primitive_val, pos) { - Ok(Value::from(code_point)) + Ok(JsValue::new(code_point)) } else { - Ok(Value::undefined()) + Ok(JsValue::undefined()) } } @@ -359,31 +367,31 @@ 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], + this: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> 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(context)?; let pos = args .get(0) .cloned() - .unwrap_or_else(Value::undefined) + .unwrap_or_else(JsValue::undefined) .to_integer(context)? as i32; // Fast path returning NaN when pos is obviously out of range if pos < 0 || pos >= primitive_val.len() as i32 { - return Ok(Value::nan()); + return Ok(JsValue::nan()); } // 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. // If there is no element at that index, the result is NaN if let Some(utf16_val) = primitive_val.encode_utf16().nth(pos as usize) { - Ok(Value::from(f64::from(utf16_val))) + Ok(JsValue::new(f64::from(utf16_val))) } else { - Ok(Value::nan()) + Ok(JsValue::nan()) } } @@ -401,7 +409,11 @@ 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], context: &mut Context) -> Result { + pub(crate) fn concat( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { let object = this.require_object_coercible(context)?; let mut string = object.to_string(context)?.to_string(); @@ -409,7 +421,7 @@ impl String { string.push_str(&arg.to_string(context)?); } - Ok(Value::from(string)) + Ok(JsValue::new(string)) } /// `String.prototype.repeat( count )` @@ -423,7 +435,11 @@ 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], context: &mut Context) -> Result { + pub(crate) fn repeat( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { let object = this.require_object_coercible(context)?; let string = object.to_string(context)?; @@ -457,7 +473,11 @@ 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], context: &mut Context) -> Result { + pub(crate) fn slice( + this: &JsValue, + args: &[JsValue], + 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(context)?; @@ -469,12 +489,12 @@ impl String { let start = args .get(0) .cloned() - .unwrap_or_else(Value::undefined) + .unwrap_or_else(JsValue::undefined) .to_integer(context)? as i32; let end = args .get(1) .cloned() - .unwrap_or_else(|| Value::integer(length)) + .unwrap_or_else(|| JsValue::new(length)) .to_integer(context)? as i32; let from = if start < 0 { @@ -495,7 +515,7 @@ impl String { .skip(from as usize) .take(span as usize) .collect(); - Ok(Value::from(new_str)) + Ok(JsValue::new(new_str)) } /// `String.prototype.startWith( searchString[, position] )` @@ -509,15 +529,15 @@ 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], + this: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> 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(context)?; - let arg = args.get(0).cloned().unwrap_or_else(Value::undefined); + let arg = args.get(0).cloned().unwrap_or_else(JsValue::undefined); if Self::is_regexp_object(&arg) { context.throw_type_error( @@ -543,11 +563,13 @@ impl String { let end = start.wrapping_add(search_length); if end > length { - Ok(Value::from(false)) + Ok(JsValue::new(false)) } else { // Only use the part of the string from "start" let this_string: StdString = primitive_val.chars().skip(start as usize).collect(); - Ok(Value::from(this_string.starts_with(search_string.as_str()))) + Ok(JsValue::new( + this_string.starts_with(search_string.as_str()), + )) } } @@ -561,12 +583,16 @@ 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], context: &mut Context) -> Result { + pub(crate) fn ends_with( + this: &JsValue, + args: &[JsValue], + 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(context)?; - let arg = args.get(0).cloned().unwrap_or_else(Value::undefined); + let arg = args.get(0).cloned().unwrap_or_else(JsValue::undefined); if Self::is_regexp_object(&arg) { context.throw_type_error( @@ -593,11 +619,11 @@ impl String { let start = end.wrapping_sub(search_length); if start < 0 { - Ok(Value::from(false)) + Ok(JsValue::new(false)) } else { // Only use the part of the string up to "end" let this_string: StdString = primitive_val.chars().take(end as usize).collect(); - Ok(Value::from(this_string.ends_with(search_string.as_str()))) + Ok(JsValue::new(this_string.ends_with(search_string.as_str()))) } } @@ -611,12 +637,16 @@ 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], context: &mut Context) -> Result { + pub(crate) fn includes( + this: &JsValue, + args: &[JsValue], + 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(context)?; - let arg = args.get(0).cloned().unwrap_or_else(Value::undefined); + let arg = args.get(0).cloned().unwrap_or_else(JsValue::undefined); if Self::is_regexp_object(&arg) { context.throw_type_error( @@ -642,12 +672,12 @@ impl String { // Take the string from "this" and use only the part of it after "start" let this_string: StdString = primitive_val.chars().skip(start as usize).collect(); - Ok(Value::from(this_string.contains(search_string.as_str()))) + Ok(JsValue::new(this_string.contains(search_string.as_str()))) } - fn is_regexp_object(value: &Value) -> bool { + fn is_regexp_object(value: &JsValue) -> bool { match value { - Value::Object(ref obj) => obj.borrow().is_regexp(), + JsValue::Object(ref obj) => obj.borrow().is_regexp(), _ => false, } } @@ -667,7 +697,11 @@ 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], context: &mut Context) -> Result { + pub(crate) fn replace( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let O be ? RequireObjectCoercible(this value). this.require_object_coercible(context)?; @@ -727,7 +761,7 @@ impl String { context .call( &replace_value, - &Value::Undefined, + &JsValue::undefined(), &[ search_str.into(), position.unwrap().into(), @@ -746,7 +780,7 @@ impl String { this_str.to_string(), position.unwrap(), captures, - Value::undefined(), + JsValue::undefined(), replace_value.to_string(context)?, context, )? @@ -777,14 +811,18 @@ 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], context: &mut Context) -> Result { + pub(crate) fn index_of( + this: &JsValue, + args: &[JsValue], + 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) + .unwrap_or_else(JsValue::undefined) .to_string(context)?; let length = string.chars().count(); @@ -804,7 +842,7 @@ impl String { } } - Ok(Value::from(-1)) + Ok(JsValue::new(-1)) } /// `String.prototype.lastIndexOf( searchValue[, fromIndex] )` @@ -821,17 +859,17 @@ 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], + this: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> 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) + .unwrap_or_else(JsValue::undefined) .to_string(context)?; let length = string.chars().count(); @@ -851,7 +889,7 @@ impl String { } } - Ok(Value::from(-1)) + Ok(JsValue::new(-1)) } /// `String.prototype.match( regexp )` @@ -865,7 +903,11 @@ 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], context: &mut Context) -> Result { + pub(crate) fn r#match( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let O be ? RequireObjectCoercible(this value). let o = this.require_object_coercible(context)?; @@ -886,12 +928,12 @@ impl String { let s = o.to_string(context)?; // 4. Let rx be ? RegExpCreate(regexp, undefined). - let rx = RegExp::create(regexp, Value::undefined(), context)?; + let rx = RegExp::create(regexp, JsValue::undefined(), context)?; // 5. Return ? Invoke(rx, @@match, ยซ S ยป). let obj = rx.as_object().expect("RegExpCreate must return Object"); if let Some(matcher) = obj.get_method(context, WellKnownSymbols::match_())? { - matcher.call(&rx, &[Value::from(s)], context) + matcher.call(&rx, &[JsValue::new(s)], context) } else { context.throw_type_error("RegExp[Symbol.match] is undefined") } @@ -906,17 +948,17 @@ impl String { max_length: i32, fill_string: Option, at_start: bool, - ) -> Value { + ) -> JsValue { let primitive_length = primitive.len() as i32; if max_length <= primitive_length { - return Value::from(primitive); + return JsValue::new(primitive); } let filler = fill_string.as_deref().unwrap_or(" "); if filler.is_empty() { - return Value::from(primitive); + return JsValue::new(primitive); } let fill_len = max_length.wrapping_sub(primitive_length); @@ -929,9 +971,9 @@ impl String { let concat_fill_str: StdString = fill_str.chars().take(fill_len as usize).collect(); if at_start { - Value::from(format!("{}{}", concat_fill_str, &primitive)) + JsValue::new(format!("{}{}", concat_fill_str, &primitive)) } else { - Value::from(format!("{}{}", primitive, &concat_fill_str)) + JsValue::new(format!("{}{}", primitive, &concat_fill_str)) } } @@ -947,10 +989,14 @@ 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], context: &mut Context) -> Result { + pub(crate) fn pad_end( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { let primitive = this.to_string(context)?; if args.is_empty() { - return Err(Value::from("padEnd requires maxLength argument")); + return Err(JsValue::new("padEnd requires maxLength argument")); } let max_length = args .get(0) @@ -974,10 +1020,14 @@ 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], context: &mut Context) -> Result { + pub(crate) fn pad_start( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { let primitive = this.to_string(context)?; if args.is_empty() { - return Err(Value::from("padStart requires maxLength argument")); + return Err(JsValue::new("padStart requires maxLength argument")); } let max_length = args .get(0) @@ -1001,10 +1051,10 @@ 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], context: &mut Context) -> Result { + pub(crate) fn trim(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { let this = this.require_object_coercible(context)?; let string = this.to_string(context)?; - Ok(Value::from(string.trim_matches(is_trimmable_whitespace))) + Ok(JsValue::new(string.trim_matches(is_trimmable_whitespace))) } /// `String.prototype.trimStart()` @@ -1019,9 +1069,13 @@ 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], context: &mut Context) -> Result { + pub(crate) fn trim_start( + this: &JsValue, + _: &[JsValue], + context: &mut Context, + ) -> Result { let string = this.to_string(context)?; - Ok(Value::from( + Ok(JsValue::new( string.trim_start_matches(is_trimmable_whitespace), )) } @@ -1038,10 +1092,14 @@ 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], context: &mut Context) -> Result { + pub(crate) fn trim_end( + this: &JsValue, + _: &[JsValue], + context: &mut Context, + ) -> Result { let this = this.require_object_coercible(context)?; let string = this.to_string(context)?; - Ok(Value::from( + Ok(JsValue::new( string.trim_end_matches(is_trimmable_whitespace), )) } @@ -1057,13 +1115,17 @@ 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], context: &mut Context) -> Result { + pub(crate) fn to_lowercase( + this: &JsValue, + _: &[JsValue], + 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(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())) + Ok(JsValue::new(this_str.to_lowercase())) } /// `String.prototype.toUpperCase()` @@ -1079,13 +1141,17 @@ 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], context: &mut Context) -> Result { + pub(crate) fn to_uppercase( + this: &JsValue, + _: &[JsValue], + 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(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())) + Ok(JsValue::new(this_str.to_uppercase())) } /// `String.prototype.substring( indexStart[, indexEnd] )` @@ -1098,7 +1164,11 @@ 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], context: &mut Context) -> Result { + pub(crate) fn substring( + this: &JsValue, + args: &[JsValue], + 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(context)?; @@ -1135,7 +1205,7 @@ impl String { .take(to.wrapping_sub(from)), ) .collect(); - Ok(Value::from(extracted_string.expect("Invalid string"))) + Ok(JsValue::new(extracted_string.expect("Invalid string"))) } /// `String.prototype.substr( start[, length] )` @@ -1149,7 +1219,11 @@ 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], context: &mut Context) -> Result { + pub(crate) fn substr( + this: &JsValue, + args: &[JsValue], + 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(context)?; @@ -1183,7 +1257,7 @@ impl String { // If length is negative we return an empty string // otherwise we extract the part of the string from start and is length code units long if result_length <= 0 { - Ok(Value::from("")) + Ok(JsValue::new("")) } else { let extracted_string: StdString = primitive_val .chars() @@ -1191,7 +1265,7 @@ impl String { .take(result_length as usize) .collect(); - Ok(Value::from(extracted_string)) + Ok(JsValue::new(extracted_string)) } } @@ -1206,7 +1280,11 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.split /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split - pub(crate) fn split(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn split( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let O be ? RequireObjectCoercible(this value). let this = this.require_object_coercible(context)?; @@ -1356,7 +1434,11 @@ 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], context: &mut Context) -> Result { + pub(crate) fn value_of( + this: &JsValue, + args: &[JsValue], + 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, context) } @@ -1373,7 +1455,11 @@ impl String { /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/matchAll /// [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 - pub(crate) fn match_all(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn match_all( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let O be ? RequireObjectCoercible(this value). let o = this.require_object_coercible(context)?; @@ -1411,12 +1497,12 @@ impl String { let s = o.to_string(context)?; // 4. Let rx be ? RegExpCreate(regexp, "g"). - let rx = RegExp::create(regexp, Value::from("g"), context)?; + let rx = RegExp::create(regexp, JsValue::new("g"), context)?; // 5. Return ? Invoke(rx, @@matchAll, ยซ S ยป). let obj = rx.as_object().expect("RegExpCreate must return Object"); if let Some(matcher) = obj.get_method(context, WellKnownSymbols::match_all())? { - matcher.call(&rx, &[Value::from(s)], context) + matcher.call(&rx, &[JsValue::new(s)], context) } else { context.throw_type_error("RegExp[Symbol.matchAll] is undefined") } @@ -1432,7 +1518,11 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.normalize /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize - pub(crate) fn normalize(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn normalize( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { let this = this.require_object_coercible(context)?; let s = this.to_string(context)?; let form = args.get(0).cloned().unwrap_or_default(); @@ -1447,10 +1537,10 @@ impl String { }; match f { - "NFC" => Ok(Value::from(s.nfc().collect::())), - "NFD" => Ok(Value::from(s.nfd().collect::())), - "NFKC" => Ok(Value::from(s.nfkc().collect::())), - "NFKD" => Ok(Value::from(s.nfkd().collect::())), + "NFC" => Ok(JsValue::new(s.nfc().collect::())), + "NFD" => Ok(JsValue::new(s.nfd().collect::())), + "NFKC" => Ok(JsValue::new(s.nfkc().collect::())), + "NFKD" => Ok(JsValue::new(s.nfkd().collect::())), _ => context .throw_range_error("The normalization form should be one of NFC, NFD, NFKC, NFKD."), } @@ -1466,7 +1556,11 @@ impl String { /// /// [spec]: https://tc39.es/ecma262/#sec-string.prototype.search /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/search - pub(crate) fn search(this: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn search( + this: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> Result { // 1. Let O be ? RequireObjectCoercible(this value). let o = this.require_object_coercible(context)?; @@ -1487,18 +1581,22 @@ impl String { let string = o.to_string(context)?; // 4. Let rx be ? RegExpCreate(regexp, undefined). - let rx = RegExp::create(regexp, Value::undefined(), context)?; + let rx = RegExp::create(regexp, JsValue::undefined(), context)?; // 5. Return ? Invoke(rx, @@search, ยซ string ยป). let obj = rx.as_object().expect("RegExpCreate must return Object"); if let Some(matcher) = obj.get_method(context, WellKnownSymbols::search())? { - matcher.call(&rx, &[Value::from(string)], context) + matcher.call(&rx, &[JsValue::new(string)], context) } else { context.throw_type_error("RegExp[Symbol.search] is undefined") } } - pub(crate) fn iterator(this: &Value, _: &[Value], context: &mut Context) -> Result { + pub(crate) fn iterator( + this: &JsValue, + _: &[JsValue], + context: &mut Context, + ) -> Result { StringIterator::create_string_iterator(context, this.clone()) } } @@ -1513,8 +1611,8 @@ pub(crate) fn get_substitution( matched: StdString, str: StdString, position: usize, - captures: Vec, - named_captures: Value, + captures: Vec, + named_captures: JsValue, replacement: JsString, context: &mut Context, ) -> Result { diff --git a/boa/src/builtins/string/string_iterator.rs b/boa/src/builtins/string/string_iterator.rs index e760cc5f53..a8aaec97f6 100644 --- a/boa/src/builtins/string/string_iterator.rs +++ b/boa/src/builtins/string/string_iterator.rs @@ -6,25 +6,25 @@ use crate::{ object::{GcObject, ObjectData}, property::PropertyDescriptor, symbol::WellKnownSymbols, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; #[derive(Debug, Clone, Finalize, Trace)] pub struct StringIterator { - string: Value, + string: JsValue, next_index: i32, } impl StringIterator { - fn new(string: Value) -> Self { + fn new(string: JsValue) -> Self { Self { string, next_index: 0, } } - pub fn create_string_iterator(context: &mut Context, string: Value) -> Result { - let string_iterator = Value::new_object(context); + pub fn create_string_iterator(context: &mut Context, string: JsValue) -> Result { + let string_iterator = JsValue::new_object(context); string_iterator.set_data(ObjectData::StringIterator(Self::new(string))); string_iterator .as_object() @@ -33,19 +33,27 @@ impl StringIterator { Ok(string_iterator) } - pub fn next(this: &Value, _: &[Value], context: &mut Context) -> Result { - if let Value::Object(ref object) = this { + pub fn next(this: &JsValue, _: &[JsValue], context: &mut Context) -> Result { + if let JsValue::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(context, Value::undefined(), true)); + return Ok(create_iter_result_object( + context, + JsValue::undefined(), + true, + )); } 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(context, Value::undefined(), true)); + string_iterator.string = JsValue::undefined(); + return Ok(create_iter_result_object( + context, + JsValue::undefined(), + true, + )); } let (_, code_unit_count, _) = code_point_at(native_string, position).expect("Invalid code point position"); @@ -70,7 +78,7 @@ impl StringIterator { /// - [ECMA reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-%arrayiteratorprototype%-object - pub(crate) fn create_prototype(context: &mut Context, iterator_prototype: Value) -> GcObject { + pub(crate) fn create_prototype(context: &mut Context, iterator_prototype: JsValue) -> GcObject { let _timer = BoaProfiler::global().start_event("String Iterator", "init"); // Create prototype diff --git a/boa/src/builtins/symbol/mod.rs b/boa/src/builtins/symbol/mod.rs index 25685247be..0c88cc9caa 100644 --- a/boa/src/builtins/symbol/mod.rs +++ b/boa/src/builtins/symbol/mod.rs @@ -23,7 +23,7 @@ use crate::{ object::{ConstructorBuilder, FunctionBuilder}, property::Attribute, symbol::{JsSymbol, WellKnownSymbols}, - value::Value, + value::JsValue, BoaProfiler, Context, JsString, Result, }; @@ -78,7 +78,7 @@ impl BuiltIn for Symbol { Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE } - fn init(context: &mut Context) -> (&'static str, Value, Attribute) { + fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let symbol_async_iterator = WellKnownSymbols::async_iterator(); @@ -160,10 +160,10 @@ 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( - new_target: &Value, - args: &[Value], + new_target: &JsValue, + args: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { if new_target.is_undefined() { return context.throw_type_error("Symbol is not a constructor"); } @@ -175,10 +175,10 @@ impl Symbol { Ok(JsSymbol::new(description).into()) } - fn this_symbol_value(value: &Value, context: &mut Context) -> Result { + fn this_symbol_value(value: &JsValue, context: &mut Context) -> Result { match value { - Value::Symbol(ref symbol) => return Ok(symbol.clone()), - Value::Object(ref object) => { + JsValue::Symbol(ref symbol) => return Ok(symbol.clone()), + JsValue::Object(ref object) => { let object = object.borrow(); if let Some(symbol) = object.as_symbol() { return Ok(symbol); @@ -201,7 +201,11 @@ 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], context: &mut Context) -> Result { + pub(crate) fn to_string( + this: &JsValue, + _: &[JsValue], + context: &mut Context, + ) -> Result { let symbol = Self::this_symbol_value(this, context)?; Ok(symbol.to_string().into()) } @@ -217,15 +221,15 @@ impl Symbol { /// [spec]: https://tc39.es/ecma262/#sec-symbol.prototype.description /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/description pub(crate) fn get_description( - this: &Value, - _: &[Value], + this: &JsValue, + _: &[JsValue], context: &mut Context, - ) -> Result { + ) -> Result { let symbol = Self::this_symbol_value(this, context)?; if let Some(ref description) = symbol.description() { Ok(description.clone().into()) } else { - Ok(Value::undefined()) + Ok(JsValue::undefined()) } } @@ -237,7 +241,7 @@ impl Symbol { /// /// [spec]: https://tc39.es/ecma262/#sec-symbol.prototype.for /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for - pub(crate) fn for_(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn for_(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { // 1. Let stringKey be ? ToString(key). let string_key = args .get(0) @@ -267,7 +271,7 @@ impl Symbol { /// /// [spec]: https://tc39.es/ecma262/#sec-symbol.prototype.keyfor /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/keyFor - pub(crate) fn key_for(_: &Value, args: &[Value], context: &mut Context) -> Result { + pub(crate) fn key_for(_: &JsValue, args: &[JsValue], context: &mut Context) -> Result { let sym = args.get(0).cloned().unwrap_or_default(); // 1. If Type(sym) is not Symbol, throw a TypeError exception. if let Some(sym) = sym.as_symbol() { @@ -280,7 +284,7 @@ impl Symbol { registry.get_symbol(sym) }); - Ok(symbol.map(Value::from).unwrap_or_default()) + Ok(symbol.map(JsValue::from).unwrap_or_default()) } else { context.throw_type_error("Symbol.keyFor: sym is not a symbol") } diff --git a/boa/src/builtins/undefined/mod.rs b/boa/src/builtins/undefined/mod.rs index 91760b427a..ed13441629 100644 --- a/boa/src/builtins/undefined/mod.rs +++ b/boa/src/builtins/undefined/mod.rs @@ -9,7 +9,7 @@ //! [spec]: https://tc39.es/ecma262/#sec-undefined //! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined -use crate::{builtins::BuiltIn, property::Attribute, BoaProfiler, Context, Value}; +use crate::{builtins::BuiltIn, property::Attribute, BoaProfiler, Context, JsValue}; #[cfg(test)] mod tests; @@ -25,9 +25,9 @@ impl BuiltIn for Undefined { Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT } - fn init(_: &mut Context) -> (&'static str, Value, Attribute) { + fn init(_: &mut Context) -> (&'static str, JsValue, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); - (Self::NAME, Value::undefined(), Self::attribute()) + (Self::NAME, JsValue::undefined(), Self::attribute()) } } diff --git a/boa/src/bytecompiler.rs b/boa/src/bytecompiler.rs index 8d063ecce4..059f4a6f19 100644 --- a/boa/src/bytecompiler.rs +++ b/boa/src/bytecompiler.rs @@ -5,7 +5,7 @@ use crate::{ Const, Node, }, vm::{CodeBlock, Opcode}, - JsBigInt, JsString, Value, + JsBigInt, JsString, JsValue, }; use std::collections::HashMap; @@ -72,8 +72,8 @@ impl ByteCompiler { } let value = match liternal.clone() { - Literal::String(value) => Value::from(value), - Literal::BigInt(value) => Value::from(value), + Literal::String(value) => JsValue::new(value), + Literal::BigInt(value) => JsValue::new(value), }; let index = self.code_block.literals.len() as u32; diff --git a/boa/src/class.rs b/boa/src/class.rs index 16396c26e4..08f743c646 100644 --- a/boa/src/class.rs +++ b/boa/src/class.rs @@ -6,7 +6,7 @@ //!# property::Attribute, //!# class::{Class, ClassBuilder}, //!# gc::{Finalize, Trace}, -//!# Context, Result, Value, +//!# Context, Result, JsValue, //!# }; //!# //! // This does not have to be an enum it can also be a struct. @@ -25,7 +25,7 @@ //! const LENGTH: usize = 1; //! //! // This is what is called when we do `new Animal()` -//! fn constructor(_this: &Value, args: &[Value], context: &mut Context) -> Result { +//! fn constructor(_this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { //! // This is equivalent to `String(arg)`. //! let kind = args.get(0).cloned().unwrap_or_default().to_string(context)?; //! @@ -50,7 +50,7 @@ //! } //! } //! } -//! Ok(Value::undefined()) +//! Ok(JsValue::undefined()) //! }); //! //! Ok(()) @@ -64,7 +64,7 @@ use crate::{ builtins::function::NativeFunction, object::{ConstructorBuilder, GcObject, NativeObject, ObjectData}, property::{Attribute, PropertyDescriptor, PropertyKey}, - Context, Result, Value, + Context, JsValue, Result, }; /// Native class. @@ -77,7 +77,7 @@ pub trait Class: NativeObject + Sized { const ATTRIBUTES: Attribute = Attribute::all(); /// The constructor of the class. - fn constructor(this: &Value, args: &[Value], context: &mut Context) -> Result; + fn constructor(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result; /// Initializes the internals and the methods of the class. fn init(class: &mut ClassBuilder<'_>) -> Result<()>; @@ -88,13 +88,13 @@ pub trait Class: NativeObject + Sized { /// This is automatically implemented, when a type implements `Class`. pub trait ClassConstructor: Class { /// The raw constructor that mathces the `NativeFunction` signature. - fn raw_constructor(this: &Value, args: &[Value], context: &mut Context) -> Result + fn raw_constructor(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result where Self: Sized; } impl ClassConstructor for T { - fn raw_constructor(this: &Value, args: &[Value], context: &mut Context) -> Result + fn raw_constructor(this: &JsValue, args: &[JsValue], context: &mut Context) -> Result where Self: Sized, { @@ -163,7 +163,7 @@ impl<'context> ClassBuilder<'context> { pub fn property(&mut self, key: K, value: V, attribute: Attribute) -> &mut Self where K: Into, - V: Into, + V: Into, { self.builder.property(key, value, attribute); self @@ -176,7 +176,7 @@ impl<'context> ClassBuilder<'context> { pub fn static_property(&mut self, key: K, value: V, attribute: Attribute) -> &mut Self where K: Into, - V: Into, + V: Into, { self.builder.static_property(key, value, attribute); self diff --git a/boa/src/context.rs b/boa/src/context.rs index 45d6fe2ba5..b4d7bde43c 100644 --- a/boa/src/context.rs +++ b/boa/src/context.rs @@ -21,7 +21,7 @@ use crate::{ }, Parser, }, - BoaProfiler, Executable, JsString, Result, Value, + BoaProfiler, Executable, JsString, JsValue, Result, }; #[cfg(feature = "console")] @@ -334,15 +334,20 @@ impl Context { /// Construct an empty object. #[inline] pub fn construct_object(&self) -> GcObject { - let object_prototype: Value = self.standard_objects().object_object().prototype().into(); + let object_prototype: JsValue = self.standard_objects().object_object().prototype().into(); GcObject::new(Object::create(object_prototype)) } /// #[inline] - pub(crate) fn call(&mut self, f: &Value, this: &Value, args: &[Value]) -> Result { + pub(crate) fn call( + &mut self, + f: &JsValue, + this: &JsValue, + args: &[JsValue], + ) -> Result { match *f { - Value::Object(ref object) => object.call(this, args, self), + JsValue::Object(ref object) => object.call(this, args, self), _ => self.throw_type_error("not a function"), } } @@ -355,7 +360,7 @@ impl Context { /// Constructs a `RangeError` with the specified message. #[inline] - pub fn construct_range_error(&mut self, message: M) -> Value + pub fn construct_range_error(&mut self, message: M) -> JsValue where M: Into>, { @@ -370,7 +375,7 @@ impl Context { /// Throws a `RangeError` with the specified message. #[inline] - pub fn throw_range_error(&mut self, message: M) -> Result + pub fn throw_range_error(&mut self, message: M) -> Result where M: Into>, { @@ -379,7 +384,7 @@ impl Context { /// Constructs a `TypeError` with the specified message. #[inline] - pub fn construct_type_error(&mut self, message: M) -> Value + pub fn construct_type_error(&mut self, message: M) -> JsValue where M: Into>, { @@ -394,7 +399,7 @@ impl Context { /// Throws a `TypeError` with the specified message. #[inline] - pub fn throw_type_error(&mut self, message: M) -> Result + pub fn throw_type_error(&mut self, message: M) -> Result where M: Into>, { @@ -403,7 +408,7 @@ impl Context { /// Constructs a `ReferenceError` with the specified message. #[inline] - pub fn construct_reference_error(&mut self, message: M) -> Value + pub fn construct_reference_error(&mut self, message: M) -> JsValue where M: Into>, { @@ -417,7 +422,7 @@ impl Context { /// Throws a `ReferenceError` with the specified message. #[inline] - pub fn throw_reference_error(&mut self, message: M) -> Result + pub fn throw_reference_error(&mut self, message: M) -> Result where M: Into>, { @@ -426,7 +431,7 @@ impl Context { /// Constructs a `SyntaxError` with the specified message. #[inline] - pub fn construct_syntax_error(&mut self, message: M) -> Value + pub fn construct_syntax_error(&mut self, message: M) -> JsValue where M: Into>, { @@ -440,7 +445,7 @@ impl Context { /// Throws a `SyntaxError` with the specified message. #[inline] - pub fn throw_syntax_error(&mut self, message: M) -> Result + pub fn throw_syntax_error(&mut self, message: M) -> Result where M: Into>, { @@ -448,7 +453,7 @@ impl Context { } /// Constructs a `EvalError` with the specified message. - pub fn construct_eval_error(&mut self, message: M) -> Value + pub fn construct_eval_error(&mut self, message: M) -> JsValue where M: Into>, { @@ -461,7 +466,7 @@ impl Context { } /// Constructs a `URIError` with the specified message. - pub fn construct_uri_error(&mut self, message: M) -> Value + pub fn construct_uri_error(&mut self, message: M) -> JsValue where M: Into>, { @@ -474,7 +479,7 @@ impl Context { } /// Throws a `EvalError` with the specified message. - pub fn throw_eval_error(&mut self, message: M) -> Result + pub fn throw_eval_error(&mut self, message: M) -> Result where M: Into>, { @@ -482,7 +487,7 @@ impl Context { } /// Throws a `URIError` with the specified message. - pub fn throw_uri_error(&mut self, message: M) -> Result + pub fn throw_uri_error(&mut self, message: M) -> Result where M: Into>, { @@ -496,14 +501,14 @@ impl Context { params: P, body: B, flags: FunctionFlags, - ) -> Result + ) -> Result where N: Into, P: Into>, B: Into, { let name = name.into(); - let function_prototype: Value = + let function_prototype: JsValue = self.standard_objects().function_object().prototype().into(); // Every new function has a prototype property pre-made @@ -606,7 +611,7 @@ impl Context { #[inline] pub fn register_global_closure(&mut self, name: &str, length: usize, body: F) -> Result<()> where - F: Fn(&Value, &[Value], &mut Context) -> Result + 'static, + F: Fn(&JsValue, &[JsValue], &mut Context) -> Result + 'static, { let function = FunctionBuilder::closure(self, body) .name(name) @@ -627,7 +632,7 @@ impl Context { /// #[inline] - pub(crate) fn has_property(&self, obj: &Value, key: &PropertyKey) -> bool { + pub(crate) fn has_property(&self, obj: &JsValue, key: &PropertyKey) -> bool { if let Some(obj) = obj.as_object() { obj.__has_property__(key) } else { @@ -636,7 +641,7 @@ impl Context { } #[inline] - pub(crate) fn set_value(&mut self, node: &Node, value: Value) -> Result { + pub(crate) fn set_value(&mut self, node: &Node, value: JsValue) -> Result { match node { Node::Identifier(ref name) => { self.set_mutable_binding(name.as_ref(), value.clone(), true)?; @@ -725,7 +730,7 @@ impl Context { pub fn register_global_property(&mut self, key: K, value: V, attribute: Attribute) where K: Into, - V: Into, + V: Into, { self.global_object().insert( key, @@ -752,7 +757,7 @@ impl Context { #[cfg(not(feature = "vm"))] #[allow(clippy::unit_arg, clippy::drop_copy)] #[inline] - pub fn eval>(&mut self, src: T) -> Result { + pub fn eval>(&mut self, src: T) -> Result { let main_timer = BoaProfiler::global().start_event("Main", "Main"); let src_bytes: &[u8] = src.as_ref(); @@ -786,7 +791,7 @@ impl Context { /// ``` #[cfg(feature = "vm")] #[allow(clippy::unit_arg, clippy::drop_copy)] - pub fn eval>(&mut self, src: T) -> Result { + pub fn eval>(&mut self, src: T) -> Result { let main_timer = BoaProfiler::global().start_event("Main", "Main"); let src_bytes: &[u8] = src.as_ref(); diff --git a/boa/src/environment/declarative_environment_record.rs b/boa/src/environment/declarative_environment_record.rs index 9890c1e39e..cf718fc90e 100644 --- a/boa/src/environment/declarative_environment_record.rs +++ b/boa/src/environment/declarative_environment_record.rs @@ -12,7 +12,7 @@ use crate::{ }, gc::{Finalize, Trace}, object::GcObject, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; use gc::{Gc, GcCell}; use rustc_hash::FxHashMap; @@ -24,7 +24,7 @@ use rustc_hash::FxHashMap; /// From this point onwards, a binding is referring to one of these structures. #[derive(Trace, Finalize, Debug, Clone)] pub struct DeclarativeEnvironmentRecordBinding { - pub value: Option, + pub value: Option, pub can_delete: bool, pub mutable: bool, pub strict: bool, @@ -104,7 +104,7 @@ impl EnvironmentRecordTrait for DeclarativeEnvironmentRecord { Ok(()) } - fn initialize_binding(&self, name: &str, value: Value, _context: &mut Context) -> Result<()> { + fn initialize_binding(&self, name: &str, value: JsValue, _context: &mut Context) -> Result<()> { if let Some(ref mut record) = self.env_rec.borrow_mut().get_mut(name) { if record.value.is_none() { record.value = Some(value); @@ -118,7 +118,7 @@ impl EnvironmentRecordTrait for DeclarativeEnvironmentRecord { fn set_mutable_binding( &self, name: &str, - value: Value, + value: JsValue, mut strict: bool, context: &mut Context, ) -> Result<()> { @@ -159,7 +159,12 @@ impl EnvironmentRecordTrait for DeclarativeEnvironmentRecord { Ok(()) } - fn get_binding_value(&self, name: &str, _strict: bool, context: &mut Context) -> Result { + fn get_binding_value( + &self, + name: &str, + _strict: bool, + context: &mut Context, + ) -> Result { if let Some(binding) = self.env_rec.borrow().get(name) { if let Some(ref val) = binding.value { Ok(val.clone()) @@ -189,8 +194,8 @@ impl EnvironmentRecordTrait for DeclarativeEnvironmentRecord { false } - fn get_this_binding(&self, _context: &mut Context) -> Result { - Ok(Value::undefined()) + fn get_this_binding(&self, _context: &mut Context) -> Result { + Ok(JsValue::undefined()) } fn has_super_binding(&self) -> bool { diff --git a/boa/src/environment/environment_record_trait.rs b/boa/src/environment/environment_record_trait.rs index 2ab9ebefcf..29c0878e59 100644 --- a/boa/src/environment/environment_record_trait.rs +++ b/boa/src/environment/environment_record_trait.rs @@ -13,7 +13,7 @@ use crate::{environment::lexical_environment::VariableScope, object::GcObject}; use crate::{ environment::lexical_environment::{Environment, EnvironmentType}, gc::{Finalize, Trace}, - Context, Result, Value, + Context, JsValue, Result, }; use std::fmt::Debug; @@ -55,7 +55,7 @@ pub trait EnvironmentRecordTrait: Debug + Trace + Finalize { /// Set the value of an already existing but uninitialized binding in an Environment Record. /// The String value N is the text of the bound name. /// V is the value for the binding and is a value of any ECMAScript language type. - fn initialize_binding(&self, name: &str, value: Value, context: &mut Context) -> Result<()>; + fn initialize_binding(&self, name: &str, value: JsValue, context: &mut Context) -> Result<()>; /// Set the value of an already existing mutable binding in an Environment Record. /// The String value `name` is the text of the bound name. @@ -64,7 +64,7 @@ pub trait EnvironmentRecordTrait: Debug + Trace + Finalize { fn set_mutable_binding( &self, name: &str, - value: Value, + value: JsValue, strict: bool, context: &mut Context, ) -> Result<()>; @@ -73,7 +73,8 @@ pub trait EnvironmentRecordTrait: Debug + Trace + Finalize { /// The String value N is the text of the bound name. /// S is used to identify references originating in strict mode code or that /// otherwise require strict mode reference semantics. - fn get_binding_value(&self, name: &str, strict: bool, context: &mut Context) -> Result; + fn get_binding_value(&self, name: &str, strict: bool, context: &mut Context) + -> Result; /// Delete a binding from an Environment Record. /// The String value name is the text of the bound name. @@ -86,7 +87,7 @@ pub trait EnvironmentRecordTrait: Debug + Trace + Finalize { fn has_this_binding(&self) -> bool; /// Return the `this` binding from the environment - fn get_this_binding(&self, context: &mut Context) -> Result; + fn get_this_binding(&self, context: &mut Context) -> Result; /// Determine if an Environment Record establishes a super method binding. /// Return true if it does and false if it does not. @@ -109,13 +110,13 @@ pub trait EnvironmentRecordTrait: Debug + Trace + Finalize { fn get_environment_type(&self) -> EnvironmentType; /// Return the `this` binding from the environment or try to get it from outer environments - fn recursive_get_this_binding(&self, context: &mut Context) -> Result { + fn recursive_get_this_binding(&self, context: &mut Context) -> Result { if self.has_this_binding() { self.get_this_binding(context) } else { match self.get_outer_environment_ref() { Some(outer) => outer.recursive_get_this_binding(context), - None => Ok(Value::Undefined), + None => Ok(JsValue::undefined()), } } } @@ -158,7 +159,7 @@ pub trait EnvironmentRecordTrait: Debug + Trace + Finalize { fn recursive_set_mutable_binding( &self, name: &str, - value: Value, + value: JsValue, strict: bool, context: &mut Context, ) -> Result<()> { @@ -175,7 +176,7 @@ pub trait EnvironmentRecordTrait: Debug + Trace + Finalize { fn recursive_initialize_binding( &self, name: &str, - value: Value, + value: JsValue, context: &mut Context, ) -> Result<()> { if self.has_binding(name) { @@ -197,7 +198,7 @@ pub trait EnvironmentRecordTrait: Debug + Trace + Finalize { } /// Retrieve binding from current or any outer environment - fn recursive_get_binding_value(&self, name: &str, context: &mut Context) -> Result { + fn recursive_get_binding_value(&self, name: &str, context: &mut Context) -> Result { if self.has_binding(name) { self.get_binding_value(name, false, context) } else { diff --git a/boa/src/environment/function_environment_record.rs b/boa/src/environment/function_environment_record.rs index 9113552519..8dce92024b 100644 --- a/boa/src/environment/function_environment_record.rs +++ b/boa/src/environment/function_environment_record.rs @@ -18,7 +18,7 @@ use crate::{ }, gc::{empty_trace, Finalize, Trace}, object::GcObject, - Context, Result, Value, + Context, JsValue, Result, }; /// Different binding status for `this`. @@ -42,7 +42,7 @@ unsafe impl Trace for BindingStatus { pub struct FunctionEnvironmentRecord { pub declarative_record: DeclarativeEnvironmentRecord, /// This is the this value used for this invocation of the function. - pub this_value: Value, + pub this_value: JsValue, /// If the value is "lexical", this is an ArrowFunction and does not have a local this value. pub this_binding_status: BindingStatus, /// The function object whose invocation caused this Environment Record to be created. @@ -50,28 +50,28 @@ pub struct FunctionEnvironmentRecord { /// If the associated function has super property accesses and is not an ArrowFunction, /// `[[HomeObject]]` is the object that the function is bound to as a method. /// The default value for `[[HomeObject]]` is undefined. - pub home_object: Value, + pub home_object: JsValue, /// If this Environment Record was created by the `[[Construct]]` internal method, /// `[[NewTarget]]` is the value of the `[[Construct]]` newTarget parameter. /// Otherwise, its value is undefined. - pub new_target: Value, + pub new_target: JsValue, } impl FunctionEnvironmentRecord { pub fn new( f: GcObject, - this: Option, + this: Option, outer: Option, binding_status: BindingStatus, - new_target: Value, + new_target: JsValue, ) -> FunctionEnvironmentRecord { let mut func_env = FunctionEnvironmentRecord { declarative_record: DeclarativeEnvironmentRecord::new(outer), // the outer environment will come from Environment set as a private property of F - https://tc39.es/ecma262/#sec-ecmascript-function-objects function: f, this_binding_status: binding_status, - home_object: Value::undefined(), + home_object: JsValue::undefined(), new_target, - this_value: Value::undefined(), + this_value: JsValue::undefined(), }; // If a `this` value has been passed, bind it to the environment if let Some(v) = this { @@ -80,7 +80,7 @@ impl FunctionEnvironmentRecord { func_env } - pub fn bind_this_value(&mut self, value: Value) -> Result { + pub fn bind_this_value(&mut self, value: JsValue) -> Result { match self.this_binding_status { // You can not bind an arrow function, their `this` value comes from the lexical scope above BindingStatus::Lexical => { @@ -99,10 +99,10 @@ impl FunctionEnvironmentRecord { } } - pub fn get_super_base(&self) -> Value { + pub fn get_super_base(&self) -> JsValue { let home = &self.home_object; if home.is_undefined() { - Value::Undefined + JsValue::undefined() } else { assert!(home.is_object()); home.as_object() @@ -138,7 +138,7 @@ impl EnvironmentRecordTrait for FunctionEnvironmentRecord { .create_immutable_binding(name, strict, context) } - fn initialize_binding(&self, name: &str, value: Value, context: &mut Context) -> Result<()> { + fn initialize_binding(&self, name: &str, value: JsValue, context: &mut Context) -> Result<()> { self.declarative_record .initialize_binding(name, value, context) } @@ -146,7 +146,7 @@ impl EnvironmentRecordTrait for FunctionEnvironmentRecord { fn set_mutable_binding( &self, name: &str, - value: Value, + value: JsValue, strict: bool, context: &mut Context, ) -> Result<()> { @@ -154,7 +154,12 @@ impl EnvironmentRecordTrait for FunctionEnvironmentRecord { .set_mutable_binding(name, value, strict, context) } - fn get_binding_value(&self, name: &str, strict: bool, context: &mut Context) -> Result { + fn get_binding_value( + &self, + name: &str, + strict: bool, + context: &mut Context, + ) -> Result { self.declarative_record .get_binding_value(name, strict, context) } @@ -167,7 +172,7 @@ impl EnvironmentRecordTrait for FunctionEnvironmentRecord { !matches!(self.this_binding_status, BindingStatus::Lexical) } - fn get_this_binding(&self, context: &mut Context) -> Result { + fn get_this_binding(&self, context: &mut Context) -> Result { match self.this_binding_status { BindingStatus::Lexical => { panic!("There is no this for a lexical function record"); diff --git a/boa/src/environment/global_environment_record.rs b/boa/src/environment/global_environment_record.rs index bc8f41d585..b5408c9691 100644 --- a/boa/src/environment/global_environment_record.rs +++ b/boa/src/environment/global_environment_record.rs @@ -17,7 +17,7 @@ use crate::{ gc::{Finalize, Trace}, object::GcObject, property::PropertyDescriptor, - Context, Result, Value, + Context, JsValue, Result, }; use gc::{Gc, GcCell}; use rustc_hash::FxHashSet; @@ -111,7 +111,7 @@ impl GlobalEnvironmentRecord { let extensible = global_object.is_extensible(); if !has_property && extensible { obj_rec.create_mutable_binding(name.clone(), deletion, false, context)?; - obj_rec.initialize_binding(&name, Value::undefined(), context)?; + obj_rec.initialize_binding(&name, JsValue::undefined(), context)?; } let mut var_declared_names = self.var_names.borrow_mut(); @@ -121,7 +121,7 @@ impl GlobalEnvironmentRecord { Ok(()) } - pub fn create_global_function_binding(&mut self, name: &str, value: Value, deletion: bool) { + pub fn create_global_function_binding(&mut self, name: &str, value: JsValue, deletion: bool) { let global_object = &mut self.object_record.bindings; let existing_prop = global_object.get_property(name); // TODO: change to desc.is_undefined() @@ -184,7 +184,7 @@ impl EnvironmentRecordTrait for GlobalEnvironmentRecord { .create_immutable_binding(name, strict, context) } - fn initialize_binding(&self, name: &str, value: Value, context: &mut Context) -> Result<()> { + fn initialize_binding(&self, name: &str, value: JsValue, context: &mut Context) -> Result<()> { if self.declarative_record.has_binding(name) { return self .declarative_record @@ -201,7 +201,7 @@ impl EnvironmentRecordTrait for GlobalEnvironmentRecord { fn set_mutable_binding( &self, name: &str, - value: Value, + value: JsValue, strict: bool, context: &mut Context, ) -> Result<()> { @@ -214,7 +214,12 @@ impl EnvironmentRecordTrait for GlobalEnvironmentRecord { .set_mutable_binding(name, value, strict, context) } - fn get_binding_value(&self, name: &str, strict: bool, context: &mut Context) -> Result { + fn get_binding_value( + &self, + name: &str, + strict: bool, + context: &mut Context, + ) -> Result { if self.declarative_record.has_binding(name) { return self .declarative_record @@ -228,7 +233,7 @@ impl EnvironmentRecordTrait for GlobalEnvironmentRecord { return self.declarative_record.delete_binding(name); } - let global: &Value = &self.object_record.bindings; + let global: &JsValue = &self.object_record.bindings; if global.has_field(name) { let status = self.object_record.delete_binding(name); if status { @@ -246,7 +251,7 @@ impl EnvironmentRecordTrait for GlobalEnvironmentRecord { true } - fn get_this_binding(&self, _context: &mut Context) -> Result { + fn get_this_binding(&self, _context: &mut Context) -> Result { Ok(self.global_this_binding.clone().into()) } @@ -298,7 +303,7 @@ impl EnvironmentRecordTrait for GlobalEnvironmentRecord { fn recursive_set_mutable_binding( &self, name: &str, - value: Value, + value: JsValue, strict: bool, context: &mut Context, ) -> Result<()> { @@ -308,7 +313,7 @@ impl EnvironmentRecordTrait for GlobalEnvironmentRecord { fn recursive_initialize_binding( &self, name: &str, - value: Value, + value: JsValue, context: &mut Context, ) -> Result<()> { self.initialize_binding(name, value, context) diff --git a/boa/src/environment/lexical_environment.rs b/boa/src/environment/lexical_environment.rs index a36243336d..6fb07c5cd9 100644 --- a/boa/src/environment/lexical_environment.rs +++ b/boa/src/environment/lexical_environment.rs @@ -8,7 +8,7 @@ use super::global_environment_record::GlobalEnvironmentRecord; use crate::{ environment::environment_record_trait::EnvironmentRecordTrait, object::GcObject, BoaProfiler, - Context, Result, Value, + Context, JsValue, Result, }; use gc::Gc; use std::{collections::VecDeque, error, fmt}; @@ -88,7 +88,7 @@ impl Context { self.realm.environment.environment_stack.pop_back() } - pub(crate) fn get_this_binding(&mut self) -> Result { + pub(crate) fn get_this_binding(&mut self) -> Result { self.get_current_environment() .recursive_get_this_binding(self) } @@ -116,14 +116,14 @@ impl Context { pub(crate) fn set_mutable_binding( &mut self, name: &str, - value: Value, + value: JsValue, strict: bool, ) -> Result<()> { self.get_current_environment() .recursive_set_mutable_binding(name, value, strict, self) } - pub(crate) fn initialize_binding(&mut self, name: &str, value: Value) -> Result<()> { + pub(crate) fn initialize_binding(&mut self, name: &str, value: JsValue) -> Result<()> { self.get_current_environment() .recursive_initialize_binding(name, value, self) } @@ -143,7 +143,7 @@ impl Context { self.get_current_environment().recursive_has_binding(name) } - pub(crate) fn get_binding_value(&mut self, name: &str) -> Result { + pub(crate) fn get_binding_value(&mut self, name: &str) -> Result { self.get_current_environment() .recursive_get_binding_value(name, self) } diff --git a/boa/src/environment/object_environment_record.rs b/boa/src/environment/object_environment_record.rs index 04b9042ee5..8e37b94811 100644 --- a/boa/src/environment/object_environment_record.rs +++ b/boa/src/environment/object_environment_record.rs @@ -16,19 +16,19 @@ use crate::{ gc::{Finalize, Trace}, object::GcObject, property::PropertyDescriptor, - Context, Result, Value, + Context, JsValue, Result, }; #[derive(Debug, Trace, Finalize, Clone)] pub struct ObjectEnvironmentRecord { // TODO: bindings should be an object. - pub bindings: Value, + pub bindings: JsValue, pub with_environment: bool, pub outer_env: Option, } impl ObjectEnvironmentRecord { - pub fn new(object: Value, environment: Option) -> ObjectEnvironmentRecord { + pub fn new(object: JsValue, environment: Option) -> ObjectEnvironmentRecord { ObjectEnvironmentRecord { bindings: object, outer_env: environment, @@ -65,7 +65,7 @@ impl EnvironmentRecordTrait for ObjectEnvironmentRecord { // only for it to be replace with the real value later. We could just add the name to a Vector instead let bindings = &self.bindings; let prop = PropertyDescriptor::builder() - .value(Value::undefined()) + .value(JsValue::undefined()) .writable(true) .enumerable(true) .configurable(deletion); @@ -83,7 +83,7 @@ impl EnvironmentRecordTrait for ObjectEnvironmentRecord { Ok(()) } - fn initialize_binding(&self, name: &str, value: Value, context: &mut Context) -> Result<()> { + fn initialize_binding(&self, name: &str, value: JsValue, context: &mut Context) -> Result<()> { // We should never need to check if a binding has been created, // As all calls to create_mutable_binding are followed by initialized binding // The below is just a check. @@ -94,7 +94,7 @@ impl EnvironmentRecordTrait for ObjectEnvironmentRecord { fn set_mutable_binding( &self, name: &str, - value: Value, + value: JsValue, strict: bool, _context: &mut Context, ) -> Result<()> { @@ -110,7 +110,12 @@ impl EnvironmentRecordTrait for ObjectEnvironmentRecord { Ok(()) } - fn get_binding_value(&self, name: &str, strict: bool, context: &mut Context) -> Result { + fn get_binding_value( + &self, + name: &str, + strict: bool, + context: &mut Context, + ) -> Result { if self.bindings.has_field(name) { Ok(self .bindings @@ -118,11 +123,11 @@ impl EnvironmentRecordTrait for ObjectEnvironmentRecord { .as_ref() .and_then(|prop| prop.value()) .cloned() - .unwrap_or(Value::Undefined)) + .unwrap_or_default()) } else if strict { context.throw_reference_error(format!("{} has no binding", name)) } else { - Ok(Value::undefined()) + Ok(JsValue::undefined()) } } @@ -135,8 +140,8 @@ impl EnvironmentRecordTrait for ObjectEnvironmentRecord { false } - fn get_this_binding(&self, _context: &mut Context) -> Result { - Ok(Value::undefined()) + fn get_this_binding(&self, _context: &mut Context) -> Result { + Ok(JsValue::undefined()) } fn has_super_binding(&self) -> bool { diff --git a/boa/src/exec/mod.rs b/boa/src/exec/mod.rs index 737de76461..803d55a69b 100644 --- a/boa/src/exec/mod.rs +++ b/boa/src/exec/mod.rs @@ -3,11 +3,11 @@ #[cfg(test)] mod tests; -use crate::{Context, Result, Value}; +use crate::{Context, JsValue, Result}; pub trait Executable { /// Runs this executable in the given context. - fn run(&self, context: &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 e86deaca9c..cb7c810c39 100644 --- a/boa/src/exec/tests.rs +++ b/boa/src/exec/tests.rs @@ -1,4 +1,4 @@ -use crate::{builtins::Number, exec, forward, forward_val, Context, Value}; +use crate::{builtins::Number, exec, forward, forward_val, Context, JsValue}; #[test] fn function_declaration_returns_undefined() { @@ -899,19 +899,19 @@ fn function_decl_hoisting() { fn to_bigint() { let mut context = Context::new(); - 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()); + assert!(JsValue::null().to_bigint(&mut context).is_err()); + assert!(JsValue::undefined().to_bigint(&mut context).is_err()); + assert!(JsValue::new(55).to_bigint(&mut context).is_ok()); + assert!(JsValue::new(10.0).to_bigint(&mut context).is_ok()); + assert!(JsValue::new("100").to_bigint(&mut context).is_ok()); } #[test] fn to_index() { let mut context = Context::new(); - assert_eq!(Value::undefined().to_index(&mut context).unwrap(), 0); - assert!(Value::integer(-1).to_index(&mut context).is_err()); + assert_eq!(JsValue::undefined().to_index(&mut context).unwrap(), 0); + assert!(JsValue::new(-1).to_index(&mut context).is_err()); } #[test] @@ -919,34 +919,34 @@ fn to_integer() { let mut context = Context::new(); assert!(Number::equal( - Value::number(f64::NAN).to_integer(&mut context).unwrap(), + JsValue::nan().to_integer(&mut context).unwrap(), 0.0 )); assert!(Number::equal( - Value::number(f64::NEG_INFINITY) + JsValue::new(f64::NEG_INFINITY) .to_integer(&mut context) .unwrap(), f64::NEG_INFINITY )); assert!(Number::equal( - Value::number(f64::INFINITY) + JsValue::new(f64::INFINITY) .to_integer(&mut context) .unwrap(), f64::INFINITY )); assert!(Number::equal( - Value::number(0.0).to_integer(&mut context).unwrap(), + JsValue::new(0.0).to_integer(&mut context).unwrap(), 0.0 )); - let number = Value::number(-0.0).to_integer(&mut context).unwrap(); + let number = JsValue::new(-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 context).unwrap(), + JsValue::new(20.9).to_integer(&mut context).unwrap(), 20.0 )); assert!(Number::equal( - Value::number(-20.9).to_integer(&mut context).unwrap(), + JsValue::new(-20.9).to_integer(&mut context).unwrap(), -20.0 )); } @@ -955,31 +955,29 @@ fn to_integer() { fn to_length() { let mut context = Context::new(); - assert_eq!(Value::number(f64::NAN).to_length(&mut context).unwrap(), 0); + assert_eq!(JsValue::new(f64::NAN).to_length(&mut context).unwrap(), 0); assert_eq!( - Value::number(f64::NEG_INFINITY) + JsValue::new(f64::NEG_INFINITY) .to_length(&mut context) .unwrap(), 0 ); assert_eq!( - Value::number(f64::INFINITY) - .to_length(&mut context) - .unwrap(), + JsValue::new(f64::INFINITY).to_length(&mut context).unwrap(), Number::MAX_SAFE_INTEGER as usize ); - 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!(JsValue::new(0.0).to_length(&mut context).unwrap(), 0); + assert_eq!(JsValue::new(-0.0).to_length(&mut context).unwrap(), 0); + assert_eq!(JsValue::new(20.9).to_length(&mut context).unwrap(), 20); + assert_eq!(JsValue::new(-20.9).to_length(&mut context).unwrap(), 0); assert_eq!( - Value::number(100000000000.0) + JsValue::new(100000000000.0) .to_length(&mut context) .unwrap() as u64, 100000000000 ); assert_eq!( - Value::number(4010101101.0).to_length(&mut context).unwrap(), + JsValue::new(4010101101.0).to_length(&mut context).unwrap(), 4010101101 ); } @@ -990,7 +988,7 @@ fn to_int32() { macro_rules! check_to_int32 { ($from:expr => $to:expr) => { - assert_eq!(Value::from($from).to_i32(&mut context).unwrap(), $to); + assert_eq!(JsValue::new($from).to_i32(&mut context).unwrap(), $to); }; } @@ -1101,15 +1099,15 @@ fn to_int32() { fn to_string() { let mut context = Context::new(); - assert_eq!(Value::null().to_string(&mut context).unwrap(), "null"); + assert_eq!(JsValue::null().to_string(&mut context).unwrap(), "null"); assert_eq!( - Value::undefined().to_string(&mut context).unwrap(), + JsValue::undefined().to_string(&mut context).unwrap(), "undefined" ); - 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!(JsValue::new(55).to_string(&mut context).unwrap(), "55"); + assert_eq!(JsValue::new(55.0).to_string(&mut context).unwrap(), "55"); assert_eq!( - Value::string("hello").to_string(&mut context).unwrap(), + JsValue::new("hello").to_string(&mut context).unwrap(), "hello" ); } @@ -1132,11 +1130,11 @@ fn calling_function_with_unspecified_arguments() { fn to_object() { let mut context = Context::new(); - assert!(Value::undefined() + assert!(JsValue::undefined() .to_object(&mut context) .unwrap_err() .is_object()); - assert!(Value::null() + assert!(JsValue::null() .to_object(&mut context) .unwrap_err() .is_object()); diff --git a/boa/src/lib.rs b/boa/src/lib.rs index 93387b717d..ec46f90ad2 100644 --- a/boa/src/lib.rs +++ b/boa/src/lib.rs @@ -69,7 +69,7 @@ pub(crate) use crate::{exec::Executable, profiler::BoaProfiler}; // Export things to root level #[doc(inline)] pub use crate::{ - bigint::JsBigInt, context::Context, string::JsString, symbol::JsSymbol, value::Value, + bigint::JsBigInt, context::Context, string::JsString, symbol::JsSymbol, value::JsValue, }; use crate::syntax::{ @@ -79,7 +79,7 @@ use crate::syntax::{ /// The result of a Javascript expression is represented like this so it can succeed (`Ok`) or fail (`Err`) #[must_use] -pub type Result = StdResult; +pub type Result = StdResult; /// Parses the given source code. /// @@ -122,7 +122,7 @@ pub(crate) fn forward>(context: &mut Context, src: T) -> 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>(context: &mut Context, src: T) -> Result { +pub(crate) fn forward_val>(context: &mut Context, src: T) -> Result { let main_timer = BoaProfiler::global().start_event("Main", "Main"); let src_bytes: &[u8] = src.as_ref(); diff --git a/boa/src/object/gcobject.rs b/boa/src/object/gcobject.rs index 2841399d06..9fd4b3811d 100644 --- a/boa/src/object/gcobject.rs +++ b/boa/src/object/gcobject.rs @@ -16,7 +16,7 @@ use crate::{ symbol::WellKnownSymbols, syntax::ast::node::RcStatementList, value::PreferredType, - Context, Executable, Result, Value, + Context, Executable, JsValue, Result, }; use gc::{Finalize, Gc, GcCell, GcCellRef, GcCellRefMut, Trace}; use serde_json::{map::Map, Value as JSONValue}; @@ -125,11 +125,11 @@ impl GcObject { #[track_caller] fn call_construct( &self, - this_target: &Value, - args: &[Value], + this_target: &JsValue, + args: &[JsValue], context: &mut Context, construct: bool, - ) -> Result { + ) -> Result { let this_function_object = self.clone(); let mut has_parameter_expressions = false; @@ -178,7 +178,7 @@ impl GcObject { .prototype() .into() }; - Value::from(Object::create(proto)) + JsValue::new(Object::create(proto)) } else { this_target.clone() }; @@ -199,7 +199,7 @@ impl GcObject { } else { BindingStatus::Uninitialized }, - Value::undefined(), + JsValue::undefined(), ); let mut arguments_in_parameter_names = false; @@ -249,7 +249,7 @@ impl GcObject { } let value = match args.get(i).cloned() { - None | Some(Value::Undefined) => param + None | Some(JsValue::Undefined) => param .init() .map(|init| init.run(context).ok()) .flatten() @@ -280,7 +280,7 @@ impl GcObject { } else { BindingStatus::Uninitialized }, - Value::undefined(), + JsValue::undefined(), ); context.push_environment(second_env); } @@ -298,7 +298,7 @@ impl GcObject { function(this_target, args, context) } FunctionBody::BuiltInConstructor(function) => { - function(&Value::undefined(), args, context) + function(&JsValue::undefined(), args, context) } FunctionBody::BuiltInFunction(function) => function(this_target, args, context), FunctionBody::Closure(function) => (function)(this_target, args, context), @@ -329,7 +329,7 @@ impl GcObject { // #[track_caller] #[inline] - pub fn call(&self, this: &Value, args: &[Value], context: &mut Context) -> Result { + pub fn call(&self, this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { self.call_construct(this, args, context, false) } @@ -343,10 +343,10 @@ impl GcObject { #[inline] pub fn construct( &self, - args: &[Value], - new_target: &Value, + args: &[JsValue], + new_target: &JsValue, context: &mut Context, - ) -> Result { + ) -> Result { self.call_construct(new_target, args, context, true) } @@ -372,7 +372,7 @@ impl GcObject { &self, context: &mut Context, hint: PreferredType, - ) -> Result { + ) -> Result { // 1. Assert: Type(O) is Object. // Already is GcObject by type. // 2. Assert: Type(hint) is String and its value is either "string" or "number". @@ -386,8 +386,8 @@ impl GcObject { if recursion_limiter.live { // we're in a recursive object, bail return Ok(match hint { - PreferredType::Number => Value::from(0), - PreferredType::String => Value::from(""), + PreferredType::Number => JsValue::new(0), + PreferredType::String => JsValue::new(""), PreferredType::Default => unreachable!("checked type hint in step 2"), }); } @@ -403,10 +403,10 @@ impl GcObject { }; // 5. For each name in methodNames in List order, do - let this = Value::from(self.clone()); + let this = JsValue::new(self.clone()); for name in &method_names { // a. Let method be ? Get(O, name). - let method: Value = this.get_field(*name, context)?; + let method: JsValue = this.get_field(*name, context)?; // b. If IsCallable(method) is true, then if method.is_function() { // i. Let result be ? Call(method, O). @@ -436,7 +436,7 @@ impl GcObject { .collect(); keys.sort_unstable(); let mut arr: Vec = Vec::with_capacity(keys.len()); - let this = Value::from(self.clone()); + let this = JsValue::new(self.clone()); for key in keys { let value = this.get_field(key, context)?; if let Some(value) = value.to_json(context)? { @@ -448,7 +448,7 @@ impl GcObject { Ok(Some(JSONValue::Array(arr))) } else { let mut new_obj = Map::new(); - let this = Value::from(self.clone()); + let this = JsValue::new(self.clone()); let keys: Vec = self.borrow().properties.keys().collect(); for k in keys { let key = k.clone(); @@ -522,7 +522,7 @@ impl GcObject { /// Panics if the object is currently mutably borrowed. #[inline] #[track_caller] - pub fn prototype_instance(&self) -> Value { + pub fn prototype_instance(&self) -> JsValue { self.borrow().prototype_instance().clone() } @@ -534,7 +534,7 @@ impl GcObject { /// or if th prototype is not an object or undefined. #[inline] #[track_caller] - pub fn set_prototype_instance(&self, prototype: Value) -> bool { + pub fn set_prototype_instance(&self, prototype: JsValue) -> bool { self.borrow_mut().set_prototype_instance(prototype) } @@ -720,7 +720,7 @@ impl GcObject { pub(crate) fn ordinary_has_instance( &self, context: &mut Context, - value: &Value, + value: &JsValue, ) -> Result { // 1. If IsCallable(C) is false, return false. if !self.is_callable() { @@ -771,9 +771,9 @@ impl GcObject { /// [spec]: https://tc39.es/ecma262/#sec-speciesconstructor pub(crate) fn species_constructor( &self, - default_constructor: Value, + default_constructor: JsValue, context: &mut Context, - ) -> Result { + ) -> Result { // 1. Assert: Type(O) is Object. // 2. Let C be ? Get(O, "constructor"). diff --git a/boa/src/object/internal_methods.rs b/boa/src/object/internal_methods.rs index 72b358abf6..4d8a66072d 100644 --- a/boa/src/object/internal_methods.rs +++ b/boa/src/object/internal_methods.rs @@ -8,7 +8,7 @@ use crate::{ object::{GcObject, Object, ObjectData}, property::{DescriptorKind, PropertyDescriptor, PropertyKey}, - value::{Type, Value}, + value::{JsValue, Type}, BoaProfiler, Context, Result, }; @@ -106,7 +106,7 @@ impl GcObject { /// /// [spec]: https://tc39.es/ecma262/#sec-get-o-p #[inline] - pub fn get(&self, key: K, context: &mut Context) -> Result + pub fn get(&self, key: K, context: &mut Context) -> Result where K: Into, { @@ -126,7 +126,7 @@ impl GcObject { pub fn set(&self, key: K, value: V, throw: bool, context: &mut Context) -> Result where K: Into, - V: Into, + V: Into, { let key = key.into(); // 1. Assert: Type(O) is Object. @@ -188,7 +188,7 @@ impl GcObject { ) -> Result where K: Into, - V: Into, + V: Into, { // 1. Assert: Type(O) is Object. // 2. Assert: IsPropertyKey(P) is true. @@ -216,7 +216,7 @@ impl GcObject { ) -> Result where K: Into, - V: Into, + V: Into, { let key = key.into(); // 1. Assert: Type(O) is Object. @@ -237,7 +237,7 @@ impl GcObject { let prop = self.__get_own_property__(key); if prop.is_none() { let parent = self.__get_prototype_of__(); - return if let Value::Object(ref object) = parent { + return if let JsValue::Object(ref object) = parent { object.__has_property__(key) } else { false @@ -286,16 +286,16 @@ impl GcObject { pub fn __get__( &self, key: &PropertyKey, - receiver: Value, + receiver: JsValue, context: &mut Context, - ) -> Result { + ) -> Result { match self.__get_own_property__(key) { None => { // parent will either be null or an Object if let Some(parent) = self.__get_prototype_of__().as_object() { Ok(parent.__get__(key, receiver, context)?) } else { - Ok(Value::undefined()) + Ok(JsValue::undefined()) } } Some(ref desc) => match desc.kind() { @@ -305,7 +305,7 @@ impl GcObject { DescriptorKind::Accessor { get: Some(get), .. } if !get.is_undefined() => { context.call(get, &receiver, &[]) } - _ => Ok(Value::undefined()), + _ => Ok(JsValue::undefined()), }, } } @@ -314,8 +314,8 @@ impl GcObject { pub fn __set__( &self, key: PropertyKey, - value: Value, - receiver: Value, + value: JsValue, + receiver: JsValue, context: &mut Context, ) -> Result { let _timer = BoaProfiler::global().start_event("Object::set", "object"); @@ -327,7 +327,7 @@ impl GcObject { return parent.__set__(key, value, receiver, context); } else { PropertyDescriptor::builder() - .value(Value::undefined()) + .value(JsValue::undefined()) .writable(true) .enumerable(true) .configurable(true) @@ -448,17 +448,17 @@ impl GcObject { if matches!(desc.writable(), Some(true)) { return false; } - if matches!(desc.value(), Some(value) if !Value::same_value(value, current.expect_value())) + if matches!(desc.value(), Some(value) if !JsValue::same_value(value, current.expect_value())) { return false; } return true; } } else if !current.expect_configurable() { - if matches!(desc.set(), Some(set) if !Value::same_value(set, current.expect_set())) { + if matches!(desc.set(), Some(set) if !JsValue::same_value(set, current.expect_set())) { return false; } - if matches!(desc.get(), Some(get) if !Value::same_value(get, current.expect_get())) { + if matches!(desc.get(), Some(get) if !JsValue::same_value(get, current.expect_get())) { return false; } return true; @@ -623,7 +623,7 @@ impl GcObject { let result_str = string .encode_utf16() .nth(pos) - .map(|utf16_val| Value::from(String::from_utf16_lossy(&[utf16_val])))?; + .map(|utf16_val| JsValue::from(String::from_utf16_lossy(&[utf16_val])))?; let desc = PropertyDescriptor::builder() .value(result_str) @@ -690,7 +690,7 @@ impl GcObject { /// /// [spec]: https://tc39.es/ecma262/#sec-object.defineproperties #[inline] - pub fn define_properties(&mut self, props: Value, context: &mut Context) -> Result<()> { + pub fn define_properties(&mut self, props: JsValue, context: &mut Context) -> Result<()> { let props = &props.to_object(context)?; let keys = props.own_property_keys(); let mut descriptors: Vec<(PropertyKey, PropertyDescriptor)> = Vec::new(); @@ -724,10 +724,10 @@ impl GcObject { /// [spec]: https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-setprototypeof-v /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf #[inline] - pub fn __set_prototype_of__(&mut self, val: Value) -> bool { + pub fn __set_prototype_of__(&mut self, val: JsValue) -> bool { debug_assert!(val.is_object() || val.is_null()); let current = self.__get_prototype_of__(); - if Value::same_value(¤t, &val) { + if JsValue::same_value(¤t, &val) { return true; } if !self.__is_extensible__() { @@ -738,7 +738,7 @@ impl GcObject { while !done { if p.is_null() { done = true - } else if Value::same_value(&Value::from(self.clone()), &p) { + } else if JsValue::same_value(&JsValue::new(self.clone()), &p) { return false; } else { let prototype = p @@ -762,7 +762,7 @@ impl GcObject { /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf #[inline] #[track_caller] - pub fn __get_prototype_of__(&self) -> Value { + pub fn __get_prototype_of__(&self) -> JsValue { self.borrow().prototype.clone() } @@ -837,7 +837,7 @@ impl GcObject { &self, element_types: &[Type], context: &mut Context, - ) -> Result> { + ) -> Result> { // 1. If elementTypes is not present, set elementTypes to ยซ Undefined, Null, Boolean, String, Symbol, Number, BigInt, Object ยป. let types = if element_types.is_empty() { &[ diff --git a/boa/src/object/mod.rs b/boa/src/object/mod.rs index 15bb613765..2c2e21c006 100644 --- a/boa/src/object/mod.rs +++ b/boa/src/object/mod.rs @@ -15,7 +15,7 @@ use crate::{ context::StandardConstructor, gc::{Finalize, Trace}, property::{Attribute, PropertyDescriptor, PropertyKey}, - BoaProfiler, Context, JsBigInt, JsString, JsSymbol, Value, + BoaProfiler, Context, JsBigInt, JsString, JsSymbol, JsValue, }; use std::{ any::Any, @@ -68,7 +68,7 @@ pub struct Object { pub data: ObjectData, properties: PropertyMap, /// Instance prototype `__proto__`. - prototype: Value, + prototype: JsValue, /// Whether it can have new properties added to it. extensible: bool, } @@ -78,7 +78,7 @@ pub struct Object { pub enum ObjectData { Array, ArrayIterator(ArrayIterator), - Map(OrderedMap), + Map(OrderedMap), MapIterator(MapIterator), RegExp(Box), RegExpStringIterator(RegExpStringIterator), @@ -86,7 +86,7 @@ pub enum ObjectData { Boolean(bool), ForInIterator(ForInIterator), Function(Function), - Set(OrderedSet), + Set(OrderedSet), SetIterator(SetIterator), String(JsString), StringIterator(StringIterator), @@ -138,7 +138,7 @@ impl Default for Object { Self { data: ObjectData::Ordinary, properties: PropertyMap::default(), - prototype: Value::null(), + prototype: JsValue::null(), extensible: true, } } @@ -152,7 +152,7 @@ impl Object { /// Return a new ObjectData struct, with `kind` set to Ordinary #[inline] - pub fn function(function: Function, prototype: Value) -> Self { + pub fn function(function: Function, prototype: JsValue) -> Self { let _timer = BoaProfiler::global().start_event("Object::Function", "object"); Self { @@ -171,7 +171,7 @@ impl Object { /// [spec]: https://tc39.es/ecma262/#sec-objectcreate // TODO: proto should be a &Value here #[inline] - pub fn create(proto: Value) -> Self { + pub fn create(proto: JsValue) -> Self { let mut obj = Self::new(); obj.prototype = proto; obj @@ -183,7 +183,7 @@ impl Object { Self { data: ObjectData::Boolean(value), properties: PropertyMap::default(), - prototype: Value::null(), + prototype: JsValue::null(), extensible: true, } } @@ -194,7 +194,7 @@ impl Object { Self { data: ObjectData::Number(value), properties: PropertyMap::default(), - prototype: Value::null(), + prototype: JsValue::null(), extensible: true, } } @@ -208,7 +208,7 @@ impl Object { Self { data: ObjectData::String(value.into()), properties: PropertyMap::default(), - prototype: Value::null(), + prototype: JsValue::null(), extensible: true, } } @@ -219,7 +219,7 @@ impl Object { Self { data: ObjectData::BigInt(value), properties: PropertyMap::default(), - prototype: Value::null(), + prototype: JsValue::null(), extensible: true, } } @@ -233,7 +233,7 @@ impl Object { Self { data: ObjectData::NativeObject(Box::new(value)), properties: PropertyMap::default(), - prototype: Value::null(), + prototype: JsValue::null(), extensible: true, } } @@ -335,7 +335,7 @@ impl Object { } #[inline] - pub fn as_map_ref(&self) -> Option<&OrderedMap> { + pub fn as_map_ref(&self) -> Option<&OrderedMap> { match self.data { ObjectData::Map(ref map) => Some(map), _ => None, @@ -343,7 +343,7 @@ impl Object { } #[inline] - pub fn as_map_mut(&mut self) -> Option<&mut OrderedMap> { + pub fn as_map_mut(&mut self) -> Option<&mut OrderedMap> { match &mut self.data { ObjectData::Map(map) => Some(map), _ => None, @@ -364,7 +364,7 @@ impl Object { } #[inline] - pub fn as_set_ref(&self) -> Option<&OrderedSet> { + pub fn as_set_ref(&self) -> Option<&OrderedSet> { match self.data { ObjectData::Set(ref set) => Some(set), _ => None, @@ -372,7 +372,7 @@ impl Object { } #[inline] - pub fn as_set_mut(&mut self) -> Option<&mut OrderedSet> { + pub fn as_set_mut(&mut self) -> Option<&mut OrderedSet> { match &mut self.data { ObjectData::Set(set) => Some(set), _ => None, @@ -506,7 +506,7 @@ impl Object { } #[inline] - pub fn prototype_instance(&self) -> &Value { + pub fn prototype_instance(&self) -> &JsValue { &self.prototype } @@ -517,7 +517,7 @@ impl Object { /// [spec]: https://tc39.es/ecma262/#sec-invariants-of-the-essential-internal-methods #[inline] #[track_caller] - pub fn set_prototype_instance(&mut self, prototype: Value) -> bool { + pub fn set_prototype_instance(&mut self, prototype: JsValue) -> bool { assert!(prototype.is_null() || prototype.is_object()); if self.extensible { self.prototype = prototype; @@ -525,13 +525,13 @@ impl Object { } else { // If target is non-extensible, [[SetPrototypeOf]] must return false // unless V is the SameValue as the target's observed [[GetPrototypeOf]] value. - Value::same_value(&prototype, &self.prototype) + JsValue::same_value(&prototype, &self.prototype) } } /// Similar to `Value::new_object`, but you can pass a prototype to create from, plus a kind #[inline] - pub fn with_prototype(proto: Value, data: ObjectData) -> Object { + pub fn with_prototype(proto: JsValue, data: ObjectData) -> Object { let mut object = Object::new(); object.data = data; object.set_prototype_instance(proto); @@ -693,7 +693,7 @@ impl<'context> FunctionBuilder<'context> { #[inline] pub fn closure(context: &'context mut Context, function: F) -> Self where - F: Fn(&Value, &[Value], &mut Context) -> Result + 'static, + F: Fn(&JsValue, &[JsValue], &mut Context) -> Result + 'static, { Self { context, @@ -789,7 +789,7 @@ impl<'context> FunctionBuilder<'context> { /// # Examples /// /// ``` -/// # use boa::{Context, Value, object::ObjectInitializer, property::Attribute}; +/// # use boa::{Context, JsValue, object::ObjectInitializer, property::Attribute}; /// let mut context = Context::new(); /// let object = ObjectInitializer::new(&mut context) /// .property( @@ -802,7 +802,7 @@ impl<'context> FunctionBuilder<'context> { /// 1, /// Attribute::all() /// ) -/// .function(|_, _, _| Ok(Value::undefined()), "func", 0) +/// .function(|_, _, _| Ok(JsValue::undefined()), "func", 0) /// .build(); /// ``` /// @@ -857,7 +857,7 @@ impl<'context> ObjectInitializer<'context> { pub fn property(&mut self, key: K, value: V, attribute: Attribute) -> &mut Self where K: Into, - V: Into, + V: Into, { let property = PropertyDescriptor::builder() .value(value) @@ -885,7 +885,7 @@ pub struct ConstructorBuilder<'context> { length: usize, callable: bool, constructable: bool, - inherit: Option, + inherit: Option, } impl Debug for ConstructorBuilder<'_> { @@ -996,7 +996,7 @@ impl<'context> ConstructorBuilder<'context> { pub fn property(&mut self, key: K, value: V, attribute: Attribute) -> &mut Self where K: Into, - V: Into, + V: Into, { let property = PropertyDescriptor::builder() .value(value) @@ -1012,7 +1012,7 @@ impl<'context> ConstructorBuilder<'context> { pub fn static_property(&mut self, key: K, value: V, attribute: Attribute) -> &mut Self where K: Into, - V: Into, + V: Into, { let property = PropertyDescriptor::builder() .value(value) @@ -1132,7 +1132,7 @@ impl<'context> ConstructorBuilder<'context> { /// /// Default is `Object.prototype` #[inline] - pub fn inherit(&mut self, prototype: Value) -> &mut Self { + pub fn inherit(&mut self, prototype: JsValue) -> &mut Self { assert!(prototype.is_object() || prototype.is_null()); self.inherit = Some(prototype); self diff --git a/boa/src/property/mod.rs b/boa/src/property/mod.rs index a8943236c7..74fc599084 100644 --- a/boa/src/property/mod.rs +++ b/boa/src/property/mod.rs @@ -16,7 +16,7 @@ use crate::{ gc::{Finalize, Trace}, - JsString, JsSymbol, Value, + JsString, JsSymbol, JsValue, }; use std::{convert::TryFrom, fmt}; @@ -55,12 +55,12 @@ pub struct PropertyDescriptor { #[derive(Debug, Clone, Trace, Finalize)] pub enum DescriptorKind { Data { - value: Option, + value: Option, writable: Option, }, Accessor { - get: Option, - set: Option, + get: Option, + set: Option, }, Generic, } @@ -129,7 +129,7 @@ impl PropertyDescriptor { } #[inline] - pub fn value(&self) -> Option<&Value> { + pub fn value(&self) -> Option<&JsValue> { match &self.kind { DescriptorKind::Data { value, .. } => value.as_ref(), _ => None, @@ -137,7 +137,7 @@ impl PropertyDescriptor { } #[inline] - pub fn get(&self) -> Option<&Value> { + pub fn get(&self) -> Option<&JsValue> { match &self.kind { DescriptorKind::Accessor { get, .. } => get.as_ref(), _ => None, @@ -145,7 +145,7 @@ impl PropertyDescriptor { } #[inline] - pub fn set(&self) -> Option<&Value> { + pub fn set(&self) -> Option<&JsValue> { match &self.kind { DescriptorKind::Accessor { set, .. } => set.as_ref(), _ => None, @@ -180,7 +180,7 @@ impl PropertyDescriptor { } #[inline] - pub fn expect_value(&self) -> &Value { + pub fn expect_value(&self) -> &JsValue { if let Some(value) = self.value() { value } else { @@ -189,7 +189,7 @@ impl PropertyDescriptor { } #[inline] - pub fn expect_get(&self) -> &Value { + pub fn expect_get(&self) -> &JsValue { if let Some(get) = self.get() { get } else { @@ -198,7 +198,7 @@ impl PropertyDescriptor { } #[inline] - pub fn expect_set(&self) -> &Value { + pub fn expect_set(&self) -> &JsValue { if let Some(set) = self.set() { set } else { @@ -298,7 +298,7 @@ impl PropertyDescriptorBuilder { Self::default() } - pub fn value>(mut self, value: V) -> Self { + pub fn value>(mut self, value: V) -> Self { match self.inner.kind { DescriptorKind::Data { value: ref mut v, .. @@ -331,7 +331,7 @@ impl PropertyDescriptorBuilder { self } - pub fn get>(mut self, get: V) -> Self { + pub fn get>(mut self, get: V) -> Self { match self.inner.kind { DescriptorKind::Accessor { get: ref mut g, .. } => *g = Some(get.into()), // TODO: maybe panic when trying to convert data to accessor? @@ -345,7 +345,7 @@ impl PropertyDescriptorBuilder { self } - pub fn set>(mut self, set: V) -> Self { + pub fn set>(mut self, set: V) -> Self { match self.inner.kind { DescriptorKind::Accessor { set: ref mut s, .. } => *s = Some(set.into()), // TODO: maybe panic when trying to convert data to accessor? @@ -373,7 +373,7 @@ impl PropertyDescriptorBuilder { self } - pub fn maybe_value>(mut self, value: Option) -> Self { + pub fn maybe_value>(mut self, value: Option) -> Self { if let Some(value) = value { self = self.value(value); } @@ -387,14 +387,14 @@ impl PropertyDescriptorBuilder { self } - pub fn maybe_get>(mut self, get: Option) -> Self { + pub fn maybe_get>(mut self, get: Option) -> Self { if let Some(get) = get { self = self.get(get); } self } - pub fn maybe_set>(mut self, set: Option) -> Self { + pub fn maybe_set>(mut self, set: Option) -> Self { if let Some(set) = set { self = self.set(set); } @@ -414,7 +414,7 @@ impl PropertyDescriptorBuilder { match self.inner.kind { DescriptorKind::Generic => { self.inner.kind = DescriptorKind::Data { - value: Some(Value::undefined()), + value: Some(JsValue::undefined()), writable: Some(false), } } @@ -423,7 +423,7 @@ impl PropertyDescriptorBuilder { ref mut writable, } => { if value.is_none() { - *value = Some(Value::undefined()) + *value = Some(JsValue::undefined()) } if writable.is_none() { *writable = Some(false) @@ -434,10 +434,10 @@ impl PropertyDescriptorBuilder { ref mut get, } => { if set.is_none() { - *set = Some(Value::undefined()) + *set = Some(JsValue::undefined()) } if get.is_none() { - *get = Some(Value::undefined()) + *get = Some(JsValue::undefined()) } } } @@ -541,34 +541,34 @@ impl fmt::Display for PropertyKey { } } -impl From<&PropertyKey> for Value { +impl From<&PropertyKey> for JsValue { #[inline] - fn from(property_key: &PropertyKey) -> Value { + fn from(property_key: &PropertyKey) -> JsValue { match property_key { PropertyKey::String(ref string) => string.clone().into(), PropertyKey::Symbol(ref symbol) => symbol.clone().into(), PropertyKey::Index(index) => { if let Ok(integer) = i32::try_from(*index) { - Value::integer(integer) + JsValue::new(integer) } else { - Value::number(*index) + JsValue::new(*index) } } } } } -impl From for Value { +impl From for JsValue { #[inline] - fn from(property_key: PropertyKey) -> Value { + fn from(property_key: PropertyKey) -> JsValue { match property_key { PropertyKey::String(ref string) => string.clone().into(), PropertyKey::Symbol(ref symbol) => symbol.clone().into(), PropertyKey::Index(index) => { if let Ok(integer) = i32::try_from(index) { - Value::integer(integer) + JsValue::new(integer) } else { - Value::number(index) + JsValue::new(index) } } } diff --git a/boa/src/syntax/ast/node/array/mod.rs b/boa/src/syntax/ast/node/array/mod.rs index d9ce793584..7ea413db3a 100644 --- a/boa/src/syntax/ast/node/array/mod.rs +++ b/boa/src/syntax/ast/node/array/mod.rs @@ -5,7 +5,7 @@ use crate::{ builtins::{iterable, Array}, exec::Executable, gc::{Finalize, Trace}, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; use std::fmt; @@ -39,7 +39,7 @@ pub struct ArrayDecl { } impl Executable for ArrayDecl { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("ArrayDecl", "exec"); let array = Array::new_array(context); let mut elements = Vec::new(); diff --git a/boa/src/syntax/ast/node/await_expr/mod.rs b/boa/src/syntax/ast/node/await_expr/mod.rs index ab1291f18e..d5f8faa35f 100644 --- a/boa/src/syntax/ast/node/await_expr/mod.rs +++ b/boa/src/syntax/ast/node/await_expr/mod.rs @@ -1,7 +1,7 @@ //! Await expression node. use super::Node; -use crate::{exec::Executable, BoaProfiler, Context, Result, Value}; +use crate::{exec::Executable, BoaProfiler, Context, JsValue, Result}; use gc::{Finalize, Trace}; use std::fmt; @@ -27,10 +27,10 @@ pub struct AwaitExpr { } impl Executable for AwaitExpr { - fn run(&self, _: &mut Context) -> Result { + fn run(&self, _: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("AwaitExpression", "exec"); // TODO: Implement AwaitExpr - Ok(Value::Undefined) + Ok(JsValue::undefined()) } } diff --git a/boa/src/syntax/ast/node/block/mod.rs b/boa/src/syntax/ast/node/block/mod.rs index 9be978f325..838ec3c451 100644 --- a/boa/src/syntax/ast/node/block/mod.rs +++ b/boa/src/syntax/ast/node/block/mod.rs @@ -6,7 +6,7 @@ use crate::{ exec::Executable, exec::InterpreterState, gc::{Finalize, Trace}, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; use std::fmt; @@ -54,7 +54,7 @@ impl Block { } impl Executable for Block { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("Block", "exec"); { let env = context.get_current_environment(); @@ -63,7 +63,7 @@ impl Executable for Block { // 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(); + let mut obj = JsValue::default(); for statement in self.items() { obj = statement.run(context).map_err(|e| { // No matter how control leaves the Block the LexicalEnvironment is always diff --git a/boa/src/syntax/ast/node/break_node/mod.rs b/boa/src/syntax/ast/node/break_node/mod.rs index 48b6108f78..49903ca881 100644 --- a/boa/src/syntax/ast/node/break_node/mod.rs +++ b/boa/src/syntax/ast/node/break_node/mod.rs @@ -3,7 +3,7 @@ use crate::{ exec::Executable, exec::InterpreterState, gc::{Finalize, Trace}, - Context, Result, Value, + Context, JsValue, Result, }; use std::fmt; @@ -52,12 +52,12 @@ impl Break { } impl Executable for Break { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { context .executor() .set_current_state(InterpreterState::Break(self.label().map(Box::from))); - Ok(Value::undefined()) + Ok(JsValue::undefined()) } } diff --git a/boa/src/syntax/ast/node/call/mod.rs b/boa/src/syntax/ast/node/call/mod.rs index da895cf712..40ec7f6a91 100644 --- a/boa/src/syntax/ast/node/call/mod.rs +++ b/boa/src/syntax/ast/node/call/mod.rs @@ -4,8 +4,7 @@ use crate::{ exec::InterpreterState, gc::{Finalize, Trace}, syntax::ast::node::{join_nodes, Node}, - value::Value, - BoaProfiler, Context, Result, + BoaProfiler, Context, JsValue, Result, }; use std::fmt; @@ -61,13 +60,13 @@ impl Call { } impl Executable for Call { - fn run(&self, context: &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(context)?; if !obj.is_object() { - obj = Value::Object(obj.to_object(context)?); + obj = JsValue::Object(obj.to_object(context)?); } ( obj.clone(), @@ -77,7 +76,7 @@ impl Executable for Call { Node::GetField(ref get_field) => { let mut obj = get_field.obj().run(context)?; if !obj.is_object() { - obj = Value::Object(obj.to_object(context)?); + obj = JsValue::Object(obj.to_object(context)?); } let field = get_field.field().run(context)?; ( 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 f6c07f14e7..d69667c9c0 100644 --- a/boa/src/syntax/ast/node/conditional/conditional_op/mod.rs +++ b/boa/src/syntax/ast/node/conditional/conditional_op/mod.rs @@ -2,7 +2,7 @@ use crate::{ exec::Executable, gc::{Finalize, Trace}, syntax::ast::node::Node, - Context, Result, Value, + Context, JsValue, Result, }; use std::fmt; @@ -60,7 +60,7 @@ impl ConditionalOp { } impl Executable for ConditionalOp { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { Ok(if self.cond().run(context)?.to_boolean() { self.if_true().run(context)? } else { 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 a38de0b4da..45009466ab 100644 --- a/boa/src/syntax/ast/node/conditional/if_node/mod.rs +++ b/boa/src/syntax/ast/node/conditional/if_node/mod.rs @@ -2,7 +2,7 @@ use crate::{ exec::Executable, gc::{Finalize, Trace}, syntax::ast::node::Node, - Context, Result, Value, + Context, JsValue, Result, }; use std::fmt; @@ -79,13 +79,13 @@ impl If { } impl Executable for If { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { Ok(if self.cond().run(context)?.to_boolean() { self.body().run(context)? } else if let Some(else_e) = self.else_node() { else_e.run(context)? } else { - Value::undefined() + JsValue::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 162646f4e4..4d0f3443f8 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 @@ -3,7 +3,7 @@ use crate::{ exec::Executable, gc::{Finalize, Trace}, syntax::ast::node::{join_nodes, FormalParameter, Node, StatementList}, - Context, Result, Value, + Context, JsValue, Result, }; use std::fmt; @@ -72,7 +72,7 @@ impl ArrowFunctionDecl { } impl Executable for ArrowFunctionDecl { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { context.create_function( "", self.params().to_vec(), diff --git a/boa/src/syntax/ast/node/declaration/async_function_decl/mod.rs b/boa/src/syntax/ast/node/declaration/async_function_decl/mod.rs index 8416843de5..f567da8900 100644 --- a/boa/src/syntax/ast/node/declaration/async_function_decl/mod.rs +++ b/boa/src/syntax/ast/node/declaration/async_function_decl/mod.rs @@ -3,7 +3,7 @@ use crate::{ exec::Executable, syntax::ast::node::{join_nodes, FormalParameter, Node, StatementList}, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; use gc::{Finalize, Trace}; use std::fmt; @@ -79,10 +79,10 @@ impl AsyncFunctionDecl { } impl Executable for AsyncFunctionDecl { - fn run(&self, _: &mut Context) -> Result { + fn run(&self, _: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("AsyncFunctionDecl", "exec"); // TODO: Implement AsyncFunctionDecl - Ok(Value::undefined()) + Ok(JsValue::undefined()) } } diff --git a/boa/src/syntax/ast/node/declaration/async_function_expr/mod.rs b/boa/src/syntax/ast/node/declaration/async_function_expr/mod.rs index 2bc9dd3ccc..a4057c61f4 100644 --- a/boa/src/syntax/ast/node/declaration/async_function_expr/mod.rs +++ b/boa/src/syntax/ast/node/declaration/async_function_expr/mod.rs @@ -3,7 +3,7 @@ use crate::{ exec::Executable, syntax::ast::node::{join_nodes, FormalParameter, Node, StatementList}, - Context, Result, Value, + Context, JsValue, Result, }; use gc::{Finalize, Trace}; use std::fmt; @@ -81,9 +81,9 @@ impl AsyncFunctionExpr { } impl Executable for AsyncFunctionExpr { - fn run(&self, _: &mut Context) -> Result { + fn run(&self, _: &mut Context) -> Result { // TODO: Implement AsyncFunctionExpr - Ok(Value::Undefined) + Ok(JsValue::undefined()) } } 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 792980cb6c..680e232c99 100644 --- a/boa/src/syntax/ast/node/declaration/function_decl/mod.rs +++ b/boa/src/syntax/ast/node/declaration/function_decl/mod.rs @@ -4,7 +4,7 @@ use crate::{ exec::Executable, gc::{Finalize, Trace}, syntax::ast::node::{join_nodes, FormalParameter, Node, StatementList}, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; use std::fmt; @@ -86,7 +86,7 @@ impl FunctionDecl { } impl Executable for FunctionDecl { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("FunctionDecl", "exec"); let val = context.create_function( self.name(), @@ -106,7 +106,7 @@ impl Executable for FunctionDecl { context.initialize_binding(self.name(), val)?; } - Ok(Value::undefined()) + Ok(JsValue::undefined()) } } 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 29e83062f0..bd149b3712 100644 --- a/boa/src/syntax/ast/node/declaration/function_expr/mod.rs +++ b/boa/src/syntax/ast/node/declaration/function_expr/mod.rs @@ -3,7 +3,7 @@ use crate::{ exec::Executable, gc::{Finalize, Trace}, syntax::ast::node::{join_nodes, FormalParameter, Node, StatementList}, - Context, Result, Value, + Context, JsValue, Result, }; use std::fmt; @@ -98,7 +98,7 @@ impl FunctionExpr { } impl Executable for FunctionExpr { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let val = context.create_function( self.name().unwrap_or(""), self.parameters().to_vec(), diff --git a/boa/src/syntax/ast/node/declaration/mod.rs b/boa/src/syntax/ast/node/declaration/mod.rs index 4f375ceb6d..b036a22a56 100644 --- a/boa/src/syntax/ast/node/declaration/mod.rs +++ b/boa/src/syntax/ast/node/declaration/mod.rs @@ -4,7 +4,7 @@ use crate::{ exec::Executable, gc::{Finalize, Trace}, syntax::ast::node::{join_nodes, Identifier, Node}, - Context, Result, Value, + Context, JsValue, Result, }; use std::fmt; @@ -90,7 +90,7 @@ pub enum DeclarationList { } impl Executable for DeclarationList { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { for decl in self.as_ref() { use DeclarationList::*; let val = match decl.init() { @@ -98,7 +98,7 @@ impl Executable for DeclarationList { return context.throw_syntax_error("missing = in const declaration") } Some(init) => init.run(context)?, - None => Value::undefined(), + None => JsValue::undefined(), }; if self.is_var() && context.has_binding(decl.name()) { @@ -129,7 +129,7 @@ impl Executable for DeclarationList { context.initialize_binding(decl.name(), val)?; } - Ok(Value::undefined()) + Ok(JsValue::undefined()) } } 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 55e5c9574d..4d1adcff7e 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 @@ -2,8 +2,7 @@ use crate::{ exec::Executable, gc::{Finalize, Trace}, syntax::ast::node::Node, - value::Value, - Context, Result, + Context, JsValue, Result, }; use std::fmt; @@ -63,10 +62,10 @@ impl GetConstField { } impl Executable for GetConstField { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let mut obj = self.obj().run(context)?; if !obj.is_object() { - obj = Value::Object(obj.to_object(context)?); + obj = JsValue::Object(obj.to_object(context)?); } obj.get_field(self.field(), context) 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 8b2963d957..a6f42bfdb9 100644 --- a/boa/src/syntax/ast/node/field/get_field/mod.rs +++ b/boa/src/syntax/ast/node/field/get_field/mod.rs @@ -2,8 +2,7 @@ use crate::{ exec::Executable, gc::{Finalize, Trace}, syntax::ast::node::Node, - value::Value, - Context, Result, + Context, JsValue, Result, }; use std::fmt; @@ -62,10 +61,10 @@ impl GetField { } impl Executable for GetField { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let mut obj = self.obj().run(context)?; if !obj.is_object() { - obj = Value::Object(obj.to_object(context)?); + obj = JsValue::Object(obj.to_object(context)?); } let field = self.field().run(context)?; diff --git a/boa/src/syntax/ast/node/identifier/mod.rs b/boa/src/syntax/ast/node/identifier/mod.rs index 0a1442c37d..48d127cae5 100644 --- a/boa/src/syntax/ast/node/identifier/mod.rs +++ b/boa/src/syntax/ast/node/identifier/mod.rs @@ -4,7 +4,7 @@ use crate::{ exec::Executable, gc::{Finalize, Trace}, syntax::ast::node::Node, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; use std::fmt; @@ -34,7 +34,7 @@ pub struct Identifier { } impl Executable for Identifier { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("Identifier", "exec"); context.get_binding_value(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 9322d48310..80c63bfbc0 100644 --- a/boa/src/syntax/ast/node/iteration/continue_node/mod.rs +++ b/boa/src/syntax/ast/node/iteration/continue_node/mod.rs @@ -2,7 +2,7 @@ use crate::{ exec::{Executable, InterpreterState}, gc::{Finalize, Trace}, syntax::ast::node::Node, - Context, Result, Value, + Context, JsValue, Result, }; use std::fmt; @@ -46,12 +46,12 @@ impl Continue { } impl Executable for Continue { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { context .executor() .set_current_state(InterpreterState::Continue(self.label().map(Box::from))); - Ok(Value::undefined()) + Ok(JsValue::undefined()) } } 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 646f1c4413..76cc11d045 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 @@ -2,7 +2,7 @@ use crate::{ exec::{Executable, InterpreterState}, gc::{Finalize, Trace}, syntax::ast::node::Node, - Context, Result, Value, + Context, JsValue, Result, }; use std::fmt; @@ -74,7 +74,7 @@ impl DoWhileLoop { } impl Executable for DoWhileLoop { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let mut result; loop { result = self.body().run(context)?; diff --git a/boa/src/syntax/ast/node/iteration/for_in_loop/mod.rs b/boa/src/syntax/ast/node/iteration/for_in_loop/mod.rs index d1a3e8ab00..b8f14c866b 100644 --- a/boa/src/syntax/ast/node/iteration/for_in_loop/mod.rs +++ b/boa/src/syntax/ast/node/iteration/for_in_loop/mod.rs @@ -7,7 +7,7 @@ use crate::{ exec::{Executable, InterpreterState}, gc::{Finalize, Trace}, syntax::ast::node::Node, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; use std::fmt; @@ -80,16 +80,16 @@ impl From for Node { } impl Executable for ForInLoop { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("ForIn", "exec"); let object = self.expr().run(context)?; - let mut result = Value::undefined(); + let mut result = JsValue::undefined(); if object.is_null_or_undefined() { return Ok(result); } let object = object.to_object(context)?; - let for_in_iterator = ForInIterator::create_for_in_iterator(context, Value::from(object)); + let for_in_iterator = ForInIterator::create_for_in_iterator(context, JsValue::new(object)); let next_function = for_in_iterator .get_property("next") .as_ref() 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 1b02833c1e..4788363d8a 100644 --- a/boa/src/syntax/ast/node/iteration/for_loop/mod.rs +++ b/boa/src/syntax/ast/node/iteration/for_loop/mod.rs @@ -3,7 +3,7 @@ use crate::{ exec::{Executable, InterpreterState}, gc::{Finalize, Trace}, syntax::ast::node::Node, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; use std::fmt; @@ -98,7 +98,7 @@ impl ForLoop { } impl Executable for ForLoop { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { // Create the block environment. let _timer = BoaProfiler::global().start_event("ForLoop", "exec"); { @@ -143,7 +143,7 @@ impl Executable for ForLoop { // pop the block env let _ = context.pop_environment(); - Ok(Value::undefined()) + Ok(JsValue::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 e5a640305f..aa507adbbf 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 @@ -7,7 +7,7 @@ use crate::{ exec::{Executable, InterpreterState}, gc::{Finalize, Trace}, syntax::ast::node::Node, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; use std::fmt; @@ -80,11 +80,11 @@ impl From for Node { } impl Executable for ForOfLoop { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("ForOf", "exec"); let iterable = self.iterable().run(context)?; let iterator = get_iterator(context, iterable)?; - let mut result = Value::undefined(); + let mut result = JsValue::undefined(); loop { { 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 c5daed590d..00b076a083 100644 --- a/boa/src/syntax/ast/node/iteration/while_loop/mod.rs +++ b/boa/src/syntax/ast/node/iteration/while_loop/mod.rs @@ -2,7 +2,7 @@ use crate::{ exec::{Executable, InterpreterState}, gc::{Finalize, Trace}, syntax::ast::node::Node, - Context, Result, Value, + Context, JsValue, Result, }; use std::fmt; @@ -72,8 +72,8 @@ impl WhileLoop { } impl Executable for WhileLoop { - fn run(&self, context: &mut Context) -> Result { - let mut result = Value::undefined(); + fn run(&self, context: &mut Context) -> Result { + let mut result = JsValue::undefined(); while self.cond().run(context)?.to_boolean() { result = self.body().run(context)?; match context.executor().get_current_state() { diff --git a/boa/src/syntax/ast/node/mod.rs b/boa/src/syntax/ast/node/mod.rs index 94eeece1ab..1745bdee4f 100644 --- a/boa/src/syntax/ast/node/mod.rs +++ b/boa/src/syntax/ast/node/mod.rs @@ -50,7 +50,7 @@ use super::Const; use crate::{ exec::Executable, gc::{empty_trace, Finalize, Trace}, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; use std::{ cmp::Ordering, @@ -307,23 +307,23 @@ impl Node { } impl Executable for Node { - fn run(&self, context: &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(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)), - Node::Const(Const::BigInt(ref num)) => Ok(Value::from(num.clone())), - Node::Const(Const::Undefined) => Ok(Value::Undefined), + Node::Const(Const::Null) => Ok(JsValue::null()), + Node::Const(Const::Num(num)) => Ok(JsValue::new(num)), + Node::Const(Const::Int(num)) => Ok(JsValue::new(num)), + Node::Const(Const::BigInt(ref num)) => Ok(JsValue::new(num.clone())), + Node::Const(Const::Undefined) => Ok(JsValue::undefined()), // we can't move String from Const into value, because const is a garbage collected value // Which means Drop() get's called on Const, but str will be gone at that point. // 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::Const(Const::String(ref value)) => Ok(JsValue::new(value.to_string())), + Node::Const(Const::Bool(value)) => Ok(JsValue::new(value)), 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), @@ -362,7 +362,7 @@ impl Executable for Node { 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), - Node::Empty => Ok(Value::Undefined), + Node::Empty => Ok(JsValue::undefined()), } } } diff --git a/boa/src/syntax/ast/node/new/mod.rs b/boa/src/syntax/ast/node/new/mod.rs index 48603ee8e5..c409e38692 100644 --- a/boa/src/syntax/ast/node/new/mod.rs +++ b/boa/src/syntax/ast/node/new/mod.rs @@ -3,7 +3,7 @@ use crate::{ exec::Executable, gc::{Finalize, Trace}, syntax::ast::node::{Call, Node}, - value::Value, + value::JsValue, BoaProfiler, Context, Result, }; use std::fmt; @@ -48,7 +48,7 @@ impl New { } impl Executable for New { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("New", "exec"); let func_object = self.expr().run(context)?; @@ -72,7 +72,9 @@ impl Executable for New { } match func_object { - Value::Object(ref object) => object.construct(&v_args, &object.clone().into(), context), + JsValue::Object(ref object) => { + object.construct(&v_args, &object.clone().into(), 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 5cc1f8a29e..8a060fd71b 100644 --- a/boa/src/syntax/ast/node/object/mod.rs +++ b/boa/src/syntax/ast/node/object/mod.rs @@ -5,7 +5,7 @@ use crate::{ gc::{Finalize, Trace}, property::PropertyDescriptor, syntax::ast::node::{join_nodes, MethodDefinitionKind, Node, PropertyDefinition}, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; use std::fmt; @@ -87,9 +87,9 @@ impl Object { } impl Executable for Object { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("object", "exec"); - let obj = Value::new_object(context); + let obj = JsValue::new_object(context); // TODO: Implement the rest of the property types. for property in self.properties().iter() { diff --git a/boa/src/syntax/ast/node/operator/assign/mod.rs b/boa/src/syntax/ast/node/operator/assign/mod.rs index 9e8e30327a..17e06e9cc6 100644 --- a/boa/src/syntax/ast/node/operator/assign/mod.rs +++ b/boa/src/syntax/ast/node/operator/assign/mod.rs @@ -3,7 +3,7 @@ use crate::{ exec::Executable, gc::{Finalize, Trace}, syntax::ast::node::Node, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; use std::fmt; @@ -53,7 +53,7 @@ impl Assign { } impl Executable for Assign { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("Assign", "exec"); let val = self.rhs().run(context)?; match self.lhs() { 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 c23623231d..144b0e997e 100644 --- a/boa/src/syntax/ast/node/operator/bin_op/mod.rs +++ b/boa/src/syntax/ast/node/operator/bin_op/mod.rs @@ -6,7 +6,7 @@ use crate::{ node::Node, op::{self, AssignOp, BitOp, CompOp, LogOp, NumOp}, }, - Context, Result, Value, + Context, JsValue, Result, }; use std::fmt; @@ -58,7 +58,7 @@ impl BinOp { } /// Runs the assignment operators. - fn run_assign(op: AssignOp, x: Value, y: &Node, context: &mut Context) -> Result { + fn run_assign(op: AssignOp, x: JsValue, y: &Node, context: &mut Context) -> Result { match op { AssignOp::Add => x.add(&y.run(context)?, context), AssignOp::Sub => x.sub(&y.run(context)?, context), @@ -98,7 +98,7 @@ impl BinOp { } impl Executable for BinOp { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { match self.op() { op::BinOp::Num(op) => { let x = self.lhs().run(context)?; @@ -127,7 +127,7 @@ impl Executable for BinOp { op::BinOp::Comp(op) => { let x = self.lhs().run(context)?; let y = self.rhs().run(context)?; - Ok(Value::from(match op { + Ok(JsValue::new(match op { CompOp::Equal => x.equals(&y, context)?, CompOp::NotEqual => !x.equals(&y, context)?, CompOp::StrictEqual => x.strict_equals(&y), @@ -213,7 +213,7 @@ impl Executable for BinOp { v_r_a.set_field(get_const_field.field(), value.clone(), false, context)?; Ok(value) } - _ => Ok(Value::undefined()), + _ => Ok(JsValue::undefined()), }, op::BinOp::Comma => { self.lhs().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 896f8e0495..26f75e89ab 100644 --- a/boa/src/syntax/ast/node/operator/unary_op/mod.rs +++ b/boa/src/syntax/ast/node/operator/unary_op/mod.rs @@ -2,7 +2,7 @@ use crate::{ exec::Executable, gc::{Finalize, Trace}, syntax::ast::{node::Node, op}, - Context, JsBigInt, Result, Value, + Context, JsBigInt, JsValue, Result, }; use std::fmt; @@ -50,10 +50,10 @@ impl UnaryOp { } impl Executable for UnaryOp { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { Ok(match self.op() { op::UnaryOp::Minus => self.target().run(context)?.neg(context)?, - op::UnaryOp::Plus => Value::from(self.target().run(context)?.to_number(context)?), + op::UnaryOp::Plus => JsValue::new(self.target().run(context)?.to_number(context)?), op::UnaryOp::IncrementPost => { let x = self.target().run(context)?; let ret = x.clone(); @@ -81,16 +81,16 @@ impl Executable for UnaryOp { let expr = self.target().run(context)?; let old_v = expr.to_numeric(context)?; match old_v { - Numeric::Number(x) => Value::from(Number::not(x)), - Numeric::BigInt(x) => Value::from(JsBigInt::not(&x)), + Numeric::Number(x) => JsValue::new(Number::not(x)), + Numeric::BigInt(x) => JsValue::new(JsBigInt::not(&x)), } } op::UnaryOp::Void => { self.target().run(context)?; - Value::undefined() + JsValue::undefined() } op::UnaryOp::Delete => match *self.target() { - Node::GetConstField(ref get_const_field) => Value::boolean( + Node::GetConstField(ref get_const_field) => JsValue::new( get_const_field .obj() .run(context)? @@ -103,9 +103,9 @@ impl Executable for UnaryOp { let res = obj .to_object(context)? .__delete__(&field.to_property_key(context)?); - return Ok(Value::boolean(res)); + return Ok(JsValue::new(res)); } - Node::Identifier(_) => Value::boolean(false), + Node::Identifier(_) => JsValue::new(false), Node::ArrayDecl(_) | Node::Block(_) | Node::Const(_) @@ -113,10 +113,10 @@ impl Executable for UnaryOp { | Node::FunctionExpr(_) | Node::New(_) | Node::Object(_) - | Node::UnaryOp(_) => Value::boolean(true), + | Node::UnaryOp(_) => JsValue::new(true), _ => return context.throw_syntax_error(format!("wrong delete argument {}", self)), }, - op::UnaryOp::TypeOf => Value::from(self.target().run(context)?.type_of()), + op::UnaryOp::TypeOf => JsValue::new(self.target().run(context)?.type_of()), }) } } diff --git a/boa/src/syntax/ast/node/return_smt/mod.rs b/boa/src/syntax/ast/node/return_smt/mod.rs index f22ae4a13f..fff1ddb1a7 100644 --- a/boa/src/syntax/ast/node/return_smt/mod.rs +++ b/boa/src/syntax/ast/node/return_smt/mod.rs @@ -2,7 +2,7 @@ use crate::{ exec::{Executable, InterpreterState}, gc::{Finalize, Trace}, syntax::ast::node::Node, - Context, Result, Value, + Context, JsValue, Result, }; use std::fmt; @@ -61,10 +61,10 @@ impl Return { } impl Executable for Return { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let result = match self.expr() { Some(v) => v.run(context), - None => Ok(Value::undefined()), + None => Ok(JsValue::undefined()), }; // Set flag for return context diff --git a/boa/src/syntax/ast/node/spread/mod.rs b/boa/src/syntax/ast/node/spread/mod.rs index b79292ebab..ae4de96bfb 100644 --- a/boa/src/syntax/ast/node/spread/mod.rs +++ b/boa/src/syntax/ast/node/spread/mod.rs @@ -2,7 +2,7 @@ use crate::{ exec::Executable, gc::{Finalize, Trace}, syntax::ast::node::Node, - Context, Result, Value, + Context, JsValue, Result, }; use std::fmt; @@ -52,7 +52,7 @@ impl Spread { } impl Executable for Spread { - fn run(&self, context: &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(context) } diff --git a/boa/src/syntax/ast/node/statement_list/mod.rs b/boa/src/syntax/ast/node/statement_list/mod.rs index aa3ac43cdc..579a75a934 100644 --- a/boa/src/syntax/ast/node/statement_list/mod.rs +++ b/boa/src/syntax/ast/node/statement_list/mod.rs @@ -4,7 +4,7 @@ use crate::{ exec::{Executable, InterpreterState}, gc::{empty_trace, Finalize, Trace}, syntax::ast::node::Node, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; use std::{collections::HashSet, fmt, ops::Deref, rc::Rc}; @@ -92,12 +92,12 @@ impl StatementList { } impl Executable for StatementList { - fn run(&self, context: &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(); + let mut obj = JsValue::default(); context .executor() .set_current_state(InterpreterState::Executing); diff --git a/boa/src/syntax/ast/node/switch/mod.rs b/boa/src/syntax/ast/node/switch/mod.rs index 18aac25891..3fe3c0ec83 100644 --- a/boa/src/syntax/ast/node/switch/mod.rs +++ b/boa/src/syntax/ast/node/switch/mod.rs @@ -4,7 +4,7 @@ use crate::{ exec::{Executable, InterpreterState}, gc::{Finalize, Trace}, syntax::ast::node::Node, - Context, Result, Value, + Context, JsValue, Result, }; use std::fmt; @@ -123,9 +123,9 @@ impl Switch { } impl Executable for Switch { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let val = self.val().run(context)?; - let mut result = Value::null(); + let mut result = JsValue::null(); let mut matched = false; context .executor() diff --git a/boa/src/syntax/ast/node/template/mod.rs b/boa/src/syntax/ast/node/template/mod.rs index 461b95e50b..633a0822c0 100644 --- a/boa/src/syntax/ast/node/template/mod.rs +++ b/boa/src/syntax/ast/node/template/mod.rs @@ -1,7 +1,7 @@ //! Template literal node. use super::Node; -use crate::{builtins::Array, exec::Executable, BoaProfiler, Context, Result, Value}; +use crate::{builtins::Array, exec::Executable, BoaProfiler, Context, JsValue, Result}; use gc::{Finalize, Trace}; #[cfg(feature = "deser")] @@ -32,7 +32,7 @@ impl TemplateLit { } impl Executable for TemplateLit { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("TemplateLiteral", "exec"); let mut result = String::new(); @@ -90,21 +90,21 @@ impl TaggedTemplate { } impl Executable for TaggedTemplate { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("TaggedTemplate", "exec"); let template_object = Array::new_array(context); let raw_array = Array::new_array(context); for (i, raw) in self.raws.iter().enumerate() { - raw_array.set_field(i, Value::from(raw), false, context)?; + raw_array.set_field(i, JsValue::new(raw.as_ref()), false, context)?; } for (i, cooked) in self.cookeds.iter().enumerate() { if let Some(cooked) = cooked { - template_object.set_field(i, Value::from(cooked), false, context)?; + template_object.set_field(i, JsValue::new(cooked.as_ref()), false, context)?; } else { - template_object.set_field(i, Value::undefined(), false, context)?; + template_object.set_field(i, JsValue::undefined(), false, context)?; } } template_object.set_field("raw", raw_array, false, context)?; @@ -113,7 +113,7 @@ impl Executable for TaggedTemplate { Node::GetConstField(ref get_const_field) => { let mut obj = get_const_field.obj().run(context)?; if !obj.is_object() { - obj = Value::Object(obj.to_object(context)?); + obj = JsValue::Object(obj.to_object(context)?); } ( obj.clone(), diff --git a/boa/src/syntax/ast/node/throw/mod.rs b/boa/src/syntax/ast/node/throw/mod.rs index e430e0a018..248844f067 100644 --- a/boa/src/syntax/ast/node/throw/mod.rs +++ b/boa/src/syntax/ast/node/throw/mod.rs @@ -2,7 +2,7 @@ use crate::{ exec::Executable, gc::{Finalize, Trace}, syntax::ast::node::Node, - Context, Result, Value, + Context, JsValue, Result, }; use std::fmt; @@ -50,7 +50,7 @@ impl Throw { impl Executable for Throw { #[inline] - fn run(&self, context: &mut Context) -> Result { + 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 cf56f56f0f..45b817772b 100644 --- a/boa/src/syntax/ast/node/try_node/mod.rs +++ b/boa/src/syntax/ast/node/try_node/mod.rs @@ -6,7 +6,7 @@ use crate::{ exec::Executable, gc::{Finalize, Trace}, syntax::ast::node::{Block, Identifier, Node}, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; use std::fmt; @@ -95,7 +95,7 @@ impl Try { } impl Executable for Try { - fn run(&self, context: &mut Context) -> Result { + fn run(&self, context: &mut Context) -> Result { let _timer = BoaProfiler::global().start_event("Try", "exec"); let res = self.block().run(context).map_or_else( |err| { diff --git a/boa/src/value/conversions.rs b/boa/src/value/conversions.rs index abb4a03185..4ef9ffd3c6 100644 --- a/boa/src/value/conversions.rs +++ b/boa/src/value/conversions.rs @@ -1,60 +1,36 @@ use super::*; use std::convert::TryFrom; -impl From<&Value> for Value { +impl From<&JsValue> for JsValue { #[inline] - fn from(value: &Value) -> Self { + fn from(value: &JsValue) -> Self { value.clone() } } -impl From for Value { +impl From for JsValue +where + T: Into, +{ #[inline] - fn from(value: String) -> Self { + fn from(value: T) -> Self { let _timer = BoaProfiler::global().start_event("From", "value"); - Self::string(value) - } -} - -impl From> for Value { - #[inline] - fn from(value: Box) -> Self { - Self::string(String::from(value)) - } -} - -impl From<&str> for Value { - #[inline] - fn from(value: &str) -> Value { - Value::string(value) - } -} -impl From<&Box> for Value { - #[inline] - fn from(value: &Box) -> Self { - Self::string(value.as_ref()) + Self::String(value.into()) } } -impl From for Value { +impl From for JsValue { #[inline] fn from(value: char) -> Self { - Value::string(value.to_string()) + JsValue::new(value.to_string()) } } -impl From for Value { - #[inline] - fn from(value: JsString) -> Self { - Value::String(value) - } -} - -impl From for Value { +impl From for JsValue { #[inline] fn from(value: JsSymbol) -> Self { - Value::Symbol(value) + JsValue::Symbol(value) } } @@ -67,81 +43,86 @@ impl Display for TryFromCharError { } } -impl From for Value { +impl From for JsValue { + #[allow(clippy::float_cmp)] #[inline] fn from(value: f64) -> Self { - Self::rational(value) + // if value as i32 as f64 == value { + // JsValue::Integer(value as i32) + // } else { + JsValue::Rational(value) + // } } } -impl From for Value { +impl From for JsValue { #[inline] - fn from(value: u32) -> Value { + fn from(value: u32) -> JsValue { if let Ok(integer) = i32::try_from(value) { - Value::integer(integer) + JsValue::Integer(integer) } else { - Value::rational(value) + JsValue::Rational(value.into()) } } } -impl From for Value { +impl From for JsValue { #[inline] - fn from(value: i32) -> Value { - Value::integer(value) + fn from(value: i32) -> JsValue { + JsValue::Integer(value) } } -impl From for Value { +impl From for JsValue { #[inline] fn from(value: JsBigInt) -> Self { - Value::BigInt(value) + JsValue::BigInt(value) } } -impl From for Value { +impl From for JsValue { #[inline] - fn from(value: usize) -> Value { + fn from(value: usize) -> JsValue { if let Ok(value) = i32::try_from(value) { - Value::integer(value) + JsValue::Integer(value) } else { - Value::rational(value as f64) + JsValue::Rational(value as f64) } } } -impl From for Value { +impl From for JsValue { #[inline] - fn from(value: u64) -> Value { + fn from(value: u64) -> JsValue { if let Ok(value) = i32::try_from(value) { - Value::integer(value) + JsValue::Integer(value) } else { - Value::rational(value as f64) + JsValue::Rational(value as f64) } } } -impl From for Value { +impl From for JsValue { #[inline] - fn from(value: i64) -> Value { + fn from(value: i64) -> JsValue { if let Ok(value) = i32::try_from(value) { - Value::integer(value) + JsValue::Integer(value) } else { - Value::rational(value as f64) + JsValue::Rational(value as f64) } } } -impl From for Value { +impl From for JsValue { #[inline] fn from(value: bool) -> Self { - Value::boolean(value) + JsValue::Boolean(value) } } -impl From<&[T]> for Value +impl From<&[T]> for JsValue where - T: Clone + Into, + T: Clone + Into, { fn from(value: &[T]) -> Self { let mut array = Object::default(); @@ -159,9 +140,9 @@ where } } -impl From> for Value +impl From> for JsValue where - T: Into, + T: Into, { fn from(value: Vec) -> Self { let mut array = Object::default(); @@ -175,22 +156,23 @@ where .configurable(true), ); } - Value::from(array) + JsValue::new(array) } } -impl From for Value { +impl From for JsValue { + #[inline] fn from(object: Object) -> Self { let _timer = BoaProfiler::global().start_event("From", "value"); - Value::object(object) + JsValue::Object(GcObject::new(object)) } } -impl From for Value { +impl From for JsValue { #[inline] fn from(object: GcObject) -> Self { let _timer = BoaProfiler::global().start_event("From", "value"); - Value::Object(object) + JsValue::Object(object) } } @@ -204,22 +186,22 @@ impl Display for TryFromObjectError { } } -impl From<()> for Value { +impl From<()> for JsValue { #[inline] fn from(_: ()) -> Self { - Value::null() + JsValue::null() } } -impl From> for Value +impl From> for JsValue where - T: Into, + T: Into, { #[inline] fn from(value: Option) -> Self { match value { Some(value) => value.into(), - None => Value::null(), + None => JsValue::null(), } } } diff --git a/boa/src/value/display.rs b/boa/src/value/display.rs index e7e657c547..1897ec4748 100644 --- a/boa/src/value/display.rs +++ b/boa/src/value/display.rs @@ -3,7 +3,7 @@ use super::*; /// This object is used for displaying a `Value`. #[derive(Debug, Clone, Copy)] pub struct ValueDisplay<'value> { - pub(super) value: &'value Value, + pub(super) value: &'value JsValue, } /// A helper macro for printing objects @@ -80,10 +80,10 @@ macro_rules! print_obj_value { }; } -pub(crate) fn log_string_from(x: &Value, print_internals: bool, print_children: bool) -> String { +pub(crate) fn log_string_from(x: &JsValue, print_internals: bool, print_children: bool) -> String { match x { // We don't want to print private (compiler) or prototype properties - Value::Object(ref v) => { + JsValue::Object(ref v) => { // Can use the private "type" field of an Object to match on // which type of Object it represents for special printing match v.borrow().data { @@ -122,7 +122,7 @@ pub(crate) fn log_string_from(x: &Value, print_internals: bool, print_children: .as_ref() // FIXME: handle accessor descriptors .and_then(|p| p.value()) - .unwrap_or(&Value::Undefined), + .unwrap_or(&JsValue::Undefined), print_internals, false, ) @@ -177,13 +177,13 @@ pub(crate) fn log_string_from(x: &Value, print_internals: bool, print_children: _ => display_obj(x, print_internals), } } - Value::Symbol(ref symbol) => symbol.to_string(), + JsValue::Symbol(ref symbol) => symbol.to_string(), _ => format!("{}", x.display()), } } /// A helper function for specifically printing object values -pub(crate) fn display_obj(v: &Value, print_internals: bool) -> String { +pub(crate) fn display_obj(v: &JsValue, print_internals: bool) -> String { // A simple helper for getting the address of a value // TODO: Find a more general place for this, as it can be used in other situations as well fn address_of(t: &T) -> usize { @@ -195,20 +195,20 @@ pub(crate) fn display_obj(v: &Value, print_internals: bool) -> String { // in-memory address in this set let mut encounters = HashSet::new(); - if let Value::Object(object) = v { + if let JsValue::Object(object) = v { if object.borrow().is_error() { let name = v .get_property("name") .as_ref() .and_then(|d| d.value()) - .unwrap_or(&Value::Undefined) + .unwrap_or(&JsValue::Undefined) .display() .to_string(); let message = v .get_property("message") .as_ref() .and_then(|d| d.value()) - .unwrap_or(&Value::Undefined) + .unwrap_or(&JsValue::Undefined) .display() .to_string(); return format!("{}: {}", name, message); @@ -216,12 +216,12 @@ pub(crate) fn display_obj(v: &Value, print_internals: bool) -> String { } fn display_obj_internal( - data: &Value, + data: &JsValue, encounters: &mut HashSet, indent: usize, print_internals: bool, ) -> String { - if let Value::Object(ref v) = *data { + if let JsValue::Object(ref v) = *data { // The in-memory address of the current object let addr = address_of(v.as_ref()); @@ -261,18 +261,18 @@ pub(crate) fn display_obj(v: &Value, print_internals: bool) -> String { impl Display for ValueDisplay<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.value { - Value::Null => write!(f, "null"), - Value::Undefined => write!(f, "undefined"), - Value::Boolean(v) => write!(f, "{}", v), - Value::Symbol(ref symbol) => match symbol.description() { + JsValue::Null => write!(f, "null"), + JsValue::Undefined => write!(f, "undefined"), + JsValue::Boolean(v) => write!(f, "{}", v), + JsValue::Symbol(ref symbol) => match symbol.description() { Some(description) => write!(f, "Symbol({})", description), None => write!(f, "Symbol()"), }, - Value::String(ref v) => write!(f, "\"{}\"", v), - Value::Rational(v) => format_rational(*v, f), - Value::Object(_) => write!(f, "{}", log_string_from(self.value, true, true)), - Value::Integer(v) => write!(f, "{}", v), - Value::BigInt(ref num) => write!(f, "{}n", num), + JsValue::String(ref v) => write!(f, "\"{}\"", v), + JsValue::Rational(v) => format_rational(*v, f), + JsValue::Object(_) => write!(f, "{}", log_string_from(self.value, true, true)), + JsValue::Integer(v) => write!(f, "{}", v), + JsValue::BigInt(ref num) => write!(f, "{}n", num), } } } diff --git a/boa/src/value/equality.rs b/boa/src/value/equality.rs index f246f2ff47..6903bdea12 100644 --- a/boa/src/value/equality.rs +++ b/boa/src/value/equality.rs @@ -1,7 +1,7 @@ use super::*; use crate::{builtins::Number, Context}; -impl Value { +impl JsValue { /// Strict equality comparison. /// /// This method is executed when doing strict equality comparisons with the `===` operator. @@ -80,10 +80,10 @@ 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), context), + (Self::Boolean(x), _) => return other.equals(&JsValue::new(*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), context), + (_, Self::Boolean(y)) => return self.equals(&JsValue::new(*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). @@ -119,7 +119,7 @@ impl Value { /// - [ECMAScript][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-samevalue - pub fn same_value(x: &Value, y: &Value) -> bool { + pub fn same_value(x: &JsValue, y: &JsValue) -> bool { // 1. If Type(x) is different from Type(y), return false. if x.get_type() != y.get_type() { return false; @@ -128,11 +128,11 @@ impl Value { match (x, y) { // 2. If Type(x) is Number or BigInt, then // a. Return ! Type(x)::SameValue(x, y). - (Value::BigInt(x), Value::BigInt(y)) => JsBigInt::same_value(x, y), - (Value::Rational(x), Value::Rational(y)) => Number::same_value(*x, *y), - (Value::Rational(x), Value::Integer(y)) => Number::same_value(*x, f64::from(*y)), - (Value::Integer(x), Value::Rational(y)) => Number::same_value(f64::from(*x), *y), - (Value::Integer(x), Value::Integer(y)) => x == y, + (JsValue::BigInt(x), JsValue::BigInt(y)) => JsBigInt::same_value(x, y), + (JsValue::Rational(x), JsValue::Rational(y)) => Number::same_value(*x, *y), + (JsValue::Rational(x), JsValue::Integer(y)) => Number::same_value(*x, f64::from(*y)), + (JsValue::Integer(x), JsValue::Rational(y)) => Number::same_value(f64::from(*x), *y), + (JsValue::Integer(x), JsValue::Integer(y)) => x == y, // 3. Return ! SameValueNonNumeric(x, y). (_, _) => Self::same_value_non_numeric(x, y), @@ -148,7 +148,7 @@ impl Value { /// - [ECMAScript][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-samevaluezero - pub fn same_value_zero(x: &Value, y: &Value) -> bool { + pub fn same_value_zero(x: &JsValue, y: &JsValue) -> bool { if x.get_type() != y.get_type() { return false; } @@ -156,26 +156,30 @@ impl Value { match (x, y) { // 2. If Type(x) is Number or BigInt, then // a. Return ! Type(x)::SameValueZero(x, y). - (Value::BigInt(x), Value::BigInt(y)) => JsBigInt::same_value_zero(x, y), + (JsValue::BigInt(x), JsValue::BigInt(y)) => JsBigInt::same_value_zero(x, y), - (Value::Rational(x), Value::Rational(y)) => Number::same_value_zero(*x, *y), - (Value::Rational(x), Value::Integer(y)) => Number::same_value_zero(*x, f64::from(*y)), - (Value::Integer(x), Value::Rational(y)) => Number::same_value_zero(f64::from(*x), *y), - (Value::Integer(x), Value::Integer(y)) => x == y, + (JsValue::Rational(x), JsValue::Rational(y)) => Number::same_value_zero(*x, *y), + (JsValue::Rational(x), JsValue::Integer(y)) => { + Number::same_value_zero(*x, f64::from(*y)) + } + (JsValue::Integer(x), JsValue::Rational(y)) => { + Number::same_value_zero(f64::from(*x), *y) + } + (JsValue::Integer(x), JsValue::Integer(y)) => x == y, // 3. Return ! SameValueNonNumeric(x, y). (_, _) => Self::same_value_non_numeric(x, y), } } - fn same_value_non_numeric(x: &Value, y: &Value) -> bool { + fn same_value_non_numeric(x: &JsValue, y: &JsValue) -> bool { debug_assert!(x.get_type() == y.get_type()); match (x, y) { - (Value::Null, Value::Null) | (Value::Undefined, Value::Undefined) => true, - (Value::String(ref x), Value::String(ref y)) => x == y, - (Value::Boolean(x), Value::Boolean(y)) => x == y, - (Value::Object(ref x), Value::Object(ref y)) => GcObject::equals(x, y), - (Value::Symbol(ref x), Value::Symbol(ref y)) => x == y, + (JsValue::Null, JsValue::Null) | (JsValue::Undefined, JsValue::Undefined) => true, + (JsValue::String(ref x), JsValue::String(ref y)) => x == y, + (JsValue::Boolean(x), JsValue::Boolean(y)) => x == y, + (JsValue::Object(ref x), JsValue::Object(ref y)) => GcObject::equals(x, y), + (JsValue::Symbol(ref x), JsValue::Symbol(ref y)) => x == y, _ => false, } } diff --git a/boa/src/value/hash.rs b/boa/src/value/hash.rs index 8a951d8228..8ffafc04f3 100644 --- a/boa/src/value/hash.rs +++ b/boa/src/value/hash.rs @@ -3,13 +3,13 @@ use super::*; use crate::builtins::Number; use std::hash::{Hash, Hasher}; -impl PartialEq for Value { +impl PartialEq for JsValue { fn eq(&self, other: &Self) -> bool { Self::same_value_zero(self, other) } } -impl Eq for Value {} +impl Eq for JsValue {} #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] struct UndefinedHashable; @@ -36,7 +36,7 @@ impl Hash for RationalHashable { } } -impl Hash for Value { +impl Hash for JsValue { fn hash(&self, state: &mut H) { match self { Self::Undefined => UndefinedHashable.hash(state), diff --git a/boa/src/value/mod.rs b/boa/src/value/mod.rs index 6ae3448855..0e6f4308a0 100644 --- a/boa/src/value/mod.rs +++ b/boa/src/value/mod.rs @@ -41,7 +41,7 @@ pub use r#type::Type; /// A Javascript value #[derive(Trace, Finalize, Debug, Clone)] -pub enum Value { +pub enum JsValue { /// `null` - A null value, for when a value doesn't exist. Null, /// `undefined` - An undefined value, for when a field or index doesn't exist. @@ -70,7 +70,16 @@ pub enum IntegerOrInfinity { NegativeInfinity, } -impl Value { +impl JsValue { + /// Create a new [`JsValue`]. + #[inline] + pub fn new(value: T) -> Self + where + T: Into, + { + value.into() + } + /// Creates a new `undefined` value. #[inline] pub fn undefined() -> Self { @@ -86,86 +95,23 @@ impl Value { /// Creates a new number with `NaN` value. #[inline] pub fn nan() -> Self { - Self::number(f64::NAN) + Self::Rational(f64::NAN) } /// Creates a new number with `Infinity` value. #[inline] pub fn positive_inifnity() -> Self { - Self::number(f64::INFINITY) + Self::Rational(f64::INFINITY) } /// Creates a new number with `-Infinity` value. #[inline] pub fn negative_inifnity() -> Self { - Self::number(f64::NEG_INFINITY) - } - - /// Creates a new string value. - #[inline] - pub fn string(value: S) -> Self - where - S: Into, - { - Self::String(value.into()) - } - - /// Creates a new number value. - #[inline] - pub fn rational(value: N) -> Self - where - N: Into, - { - Self::Rational(value.into()) - } - - /// Creates a new number value. - #[inline] - pub fn integer(value: I) -> Self - where - I: Into, - { - Self::Integer(value.into()) - } - - /// Creates a new number value. - #[inline] - pub fn number(value: N) -> Self - where - N: Into, - { - Self::rational(value.into()) - } - - /// Creates a new bigint value. - #[inline] - pub fn bigint(value: B) -> Self - where - B: Into, - { - Self::BigInt(value.into()) - } - - /// Creates a new boolean value. - #[inline] - pub fn boolean(value: bool) -> Self { - Self::Boolean(value) - } - - /// Creates a new object value. - #[inline] - pub fn object(object: Object) -> Self { - Self::Object(GcObject::new(object)) - } - - /// Creates a new symbol value. - #[inline] - pub fn symbol(symbol: JsSymbol) -> Self { - Self::Symbol(symbol) + Self::Rational(f64::NEG_INFINITY) } /// Returns a new empty object - pub fn new_object(context: &Context) -> Self { + pub(crate) fn new_object(context: &Context) -> Self { let _timer = BoaProfiler::global().start_event("new_object", "value"); context.construct_object().into() } @@ -175,16 +121,16 @@ impl Value { match json { JSONValue::Number(v) => { if let Some(Ok(integer_32)) = v.as_i64().map(i32::try_from) { - Self::integer(integer_32) + Self::new(integer_32) } else { - Self::rational(v.as_f64().expect("Could not convert value to f64")) + Self::new(v.as_f64().expect("Could not convert value to f64")) } } - JSONValue::String(v) => Self::string(v), - JSONValue::Bool(v) => Self::boolean(v), + JSONValue::String(v) => Self::new(v), + JSONValue::Bool(v) => Self::new(v), JSONValue::Array(vs) => { let array_prototype = context.standard_objects().array_object().prototype(); - let new_obj: Value = + let new_obj: JsValue = Object::with_prototype(array_prototype.into(), ObjectData::Array).into(); let length = vs.len(); for (idx, json) in vs.into_iter().enumerate() { @@ -209,7 +155,7 @@ impl Value { new_obj } JSONValue::Object(obj) => { - let new_obj = Value::new_object(context); + let new_obj = JsValue::new_object(context); for (key, json) in obj.into_iter() { let value = Self::from_json(json, context); new_obj.set_property( @@ -227,7 +173,7 @@ impl Value { } } - /// Converts the `Value` to `JSON`. + /// Converts the `JsValue` to `JSON`. pub fn to_json(&self, context: &mut Context) -> Result> { let to_json = self.get_field("toJSON", context)?; if to_json.is_function() { @@ -425,7 +371,7 @@ impl Value { } } - /// Removes a property from a Value object. + /// Removes a property from a [`JsValue`] object. /// /// It will return a boolean based on if the value was removed, if there was no value to remove false is returned. pub(crate) fn remove_property(&self, key: Key) -> bool @@ -468,7 +414,7 @@ impl Value { obj.clone() .__get__(&key.into(), obj.clone().into(), context) } else { - Ok(Value::undefined()) + Ok(JsValue::undefined()) } } @@ -499,10 +445,10 @@ impl Value { value: V, throw: bool, context: &mut Context, - ) -> Result + ) -> Result where K: Into, - V: Into, + V: Into, { // 1. Assert: Type(O) is Object. // TODO: Currently the value may not be an object. @@ -557,10 +503,10 @@ impl Value { &self, context: &mut Context, preferred_type: PreferredType, - ) -> Result { + ) -> 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 { + if let JsValue::Object(obj) = self { if let Some(exotic_to_prim) = obj.get_method(context, WellKnownSymbols::to_primitive())? { @@ -597,11 +543,11 @@ impl Value { /// This function is equivelent to `BigInt(value)` in JavaScript. pub fn to_bigint(&self, context: &mut Context) -> Result { match self { - Value::Null => Err(context.construct_type_error("cannot convert null to a BigInt")), - Value::Undefined => { + JsValue::Null => Err(context.construct_type_error("cannot convert null to a BigInt")), + JsValue::Undefined => { Err(context.construct_type_error("cannot convert undefined to a BigInt")) } - Value::String(ref string) => { + JsValue::String(ref string) => { if let Some(value) = JsBigInt::from_string(string) { Ok(value) } else { @@ -611,10 +557,10 @@ impl Value { ))) } } - Value::Boolean(true) => Ok(JsBigInt::one()), - Value::Boolean(false) => Ok(JsBigInt::zero()), - Value::Integer(num) => Ok(JsBigInt::new(*num)), - Value::Rational(num) => { + JsValue::Boolean(true) => Ok(JsBigInt::one()), + JsValue::Boolean(false) => Ok(JsBigInt::zero()), + JsValue::Integer(num) => Ok(JsBigInt::new(*num)), + JsValue::Rational(num) => { if let Ok(bigint) = JsBigInt::try_from(*num) { return Ok(bigint); } @@ -623,12 +569,12 @@ impl Value { num ))) } - Value::BigInt(b) => Ok(b.clone()), - Value::Object(_) => { + JsValue::BigInt(b) => Ok(b.clone()), + JsValue::Object(_) => { let primitive = self.to_primitive(context, PreferredType::Number)?; primitive.to_bigint(context) } - Value::Symbol(_) => { + JsValue::Symbol(_) => { Err(context.construct_type_error("cannot convert Symbol to a BigInt")) } } @@ -639,9 +585,9 @@ impl Value { /// # Examples /// /// ``` - /// use boa::Value; + /// use boa::JsValue; /// - /// let value = Value::number(3); + /// let value = JsValue::new(3); /// /// println!("{}", value.display()); /// ``` @@ -655,15 +601,17 @@ impl Value { /// This function is equivalent to `String(value)` in JavaScript. pub fn to_string(&self, context: &mut Context) -> Result { match self { - Value::Null => Ok("null".into()), - Value::Undefined => Ok("undefined".into()), - Value::Boolean(boolean) => Ok(boolean.to_string().into()), - 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(context.construct_type_error("can't convert symbol to string")), - Value::BigInt(ref bigint) => Ok(bigint.to_string().into()), - Value::Object(_) => { + JsValue::Null => Ok("null".into()), + JsValue::Undefined => Ok("undefined".into()), + JsValue::Boolean(boolean) => Ok(boolean.to_string().into()), + JsValue::Rational(rational) => Ok(Number::to_native_string(*rational).into()), + JsValue::Integer(integer) => Ok(integer.to_string().into()), + JsValue::String(string) => Ok(string.clone()), + JsValue::Symbol(_) => { + Err(context.construct_type_error("can't convert symbol to string")) + } + JsValue::BigInt(ref bigint) => Ok(bigint.to_string().into()), + JsValue::Object(_) => { let primitive = self.to_primitive(context, PreferredType::String)?; primitive.to_string(context) } @@ -677,31 +625,31 @@ impl Value { /// See: pub fn to_object(&self, context: &mut Context) -> Result { match self { - Value::Undefined | Value::Null => { + JsValue::Undefined | JsValue::Null => { Err(context.construct_type_error("cannot convert 'null' or 'undefined' to object")) } - Value::Boolean(boolean) => { + JsValue::Boolean(boolean) => { let prototype = context.standard_objects().boolean_object().prototype(); Ok(GcObject::new(Object::with_prototype( prototype.into(), ObjectData::Boolean(*boolean), ))) } - Value::Integer(integer) => { + JsValue::Integer(integer) => { let prototype = context.standard_objects().number_object().prototype(); Ok(GcObject::new(Object::with_prototype( prototype.into(), ObjectData::Number(f64::from(*integer)), ))) } - Value::Rational(rational) => { + JsValue::Rational(rational) => { let prototype = context.standard_objects().number_object().prototype(); Ok(GcObject::new(Object::with_prototype( prototype.into(), ObjectData::Number(*rational), ))) } - Value::String(ref string) => { + JsValue::String(ref string) => { let prototype = context.standard_objects().string_object().prototype(); let object = GcObject::new(Object::with_prototype( @@ -719,21 +667,21 @@ impl Value { ); Ok(object) } - Value::Symbol(ref symbol) => { + JsValue::Symbol(ref symbol) => { let prototype = context.standard_objects().symbol_object().prototype(); Ok(GcObject::new(Object::with_prototype( prototype.into(), ObjectData::Symbol(symbol.clone()), ))) } - Value::BigInt(ref bigint) => { + JsValue::BigInt(ref bigint) => { let prototype = context.standard_objects().bigint_object().prototype(); Ok(GcObject::new(Object::with_prototype( prototype.into(), ObjectData::BigInt(bigint.clone()), ))) } - Value::Object(gcobject) => Ok(gcobject.clone()), + JsValue::Object(gcobject) => Ok(gcobject.clone()), } } @@ -743,12 +691,12 @@ impl Value { 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(), + JsValue::String(string) => string.clone().into(), + JsValue::Symbol(symbol) => symbol.clone().into(), // Slow path: _ => match self.to_primitive(context, PreferredType::String)? { - Value::String(ref string) => string.clone().into(), - Value::Symbol(ref symbol) => symbol.clone().into(), + JsValue::String(ref string) => string.clone().into(), + JsValue::Symbol(ref symbol) => symbol.clone().into(), primitive => primitive.to_string(context)?.into(), }, }) @@ -772,7 +720,7 @@ impl Value { /// See: 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 { + if let JsValue::Integer(number) = *self { return Ok(number as u32); } let number = self.to_number(context)?; @@ -785,7 +733,7 @@ impl Value { /// See: 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 { + if let JsValue::Integer(number) = *self { return Ok(number); } let number = self.to_number(context)?; @@ -861,10 +809,10 @@ impl Value { /// See: pub fn to_number(&self, context: &mut Context) -> Result { match *self { - Value::Null => Ok(0.0), - Value::Undefined => Ok(f64::NAN), - Value::Boolean(b) => Ok(if b { 1.0 } else { 0.0 }), - Value::String(ref string) => { + JsValue::Null => Ok(0.0), + JsValue::Undefined => Ok(f64::NAN), + JsValue::Boolean(b) => Ok(if b { 1.0 } else { 0.0 }), + JsValue::String(ref string) => { let string = string.trim_matches(is_trimmable_whitespace); // TODO: write our own lexer to match syntax StrDecimalLiteral @@ -888,11 +836,15 @@ impl Value { _ => Ok(fast_float::parse(string).unwrap_or(f64::NAN)), } } - Value::Rational(number) => Ok(number), - Value::Integer(integer) => Ok(f64::from(integer)), - 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(_) => { + JsValue::Rational(number) => Ok(number), + JsValue::Integer(integer) => Ok(f64::from(integer)), + JsValue::Symbol(_) => { + Err(context.construct_type_error("argument must not be a symbol")) + } + JsValue::BigInt(_) => { + Err(context.construct_type_error("argument must not be a bigint")) + } + JsValue::Object(_) => { let primitive = self.to_primitive(context, PreferredType::Number)?; primitive.to_number(context) } @@ -924,7 +876,7 @@ impl Value { /// [table]: https://tc39.es/ecma262/#table-14 /// [spec]: https://tc39.es/ecma262/#sec-requireobjectcoercible #[inline] - pub fn require_object_coercible(&self, context: &mut Context) -> Result<&Value> { + pub fn require_object_coercible(&self, context: &mut Context) -> Result<&JsValue> { if self.is_null_or_undefined() { Err(context.construct_type_error("cannot convert null or undefined to Object")) } else { @@ -936,7 +888,7 @@ impl Value { pub fn to_property_descriptor(&self, context: &mut Context) -> Result { // 1. If Type(Obj) is not Object, throw a TypeError exception. match self { - Value::Object(ref obj) => obj.to_property_descriptor(context), + JsValue::Object(ref obj) => obj.to_property_descriptor(context), _ => Err(context .construct_type_error("Cannot construct a property descriptor from a non-object")), } @@ -1022,7 +974,7 @@ impl Value { } } -impl Default for Value { +impl Default for JsValue { fn default() -> Self { Self::Undefined } @@ -1101,11 +1053,11 @@ impl From for Numeric { } } -impl From for Value { +impl From for JsValue { fn from(value: Numeric) -> Self { match value { - Numeric::Number(number) => Self::rational(number), - Numeric::BigInt(bigint) => Self::bigint(bigint), + Numeric::Number(number) => Self::new(number), + Numeric::BigInt(bigint) => Self::new(bigint), } } } diff --git a/boa/src/value/operations.rs b/boa/src/value/operations.rs index 88040bace2..072ab7fe83 100644 --- a/boa/src/value/operations.rs +++ b/boa/src/value/operations.rs @@ -1,22 +1,20 @@ use super::*; use crate::builtins::number::{f64_to_int32, f64_to_uint32, Number}; -impl Value { +impl JsValue { #[inline] - pub fn add(&self, other: &Self, context: &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)), - (Self::Rational(x), Self::Rational(y)) => Self::rational(x + y), - (Self::Integer(x), Self::Rational(y)) => Self::rational(f64::from(*x) + y), - (Self::Rational(x), Self::Integer(y)) => Self::rational(x + f64::from(*y)), + (Self::Integer(x), Self::Integer(y)) => Self::new(f64::from(*x) + f64::from(*y)), + (Self::Rational(x), Self::Rational(y)) => Self::new(x + y), + (Self::Integer(x), Self::Rational(y)) => Self::new(f64::from(*x) + y), + (Self::Rational(x), Self::Integer(y)) => Self::new(x + f64::from(*y)), (Self::String(ref x), Self::String(ref y)) => Self::from(JsString::concat(x, y)), (Self::String(ref x), y) => Self::from(JsString::concat(x, y.to_string(context)?)), (x, Self::String(ref y)) => Self::from(JsString::concat(x.to_string(context)?, y)), - (Self::BigInt(ref n1), Self::BigInt(ref n2)) => { - Self::bigint(n1.as_inner().clone() + n2.as_inner().clone()) - } + (Self::BigInt(ref x), Self::BigInt(ref y)) => Self::new(JsBigInt::add(x, y)), // Slow path: (_, _) => match ( @@ -30,9 +28,9 @@ impl Value { Self::from(JsString::concat(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()) + (Numeric::Number(x), Numeric::Number(y)) => Self::new(x + y), + (Numeric::BigInt(ref x), Numeric::BigInt(ref y)) => { + Self::new(JsBigInt::add(x, y)) } (_, _) => { return context.throw_type_error( @@ -45,24 +43,20 @@ impl Value { } #[inline] - pub fn sub(&self, other: &Self, context: &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)), - (Self::Rational(x), Self::Rational(y)) => Self::rational(x - y), - (Self::Integer(x), Self::Rational(y)) => Self::rational(f64::from(*x) - y), - (Self::Rational(x), Self::Integer(y)) => Self::rational(x - f64::from(*y)), + (Self::Integer(x), Self::Integer(y)) => Self::new(f64::from(*x) - f64::from(*y)), + (Self::Rational(x), Self::Rational(y)) => Self::new(x - y), + (Self::Integer(x), Self::Rational(y)) => Self::new(f64::from(*x) - y), + (Self::Rational(x), Self::Integer(y)) => Self::new(x - f64::from(*y)), - (Self::BigInt(ref a), Self::BigInt(ref b)) => { - Self::bigint(a.as_inner().clone() - b.as_inner().clone()) - } + (Self::BigInt(ref x), Self::BigInt(ref y)) => Self::new(JsBigInt::sub(x, y)), // Slow path: (_, _) => 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()) - } + (Numeric::Number(a), Numeric::Number(b)) => Self::new(a - b), + (Numeric::BigInt(ref x), Numeric::BigInt(ref y)) => Self::new(JsBigInt::sub(x, y)), (_, _) => { return context.throw_type_error( "cannot mix BigInt and other types, use explicit conversions", @@ -73,24 +67,20 @@ impl Value { } #[inline] - pub fn mul(&self, other: &Self, context: &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)), - (Self::Rational(x), Self::Rational(y)) => Self::rational(x * y), - (Self::Integer(x), Self::Rational(y)) => Self::rational(f64::from(*x) * y), - (Self::Rational(x), Self::Integer(y)) => Self::rational(x * f64::from(*y)), + (Self::Integer(x), Self::Integer(y)) => Self::new(f64::from(*x) * f64::from(*y)), + (Self::Rational(x), Self::Rational(y)) => Self::new(x * y), + (Self::Integer(x), Self::Rational(y)) => Self::new(f64::from(*x) * y), + (Self::Rational(x), Self::Integer(y)) => Self::new(x * f64::from(*y)), - (Self::BigInt(ref a), Self::BigInt(ref b)) => { - Self::bigint(a.as_inner().clone() * b.as_inner().clone()) - } + (Self::BigInt(ref x), Self::BigInt(ref y)) => Self::new(JsBigInt::mul(x, y)), // Slow path: (_, _) => 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()) - } + (Numeric::Number(a), Numeric::Number(b)) => Self::new(a * b), + (Numeric::BigInt(ref x), Numeric::BigInt(ref y)) => Self::new(JsBigInt::mul(x, y)), (_, _) => { return context.throw_type_error( "cannot mix BigInt and other types, use explicit conversions", @@ -101,29 +91,29 @@ impl Value { } #[inline] - pub fn div(&self, other: &Self, context: &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)), - (Self::Rational(x), Self::Rational(y)) => Self::rational(x / y), - (Self::Integer(x), Self::Rational(y)) => Self::rational(f64::from(*x) / y), - (Self::Rational(x), Self::Integer(y)) => Self::rational(x / f64::from(*y)), + (Self::Integer(x), Self::Integer(y)) => Self::new(f64::from(*x) / f64::from(*y)), + (Self::Rational(x), Self::Rational(y)) => Self::new(x / y), + (Self::Integer(x), Self::Rational(y)) => Self::new(f64::from(*x) / y), + (Self::Rational(x), Self::Integer(y)) => Self::new(x / f64::from(*y)), - (Self::BigInt(ref a), Self::BigInt(ref b)) => { - if b.is_zero() { + (Self::BigInt(ref x), Self::BigInt(ref y)) => { + if y.is_zero() { return context.throw_range_error("BigInt division by zero"); } - Self::bigint(a.as_inner().clone() / b.as_inner().clone()) + Self::new(JsBigInt::div(x, y)) } // Slow path: (_, _) => 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.is_zero() { + (Numeric::Number(a), Numeric::Number(b)) => Self::new(a / b), + (Numeric::BigInt(ref x), Numeric::BigInt(ref y)) => { + if y.is_zero() { return context.throw_range_error("BigInt division by zero"); } - Self::bigint(a.as_inner().clone() / b.as_inner().clone()) + Self::new(JsBigInt::div(x, y)) } (_, _) => { return context.throw_type_error( @@ -135,32 +125,35 @@ impl Value { } #[inline] - pub fn rem(&self, other: &Self, context: &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)) => { if *y == 0 { Self::nan() } else { - Self::integer(x % *y) + Self::new(x % *y) } } - (Self::Rational(x), Self::Rational(y)) => Self::rational(x % y), - (Self::Integer(x), Self::Rational(y)) => Self::rational(f64::from(*x) % y), - (Self::Rational(x), Self::Integer(y)) => Self::rational(x % f64::from(*y)), + (Self::Rational(x), Self::Rational(y)) => Self::new(x % y), + (Self::Integer(x), Self::Rational(y)) => Self::new(f64::from(*x) % y), + (Self::Rational(x), Self::Integer(y)) => Self::new(x % f64::from(*y)), - (Self::BigInt(ref a), Self::BigInt(ref b)) => { - if b.is_zero() { + (Self::BigInt(ref x), Self::BigInt(ref y)) => { + if y.is_zero() { return context.throw_range_error("BigInt division by zero"); } - Self::bigint(a.as_inner().clone() % b.as_inner().clone()) + Self::new(JsBigInt::rem(x, y)) } // Slow path: (_, _) => 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()) + (Numeric::Number(a), Numeric::Number(b)) => Self::new(a % b), + (Numeric::BigInt(ref x), Numeric::BigInt(ref y)) => { + if y.is_zero() { + return context.throw_range_error("BigInt division by zero"); + } + Self::new(JsBigInt::rem(x, y)) } (_, _) => { return context.throw_type_error( @@ -172,23 +165,21 @@ impl Value { } #[inline] - pub fn pow(&self, other: &Self, context: &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)), - (Self::Rational(x), Self::Rational(y)) => Self::rational(x.powf(*y)), - (Self::Integer(x), Self::Rational(y)) => Self::rational(f64::from(*x).powf(*y)), - (Self::Rational(x), Self::Integer(y)) => Self::rational(x.powi(*y)), + (Self::Integer(x), Self::Integer(y)) => Self::new(f64::from(*x).powi(*y)), + (Self::Rational(x), Self::Rational(y)) => Self::new(x.powf(*y)), + (Self::Integer(x), Self::Rational(y)) => Self::new(f64::from(*x).powf(*y)), + (Self::Rational(x), Self::Integer(y)) => Self::new(x.powi(*y)), - (Self::BigInt(ref a), Self::BigInt(ref b)) => { - Self::bigint(JsBigInt::pow(a, b, context)?) - } + (Self::BigInt(ref a), Self::BigInt(ref b)) => Self::new(JsBigInt::pow(a, b, context)?), // Slow path: (_, _) => match (self.to_numeric(context)?, other.to_numeric(context)?) { - (Numeric::Number(a), Numeric::Number(b)) => Self::rational(a.powf(b)), + (Numeric::Number(a), Numeric::Number(b)) => Self::new(a.powf(b)), (Numeric::BigInt(ref a), Numeric::BigInt(ref b)) => { - Self::bigint(JsBigInt::pow(a, b, context)?) + Self::new(JsBigInt::pow(a, b, context)?) } (_, _) => { return context.throw_type_error( @@ -200,27 +191,25 @@ impl Value { } #[inline] - pub fn bitand(&self, other: &Self, context: &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), + (Self::Integer(x), Self::Integer(y)) => Self::new(x & y), (Self::Rational(x), Self::Rational(y)) => { - Self::integer(f64_to_int32(*x) & f64_to_int32(*y)) + Self::new(f64_to_int32(*x) & f64_to_int32(*y)) } - (Self::Integer(x), Self::Rational(y)) => Self::integer(x & f64_to_int32(*y)), - (Self::Rational(x), Self::Integer(y)) => Self::integer(f64_to_int32(*x) & y), + (Self::Integer(x), Self::Rational(y)) => Self::new(x & f64_to_int32(*y)), + (Self::Rational(x), Self::Integer(y)) => Self::new(f64_to_int32(*x) & y), - (Self::BigInt(ref a), Self::BigInt(ref b)) => { - Self::bigint(a.as_inner().clone() & b.as_inner().clone()) - } + (Self::BigInt(ref x), Self::BigInt(ref y)) => Self::new(JsBigInt::bitand(x, y)), // Slow path: (_, _) => 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)) + Self::new(f64_to_int32(a) & f64_to_int32(b)) } - (Numeric::BigInt(ref a), Numeric::BigInt(ref b)) => { - Self::bigint(a.as_inner().clone() & b.as_inner().clone()) + (Numeric::BigInt(ref x), Numeric::BigInt(ref y)) => { + Self::new(JsBigInt::bitand(x, y)) } (_, _) => { return context.throw_type_error( @@ -232,27 +221,25 @@ impl Value { } #[inline] - pub fn bitor(&self, other: &Self, context: &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), + (Self::Integer(x), Self::Integer(y)) => Self::new(x | y), (Self::Rational(x), Self::Rational(y)) => { - Self::integer(f64_to_int32(*x) | f64_to_int32(*y)) + Self::new(f64_to_int32(*x) | f64_to_int32(*y)) } - (Self::Integer(x), Self::Rational(y)) => Self::integer(x | f64_to_int32(*y)), - (Self::Rational(x), Self::Integer(y)) => Self::integer(f64_to_int32(*x) | y), + (Self::Integer(x), Self::Rational(y)) => Self::new(x | f64_to_int32(*y)), + (Self::Rational(x), Self::Integer(y)) => Self::new(f64_to_int32(*x) | y), - (Self::BigInt(ref a), Self::BigInt(ref b)) => { - Self::bigint(a.as_inner().clone() | b.as_inner().clone()) - } + (Self::BigInt(ref x), Self::BigInt(ref y)) => Self::new(JsBigInt::bitor(x, y)), // Slow path: (_, _) => 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)) + Self::new(f64_to_int32(a) | f64_to_int32(b)) } - (Numeric::BigInt(ref a), Numeric::BigInt(ref b)) => { - Self::bigint(a.as_inner().clone() | b.as_inner().clone()) + (Numeric::BigInt(ref x), Numeric::BigInt(ref y)) => { + Self::new(JsBigInt::bitor(x, y)) } (_, _) => { return context.throw_type_error( @@ -264,27 +251,25 @@ impl Value { } #[inline] - pub fn bitxor(&self, other: &Self, context: &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), + (Self::Integer(x), Self::Integer(y)) => Self::new(x ^ y), (Self::Rational(x), Self::Rational(y)) => { - Self::integer(f64_to_int32(*x) ^ f64_to_int32(*y)) + Self::new(f64_to_int32(*x) ^ f64_to_int32(*y)) } - (Self::Integer(x), Self::Rational(y)) => Self::integer(x ^ f64_to_int32(*y)), - (Self::Rational(x), Self::Integer(y)) => Self::integer(f64_to_int32(*x) ^ y), + (Self::Integer(x), Self::Rational(y)) => Self::new(x ^ f64_to_int32(*y)), + (Self::Rational(x), Self::Integer(y)) => Self::new(f64_to_int32(*x) ^ y), - (Self::BigInt(ref a), Self::BigInt(ref b)) => { - Self::bigint(a.as_inner().clone() ^ b.as_inner().clone()) - } + (Self::BigInt(ref x), Self::BigInt(ref y)) => Self::new(JsBigInt::bitxor(x, y)), // Slow path: (_, _) => 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)) + Self::new(f64_to_int32(a) ^ f64_to_int32(b)) } - (Numeric::BigInt(ref a), Numeric::BigInt(ref b)) => { - Self::bigint(a.as_inner().clone() ^ b.as_inner().clone()) + (Numeric::BigInt(ref x), Numeric::BigInt(ref y)) => { + Self::new(JsBigInt::bitxor(x, y)) } (_, _) => { return context.throw_type_error( @@ -296,31 +281,29 @@ impl Value { } #[inline] - pub fn shl(&self, other: &Self, context: &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)), + (Self::Integer(x), Self::Integer(y)) => Self::new(x.wrapping_shl(*y as u32)), (Self::Rational(x), Self::Rational(y)) => { - Self::integer(f64_to_int32(*x).wrapping_shl(f64_to_uint32(*y))) - } - (Self::Integer(x), Self::Rational(y)) => { - Self::integer(x.wrapping_shl(f64_to_uint32(*y))) + Self::new(f64_to_int32(*x).wrapping_shl(f64_to_uint32(*y))) } + (Self::Integer(x), Self::Rational(y)) => Self::new(x.wrapping_shl(f64_to_uint32(*y))), (Self::Rational(x), Self::Integer(y)) => { - Self::integer(f64_to_int32(*x).wrapping_shl(*y as u32)) + Self::new(f64_to_int32(*x).wrapping_shl(*y as u32)) } (Self::BigInt(ref a), Self::BigInt(ref b)) => { - Self::bigint(JsBigInt::shift_left(a, b, context)?) + Self::new(JsBigInt::shift_left(a, b, context)?) } // Slow path: (_, _) => 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))) + Self::new(f64_to_int32(x).wrapping_shl(f64_to_uint32(y))) } (Numeric::BigInt(ref x), Numeric::BigInt(ref y)) => { - Self::bigint(JsBigInt::shift_left(x, y, context)?) + Self::new(JsBigInt::shift_left(x, y, context)?) } (_, _) => { return context.throw_type_error( @@ -332,31 +315,29 @@ impl Value { } #[inline] - pub fn shr(&self, other: &Self, context: &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)), + (Self::Integer(x), Self::Integer(y)) => Self::new(x.wrapping_shr(*y as u32)), (Self::Rational(x), Self::Rational(y)) => { - Self::integer(f64_to_int32(*x).wrapping_shr(f64_to_uint32(*y))) - } - (Self::Integer(x), Self::Rational(y)) => { - Self::integer(x.wrapping_shr(f64_to_uint32(*y))) + Self::new(f64_to_int32(*x).wrapping_shr(f64_to_uint32(*y))) } + (Self::Integer(x), Self::Rational(y)) => Self::new(x.wrapping_shr(f64_to_uint32(*y))), (Self::Rational(x), Self::Integer(y)) => { - Self::integer(f64_to_int32(*x).wrapping_shr(*y as u32)) + Self::new(f64_to_int32(*x).wrapping_shr(*y as u32)) } (Self::BigInt(ref a), Self::BigInt(ref b)) => { - Self::bigint(JsBigInt::shift_right(a, b, context)?) + Self::new(JsBigInt::shift_right(a, b, context)?) } // Slow path: (_, _) => 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))) + Self::new(f64_to_int32(x).wrapping_shr(f64_to_uint32(y))) } (Numeric::BigInt(ref x), Numeric::BigInt(ref y)) => { - Self::bigint(JsBigInt::shift_right(x, y, context)?) + Self::new(JsBigInt::shift_right(x, y, context)?) } (_, _) => { return context.throw_type_error( @@ -368,26 +349,24 @@ impl Value { } #[inline] - pub fn ushr(&self, other: &Self, context: &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)) => { - Self::rational((*x as u32).wrapping_shr(*y as u32)) - } + (Self::Integer(x), Self::Integer(y)) => Self::new((*x as u32).wrapping_shr(*y as u32)), (Self::Rational(x), Self::Rational(y)) => { - Self::rational(f64_to_uint32(*x).wrapping_shr(f64_to_uint32(*y))) + Self::new(f64_to_uint32(*x).wrapping_shr(f64_to_uint32(*y))) } (Self::Integer(x), Self::Rational(y)) => { - Self::rational((*x as u32).wrapping_shr(f64_to_uint32(*y))) + Self::new((*x as u32).wrapping_shr(f64_to_uint32(*y))) } (Self::Rational(x), Self::Integer(y)) => { - Self::rational(f64_to_uint32(*x).wrapping_shr(*y as u32)) + Self::new(f64_to_uint32(*x).wrapping_shr(*y as u32)) } // Slow path: (_, _) => 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))) + Self::new(f64_to_uint32(x).wrapping_shr(f64_to_uint32(y))) } (Numeric::BigInt(_), Numeric::BigInt(_)) => { return context @@ -403,22 +382,22 @@ impl Value { } #[inline] - pub fn neg(&self, context: &mut Context) -> Result { + pub fn neg(&self, context: &mut Context) -> Result { Ok(match *self { - Self::Symbol(_) | Self::Undefined => Self::rational(f64::NAN), - Self::Object(_) => Self::rational(match self.to_numeric_number(context) { + Self::Symbol(_) | Self::Undefined => Self::new(f64::NAN), + Self::Object(_) => Self::new(match self.to_numeric_number(context) { Ok(num) => -num, Err(_) => f64::NAN, }), - Self::String(ref str) => Self::rational(match f64::from_str(str) { + Self::String(ref str) => Self::new(match f64::from_str(str) { Ok(num) => -num, Err(_) => f64::NAN, }), - Self::Rational(num) => Self::rational(-num), - Self::Integer(num) => Self::rational(-f64::from(num)), - Self::Boolean(true) => Self::integer(1), - Self::Boolean(false) | Self::Null => Self::integer(0), - Self::BigInt(ref num) => Self::bigint(-num.as_inner().clone()), + Self::Rational(num) => Self::new(-num), + Self::Integer(num) => Self::new(-f64::from(num)), + Self::Boolean(true) => Self::new(1), + Self::Boolean(false) | Self::Null => Self::new(0), + Self::BigInt(ref x) => Self::new(JsBigInt::neg(x)), }) } diff --git a/boa/src/value/tests.rs b/boa/src/value/tests.rs index 1323aa344e..ba3fbcab1c 100644 --- a/boa/src/value/tests.rs +++ b/boa/src/value/tests.rs @@ -9,21 +9,21 @@ use std::hash::{Hash, Hasher}; #[test] fn is_object() { let context = Context::new(); - let val = Value::new_object(&context); + let val = JsValue::new_object(&context); assert!(val.is_object()); } #[test] fn string_to_value() { let s = String::from("Hello"); - let v = Value::from(s); + let v = JsValue::new(s); assert!(v.is_string()); assert!(!v.is_null()); } #[test] fn undefined() { - let u = Value::Undefined; + let u = JsValue::undefined(); assert_eq!(u.get_type(), Type::Undefined); assert_eq!(u.display().to_string(), "undefined"); } @@ -31,9 +31,9 @@ fn undefined() { #[test] fn get_set_field() { let mut context = Context::new(); - let obj = Value::new_object(&context); + let obj = JsValue::new_object(&context); // Create string and convert it to a Value - let s = Value::from("bar"); + let s = JsValue::new("bar"); obj.set_field("foo", s, false, &mut context).unwrap(); assert_eq!( obj.get_field("foo", &mut context) @@ -46,19 +46,19 @@ fn get_set_field() { #[test] fn integer_is_true() { - assert!(Value::from(1).to_boolean()); - assert!(!Value::from(0).to_boolean()); - assert!(Value::from(-1).to_boolean()); + assert!(JsValue::new(1).to_boolean()); + assert!(!JsValue::new(0).to_boolean()); + assert!(JsValue::new(-1).to_boolean()); } #[test] fn number_is_true() { - assert!(Value::from(1.0).to_boolean()); - assert!(Value::from(0.1).to_boolean()); - assert!(!Value::from(0.0).to_boolean()); - assert!(!Value::from(-0.0).to_boolean()); - assert!(Value::from(-1.0).to_boolean()); - assert!(!Value::nan().to_boolean()); + assert!(JsValue::new(1.0).to_boolean()); + assert!(JsValue::new(0.1).to_boolean()); + assert!(!JsValue::new(0.0).to_boolean()); + assert!(!JsValue::new(-0.0).to_boolean()); + assert!(JsValue::new(-1.0).to_boolean()); + assert!(!JsValue::nan().to_boolean()); } // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness @@ -124,7 +124,7 @@ fn abstract_equality_comparison() { } /// Helper function to get the hash of a `Value`. -fn hash_value(value: &Value) -> u64 { +fn hash_value(value: &JsValue) -> u64 { let mut hasher = DefaultHasher::new(); value.hash(&mut hasher); hasher.finish() @@ -132,11 +132,11 @@ fn hash_value(value: &Value) -> u64 { #[test] fn hash_undefined() { - let value1 = Value::undefined(); + let value1 = JsValue::undefined(); let value_clone = value1.clone(); assert_eq!(value1, value_clone); - let value2 = Value::undefined(); + let value2 = JsValue::undefined(); assert_eq!(value1, value2); assert_eq!(hash_value(&value1), hash_value(&value_clone)); @@ -146,25 +146,25 @@ fn hash_undefined() { #[test] #[allow(clippy::eq_op)] fn hash_rational() { - let value1 = Value::rational(1.0); - let value2 = Value::rational(1.0); + let value1 = JsValue::new(1.0); + let value2 = JsValue::new(1.0); assert_eq!(value1, value2); assert_eq!(hash_value(&value1), hash_value(&value2)); - let nan = Value::nan(); + let nan = JsValue::nan(); assert_eq!(nan, nan); assert_eq!(hash_value(&nan), hash_value(&nan)); - assert_ne!(hash_value(&nan), hash_value(&Value::rational(1.0))); + assert_ne!(hash_value(&nan), hash_value(&JsValue::new(1.0))); } #[test] #[allow(clippy::eq_op)] fn hash_object() { - let object1 = Value::object(Object::default()); + let object1 = JsValue::new(Object::default()); assert_eq!(object1, object1); assert_eq!(object1, object1.clone()); - let object2 = Value::object(Object::default()); + let object2 = JsValue::new(Object::default()); assert_ne!(object1, object2); assert_eq!(hash_value(&object1), hash_value(&object1.clone())); @@ -229,7 +229,7 @@ fn get_types() { #[test] fn to_string() { - let f64_to_str = |f| Value::Rational(f).display().to_string(); + let f64_to_str = |f| JsValue::new(f).display().to_string(); assert_eq!(f64_to_str(f64::NAN), "NaN"); assert_eq!(f64_to_str(0.0), "0"); @@ -265,7 +265,7 @@ fn to_string() { fn string_length_is_not_enumerable() { let mut context = Context::new(); - let object = Value::from("foo").to_object(&mut context).unwrap(); + let object = JsValue::new("foo").to_object(&mut context).unwrap(); let length_desc = object .__get_own_property__(&PropertyKey::from("length")) .unwrap(); @@ -277,7 +277,7 @@ fn string_length_is_in_utf16_codeunits() { let mut context = Context::new(); // ๐Ÿ˜€ is one Unicode code point, but 2 UTF-16 code units - let object = Value::from("๐Ÿ˜€").to_object(&mut context).unwrap(); + let object = JsValue::new("๐Ÿ˜€").to_object(&mut context).unwrap(); let length_desc = object .__get_own_property__(&PropertyKey::from("length")) .unwrap(); @@ -446,7 +446,7 @@ fn assign_pow_number_and_string() { #[test] fn display_string() { let s = String::from("Hello"); - let v = Value::from(s); + let v = JsValue::new(s); assert_eq!(v.display().to_string(), "\"Hello\""); } @@ -563,45 +563,45 @@ fn to_integer_or_infinity() { let mut context = Context::new(); assert_eq!( - Value::undefined().to_integer_or_infinity(&mut context), + JsValue::undefined().to_integer_or_infinity(&mut context), Ok(IntegerOrInfinity::Integer(0)) ); assert_eq!( - Value::nan().to_integer_or_infinity(&mut context), + JsValue::nan().to_integer_or_infinity(&mut context), Ok(IntegerOrInfinity::Integer(0)) ); assert_eq!( - Value::from(0.0).to_integer_or_infinity(&mut context), + JsValue::new(0.0).to_integer_or_infinity(&mut context), Ok(IntegerOrInfinity::Integer(0)) ); assert_eq!( - Value::from(-0.0).to_integer_or_infinity(&mut context), + JsValue::new(-0.0).to_integer_or_infinity(&mut context), Ok(IntegerOrInfinity::Integer(0)) ); assert_eq!( - Value::from(f64::INFINITY).to_integer_or_infinity(&mut context), + JsValue::new(f64::INFINITY).to_integer_or_infinity(&mut context), Ok(IntegerOrInfinity::PositiveInfinity) ); assert_eq!( - Value::from(f64::NEG_INFINITY).to_integer_or_infinity(&mut context), + JsValue::new(f64::NEG_INFINITY).to_integer_or_infinity(&mut context), Ok(IntegerOrInfinity::NegativeInfinity) ); assert_eq!( - Value::from(10).to_integer_or_infinity(&mut context), + JsValue::new(10).to_integer_or_infinity(&mut context), Ok(IntegerOrInfinity::Integer(10)) ); assert_eq!( - Value::from(11.0).to_integer_or_infinity(&mut context), + JsValue::new(11.0).to_integer_or_infinity(&mut context), Ok(IntegerOrInfinity::Integer(11)) ); assert_eq!( - Value::from("12").to_integer_or_infinity(&mut context), + JsValue::new("12").to_integer_or_infinity(&mut context), Ok(IntegerOrInfinity::Integer(12)) ); assert_eq!( - Value::from(true).to_integer_or_infinity(&mut context), + JsValue::new(true).to_integer_or_infinity(&mut context), Ok(IntegerOrInfinity::Integer(1)) ); } @@ -709,7 +709,7 @@ mod cyclic_conversions { let value = forward_val(&mut context, src).unwrap(); // There isn't an as_boolean function for some reason? - assert_eq!(value, Value::Boolean(true)); + assert_eq!(value, JsValue::new(true)); } #[test] diff --git a/boa/src/value/type.rs b/boa/src/value/type.rs index bcd6f38240..fec00c85e2 100644 --- a/boa/src/value/type.rs +++ b/boa/src/value/type.rs @@ -1,4 +1,4 @@ -use super::Value; +use super::JsValue; /// Possible types of values as defined at . #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -13,7 +13,7 @@ pub enum Type { Object, } -impl Value { +impl JsValue { /// Get the type of a value /// /// This is the abstract operation Type(v), as described in diff --git a/boa/src/vm/code_block.rs b/boa/src/vm/code_block.rs index ad221bd406..ae7f1bcdf4 100644 --- a/boa/src/vm/code_block.rs +++ b/boa/src/vm/code_block.rs @@ -1,4 +1,4 @@ -use crate::{vm::Opcode, JsString, Value}; +use crate::{vm::Opcode, JsString, JsValue}; use std::{convert::TryInto, fmt::Write, mem::size_of}; @@ -22,7 +22,7 @@ pub struct CodeBlock { pub(crate) code: Vec, /// Literals - pub(crate) literals: Vec, + pub(crate) literals: Vec, /// Variables names pub(crate) names: Vec, diff --git a/boa/src/vm/mod.rs b/boa/src/vm/mod.rs index 11f7dd3e4a..9809f3fcbd 100644 --- a/boa/src/vm/mod.rs +++ b/boa/src/vm/mod.rs @@ -4,7 +4,7 @@ use crate::{ builtins::Array, environment::lexical_environment::VariableScope, symbol::WellKnownSymbols, - BoaProfiler, Context, Result, Value, + BoaProfiler, Context, JsValue, Result, }; mod code_block; @@ -23,7 +23,7 @@ pub struct Vm<'a> { context: &'a mut Context, pc: usize, code: CodeBlock, - stack: Vec, + stack: Vec, stack_pointer: usize, is_trace: bool, } @@ -48,7 +48,7 @@ impl<'a> Vm<'a> { #[inline] pub fn push(&mut self, value: T) where - T: Into, + T: Into, { self.stack.push(value.into()); } @@ -60,7 +60,7 @@ impl<'a> Vm<'a> { /// If there is nothing to pop, then this will panic. #[inline] #[track_caller] - pub fn pop(&mut self) -> Value { + pub fn pop(&mut self) -> JsValue { self.stack.pop().unwrap() } @@ -102,8 +102,8 @@ impl<'a> Vm<'a> { self.push(first); self.push(second); } - Opcode::PushUndefined => self.push(Value::undefined()), - Opcode::PushNull => self.push(Value::null()), + Opcode::PushUndefined => self.push(JsValue::undefined()), + Opcode::PushNull => self.push(JsValue::null()), Opcode::PushTrue => self.push(true), Opcode::PushFalse => self.push(false), Opcode::PushZero => self.push(0), @@ -124,15 +124,15 @@ impl<'a> Vm<'a> { let value = self.read::(); self.push(value); } - Opcode::PushNaN => self.push(Value::nan()), - Opcode::PushPositiveInfinity => self.push(Value::positive_inifnity()), - Opcode::PushNegativeInfinity => self.push(Value::negative_inifnity()), + Opcode::PushNaN => self.push(JsValue::nan()), + Opcode::PushPositiveInfinity => self.push(JsValue::positive_inifnity()), + Opcode::PushNegativeInfinity => self.push(JsValue::negative_inifnity()), Opcode::PushLiteral => { let index = self.read::() as usize; let value = self.code.literals[index].clone(); self.push(value) } - Opcode::PushEmptyObject => self.push(Value::new_object(self.context)), + Opcode::PushEmptyObject => self.push(JsValue::new_object(self.context)), Opcode::PushNewArray => { let count = self.read::(); let mut elements = Vec::with_capacity(count as usize); @@ -224,7 +224,7 @@ impl<'a> Vm<'a> { } Opcode::Void => { let _ = self.pop(); - self.push(Value::undefined()); + self.push(JsValue::undefined()); } Opcode::TypeOf => { let value = self.pop(); @@ -445,7 +445,7 @@ impl<'a> Vm<'a> { Ok(()) } - pub fn run(&mut self) -> Result { + pub fn run(&mut self) -> Result { let _timer = BoaProfiler::global().start_event("run", "vm"); const COLUMN_WIDTH: usize = 24; @@ -520,7 +520,7 @@ impl<'a> Vm<'a> { } if self.stack.is_empty() { - return Ok(Value::undefined()); + return Ok(JsValue::undefined()); } Ok(self.pop()) diff --git a/boa_tester/src/exec/js262.rs b/boa_tester/src/exec/js262.rs index a4c2286350..a892469a86 100644 --- a/boa_tester/src/exec/js262.rs +++ b/boa_tester/src/exec/js262.rs @@ -2,7 +2,7 @@ use boa::{ exec::Executable, object::{GcObject, ObjectInitializer}, property::Attribute, - Context, Result, Value, + Context, JsValue, Result, }; /// Initializes the object in the context. @@ -25,7 +25,7 @@ pub(super) fn init(context: &mut Context) -> GcObject { /// /// Creates a new ECMAScript Realm, defines this API on the new realm's global object, and /// returns the `$262` property of the new realm's global object. -fn create_realm(_this: &Value, _: &[Value], _context: &mut Context) -> Result { +fn create_realm(_this: &JsValue, _: &[JsValue], _context: &mut Context) -> Result { // eprintln!("called $262.createRealm()"); let mut context = Context::new(); @@ -33,21 +33,21 @@ fn create_realm(_this: &Value, _: &[Value], _context: &mut Context) -> Result Result { +fn detach_array_buffer(_this: &JsValue, _: &[JsValue], _context: &mut Context) -> Result { todo!() } /// The `$262.evalScript()` function. /// /// Accepts a string value as its first argument and executes it as an ECMAScript script. -fn eval_script(_this: &Value, args: &[Value], context: &mut Context) -> Result { +fn eval_script(_this: &JsValue, args: &[JsValue], context: &mut Context) -> Result { // eprintln!("called $262.evalScript()"); if let Some(source_text) = args.get(0).and_then(|val| val.as_string()) { @@ -57,7 +57,7 @@ fn eval_script(_this: &Value, args: &[Value], context: &mut Context) -> Result script.run(context), } } else { - Ok(Value::undefined()) + Ok(JsValue::undefined()) } } @@ -67,6 +67,6 @@ fn eval_script(_this: &Value, args: &[Value], context: &mut Context) -> Result Result { +fn gc(_this: &JsValue, _: &[JsValue], _context: &mut Context) -> Result { todo!() } diff --git a/boa_tester/src/exec/mod.rs b/boa_tester/src/exec/mod.rs index b8be340439..8e77b42b75 100644 --- a/boa_tester/src/exec/mod.rs +++ b/boa_tester/src/exec/mod.rs @@ -6,7 +6,7 @@ use super::{ Harness, Outcome, Phase, SuiteResult, Test, TestFlags, TestOutcomeResult, TestResult, TestSuite, IGNORED, }; -use boa::{parse, Context, Value}; +use boa::{parse, Context, JsValue}; use colored::Colorize; use rayon::prelude::*; use std::panic; @@ -312,6 +312,6 @@ impl Test { } /// `print()` function required by the test262 suite. -fn test262_print(_this: &Value, _: &[Value], _context: &mut Context) -> boa::Result { +fn test262_print(_this: &JsValue, _: &[JsValue], _context: &mut Context) -> boa::Result { todo!("print() function"); }