LibJS: Implement the thisBooleanValue AO and use it in BooleanPrototype

This commit is contained in:
Linus Groh 2023-01-27 21:24:21 +00:00
parent b5deccf859
commit 039cd353f1
Notes: sideshowbarker 2024-07-17 01:03:51 +09:00

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2020, Jack Karamanian <karamanian.jack@gmail.com>
* Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -26,29 +27,40 @@ void BooleanPrototype::initialize(Realm& realm)
define_native_function(realm, vm.names.valueOf, value_of, 0, attr);
}
// thisBooleanValue ( value ), https://tc39.es/ecma262/#thisbooleanvalue
static ThrowCompletionOr<bool> this_boolean_value(VM& vm, Value value)
{
// 1. If value is a Boolean, return value.
if (value.is_boolean())
return value.as_bool();
// 2. If value is an Object and value has a [[BooleanData]] internal slot, then
if (value.is_object() && is<BooleanObject>(value.as_object())) {
// a. Let b be value.[[BooleanData]].
// b. Assert: b is a Boolean.
// c. Return b.
return static_cast<BooleanObject&>(value.as_object()).boolean();
}
// 3. Throw a TypeError exception.
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Boolean");
}
// 20.3.3.2 Boolean.prototype.toString ( ), https://tc39.es/ecma262/#sec-boolean.prototype.tostring
JS_DEFINE_NATIVE_FUNCTION(BooleanPrototype::to_string)
{
auto this_value = vm.this_value();
if (this_value.is_boolean())
return PrimitiveString::create(vm, this_value.as_bool() ? "true" : "false");
if (!this_value.is_object() || !is<BooleanObject>(this_value.as_object()))
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Boolean");
// 1. Let b be ? thisBooleanValue(this value).
auto b = TRY(this_boolean_value(vm, vm.this_value()));
bool bool_value = static_cast<BooleanObject const&>(this_value.as_object()).boolean();
return PrimitiveString::create(vm, bool_value ? "true" : "false");
// 2. If b is true, return "true"; else return "false".
return PrimitiveString::create(vm, TRY_OR_THROW_OOM(vm, String::from_utf8(b ? "true"sv : "false"sv)));
}
// 20.3.3.3 Boolean.prototype.valueOf ( ), https://tc39.es/ecma262/#sec-boolean.prototype.valueof
JS_DEFINE_NATIVE_FUNCTION(BooleanPrototype::value_of)
{
auto this_value = vm.this_value();
if (this_value.is_boolean())
return this_value;
if (!this_value.is_object() || !is<BooleanObject>(this_value.as_object()))
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Boolean");
return Value(static_cast<BooleanObject const&>(this_value.as_object()).boolean());
// 1. Return ? thisBooleanValue(this value).
return TRY(this_boolean_value(vm, vm.this_value()));
}
}