Skip to content

Commit

Permalink
Mirror Ref type into default
Browse files Browse the repository at this point in the history
  • Loading branch information
jedel1043 committed May 20, 2022
1 parent c3dc570 commit f67c197
Show file tree
Hide file tree
Showing 12 changed files with 84 additions and 41 deletions.
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ impl BuiltInFunctionObject {
context.construct_type_error("cannot bind `this` without a `[[Call]]` internal method")
})?;

let this_arg = args.get_or_undefined(0).clone();
let this_arg = args.get_or_undefined(0);
let bound_args = args.get(1..).unwrap_or(&[]).to_vec();
let arg_count = bound_args.len() as i64;

Expand Down
4 changes: 2 additions & 2 deletions boa_engine/src/builtins/generator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ impl Generator {
// 1. Let g be the this value.
// 2. Let C be Completion { [[Type]]: return, [[Value]]: value, [[Target]]: empty }.
// 3. Return ? GeneratorResumeAbrupt(g, C, empty).
Self::generator_resume_abrupt(this, Ok(args.get_or_undefined(0).clone()), context)
Self::generator_resume_abrupt(this, Ok(args.get_or_undefined(0)), context)
}

/// `Generator.prototype.throw ( exception )`
Expand All @@ -195,7 +195,7 @@ impl Generator {
// 1. Let g be the this value.
// 2. Let C be ThrowCompletion(exception).
// 3. Return ? GeneratorResumeAbrupt(g, C, empty).
Self::generator_resume_abrupt(this, Err(args.get_or_undefined(0).clone()), context)
Self::generator_resume_abrupt(this, Err(args.get_or_undefined(0)), context)
}

/// `27.5.3.3 GeneratorResume ( generator, value, generatorBrand )`
Expand Down
4 changes: 2 additions & 2 deletions boa_engine/src/builtins/json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ impl Json {
}
}

let mut space = args.get_or_undefined(2).clone();
let mut space = args.get_or_undefined(2);

// 5. If Type(space) is Object, then
if let Some(space_obj) = space.as_object() {
Expand Down Expand Up @@ -332,7 +332,7 @@ impl Json {

// 10. Perform ! CreateDataPropertyOrThrow(wrapper, the empty String, value).
wrapper
.create_data_property_or_throw("", args.get_or_undefined(0).clone(), context)
.create_data_property_or_throw("", args.get_or_undefined(0), context)
.expect("CreateDataPropertyOrThrow should never fail here");

// 11. Let state be the Record { [[ReplacerFunction]]: ReplacerFunction, [[Stack]]: stack, [[Indent]]: indent, [[Gap]]: gap, [[PropertyList]]: PropertyList }.
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ impl Map {
// i. Set p.[[Value]] to value.
// 6. Let p be the Record { [[Key]]: key, [[Value]]: value }.
// 7. Append p as the last element of entries.
map.insert(key, value.clone());
map.insert(key, value);
// ii. Return M.
// 8. Return M.
return Ok(this.clone());
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ impl Object {
if !v.is_object() {
return Ok(JsValue::new(false));
}
let mut v = v.clone();
let mut v = v;
let o = JsValue::new(this.to_object(context)?);
loop {
v = Self::get_prototype_of(this, &[v], context)?;
Expand Down
4 changes: 1 addition & 3 deletions boa_engine/src/builtins/reflect/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,9 +365,7 @@ impl Reflect {
} else {
target.clone().into()
};
Ok(target
.__set__(key, value.clone(), receiver, context)?
.into())
Ok(target.__set__(key, value, receiver, context)?.into())
}

/// Sets the prototype of an object.
Expand Down
6 changes: 3 additions & 3 deletions boa_engine/src/builtins/regexp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,12 @@ impl RegExp {
JsValue::new(regexp.original_flags.clone()),
)
} else {
(JsValue::new(regexp.original_source.clone()), flags.clone())
(JsValue::new(regexp.original_source.clone()), flags)
}
} else {
// a. Let P be pattern.
// b. Let F be flags.
(pattern.clone(), flags.clone())
(pattern.clone(), flags)
};

// 7. Let O be ? RegExpAlloc(newTarget).
Expand Down Expand Up @@ -1254,7 +1254,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).clone();
let mut replace_value = args.get_or_undefined(1);
let functional_replace = replace_value
.as_object()
.as_deref()
Expand Down
6 changes: 3 additions & 3 deletions boa_engine/src/builtins/set/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ impl Set {
})?;

