1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 14:27:35 +00:00

LibJS: Implement the RequireObjectCoercible abstract operation

Throws an exception if the given value is nullish, returns it otherwise.
We can now gradually replace such manual checks with this function where
applicable.

This also has the advantage that the somewhat useless "ToObject on null
or undefined" will be replaced with "null cannot be converted to an
object" or "undefined cannot be converted to an object". :^)
This commit is contained in:
Linus Groh 2021-06-06 16:10:23 +01:00 committed by Andreas Kling
parent 4ca4c43cbd
commit cd12b2aa57
3 changed files with 16 additions and 1 deletions

View file

@ -44,6 +44,7 @@
M(JsonCircular, "Cannot stringify circular object") \ M(JsonCircular, "Cannot stringify circular object") \
M(JsonMalformed, "Malformed JSON string") \ M(JsonMalformed, "Malformed JSON string") \
M(NegativeExponent, "Exponent must be positive") \ M(NegativeExponent, "Exponent must be positive") \
M(NonExtensibleDefine, "Cannot define property {} on non-extensible object") \
M(NotA, "Not a {} object") \ M(NotA, "Not a {} object") \
M(NotAConstructor, "{} is not a constructor") \ M(NotAConstructor, "{} is not a constructor") \
M(NotAFunction, "{} is not a function") \ M(NotAFunction, "{} is not a function") \
@ -52,7 +53,7 @@
M(NotAnObject, "{} is not an object") \ M(NotAnObject, "{} is not an object") \
M(NotASymbol, "{} is not a symbol") \ M(NotASymbol, "{} is not a symbol") \
M(NotIterable, "{} is not iterable") \ M(NotIterable, "{} is not iterable") \
M(NonExtensibleDefine, "Cannot define property {} on non-extensible object") \ M(NotObjectCoercible, "{} cannot be converted to an object") \
M(NumberIncompatibleThis, "Number.prototype.{}() called with incompatible this target") \ M(NumberIncompatibleThis, "Number.prototype.{}() called with incompatible this target") \
M(ObjectDefinePropertyReturnedFalse, "Object's [[DefineProperty]] method returned false") \ M(ObjectDefinePropertyReturnedFalse, "Object's [[DefineProperty]] method returned false") \
M(ObjectFreezeFailed, "Could not freeze object") \ M(ObjectFreezeFailed, "Could not freeze object") \

View file

@ -1390,4 +1390,16 @@ Object* species_constructor(GlobalObject& global_object, const Object& object, O
vm.throw_exception<TypeError>(global_object, ErrorType::NotAConstructor, species.to_string_without_side_effects()); vm.throw_exception<TypeError>(global_object, ErrorType::NotAConstructor, species.to_string_without_side_effects());
return nullptr; return nullptr;
} }
// 7.2.1 RequireObjectCoercible, https://tc39.es/ecma262/#sec-requireobjectcoercible
Value require_object_coercible(GlobalObject& global_object, Value value)
{
auto& vm = global_object.vm();
if (value.is_nullish()) {
vm.throw_exception<TypeError>(global_object, ErrorType::NotObjectCoercible, value.to_string_without_side_effects());
return {};
}
return value;
}
} }

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org> * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -366,6 +367,7 @@ TriState abstract_relation(GlobalObject&, bool left_first, Value lhs, Value rhs)
Function* get_method(GlobalObject& global_object, Value, const PropertyName&); Function* get_method(GlobalObject& global_object, Value, const PropertyName&);
size_t length_of_array_like(GlobalObject&, const Object&); size_t length_of_array_like(GlobalObject&, const Object&);
Object* species_constructor(GlobalObject&, const Object&, Object& default_constructor); Object* species_constructor(GlobalObject&, const Object&, Object& default_constructor);
Value require_object_coercible(GlobalObject&, Value);
} }