diff --git a/boa/src/builtins/bigint/mod.rs b/boa/src/builtins/bigint/mod.rs index d992d341487..4be4b7af0cd 100644 --- a/boa/src/builtins/bigint/mod.rs +++ b/boa/src/builtins/bigint/mod.rs @@ -135,7 +135,7 @@ impl BigInt { // 1. Let x be ? thisBigIntValue(this value). let x = Self::this_bigint_value(this, context)?; - let radix = args.get(0).cloned().unwrap_or_default(); + let radix = args.get_or_undefined(0); // 2. If radix is undefined, let radixMV be 10. let radix_mv = if radix.is_undefined() { diff --git a/boa/src/builtins/date/mod.rs b/boa/src/builtins/date/mod.rs index a7784e9e494..026cce62ae8 100644 --- a/boa/src/builtins/date/mod.rs +++ b/boa/src/builtins/date/mod.rs @@ -13,6 +13,8 @@ use crate::{ use chrono::{prelude::*, Duration, LocalResult}; use std::fmt::Display; +use super::JsArgs; + /// The number of nanoseconds in a millisecond. const NANOS_PER_MS: i64 = 1_000_000; /// The number of milliseconds in an hour. @@ -523,7 +525,7 @@ impl Date { return context.throw_type_error("Date.prototype[@@toPrimitive] called on non object"); }; - let hint = args.get(0).cloned().unwrap_or_default(); + let hint = args.get_or_undefined(0); let try_first = match hint.as_string().map(|s| s.as_str()) { // 3. If hint is "string" or "default", then diff --git a/boa/src/builtins/json/mod.rs b/boa/src/builtins/json/mod.rs index f738292bcd7..cfc73e0d893 100644 --- a/boa/src/builtins/json/mod.rs +++ b/boa/src/builtins/json/mod.rs @@ -28,6 +28,8 @@ use crate::{ }; use serde_json::{self, Value as JSONValue}; +use super::JsArgs; + #[cfg(test)] mod tests; @@ -158,7 +160,7 @@ impl Json { let mut property_list = None; let mut replacer_function = None; - let replacer = args.get(1).cloned().unwrap_or_default(); + let replacer = args.get_or_undefined(1); // 4. If Type(replacer) is Object, then if let Some(replacer_obj) = replacer.as_object() { @@ -214,7 +216,7 @@ impl Json { } } - let mut space = args.get(2).cloned().unwrap_or_default(); + let mut space = args.get_or_undefined(2).clone(); // 5. If Type(space) is Object, then if let Some(space_obj) = space.as_object() { @@ -266,7 +268,7 @@ impl Json { // 10. Perform ! CreateDataPropertyOrThrow(wrapper, the empty String, value). wrapper - .create_data_property_or_throw("", args.get(0).cloned().unwrap_or_default(), context) + .create_data_property_or_throw("", args.get_or_undefined(0).clone(), context) .expect("CreateDataPropertyOrThrow should never fail here"); // 11. Let state be the Record { [[ReplacerFunction]]: ReplacerFunction, [[Stack]]: stack, [[Indent]]: indent, [[Gap]]: gap, [[PropertyList]]: PropertyList }. diff --git a/boa/src/builtins/mod.rs b/boa/src/builtins/mod.rs index 78173840c3c..e9f17db73ba 100644 --- a/boa/src/builtins/mod.rs +++ b/boa/src/builtins/mod.rs @@ -114,6 +114,17 @@ pub fn init(context: &mut Context) { } pub trait JsArgs { + /// Utility function to `get` a parameter from + /// a `[JsValue]` or default to `JsValue::Undefined` + /// if `get` returns `None`. + /// + /// Call this if you are thinking of calling something similar to + /// `args.get(n).cloned().unwrap_or_default()` or + /// `args.get(n).unwrap_or(&undefined)`. + /// + /// This returns a reference for efficiency, in case + /// you only need to call methods of `JsValue`, so + /// try to minimize calling `clone`. fn get_or_undefined(&self, index: usize) -> &JsValue; }