diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index 0459bd97f39..b9ed750fbbb 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -688,7 +688,7 @@ impl Array { let k_value = o.get(pk, context)?; // ii. Perform ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »). let this_arg = args.get_or_undefined(1); - callback.call(&this_arg, &[k_value, k.into(), o.clone().into()], context)?; + callback.call(this_arg, &[k_value, k.into(), o.clone().into()], context)?; } // d. Set k to k + 1. } @@ -1036,7 +1036,7 @@ impl Array { let k_value = o.get(k, context)?; // ii. Let testResult be ! ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)). let test_result = callback - .call(&this_arg, &[k_value, k.into(), o.clone().into()], context)? + .call(this_arg, &[k_value, k.into(), o.clone().into()], context)? .to_boolean(); // iii. If testResult is false, return false. if !test_result { @@ -1092,7 +1092,7 @@ impl Array { let k_value = o.get(k, context)?; // ii. Let mappedValue be ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »). let mapped_value = - context.call(&callback, &this_arg, &[k_value, k.into(), this.into()])?; + context.call(callback, this_arg, &[k_value, k.into(), this.into()])?; // iii. Perform ? CreateDataPropertyOrThrow(A, Pk, mappedValue). a.create_data_property_or_throw(k, mapped_value, context)?; } @@ -1244,7 +1244,7 @@ impl Array { let element_k = o.get(k, context)?; // ii. Let same be IsStrictlyEqual(searchElement, elementK). // iii. If same is true, return 𝔽(k). - if JsValue::strict_equals(&search_element, &element_k) { + if JsValue::strict_equals(search_element, &element_k) { return Ok(JsValue::new(k)); } } @@ -1299,7 +1299,7 @@ impl Array { // c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)). let test_result = predicate .call( - &this_arg, + this_arg, &[k_value.clone(), k.into(), o.clone().into()], context, )? @@ -1359,7 +1359,7 @@ impl Array { let k_value = o.get(pk, context)?; // c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)). let test_result = predicate - .call(&this_arg, &[k_value, k.into(), o.clone().into()], context)? + .call(this_arg, &[k_value, k.into(), o.clone().into()], context)? .to_boolean(); // d. If testResult is true, return 𝔽(k). if test_result { @@ -1467,7 +1467,7 @@ impl Array { 0, 1, Some(mapper_function.as_object().unwrap()), - &args.get_or_undefined(1), + args.get_or_undefined(1), context, )?; @@ -1700,7 +1700,7 @@ 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 JsValue::same_value_zero(&search_element, &element_k) { + if JsValue::same_value_zero(search_element, &element_k) { return Ok(JsValue::new(true)); } // c. Set k to k + 1. @@ -1813,7 +1813,7 @@ impl Array { "missing argument 0 when calling function Array.prototype.filter", ) })?; - let this_val = args.get_or_undefined(1); + let this_arg = args.get_or_undefined(1); if !callback.is_callable() { return context.throw_type_error("the callback must be callable"); @@ -1837,7 +1837,7 @@ impl Array { 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(); + let selected = callback.call(this_arg, &args, context)?.to_boolean(); // iii. If selected is true, then if selected { @@ -1901,7 +1901,7 @@ impl Array { // ii. Let testResult be ! ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)). let this_arg = args.get_or_undefined(1); let test_result = callback - .call(&this_arg, &[k_value, k.into(), o.clone().into()], context)? + .call(this_arg, &[k_value, k.into(), o.clone().into()], context)? .to_boolean(); // iii. If testResult is true, return true. if test_result { diff --git a/boa/src/builtins/console/mod.rs b/boa/src/builtins/console/mod.rs index b645b5739b7..e6c8abd586c 100644 --- a/boa/src/builtins/console/mod.rs +++ b/boa/src/builtins/console/mod.rs @@ -565,7 +565,7 @@ impl Console { /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/dir pub(crate) fn dir(_: &JsValue, args: &[JsValue], context: &mut Context) -> JsResult { logger( - LogMessage::Info(display_obj(&args.get_or_undefined(0), true)), + LogMessage::Info(display_obj(args.get_or_undefined(0), true)), context.console(), ); diff --git a/boa/src/builtins/function/mod.rs b/boa/src/builtins/function/mod.rs index 711847a1501..26d55f0f31a 100644 --- a/boa/src/builtins/function/mod.rs +++ b/boa/src/builtins/function/mod.rs @@ -318,7 +318,7 @@ impl BuiltInFunctionObject { let this_arg = args.get_or_undefined(0); // TODO?: 3. Perform PrepareForTailCall let start = if !args.is_empty() { 1 } else { 0 }; - context.call(this, &this_arg, &args[start..]) + context.call(this, this_arg, &args[start..]) } /// `Function.prototype.apply` @@ -340,14 +340,14 @@ impl BuiltInFunctionObject { let arg_array = args.get_or_undefined(1); if arg_array.is_null_or_undefined() { // TODO?: 3.a. PrepareForTailCall - return context.call(this, &this_arg, &[]); + return context.call(this, this_arg, &[]); } let arg_array = arg_array.as_object().ok_or_else(|| { context.construct_type_error("argList must be null, undefined or an object") })?; let arg_list = arg_array.create_list_from_array_like(&[], context)?; // TODO?: 5. PrepareForTailCall - context.call(this, &this_arg, &arg_list) + context.call(this, this_arg, &arg_list) } } diff --git a/boa/src/builtins/map/mod.rs b/boa/src/builtins/map/mod.rs index 8b361deb8f0..cd8f01facd3 100644 --- a/boa/src/builtins/map/mod.rs +++ b/boa/src/builtins/map/mod.rs @@ -252,7 +252,7 @@ impl Map { let size = if let Some(object) = this.as_object() { if let Some(map) = object.borrow_mut().as_map_mut() { - map.insert(key, value); + map.insert(key.clone(), value.clone()); map.len() } else { return Err(context.construct_type_error("'this' is not a Map")); @@ -284,7 +284,7 @@ impl Map { 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")); @@ -316,7 +316,7 @@ impl Map { 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 { JsValue::undefined() @@ -365,7 +365,7 @@ impl Map { 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()); } } @@ -415,7 +415,7 @@ impl Map { }; if let Some(arguments) = arguments { - context.call(callback_arg, &this_arg, &arguments)?; + context.call(callback_arg, this_arg, &arguments)?; } index += 1; diff --git a/boa/src/builtins/mod.rs b/boa/src/builtins/mod.rs index 4b2124e196f..78173840c3c 100644 --- a/boa/src/builtins/mod.rs +++ b/boa/src/builtins/mod.rs @@ -114,11 +114,12 @@ pub fn init(context: &mut Context) { } pub trait JsArgs { - fn get_or_undefined(&self, index: usize) -> JsValue; + fn get_or_undefined(&self, index: usize) -> &JsValue; } impl JsArgs for [JsValue] { - fn get_or_undefined(&self, index: usize) -> JsValue { - self.get(index).cloned().unwrap_or_default() + fn get_or_undefined(&self, index: usize) -> &JsValue { + const UNDEFINED: &JsValue = &JsValue::Undefined; + self.get(index).unwrap_or(UNDEFINED) } } diff --git a/boa/src/builtins/object/mod.rs b/boa/src/builtins/object/mod.rs index 37e925d5145..b173b48d013 100644 --- a/boa/src/builtins/object/mod.rs +++ b/boa/src/builtins/object/mod.rs @@ -132,7 +132,7 @@ impl Object { let obj = match prototype { JsValue::Object(_) | JsValue::Null => JsValue::new(BuiltinObject::with_prototype( - prototype, + prototype.clone(), ObjectData::Ordinary, )), _ => { @@ -144,7 +144,11 @@ impl Object { }; if !properties.is_undefined() { - return Object::define_properties(&JsValue::undefined(), &[obj, properties], context); + return Object::define_properties( + &JsValue::undefined(), + &[obj, properties.clone()], + context, + ); } Ok(obj) @@ -267,7 +271,7 @@ impl Object { let x = args.get_or_undefined(0); let y = args.get_or_undefined(1); - Ok(JsValue::same_value(&x, &y).into()) + Ok(JsValue::same_value(x, y).into()) } /// Get the `prototype` of an object. @@ -324,7 +328,7 @@ impl Object { let status = obj .as_object() .expect("obj was not an object") - .__set_prototype_of__(proto); + .__set_prototype_of__(proto.clone()); // 5. If status is false, throw a TypeError exception. if !status { @@ -350,10 +354,11 @@ impl Object { args: &[JsValue], context: &mut Context, ) -> JsResult { - let mut v = args.get_or_undefined(0); + let v = args.get_or_undefined(0); if !v.is_object() { return Ok(JsValue::new(false)); } + let mut v = v.clone(); let o = JsValue::new(this.to_object(context)?); loop { v = Self::get_prototype_of(this, &[v], context)?; @@ -410,8 +415,8 @@ impl Object { let arg_obj = arg.as_object(); if let Some(mut obj) = arg_obj { let props = args.get_or_undefined(1); - obj.define_properties(props, context)?; - Ok(arg) + obj.define_properties(props.clone(), context)?; + Ok(arg.clone()) } else { context.throw_type_error("Expected an object") } diff --git a/boa/src/builtins/reflect/mod.rs b/boa/src/builtins/reflect/mod.rs index 31e8da00532..1535e6f0b75 100644 --- a/boa/src/builtins/reflect/mod.rs +++ b/boa/src/builtins/reflect/mod.rs @@ -91,7 +91,7 @@ impl Reflect { return context.throw_type_error("target must be a function"); } let args = args_list.create_list_from_array_like(&[], context)?; - target.call(&this_arg, &args, context) + target.call(this_arg, &args, context) } /// Calls a target function as a constructor with arguments. @@ -371,7 +371,9 @@ impl Reflect { } else { target.clone().into() }; - Ok(target.__set__(key, value, receiver, context)?.into()) + Ok(target + .__set__(key, value.clone(), receiver, context)? + .into()) } /// Sets the prototype of an object. @@ -395,6 +397,6 @@ impl Reflect { if !proto.is_null() && !proto.is_object() { return context.throw_type_error("proto must be an object or null"); } - Ok(target.__set_prototype_of__(proto).into()) + Ok(target.__set_prototype_of__(proto.clone()).into()) } } diff --git a/boa/src/builtins/regexp/mod.rs b/boa/src/builtins/regexp/mod.rs index 9725e329318..c1d8a8cc89a 100644 --- a/boa/src/builtins/regexp/mod.rs +++ b/boa/src/builtins/regexp/mod.rs @@ -235,12 +235,12 @@ impl RegExp { JsValue::new(regexp.original_flags.clone()), ) } else { - (JsValue::new(regexp.original_source.clone()), flags) + (JsValue::new(regexp.original_source.clone()), flags.clone()) } } else { // a. Let P be pattern. // b. Let F be flags. - (pattern, flags) + (pattern.clone(), flags.clone()) }; // 7. Let O be ? RegExpAlloc(newTarget). @@ -1284,7 +1284,7 @@ impl RegExp { let length_arg_str = arg_str.encode_utf16().count(); // 5. Let functionalReplace be IsCallable(replaceValue). - let mut replace_value = args.get_or_undefined(1); + let mut replace_value = args.get_or_undefined(1).clone(); let functional_replace = replace_value.is_function(); // 6. If functionalReplace is false, then diff --git a/boa/src/builtins/set/mod.rs b/boa/src/builtins/set/mod.rs index de40c3ca3f9..52490678558 100644 --- a/boa/src/builtins/set/mod.rs +++ b/boa/src/builtins/set/mod.rs @@ -156,7 +156,7 @@ impl Set { } // 7 - let iterator_record = get_iterator(context, iterable)?; + let iterator_record = get_iterator(context, iterable.clone())?; // 8.a let mut next = iterator_record.next(context)?; @@ -208,14 +208,15 @@ impl Set { args: &[JsValue], context: &mut Context, ) -> JsResult { - let mut value = args.get_or_undefined(0); + let value = args.get_or_undefined(0); 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 = JsValue::Integer(0); - } - set.add(value); + set.add(if value.as_number().map(|n| n == -0f64).unwrap_or(false) { + JsValue::Integer(0) + } else { + value.clone() + }); } else { return context.throw_type_error("'this' is not a Set"); } @@ -269,7 +270,7 @@ impl Set { let res = if let Some(object) = this.as_object() { if let Some(set) = object.borrow_mut().as_set_mut() { - set.delete(&value) + set.delete(value) } else { return context.throw_type_error("'this' is not a Set"); } @@ -339,7 +340,7 @@ impl Set { let this_arg = if this_arg.is_undefined() { JsValue::Object(context.global_object()) } else { - this_arg + this_arg.clone() }; let mut index = 0; @@ -387,7 +388,7 @@ impl Set { 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()); } } diff --git a/boa/src/builtins/string/mod.rs b/boa/src/builtins/string/mod.rs index 71a83ce5b79..ea490f03c0a 100644 --- a/boa/src/builtins/string/mod.rs +++ b/boa/src/builtins/string/mod.rs @@ -542,7 +542,7 @@ impl String { let arg = args.get_or_undefined(0); - if Self::is_regexp_object(&arg) { + if Self::is_regexp_object(arg) { context.throw_type_error( "First argument to String.prototype.startsWith must not be a regular expression", )?; @@ -595,7 +595,7 @@ impl String { let arg = args.get_or_undefined(0); - if Self::is_regexp_object(&arg) { + if Self::is_regexp_object(arg) { context.throw_type_error( "First argument to String.prototype.endsWith must not be a regular expression", )?; @@ -647,7 +647,7 @@ impl String { let arg = args.get_or_undefined(0); - if Self::is_regexp_object(&arg) { + if Self::is_regexp_object(arg) { context.throw_type_error( "First argument to String.prototype.includes must not be a regular expression", )?; @@ -720,8 +720,8 @@ impl String { // i. Return ? Call(replacer, searchValue, « O, replaceValue »). return context.call( &replacer.into(), - &search_value, - &[this.clone(), replace_value], + search_value, + &[this.clone(), replace_value.clone()], ); } } @@ -760,7 +760,7 @@ impl String { // a. Let replacement be ? ToString(? Call(replaceValue, undefined, « searchString, 𝔽(position), string »)). context .call( - &replace_value, + replace_value, &JsValue::undefined(), &[search_str.into(), position.into(), this_str.clone().into()], )? @@ -852,7 +852,7 @@ impl String { // d. If replacer is not undefined, then if let Some(replacer) = replacer { // i. Return ? Call(replacer, searchValue, « O, replaceValue »). - return replacer.call(&search_value, &[o.into(), replace_value], context); + return replacer.call(search_value, &[o.into(), replace_value.clone()], context); } } @@ -918,7 +918,7 @@ impl String { // i. Let replacement be ? ToString(? Call(replaceValue, undefined, « searchString, 𝔽(p), string »)). context .call( - &replace_value, + replace_value, &JsValue::undefined(), &[ search_string.clone().into(), @@ -1089,7 +1089,7 @@ impl String { if let Some(obj) = regexp.as_object() { if let Some(matcher) = obj.get_method(context, WellKnownSymbols::match_())? { // i. Return ? Call(matcher, regexp, « O »). - return matcher.call(®exp, &[o.clone()], context); + return matcher.call(regexp, &[o.clone()], context); } } } @@ -1098,7 +1098,7 @@ impl String { let s = o.to_string(context)?; // 4. Let rx be ? RegExpCreate(regexp, undefined). - let rx = RegExp::create(regexp, JsValue::undefined(), context)?; + let rx = RegExp::create(regexp.clone(), JsValue::undefined(), context)?; // 5. Return ? Invoke(rx, @@match, « S »). let obj = rx.as_object().expect("RegExpCreate must return Object"); @@ -1463,7 +1463,7 @@ impl String { .get_method(context, WellKnownSymbols::split())? { // i. Return ? Call(splitter, separator, « O, limit »). - return splitter.call(&separator, &[this.clone(), limit], context); + return splitter.call(separator, &[this.clone(), limit.clone()], context); } } @@ -1650,7 +1650,7 @@ impl String { if let Some(obj) = regexp.as_object() { if let Some(matcher) = obj.get_method(context, WellKnownSymbols::match_all())? { // i. Return ? Call(matcher, regexp, « O »). - return matcher.call(®exp, &[o.clone()], context); + return matcher.call(regexp, &[o.clone()], context); } } } @@ -1659,7 +1659,7 @@ impl String { let s = o.to_string(context)?; // 4. Let rx be ? RegExpCreate(regexp, "g"). - let rx = RegExp::create(regexp, JsValue::new("g"), context)?; + let rx = RegExp::create(regexp.clone(), JsValue::new("g"), context)?; // 5. Return ? Invoke(rx, @@matchAll, « S »). let obj = rx.as_object().expect("RegExpCreate must return Object"); @@ -1734,7 +1734,7 @@ impl String { if let Some(obj) = regexp.as_object() { if let Some(searcher) = obj.get_method(context, WellKnownSymbols::search())? { // i. Return ? Call(searcher, regexp, « O »). - return searcher.call(®exp, &[o.clone()], context); + return searcher.call(regexp, &[o.clone()], context); } } } @@ -1743,7 +1743,7 @@ impl String { let string = o.to_string(context)?; // 4. Let rx be ? RegExpCreate(regexp, undefined). - let rx = RegExp::create(regexp, JsValue::undefined(), context)?; + let rx = RegExp::create(regexp.clone(), JsValue::undefined(), context)?; // 5. Return ? Invoke(rx, @@search, « string »). let obj = rx.as_object().expect("RegExpCreate must return Object");