Skip to content

Commit

Permalink
Return &JsValue from get_or_undefined instead of cloning
Browse files Browse the repository at this point in the history
  • Loading branch information
jedel1043 committed Aug 24, 2021
1 parent 2ddb421 commit 5c96fc0
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 60 deletions.
22 changes: 11 additions & 11 deletions boa/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
}
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)?;
}
Expand Down Expand Up @@ -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));
}
}
Expand Down Expand Up @@ -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,
)?
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
)?;

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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");
Expand All @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion boa/src/builtins/console/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<JsValue> {
logger(
LogMessage::Info(display_obj(&args.get_or_undefined(0), true)),
LogMessage::Info(display_obj(args.get_or_undefined(0), true)),
context.console(),
);

Expand Down
6 changes: 3 additions & 3 deletions boa/src/builtins/function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand All @@ -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)
}
}

Expand Down
10 changes: 5 additions & 5 deletions boa/src/builtins/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"));
Expand Down Expand Up @@ -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"));
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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());
}
}

Expand Down Expand Up @@ -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;
Expand Down
7 changes: 4 additions & 3 deletions boa/src/builtins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
19 changes: 12 additions & 7 deletions boa/src/builtins/object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ impl Object {

let obj = match prototype {
JsValue::Object(_) | JsValue::Null => JsValue::new(BuiltinObject::with_prototype(
prototype,
prototype.clone(),
ObjectData::Ordinary,
)),
_ => {
Expand All @@ -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)
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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 {
Expand All @@ -350,10 +354,11 @@ impl Object {
args: &[JsValue],
context: &mut Context,
) -> JsResult<JsValue> {
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)?;
Expand Down Expand Up @@ -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")
}
Expand Down
8 changes: 5 additions & 3 deletions boa/src/builtins/reflect/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand All @@ -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())
}
}
6 changes: 3 additions & 3 deletions boa/src/builtins/regexp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down Expand Up @@ -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
Expand Down
19 changes: 10 additions & 9 deletions boa/src/builtins/set/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?;
Expand Down Expand Up @@ -208,14 +208,15 @@ impl Set {
args: &[JsValue],
context: &mut Context,
) -> JsResult<JsValue> {
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");
}
Expand Down Expand Up @@ -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");
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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());
}
}

Expand Down
Loading

0 comments on commit 5c96fc0

Please sign in to comment.