From 7e043f7e9be1384f2ee402217de1f5ca259c77c8 Mon Sep 17 00:00:00 2001 From: Iban Eguia Moraza Date: Fri, 17 Jun 2022 18:12:07 +0200 Subject: [PATCH] Fixed Promises with the `[[Done]]` flag in iterators. Also upgraded dependencies, updated the Test262 and fixed a couple of small spec implementations. --- Cargo.lock | 84 ++++++++++--------- boa_cli/Cargo.toml | 2 +- boa_engine/Cargo.toml | 4 +- boa_engine/src/builtins/array/mod.rs | 16 ++-- boa_engine/src/builtins/array_buffer/mod.rs | 2 +- boa_engine/src/builtins/iterable/mod.rs | 9 ++ boa_engine/src/builtins/promise/mod.rs | 19 +++-- boa_engine/src/builtins/reflect/mod.rs | 34 ++++---- boa_engine/src/builtins/regexp/mod.rs | 8 +- boa_engine/src/builtins/typed_array/mod.rs | 2 +- .../object/internal_methods/bound_function.rs | 11 +-- .../src/object/internal_methods/function.rs | 4 +- boa_engine/src/object/internal_methods/mod.rs | 4 +- .../src/object/internal_methods/proxy.rs | 12 ++- boa_engine/src/object/operations.rs | 11 ++- boa_engine/src/vm/mod.rs | 4 +- boa_wasm/Cargo.toml | 2 +- test262 | 2 +- 18 files changed, 130 insertions(+), 100 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6d45534b291..27e92881e17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,7 +75,7 @@ version = "0.15.0" dependencies = [ "boa_engine", "boa_interner", - "clap 3.1.18", + "clap 3.2.5", "colored", "jemallocator", "phf", @@ -270,16 +270,16 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.18" +version = "3.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b" +checksum = "d53da17d37dba964b9b3ecb5c5a1f193a2762c700e6829201e645b9381c99dc7" dependencies = [ "atty", "bitflags", "clap_derive", "clap_lex", "indexmap", - "lazy_static", + "once_cell", "strsim 0.10.0", "termcolor", "textwrap 0.15.0", @@ -287,9 +287,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.1.18" +version = "3.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c" +checksum = "c11d40217d16aee8508cc8e5fde8b4ff24639758608e5374e731b53f85749fb9" dependencies = [ "heck 0.4.0", "proc-macro-error", @@ -300,9 +300,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" +checksum = "5538cd660450ebeb4234cfecf8f2284b844ffc4c50531e66d584ad5b91293613" dependencies = [ "os_str_bytes", ] @@ -367,9 +367,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" +checksum = "4c02a4d71819009c192cf4872265391563fd6a84c81ff2c0f2a7026ca4c1d85c" dependencies = [ "cfg-if", "crossbeam-utils", @@ -388,26 +388,26 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" +checksum = "07db9d94cbd326813772c968ccd25999e5f8ae22f4f8d1b11effa37ef6ce281d" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "lazy_static", "memoffset", + "once_cell", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" +checksum = "8ff1f980957787286a554052d03c7aee98d99cc32e09f6d45f0a814133c87978" dependencies = [ "cfg-if", - "lazy_static", + "once_cell", ] [[package]] @@ -631,6 +631,12 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" + [[package]] name = "heck" version = "0.3.3" @@ -786,12 +792,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.8.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a" +checksum = "6c6392766afd7964e2531940894cffe4bd8d7d17dbc3c1c4857040fd4b33bdb3" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.1", ] [[package]] @@ -853,9 +859,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.57" +version = "0.3.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" +checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" dependencies = [ "wasm-bindgen", ] @@ -1529,7 +1535,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91e2531d8525b29b514d25e275a43581320d587b86db302b9a7e464bac579648" dependencies = [ "cfg-if", - "hashbrown", + "hashbrown 0.11.2", "serde", ] @@ -1594,13 +1600,15 @@ dependencies = [ [[package]] name = "sys-locale" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3913c5a3d30054d7f77cf07cdd800c8103ace15c6e44437c5db66a43dd3a92cf" +checksum = "658ee915b6c7b73ec4c1ffcd838506b5c5a4087eadc1ec8f862f1066cf2c8132" dependencies = [ "cc", "cstr_core", + "js-sys", "libc", + "wasm-bindgen", "web-sys", "winapi", ] @@ -1710,9 +1718,9 @@ checksum = "1218098468b8085b19a2824104c70d976491d247ce194bbd9dc77181150cdfd6" [[package]] name = "unicode-ident" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" +checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" [[package]] name = "unicode-normalization" @@ -1784,9 +1792,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.80" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" +checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1794,9 +1802,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.80" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" +checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" dependencies = [ "bumpalo", "lazy_static", @@ -1809,9 +1817,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.80" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" +checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1819,9 +1827,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.80" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" +checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" dependencies = [ "proc-macro2", "quote", @@ -1832,15 +1840,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.80" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" +checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" [[package]] name = "web-sys" -version = "0.3.57" +version = "0.3.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" +checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/boa_cli/Cargo.toml b/boa_cli/Cargo.toml index f3a7066d6b7..4264af7d677 100644 --- a/boa_cli/Cargo.toml +++ b/boa_cli/Cargo.toml @@ -16,7 +16,7 @@ boa_engine = { path = "../boa_engine", features = ["deser", "console"], version boa_interner = { path = "../boa_interner", version = "0.15.0" } rustyline = "9.1.2" rustyline-derive = "0.6.0" -clap = { version = "3.1.18", features = ["derive"] } +clap = { version = "3.2.5", features = ["derive"] } serde_json = "1.0.81" colored = "2.0.0" regex = "1.5.6" diff --git a/boa_engine/Cargo.toml b/boa_engine/Cargo.toml index 875472c7b91..f617608dd84 100644 --- a/boa_engine/Cargo.toml +++ b/boa_engine/Cargo.toml @@ -42,7 +42,7 @@ rustc-hash = "1.1.0" num-bigint = { version = "0.4.3", features = ["serde"] } num-integer = "0.1.45" bitflags = "1.3.2" -indexmap = "1.8.2" +indexmap = "1.9.0" ryu-js = "0.2.2" chrono = "0.4.19" fast-float = "0.2.0" @@ -56,7 +56,7 @@ icu_datetime = { version = "0.6.0", features = ["serde"], optional = true } icu_plurals = { version = "0.6.0", features = ["serde"], optional = true } icu_provider = { version = "0.6.0", optional = true } icu_testdata = { version = "0.6.0", optional = true } -sys-locale = { version = "0.2.0", optional = true } +sys-locale = { version = "0.2.1", optional = true } [dev-dependencies] criterion = "0.3.5" diff --git a/boa_engine/src/builtins/array/mod.rs b/boa_engine/src/builtins/array/mod.rs index 7404a876cfb..02b2ff784e0 100644 --- a/boa_engine/src/builtins/array/mod.rs +++ b/boa_engine/src/builtins/array/mod.rs @@ -366,12 +366,10 @@ impl Array { // 7. If IsConstructor(C) is false, throw a TypeError exception. if let Some(c) = c.as_constructor() { // 8. Return ? Construct(C, « 𝔽(length) »). - Ok( - c.construct(&[JsValue::new(length)], &c.clone().into(), context)? - .as_object() - .expect("constructing an object should always return an object") - .clone(), - ) + Ok(c.construct(&[JsValue::new(length)], Some(c), context)? + .as_object() + .expect("constructing an object should always return an object") + .clone()) } else { context.throw_type_error("Symbol.species must be a constructor") } @@ -421,7 +419,7 @@ impl Array { // i. Let A be ? ArrayCreate(0en). let a = match this.as_constructor() { Some(constructor) => constructor - .construct(&[], this, context)? + .construct(&[], None, context)? .as_object() .cloned() .ok_or_else(|| { @@ -500,7 +498,7 @@ impl Array { // a. Let A be ? ArrayCreate(len). let a = match this.as_constructor() { Some(constructor) => constructor - .construct(&[len.into()], this, context)? + .construct(&[len.into()], None, context)? .as_object() .cloned() .ok_or_else(|| { @@ -582,7 +580,7 @@ impl Array { // a. Let A be ? ArrayCreate(len). let a = match this.as_constructor() { Some(constructor) => constructor - .construct(&[len.into()], this, context)? + .construct(&[len.into()], None, context)? .as_object() .cloned() .ok_or_else(|| { diff --git a/boa_engine/src/builtins/array_buffer/mod.rs b/boa_engine/src/builtins/array_buffer/mod.rs index e36ddf7a7f8..647e4bdf129 100644 --- a/boa_engine/src/builtins/array_buffer/mod.rs +++ b/boa_engine/src/builtins/array_buffer/mod.rs @@ -241,7 +241,7 @@ impl ArrayBuffer { let ctor = obj.species_constructor(StandardConstructors::array_buffer, context)?; // 16. Let new be ? Construct(ctor, « 𝔽(newLen) »). - let new = ctor.construct(&[new_len.into()], &ctor.clone().into(), context)?; + let new = ctor.construct(&[new_len.into()], Some(&ctor), context)?; // 17. Perform ? RequireInternalSlot(new, [[ArrayBufferData]]). let new_obj = new.as_object().cloned().ok_or_else(|| { diff --git a/boa_engine/src/builtins/iterable/mod.rs b/boa_engine/src/builtins/iterable/mod.rs index 5f50c694981..ee92160023c 100644 --- a/boa_engine/src/builtins/iterable/mod.rs +++ b/boa_engine/src/builtins/iterable/mod.rs @@ -277,21 +277,30 @@ impl IteratorRecord { } } + /// Get the `[[Iterator]]` field of the `IteratorRecord`. #[inline] pub(crate) fn iterator(&self) -> &JsObject { &self.iterator } + /// Get the `[[NextMethod]]` field of the `IteratorRecord`. #[inline] pub(crate) fn next_method(&self) -> &JsValue { &self.next_method } + /// Get the `[[Done]]` field of the `IteratorRecord`. #[inline] pub(crate) fn done(&self) -> bool { self.done } + /// Sets the `[[Done]]` field of the `IteratorRecord`. + #[inline] + pub(crate) fn set_done(&mut self, done: bool) { + self.done = done; + } + /// `IteratorNext ( iteratorRecord [ , value ] )` /// /// The abstract operation `IteratorNext` takes argument `iteratorRecord` (an `Iterator` diff --git a/boa_engine/src/builtins/promise/mod.rs b/boa_engine/src/builtins/promise/mod.rs index cca904f395d..8f7c8c9933c 100644 --- a/boa_engine/src/builtins/promise/mod.rs +++ b/boa_engine/src/builtins/promise/mod.rs @@ -164,7 +164,7 @@ impl PromiseCapability { .into(); // 6. Let promise be ? Construct(C, « executor »). - let promise = c.construct(&[executor], &c.clone().into(), context)?; + let promise = c.construct(&[executor], Some(&c), context)?; let promise_capability: &mut Self = &mut promise_capability.try_borrow_mut().expect("msg"); @@ -661,10 +661,11 @@ impl Promise { // 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability). if_abrupt_reject_promise!(iterator_record, promise_capability, context); + let mut iterator_record = iterator_record; // 7. Let result be Completion(PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve)). - let result = Self::perform_promise_race( - &iterator_record, + let mut result = Self::perform_promise_race( + &mut iterator_record, c, &promise_capability, &promise_resolve, @@ -674,7 +675,9 @@ impl Promise { // 8. If result is an abrupt completion, then if result.is_err() { // a. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)). - // TODO: set the [[Done]] field in the IteratorRecord (currently doesn't exist) + if !iterator_record.done() { + result = iterator_record.close(result, context); + } // b. IfAbruptRejectPromise(result, promiseCapability). if_abrupt_reject_promise!(result, promise_capability, context); @@ -698,7 +701,7 @@ impl Promise { /// /// [spec]: https://tc39.es/ecma262/#sec-performpromiserace fn perform_promise_race( - iterator_record: &IteratorRecord, + iterator_record: &mut IteratorRecord, constructor: &JsValue, result_capability: &PromiseCapability, promise_resolve: &JsValue, @@ -711,7 +714,7 @@ impl Promise { // b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true. if next.is_err() { - // TODO: set the [[Done]] field in the IteratorRecord (currently doesn't exist) + iterator_record.set_done(true); } // c. ReturnIfAbrupt(next). @@ -723,7 +726,7 @@ impl Promise { // f. If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true. if next_value.is_err() { - // TODO: set the [[Done]] field in the IteratorRecord (currently doesn't exist) + iterator_record.set_done(true); } // g. ReturnIfAbrupt(nextValue). @@ -744,7 +747,7 @@ impl Promise { } else { // d. If next is false, then // i. Set iteratorRecord.[[Done]] to true. - // TODO: set the [[Done]] field in the IteratorRecord (currently doesn't exist) + iterator_record.set_done(true); // ii. Return resultCapability.[[Promise]]. return Ok(result_capability.promise.clone()); diff --git a/boa_engine/src/builtins/reflect/mod.rs b/boa_engine/src/builtins/reflect/mod.rs index 0adad88ba67..9835c358342 100644 --- a/boa_engine/src/builtins/reflect/mod.rs +++ b/boa_engine/src/builtins/reflect/mod.rs @@ -13,7 +13,7 @@ use super::{Array, JsArgs}; use crate::{ builtins::{self, BuiltIn}, - object::{JsObject, ObjectInitializer}, + object::ObjectInitializer, property::Attribute, symbol::WellKnownSymbols, Context, JsResult, JsValue, @@ -102,27 +102,31 @@ impl Reflect { args: &[JsValue], context: &mut Context, ) -> JsResult { + // 1. If IsConstructor(target) is false, throw a TypeError exception. let target = args - .get(0) - .and_then(JsValue::as_object) - .ok_or_else(|| context.construct_type_error("target must be a function"))?; - let args_list = args.get_or_undefined(1); - - if !target.is_constructor() { - return context.throw_type_error("target must be a constructor"); - } + .get_or_undefined(0) + .as_constructor() + .ok_or_else(|| context.construct_type_error("target must be a constructor"))?; let new_target = if let Some(new_target) = args.get(2) { - if new_target.as_object().map(JsObject::is_constructor) != Some(true) { - return context.throw_type_error("newTarget must be constructor"); + // 3. Else if IsConstructor(newTarget) is false, throw a TypeError exception. + if let Some(new_target) = new_target.as_constructor() { + new_target + } else { + return context.throw_type_error("newTarget must be a constructor"); } - new_target.clone() } else { - target.clone().into() + // 2. If newTarget is not present, set newTarget to target. + target }; - let args = args_list.create_list_from_array_like(&[], context)?; - target.construct(&args, &new_target, context) + // 4. Let args be ? CreateListFromArrayLike(argumentsList). + let args = args + .get_or_undefined(1) + .create_list_from_array_like(&[], context)?; + + // 5. Return ? Construct(target, args, newTarget). + target.construct(&args, Some(new_target), context) } /// Defines a property on an object. diff --git a/boa_engine/src/builtins/regexp/mod.rs b/boa_engine/src/builtins/regexp/mod.rs index dd924457042..49f419b17a8 100644 --- a/boa_engine/src/builtins/regexp/mod.rs +++ b/boa_engine/src/builtins/regexp/mod.rs @@ -1183,11 +1183,7 @@ impl RegExp { let flags = regexp.get("flags", context)?.to_string(context)?; // 6. Let matcher be ? Construct(C, « R, flags »). - let matcher = c.construct( - &[this.clone(), flags.clone().into()], - &c.clone().into(), - context, - )?; + let matcher = c.construct(&[this.clone(), flags.clone().into()], Some(&c), context)?; let matcher = matcher .as_object() .expect("construct must always return an Object"); @@ -1580,7 +1576,7 @@ impl RegExp { // 10. Let splitter be ? Construct(C, « rx, newFlags »). let splitter = constructor.construct( &[this.clone(), new_flags.into()], - &constructor.clone().into(), + Some(&constructor), context, )?; let splitter = splitter diff --git a/boa_engine/src/builtins/typed_array/mod.rs b/boa_engine/src/builtins/typed_array/mod.rs index 1b30d9a9580..2fcf0ba16ce 100644 --- a/boa_engine/src/builtins/typed_array/mod.rs +++ b/boa_engine/src/builtins/typed_array/mod.rs @@ -2968,7 +2968,7 @@ impl TypedArray { context: &mut Context, ) -> JsResult { // 1. Let newTypedArray be ? Construct(constructor, argumentList). - let new_typed_array = constructor.construct(args, &constructor.clone().into(), context)?; + let new_typed_array = constructor.construct(args, Some(constructor), context)?; // 2. Perform ? ValidateTypedArray(newTypedArray). let obj = new_typed_array diff --git a/boa_engine/src/object/internal_methods/bound_function.rs b/boa_engine/src/object/internal_methods/bound_function.rs index d48d4ea3b9a..1b504d44b30 100644 --- a/boa_engine/src/object/internal_methods/bound_function.rs +++ b/boa_engine/src/object/internal_methods/bound_function.rs @@ -68,7 +68,7 @@ fn bound_function_exotic_call( fn bound_function_exotic_construct( obj: &JsObject, arguments_list: &[JsValue], - new_target: &JsValue, + new_target: &JsObject, context: &mut Context, ) -> JsResult { let object = obj.borrow(); @@ -89,11 +89,12 @@ fn bound_function_exotic_construct( args.extend_from_slice(arguments_list); // 5. If SameValue(F, newTarget) is true, set newTarget to target. - let new_target = match new_target { - JsValue::Object(new_target) if JsObject::equals(obj, new_target) => target.clone().into(), - _ => new_target.clone(), + let new_target = if JsObject::equals(obj, new_target) { + target + } else { + new_target }; // 6. Return ? Construct(target, args, newTarget). - target.construct(&args, &new_target, context) + target.construct(&args, Some(new_target), context) } diff --git a/boa_engine/src/object/internal_methods/function.rs b/boa_engine/src/object/internal_methods/function.rs index 797868855fc..c80ace69ee6 100644 --- a/boa_engine/src/object/internal_methods/function.rs +++ b/boa_engine/src/object/internal_methods/function.rs @@ -53,8 +53,8 @@ fn function_call( fn function_construct( obj: &JsObject, args: &[JsValue], - new_target: &JsValue, + new_target: &JsObject, context: &mut Context, ) -> JsResult { - obj.construct_internal(args, new_target, context) + obj.construct_internal(args, &new_target.clone().into(), context) } diff --git a/boa_engine/src/object/internal_methods/mod.rs b/boa_engine/src/object/internal_methods/mod.rs index d628f6d1164..4e660fbf3b8 100644 --- a/boa_engine/src/object/internal_methods/mod.rs +++ b/boa_engine/src/object/internal_methods/mod.rs @@ -259,7 +259,7 @@ impl JsObject { pub(crate) fn __construct__( &self, args: &[JsValue], - new_target: &JsValue, + new_target: &JsObject, context: &mut Context, ) -> JsResult { let _timer = Profiler::global().start_event("Object::__construct__", "object"); @@ -324,7 +324,7 @@ pub(crate) struct InternalObjectMethods { pub(crate) __call__: Option JsResult>, pub(crate) __construct__: - Option JsResult>, + Option JsResult>, } /// Abstract operation `OrdinaryGetPrototypeOf`. diff --git a/boa_engine/src/object/internal_methods/proxy.rs b/boa_engine/src/object/internal_methods/proxy.rs index 7ecb7e0d8ab..3359153b208 100644 --- a/boa_engine/src/object/internal_methods/proxy.rs +++ b/boa_engine/src/object/internal_methods/proxy.rs @@ -935,7 +935,7 @@ fn proxy_exotic_call( ) } -/// `10.5.13 [[Construct]] ( argumentsList, newTarget )` +/// `[[Construct]] ( argumentsList, newTarget )` /// /// More information: /// - [ECMAScript reference][spec] @@ -944,7 +944,7 @@ fn proxy_exotic_call( fn proxy_exotic_construct( obj: &JsObject, args: &[JsValue], - new_target: &JsValue, + new_target: &JsObject, context: &mut Context, ) -> JsResult { // 1. Let handler be O.[[ProxyHandler]]. @@ -966,7 +966,7 @@ fn proxy_exotic_construct( // 7. If trap is undefined, then } else { // a. Return ? Construct(target, argumentsList, newTarget). - return target.construct(args, new_target, context); + return target.construct(args, Some(new_target), context); }; // 8. Let argArray be ! CreateArrayFromList(argumentsList). @@ -975,7 +975,11 @@ fn proxy_exotic_construct( // 9. Let newObj be ? Call(trap, handler, « target, argArray, newTarget »). let new_obj = trap.call( &handler.into(), - &[target.clone().into(), arg_array.into(), new_target.clone()], + &[ + target.clone().into(), + arg_array.into(), + new_target.clone().into(), + ], context, )?; diff --git a/boa_engine/src/object/operations.rs b/boa_engine/src/object/operations.rs index 37ffad51b83..5a8ef6accb7 100644 --- a/boa_engine/src/object/operations.rs +++ b/boa_engine/src/object/operations.rs @@ -309,21 +309,28 @@ impl JsObject { self.__call__(this, args, context) } + /// `Construct ( F [ , argumentsList [ , newTarget ] ] )` + /// /// Construct an instance of this object with the specified arguments. /// /// # Panics /// /// Panics if the object is currently mutably borrowed. - // + /// + /// More information: + /// - [ECMAScript reference][spec] + /// + /// [spec]: https://tc39.es/ecma262/#sec-construct #[track_caller] #[inline] pub fn construct( &self, args: &[JsValue], - new_target: &JsValue, + new_target: Option<&JsObject>, context: &mut Context, ) -> JsResult { // 1. If newTarget is not present, set newTarget to F. + let new_target = new_target.unwrap_or(self); // 2. If argumentsList is not present, set argumentsList to a new empty List. // 3. Return ? F.[[Construct]](argumentsList, newTarget). self.__construct__(args, new_target, context) diff --git a/boa_engine/src/vm/mod.rs b/boa_engine/src/vm/mod.rs index 83cad0692cd..7ceee547497 100644 --- a/boa_engine/src/vm/mod.rs +++ b/boa_engine/src/vm/mod.rs @@ -1400,7 +1400,7 @@ impl Context { let result = func .as_constructor() .ok_or_else(|| self.construct_type_error("not a constructor")) - .and_then(|cons| cons.__construct__(&arguments, &cons.clone().into(), self))?; + .and_then(|cons| cons.__construct__(&arguments, cons, self))?; self.vm.push(result); } @@ -1427,7 +1427,7 @@ impl Context { let result = func .as_constructor() .ok_or_else(|| self.construct_type_error("not a constructor")) - .and_then(|cons| cons.__construct__(&arguments, &cons.clone().into(), self))?; + .and_then(|cons| cons.__construct__(&arguments, cons, self))?; self.vm.push(result); } diff --git a/boa_wasm/Cargo.toml b/boa_wasm/Cargo.toml index e00671a0f63..b5029ca92ed 100644 --- a/boa_wasm/Cargo.toml +++ b/boa_wasm/Cargo.toml @@ -13,7 +13,7 @@ publish = false [dependencies] boa_engine = { path = "../boa_engine", features = ["console"], version = "0.15.0" } -wasm-bindgen = "0.2.80" +wasm-bindgen = "0.2.81" getrandom = { version = "0.2.7", features = ["js"] } [lib] diff --git a/test262 b/test262 index 79e3bc5176b..74de3d1d327 160000 --- a/test262 +++ b/test262 @@ -1 +1 @@ -Subproject commit 79e3bc5176b6f29a5aed3b7164a9c623a3a9a63b +Subproject commit 74de3d1d327b3238d6193242c3cc157746f2faad