From e35ece0f52766834b69f0a3387da5be110c50b1e Mon Sep 17 00:00:00 2001 From: HalidOdat Date: Sun, 17 Apr 2022 01:20:57 +0200 Subject: [PATCH 1/2] Fix `Symbol` and `BigInt` constructor --- boa_engine/src/builtins/bigint/mod.rs | 13 ++++++++++--- boa_engine/src/builtins/symbol/mod.rs | 2 -- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/boa_engine/src/builtins/bigint/mod.rs b/boa_engine/src/builtins/bigint/mod.rs index 7258d56d1f8..96cc4e08452 100644 --- a/boa_engine/src/builtins/bigint/mod.rs +++ b/boa_engine/src/builtins/bigint/mod.rs @@ -50,8 +50,6 @@ impl BuiltIn for BigInt { .method(Self::value_of, "valueOf", 0) .static_method(Self::as_int_n, "asIntN", 2) .static_method(Self::as_uint_n, "asUintN", 2) - .callable(true) - .constructor(true) .property( to_string_tag, Self::NAME, @@ -77,7 +75,16 @@ impl BigInt { /// /// [spec]: https://tc39.es/ecma262/#sec-bigint-objects /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/BigInt - fn constructor(_: &JsValue, args: &[JsValue], context: &mut Context) -> JsResult { + fn constructor( + new_target: &JsValue, + args: &[JsValue], + context: &mut Context, + ) -> JsResult { + // 1. If NewTarget is not undefined, throw a TypeError exception. + if !new_target.is_undefined() { + return context.throw_type_error("BigInt is not a constructor"); + } + let value = args.get_or_undefined(0); // 2. Let prim be ? ToPrimitive(value, number). diff --git a/boa_engine/src/builtins/symbol/mod.rs b/boa_engine/src/builtins/symbol/mod.rs index df98d652c1a..05495eba4fa 100644 --- a/boa_engine/src/builtins/symbol/mod.rs +++ b/boa_engine/src/builtins/symbol/mod.rs @@ -135,8 +135,6 @@ impl BuiltIn for Symbol { None, Attribute::CONFIGURABLE | Attribute::NON_ENUMERABLE, ) - .callable(true) - .constructor(false) .property( symbol_to_string_tag, Self::NAME, From 4277453fc246dfded90ed2a1b91ca11817d557ac Mon Sep 17 00:00:00 2001 From: HalidOdat Date: Sun, 17 Apr 2022 01:27:59 +0200 Subject: [PATCH 2/2] Fix step 1 in Symbol constructor --- boa_engine/src/builtins/bigint/mod.rs | 2 ++ boa_engine/src/builtins/symbol/mod.rs | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/boa_engine/src/builtins/bigint/mod.rs b/boa_engine/src/builtins/bigint/mod.rs index 96cc4e08452..dc1ddd3485a 100644 --- a/boa_engine/src/builtins/bigint/mod.rs +++ b/boa_engine/src/builtins/bigint/mod.rs @@ -46,6 +46,8 @@ impl BuiltIn for BigInt { ) .name(Self::NAME) .length(Self::LENGTH) + .callable(true) + .constructor(true) .method(Self::to_string, "toString", 0) .method(Self::value_of, "valueOf", 0) .static_method(Self::as_int_n, "asIntN", 2) diff --git a/boa_engine/src/builtins/symbol/mod.rs b/boa_engine/src/builtins/symbol/mod.rs index 05495eba4fa..3dd58078e45 100644 --- a/boa_engine/src/builtins/symbol/mod.rs +++ b/boa_engine/src/builtins/symbol/mod.rs @@ -112,6 +112,8 @@ impl BuiltIn for Symbol { ) .name(Self::NAME) .length(Self::LENGTH) + .callable(true) + .constructor(true) .static_method(Self::for_, "for", 1) .static_method(Self::key_for, "keyFor", 1) .static_property("asyncIterator", symbol_async_iterator, attribute) @@ -171,14 +173,19 @@ impl Symbol { args: &[JsValue], context: &mut Context, ) -> JsResult { - if new_target.is_undefined() { + // 1. If NewTarget is not undefined, throw a TypeError exception. + if !new_target.is_undefined() { return context.throw_type_error("Symbol is not a constructor"); } + + // 2. If description is undefined, let descString be undefined. + // 3. Else, let descString be ? ToString(description). let description = match args.get(0) { Some(value) if !value.is_undefined() => Some(value.to_string(context)?), _ => None, }; + // 4. Return a new unique Symbol value whose [[Description]] value is descString. Ok(JsSymbol::new(description).into()) }