From 039cd353f1dad9d3a567d5c2e34e3a2bfe44cf64 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Fri, 27 Jan 2023 21:24:21 +0000 Subject: [PATCH] LibJS: Implement the thisBooleanValue AO and use it in BooleanPrototype --- .../LibJS/Runtime/BooleanPrototype.cpp | 40 ++++++++++++------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/BooleanPrototype.cpp b/Userland/Libraries/LibJS/Runtime/BooleanPrototype.cpp index 0a8f85c3a0c..bb89ba895d0 100644 --- a/Userland/Libraries/LibJS/Runtime/BooleanPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/BooleanPrototype.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, Jack Karamanian + * Copyright (c) 2021-2023, Linus Groh * * 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 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(value.as_object())) { + // a. Let b be value.[[BooleanData]]. + // b. Assert: b is a Boolean. + // c. Return b. + return static_cast(value.as_object()).boolean(); + } + + // 3. Throw a TypeError exception. + return vm.throw_completion(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(this_value.as_object())) - return vm.throw_completion(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(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(this_value.as_object())) - return vm.throw_completion(ErrorType::NotAnObjectOfType, "Boolean"); - - return Value(static_cast(this_value.as_object()).boolean()); + // 1. Return ? thisBooleanValue(this value). + return TRY(this_boolean_value(vm, vm.this_value())); } }