LibJS: Remove PropertyKey::is_valid() method

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
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) 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. // 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_key.is_valid());
// 2. If current is undefined, then // 2. If current is undefined, then
if (!current.has_value()) { if (!current.has_value()) {

View file

@ -281,8 +281,6 @@ ThrowCompletionOr<bool> Array::internal_define_own_property(PropertyKey const& p
{ {
auto& vm = this->vm(); auto& vm = this->vm();
VERIFY(property_key.is_valid());
// 1. If P is "length", then // 1. If P is "length", then
if (property_key.is_string() && property_key.as_string() == vm.names.length.as_string()) { if (property_key.is_string() && property_key.as_string() == vm.names.length.as_string()) {
// a. Return ? ArraySetLength(A, Desc). // 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 // 7.3.2 Get ( O, P ), https://tc39.es/ecma262/#sec-get-o-p
ThrowCompletionOr<Value> Object::get(PropertyKey const& property_key) const ThrowCompletionOr<Value> Object::get(PropertyKey const& property_key) const
{ {
VERIFY(property_key.is_valid());
// 1. Return ? O.[[Get]](P, O). // 1. Return ? O.[[Get]](P, O).
return TRY(internal_get(property_key, this)); 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(); auto& vm = this->vm();
VERIFY(property_key.is_valid());
VERIFY(!value.is_empty()); VERIFY(!value.is_empty());
// 1. Let success be ? O.[[Set]](P, V, O). // 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 // 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) 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 }. // 1. Let newDesc be the PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }.
auto new_descriptor = PropertyDescriptor { auto new_descriptor = PropertyDescriptor {
.value = value, .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 // 7.3.6 CreateMethodProperty ( O, P, V ), https://tc39.es/ecma262/#sec-createmethodproperty
void Object::create_method_property(PropertyKey const& property_key, Value value) void Object::create_method_property(PropertyKey const& property_key, Value value)
{ {
VERIFY(property_key.is_valid());
VERIFY(!value.is_empty()); VERIFY(!value.is_empty());
// 1. Assert: O is an ordinary, extensible object with no non-configurable properties. // 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(); auto& vm = this->vm();
VERIFY(property_key.is_valid());
VERIFY(!value.is_empty()); VERIFY(!value.is_empty());
// 1. Let success be ? CreateDataProperty(O, P, V). // 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 // 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) void Object::create_non_enumerable_data_property_or_throw(PropertyKey const& property_key, Value value)
{ {
VERIFY(property_key.is_valid());
VERIFY(!value.is_empty()); VERIFY(!value.is_empty());
// 1. Assert: O is an ordinary, extensible object with no non-configurable properties. // 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(); auto& vm = this->vm();
VERIFY(property_key.is_valid());
// 1. Let success be ? O.[[DefineOwnProperty]](P, desc). // 1. Let success be ? O.[[DefineOwnProperty]](P, desc).
auto success = TRY(internal_define_own_property(property_key, property_descriptor)); 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(); auto& vm = this->vm();
VERIFY(property_key.is_valid());
// 1. Let success be ? O.[[Delete]](P). // 1. Let success be ? O.[[Delete]](P).
auto success = TRY(internal_delete(property_key)); 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 // 7.3.12 HasProperty ( O, P ), https://tc39.es/ecma262/#sec-hasproperty
ThrowCompletionOr<bool> Object::has_property(PropertyKey const& property_key) const ThrowCompletionOr<bool> Object::has_property(PropertyKey const& property_key) const
{ {
VERIFY(property_key.is_valid());
// 1. Return ? O.[[HasProperty]](P). // 1. Return ? O.[[HasProperty]](P).
return internal_has_property(property_key); 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 // 7.3.13 HasOwnProperty ( O, P ), https://tc39.es/ecma262/#sec-hasownproperty
ThrowCompletionOr<bool> Object::has_own_property(PropertyKey const& property_key) const ThrowCompletionOr<bool> Object::has_own_property(PropertyKey const& property_key) const
{ {
VERIFY(property_key.is_valid());
// 1. Let desc be ? O.[[GetOwnProperty]](P). // 1. Let desc be ? O.[[GetOwnProperty]](P).
auto descriptor = TRY(internal_get_own_property(property_key)); 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 [[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 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. // 1. If O does not have an own property with key P, return undefined.
auto maybe_storage_entry = storage_get(property_key); auto maybe_storage_entry = storage_get(property_key);
if (!maybe_storage_entry.has_value()) 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 [[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) 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). // 1. Let current be ? O.[[GetOwnProperty]](P).
auto current = precomputed_get_own_property ? *precomputed_get_own_property : TRY(internal_get_own_property(property_key)); 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 [[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 ThrowCompletionOr<bool> Object::internal_has_property(PropertyKey const& property_key) const
{ {
VERIFY(property_key.is_valid());
// 1. Let hasOwn be ? O.[[GetOwnProperty]](P). // 1. Let hasOwn be ? O.[[GetOwnProperty]](P).
auto has_own = TRY(internal_get_own_property(property_key)); 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 [[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 ThrowCompletionOr<Value> Object::internal_get(PropertyKey const& property_key, Value receiver, CacheablePropertyMetadata* cacheable_metadata, PropertyLookupPhase phase) const
{ {
VERIFY(!receiver.is_empty()); VERIFY(!receiver.is_empty());
VERIFY(property_key.is_valid());
auto& vm = this->vm(); 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 [[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) 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(!value.is_empty());
VERIFY(!receiver.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 // 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) 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(!value.is_empty());
VERIFY(!receiver.is_empty()); VERIFY(!receiver.is_empty());
@ -1005,7 +985,7 @@ ThrowCompletionOr<bool> Object::ordinary_set_with_own_descriptor(PropertyKey con
if (!*own_descriptor->writable) if (!*own_descriptor->writable)
return false; return false;
// b. If Type(Receiver) is not Object, return false. // b. If Receiver is not an Object, return false.
if (!receiver.is_object()) if (!receiver.is_object())
return false; 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 [[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) ThrowCompletionOr<bool> Object::internal_delete(PropertyKey const& property_key)
{ {
VERIFY(property_key.is_valid());
// 1. Let desc be ? O.[[GetOwnProperty]](P). // 1. Let desc be ? O.[[GetOwnProperty]](P).
auto descriptor = TRY(internal_get_own_property(property_key)); 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 Optional<ValueAndAttributes> Object::storage_get(PropertyKey const& property_key) const
{ {
VERIFY(property_key.is_valid());
Value value; Value value;
PropertyAttributes attributes; PropertyAttributes attributes;
Optional<u32> property_offset; 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 bool Object::storage_has(PropertyKey const& property_key) const
{ {
VERIFY(property_key.is_valid());
if (property_key.is_number()) if (property_key.is_number())
return m_indexed_properties.has_index(property_key.as_number()); return m_indexed_properties.has_index(property_key.as_number());
return shape().lookup(property_key.to_string_or_symbol()).has_value(); 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) void Object::storage_set(PropertyKey const& property_key, ValueAndAttributes const& value_and_attributes)
{ {
VERIFY(property_key.is_valid());
auto [value, attributes, _] = value_and_attributes; auto [value, attributes, _] = value_and_attributes;
if (property_key.is_number()) { 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) void Object::storage_delete(PropertyKey const& property_key)
{ {
VERIFY(property_key.is_valid());
VERIFY(storage_has(property_key)); VERIFY(storage_has(property_key));
if (property_key.is_number()) 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) 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 existing_property = storage_get(property_key).value_or({}).value;
auto* accessor = existing_property.is_accessor() ? &existing_property.as_accessor() : nullptr; auto* accessor = existing_property.is_accessor() ? &existing_property.as_accessor() : nullptr;
if (!accessor) { if (!accessor) {

View file

@ -103,7 +103,6 @@ public:
ALWAYS_INLINE Type type() const { return m_type; } ALWAYS_INLINE Type type() const { return m_type; }
bool is_valid() const { return m_type != Type::Invalid; }
bool is_number() const bool is_number() const
{ {
if (m_type == Type::Number) if (m_type == Type::Number)
@ -170,7 +169,6 @@ public:
ByteString to_string() const ByteString to_string() const
{ {
VERIFY(is_valid());
VERIFY(!is_symbol()); VERIFY(!is_symbol());
if (is_string()) if (is_string())
return as_string(); return as_string();
@ -179,7 +177,6 @@ public:
StringOrSymbol to_string_or_symbol() const StringOrSymbol to_string_or_symbol() const
{ {
VERIFY(is_valid());
VERIFY(!is_number()); VERIFY(!is_number());
if (is_string()) if (is_string())
return StringOrSymbol(as_string()); return StringOrSymbol(as_string());
@ -202,7 +199,6 @@ template<>
struct Traits<JS::PropertyKey> : public DefaultTraits<JS::PropertyKey> { struct Traits<JS::PropertyKey> : public DefaultTraits<JS::PropertyKey> {
static unsigned hash(JS::PropertyKey const& name) static unsigned hash(JS::PropertyKey const& name)
{ {
VERIFY(name.is_valid());
if (name.is_string()) if (name.is_string())
return name.as_string().hash(); return name.as_string().hash();
if (name.is_number()) if (name.is_number())
@ -232,8 +228,6 @@ template<>
struct Formatter<JS::PropertyKey> : Formatter<StringView> { struct Formatter<JS::PropertyKey> : Formatter<StringView> {
ErrorOr<void> format(FormatBuilder& builder, JS::PropertyKey const& property_key) 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()) if (property_key.is_number())
return builder.put_u64(property_key.as_number()); return builder.put_u64(property_key.as_number());
return builder.put_string(property_key.to_string_or_symbol().to_display_string()); 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) static Value property_key_to_value(VM& vm, PropertyKey const& property_key)
{ {
VERIFY(property_key.is_valid());
if (property_key.is_symbol()) if (property_key.is_symbol())
return property_key.as_symbol(); return property_key.as_symbol();
@ -249,8 +248,6 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> ProxyObject::internal_get_own_pr
auto& vm = this->vm(); auto& vm = this->vm();
VERIFY(property_key.is_valid());
// 1. Let handler be O.[[ProxyHandler]]. // 1. Let handler be O.[[ProxyHandler]].
// 2. If handler is null, throw a TypeError exception. // 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(); auto& vm = this->vm();
VERIFY(property_key.is_valid());
// 1. Let handler be O.[[ProxyHandler]]. // 1. Let handler be O.[[ProxyHandler]].
// 2. If handler is null, throw a TypeError exception. // 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(); auto& vm = this->vm();
VERIFY(property_key.is_valid());
// 1. Let handler be O.[[ProxyHandler]]. // 1. Let handler be O.[[ProxyHandler]].
// 2. If handler is null, throw a TypeError exception. // 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(); auto& vm = this->vm();
VERIFY(property_key.is_valid());
VERIFY(!receiver.is_empty()); VERIFY(!receiver.is_empty());
// 1. Let handler be O.[[ProxyHandler]]. // 1. Let handler be O.[[ProxyHandler]].
@ -567,7 +559,6 @@ ThrowCompletionOr<bool> ProxyObject::internal_set(PropertyKey const& property_ke
auto& vm = this->vm(); auto& vm = this->vm();
VERIFY(property_key.is_valid());
VERIFY(!value.is_empty()); VERIFY(!value.is_empty());
VERIFY(!receiver.is_empty()); VERIFY(!receiver.is_empty());
@ -642,8 +633,6 @@ ThrowCompletionOr<bool> ProxyObject::internal_delete(PropertyKey const& property
auto& vm = this->vm(); auto& vm = this->vm();
VERIFY(property_key.is_valid());
// 1. Let handler be O.[[ProxyHandler]]. // 1. Let handler be O.[[ProxyHandler]].
// 2. If handler is null, throw a TypeError exception. // 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) void Shape::add_property_without_transition(StringOrSymbol const& property_key, PropertyAttributes attributes)
{ {
VERIFY(property_key.is_valid());
ensure_property_table(); ensure_property_table();
if (m_property_table->set(property_key, { m_property_count, attributes }) == AK::HashSetResult::InsertedNewEntry) { if (m_property_table->set(property_key, { m_property_count, attributes }) == AK::HashSetResult::InsertedNewEntry) {
VERIFY(m_property_count < NumericLimits<u32>::max()); 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) 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); 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 // 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) static ThrowCompletionOr<Optional<PropertyDescriptor>> string_get_own_property(StringObject const& string, PropertyKey const& property_key)
{ {
VERIFY(property_key.is_valid());
auto& vm = string.vm(); 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 - // 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. // this is not the case for PropertyKey, so '!property_key.is_string()' would be wrong.
if (property_key.is_symbol()) 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); auto index = canonical_numeric_index_string(property_key, CanonicalIndexMode::IgnoreNumericRoundtrip);
// 3. If index is undefined, return undefined. // 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. // 5. If index is -0𝔽, return undefined.
if (!index.is_index()) if (!index.is_index())
return Optional<PropertyDescriptor> {}; return Optional<PropertyDescriptor> {};
@ -84,7 +82,7 @@ static ThrowCompletionOr<Optional<PropertyDescriptor>> string_get_own_property(S
if (length <= index.as_index()) if (length <= index.as_index())
return Optional<PropertyDescriptor> {}; 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))); 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 }. // 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 // 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 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). // 1. Let desc be OrdinaryGetOwnProperty(S, P).
auto descriptor = MUST(Object::internal_get_own_property(property_key)); 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 // 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) 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). // 1. Let stringDesc be StringGetOwnProperty(S, P).
auto string_descriptor = TRY(string_get_own_property(*this, property_key)); 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]]. // 2. Let str be O.[[StringData]].
auto str = m_string->utf16_string_view(); 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. // 4. Let len be the length of str.
auto length = str.length_in_code_units(); 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()) { for (auto& it : shape().property_table()) {
if (it.key.is_string()) { if (it.key.is_string()) {
// a. Add P as the last element of keys. // 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()) { for (auto& it : shape().property_table()) {
if (it.key.is_symbol()) { if (it.key.is_symbol()) {
// a. Add P as the last element of keys. // 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 // 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 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 // 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 // property key type), it can be treated as a string property that will transparently be
// converted into a canonical numeric index. // 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! // NOTE: This includes an implementation-defined optimization, see note above!
if (property_key.is_string() || property_key.is_number()) { if (property_key.is_string() || property_key.is_number()) {
// a. Let numericIndex be CanonicalNumericIndexString(P). // 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 // 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 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 // 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 // property key type), it can be treated as a string property that will transparently be
// converted into a canonical numeric index. // 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! // NOTE: This includes an implementation-defined optimization, see note above!
if (property_key.is_string() || property_key.is_number()) { if (property_key.is_string() || property_key.is_number()) {
// a. Let numericIndex be CanonicalNumericIndexString(P). // 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 // 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 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 // 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 // property key type), it can be treated as a string property that will transparently be
// converted into a canonical numeric index. // 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! // NOTE: This includes an implementation-defined optimization, see note above!
if (property_key.is_string() || property_key.is_number()) { if (property_key.is_string() || property_key.is_number()) {
// a. Let numericIndex be CanonicalNumericIndexString(P). // 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); 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 virtual ThrowCompletionOr<Value> internal_get(PropertyKey const& property_key, Value receiver, CacheablePropertyMetadata* cacheable_metadata, PropertyLookupPhase phase) const override
{ {
VERIFY(!receiver.is_empty()); VERIFY(!receiver.is_empty());
VERIFY(property_key.is_valid());
// NOTE: If the property name is a number type (An implementation-defined optimized // 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 // property key type), it can be treated as a string property that will transparently be
// converted into a canonical numeric index. // 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! // NOTE: This includes an implementation-defined optimization, see note above!
if (property_key.is_string() || property_key.is_number()) { if (property_key.is_string() || property_key.is_number()) {
// a. Let numericIndex be CanonicalNumericIndexString(P). // a. Let numericIndex be CanonicalNumericIndexString(P).
@ -348,12 +341,11 @@ public:
VERIFY(!value.is_empty()); VERIFY(!value.is_empty());
VERIFY(!receiver.is_empty()); VERIFY(!receiver.is_empty());
VERIFY(property_key.is_valid());
// NOTE: If the property name is a number type (An implementation-defined optimized // 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 // property key type), it can be treated as a string property that will transparently be
// converted into a canonical numeric index. // 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! // NOTE: This includes an implementation-defined optimization, see note above!
if (property_key.is_string() || property_key.is_number()) { if (property_key.is_string() || property_key.is_number()) {
// a. Let numericIndex be CanonicalNumericIndexString(P). // 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 // 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 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 // 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 // property key type), it can be treated as a string property that will transparently be
// converted into a canonical numeric index. // 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! // NOTE: This includes an implementation-defined optimization, see note above!
if (property_key.is_string() || property_key.is_number()) { if (property_key.is_string() || property_key.is_number()) {
// a. Let numericIndex be CanonicalNumericIndexString(P). // 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 // 7.3.3 GetV ( V, P ), https://tc39.es/ecma262/#sec-getv
ThrowCompletionOr<Value> Value::get(VM& vm, PropertyKey const& property_key) const ThrowCompletionOr<Value> Value::get(VM& vm, PropertyKey const& property_key) const
{ {
// 1. Assert: IsPropertyKey(P) is true. // 1. Let O be ? ToObject(V).
VERIFY(property_key.is_valid());
// 2. Let O be ? ToObject(V).
auto object = TRY(to_object(vm)); 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)); return TRY(object->internal_get(property_key, *this));
} }
// 7.3.11 GetMethod ( V, P ), https://tc39.es/ecma262/#sec-getmethod // 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 ThrowCompletionOr<GCPtr<FunctionObject>> Value::get_method(VM& vm, PropertyKey const& property_key) const
{ {
// 1. Assert: IsPropertyKey(P) is true. // 1. Let func be ? GetV(V, P).
VERIFY(property_key.is_valid());
// 2. Let func be ? GetV(V, P).
auto function = TRY(get(vm, property_key)); 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()) if (function.is_nullish())
return nullptr; 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()) if (!function.is_function())
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, function.to_string_without_side_effects()); return vm.throw_completion<TypeError>(ErrorType::NotAFunction, function.to_string_without_side_effects());
// 5. Return func. // 4. Return func.
return function.as_function(); return function.as_function();
} }