From 1cbbb0fd723a02bab3cff9bdb56ea2f58d772ae0 Mon Sep 17 00:00:00 2001 From: jedel1043 Date: Sat, 2 Oct 2021 15:20:23 -0500 Subject: [PATCH] Rewrite initialization of builtins to use the `BuiltIn` trait (#1586) * Rewrite initialization of builtins to use the `BuiltIn` trait * Document the `BuiltIn` trait --- boa/src/builtins/array/mod.rs | 10 +-- boa/src/builtins/bigint/mod.rs | 10 +-- boa/src/builtins/boolean/mod.rs | 10 +-- boa/src/builtins/console/mod.rs | 10 +-- boa/src/builtins/date/mod.rs | 10 +-- boa/src/builtins/error/eval.rs | 10 +-- boa/src/builtins/error/mod.rs | 10 +-- boa/src/builtins/error/range.rs | 10 +-- boa/src/builtins/error/reference.rs | 10 +-- boa/src/builtins/error/syntax.rs | 10 +-- boa/src/builtins/error/type.rs | 10 +-- boa/src/builtins/error/uri.rs | 10 +-- boa/src/builtins/function/mod.rs | 10 +-- boa/src/builtins/global_this/mod.rs | 14 ++-- boa/src/builtins/infinity/mod.rs | 10 +-- boa/src/builtins/json/mod.rs | 10 +-- boa/src/builtins/map/mod.rs | 10 +-- boa/src/builtins/math/mod.rs | 10 +-- boa/src/builtins/mod.rs | 119 +++++++++++++++++----------- boa/src/builtins/nan/mod.rs | 10 +-- boa/src/builtins/number/mod.rs | 10 +-- boa/src/builtins/object/mod.rs | 10 +-- boa/src/builtins/reflect/mod.rs | 10 +-- boa/src/builtins/regexp/mod.rs | 10 +-- boa/src/builtins/set/mod.rs | 10 +-- boa/src/builtins/string/mod.rs | 10 +-- boa/src/builtins/symbol/mod.rs | 10 +-- boa/src/builtins/undefined/mod.rs | 10 +-- boa/src/property/attribute/mod.rs | 2 +- 29 files changed, 207 insertions(+), 188 deletions(-) diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index e79683cb1a..99dedeb9ed 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -38,11 +38,11 @@ pub(crate) struct Array; impl BuiltIn for Array { const NAME: &'static str = "Array"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let symbol_iterator = WellKnownSymbols::iterator(); @@ -120,7 +120,7 @@ impl BuiltIn for Array { .static_method(Self::of, "of", 0) .build(); - (Self::NAME, array.into(), Self::attribute()) + array.into() } } diff --git a/boa/src/builtins/bigint/mod.rs b/boa/src/builtins/bigint/mod.rs index 499650f9e2..a6f183f10b 100644 --- a/boa/src/builtins/bigint/mod.rs +++ b/boa/src/builtins/bigint/mod.rs @@ -30,11 +30,11 @@ pub struct BigInt; impl BuiltIn for BigInt { const NAME: &'static str = "BigInt"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let to_string_tag = WellKnownSymbols::to_string_tag(); @@ -59,7 +59,7 @@ impl BuiltIn for BigInt { ) .build(); - (Self::NAME, bigint_object.into(), Self::attribute()) + bigint_object.into() } } diff --git a/boa/src/builtins/boolean/mod.rs b/boa/src/builtins/boolean/mod.rs index 3739c44659..acd9d6ab79 100644 --- a/boa/src/builtins/boolean/mod.rs +++ b/boa/src/builtins/boolean/mod.rs @@ -28,11 +28,11 @@ impl BuiltIn for Boolean { /// The name of the object. const NAME: &'static str = "Boolean"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let boolean_object = ConstructorBuilder::with_standard_object( @@ -46,7 +46,7 @@ impl BuiltIn for Boolean { .method(Self::value_of, "valueOf", 0) .build(); - (Self::NAME, boolean_object.into(), Self::attribute()) + boolean_object.into() } } diff --git a/boa/src/builtins/console/mod.rs b/boa/src/builtins/console/mod.rs index e6c8abd586..06ba2cd9f1 100644 --- a/boa/src/builtins/console/mod.rs +++ b/boa/src/builtins/console/mod.rs @@ -137,11 +137,11 @@ pub(crate) struct Console { impl BuiltIn for Console { const NAME: &'static str = "console"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let console = ObjectInitializer::new(context) .function(Self::assert, "assert", 0) @@ -165,7 +165,7 @@ impl BuiltIn for Console { .function(Self::dir, "dirxml", 0) .build(); - (Self::NAME, console.into(), Self::attribute()) + console.into() } } diff --git a/boa/src/builtins/date/mod.rs b/boa/src/builtins/date/mod.rs index 7b89169476..8a23ee1f5c 100644 --- a/boa/src/builtins/date/mod.rs +++ b/boa/src/builtins/date/mod.rs @@ -89,11 +89,11 @@ impl Default for Date { impl BuiltIn for Date { const NAME: &'static str = "Date"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let date_object = ConstructorBuilder::new(context, Self::constructor) @@ -157,7 +157,7 @@ impl BuiltIn for Date { .static_method(Self::utc, "UTC", 7) .build(); - (Self::NAME, date_object.into(), Self::attribute()) + date_object.into() } } diff --git a/boa/src/builtins/error/eval.rs b/boa/src/builtins/error/eval.rs index ef914de6c8..21fb99ca9a 100644 --- a/boa/src/builtins/error/eval.rs +++ b/boa/src/builtins/error/eval.rs @@ -29,11 +29,11 @@ pub(crate) struct EvalError; impl BuiltIn for EvalError { const NAME: &'static str = "EvalError"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let error_prototype = context.standard_objects().error_object().prototype(); @@ -50,7 +50,7 @@ impl BuiltIn for EvalError { .property("message", "", attribute) .build(); - (Self::NAME, eval_error_object.into(), Self::attribute()) + eval_error_object.into() } } diff --git a/boa/src/builtins/error/mod.rs b/boa/src/builtins/error/mod.rs index e5da9d9f94..89791f7c2c 100644 --- a/boa/src/builtins/error/mod.rs +++ b/boa/src/builtins/error/mod.rs @@ -43,11 +43,11 @@ pub(crate) struct Error; impl BuiltIn for Error { const NAME: &'static str = "Error"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let attribute = Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE; @@ -63,7 +63,7 @@ impl BuiltIn for Error { .method(Self::to_string, "toString", 0) .build(); - (Self::NAME, error_object.into(), Self::attribute()) + error_object.into() } } diff --git a/boa/src/builtins/error/range.rs b/boa/src/builtins/error/range.rs index 1a31527460..b58f7e5ae7 100644 --- a/boa/src/builtins/error/range.rs +++ b/boa/src/builtins/error/range.rs @@ -25,11 +25,11 @@ pub(crate) struct RangeError; impl BuiltIn for RangeError { const NAME: &'static str = "RangeError"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let error_prototype = context.standard_objects().error_object().prototype(); @@ -46,7 +46,7 @@ impl BuiltIn for RangeError { .property("message", "", attribute) .build(); - (Self::NAME, range_error_object.into(), Self::attribute()) + range_error_object.into() } } diff --git a/boa/src/builtins/error/reference.rs b/boa/src/builtins/error/reference.rs index e95b00211b..8384068ca2 100644 --- a/boa/src/builtins/error/reference.rs +++ b/boa/src/builtins/error/reference.rs @@ -24,11 +24,11 @@ pub(crate) struct ReferenceError; impl BuiltIn for ReferenceError { const NAME: &'static str = "ReferenceError"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let error_prototype = context.standard_objects().error_object().prototype(); @@ -45,7 +45,7 @@ impl BuiltIn for ReferenceError { .property("message", "", attribute) .build(); - (Self::NAME, reference_error_object.into(), Self::attribute()) + reference_error_object.into() } } diff --git a/boa/src/builtins/error/syntax.rs b/boa/src/builtins/error/syntax.rs index f84ab4140f..d8d8a0404f 100644 --- a/boa/src/builtins/error/syntax.rs +++ b/boa/src/builtins/error/syntax.rs @@ -27,11 +27,11 @@ pub(crate) struct SyntaxError; impl BuiltIn for SyntaxError { const NAME: &'static str = "SyntaxError"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let error_prototype = context.standard_objects().error_object().prototype(); @@ -48,7 +48,7 @@ impl BuiltIn for SyntaxError { .property("message", "", attribute) .build(); - (Self::NAME, syntax_error_object.into(), Self::attribute()) + syntax_error_object.into() } } diff --git a/boa/src/builtins/error/type.rs b/boa/src/builtins/error/type.rs index 2933cdcca9..c0a7455f79 100644 --- a/boa/src/builtins/error/type.rs +++ b/boa/src/builtins/error/type.rs @@ -30,11 +30,11 @@ pub(crate) struct TypeError; impl BuiltIn for TypeError { const NAME: &'static str = "TypeError"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let error_prototype = context.standard_objects().error_object().prototype(); @@ -51,7 +51,7 @@ impl BuiltIn for TypeError { .property("message", "", attribute) .build(); - (Self::NAME, type_error_object.into(), Self::attribute()) + type_error_object.into() } } diff --git a/boa/src/builtins/error/uri.rs b/boa/src/builtins/error/uri.rs index 6b93dc10d9..d5ef0b0c5d 100644 --- a/boa/src/builtins/error/uri.rs +++ b/boa/src/builtins/error/uri.rs @@ -26,11 +26,11 @@ pub(crate) struct UriError; impl BuiltIn for UriError { const NAME: &'static str = "URIError"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let error_prototype = context.standard_objects().error_object().prototype(); @@ -47,7 +47,7 @@ impl BuiltIn for UriError { .property("message", "", attribute) .build(); - (Self::NAME, uri_error_object.into(), Self::attribute()) + uri_error_object.into() } } diff --git a/boa/src/builtins/function/mod.rs b/boa/src/builtins/function/mod.rs index d19761fc65..819169b7d3 100644 --- a/boa/src/builtins/function/mod.rs +++ b/boa/src/builtins/function/mod.rs @@ -184,11 +184,11 @@ impl BuiltInFunctionObject { impl BuiltIn for BuiltInFunctionObject { const NAME: &'static str = "Function"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event("function", "init"); let function_prototype = context.standard_objects().function_object().prototype(); @@ -210,6 +210,6 @@ impl BuiltIn for BuiltInFunctionObject { .method(Self::to_string, "toString", 0) .build(); - (Self::NAME, function_object.into(), Self::attribute()) + function_object.into() } } diff --git a/boa/src/builtins/global_this/mod.rs b/boa/src/builtins/global_this/mod.rs index 3ccf2b98c1..3de2be3ca2 100644 --- a/boa/src/builtins/global_this/mod.rs +++ b/boa/src/builtins/global_this/mod.rs @@ -21,17 +21,13 @@ pub(crate) struct GlobalThis; impl BuiltIn for GlobalThis { const NAME: &'static str = "globalThis"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); - ( - Self::NAME, - context.global_object().into(), - Self::attribute(), - ) + context.global_object().into() } } diff --git a/boa/src/builtins/infinity/mod.rs b/boa/src/builtins/infinity/mod.rs index 99cbbaeb13..37140d35ac 100644 --- a/boa/src/builtins/infinity/mod.rs +++ b/boa/src/builtins/infinity/mod.rs @@ -21,13 +21,13 @@ pub(crate) struct Infinity; impl BuiltIn for Infinity { const NAME: &'static str = "Infinity"; - fn attribute() -> Attribute { - Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT - } + const ATTRIBUTE: Attribute = Attribute::READONLY + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::PERMANENT); - fn init(_: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(_: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); - (Self::NAME, f64::INFINITY.into(), Self::attribute()) + f64::INFINITY.into() } } diff --git a/boa/src/builtins/json/mod.rs b/boa/src/builtins/json/mod.rs index cbef96cf47..496f1162d2 100644 --- a/boa/src/builtins/json/mod.rs +++ b/boa/src/builtins/json/mod.rs @@ -38,11 +38,11 @@ pub(crate) struct Json; impl BuiltIn for Json { const NAME: &'static str = "JSON"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let to_string_tag = WellKnownSymbols::to_string_tag(); @@ -54,7 +54,7 @@ impl BuiltIn for Json { .property(to_string_tag, Self::NAME, attribute) .build(); - (Self::NAME, json_object.into(), Self::attribute()) + json_object.into() } } diff --git a/boa/src/builtins/map/mod.rs b/boa/src/builtins/map/mod.rs index 776b9c81a6..227415f699 100644 --- a/boa/src/builtins/map/mod.rs +++ b/boa/src/builtins/map/mod.rs @@ -44,11 +44,11 @@ pub(crate) struct Map(OrderedMap); impl BuiltIn for Map { const NAME: &'static str = "Map"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let get_species = FunctionBuilder::native(context, Self::get_species) @@ -107,7 +107,7 @@ impl BuiltIn for Map { .accessor("size", Some(get_size), None, Attribute::CONFIGURABLE) .build(); - (Self::NAME, map_object.into(), Self::attribute()) + map_object.into() } } diff --git a/boa/src/builtins/math/mod.rs b/boa/src/builtins/math/mod.rs index 12cdc0683b..99c6856097 100644 --- a/boa/src/builtins/math/mod.rs +++ b/boa/src/builtins/math/mod.rs @@ -28,11 +28,11 @@ pub(crate) struct Math; impl BuiltIn for Math { const NAME: &'static str = "Math"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let attribute = Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT; @@ -88,7 +88,7 @@ impl BuiltIn for Math { ) .build(); - (Self::NAME, object.into(), Self::attribute()) + object.into() } } diff --git a/boa/src/builtins/mod.rs b/boa/src/builtins/mod.rs index e9f17db73b..f1544ef3d1 100644 --- a/boa/src/builtins/mod.rs +++ b/boa/src/builtins/mod.rs @@ -1,8 +1,5 @@ //! Builtins live here, such as Object, String, Math, etc. -// builtins module has a lot of built-in functions that need unnecessary_wraps -#![allow(clippy::unnecessary_wraps)] - pub mod array; pub mod bigint; pub mod boolean; @@ -57,60 +54,86 @@ use crate::{ Context, JsValue, }; +/// Trait representing a global built-in object such as `Math`, `Object` or +/// `String`. +/// +/// This trait must be implemented for any global built-in accessible from +/// Javascript. pub(crate) trait BuiltIn { - /// The binding name of the property. + /// Binding name of the built-in inside the global object. + /// + /// E.g. If you want access the properties of a `Complex` built-in + /// with the name `Cplx` you must assign `"Cplx"` to this constant, + /// making any property inside it accessible from Javascript as `Cplx.prop` const NAME: &'static str; - fn attribute() -> Attribute; - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute); + /// Property attribute flags of the built-in. + /// Check [Attribute] for more information. + const ATTRIBUTE: Attribute; + + /// Initialization code for the built-in. + /// This is where the methods, properties, static methods and the constructor + /// of a built-in must be initialized to be accessible from Javascript. + fn init(context: &mut Context) -> JsValue; +} + +/// Utility function that checks if a type implements `BuiltIn` before +/// initializing it as a global built-in. +#[inline] +fn init_builtin(context: &mut Context) { + let value = B::init(context); + let property = PropertyDescriptor::builder() + .value(value) + .writable(B::ATTRIBUTE.writable()) + .enumerable(B::ATTRIBUTE.enumerable()) + .configurable(B::ATTRIBUTE.configurable()); + context + .global_object() + .borrow_mut() + .insert(B::NAME, property); } -/// Initializes builtin objects and functions +/// Initializes built-in objects and functions #[inline] pub fn init(context: &mut Context) { - let globals = [ - // Global properties. - Undefined::init, - Infinity::init, - NaN::init, - GlobalThis::init, - BuiltInFunctionObject::init, - BuiltInObjectObject::init, - Math::init, - Json::init, - Array::init, - BigInt::init, - Boolean::init, - Date::init, - Map::init, - Number::init, - Set::init, - String::init, - RegExp::init, - Symbol::init, - Error::init, - RangeError::init, - ReferenceError::init, - TypeError::init, - SyntaxError::init, - EvalError::init, - UriError::init, - Reflect::init, - #[cfg(feature = "console")] - console::Console::init, - ]; + macro_rules! globals { + ($( $builtin:ty ),*) => { + $(init_builtin::<$builtin>(context) + );* + } + } - let global_object = context.global_object(); + globals! { + Undefined, + Infinity, + NaN, + GlobalThis, + BuiltInFunctionObject, + BuiltInObjectObject, + Math, + Json, + Array, + BigInt, + Boolean, + Date, + Map, + Number, + Set, + String, + RegExp, + Symbol, + Error, + RangeError, + ReferenceError, + TypeError, + SyntaxError, + EvalError, + UriError, + Reflect + }; - for init in &globals { - let (name, value, attribute) = init(context); - let property = PropertyDescriptor::builder() - .value(value) - .writable(attribute.writable()) - .enumerable(attribute.enumerable()) - .configurable(attribute.configurable()); - global_object.borrow_mut().insert(name, property); - } + #[cfg(feature = "console")] + init_builtin::(context); } pub trait JsArgs { diff --git a/boa/src/builtins/nan/mod.rs b/boa/src/builtins/nan/mod.rs index 077702f612..c1bbb40bf3 100644 --- a/boa/src/builtins/nan/mod.rs +++ b/boa/src/builtins/nan/mod.rs @@ -22,13 +22,13 @@ pub(crate) struct NaN; impl BuiltIn for NaN { const NAME: &'static str = "NaN"; - fn attribute() -> Attribute { - Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT - } + const ATTRIBUTE: Attribute = Attribute::READONLY + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::PERMANENT); - fn init(_: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(_: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); - (Self::NAME, f64::NAN.into(), Self::attribute()) + f64::NAN.into() } } diff --git a/boa/src/builtins/number/mod.rs b/boa/src/builtins/number/mod.rs index c4e8e4dc00..4713579852 100644 --- a/boa/src/builtins/number/mod.rs +++ b/boa/src/builtins/number/mod.rs @@ -50,11 +50,11 @@ const PARSE_FLOAT_MAX_ARG_COUNT: usize = 1; impl BuiltIn for Number { const NAME: &'static str = "Number"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let attribute = Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT; @@ -103,7 +103,7 @@ impl BuiltIn for Number { make_builtin_fn(Self::global_is_finite, "isFinite", &global, 1, context); make_builtin_fn(Self::global_is_nan, "isNaN", &global, 1, context); - (Self::NAME, number_object.into(), Self::attribute()) + number_object.into() } } diff --git a/boa/src/builtins/object/mod.rs b/boa/src/builtins/object/mod.rs index 35e384fa0c..6773253db4 100644 --- a/boa/src/builtins/object/mod.rs +++ b/boa/src/builtins/object/mod.rs @@ -39,11 +39,11 @@ pub struct Object; impl BuiltIn for Object { const NAME: &'static str = "Object"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let object = ConstructorBuilder::with_standard_object( @@ -89,7 +89,7 @@ impl BuiltIn for Object { .static_method(Self::get_own_property_symbols, "getOwnPropertySymbols", 1) .build(); - (Self::NAME, object.into(), Self::attribute()) + object.into() } } diff --git a/boa/src/builtins/reflect/mod.rs b/boa/src/builtins/reflect/mod.rs index c699f572bf..7bed5e6de7 100644 --- a/boa/src/builtins/reflect/mod.rs +++ b/boa/src/builtins/reflect/mod.rs @@ -30,11 +30,11 @@ pub(crate) struct Reflect; impl BuiltIn for Reflect { const NAME: &'static str = "Reflect"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let to_string_tag = WellKnownSymbols::to_string_tag(); @@ -63,7 +63,7 @@ impl BuiltIn for Reflect { Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, ) .build(); - (Self::NAME, object.into(), Self::attribute()) + object.into() } } diff --git a/boa/src/builtins/regexp/mod.rs b/boa/src/builtins/regexp/mod.rs index ca49d3b648..51388dcac3 100644 --- a/boa/src/builtins/regexp/mod.rs +++ b/boa/src/builtins/regexp/mod.rs @@ -71,11 +71,11 @@ unsafe impl Trace for RegExp { impl BuiltIn for RegExp { const NAME: &'static str = "RegExp"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let get_species = FunctionBuilder::native(context, Self::get_species) @@ -171,7 +171,7 @@ impl BuiltIn for RegExp { // TODO: add them RegExp accessor properties - (Self::NAME, regexp_object.into(), Self::attribute()) + regexp_object.into() } } diff --git a/boa/src/builtins/set/mod.rs b/boa/src/builtins/set/mod.rs index 971f3130e7..f1021b7b47 100644 --- a/boa/src/builtins/set/mod.rs +++ b/boa/src/builtins/set/mod.rs @@ -38,11 +38,11 @@ pub(crate) struct Set(OrderedSet); impl BuiltIn for Set { const NAME: &'static str = "Set"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let get_species = FunctionBuilder::native(context, Self::get_species) @@ -107,7 +107,7 @@ impl BuiltIn for Set { ) .build(); - (Self::NAME, set_object.into(), Self::attribute()) + set_object.into() } } diff --git a/boa/src/builtins/string/mod.rs b/boa/src/builtins/string/mod.rs index 303526718c..6f8bde82d9 100644 --- a/boa/src/builtins/string/mod.rs +++ b/boa/src/builtins/string/mod.rs @@ -90,11 +90,11 @@ pub(crate) struct String; impl BuiltIn for String { const NAME: &'static str = "String"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let symbol_iterator = WellKnownSymbols::iterator(); @@ -141,7 +141,7 @@ impl BuiltIn for String { .method(Self::at, "at", 1) .build(); - (Self::NAME, string_object.into(), Self::attribute()) + string_object.into() } } diff --git a/boa/src/builtins/symbol/mod.rs b/boa/src/builtins/symbol/mod.rs index e7a91cd898..6b9c3b4d55 100644 --- a/boa/src/builtins/symbol/mod.rs +++ b/boa/src/builtins/symbol/mod.rs @@ -76,11 +76,11 @@ pub struct Symbol; impl BuiltIn for Symbol { const NAME: &'static str = "Symbol"; - fn attribute() -> Attribute { - Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE - } + const ATTRIBUTE: Attribute = Attribute::WRITABLE + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::CONFIGURABLE); - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(context: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); let symbol_async_iterator = WellKnownSymbols::async_iterator(); @@ -142,7 +142,7 @@ impl BuiltIn for Symbol { ) .build(); - (Self::NAME, symbol_object.into(), Self::attribute()) + symbol_object.into() } } diff --git a/boa/src/builtins/undefined/mod.rs b/boa/src/builtins/undefined/mod.rs index ed13441629..55cb0b45ee 100644 --- a/boa/src/builtins/undefined/mod.rs +++ b/boa/src/builtins/undefined/mod.rs @@ -21,13 +21,13 @@ pub(crate) struct Undefined; impl BuiltIn for Undefined { const NAME: &'static str = "undefined"; - fn attribute() -> Attribute { - Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT - } + const ATTRIBUTE: Attribute = Attribute::READONLY + .union(Attribute::NON_ENUMERABLE) + .union(Attribute::PERMANENT); - fn init(_: &mut Context) -> (&'static str, JsValue, Attribute) { + fn init(_: &mut Context) -> JsValue { let _timer = BoaProfiler::global().start_event(Self::NAME, "init"); - (Self::NAME, JsValue::undefined(), Self::attribute()) + JsValue::undefined() } } diff --git a/boa/src/property/attribute/mod.rs b/boa/src/property/attribute/mod.rs index 875db40c7b..29b826b105 100644 --- a/boa/src/property/attribute/mod.rs +++ b/boa/src/property/attribute/mod.rs @@ -7,7 +7,7 @@ use bitflags::bitflags; mod tests; bitflags! { - /// This struct constains the property flags as describen in the ECMAScript specification. + /// This struct constains the property flags as described in the ECMAScript specification. /// /// It contains the following flags: /// - `[[Writable]]` (`WRITABLE`) - If `false`, attempts by ECMAScript code to change the property's