// 7. Let iteratorRecord be ? GetIterator(iterable).
let iterator_record = iterable.clone().get_iterator(context, None, None)?;
let iterator_record = iterable.get_iterator(context, None, None)?;

// 8. Repeat,
// a. Let next be ? IteratorStep(iteratorRecord).
Expand Down Expand Up @@ -202,7 +202,7 @@ impl Set {
set.add(if value.as_number().map_or(false, |n| n == -0f64) {
JsValue::new(0)
} else {
value.clone()
value
});
} else {
return context.throw_type_error("'this' is not a Set");
Expand Down Expand Up @@ -327,7 +327,7 @@ impl Set {
let this_arg = if this_arg.is_undefined() {
context.global_object().clone().into()
} else {
this_arg.clone()
this_arg
};

let mut index = 0;
Expand Down
4 changes: 1 addition & 3 deletions boa_engine/src/object/jstypedarray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ impl JsTypedArray {
#[inline]
pub fn from_object(object: JsObject, context: &mut Context) -> JsResult<Self> {
if object.borrow().is_typed_array() {
Ok(Self {
inner: object.into(),
})
Ok(Self { inner: object })
} else {
context.throw_type_error("object is not a TypedArray")
}
Expand Down
4 changes: 3 additions & 1 deletion boa_engine/src/value/equality.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,9 @@ impl JsValue {
fn same_value_non_numeric(x: &Self, y: &Self) -> bool {
debug_assert!(x.get_type() == y.get_type());
match (x.variant(), y.variant()) {
(JsVariant::Null, JsVariant::Null) | (JsVariant::Undefined, JsVariant::Undefined) => true,
(JsVariant::Null, JsVariant::Null) | (JsVariant::Undefined, JsVariant::Undefined) => {
true
}
(JsVariant::String(x), JsVariant::String(y)) => x == y,
(JsVariant::Boolean(x), JsVariant::Boolean(y)) => x == y,
(JsVariant::Object(ref x), JsVariant::Object(ref y)) => JsObject::equals(x, y),
Expand Down
12 changes: 7 additions & 5 deletions boa_engine/src/value/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,9 @@ impl JsValue {
pub fn to_bigint(&self, context: &mut Context) -> JsResult<JsBigInt> {
match self.variant() {
JsVariant::Null => context.throw_type_error("cannot convert null to a BigInt"),
JsVariant::Undefined => context.throw_type_error("cannot convert undefined to a BigInt"),
JsVariant::Undefined => {
context.throw_type_error("cannot convert undefined to a BigInt")
}
JsVariant::String(string) => {
let string = &*string;
if let Some(value) = JsBigInt::from_string(string) {
Expand Down Expand Up @@ -410,11 +412,11 @@ impl JsValue {
_ => {
let primitive = self.to_primitive(context, PreferredType::String)?;
match primitive.variant() {
JsVariant::String(string) => string.clone().into(),
JsVariant::Symbol(symbol) => symbol.clone().into(),
_ => primitive.to_string(context)?.into(),
JsVariant::String(string) => string.clone().into(),
JsVariant::Symbol(symbol) => symbol.clone().into(),
_ => primitive.to_string(context)?.into(),
}
}
},
})
}

Expand Down
75 changes: 59 additions & 16 deletions boa_engine/src/value/platform/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ use super::JsVariant;

use crate::{object::JsObject, JsBigInt, JsString, JsSymbol};

pub type Ref<'a, T> = &'a T;

/// A Javascript value
#[derive(Trace, Finalize, Debug, Clone)]
pub enum JsValue {
Expand Down Expand Up @@ -108,34 +106,34 @@ impl JsValue {
}

#[inline]
pub fn as_object(&self) -> Option<&JsObject> {
match *self {
Self::Object(ref o) => Some(o),
pub fn as_object(&self) -> Option<Ref<'_, JsObject>> {
match self {
Self::Object(inner) => Some(Ref { inner }),
_ => None,
}
}

/// Returns the string if the values is a string, otherwise `None`.
#[inline]
pub fn as_string(&self) -> Option<&JsString> {
pub fn as_string(&self) -> Option<Ref<'_, JsString>> {
match self {
Self::String(ref string) => Some(string),
Self::String(inner) => Some(Ref { inner }),
_ => None,
}
}

pub fn as_symbol(&self) -> Option<&JsSymbol> {
pub fn as_symbol(&self) -> Option<Ref<'_, JsSymbol>> {
match self {
Self::Symbol(symbol) => Some(symbol),
Self::Symbol(inner) => Some(Ref { inner }),
_ => None,
}
}

/// Returns an optional reference to a `BigInt` if the value is a `BigInt` primitive.
#[inline]
pub fn as_bigint(&self) -> Option<&JsBigInt> {
pub fn as_bigint(&self) -> Option<Ref<'_, JsBigInt>> {
match self {
Self::BigInt(bigint) => Some(bigint),
Self::BigInt(inner) => Some(Ref { inner }),
_ => None,
}
}
Expand All @@ -158,7 +156,7 @@ impl JsValue {
matches!(self, Self::Rational(_))
}

/// Returns true if the value is any of the representations of a 64-bit floating-point NaN.
/// Returns true if the value is any of the representations of a 64-bit floating-point `NaN`.
#[inline]
pub fn is_nan(&self) -> bool {
matches!(self, Self::Rational(r) if r.is_nan())
Expand Down Expand Up @@ -207,10 +205,55 @@ impl JsValue {
Self::Integer(i) => JsVariant::Integer(*i),
Self::Rational(d) => JsVariant::Rational(*d),
Self::Boolean(b) => JsVariant::Boolean(*b),
Self::Object(o) => JsVariant::Object(o),
Self::String(str) => JsVariant::String(str),
Self::Symbol(sym) => JsVariant::Symbol(sym),
Self::BigInt(b) => JsVariant::BigInt(b),
Self::Object(inner) => JsVariant::Object(Ref { inner }),
Self::String(inner) => JsVariant::String(Ref { inner }),
Self::Symbol(inner) => JsVariant::Symbol(Ref { inner }),
Self::BigInt(inner) => JsVariant::BigInt(Ref { inner }),
}
}
}

/// Represents a reference to a pointer type inside a [`JsValue`]
///
/// [`Ref`] implements [`Deref`][`std::ops::Deref`], which facilitates conversion
/// to a proper [`reference`] by using the `ref` keyword or the
/// [`Option::as_deref`][`std::option::Option::as_deref`] method.
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Ref<'a, T> {
inner: &'a T,
}

// Lift `Ref` over `AsRef`, since implementing `AsRef<T>` would override the
// `as_ref` implementations of `T`.
impl<U, T> AsRef<U> for Ref<'_, T>
where
T: AsRef<U>,
{
#[inline]
fn as_ref(&self) -> &U {
<T as AsRef<U>>::as_ref(self.inner)
}
}

impl<T> std::ops::Deref for Ref<'_, T> {
type Target = T;

#[inline]
fn deref(&self) -> &Self::Target {
self.inner
}
}

impl<T: PartialEq> PartialEq<T> for Ref<'_, T> {
#[inline]
fn eq(&self, other: &T) -> bool {
self.inner == other
}
}

impl<T> std::borrow::Borrow<T> for Ref<'_, T> {
#[inline]
fn borrow(&self) -> &T {
self.inner
}
}

0 comments on commit f67c197

Please sign in to comment.