diff --git a/Userland/Libraries/LibJS/Runtime/SymbolPrototype.cpp b/Userland/Libraries/LibJS/Runtime/SymbolPrototype.cpp index 9fcb5f90fbe..1bcdbbab2aa 100644 --- a/Userland/Libraries/LibJS/Runtime/SymbolPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/SymbolPrototype.cpp @@ -42,40 +42,58 @@ ThrowCompletionOr SymbolPrototype::initialize(Realm& realm) // thisSymbolValue ( value ), https://tc39.es/ecma262/#thissymbolvalue static ThrowCompletionOr this_symbol_value(VM& vm, Value value) { + // 1. If value is a Symbol, return value. if (value.is_symbol()) return &value.as_symbol(); - if (value.is_object() && is(value.as_object())) + + // 2. If value is an Object and value has a [[SymbolData]] internal slot, then + if (value.is_object() && is(value.as_object())) { + // a. Let s be value.[[SymbolData]]. + // b. Assert: s is a Symbol. + // c. Return s. return &static_cast(value.as_object()).primitive_symbol(); + } + + // 3. Throw a TypeError exception. return vm.throw_completion(ErrorType::NotAnObjectOfType, "Symbol"); } // 20.4.3.2 get Symbol.prototype.description, https://tc39.es/ecma262/#sec-symbol.prototype.description JS_DEFINE_NATIVE_FUNCTION(SymbolPrototype::description_getter) { + // 1. Let s be the this value. + // 2. Let sym be ? thisSymbolValue(s). auto* symbol = TRY(this_symbol_value(vm, vm.this_value())); + + // 3. Return sym.[[Description]]. auto& description = symbol->description(); - if (!description.has_value()) - return js_undefined(); - return PrimitiveString::create(vm, *description); + return description.has_value() + ? PrimitiveString::create(vm, *description) + : js_undefined(); } // 20.4.3.3 Symbol.prototype.toString ( ), https://tc39.es/ecma262/#sec-symbol.prototype.tostring JS_DEFINE_NATIVE_FUNCTION(SymbolPrototype::to_string) { + // 1. Let sym be ? thisSymbolValue(this value). auto* symbol = TRY(this_symbol_value(vm, vm.this_value())); + + // 2. Return SymbolDescriptiveString(sym). return PrimitiveString::create(vm, TRY_OR_THROW_OOM(vm, symbol->descriptive_string())); } // 20.4.3.4 Symbol.prototype.valueOf ( ), https://tc39.es/ecma262/#sec-symbol.prototype.valueof JS_DEFINE_NATIVE_FUNCTION(SymbolPrototype::value_of) { + // 1. Return ? thisSymbolValue(this value). return TRY(this_symbol_value(vm, vm.this_value())); } // 20.4.3.5 Symbol.prototype [ @@toPrimitive ] ( hint ), https://tc39.es/ecma262/#sec-symbol.prototype-@@toprimitive JS_DEFINE_NATIVE_FUNCTION(SymbolPrototype::symbol_to_primitive) { - // The hint argument is ignored. + // 1. Return ? thisSymbolValue(this value). + // NOTE: The argument is ignored. return TRY(this_symbol_value(vm, vm.this_value())); }