1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-06-28 03:02:12 +00:00

LibJS: Add spec comments to Value::to_primitive()

This commit is contained in:
Linus Groh 2022-12-09 23:57:54 +00:00
parent e3c8e1362f
commit 9c10624278

View file

@ -466,31 +466,51 @@ bool Value::to_boolean() const
// 7.1.1 ToPrimitive ( input [ , preferredType ] ), https://tc39.es/ecma262/#sec-toprimitive // 7.1.1 ToPrimitive ( input [ , preferredType ] ), https://tc39.es/ecma262/#sec-toprimitive
ThrowCompletionOr<Value> Value::to_primitive(VM& vm, PreferredType preferred_type) const ThrowCompletionOr<Value> Value::to_primitive(VM& vm, PreferredType preferred_type) const
{ {
auto get_hint_for_preferred_type = [&]() -> DeprecatedString { // 1. If input is an Object, then
if (is_object()) {
// a. Let exoticToPrim be ? GetMethod(input, @@toPrimitive).
auto* exotic_to_primitive = TRY(get_method(vm, *vm.well_known_symbol_to_primitive()));
// b. If exoticToPrim is not undefined, then
if (exotic_to_primitive) {
auto hint = [&]() -> DeprecatedString {
switch (preferred_type) { switch (preferred_type) {
// i. If preferredType is not present, let hint be "default".
case PreferredType::Default: case PreferredType::Default:
return "default"; return "default";
// ii. Else if preferredType is string, let hint be "string".
case PreferredType::String: case PreferredType::String:
return "string"; return "string";
// iii. Else,
// 1. Assert: preferredType is number.
// 2. Let hint be "number".
case PreferredType::Number: case PreferredType::Number:
return "number"; return "number";
default: default:
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
}; }();
if (is_object()) {
auto to_primitive_method = TRY(get_method(vm, *vm.well_known_symbol_to_primitive())); // iv. Let result be ? Call(exoticToPrim, input, « hint »).
if (to_primitive_method) { auto result = TRY(call(vm, *exotic_to_primitive, *this, PrimitiveString::create(vm, hint)));
auto hint = get_hint_for_preferred_type();
auto result = TRY(call(vm, *to_primitive_method, *this, PrimitiveString::create(vm, hint))); // v. If result is not an Object, return result.
if (!result.is_object()) if (!result.is_object())
return result; return result;
// vi. Throw a TypeError exception.
return vm.throw_completion<TypeError>(ErrorType::ToPrimitiveReturnedObject, to_string_without_side_effects(), hint); return vm.throw_completion<TypeError>(ErrorType::ToPrimitiveReturnedObject, to_string_without_side_effects(), hint);
} }
// c. If preferredType is not present, let preferredType be number.
if (preferred_type == PreferredType::Default) if (preferred_type == PreferredType::Default)
preferred_type = PreferredType::Number; preferred_type = PreferredType::Number;
// d. Return ? OrdinaryToPrimitive(input, preferredType).
return as_object().ordinary_to_primitive(preferred_type); return as_object().ordinary_to_primitive(preferred_type);
} }
// 2. Return input.
return *this; return *this;
} }