From 7f1ab6289b2f58018c4009f7b728db721d4e196f Mon Sep 17 00:00:00 2001 From: jedel1043 Date: Mon, 20 Sep 2021 16:29:00 -0500 Subject: [PATCH 1/2] Rewrite initialization of builtins to use 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 | 96 +++++++++++++++-------------- 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 +-- 28 files changed, 186 insertions(+), 184 deletions(-) diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index e79683cb1af..99dedeb9ed6 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 499650f9e2a..a6f183f10b4 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 3739c446593..acd9d6ab79a 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 e6c8abd586c..06ba2cd9f1f 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 7b89169476e..8a23ee1f5cd 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 ef914de6c8d..21fb99ca9ae 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 e5da9d9f947..89791f7c2c2 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 1a315274604..b58f7e5ae7d 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 e95b00211b4..8384068ca29 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 f84ab4140f0..d8d8a0404f1 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 2933cdcca95..c0a7455f797 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 6b93dc10d9b..d5ef0b0c5dd 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 d19761fc65c..819169b7d38 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 3ccf2b98c11..3de2be3ca2e 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 99cbbaeb135..37140d35acf 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 cbef96cf473..496f1162d29 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 776b9c81a60..227415f6999 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 12cdc0683b6..99c6856097f 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 e9f17db73ba..94580d9d443 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; @@ -53,6 +50,7 @@ pub(crate) use self::{ undefined::Undefined, }; use crate::{ + object::JsObject, property::{Attribute, PropertyDescriptor}, Context, JsValue, }; @@ -61,56 +59,64 @@ pub(crate) trait BuiltIn { /// The binding name of the property. const NAME: &'static str; - fn attribute() -> Attribute; - fn init(context: &mut Context) -> (&'static str, JsValue, Attribute); + const ATTRIBUTE: Attribute; + fn init(context: &mut Context) -> JsValue; +} + +#[inline] +fn init_builtin(global: &JsObject, 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()); + global.borrow_mut().insert(B::NAME, property); } /// Initializes builtin 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, - ]; - let global_object = context.global_object(); - 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); + macro_rules! globals { + ($( $builtin:ty ),*) => { + $(init_builtin::<$builtin>(&global_object, context) + );* + } } + + 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 + }; + + #[cfg(feature = "console")] + init_builtin::(&global_object, context); } pub trait JsArgs { diff --git a/boa/src/builtins/nan/mod.rs b/boa/src/builtins/nan/mod.rs index 077702f6129..c1bbb40bf3e 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 c4e8e4dc008..47135798527 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 58b5174b36e..d0229ad4030 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( @@ -87,7 +87,7 @@ impl BuiltIn for Object { ) .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 c699f572bff..7bed5e6de7b 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 ca49d3b648e..51388dcac30 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 971f3130e70..f1021b7b477 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 303526718cf..6f8bde82d96 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 e7a91cd8989..6b9c3b4d55b 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 ed134416296..55cb0b45eef 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() } } From 7f6e06b89621857c84e533ff88d546fd4c747bdb Mon Sep 17 00:00:00 2001 From: jedel1043 Date: Fri, 1 Oct 2021 22:32:28 -0500 Subject: [PATCH 2/2] Document the `BuiltIn` trait --- boa/src/builtins/mod.rs | 35 +++++++++++++++++++++++-------- boa/src/property/attribute/mod.rs | 2 +- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/boa/src/builtins/mod.rs b/boa/src/builtins/mod.rs index 94580d9d443..f1544ef3d17 100644 --- a/boa/src/builtins/mod.rs +++ b/boa/src/builtins/mod.rs @@ -50,38 +50,55 @@ pub(crate) use self::{ undefined::Undefined, }; use crate::{ - object::JsObject, property::{Attribute, PropertyDescriptor}, 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; + /// 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(global: &JsObject, context: &mut Context) { +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()); - global.borrow_mut().insert(B::NAME, property); + 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 global_object = context.global_object(); - macro_rules! globals { ($( $builtin:ty ),*) => { - $(init_builtin::<$builtin>(&global_object, context) + $(init_builtin::<$builtin>(context) );* } } @@ -116,7 +133,7 @@ pub fn init(context: &mut Context) { }; #[cfg(feature = "console")] - init_builtin::(&global_object, context); + init_builtin::(context); } pub trait JsArgs { diff --git a/boa/src/property/attribute/mod.rs b/boa/src/property/attribute/mod.rs index 875db40c7b3..29b826b1052 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