diff --git a/boa/src/builtins/symbol/mod.rs b/boa/src/builtins/symbol/mod.rs index 02cf30aabb..1bc43b1e0b 100644 --- a/boa/src/builtins/symbol/mod.rs +++ b/boa/src/builtins/symbol/mod.rs @@ -99,6 +99,12 @@ impl BuiltIn for Symbol { let attribute = Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT; + let to_primitive = FunctionBuilder::native(context, Self::to_primitive) + .name("[Symbol.toPrimitive]") + .length(1) + .constructable(false) + .build(); + let get_description = FunctionBuilder::native(context, Self::get_description) .name("get description") .constructable(false) @@ -123,7 +129,7 @@ impl BuiltIn for Symbol { .static_property("search", symbol_search, attribute) .static_property("species", symbol_species, attribute) .static_property("split", symbol_split, attribute) - .static_property("toPrimitive", symbol_to_primitive, attribute) + .static_property("toPrimitive", symbol_to_primitive.clone(), attribute) .static_property("toStringTag", symbol_to_string_tag.clone(), attribute) .static_property("unscopables", symbol_unscopables, attribute) .method(Self::to_string, "toString", 0) @@ -141,6 +147,11 @@ impl BuiltIn for Symbol { Self::NAME, Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, ) + .property( + symbol_to_primitive, + to_primitive, + Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ) .build(); symbol_object.into() @@ -316,4 +327,25 @@ impl Symbol { context.throw_type_error("Symbol.keyFor: sym is not a symbol") } } + + /// `Symbol.prototype [ @@toPrimitive ]` + /// + /// This function is called by ECMAScript language operators to convert a Symbol object to a primitive value. + /// NOTE: The argument is ignored + /// + /// More information: + /// - [MDN documentation][mdn] + /// - [ECMAScript reference][spec] + /// + /// [spec]: https://tc39.es/ecma262/multipage/#sec-symbol.prototype-@@toprimitive + /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/@@toPrimitive + pub(crate) fn to_primitive( + this: &JsValue, + _: &[JsValue], + context: &mut Context, + ) -> JsResult { + let sym = Self::this_symbol_value(this, context)?; + // 1. Return ? thisSymbolValue(this value). + Ok(sym.into()) + } } diff --git a/boa/src/object/mod.rs b/boa/src/object/mod.rs index 87dc77ddc7..261d02591b 100644 --- a/boa/src/object/mod.rs +++ b/boa/src/object/mod.rs @@ -1227,7 +1227,7 @@ impl<'context> FunctionBuilder<'context> { self } - /// Specify the whether the object function object can be called with `new` keyword. + /// Specify whether the object function object can be called with `new` keyword. /// /// The default is `false`. #[inline]