diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index 4cf03d37901..2f79c7ce4ac 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -16,7 +16,7 @@ use super::function::{make_builtin_fn, make_constructor_fn}; use crate::{ builtins::{ error::RangeError, - object::{ObjectKind, INSTANCE_PROTOTYPE, PROTOTYPE}, + object::{ObjectData, INSTANCE_PROTOTYPE, PROTOTYPE}, property::Property, value::{same_value_zero, ResultValue, Value, ValueData}, }, @@ -42,7 +42,7 @@ impl Array { .get_global_object() .expect("Could not get global object"), )); - array.set_kind(ObjectKind::Array); + array.set_data(ObjectData::Array); array.borrow().set_internal_slot( INSTANCE_PROTOTYPE, interpreter @@ -117,7 +117,7 @@ impl Array { this.set_internal_slot(INSTANCE_PROTOTYPE, prototype); // This value is used by console.log and other routines to match Object type // to its Javascript Identifier (global constructor method name) - this.set_kind(ObjectKind::Array); + this.set_data(ObjectData::Array); // add our arguments in let mut length = args.len() as i32; @@ -176,7 +176,7 @@ impl Array { // 1. ValueData::Object(ref obj) => { // 2. - if (*obj).deref().borrow().kind == ObjectKind::Array { + if (*obj).deref().borrow().data == ObjectData::Array { return Ok(value_true); } Ok(value_false) diff --git a/boa/src/builtins/boolean/mod.rs b/boa/src/builtins/boolean/mod.rs index 40b7de056dd..f8895ae2816 100644 --- a/boa/src/builtins/boolean/mod.rs +++ b/boa/src/builtins/boolean/mod.rs @@ -15,7 +15,7 @@ mod tests; use super::function::{make_builtin_fn, make_constructor_fn}; use crate::{ builtins::{ - object::{internal_methods_trait::ObjectInternalMethods, ObjectKind}, + object::ObjectData, value::{ResultValue, Value, ValueData}, }, exec::Interpreter, @@ -35,19 +35,11 @@ impl Boolean { args: &[Value], _: &mut Interpreter, ) -> ResultValue { - this.set_kind(ObjectKind::Boolean); - // Get the argument, if any - if let Some(ref value) = args.get(0) { - this.set_internal_slot("BooleanData", Self::to_boolean(value)); - } else { - this.set_internal_slot("BooleanData", Self::to_boolean(&Value::from(false))); - } + let data = args.get(0).map(|x| x.to_boolean()).unwrap_or(false); + this.set_data(ObjectData::Boolean(data)); - match args.get(0) { - Some(ref value) => Ok(Self::to_boolean(value)), - None => Ok(Self::to_boolean(&Value::from(false))), - } + Ok(Value::from(data)) } /// The `toString()` method returns a string representing the specified `Boolean` object. @@ -73,22 +65,7 @@ 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 pub(crate) fn value_of(this: &mut Value, _: &[Value], _: &mut Interpreter) -> ResultValue { - Ok(Self::this_boolean_value(this)) - } - - // === Utility Functions === - /// [toBoolean](https://tc39.es/ecma262/#sec-toboolean) - /// Creates a new boolean value from the input - #[allow(clippy::wrong_self_convention)] - pub(crate) fn to_boolean(value: &Value) -> Value { - match *value.deref().borrow() { - ValueData::Object(_) => Value::from(true), - ValueData::String(ref s) if !s.is_empty() => Value::from(true), - ValueData::Rational(n) if n != 0.0 && !n.is_nan() => Value::from(true), - ValueData::Integer(n) if n != 0 => Value::from(true), - ValueData::Boolean(v) => Value::from(v), - _ => Value::from(false), - } + Ok(Value::from(Self::this_boolean_value(this))) } /// An Utility function used to get the internal BooleanData. @@ -97,11 +74,14 @@ impl Boolean { /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-thisbooleanvalue - pub(crate) fn this_boolean_value(value: &Value) -> Value { + pub(crate) fn this_boolean_value(value: &Value) -> bool { match *value.deref().borrow() { - ValueData::Boolean(v) => Value::from(v), - ValueData::Object(ref v) => (v).deref().borrow().get_internal_slot("BooleanData"), - _ => Value::from(false), + ValueData::Boolean(v) => v, + ValueData::Object(ref v) => match v.deref().borrow().data { + ObjectData::Boolean(boolean) => boolean, + _ => unreachable!(), + }, + _ => false, } } @@ -110,7 +90,6 @@ impl Boolean { // Create Prototype // https://tc39.es/ecma262/#sec-properties-of-the-boolean-prototype-object let prototype = Value::new_object(Some(global)); - prototype.set_internal_slot("BooleanData", Self::to_boolean(&Value::from(false))); make_builtin_fn(Self::to_string, "toString", &prototype, 0); make_builtin_fn(Self::value_of, "valueOf", &prototype, 0); diff --git a/boa/src/builtins/error/mod.rs b/boa/src/builtins/error/mod.rs index 328edc50bfb..bea435ea65b 100644 --- a/boa/src/builtins/error/mod.rs +++ b/boa/src/builtins/error/mod.rs @@ -13,7 +13,7 @@ use crate::{ builtins::{ function::{make_builtin_fn, make_constructor_fn}, - object::ObjectKind, + object::ObjectData, value::{ResultValue, Value}, }, exec::Interpreter, @@ -47,7 +47,7 @@ impl Error { } // This value is used by console.log and other routines to match Object type // to its Javascript Identifier (global constructor method name) - this.set_kind(ObjectKind::Error); + this.set_data(ObjectData::Error); Ok(Value::undefined()) } diff --git a/boa/src/builtins/error/range.rs b/boa/src/builtins/error/range.rs index 34e4c88ff77..1fc3789219c 100644 --- a/boa/src/builtins/error/range.rs +++ b/boa/src/builtins/error/range.rs @@ -13,7 +13,7 @@ use crate::{ builtins::{ function::make_builtin_fn, function::make_constructor_fn, - object::ObjectKind, + object::ObjectData, value::{ResultValue, Value}, }, exec::Interpreter, @@ -38,7 +38,7 @@ impl RangeError { } // This value is used by console.log and other routines to match Object type // to its Javascript Identifier (global constructor method name) - this.set_kind(ObjectKind::Error); + this.set_data(ObjectData::Error); Ok(Value::undefined()) } diff --git a/boa/src/builtins/function/mod.rs b/boa/src/builtins/function/mod.rs index 2886b97051f..f16355e4ada 100644 --- a/boa/src/builtins/function/mod.rs +++ b/boa/src/builtins/function/mod.rs @@ -14,7 +14,7 @@ use crate::{ builtins::{ array::Array, - object::{Object, ObjectInternalMethods, ObjectKind, INSTANCE_PROTOTYPE, PROTOTYPE}, + object::{Object, ObjectData, ObjectInternalMethods, INSTANCE_PROTOTYPE, PROTOTYPE}, property::Property, value::{ResultValue, Value}, }, @@ -368,7 +368,7 @@ pub fn create_unmapped_arguments_object(arguments_list: &[Value]) -> Value { /// // This gets called when a new Function() is created. pub fn make_function(this: &mut Value, _: &[Value], _: &mut Interpreter) -> ResultValue { - this.set_kind(ObjectKind::Function); + this.set_data(ObjectData::Function); Ok(this.clone()) } diff --git a/boa/src/builtins/number/mod.rs b/boa/src/builtins/number/mod.rs index e3dae7bf893..8d42f2bb772 100644 --- a/boa/src/builtins/number/mod.rs +++ b/boa/src/builtins/number/mod.rs @@ -18,18 +18,17 @@ mod tests; use super::{ function::{make_builtin_fn, make_constructor_fn}, - object::ObjectKind, + object::ObjectData, }; use crate::{ builtins::{ - object::internal_methods_trait::ObjectInternalMethods, value::{ResultValue, Value, ValueData}, RangeError, }, exec::Interpreter, }; use num_traits::float::FloatCore; -use std::{borrow::Borrow, f64, ops::Deref}; +use std::{f64, ops::Deref}; const BUF_SIZE: usize = 2200; @@ -41,19 +40,22 @@ impl Number { /// Helper function that converts a Value to a Number. #[allow(clippy::wrong_self_convention)] fn to_number(value: &Value) -> Value { - match *value.deref().borrow() { + match value.data() { ValueData::Boolean(b) => { - if b { + if *b { Value::from(1) } else { Value::from(0) } } ValueData::Symbol(_) | ValueData::Undefined => Value::from(f64::NAN), - ValueData::Integer(i) => Value::from(f64::from(i)), - ValueData::Object(ref o) => (o).deref().borrow().get_internal_slot("NumberData"), + ValueData::Integer(i) => Value::from(f64::from(*i)), + ValueData::Object(ref o) => match (o).deref().borrow().data { + ObjectData::Number(num) => Value::from(num), + _ => unreachable!(), + }, ValueData::Null => Value::from(0), - ValueData::Rational(n) => Value::from(n), + ValueData::Rational(n) => Value::from(*n), ValueData::BigInt(ref bigint) => Value::from(bigint.to_f64()), ValueData::String(ref s) => match s.parse::() { Ok(n) => Value::from(n), @@ -80,13 +82,12 @@ impl Number { _ctx: &mut Interpreter, ) -> ResultValue { let data = match args.get(0) { - Some(ref value) => Self::to_number(value), - None => Self::to_number(&Value::from(0)), + Some(ref value) => Self::to_number(value).to_number(), + None => 0.0, }; - this.set_kind(ObjectKind::Number); - this.set_internal_slot("NumberData", data.clone()); + this.set_data(ObjectData::Number(data)); - Ok(data) + Ok(Value::from(data)) } /// `Number.prototype.toExponential( [fractionDigits] )` @@ -393,7 +394,6 @@ impl Number { /// Create a new `Number` object pub(crate) fn create(global: &Value) -> Value { let prototype = Value::new_object(Some(global)); - prototype.set_internal_slot("NumberData", Value::from(0)); make_builtin_fn(Self::to_exponential, "toExponential", &prototype, 1); make_builtin_fn(Self::to_fixed, "toFixed", &prototype, 1); diff --git a/boa/src/builtins/object/mod.rs b/boa/src/builtins/object/mod.rs index 912d15203cd..5fae2778f37 100644 --- a/boa/src/builtins/object/mod.rs +++ b/boa/src/builtins/object/mod.rs @@ -21,11 +21,10 @@ use crate::{ }, exec::Interpreter, }; -use gc::{unsafe_empty_trace, Finalize, Trace}; +use gc::{Finalize, Trace}; use rustc_hash::FxHashMap; use std::{ - borrow::Borrow, - fmt::{self, Debug, Display, Error, Formatter}, + fmt::{Debug, Display, Error, Formatter}, ops::Deref, }; @@ -43,10 +42,10 @@ pub static PROTOTYPE: &str = "prototype"; pub static INSTANCE_PROTOTYPE: &str = "__proto__"; /// The internal representation of an JavaScript object. -#[derive(Trace, Finalize, Clone)] +#[derive(Debug, Trace, Finalize, Clone)] pub struct Object { /// The type of the object. - pub kind: ObjectKind, + pub data: ObjectData, /// Internal Slots pub internal_slots: FxHashMap, /// Properties @@ -59,21 +58,6 @@ pub struct Object { pub func: Option, } -impl Debug for Object { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - writeln!(f, "{{")?; - writeln!(f, "\tkind: {}", self.kind)?; - writeln!(f, "\tstate: {:?}", self.state)?; - writeln!(f, "\tfunc: {:?}", self.func)?; - writeln!(f, "\tproperties: {{")?; - for (key, _) in self.properties.iter() { - writeln!(f, "\t\t{}", key)?; - } - writeln!(f, "\t }}")?; - write!(f, "}}") - } -} - impl ObjectInternalMethods for Object { /// `Object.setPropertyOf(obj, prototype)` /// @@ -335,7 +319,7 @@ impl Object { /// Return a new ObjectData struct, with `kind` set to Ordinary pub fn default() -> Self { let mut object = Self { - kind: ObjectKind::Ordinary, + data: ObjectData::Ordinary, internal_slots: FxHashMap::default(), properties: FxHashMap::default(), sym_properties: FxHashMap::default(), @@ -350,7 +334,7 @@ impl Object { /// Return a new ObjectData struct, with `kind` set to Ordinary pub fn function() -> Self { let mut object = Self { - kind: ObjectKind::Function, + data: ObjectData::Function, internal_slots: FxHashMap::default(), properties: FxHashMap::default(), sym_properties: FxHashMap::default(), @@ -384,57 +368,45 @@ impl Object { } /// Return a new Boolean object whose `[[BooleanData]]` internal slot is set to argument. - fn from_boolean(argument: &Value) -> Self { - let mut obj = Self { - kind: ObjectKind::Boolean, + fn from_boolean(value: bool) -> Self { + Self { + data: ObjectData::Boolean(value), internal_slots: FxHashMap::default(), properties: FxHashMap::default(), sym_properties: FxHashMap::default(), state: None, func: None, - }; - - obj.internal_slots - .insert("BooleanData".to_string(), argument.clone()); - obj + } } /// Return a new `Number` object whose `[[NumberData]]` internal slot is set to argument. - fn from_number(argument: &Value) -> Self { - let mut obj = Self { - kind: ObjectKind::Number, + fn from_number(value: f64) -> Self { + Self { + data: ObjectData::Number(value), internal_slots: FxHashMap::default(), properties: FxHashMap::default(), sym_properties: FxHashMap::default(), state: None, func: None, - }; - - obj.internal_slots - .insert("NumberData".to_string(), argument.clone()); - obj + } } /// Return a new `String` object whose `[[StringData]]` internal slot is set to argument. - fn from_string(argument: &Value) -> Self { - let mut obj = Self { - kind: ObjectKind::String, + fn from_string(value: String) -> Self { + Self { + data: ObjectData::String(value), internal_slots: FxHashMap::default(), properties: FxHashMap::default(), sym_properties: FxHashMap::default(), state: None, func: None, - }; - - obj.internal_slots - .insert("StringData".to_string(), argument.clone()); - obj + } } /// Return a new `BigInt` object whose `[[BigIntData]]` internal slot is set to argument. fn from_bigint(argument: &Value) -> Self { let mut obj = Self { - kind: ObjectKind::BigInt, + data: ObjectData::BigInt, internal_slots: FxHashMap::default(), properties: FxHashMap::default(), sym_properties: FxHashMap::default(), @@ -454,10 +426,11 @@ impl Object { /// /// [spec]: https://tc39.es/ecma262/#sec-toobject pub fn from(value: &Value) -> Result { - match *value.deref().borrow() { - ValueData::Boolean(_) => Ok(Self::from_boolean(value)), - ValueData::Rational(_) => Ok(Self::from_number(value)), - ValueData::String(_) => Ok(Self::from_string(value)), + match *value.data() { + ValueData::Boolean(a) => Ok(Self::from_boolean(a)), + ValueData::Rational(a) => Ok(Self::from_number(a)), + ValueData::Integer(a) => Ok(Self::from_number(f64::from(a))), + ValueData::String(ref a) => Ok(Self::from_string(a.clone())), ValueData::BigInt(_) => Ok(Self::from_bigint(value)), ValueData::Object(ref obj) => Ok((*obj).deref().borrow().clone()), _ => Err(()), @@ -492,20 +465,20 @@ impl Object { } /// Defines the different types of objects. -#[derive(Finalize, Debug, Copy, Clone, Eq, PartialEq)] -pub enum ObjectKind { +#[derive(Debug, Trace, Finalize, Clone, PartialEq)] +pub enum ObjectData { Function, Array, - String, + String(String), Symbol, Error, - Ordinary, - Boolean, - Number, + Boolean(bool), + Number(f64), BigInt, + Ordinary, } -impl Display for ObjectKind { +impl Display for ObjectData { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> { write!( f, @@ -513,30 +486,18 @@ impl Display for ObjectKind { match self { Self::Function => "Function", Self::Array => "Array", - Self::String => "String", + Self::String(_) => "String", Self::Symbol => "Symbol", Self::Error => "Error", Self::Ordinary => "Ordinary", - Self::Boolean => "Boolean", - Self::Number => "Number", + Self::Boolean(_) => "Boolean", + Self::Number(_) => "Number", Self::BigInt => "BigInt", } ) } } -/// `Trace` implementation for `ObjectKind`. -/// -/// This is indeed safe, but we need to mark this as an empty trace because neither -// `NativeFunctionData` nor Node hold any GC'd objects, but Gc doesn't know that. So we need to -/// signal it manually. `rust-gc` does not have a `Trace` implementation for `fn(_, _, _)`. -/// -/// -/// Waiting on until we can derive Copy -unsafe impl Trace for ObjectKind { - unsafe_empty_trace!(); -} - /// Create a new object. pub fn make_object(_: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue { if let Some(arg) = args.get(0) { diff --git a/boa/src/builtins/regexp/mod.rs b/boa/src/builtins/regexp/mod.rs index af82d3bfe80..4d333f90482 100644 --- a/boa/src/builtins/regexp/mod.rs +++ b/boa/src/builtins/regexp/mod.rs @@ -16,7 +16,7 @@ use regex::Regex; use super::function::{make_builtin_fn, make_constructor_fn}; use crate::{ builtins::{ - object::{InternalState, ObjectKind}, + object::{InternalState, ObjectData}, property::Property, value::{ResultValue, Value, ValueData}, }, @@ -159,7 +159,7 @@ impl RegExp { // This value is used by console.log and other routines to match Object type // to its Javascript Identifier (global constructor method name) - this.set_kind(ObjectKind::Ordinary); + this.set_data(ObjectData::Ordinary); this.set_internal_slot("RegExpMatcher", Value::undefined()); this.set_internal_slot("OriginalSource", Value::from(regex_body)); this.set_internal_slot("OriginalFlags", Value::from(regex_flags)); @@ -462,7 +462,7 @@ impl RegExp { let length = matches.len(); let result = Value::from(matches); result.set_field("length", Value::from(length)); - result.set_kind(ObjectKind::Array); + result.set_data(ObjectData::Array); Ok(result) } diff --git a/boa/src/builtins/string/mod.rs b/boa/src/builtins/string/mod.rs index 06ba55460b1..dee862feb6b 100644 --- a/boa/src/builtins/string/mod.rs +++ b/boa/src/builtins/string/mod.rs @@ -15,7 +15,7 @@ mod tests; use super::function::{make_builtin_fn, make_constructor_fn}; use crate::{ builtins::{ - object::{Object, ObjectKind}, + object::{Object, ObjectData}, property::Property, value::{ResultValue, Value, ValueData}, RegExp, @@ -46,32 +46,20 @@ impl String { ) -> ResultValue { // This value is used by console.log and other routines to match Obexpecty"failed to parse argument for String method"pe // to its Javascript Identifier (global constructor method name) - let s = args.get(0).unwrap_or(&Value::string("")).clone(); - let length_str = s.to_string().chars().count(); + let string = args.get(0).map(|x| x.to_string()).unwrap_or_default(); + let length = string.chars().count(); - this.set_field("length", Value::from(length_str as i32)); + this.set_field("length", Value::from(length as i32)); - this.set_kind(ObjectKind::String); - this.set_internal_slot("StringData", s); + this.set_data(ObjectData::String(string.clone())); - let arg = match args.get(0) { - Some(v) => v.clone(), - None => Value::undefined(), - }; - - if arg.is_undefined() { - return Ok("".into()); - } - - Ok(Value::from(arg.to_string())) + Ok(Value::from(string)) } /// Get the string value to a primitive string #[allow(clippy::wrong_self_convention)] pub(crate) fn to_string(this: &mut Value, _: &[Value], _: &mut Interpreter) -> ResultValue { - // Get String from String Object and send it back as a new value - let primitive_val = this.get_internal_slot("StringData"); - Ok(Value::from(format!("{}", primitive_val))) + Ok(Value::from(this.to_string())) } /// `String.prototype.charAt( index )` diff --git a/boa/src/builtins/symbol/mod.rs b/boa/src/builtins/symbol/mod.rs index e71a5dc09c3..9fd53fae84b 100644 --- a/boa/src/builtins/symbol/mod.rs +++ b/boa/src/builtins/symbol/mod.rs @@ -22,7 +22,7 @@ use super::function::{make_builtin_fn, make_constructor_fn}; use crate::{ builtins::{ object::{ - internal_methods_trait::ObjectInternalMethods, Object, ObjectKind, INSTANCE_PROTOTYPE, + internal_methods_trait::ObjectInternalMethods, Object, ObjectData, INSTANCE_PROTOTYPE, PROTOTYPE, }, value::{ResultValue, Value, ValueData}, @@ -48,7 +48,7 @@ pub fn call_symbol(_: &mut Value, args: &[Value], ctx: &mut Interpreter) -> Resu // So we start by creating an Object // TODO: Set prototype to Symbol.prototype (by changing to Object::create(), use interpreter to get Symbol.prototype) let mut sym_instance = Object::default(); - sym_instance.kind = ObjectKind::Symbol; + sym_instance.data = ObjectData::Symbol; // Set description which should either be undefined or a string let desc_string = match args.get(0) { diff --git a/boa/src/builtins/value/mod.rs b/boa/src/builtins/value/mod.rs index 0d3f86672cb..99016633b70 100644 --- a/boa/src/builtins/value/mod.rs +++ b/boa/src/builtins/value/mod.rs @@ -9,7 +9,7 @@ use crate::builtins::{ function::Function, object::{ internal_methods_trait::ObjectInternalMethods, InternalState, InternalStateCell, Object, - ObjectKind, INSTANCE_PROTOTYPE, PROTOTYPE, + ObjectData, INSTANCE_PROTOTYPE, PROTOTYPE, }, property::Property, }; @@ -133,9 +133,9 @@ impl Value { } /// Similar to `new_object`, but you can pass a prototype to create from, plus a kind - pub fn new_object_from_prototype(proto: Value, kind: ObjectKind) -> Self { + pub fn new_object_from_prototype(proto: Value, data: ObjectData) -> Self { let mut object = Object::default(); - object.kind = kind; + object.data = data; object .internal_slots @@ -364,7 +364,7 @@ impl ValueData { ValueData::BigInt(b) => Some(b.clone()), ValueData::Object(ref o) => { let object = (o).deref().borrow(); - if object.kind == ObjectKind::BigInt { + if object.data == ObjectData::BigInt { object.get_internal_slot("BigIntData").to_bigint() } else { None @@ -374,6 +374,20 @@ impl ValueData { } } + /// Creates a new boolean value from the input + pub fn to_boolean(&self) -> bool { + match *self { + Self::Undefined | Self::Null => false, + Self::Symbol(_) | Self::Object(_) => true, + Self::String(ref s) if !s.is_empty() => true, + Self::Rational(n) if n != 0.0 && !n.is_nan() => true, + Self::Integer(n) if n != 0 => true, + Self::BigInt(ref n) if *n != 0 => true, + Self::Boolean(v) => v, + _ => false, + } + } + pub fn as_object(&self) -> Option> { match *self { ValueData::Object(ref o) => Some(o.borrow()), @@ -600,7 +614,7 @@ impl ValueData { let val = val.into(); if let Self::Object(ref obj) = *self { - if obj.borrow().kind == ObjectKind::Array { + if obj.borrow().data == ObjectData::Array { if let Ok(num) = field.to_string().parse::() { if num > 0 { let len = i32::from(&self.get_field("length")); @@ -634,9 +648,9 @@ impl ValueData { } /// Set the kind of an object - pub fn set_kind(&self, kind: ObjectKind) { + pub fn set_data(&self, data: ObjectData) { if let Self::Object(ref obj) = *self { - (*obj.deref().borrow_mut()).kind = kind; + (*obj.deref().borrow_mut()).data = data; } } @@ -836,19 +850,10 @@ pub(crate) fn log_string_from(x: &ValueData, print_internals: bool) -> String { ValueData::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().kind { - ObjectKind::String => String::from( - v.borrow() - .internal_slots - .get("StringData") - .expect("Cannot get primitive value from String"), - ), - ObjectKind::Boolean => { - let bool_data = v.borrow().get_internal_slot("BooleanData").to_string(); - - format!("Boolean {{ {} }}", bool_data) - } - ObjectKind::Array => { + match v.borrow().data { + ObjectData::String(ref string) => string.clone(), + ObjectData::Boolean(boolean) => format!("Boolean {{ {} }}", boolean), + ObjectData::Array => { let len = i32::from( &v.borrow() .properties diff --git a/boa/src/exec/mod.rs b/boa/src/exec/mod.rs index 4f0c8266818..93e99bcf170 100644 --- a/boa/src/exec/mod.rs +++ b/boa/src/exec/mod.rs @@ -15,7 +15,7 @@ use crate::{ builtins::{ function::{Function as FunctionObject, FunctionBody, ThisMode}, object::{ - internal_methods_trait::ObjectInternalMethods, Object, ObjectKind, INSTANCE_PROTOTYPE, + internal_methods_trait::ObjectInternalMethods, Object, ObjectData, INSTANCE_PROTOTYPE, PROTOTYPE, }, property::Property, @@ -151,7 +151,7 @@ impl Interpreter { pub(crate) fn extract_array_properties(&mut self, value: &Value) -> Result, ()> { if let ValueData::Object(ref x) = *value.deref().borrow() { // Check if object is array - if x.deref().borrow().kind == ObjectKind::Array { + if x.deref().borrow().data == ObjectData::Array { let length: i32 = self.value_to_rust_number(&value.get_field("length")) as i32; let values: Vec = (0..length) .map(|idx| value.get_field(idx.to_string())) @@ -281,36 +281,41 @@ impl Interpreter { ValueData::Undefined | ValueData::Integer(_) | ValueData::Null => { Err(Value::undefined()) } - ValueData::Boolean(_) => { + ValueData::Boolean(boolean) => { let proto = self .realm .environment .get_binding_value("Boolean") .get_field(PROTOTYPE); - let bool_obj = Value::new_object_from_prototype(proto, ObjectKind::Boolean); - bool_obj.set_internal_slot("BooleanData", value.clone()); - Ok(bool_obj) + Ok(Value::new_object_from_prototype( + proto, + ObjectData::Boolean(boolean), + )) } - ValueData::Rational(_) => { + ValueData::Rational(rational) => { let proto = self .realm .environment .get_binding_value("Number") .get_field(PROTOTYPE); - let number_obj = Value::new_object_from_prototype(proto, ObjectKind::Number); - number_obj.set_internal_slot("NumberData", value.clone()); - Ok(number_obj) + + Ok(Value::new_object_from_prototype( + proto, + ObjectData::Number(rational), + )) } - ValueData::String(_) => { + ValueData::String(ref string) => { let proto = self .realm .environment .get_binding_value("String") .get_field(PROTOTYPE); - let string_obj = Value::new_object_from_prototype(proto, ObjectKind::String); - string_obj.set_internal_slot("StringData", value.clone()); - Ok(string_obj) + + Ok(Value::new_object_from_prototype( + proto, + ObjectData::String(string.clone()), + )) } ValueData::Object(_) | ValueData::Symbol(_) => Ok(value.clone()), ValueData::BigInt(_) => { @@ -319,7 +324,7 @@ impl Interpreter { .environment .get_binding_value("BigInt") .get_field(PROTOTYPE); - let bigint_obj = Value::new_object_from_prototype(proto, ObjectKind::BigInt); + let bigint_obj = Value::new_object_from_prototype(proto, ObjectData::BigInt); bigint_obj.set_internal_slot("BigIntData", value.clone()); Ok(bigint_obj) }