LibJS: Remove PropertyKey::is_valid() method
Some checks failed
CI / Lagom (false, FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (true, NO_FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Push notes / build (push) Waiting to run
Build Dev Container Image / build (push) Has been cancelled

This method was being used to check for invalid `PropertyKey`s.
Since invalid `PropertyKey`s are no longer created, and since the
associated method has also been removed in the latest edition of
ECMA-262, the method can now be removed here as well.

While we are removing all its calls, lets also update any surrounding
spec comments to the current latest edition, where possible.
This commit is contained in:
Jonne Ransijn 2024-11-01 23:31:36 +01:00 committed by Andreas Kling
parent bc05f6303f
commit 0080f399c7
Notes: github-actions[bot] 2024-11-09 16:55:59 +00:00
9 changed files with 26 additions and 99 deletions

View file

@ -239,7 +239,6 @@ bool is_compatible_property_descriptor(bool extensible, PropertyDescriptor const
bool validate_and_apply_property_descriptor(Object* object, PropertyKey const& property_key, bool extensible, PropertyDescriptor const& descriptor, Optional<PropertyDescriptor> const& current)
{
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_key.is_valid());
// 2. If current is undefined, then
if (!current.has_value()) {

View file

@ -281,8 +281,6 @@ ThrowCompletionOr<bool> Array::internal_define_own_property(PropertyKey const& p
{
auto& vm = this->vm();
VERIFY(property_key.is_valid());
// 1. If P is "length", then
if (property_key.is_string() && property_key.as_string() == vm.names.length.as_string()) {
// a. Return ? ArraySetLength(A, Desc).

View file

@ -111,8 +111,6 @@ ThrowCompletionOr<bool> Object::is_extensible() const
// 7.3.2 Get ( O, P ), https://tc39.es/ecma262/#sec-get-o-p
ThrowCompletionOr<Value> Object::get(PropertyKey const& property_key) const
{
VERIFY(property_key.is_valid());
// 1. Return ? O.[[Get]](P, O).
return TRY(internal_get(property_key, this));
}
@ -124,7 +122,6 @@ ThrowCompletionOr<void> Object::set(PropertyKey const& property_key, Value value
{
auto& vm = this->vm();
VERIFY(property_key.is_valid());
VERIFY(!value.is_empty());
// 1. Let success be ? O.[[Set]](P, V, O).
@ -143,8 +140,6 @@ ThrowCompletionOr<void> Object::set(PropertyKey const& property_key, Value value
// 7.3.5 CreateDataProperty ( O, P, V ), https://tc39.es/ecma262/#sec-createdataproperty
ThrowCompletionOr<bool> Object::create_data_property(PropertyKey const& property_key, Value value)
{
VERIFY(property_key.is_valid());
// 1. Let newDesc be the PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }.
auto new_descriptor = PropertyDescriptor {
.value = value,
@ -160,7 +155,6 @@ ThrowCompletionOr<bool> Object::create_data_property(PropertyKey const& property
// 7.3.6 CreateMethodProperty ( O, P, V ), https://tc39.es/ecma262/#sec-createmethodproperty
void Object::create_method_property(PropertyKey const& property_key, Value value)
{
VERIFY(property_key.is_valid());
VERIFY(!value.is_empty());
// 1. Assert: O is an ordinary, extensible object with no non-configurable properties.
@ -184,7 +178,6 @@ ThrowCompletionOr<bool> Object::create_data_property_or_throw(PropertyKey const&
{
auto& vm = this->vm();
VERIFY(property_key.is_valid());
VERIFY(!value.is_empty());
// 1. Let success be ? CreateDataProperty(O, P, V).
@ -203,7 +196,6 @@ ThrowCompletionOr<bool> Object::create_data_property_or_throw(PropertyKey const&
// 7.3.8 CreateNonEnumerableDataPropertyOrThrow ( O, P, V ), https://tc39.es/ecma262/#sec-createnonenumerabledatapropertyorthrow
void Object::create_non_enumerable_data_property_or_throw(PropertyKey const& property_key, Value value)
{
VERIFY(property_key.is_valid());
VERIFY(!value.is_empty());
// 1. Assert: O is an ordinary, extensible object with no non-configurable properties.
@ -222,8 +214,6 @@ ThrowCompletionOr<void> Object::define_property_or_throw(PropertyKey const& prop
{
auto& vm = this->vm();
VERIFY(property_key.is_valid());
// 1. Let success be ? O.[[DefineOwnProperty]](P, desc).
auto success = TRY(internal_define_own_property(property_key, property_descriptor));
@ -242,8 +232,6 @@ ThrowCompletionOr<void> Object::delete_property_or_throw(PropertyKey const& prop
{
auto& vm = this->vm();
VERIFY(property_key.is_valid());
// 1. Let success be ? O.[[Delete]](P).
auto success = TRY(internal_delete(property_key));
@ -260,8 +248,6 @@ ThrowCompletionOr<void> Object::delete_property_or_throw(PropertyKey const& prop
// 7.3.12 HasProperty ( O, P ), https://tc39.es/ecma262/#sec-hasproperty
ThrowCompletionOr<bool> Object::has_property(PropertyKey const& property_key) const
{
VERIFY(property_key.is_valid());
// 1. Return ? O.[[HasProperty]](P).
return internal_has_property(property_key);
}
@ -269,8 +255,6 @@ ThrowCompletionOr<bool> Object::has_property(PropertyKey const& property_key) co
// 7.3.13 HasOwnProperty ( O, P ), https://tc39.es/ecma262/#sec-hasownproperty
ThrowCompletionOr<bool> Object::has_own_property(PropertyKey const& property_key) const
{
VERIFY(property_key.is_valid());
// 1. Let desc be ? O.[[GetOwnProperty]](P).
auto descriptor = TRY(internal_get_own_property(property_key));
@ -793,10 +777,9 @@ ThrowCompletionOr<bool> Object::internal_prevent_extensions()
}
// 10.1.5 [[GetOwnProperty]] ( P ), https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-getownproperty-p
// 10.1.5.1 OrdinaryGetOwnProperty ( O, P ) https://tc39.es/ecma262/#sec-ordinarygetownproperty
ThrowCompletionOr<Optional<PropertyDescriptor>> Object::internal_get_own_property(PropertyKey const& property_key) const
{
VERIFY(property_key.is_valid());
// 1. If O does not have an own property with key P, return undefined.
auto maybe_storage_entry = storage_get(property_key);
if (!maybe_storage_entry.has_value())
@ -848,10 +831,9 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> Object::internal_get_own_propert
}
// 10.1.6 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-defineownproperty-p-desc
// 10.1.6.1 OrdinaryDefineOwnProperty ( O, P, Desc ), https://tc39.es/ecma262/#sec-ordinarydefineownproperty
ThrowCompletionOr<bool> Object::internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& property_descriptor, Optional<PropertyDescriptor>* precomputed_get_own_property)
{
VERIFY(property_key.is_valid());
// 1. Let current be ? O.[[GetOwnProperty]](P).
auto current = precomputed_get_own_property ? *precomputed_get_own_property : TRY(internal_get_own_property(property_key));
@ -863,10 +845,9 @@ ThrowCompletionOr<bool> Object::internal_define_own_property(PropertyKey const&
}
// 10.1.7 [[HasProperty]] ( P ), https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-hasproperty-p
// 10.1.7.1 OrdinaryHasProperty ( O, P ), https://tc39.es/ecma262/#sec-ordinaryhasproperty
ThrowCompletionOr<bool> Object::internal_has_property(PropertyKey const& property_key) const
{
VERIFY(property_key.is_valid());
// 1. Let hasOwn be ? O.[[GetOwnProperty]](P).
auto has_own = TRY(internal_get_own_property(property_key));
@ -888,10 +869,10 @@ ThrowCompletionOr<bool> Object::internal_has_property(PropertyKey const& propert
}
// 10.1.8 [[Get]] ( P, Receiver ), https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-get-p-receiver
// 10.1.8.1 OrdinaryGet ( O, P, Receiver ), https://tc39.es/ecma262/#sec-ordinaryget
ThrowCompletionOr<Value> Object::internal_get(PropertyKey const& property_key, Value receiver, CacheablePropertyMetadata* cacheable_metadata, PropertyLookupPhase phase) const
{
VERIFY(!receiver.is_empty());
VERIFY(property_key.is_valid());
auto& vm = this->vm();
@ -955,9 +936,9 @@ ThrowCompletionOr<Value> Object::internal_get(PropertyKey const& property_key, V
}
// 10.1.9 [[Set]] ( P, V, Receiver ), https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-set-p-v-receiver
// 10.1.9.1 OrdinarySet ( O, P, V, Receiver ), https://tc39.es/ecma262/#sec-ordinaryset
ThrowCompletionOr<bool> Object::internal_set(PropertyKey const& property_key, Value value, Value receiver, CacheablePropertyMetadata* cacheable_metadata)
{
VERIFY(property_key.is_valid());
VERIFY(!value.is_empty());
VERIFY(!receiver.is_empty());
@ -971,7 +952,6 @@ ThrowCompletionOr<bool> Object::internal_set(PropertyKey const& property_key, Va
// 10.1.9.2 OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc ), https://tc39.es/ecma262/#sec-ordinarysetwithowndescriptor
ThrowCompletionOr<bool> Object::ordinary_set_with_own_descriptor(PropertyKey const& property_key, Value value, Value receiver, Optional<PropertyDescriptor> own_descriptor, CacheablePropertyMetadata* cacheable_metadata)
{
VERIFY(property_key.is_valid());
VERIFY(!value.is_empty());
VERIFY(!receiver.is_empty());
@ -1005,7 +985,7 @@ ThrowCompletionOr<bool> Object::ordinary_set_with_own_descriptor(PropertyKey con
if (!*own_descriptor->writable)
return false;
// b. If Type(Receiver) is not Object, return false.
// b. If Receiver is not an Object, return false.
if (!receiver.is_object())
return false;
@ -1066,10 +1046,9 @@ ThrowCompletionOr<bool> Object::ordinary_set_with_own_descriptor(PropertyKey con
}
// 10.1.10 [[Delete]] ( P ), https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-delete-p
// 10.1.10.1 OrdinaryDelete ( O, P ), https://tc39.es/ecma262/#sec-ordinarydelete
ThrowCompletionOr<bool> Object::internal_delete(PropertyKey const& property_key)
{
VERIFY(property_key.is_valid());
// 1. Let desc be ? O.[[GetOwnProperty]](P).
auto descriptor = TRY(internal_get_own_property(property_key));
@ -1158,8 +1137,6 @@ static Optional<Object::IntrinsicAccessor> find_intrinsic_accessor(Object const*
Optional<ValueAndAttributes> Object::storage_get(PropertyKey const& property_key) const
{
VERIFY(property_key.is_valid());
Value value;
PropertyAttributes attributes;
Optional<u32> property_offset;
@ -1190,7 +1167,6 @@ Optional<ValueAndAttributes> Object::storage_get(PropertyKey const& property_key
bool Object::storage_has(PropertyKey const& property_key) const
{
VERIFY(property_key.is_valid());
if (property_key.is_number())
return m_indexed_properties.has_index(property_key.as_number());
return shape().lookup(property_key.to_string_or_symbol()).has_value();
@ -1198,8 +1174,6 @@ bool Object::storage_has(PropertyKey const& property_key) const
void Object::storage_set(PropertyKey const& property_key, ValueAndAttributes const& value_and_attributes)
{
VERIFY(property_key.is_valid());
auto [value, attributes, _] = value_and_attributes;
if (property_key.is_number()) {
@ -1241,7 +1215,6 @@ void Object::storage_set(PropertyKey const& property_key, ValueAndAttributes con
void Object::storage_delete(PropertyKey const& property_key)
{
VERIFY(property_key.is_valid());
VERIFY(storage_has(property_key));
if (property_key.is_number())
@ -1287,8 +1260,6 @@ void Object::define_native_accessor(Realm& realm, PropertyKey const& property_ke
void Object::define_direct_accessor(PropertyKey const& property_key, FunctionObject* getter, FunctionObject* setter, PropertyAttributes attributes)
{
VERIFY(property_key.is_valid());
auto existing_property = storage_get(property_key).value_or({}).value;
auto* accessor = existing_property.is_accessor() ? &existing_property.as_accessor() : nullptr;
if (!accessor) {

View file

@ -103,7 +103,6 @@ public:
ALWAYS_INLINE Type type() const { return m_type; }
bool is_valid() const { return m_type != Type::Invalid; }
bool is_number() const
{
if (m_type == Type::Number)
@ -170,7 +169,6 @@ public:
ByteString to_string() const
{
VERIFY(is_valid());
VERIFY(!is_symbol());
if (is_string())
return as_string();
@ -179,7 +177,6 @@ public:
StringOrSymbol to_string_or_symbol() const
{
VERIFY(is_valid());
VERIFY(!is_number());
if (is_string())
return StringOrSymbol(as_string());
@ -202,7 +199,6 @@ template<>
struct Traits<JS::PropertyKey> : public DefaultTraits<JS::PropertyKey> {
static unsigned hash(JS::PropertyKey const& name)
{
VERIFY(name.is_valid());
if (name.is_string())
return name.as_string().hash();
if (name.is_number())
@ -232,8 +228,6 @@ template<>
struct Formatter<JS::PropertyKey> : Formatter<StringView> {
ErrorOr<void> format(FormatBuilder& builder, JS::PropertyKey const& property_key)
{
if (!property_key.is_valid())
return builder.put_string("<invalid PropertyKey>"sv);
if (property_key.is_number())
return builder.put_u64(property_key.as_number());
return builder.put_string(property_key.to_string_or_symbol().to_display_string());

View file

@ -50,7 +50,6 @@ ProxyObject::ProxyObject(Object& target, Object& handler, Object& prototype)
static Value property_key_to_value(VM& vm, PropertyKey const& property_key)
{
VERIFY(property_key.is_valid());
if (property_key.is_symbol())
return property_key.as_symbol();
@ -249,8 +248,6 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> ProxyObject::internal_get_own_pr
auto& vm = this->vm();
VERIFY(property_key.is_valid());
// 1. Let handler be O.[[ProxyHandler]].
// 2. If handler is null, throw a TypeError exception.
@ -342,8 +339,6 @@ ThrowCompletionOr<bool> ProxyObject::internal_define_own_property(PropertyKey co
auto& vm = this->vm();
VERIFY(property_key.is_valid());
// 1. Let handler be O.[[ProxyHandler]].
// 2. If handler is null, throw a TypeError exception.
@ -426,8 +421,6 @@ ThrowCompletionOr<bool> ProxyObject::internal_has_property(PropertyKey const& pr
auto& vm = this->vm();
VERIFY(property_key.is_valid());
// 1. Let handler be O.[[ProxyHandler]].
// 2. If handler is null, throw a TypeError exception.
@ -497,7 +490,6 @@ ThrowCompletionOr<Value> ProxyObject::internal_get(PropertyKey const& property_k
auto& vm = this->vm();
VERIFY(property_key.is_valid());
VERIFY(!receiver.is_empty());
// 1. Let handler be O.[[ProxyHandler]].
@ -567,7 +559,6 @@ ThrowCompletionOr<bool> ProxyObject::internal_set(PropertyKey const& property_ke
auto& vm = this->vm();
VERIFY(property_key.is_valid());
VERIFY(!value.is_empty());
VERIFY(!receiver.is_empty());
@ -642,8 +633,6 @@ ThrowCompletionOr<bool> ProxyObject::internal_delete(PropertyKey const& property
auto& vm = this->vm();
VERIFY(property_key.is_valid());
// 1. Let handler be O.[[ProxyHandler]].
// 2. If handler is null, throw a TypeError exception.

View file

@ -284,7 +284,6 @@ NonnullGCPtr<Shape> Shape::create_delete_transition(StringOrSymbol const& proper
void Shape::add_property_without_transition(StringOrSymbol const& property_key, PropertyAttributes attributes)
{
VERIFY(property_key.is_valid());
ensure_property_table();
if (m_property_table->set(property_key, { m_property_count, attributes }) == AK::HashSetResult::InsertedNewEntry) {
VERIFY(m_property_count < NumericLimits<u32>::max());
@ -294,7 +293,6 @@ void Shape::add_property_without_transition(StringOrSymbol const& property_key,
FLATTEN void Shape::add_property_without_transition(PropertyKey const& property_key, PropertyAttributes attributes)
{
VERIFY(property_key.is_valid());
add_property_without_transition(property_key.to_string_or_symbol(), attributes);
}

View file

@ -54,11 +54,9 @@ void StringObject::visit_edges(Cell::Visitor& visitor)
// 10.4.3.5 StringGetOwnProperty ( S, P ), https://tc39.es/ecma262/#sec-stringgetownproperty
static ThrowCompletionOr<Optional<PropertyDescriptor>> string_get_own_property(StringObject const& string, PropertyKey const& property_key)
{
VERIFY(property_key.is_valid());
auto& vm = string.vm();
// 1. If Type(P) is not String, return undefined.
// 1. If P is not a String, return undefined.
// NOTE: The spec only uses string and symbol keys, and later coerces to numbers -
// this is not the case for PropertyKey, so '!property_key.is_string()' would be wrong.
if (property_key.is_symbol())
@ -68,7 +66,7 @@ static ThrowCompletionOr<Optional<PropertyDescriptor>> string_get_own_property(S
auto index = canonical_numeric_index_string(property_key, CanonicalIndexMode::IgnoreNumericRoundtrip);
// 3. If index is undefined, return undefined.
// 4. If IsIntegralNumber(index) is false, return undefined.
// 4. If index is not an integral Number, return undefined.
// 5. If index is -0𝔽, return undefined.
if (!index.is_index())
return Optional<PropertyDescriptor> {};
@ -84,7 +82,7 @@ static ThrowCompletionOr<Optional<PropertyDescriptor>> string_get_own_property(S
if (length <= index.as_index())
return Optional<PropertyDescriptor> {};
// 10. Let resultStr be the String value of length 1, containing one code unit from str, specifically the code unit at index (index).
// 10. Let resultStr be the substring of str from (index) to (index) + 1.
auto result_str = PrimitiveString::create(vm, Utf16String::create(str.substring_view(index.as_index(), 1)));
// 11. Return the PropertyDescriptor { [[Value]]: resultStr, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false }.
@ -99,8 +97,6 @@ static ThrowCompletionOr<Optional<PropertyDescriptor>> string_get_own_property(S
// 10.4.3.1 [[GetOwnProperty]] ( P ), https://tc39.es/ecma262/#sec-string-exotic-objects-getownproperty-p
ThrowCompletionOr<Optional<PropertyDescriptor>> StringObject::internal_get_own_property(PropertyKey const& property_key) const
{
VERIFY(property_key.is_valid());
// 1. Let desc be OrdinaryGetOwnProperty(S, P).
auto descriptor = MUST(Object::internal_get_own_property(property_key));
@ -115,8 +111,6 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> StringObject::internal_get_own_p
// 10.4.3.2 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-string-exotic-objects-defineownproperty-p-desc
ThrowCompletionOr<bool> StringObject::internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& property_descriptor, Optional<PropertyDescriptor>* precomputed_get_own_property)
{
VERIFY(property_key.is_valid());
// 1. Let stringDesc be StringGetOwnProperty(S, P).
auto string_descriptor = TRY(string_get_own_property(*this, property_key));
@ -144,7 +138,7 @@ ThrowCompletionOr<MarkedVector<Value>> StringObject::internal_own_property_keys(
// 2. Let str be O.[[StringData]].
auto str = m_string->utf16_string_view();
// 3. Assert: Type(str) is String.
// 3. Assert: str is a String.
// 4. Let len be the length of str.
auto length = str.length_in_code_units();
@ -163,7 +157,7 @@ ThrowCompletionOr<MarkedVector<Value>> StringObject::internal_own_property_keys(
}
}
// 7. For each own property key P of O such that Type(P) is String and P is not an array index, in ascending chronological order of property creation, do
// 7. For each own property key P of O such that P is a String and P is not an array index, in ascending chronological order of property creation, do
for (auto& it : shape().property_table()) {
if (it.key.is_string()) {
// a. Add P as the last element of keys.
@ -171,7 +165,7 @@ ThrowCompletionOr<MarkedVector<Value>> StringObject::internal_own_property_keys(
}
}
// 8. For each own property key P of O such that Type(P) is Symbol, in ascending chronological order of property creation, do
// 8. For each own property key P of O such that P is a Symbol, in ascending chronological order of property creation, do
for (auto& it : shape().property_table()) {
if (it.key.is_symbol()) {
// a. Add P as the last element of keys.

View file

@ -210,13 +210,11 @@ public:
// 10.4.5.1 [[GetOwnProperty]] ( P ), https://tc39.es/ecma262/#sec-integer-indexed-exotic-objects-getownproperty-p
virtual ThrowCompletionOr<Optional<PropertyDescriptor>> internal_get_own_property(PropertyKey const& property_key) const override
{
VERIFY(property_key.is_valid());
// NOTE: If the property name is a number type (An implementation-defined optimized
// property key type), it can be treated as a string property that will transparently be
// converted into a canonical numeric index.
// 1. If Type(P) is String, then
// 1. If P is a String, then
// NOTE: This includes an implementation-defined optimization, see note above!
if (property_key.is_string() || property_key.is_number()) {
// a. Let numericIndex be CanonicalNumericIndexString(P).
@ -247,13 +245,11 @@ public:
// 10.4.5.2 [[HasProperty]] ( P ), https://tc39.es/ecma262/#sec-integer-indexed-exotic-objects-hasproperty-p
virtual ThrowCompletionOr<bool> internal_has_property(PropertyKey const& property_key) const override
{
VERIFY(property_key.is_valid());
// NOTE: If the property name is a number type (An implementation-defined optimized
// property key type), it can be treated as a string property that will transparently be
// converted into a canonical numeric index.
// 1. If Type(P) is String, then
// 1. If P is a String, then
// NOTE: This includes an implementation-defined optimization, see note above!
if (property_key.is_string() || property_key.is_number()) {
// a. Let numericIndex be CanonicalNumericIndexString(P).
@ -270,13 +266,11 @@ public:
// 10.4.5.3 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-integer-indexed-exotic-objects-defineownproperty-p-desc
virtual ThrowCompletionOr<bool> internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& property_descriptor, Optional<PropertyDescriptor>* precomputed_get_own_property = nullptr) override
{
VERIFY(property_key.is_valid());
// NOTE: If the property name is a number type (An implementation-defined optimized
// property key type), it can be treated as a string property that will transparently be
// converted into a canonical numeric index.
// 1. If Type(P) is String, then
// 1. If P is a String, then
// NOTE: This includes an implementation-defined optimization, see note above!
if (property_key.is_string() || property_key.is_number()) {
// a. Let numericIndex be CanonicalNumericIndexString(P).
@ -316,17 +310,16 @@ public:
return Object::internal_define_own_property(property_key, property_descriptor, precomputed_get_own_property);
}
// 10.4.5.4 [[Get]] ( P, Receiver ), 10.4.5.4 [[Get]] ( P, Receiver )
// 10.4.5.4 [[Get]] ( P, Receiver ), https://tc39.es/ecma262/#sec-typedarray-get
virtual ThrowCompletionOr<Value> internal_get(PropertyKey const& property_key, Value receiver, CacheablePropertyMetadata* cacheable_metadata, PropertyLookupPhase phase) const override
{
VERIFY(!receiver.is_empty());
VERIFY(property_key.is_valid());
// NOTE: If the property name is a number type (An implementation-defined optimized
// property key type), it can be treated as a string property that will transparently be
// converted into a canonical numeric index.
// 1. If Type(P) is String, then
// 1. If P is a String, then
// NOTE: This includes an implementation-defined optimization, see note above!
if (property_key.is_string() || property_key.is_number()) {
// a. Let numericIndex be CanonicalNumericIndexString(P).
@ -348,12 +341,11 @@ public:
VERIFY(!value.is_empty());
VERIFY(!receiver.is_empty());
VERIFY(property_key.is_valid());
// NOTE: If the property name is a number type (An implementation-defined optimized
// property key type), it can be treated as a string property that will transparently be
// converted into a canonical numeric index.
// 1. If Type(P) is String, then
// 1. If P is a String, then
// NOTE: This includes an implementation-defined optimization, see note above!
if (property_key.is_string() || property_key.is_number()) {
// a. Let numericIndex be CanonicalNumericIndexString(P).
@ -382,13 +374,11 @@ public:
// 10.4.5.6 [[Delete]] ( P ), https://tc39.es/ecma262/#sec-integer-indexed-exotic-objects-delete-p
virtual ThrowCompletionOr<bool> internal_delete(PropertyKey const& property_key) override
{
VERIFY(property_key.is_valid());
// NOTE: If the property name is a number type (An implementation-defined optimized
// property key type), it can be treated as a string property that will transparently be
// converted into a canonical numeric index.
// 1. If Type(P) is String, then
// 1. If P is a String, then
// NOTE: This includes an implementation-defined optimization, see note above!
if (property_key.is_string() || property_key.is_number()) {
// a. Let numericIndex be CanonicalNumericIndexString(P).

View file

@ -1210,34 +1210,28 @@ double to_integer_or_infinity(double number)
// 7.3.3 GetV ( V, P ), https://tc39.es/ecma262/#sec-getv
ThrowCompletionOr<Value> Value::get(VM& vm, PropertyKey const& property_key) const
{
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_key.is_valid());
// 2. Let O be ? ToObject(V).
// 1. Let O be ? ToObject(V).
auto object = TRY(to_object(vm));
// 3. Return ? O.[[Get]](P, V).
// 2. Return ? O.[[Get]](P, V).
return TRY(object->internal_get(property_key, *this));
}
// 7.3.11 GetMethod ( V, P ), https://tc39.es/ecma262/#sec-getmethod
ThrowCompletionOr<GCPtr<FunctionObject>> Value::get_method(VM& vm, PropertyKey const& property_key) const
{
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_key.is_valid());
// 2. Let func be ? GetV(V, P).
// 1. Let func be ? GetV(V, P).
auto function = TRY(get(vm, property_key));
// 3. If func is either undefined or null, return undefined.
// 2. If func is either undefined or null, return undefined.
if (function.is_nullish())
return nullptr;
// 4. If IsCallable(func) is false, throw a TypeError exception.
// 3. If IsCallable(func) is false, throw a TypeError exception.
if (!function.is_function())
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, function.to_string_without_side_effects());
// 5. Return func.
// 4. Return func.
return function.as_function();
}