From 7688ab0e450db061518b5fec2fd478ca02e7aa9c Mon Sep 17 00:00:00 2001 From: Norbert Garfield Date: Mon, 21 Mar 2022 21:37:00 +0000 Subject: [PATCH 1/3] Implement unscopables for Array.prototype --- boa_engine/src/builtins/array/mod.rs | 47 ++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/boa_engine/src/builtins/array/mod.rs b/boa_engine/src/builtins/array/mod.rs index bb8a9547c9f..645445387f5 100644 --- a/boa_engine/src/builtins/array/mod.rs +++ b/boa_engine/src/builtins/array/mod.rs @@ -45,6 +45,7 @@ impl BuiltIn for Array { let _timer = Profiler::global().start_event(Self::NAME, "init"); let symbol_iterator = WellKnownSymbols::iterator(); + let symbol_unscopables = WellKnownSymbols::unscopables(); let get_species = FunctionBuilder::native(context, Self::get_species) .name("get [Symbol.species]") @@ -52,6 +53,7 @@ impl BuiltIn for Array { .build(); let values_function = Self::values_intrinsic(context); + let unscopables_object = Self::unscopables_intrinsic(context); ConstructorBuilder::with_standard_constructor( context, @@ -81,6 +83,11 @@ impl BuiltIn for Array { values_function, Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, ) + .property( + symbol_unscopables, + unscopables_object, + Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) .method(Self::at, "at", 1) .method(Self::concat, "concat", 1) .method(Self::push, "push", 1) @@ -2855,4 +2862,44 @@ impl Array { .constructor(false) .build() } + + pub(crate) fn unscopables_intrinsic(context: &mut Context) -> JsObject { + let object_prototype = context.construct_object(); + let result_obj = JsObject::from_proto_and_data(object_prototype, ObjectData::ordinary()); + result_obj + .create_data_property_or_throw("at", true, context) + .expect("CreateDataPropertyOrThrow for 'at' must not fail"); + result_obj + .create_data_property_or_throw("copyWithin", true, context) + .expect("CreateDataPropertyOrThrow for 'copyWithin' must not fail"); + result_obj + .create_data_property_or_throw("entries", true, context) + .expect("CreateDataPropertyOrThrow for 'entries' must not fail"); + result_obj + .create_data_property_or_throw("fill", true, context) + .expect("CreateDataPropertyOrThrow for 'fill' must not fail"); + result_obj + .create_data_property_or_throw("find", true, context) + .expect("CreateDataPropertyOrThrow for 'find' must not fail"); + result_obj + .create_data_property_or_throw("findIndex", true, context) + .expect("CreateDataPropertyOrThrow for 'findIndex' must not fail"); + result_obj + .create_data_property_or_throw("flat", true, context) + .expect("CreateDataPropertyOrThrow for 'flat' must not fail"); + result_obj + .create_data_property_or_throw("flatMap", true, context) + .expect("CreateDataPropertyOrThrow for 'flatMap' must not fail"); + result_obj + .create_data_property_or_throw("includes", true, context) + .expect("CreateDataPropertyOrThrow for 'includes' must not fail"); + result_obj + .create_data_property_or_throw("keys", true, context) + .expect("CreateDataPropertyOrThrow for 'keys' must not fail"); + result_obj + .create_data_property_or_throw("values", true, context) + .expect("CreateDataPropertyOrThrow for 'values' must not fail"); + + result_obj + } } From 61f2c67542cc2c3859479b51c5dc628f7d4296a9 Mon Sep 17 00:00:00 2001 From: Norbert Garfield Date: Tue, 22 Mar 2022 20:27:35 +0000 Subject: [PATCH 2/3] Add subroutine documentation --- boa_engine/src/builtins/array/mod.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/boa_engine/src/builtins/array/mod.rs b/boa_engine/src/builtins/array/mod.rs index 645445387f5..2e7a49b8424 100644 --- a/boa_engine/src/builtins/array/mod.rs +++ b/boa_engine/src/builtins/array/mod.rs @@ -2863,9 +2863,21 @@ impl Array { .build() } + /// `Array.prototype [ @@unscopables ]` + /// + /// The initial value of the 'unscopables' data property is an ordinary object + /// with the following boolean properties set to true: + /// 'at', 'copyWithin', 'entries', 'fill', 'find', 'findIndex', 'flat', + /// 'flatMap', 'includes', 'keys', 'values' + /// + /// More information: + /// - [ECMAScript reference][spec] + /// - [MDN documentation][mdn] + /// + /// [spec]: https://tc39.es/ecma262/#sec-array.prototype-@@unscopables + /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/@@unscopables pub(crate) fn unscopables_intrinsic(context: &mut Context) -> JsObject { - let object_prototype = context.construct_object(); - let result_obj = JsObject::from_proto_and_data(object_prototype, ObjectData::ordinary()); + let result_obj = JsObject::empty(); result_obj .create_data_property_or_throw("at", true, context) .expect("CreateDataPropertyOrThrow for 'at' must not fail"); From d4e844f8916bb1721f218541faf70c666502734f Mon Sep 17 00:00:00 2001 From: Norbert Garfield Date: Tue, 22 Mar 2022 21:05:15 +0000 Subject: [PATCH 3/3] Document unscopables implementation steps --- boa_engine/src/builtins/array/mod.rs | 39 ++++++++++++++++++---------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/boa_engine/src/builtins/array/mod.rs b/boa_engine/src/builtins/array/mod.rs index 2e7a49b8424..33d76ac2f82 100644 --- a/boa_engine/src/builtins/array/mod.rs +++ b/boa_engine/src/builtins/array/mod.rs @@ -2877,41 +2877,54 @@ impl Array { /// [spec]: https://tc39.es/ecma262/#sec-array.prototype-@@unscopables /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/@@unscopables pub(crate) fn unscopables_intrinsic(context: &mut Context) -> JsObject { - let result_obj = JsObject::empty(); - result_obj + // 1. Let unscopableList be OrdinaryObjectCreate(null). + let unscopable_list = JsObject::empty(); + // 2. Perform ! CreateDataPropertyOrThrow(unscopableList, "at", true). + unscopable_list .create_data_property_or_throw("at", true, context) .expect("CreateDataPropertyOrThrow for 'at' must not fail"); - result_obj + // 3. Perform ! CreateDataPropertyOrThrow(unscopableList, "copyWithin", true). + unscopable_list .create_data_property_or_throw("copyWithin", true, context) .expect("CreateDataPropertyOrThrow for 'copyWithin' must not fail"); - result_obj + // 4. Perform ! CreateDataPropertyOrThrow(unscopableList, "entries", true). + unscopable_list .create_data_property_or_throw("entries", true, context) .expect("CreateDataPropertyOrThrow for 'entries' must not fail"); - result_obj + // 5. Perform ! CreateDataPropertyOrThrow(unscopableList, "fill", true). + unscopable_list .create_data_property_or_throw("fill", true, context) .expect("CreateDataPropertyOrThrow for 'fill' must not fail"); - result_obj + // 6. Perform ! CreateDataPropertyOrThrow(unscopableList, "find", true). + unscopable_list .create_data_property_or_throw("find", true, context) .expect("CreateDataPropertyOrThrow for 'find' must not fail"); - result_obj + // 7. Perform ! CreateDataPropertyOrThrow(unscopableList, "findIndex", true). + unscopable_list .create_data_property_or_throw("findIndex", true, context) .expect("CreateDataPropertyOrThrow for 'findIndex' must not fail"); - result_obj + // 8. Perform ! CreateDataPropertyOrThrow(unscopableList, "flat", true). + unscopable_list .create_data_property_or_throw("flat", true, context) .expect("CreateDataPropertyOrThrow for 'flat' must not fail"); - result_obj + // 9. Perform ! CreateDataPropertyOrThrow(unscopableList, "flatMap", true). + unscopable_list .create_data_property_or_throw("flatMap", true, context) .expect("CreateDataPropertyOrThrow for 'flatMap' must not fail"); - result_obj + // 10. Perform ! CreateDataPropertyOrThrow(unscopableList, "includes", true). + unscopable_list .create_data_property_or_throw("includes", true, context) .expect("CreateDataPropertyOrThrow for 'includes' must not fail"); - result_obj + // 11. Perform ! CreateDataPropertyOrThrow(unscopableList, "keys", true). + unscopable_list .create_data_property_or_throw("keys", true, context) .expect("CreateDataPropertyOrThrow for 'keys' must not fail"); - result_obj + // 12. Perform ! CreateDataPropertyOrThrow(unscopableList, "values", true). + unscopable_list .create_data_property_or_throw("values", true, context) .expect("CreateDataPropertyOrThrow for 'values' must not fail"); - result_obj + // 13. Return unscopableList. + unscopable_list } }