diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index 58596a94593..73882b89032 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -1135,7 +1135,7 @@ impl Array { /// Initialise the `Array` object on the global object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let global = interpreter.global(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); @@ -1193,6 +1193,10 @@ impl Array { // Static Methods make_builtin_fn(Self::is_array, "isArray", &array, 1, interpreter); - (Self::NAME, array) + ( + Self::NAME, + array, + Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) } } diff --git a/boa/src/builtins/bigint/mod.rs b/boa/src/builtins/bigint/mod.rs index e2e9ffe879b..e28a942d4d8 100644 --- a/boa/src/builtins/bigint/mod.rs +++ b/boa/src/builtins/bigint/mod.rs @@ -16,6 +16,7 @@ use crate::{ builtins::{ function::{make_builtin_fn, make_constructor_fn}, object::ObjectData, + property::Attribute, value::{RcBigInt, Value}, }, exec::Interpreter, @@ -200,7 +201,7 @@ impl BigInt { /// Initialise the `BigInt` object on the global object. #[inline] - pub fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { + pub fn init(interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let global = interpreter.global(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); @@ -222,7 +223,11 @@ impl BigInt { make_builtin_fn(Self::as_int_n, "asIntN", &bigint_object, 2, interpreter); make_builtin_fn(Self::as_uint_n, "asUintN", &bigint_object, 2, interpreter); - (Self::NAME, bigint_object) + ( + Self::NAME, + bigint_object, + Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) } } diff --git a/boa/src/builtins/boolean/mod.rs b/boa/src/builtins/boolean/mod.rs index 2d907cddaec..b7a326f5c0d 100644 --- a/boa/src/builtins/boolean/mod.rs +++ b/boa/src/builtins/boolean/mod.rs @@ -14,7 +14,7 @@ mod tests; use super::function::{make_builtin_fn, make_constructor_fn}; use crate::{ - builtins::{object::ObjectData, value::Value}, + builtins::{object::ObjectData, property::Attribute, value::Value}, exec::Interpreter, BoaProfiler, Result, }; @@ -95,7 +95,7 @@ impl Boolean { /// Initialise the `Boolean` object on the global object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let global = interpreter.global(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); @@ -115,7 +115,10 @@ impl Boolean { true, true, ); - - (Self::NAME, boolean_object) + ( + Self::NAME, + boolean_object, + Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) } } diff --git a/boa/src/builtins/console/mod.rs b/boa/src/builtins/console/mod.rs index be1153d8477..0f925b8df30 100644 --- a/boa/src/builtins/console/mod.rs +++ b/boa/src/builtins/console/mod.rs @@ -19,6 +19,7 @@ mod tests; use crate::{ builtins::{ function::make_builtin_fn, + property::Attribute, value::{display_obj, RcString, Value}, }, exec::Interpreter, @@ -501,7 +502,7 @@ impl Console { /// Initialise the `console` object on the global object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let global = interpreter.global(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); @@ -527,6 +528,10 @@ impl Console { make_builtin_fn(Self::dir, "dir", &console, 0, interpreter); make_builtin_fn(Self::dir, "dirxml", &console, 0, interpreter); - (Self::NAME, console) + ( + Self::NAME, + console, + Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) } } diff --git a/boa/src/builtins/date/mod.rs b/boa/src/builtins/date/mod.rs index 9f792aaa8e7..24d7f1bbbdd 100644 --- a/boa/src/builtins/date/mod.rs +++ b/boa/src/builtins/date/mod.rs @@ -5,6 +5,7 @@ use crate::{ builtins::{ function::{make_builtin_fn, make_constructor_fn}, object::ObjectData, + property::Attribute, value::PreferredType, Value, }, @@ -1242,7 +1243,7 @@ impl Date { /// Initialise the `Date` object on the global object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let global = interpreter.global(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); @@ -1564,7 +1565,12 @@ impl Date { make_builtin_fn(Self::now, "now", &date_time_object, 0, interpreter); make_builtin_fn(Self::parse, "parse", &date_time_object, 1, interpreter); make_builtin_fn(Self::utc, "UTC", &date_time_object, 7, interpreter); - (Self::NAME, date_time_object) + + ( + Self::NAME, + date_time_object, + Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) } } diff --git a/boa/src/builtins/error/mod.rs b/boa/src/builtins/error/mod.rs index 6b97c751b9d..a3ff8aec968 100644 --- a/boa/src/builtins/error/mod.rs +++ b/boa/src/builtins/error/mod.rs @@ -14,6 +14,7 @@ use crate::{ builtins::{ function::{make_builtin_fn, make_constructor_fn}, object::ObjectData, + property::Attribute, value::Value, }, exec::Interpreter, @@ -81,7 +82,7 @@ impl Error { /// Initialise the global object with the `Error` object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let global = interpreter.global(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); @@ -100,7 +101,10 @@ impl Error { true, true, ); - - (Self::NAME, error_object) + ( + Self::NAME, + error_object, + Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) } } diff --git a/boa/src/builtins/error/range.rs b/boa/src/builtins/error/range.rs index 2b5e635c99e..4298648e7ca 100644 --- a/boa/src/builtins/error/range.rs +++ b/boa/src/builtins/error/range.rs @@ -11,7 +11,8 @@ use crate::{ builtins::{ - function::make_builtin_fn, function::make_constructor_fn, object::ObjectData, value::Value, + function::make_builtin_fn, function::make_constructor_fn, object::ObjectData, + property::Attribute, value::Value, }, exec::Interpreter, profiler::BoaProfiler, @@ -61,7 +62,7 @@ impl RangeError { /// Initialise the global object with the `RangeError` object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let global = interpreter.global(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); @@ -80,7 +81,10 @@ impl RangeError { true, true, ); - - (Self::NAME, range_error_object) + ( + Self::NAME, + range_error_object, + Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) } } diff --git a/boa/src/builtins/error/reference.rs b/boa/src/builtins/error/reference.rs index 9f20117dd3e..9b3c4f322cc 100644 --- a/boa/src/builtins/error/reference.rs +++ b/boa/src/builtins/error/reference.rs @@ -11,7 +11,8 @@ use crate::{ builtins::{ - function::make_builtin_fn, function::make_constructor_fn, object::ObjectData, value::Value, + function::make_builtin_fn, function::make_constructor_fn, object::ObjectData, + property::Attribute, value::Value, }, exec::Interpreter, profiler::BoaProfiler, @@ -59,7 +60,7 @@ impl ReferenceError { } /// Initialise the global object with the `ReferenceError` object. - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let global = interpreter.global(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); @@ -79,6 +80,10 @@ impl ReferenceError { true, ); - (Self::NAME, reference_error_object) + ( + Self::NAME, + reference_error_object, + Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) } } diff --git a/boa/src/builtins/error/syntax.rs b/boa/src/builtins/error/syntax.rs index c05f0f7fbb5..b97c47797dd 100644 --- a/boa/src/builtins/error/syntax.rs +++ b/boa/src/builtins/error/syntax.rs @@ -13,7 +13,10 @@ use crate::{ builtins::{ - function::make_builtin_fn, function::make_constructor_fn, object::ObjectData, value::Value, + function::{make_builtin_fn, make_constructor_fn}, + object::ObjectData, + property::Attribute, + value::Value, }, exec::Interpreter, profiler::BoaProfiler, @@ -63,7 +66,7 @@ impl SyntaxError { /// Initialise the global object with the `SyntaxError` object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let global = interpreter.global(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); @@ -82,7 +85,10 @@ impl SyntaxError { true, true, ); - - (Self::NAME, syntax_error_object) + ( + Self::NAME, + syntax_error_object, + Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) } } diff --git a/boa/src/builtins/error/type.rs b/boa/src/builtins/error/type.rs index 60fff80f962..0862dba6357 100644 --- a/boa/src/builtins/error/type.rs +++ b/boa/src/builtins/error/type.rs @@ -17,7 +17,10 @@ use crate::{ builtins::{ - function::make_builtin_fn, function::make_constructor_fn, object::ObjectData, value::Value, + function::{make_builtin_fn, make_constructor_fn}, + object::ObjectData, + property::Attribute, + value::Value, }, exec::Interpreter, BoaProfiler, Result, @@ -66,7 +69,7 @@ impl TypeError { /// Initialise the global object with the `RangeError` object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let global = interpreter.global(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); @@ -86,6 +89,10 @@ impl TypeError { true, ); - (Self::NAME, type_error_object) + ( + Self::NAME, + type_error_object, + Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) } } diff --git a/boa/src/builtins/function/mod.rs b/boa/src/builtins/function/mod.rs index f6e6eb56652..ea745244e6a 100644 --- a/boa/src/builtins/function/mod.rs +++ b/boa/src/builtins/function/mod.rs @@ -184,12 +184,12 @@ pub fn create_unmapped_arguments_object(arguments_list: &[Value]) -> Value { let mut index: usize = 0; while index < len { let val = arguments_list.get(index).expect("Could not get argument"); - let prop = Property::data_descriptor( + + obj.insert_property( + index, val.clone(), Attribute::WRITABLE | Attribute::ENUMERABLE | Attribute::CONFIGURABLE, ); - - obj.insert_property(index, prop); index += 1; } @@ -234,29 +234,22 @@ pub fn make_constructor_fn( let mut constructor = Object::function(function, global.get_field("Function").get_field(PROTOTYPE)); - let length = Property::data_descriptor( - length.into(), - Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT, - ); - constructor.insert_property("length", length); + constructor.insert_property("length", length, Attribute::default()); - let name = Property::data_descriptor( - name.into(), - Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT, - ); - constructor.insert_property("name", name); + constructor.insert_property("name", name, Attribute::default()); let constructor = Value::from(constructor); - prototype - .as_object_mut() - .unwrap() - .insert_field("constructor", constructor.clone()); + prototype.as_object_mut().unwrap().insert_property( + "constructor", + constructor.clone(), + Attribute::default(), + ); constructor .as_object_mut() .expect("constructor object") - .insert_field(PROTOTYPE, prototype); + .insert_property(PROTOTYPE, prototype, Attribute::default()); constructor } @@ -298,23 +291,27 @@ pub fn make_builtin_fn( .get_field("Function") .get_field("prototype"), ); - function.insert_field("length", Value::from(length)); + function.insert_property("length", Value::from(length), Attribute::default()); - parent - .as_object_mut() - .unwrap() - .insert_field(name, Value::from(function)); + parent.as_object_mut().unwrap().insert_property( + name, + Value::from(function), + Attribute::default(), + ); } /// Initialise the `Function` object on the global object. #[inline] -pub fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { +pub fn init(interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let global = interpreter.global(); let _timer = BoaProfiler::global().start_event("function", "init"); let prototype = Value::new_object(Some(global)); let function_object = make_constructor_fn("Function", 1, make_function, global, prototype, true, true); - - ("Function", function_object) + ( + "Function", + function_object, + Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) } diff --git a/boa/src/builtins/global_this/mod.rs b/boa/src/builtins/global_this/mod.rs index 481b619decb..dd28e4c2e6b 100644 --- a/boa/src/builtins/global_this/mod.rs +++ b/boa/src/builtins/global_this/mod.rs @@ -10,7 +10,8 @@ //! [spec]: https://tc39.es/ecma262/#sec-globalthis //! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis -use crate::{builtins::value::Value, BoaProfiler, Interpreter}; +use super::{property::Attribute, value::Value}; +use crate::{BoaProfiler, Interpreter}; #[cfg(test)] mod tests; @@ -24,10 +25,12 @@ impl GlobalThis { /// Initialize the `globalThis` property on the global object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { - let global = interpreter.global(); + pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); - - (Self::NAME, global.clone()) + ( + Self::NAME, + interpreter.global().clone(), + Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) } } diff --git a/boa/src/builtins/infinity/mod.rs b/boa/src/builtins/infinity/mod.rs index 7cb9b78fff3..2e8a0151bf1 100644 --- a/boa/src/builtins/infinity/mod.rs +++ b/boa/src/builtins/infinity/mod.rs @@ -12,6 +12,7 @@ #[cfg(test)] mod tests; +use super::property::Attribute; use crate::{builtins::value::Value, BoaProfiler, Interpreter}; /// JavaScript global `Infinity` property. @@ -24,9 +25,8 @@ impl Infinity { /// Initialize the `Infinity` property on the global object. #[inline] - pub(crate) fn init(_interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(_interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); - - (Self::NAME, Value::from(f64::INFINITY)) + (Self::NAME, Value::from(f64::INFINITY), Attribute::default()) } } diff --git a/boa/src/builtins/json/mod.rs b/boa/src/builtins/json/mod.rs index 71f86e50107..ae4a680c6ba 100644 --- a/boa/src/builtins/json/mod.rs +++ b/boa/src/builtins/json/mod.rs @@ -16,12 +16,13 @@ use crate::{ builtins::{ function::make_builtin_fn, - property::{Property, PropertyKey}, + property::{Attribute, Property, PropertyKey}, value::Value, }, exec::Interpreter, BoaProfiler, Result, }; + use serde_json::{self, Value as JSONValue}; #[cfg(test)] @@ -181,7 +182,7 @@ impl Json { /// Initialise the `JSON` object on the global object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let global = interpreter.global(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let json = Value::new_object(Some(global)); @@ -189,6 +190,10 @@ impl Json { make_builtin_fn(Self::parse, "parse", &json, 2, interpreter); make_builtin_fn(Self::stringify, "stringify", &json, 3, interpreter); - (Self::NAME, json) + ( + Self::NAME, + json, + Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) } } diff --git a/boa/src/builtins/map/mod.rs b/boa/src/builtins/map/mod.rs index 46aa475ba47..3235f1edd18 100644 --- a/boa/src/builtins/map/mod.rs +++ b/boa/src/builtins/map/mod.rs @@ -284,7 +284,7 @@ impl Map { } /// Initialise the `Map` object on the global object. - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let global = interpreter.global(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); @@ -308,6 +308,10 @@ impl Map { false, ); - (Self::NAME, map_object) + ( + Self::NAME, + map_object, + Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) } } diff --git a/boa/src/builtins/math/mod.rs b/boa/src/builtins/math/mod.rs index be769e61f10..34de8698978 100644 --- a/boa/src/builtins/math/mod.rs +++ b/boa/src/builtins/math/mod.rs @@ -12,7 +12,7 @@ //! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math use crate::{ - builtins::{function::make_builtin_fn, value::Value}, + builtins::{function::make_builtin_fn, property::Attribute, value::Value}, exec::Interpreter, BoaProfiler, Result, }; @@ -645,14 +645,15 @@ impl Math { { let mut properties = math.as_object_mut().unwrap(); - properties.insert_field("E", Value::from(f64::consts::E)); - properties.insert_field("LN2", Value::from(f64::consts::LN_2)); - properties.insert_field("LN10", Value::from(f64::consts::LN_10)); - properties.insert_field("LOG2E", Value::from(f64::consts::LOG2_E)); - properties.insert_field("LOG10E", Value::from(f64::consts::LOG10_E)); - properties.insert_field("SQRT1_2", Value::from(0.5_f64.sqrt())); - properties.insert_field("SQRT2", Value::from(f64::consts::SQRT_2)); - properties.insert_field("PI", Value::from(f64::consts::PI)); + let attribute = Attribute::default(); + properties.insert_property("E", Value::from(f64::consts::E), attribute); + properties.insert_property("LN2", Value::from(f64::consts::LN_2), attribute); + properties.insert_property("LN10", Value::from(f64::consts::LN_10), attribute); + properties.insert_property("LOG2E", Value::from(f64::consts::LOG2_E), attribute); + properties.insert_property("LOG10E", Value::from(f64::consts::LOG10_E), attribute); + properties.insert_property("SQRT1_2", Value::from(0.5_f64.sqrt()), attribute); + properties.insert_property("SQRT2", Value::from(f64::consts::SQRT_2), attribute); + properties.insert_property("PI", Value::from(f64::consts::PI), attribute); } make_builtin_fn(Self::abs, "abs", &math, 1, interpreter); @@ -696,9 +697,14 @@ impl Math { /// Initialise the `Math` object on the global object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); + let math = Self::create(interpreter); - (Self::NAME, Self::create(interpreter)) + ( + Self::NAME, + math, + Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) } } diff --git a/boa/src/builtins/mod.rs b/boa/src/builtins/mod.rs index 29d1628c33b..ef1eede6aaa 100644 --- a/boa/src/builtins/mod.rs +++ b/boa/src/builtins/mod.rs @@ -76,14 +76,13 @@ pub fn init(interpreter: &mut Interpreter) { Undefined::init, ]; - for init in &globals { - let (name, value) = init(interpreter); - let global = interpreter.global(); - match global { - Value::Object(ref global_object) => { - global_object.borrow_mut().insert_field(name, value); - } - _ => unreachable!("expect global object"), - } - } + let global = match interpreter.global() { + Value::Object(ref global) => global.clone(), + _ => panic!("Expect object"), + }; + globals.iter().for_each(|init| { + let (name, value, attr) = init(interpreter); + + global.borrow_mut().insert_property(name, value, attr); + }); } diff --git a/boa/src/builtins/nan/mod.rs b/boa/src/builtins/nan/mod.rs index eeb29c039c9..10e7602dd21 100644 --- a/boa/src/builtins/nan/mod.rs +++ b/boa/src/builtins/nan/mod.rs @@ -13,6 +13,7 @@ #[cfg(test)] mod tests; +use super::property::Attribute; use crate::{builtins::value::Value, BoaProfiler, Interpreter}; /// JavaScript global `NaN` property. @@ -25,9 +26,9 @@ impl NaN { /// Initialize the `NaN` property on the global object. #[inline] - pub(crate) fn init(_interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(_interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); - (Self::NAME, Value::from(f64::NAN)) + (Self::NAME, Value::from(f64::NAN), Attribute::default()) } } diff --git a/boa/src/builtins/number/mod.rs b/boa/src/builtins/number/mod.rs index 28dd2c7468b..a01f2334f24 100644 --- a/boa/src/builtins/number/mod.rs +++ b/boa/src/builtins/number/mod.rs @@ -16,6 +16,7 @@ use super::{ function::{make_builtin_fn, make_constructor_fn}, object::ObjectData, + property::attribute::Attribute, value::AbstractRelation, }; use crate::{builtins::value::Value, exec::Interpreter, BoaProfiler, Result}; @@ -740,7 +741,7 @@ impl Number { /// Initialise the `Number` object on the global object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let global = interpreter.global(); let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); @@ -826,17 +827,22 @@ impl Number { // https://tc39.es/ecma262/#sec-properties-of-the-number-constructor { let mut properties = number_object.as_object_mut().expect("'Number' object"); - properties.insert_field("EPSILON", Value::from(f64::EPSILON)); - properties.insert_field("MAX_SAFE_INTEGER", Value::from(Self::MAX_SAFE_INTEGER)); - properties.insert_field("MIN_SAFE_INTEGER", Value::from(Self::MIN_SAFE_INTEGER)); - properties.insert_field("MAX_VALUE", Value::from(Self::MAX_VALUE)); - properties.insert_field("MIN_VALUE", Value::from(Self::MIN_VALUE)); - properties.insert_field("NEGATIVE_INFINITY", Value::from(f64::NEG_INFINITY)); - properties.insert_field("POSITIVE_INFINITY", Value::from(f64::INFINITY)); - properties.insert_field("NaN", Value::from(f64::NAN)); + let attribute = Attribute::default(); + properties.insert_property("EPSILON", f64::EPSILON, attribute); + properties.insert_property("MAX_SAFE_INTEGER", Self::MAX_SAFE_INTEGER, attribute); + properties.insert_property("MIN_SAFE_INTEGER", Self::MIN_SAFE_INTEGER, attribute); + properties.insert_property("MAX_VALUE", Self::MAX_VALUE, attribute); + properties.insert_property("MIN_VALUE", Self::MIN_VALUE, attribute); + properties.insert_property("NEGATIVE_INFINITY", f64::NEG_INFINITY, attribute); + properties.insert_property("POSITIVE_INFINITY", f64::INFINITY, attribute); + properties.insert_property("NaN", f64::NAN, attribute); } - (Self::NAME, number_object) + ( + Self::NAME, + number_object, + Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) } /// The abstract operation Number::equal takes arguments diff --git a/boa/src/builtins/object/internal_methods.rs b/boa/src/builtins/object/internal_methods.rs index 0595a294abf..f4684eb677f 100644 --- a/boa/src/builtins/object/internal_methods.rs +++ b/boa/src/builtins/object/internal_methods.rs @@ -168,7 +168,7 @@ impl Object { return false; } - self.insert_property(key, desc); + self.insert(key, desc); return true; } // If every field is absent we don't need to set anything @@ -207,7 +207,7 @@ impl Object { current.set = None; } - self.insert_property(key, current); + self.insert(key, current); return true; // 7 } else if current.is_data_descriptor() && desc.is_data_descriptor() { @@ -247,7 +247,7 @@ impl Object { return true; } // 9 - self.insert_property(key, desc); + self.insert(key, desc); true } @@ -336,17 +336,19 @@ impl Object { /// Helper function for property insertion. #[inline] - pub(crate) fn insert_property(&mut self, key: K, property: Property) -> Option + pub(crate) fn insert(&mut self, key: K, property: Property) where K: Into, { match key.into() { - PropertyKey::Index(index) => self.indexed_properties.insert(index, property), + PropertyKey::Index(index) => { + self.indexed_properties.insert(index, property); + } PropertyKey::String(ref string) => { - self.string_properties.insert(string.clone(), property) + self.string_properties.insert(string.clone(), property); } PropertyKey::Symbol(ref symbol) => { - self.symbol_properties.insert(symbol.clone(), property) + self.symbol_properties.insert(symbol.clone(), property); } } } @@ -361,21 +363,30 @@ impl Object { } } - /// Inserts a field in the object `properties` without checking if it's writable. + /// Inserts a field in the object `properties`, given an attribute without checking if it's writable. /// /// If a field was already in the object with the same name that a `Some` is returned /// with that field, otherwise None is retuned. #[inline] - pub(crate) fn insert_field(&mut self, key: K, value: Value) -> Option + pub(crate) fn insert_property( + &mut self, + key: K, + value: V, + attribute: Attribute, + ) -> Option where K: Into, + V: Into, { - self.insert_property( - key.into(), - Property::data_descriptor( - value, - Attribute::WRITABLE | Attribute::ENUMERABLE | Attribute::CONFIGURABLE, - ), - ) + let property = Property::data_descriptor(value.into(), attribute); + match key.into() { + PropertyKey::Index(index) => self.indexed_properties.insert(index, property), + PropertyKey::String(ref string) => { + self.string_properties.insert(string.clone(), property) + } + PropertyKey::Symbol(ref symbol) => { + self.symbol_properties.insert(symbol.clone(), property) + } + } } } diff --git a/boa/src/builtins/object/mod.rs b/boa/src/builtins/object/mod.rs index 18ec20ff435..36a5822cc91 100644 --- a/boa/src/builtins/object/mod.rs +++ b/boa/src/builtins/object/mod.rs @@ -17,7 +17,7 @@ use crate::{ builtins::{ function::Function, map::ordered_map::OrderedMap, - property::{Property, PropertyKey}, + property::{Attribute, Property, PropertyKey}, value::{RcBigInt, RcString, RcSymbol, Value}, BigInt, Date, RegExp, }, @@ -551,7 +551,7 @@ pub fn property_is_enumerable( /// Initialise the `Object` object on the global object. #[inline] -pub fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { +pub fn init(interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let global = interpreter.global(); let _timer = BoaProfiler::global().start_event("object", "init"); @@ -582,5 +582,9 @@ pub fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { make_builtin_fn(define_property, "defineProperty", &object, 3, interpreter); make_builtin_fn(is, "is", &object, 2, interpreter); - ("Object", object) + ( + "Object", + object, + Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) } diff --git a/boa/src/builtins/regexp/mod.rs b/boa/src/builtins/regexp/mod.rs index 214b2807ca3..ab69b58e564 100644 --- a/boa/src/builtins/regexp/mod.rs +++ b/boa/src/builtins/regexp/mod.rs @@ -15,7 +15,7 @@ use super::function::{make_builtin_fn, make_constructor_fn}; use crate::{ builtins::{ object::ObjectData, - property::Property, + property::{Attribute, Property}, value::{RcString, Value}, }, exec::Interpreter, @@ -480,16 +480,17 @@ impl RegExp { /// Initialise the `RegExp` object on the global object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let global = interpreter.global(); // Create prototype let prototype = Value::new_object(Some(global)); - prototype - .as_object_mut() - .unwrap() - .insert_field("lastIndex", Value::from(0)); + prototype.as_object_mut().unwrap().insert_property( + "lastIndex", + Value::from(0), + Attribute::default(), + ); make_builtin_fn(Self::test, "test", &prototype, 1, interpreter); make_builtin_fn(Self::exec, "exec", &prototype, 1, interpreter); @@ -515,6 +516,10 @@ impl RegExp { true, ); - (Self::NAME, regexp) + ( + Self::NAME, + regexp, + Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) } } diff --git a/boa/src/builtins/string/mod.rs b/boa/src/builtins/string/mod.rs index 17a6ec71d13..3decc77ae84 100644 --- a/boa/src/builtins/string/mod.rs +++ b/boa/src/builtins/string/mod.rs @@ -16,7 +16,7 @@ use super::function::{make_builtin_fn, make_constructor_fn}; use crate::{ builtins::{ object::{Object, ObjectData}, - property::Property, + property::{Attribute, Property}, value::{RcString, Value}, RegExp, }, @@ -1029,7 +1029,7 @@ impl String { /// Initialise the `String` object on the global object. #[inline] - pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); // Create `String` `prototype` @@ -1093,6 +1093,10 @@ impl String { true, ); - (Self::NAME, string_object) + ( + Self::NAME, + string_object, + Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) } } diff --git a/boa/src/builtins/symbol/mod.rs b/boa/src/builtins/symbol/mod.rs index 25ccf148f8c..1f2c66a6a3e 100644 --- a/boa/src/builtins/symbol/mod.rs +++ b/boa/src/builtins/symbol/mod.rs @@ -21,7 +21,7 @@ mod tests; use super::function::{make_builtin_fn, make_constructor_fn}; use crate::{ builtins::{ - property::{Attribute, Property}, + property::Attribute, value::{RcString, RcSymbol, Value}, }, exec::Interpreter, @@ -112,7 +112,7 @@ impl Symbol { /// Initialise the `Symbol` object on the global object. #[inline] - pub fn init(interpreter: &mut Interpreter) -> (&'static str, Value) { + pub fn init(interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { // Define the Well-Known Symbols // https://tc39.es/ecma262/#sec-well-known-symbols let symbol_async_iterator = @@ -152,60 +152,29 @@ impl Symbol { { let mut symbol_object = symbol_object.as_object_mut().unwrap(); let attribute = Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT; - symbol_object.insert_property( - "asyncIterator", - Property::data_descriptor(symbol_async_iterator.into(), attribute), - ); - symbol_object.insert_property( - "hasInstance", - Property::data_descriptor(symbol_has_instance.into(), attribute), - ); + symbol_object.insert_property("asyncIterator", symbol_async_iterator, attribute); + symbol_object.insert_property("hasInstance", symbol_has_instance, attribute); symbol_object.insert_property( "isConcatSpreadable", - Property::data_descriptor(symbol_is_concat_spreadable.into(), attribute), - ); - symbol_object.insert_property( - "iterator", - Property::data_descriptor(symbol_iterator.into(), attribute), - ); - symbol_object.insert_property( - "match", - Property::data_descriptor(symbol_match.into(), attribute), - ); - symbol_object.insert_property( - "matchAll", - Property::data_descriptor(symbol_match_all.into(), attribute), - ); - symbol_object.insert_property( - "replace", - Property::data_descriptor(symbol_replace.into(), attribute), - ); - symbol_object.insert_property( - "search", - Property::data_descriptor(symbol_search.into(), attribute), - ); - symbol_object.insert_property( - "species", - Property::data_descriptor(symbol_species.into(), attribute), - ); - symbol_object.insert_property( - "split", - Property::data_descriptor(symbol_split.into(), attribute), - ); - symbol_object.insert_property( - "toPrimitive", - Property::data_descriptor(symbol_to_primitive.into(), attribute), - ); - symbol_object.insert_property( - "toStringTag", - Property::data_descriptor(symbol_to_string_tag.into(), attribute), - ); - symbol_object.insert_property( - "unscopables", - Property::data_descriptor(symbol_unscopables.into(), attribute), + symbol_is_concat_spreadable, + attribute, ); + symbol_object.insert_property("iterator", symbol_iterator, attribute); + symbol_object.insert_property("match", symbol_match, attribute); + symbol_object.insert_property("matchAll", symbol_match_all, attribute); + symbol_object.insert_property("replace", symbol_replace, attribute); + symbol_object.insert_property("search", symbol_search, attribute); + symbol_object.insert_property("species", symbol_species, attribute); + symbol_object.insert_property("split", symbol_split, attribute); + symbol_object.insert_property("toPrimitive", symbol_to_primitive, attribute); + symbol_object.insert_property("toStringTag", symbol_to_string_tag, attribute); + symbol_object.insert_property("unscopables", symbol_unscopables, attribute); } - (Self::NAME, symbol_object) + ( + Self::NAME, + symbol_object, + Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) } } diff --git a/boa/src/builtins/undefined/mod.rs b/boa/src/builtins/undefined/mod.rs index ae21964a3ae..54bf8e5f86f 100644 --- a/boa/src/builtins/undefined/mod.rs +++ b/boa/src/builtins/undefined/mod.rs @@ -17,6 +17,7 @@ use crate::{builtins::value::Value, BoaProfiler, Interpreter}; /// JavaScript global `undefined` property. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub(crate) struct Undefined; +use super::property::Attribute; impl Undefined { /// The binding name of the property. @@ -24,9 +25,9 @@ impl Undefined { /// Initialize the `undefined` property on the global object. #[inline] - pub(crate) fn init(_interpreter: &mut Interpreter) -> (&'static str, Value) { + pub(crate) fn init(_interpreter: &mut Interpreter) -> (&'static str, Value, Attribute) { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); - (Self::NAME, Value::undefined()) + (Self::NAME, Value::undefined(), Attribute::default()) } } diff --git a/boa/src/builtins/value/conversions.rs b/boa/src/builtins/value/conversions.rs index 5e47b216847..4ea185ec7e0 100644 --- a/boa/src/builtins/value/conversions.rs +++ b/boa/src/builtins/value/conversions.rs @@ -127,7 +127,7 @@ where fn from(value: &[T]) -> Self { let mut array = Object::default(); for (i, item) in value.iter().enumerate() { - array.insert_property(i, Property::default().value(item.clone().into())); + array.insert_property(i, item.clone(), Attribute::default()); } Self::from(array) } @@ -140,7 +140,7 @@ where fn from(value: Vec) -> Self { let mut array = Object::default(); for (i, item) in value.into_iter().enumerate() { - array.insert_property(i, Property::default().value(item.into())); + array.insert_property(i, item, Attribute::default()); } Value::from(array) } diff --git a/boa/src/builtins/value/mod.rs b/boa/src/builtins/value/mod.rs index 145c15e619a..be46c609ef4 100644 --- a/boa/src/builtins/value/mod.rs +++ b/boa/src/builtins/value/mod.rs @@ -486,7 +486,8 @@ impl Value { let _timer = BoaProfiler::global().start_event("Value::update_property", "value"); if let Some(ref mut object) = self.as_object_mut() { - object.insert_property(field, new_property); + // FIXME overwrite the property + object.insert(field, new_property); } } @@ -572,7 +573,7 @@ impl Value { K: Into, { if let Some(mut object) = self.as_object_mut() { - object.insert_property(key.into(), property.clone()); + object.insert(key, property.clone()); } property }