Browse Source

Fix `Symbol` and `BigInt` constructors (#2032)

It changes the following:
- `Symbol` object has `[[Construct]]` internal method
- Fix and comment step 1 in `Symbol` constructor.
- Implement step 1 in `BigInt` constructor.
pull/2034/head
Halid Odat 3 years ago
parent
commit
2d6e93cc83
  1. 15
      boa_engine/src/builtins/bigint/mod.rs
  2. 11
      boa_engine/src/builtins/symbol/mod.rs

15
boa_engine/src/builtins/bigint/mod.rs

@ -46,12 +46,12 @@ impl BuiltIn for BigInt {
) )
.name(Self::NAME) .name(Self::NAME)
.length(Self::LENGTH) .length(Self::LENGTH)
.callable(true)
.constructor(true)
.method(Self::to_string, "toString", 0) .method(Self::to_string, "toString", 0)
.method(Self::value_of, "valueOf", 0) .method(Self::value_of, "valueOf", 0)
.static_method(Self::as_int_n, "asIntN", 2) .static_method(Self::as_int_n, "asIntN", 2)
.static_method(Self::as_uint_n, "asUintN", 2) .static_method(Self::as_uint_n, "asUintN", 2)
.callable(true)
.constructor(true)
.property( .property(
to_string_tag, to_string_tag,
Self::NAME, Self::NAME,
@ -77,7 +77,16 @@ impl BigInt {
/// ///
/// [spec]: https://tc39.es/ecma262/#sec-bigint-objects /// [spec]: https://tc39.es/ecma262/#sec-bigint-objects
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/BigInt /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/BigInt
fn constructor(_: &JsValue, args: &[JsValue], context: &mut Context) -> JsResult<JsValue> { fn constructor(
new_target: &JsValue,
args: &[JsValue],
context: &mut Context,
) -> JsResult<JsValue> {
// 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); let value = args.get_or_undefined(0);
// 2. Let prim be ? ToPrimitive(value, number). // 2. Let prim be ? ToPrimitive(value, number).

11
boa_engine/src/builtins/symbol/mod.rs

@ -112,6 +112,8 @@ impl BuiltIn for Symbol {
) )
.name(Self::NAME) .name(Self::NAME)
.length(Self::LENGTH) .length(Self::LENGTH)
.callable(true)
.constructor(true)
.static_method(Self::for_, "for", 1) .static_method(Self::for_, "for", 1)
.static_method(Self::key_for, "keyFor", 1) .static_method(Self::key_for, "keyFor", 1)
.static_property("asyncIterator", symbol_async_iterator, attribute) .static_property("asyncIterator", symbol_async_iterator, attribute)
@ -135,8 +137,6 @@ impl BuiltIn for Symbol {
None, None,
Attribute::CONFIGURABLE | Attribute::NON_ENUMERABLE, Attribute::CONFIGURABLE | Attribute::NON_ENUMERABLE,
) )
.callable(true)
.constructor(false)
.property( .property(
symbol_to_string_tag, symbol_to_string_tag,
Self::NAME, Self::NAME,
@ -173,14 +173,19 @@ impl Symbol {
args: &[JsValue], args: &[JsValue],
context: &mut Context, context: &mut Context,
) -> JsResult<JsValue> { ) -> JsResult<JsValue> {
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"); 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) { let description = match args.get(0) {
Some(value) if !value.is_undefined() => Some(value.to_string(context)?), Some(value) if !value.is_undefined() => Some(value.to_string(context)?),
_ => None, _ => None,
}; };
// 4. Return a new unique Symbol value whose [[Description]] value is descString.
Ok(JsSymbol::new(description).into()) Ok(JsSymbol::new(description).into())
} }

Loading…
Cancel
Save