Everywhere: Rename JS::PropertyKey variables from property_{name => key}

PropertyKey used to be called PropertyName, but got renamed. Let's
update all the variables of this type as well.
This commit is contained in:
Linus Groh 2022-02-06 15:59:04 +00:00
parent 3e6aaa3520
commit 6f20f49b21
25 changed files with 435 additions and 435 deletions

View file

@ -2411,27 +2411,27 @@ static JS::Value wrap_for_legacy_platform_object_get_own_property(JS::GlobalObje
// https://webidl.spec.whatwg.org/#dfn-named-property-visibility
scoped_generator.append(R"~~~(
JS::ThrowCompletionOr<bool> @class_name@::is_named_property_exposed_on_object(JS::PropertyKey const& property_name) const
JS::ThrowCompletionOr<bool> @class_name@::is_named_property_exposed_on_object(JS::PropertyKey const& property_key) const
{
[[maybe_unused]] auto& vm = this->vm();
// The spec doesn't say anything about the type of the property name here.
// Numbers can be converted to a string, which is fine and what other engines do.
// However, since a symbol cannot be converted to a string, it cannot be a supported property name. Return early if it's a symbol.
if (property_name.is_symbol())
if (property_key.is_symbol())
return false;
// 1. If P is not a supported property name of O, then return false.
// NOTE: This is in it's own variable to enforce the type.
// FIXME: Can this throw?
Vector<String> supported_property_names = impl().supported_property_names();
auto property_name_string = property_name.to_string();
if (!supported_property_names.contains_slow(property_name_string))
auto property_key_string = property_key.to_string();
if (!supported_property_names.contains_slow(property_key_string))
return false;
// 2. If O has an own property named P, then return false.
// NOTE: This has to be done manually instead of using Object::has_own_property, as that would use the overridden internal_get_own_property.
auto own_property_named_p = MUST(Object::internal_get_own_property(property_name));
auto own_property_named_p = MUST(Object::internal_get_own_property(property_key));
if (own_property_named_p.has_value())
return false;
@ -2453,7 +2453,7 @@ JS::ThrowCompletionOr<bool> @class_name@::is_named_property_exposed_on_object(JS
while (prototype) {
// FIXME: 1. If prototype is not a named properties object, and prototype has an own property named P, then return false.
// (It currently does not check for named property objects)
bool prototype_has_own_property_named_p = TRY(prototype->has_own_property(property_name));
bool prototype_has_own_property_named_p = TRY(prototype->has_own_property(property_key));
if (prototype_has_own_property_named_p)
return false;

View file

@ -22,39 +22,39 @@ DebuggerGlobalJSObject::DebuggerGlobalJSObject()
m_variables = lib->debug_info->get_variables_in_current_scope(regs);
}
JS::ThrowCompletionOr<JS::Value> DebuggerGlobalJSObject::internal_get(JS::PropertyKey const& property_name, JS::Value receiver) const
JS::ThrowCompletionOr<JS::Value> DebuggerGlobalJSObject::internal_get(JS::PropertyKey const& property_key, JS::Value receiver) const
{
if (m_variables.is_empty() || !property_name.is_string())
return Base::internal_get(property_name, receiver);
if (m_variables.is_empty() || !property_key.is_string())
return Base::internal_get(property_key, receiver);
auto it = m_variables.find_if([&](auto& variable) {
return variable->name == property_name.as_string();
return variable->name == property_key.as_string();
});
if (it.is_end())
return Base::internal_get(property_name, receiver);
return Base::internal_get(property_key, receiver);
auto& target_variable = **it;
auto js_value = debugger_to_js(target_variable);
if (js_value.has_value())
return js_value.value();
auto error_string = String::formatted("Variable {} of type {} is not convertible to a JS Value", property_name.as_string(), target_variable.type_name);
auto error_string = String::formatted("Variable {} of type {} is not convertible to a JS Value", property_key.as_string(), target_variable.type_name);
return vm().throw_completion<JS::TypeError>(const_cast<DebuggerGlobalJSObject&>(*this), move(error_string));
}
JS::ThrowCompletionOr<bool> DebuggerGlobalJSObject::internal_set(JS::PropertyKey const& property_name, JS::Value value, JS::Value receiver)
JS::ThrowCompletionOr<bool> DebuggerGlobalJSObject::internal_set(JS::PropertyKey const& property_key, JS::Value value, JS::Value receiver)
{
if (m_variables.is_empty() || !property_name.is_string())
return Base::internal_set(property_name, value, receiver);
if (m_variables.is_empty() || !property_key.is_string())
return Base::internal_set(property_key, value, receiver);
auto it = m_variables.find_if([&](auto& variable) {
return variable->name == property_name.as_string();
return variable->name == property_key.as_string();
});
if (it.is_end())
return Base::internal_set(property_name, value, receiver);
return Base::internal_set(property_key, value, receiver);
auto& target_variable = **it;
auto debugger_value = js_to_debugger(value, target_variable);
if (debugger_value.has_value())
return Debugger::the().session()->poke(target_variable.location_data.address, debugger_value.value());
auto error_string = String::formatted("Cannot convert JS value {} to variable {} of type {}", value.to_string_without_side_effects(), property_name.as_string(), target_variable.type_name);
auto error_string = String::formatted("Cannot convert JS value {} to variable {} of type {}", value.to_string_without_side_effects(), property_key.as_string(), target_variable.type_name);
return vm().throw_completion<JS::TypeError>(const_cast<DebuggerGlobalJSObject&>(*this), move(error_string));
}

View file

@ -29,20 +29,20 @@ DebuggerVariableJSObject::~DebuggerVariableJSObject()
{
}
JS::ThrowCompletionOr<bool> DebuggerVariableJSObject::internal_set(const JS::PropertyKey& property_name, JS::Value value, JS::Value)
JS::ThrowCompletionOr<bool> DebuggerVariableJSObject::internal_set(const JS::PropertyKey& property_key, JS::Value value, JS::Value)
{
auto& vm = this->vm();
if (!property_name.is_string())
return vm.throw_completion<JS::TypeError>(global_object(), String::formatted("Invalid variable name {}", property_name.to_string()));
if (!property_key.is_string())
return vm.throw_completion<JS::TypeError>(global_object(), String::formatted("Invalid variable name {}", property_key.to_string()));
auto name = property_name.as_string();
auto name = property_key.as_string();
auto it = m_variable_info.members.find_if([&](auto& variable) {
return variable->name == name;
});
if (it.is_end())
return vm.throw_completion<JS::TypeError>(global_object(), String::formatted("Variable of type {} has no property {}", m_variable_info.type_name, property_name));
return vm.throw_completion<JS::TypeError>(global_object(), String::formatted("Variable of type {} has no property {}", m_variable_info.type_name, property_key));
auto& member = **it;
auto new_value = debugger_object().js_to_debugger(value, member);

View file

@ -1397,7 +1397,7 @@ ThrowCompletionOr<Reference> MemberExpression::to_reference(Interpreter& interpr
// From here on equivalent to
// 13.3.4 EvaluatePropertyAccessWithIdentifierKey ( baseValue, identifierName, strict ), https://tc39.es/ecma262/#sec-evaluate-property-access-with-identifier-key
PropertyKey property_name;
PropertyKey property_key;
if (is_computed()) {
// Weird order which I can't quite find from the specs.
auto value = TRY(m_property->execute(interpreter, global_object)).release_value();
@ -1405,19 +1405,19 @@ ThrowCompletionOr<Reference> MemberExpression::to_reference(Interpreter& interpr
TRY(require_object_coercible(global_object, base_value));
property_name = TRY(PropertyKey::from_value(global_object, value));
property_key = TRY(PropertyKey::from_value(global_object, value));
} else if (is<PrivateIdentifier>(*m_property)) {
auto& private_identifier = static_cast<PrivateIdentifier const&>(*m_property);
return make_private_reference(interpreter.vm(), base_value, private_identifier.string());
} else {
property_name = verify_cast<Identifier>(*m_property).string();
property_key = verify_cast<Identifier>(*m_property).string();
TRY(require_object_coercible(global_object, base_value));
}
if (!property_name.is_valid())
if (!property_key.is_valid())
return Reference {};
auto strict = interpreter.vm().in_strict_mode();
return Reference { base_value, move(property_name), {}, strict };
return Reference { base_value, move(property_key), {}, strict };
}
// 13.5.1.2 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-delete-operator-runtime-semantics-evaluation
@ -1504,7 +1504,7 @@ static ThrowCompletionOr<ClassElement::ClassElementName> class_key_to_property_n
// 15.4.5 Runtime Semantics: MethodDefinitionEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-methoddefinitionevaluation
ThrowCompletionOr<ClassElement::ClassValue> ClassMethod::class_element_evaluation(Interpreter& interpreter, GlobalObject& global_object, Object& target) const
{
auto property_key = TRY(class_key_to_property_name(interpreter, global_object, *m_key));
auto property_key_or_private_name = TRY(class_key_to_property_name(interpreter, global_object, *m_key));
auto method_value = TRY(m_function->execute(interpreter, global_object)).release_value();
@ -1514,38 +1514,38 @@ ThrowCompletionOr<ClassElement::ClassValue> ClassMethod::class_element_evaluatio
method_function.make_method(target);
auto set_function_name = [&](String prefix = "") {
auto property_name = property_key.visit(
[&](PropertyKey const& property_name) -> String {
if (property_name.is_symbol()) {
auto description = property_name.as_symbol()->description();
auto name = property_key_or_private_name.visit(
[&](PropertyKey const& property_key) -> String {
if (property_key.is_symbol()) {
auto description = property_key.as_symbol()->description();
if (description.is_empty())
return "";
return String::formatted("[{}]", description);
} else {
return property_name.to_string();
return property_key.to_string();
}
},
[&](PrivateName const& private_name) -> String {
return private_name.description;
});
update_function_name(method_value, String::formatted("{}{}{}", prefix, prefix.is_empty() ? "" : " ", property_name));
update_function_name(method_value, String::formatted("{}{}{}", prefix, prefix.is_empty() ? "" : " ", name));
};
if (property_key.has<PropertyKey>()) {
auto& property_name = property_key.get<PropertyKey>();
if (property_key_or_private_name.has<PropertyKey>()) {
auto& property_key = property_key_or_private_name.get<PropertyKey>();
switch (kind()) {
case ClassMethod::Kind::Method:
set_function_name();
TRY(target.define_property_or_throw(property_name, { .value = method_value, .writable = true, .enumerable = false, .configurable = true }));
TRY(target.define_property_or_throw(property_key, { .value = method_value, .writable = true, .enumerable = false, .configurable = true }));
break;
case ClassMethod::Kind::Getter:
set_function_name("get");
TRY(target.define_property_or_throw(property_name, { .get = &method_function, .enumerable = true, .configurable = true }));
TRY(target.define_property_or_throw(property_key, { .get = &method_function, .enumerable = true, .configurable = true }));
break;
case ClassMethod::Kind::Setter:
set_function_name("set");
TRY(target.define_property_or_throw(property_name, { .set = &method_function, .enumerable = true, .configurable = true }));
TRY(target.define_property_or_throw(property_key, { .set = &method_function, .enumerable = true, .configurable = true }));
break;
default:
VERIFY_NOT_REACHED();
@ -1553,7 +1553,7 @@ ThrowCompletionOr<ClassElement::ClassValue> ClassMethod::class_element_evaluatio
return ClassValue { normal_completion({}) };
} else {
auto& private_name = property_key.get<PrivateName>();
auto& private_name = property_key_or_private_name.get<PrivateName>();
switch (kind()) {
case Kind::Method:
set_function_name();
@ -1614,13 +1614,13 @@ private:
// 15.7.10 Runtime Semantics: ClassFieldDefinitionEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-classfielddefinitionevaluation
ThrowCompletionOr<ClassElement::ClassValue> ClassField::class_element_evaluation(Interpreter& interpreter, GlobalObject& global_object, Object& target) const
{
auto property_key = TRY(class_key_to_property_name(interpreter, global_object, *m_key));
auto property_key_or_private_name = TRY(class_key_to_property_name(interpreter, global_object, *m_key));
Handle<ECMAScriptFunctionObject> initializer {};
if (m_initializer) {
auto copy_initializer = m_initializer;
auto name = property_key.visit(
[&](PropertyKey const& property_name) -> String {
return property_name.is_number() ? property_name.to_string() : property_name.to_string_or_symbol().to_display_string();
auto name = property_key_or_private_name.visit(
[&](PropertyKey const& property_key) -> String {
return property_key.is_number() ? property_key.to_string() : property_key.to_string_or_symbol().to_display_string();
},
[&](PrivateName const& private_name) -> String {
return private_name.description;
@ -1634,7 +1634,7 @@ ThrowCompletionOr<ClassElement::ClassValue> ClassField::class_element_evaluation
return ClassValue {
ClassFieldDefinition {
move(property_key),
move(property_key_or_private_name),
move(initializer),
}
};

View file

@ -236,15 +236,15 @@ void CopyObjectExcludingProperties::execute_impl(Bytecode::Interpreter& interpre
for (auto& key : own_keys) {
if (!excluded_names.contains(key)) {
auto property_name_or_error = key.to_property_key(interpreter.global_object());
if (property_name_or_error.is_error())
auto property_key_or_error = key.to_property_key(interpreter.global_object());
if (property_key_or_error.is_error())
return;
PropertyKey property_name = property_name_or_error.release_value();
auto property_value_or_error = from_object->get(property_name);
PropertyKey property_key = property_key_or_error.release_value();
auto property_value_or_error = from_object->get(property_key);
if (property_value_or_error.is_error())
return;
auto property_value = property_value_or_error.release_value();
to_object->define_direct_property(property_name, property_value, JS::default_attributes);
to_object->define_direct_property(property_key, property_value, JS::default_attributes);
}
}

View file

@ -1654,14 +1654,14 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
while (!done() && !match(TokenType::CurlyClose)) {
property_type = ObjectProperty::Type::KeyValue;
RefPtr<Expression> property_name;
RefPtr<Expression> property_key;
RefPtr<Expression> property_value;
FunctionKind function_kind { FunctionKind::Normal };
if (match(TokenType::TripleDot)) {
consume();
property_name = parse_expression(4);
properties.append(create_ast_node<ObjectProperty>({ m_state.current_token.filename(), rule_start.position(), position() }, *property_name, nullptr, ObjectProperty::Type::Spread, false));
property_key = parse_expression(4);
properties.append(create_ast_node<ObjectProperty>({ m_state.current_token.filename(), rule_start.position(), position() }, *property_key, nullptr, ObjectProperty::Type::Spread, false));
if (!match(TokenType::Comma))
break;
consume(TokenType::Comma);
@ -1685,26 +1685,26 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
if (match(TokenType::Asterisk)) {
consume();
property_type = ObjectProperty::Type::KeyValue;
property_name = parse_property_key();
property_key = parse_property_key();
VERIFY(function_kind == FunctionKind::Normal || function_kind == FunctionKind::Async);
function_kind = function_kind == FunctionKind::Normal ? FunctionKind::Generator : FunctionKind::AsyncGenerator;
} else if (match_identifier()) {
auto identifier = consume();
if (identifier.original_value() == "get"sv && match_property_key()) {
property_type = ObjectProperty::Type::Getter;
property_name = parse_property_key();
property_key = parse_property_key();
} else if (identifier.original_value() == "set"sv && match_property_key()) {
property_type = ObjectProperty::Type::Setter;
property_name = parse_property_key();
property_key = parse_property_key();
} else {
property_name = create_ast_node<StringLiteral>({ m_state.current_token.filename(), rule_start.position(), position() }, identifier.value());
property_key = create_ast_node<StringLiteral>({ m_state.current_token.filename(), rule_start.position(), position() }, identifier.value());
property_value = create_ast_node<Identifier>({ m_state.current_token.filename(), rule_start.position(), position() }, identifier.value());
}
} else {
property_name = parse_property_key();
property_key = parse_property_key();
}
bool is_proto = (type == TokenType::StringLiteral || type == TokenType::Identifier) && is<StringLiteral>(*property_name) && static_cast<StringLiteral const&>(*property_name).value() == "__proto__";
bool is_proto = (type == TokenType::StringLiteral || type == TokenType::Identifier) && is<StringLiteral>(*property_key) && static_cast<StringLiteral const&>(*property_key).value() == "__proto__";
if (property_type == ObjectProperty::Type::Getter || property_type == ObjectProperty::Type::Setter) {
if (!match(TokenType::ParenOpen)) {
@ -1721,7 +1721,7 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
if (!invalid_object_literal_property_range.has_value())
invalid_object_literal_property_range = expression->source_range();
} else if (match(TokenType::ParenOpen)) {
VERIFY(property_name);
VERIFY(property_key);
u8 parse_options = FunctionNodeParseOptions::AllowSuperPropertyLookup;
if (property_type == ObjectProperty::Type::Getter)
parse_options |= FunctionNodeParseOptions::IsGetterFunction;
@ -1732,9 +1732,9 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
if (function_kind == FunctionKind::Async || function_kind == FunctionKind::AsyncGenerator)
parse_options |= FunctionNodeParseOptions::IsAsyncFunction;
auto function = parse_function_node<FunctionExpression>(parse_options, function_start);
properties.append(create_ast_node<ObjectProperty>({ m_state.current_token.filename(), rule_start.position(), position() }, *property_name, function, property_type, true));
properties.append(create_ast_node<ObjectProperty>({ m_state.current_token.filename(), rule_start.position(), position() }, *property_key, function, property_type, true));
} else if (match(TokenType::Colon)) {
if (!property_name) {
if (!property_key) {
expected("a property name");
skip_to_next_property();
continue;
@ -1745,15 +1745,15 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
syntax_error("Property name '__proto__' must not appear more than once in object literal");
has_direct_proto_property = true;
}
properties.append(create_ast_node<ObjectProperty>({ m_state.current_token.filename(), rule_start.position(), position() }, *property_name, parse_expression(2), property_type, false));
} else if (property_name && property_value) {
if (m_state.strict_mode && is<StringLiteral>(*property_name)) {
auto& string_literal = static_cast<StringLiteral const&>(*property_name);
properties.append(create_ast_node<ObjectProperty>({ m_state.current_token.filename(), rule_start.position(), position() }, *property_key, parse_expression(2), property_type, false));
} else if (property_key && property_value) {
if (m_state.strict_mode && is<StringLiteral>(*property_key)) {
auto& string_literal = static_cast<StringLiteral const&>(*property_key);
if (is_strict_reserved_word(string_literal.value()))
syntax_error(String::formatted("'{}' is a reserved keyword", string_literal.value()));
}
properties.append(create_ast_node<ObjectProperty>({ m_state.current_token.filename(), rule_start.position(), position() }, *property_name, *property_value, property_type, false));
properties.append(create_ast_node<ObjectProperty>({ m_state.current_token.filename(), rule_start.position(), position() }, *property_key, *property_value, property_type, false));
} else {
expected("a property");
skip_to_next_property();

View file

@ -246,11 +246,11 @@ bool is_compatible_property_descriptor(bool extensible, PropertyDescriptor const
}
// 10.1.6.3 ValidateAndApplyPropertyDescriptor ( O, P, extensible, Desc, current ), https://tc39.es/ecma262/#sec-validateandapplypropertydescriptor
bool validate_and_apply_property_descriptor(Object* object, PropertyKey const& property_name, 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: If O is not undefined, then IsPropertyKey(P) is true.
if (object)
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 2. If current is undefined, then
if (!current.has_value()) {
@ -267,7 +267,7 @@ bool validate_and_apply_property_descriptor(Object* object, PropertyKey const& p
// to its default value.
if (object) {
auto value = descriptor.value.value_or(js_undefined());
object->storage_set(property_name, { value, descriptor.attributes() });
object->storage_set(property_key, { value, descriptor.attributes() });
}
}
// d. Else,
@ -281,7 +281,7 @@ bool validate_and_apply_property_descriptor(Object* object, PropertyKey const& p
// to its default value.
if (object) {
auto accessor = Accessor::create(object->vm(), descriptor.get.value_or(nullptr), descriptor.set.value_or(nullptr));
object->storage_set(property_name, { accessor, descriptor.attributes() });
object->storage_set(property_key, { accessor, descriptor.attributes() });
}
}
// e. Return true.
@ -320,7 +320,7 @@ bool validate_and_apply_property_descriptor(Object* object, PropertyKey const& p
// set the rest of the property's attributes to their default values.
if (object) {
auto accessor = Accessor::create(object->vm(), nullptr, nullptr);
object->storage_set(property_name, { accessor, current->attributes() });
object->storage_set(property_key, { accessor, current->attributes() });
}
}
// c. Else,
@ -330,7 +330,7 @@ bool validate_and_apply_property_descriptor(Object* object, PropertyKey const& p
// set the rest of the property's attributes to their default values.
if (object) {
auto value = js_undefined();
object->storage_set(property_name, { value, current->attributes() });
object->storage_set(property_key, { value, current->attributes() });
}
}
}
@ -386,7 +386,7 @@ bool validate_and_apply_property_descriptor(Object* object, PropertyKey const& p
attributes.set_writable(descriptor.writable.value_or(current->writable.value_or(false)));
attributes.set_enumerable(descriptor.enumerable.value_or(current->enumerable.value_or(false)));
attributes.set_configurable(descriptor.configurable.value_or(current->configurable.value_or(false)));
object->storage_set(property_name, { value, attributes });
object->storage_set(property_key, { value, attributes });
}
// 10. Return true.
@ -913,19 +913,19 @@ Object* create_mapped_arguments_object(GlobalObject& global_object, FunctionObje
}
// 7.1.21 CanonicalNumericIndexString ( argument ), https://tc39.es/ecma262/#sec-canonicalnumericindexstring
Value canonical_numeric_index_string(GlobalObject& global_object, PropertyKey const& property_name)
Value canonical_numeric_index_string(GlobalObject& global_object, PropertyKey const& property_key)
{
// 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 has already been
// converted successfully into a canonical numeric index.
VERIFY(property_name.is_string() || property_name.is_number());
VERIFY(property_key.is_string() || property_key.is_number());
if (property_name.is_number())
return Value(property_name.as_number());
if (property_key.is_number())
return Value(property_key.as_number());
// 1. Assert: Type(argument) is String.
auto argument = Value(js_string(global_object.vm(), property_name.as_string()));
auto argument = Value(js_string(global_object.vm(), property_key.as_string()));
// 2. If argument is "-0", return -0𝔽.
if (argument.as_string().string() == "-0")

View file

@ -35,28 +35,28 @@ void ArgumentsObject::visit_edges(Cell::Visitor& visitor)
}
// 10.4.4.3 [[Get]] ( P, Receiver ), https://tc39.es/ecma262/#sec-arguments-exotic-objects-get-p-receiver
ThrowCompletionOr<Value> ArgumentsObject::internal_get(PropertyKey const& property_name, Value receiver) const
ThrowCompletionOr<Value> ArgumentsObject::internal_get(PropertyKey const& property_key, Value receiver) const
{
// 1. Let map be args.[[ParameterMap]].
auto& map = *m_parameter_map;
// 2. Let isMapped be ! HasOwnProperty(map, P).
bool is_mapped = MUST(m_parameter_map->has_own_property(property_name));
bool is_mapped = MUST(m_parameter_map->has_own_property(property_key));
// 3. If isMapped is false, then
if (!is_mapped) {
// a. Return ? OrdinaryGet(args, P, Receiver).
return Object::internal_get(property_name, receiver);
return Object::internal_get(property_key, receiver);
}
// FIXME: a. Assert: map contains a formal parameter mapping for P.
// b. Return Get(map, P).
return map.get(property_name);
return map.get(property_key);
}
// 10.4.4.4 [[Set]] ( P, V, Receiver ), https://tc39.es/ecma262/#sec-arguments-exotic-objects-set-p-v-receiver
ThrowCompletionOr<bool> ArgumentsObject::internal_set(PropertyKey const& property_name, Value value, Value receiver)
ThrowCompletionOr<bool> ArgumentsObject::internal_set(PropertyKey const& property_key, Value value, Value receiver)
{
bool is_mapped = false;
@ -67,38 +67,38 @@ ThrowCompletionOr<bool> ArgumentsObject::internal_set(PropertyKey const& propert
} else {
// a. Let map be args.[[ParameterMap]].
// b. Let isMapped be ! HasOwnProperty(map, P).
is_mapped = MUST(parameter_map().has_own_property(property_name));
is_mapped = MUST(parameter_map().has_own_property(property_key));
}
// 3. If isMapped is true, then
if (is_mapped) {
// a. Let setStatus be Set(map, P, V, false).
auto set_status = MUST(m_parameter_map->set(property_name, value, Object::ShouldThrowExceptions::No));
auto set_status = MUST(m_parameter_map->set(property_key, value, Object::ShouldThrowExceptions::No));
// b. Assert: setStatus is true because formal parameters mapped by argument objects are always writable.
VERIFY(set_status);
}
// 4. Return ? OrdinarySet(args, P, V, Receiver).
return Object::internal_set(property_name, value, receiver);
return Object::internal_set(property_key, value, receiver);
}
// 10.4.4.5 [[Delete]] ( P ), https://tc39.es/ecma262/#sec-arguments-exotic-objects-delete-p
ThrowCompletionOr<bool> ArgumentsObject::internal_delete(PropertyKey const& property_name)
ThrowCompletionOr<bool> ArgumentsObject::internal_delete(PropertyKey const& property_key)
{
// 1. Let map be args.[[ParameterMap]].
auto& map = parameter_map();
// 2. Let isMapped be ! HasOwnProperty(map, P).
bool is_mapped = MUST(map.has_own_property(property_name));
bool is_mapped = MUST(map.has_own_property(property_key));
// 3. Let result be ? OrdinaryDelete(args, P).
bool result = TRY(Object::internal_delete(property_name));
bool result = TRY(Object::internal_delete(property_key));
// 4. If result is true and isMapped is true, then
if (result && is_mapped) {
// a. Call map.[[Delete]](P).
MUST(map.internal_delete(property_name));
MUST(map.internal_delete(property_key));
}
// 5. Return result.
@ -106,10 +106,10 @@ ThrowCompletionOr<bool> ArgumentsObject::internal_delete(PropertyKey const& prop
}
// 10.4.4.1 [[GetOwnProperty]] ( P ), https://tc39.es/ecma262/#sec-arguments-exotic-objects-getownproperty-p
ThrowCompletionOr<Optional<PropertyDescriptor>> ArgumentsObject::internal_get_own_property(PropertyKey const& property_name) const
ThrowCompletionOr<Optional<PropertyDescriptor>> ArgumentsObject::internal_get_own_property(PropertyKey const& property_key) const
{
// 1. Let desc be OrdinaryGetOwnProperty(args, P).
auto desc = MUST(Object::internal_get_own_property(property_name));
auto desc = MUST(Object::internal_get_own_property(property_key));
// 2. If desc is undefined, return desc.
if (!desc.has_value())
@ -117,12 +117,12 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> ArgumentsObject::internal_get_ow
// 3. Let map be args.[[ParameterMap]].
// 4. Let isMapped be ! HasOwnProperty(map, P).
bool is_mapped = MUST(m_parameter_map->has_own_property(property_name));
bool is_mapped = MUST(m_parameter_map->has_own_property(property_key));
// 5. If isMapped is true, then
if (is_mapped) {
// a. Set desc.[[Value]] to Get(map, P).
desc->value = TRY(m_parameter_map->get(property_name));
desc->value = TRY(m_parameter_map->get(property_key));
}
// 6. Return desc.
@ -130,13 +130,13 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> ArgumentsObject::internal_get_ow
}
// 10.4.4.2 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-arguments-exotic-objects-defineownproperty-p-desc
ThrowCompletionOr<bool> ArgumentsObject::internal_define_own_property(PropertyKey const& property_name, PropertyDescriptor const& descriptor)
ThrowCompletionOr<bool> ArgumentsObject::internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& descriptor)
{
// 1. Let map be args.[[ParameterMap]].
auto& map = parameter_map();
// 2. Let isMapped be HasOwnProperty(map, P).
bool is_mapped = MUST(map.has_own_property(property_name));
bool is_mapped = MUST(map.has_own_property(property_key));
// 3. Let newArgDesc be Desc.
auto new_arg_desc = descriptor;
@ -148,12 +148,12 @@ ThrowCompletionOr<bool> ArgumentsObject::internal_define_own_property(PropertyKe
// i. Set newArgDesc to a copy of Desc.
new_arg_desc = descriptor;
// ii. Set newArgDesc.[[Value]] to Get(map, P).
new_arg_desc.value = TRY(map.get(property_name));
new_arg_desc.value = TRY(map.get(property_key));
}
}
// 5. Let allowed be ? OrdinaryDefineOwnProperty(args, P, newArgDesc).
bool allowed = TRY(Object::internal_define_own_property(property_name, new_arg_desc));
bool allowed = TRY(Object::internal_define_own_property(property_key, new_arg_desc));
// 6. If allowed is false, return false.
if (!allowed)
@ -164,12 +164,12 @@ ThrowCompletionOr<bool> ArgumentsObject::internal_define_own_property(PropertyKe
// a. If IsAccessorDescriptor(Desc) is true, then
if (descriptor.is_accessor_descriptor()) {
// i. Call map.[[Delete]](P).
MUST(map.internal_delete(property_name));
MUST(map.internal_delete(property_key));
} else {
// i. If Desc.[[Value]] is present, then
if (descriptor.value.has_value()) {
// 1. Let setStatus be Set(map, P, Desc.[[Value]], false).
bool set_status = MUST(map.set(property_name, descriptor.value.value(), Object::ShouldThrowExceptions::No));
bool set_status = MUST(map.set(property_key, descriptor.value.value(), Object::ShouldThrowExceptions::No));
// 2. Assert: setStatus is true because formal parameters mapped by argument objects are always writable.
VERIFY(set_status);
@ -177,7 +177,7 @@ ThrowCompletionOr<bool> ArgumentsObject::internal_define_own_property(PropertyKe
// ii. If Desc.[[Writable]] is present and its value is false, then
if (descriptor.writable == false) {
// 1. Call map.[[Delete]](P).
MUST(map.internal_delete(property_name));
MUST(map.internal_delete(property_key));
}
}
}

View file

@ -151,31 +151,31 @@ ThrowCompletionOr<bool> Array::set_length(PropertyDescriptor const& property_des
}
// NON-STANDARD: Used to return the value of the ephemeral length property
ThrowCompletionOr<Optional<PropertyDescriptor>> Array::internal_get_own_property(PropertyKey const& property_name) const
ThrowCompletionOr<Optional<PropertyDescriptor>> Array::internal_get_own_property(PropertyKey const& property_key) const
{
auto& vm = this->vm();
if (property_name.is_string() && property_name.as_string() == vm.names.length.as_string())
if (property_key.is_string() && property_key.as_string() == vm.names.length.as_string())
return PropertyDescriptor { .value = Value(indexed_properties().array_like_size()), .writable = m_length_writable, .enumerable = false, .configurable = false };
return Object::internal_get_own_property(property_name);
return Object::internal_get_own_property(property_key);
}
// 10.4.2.1 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-array-exotic-objects-defineownproperty-p-desc
ThrowCompletionOr<bool> Array::internal_define_own_property(PropertyKey const& property_name, PropertyDescriptor const& property_descriptor)
ThrowCompletionOr<bool> Array::internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& property_descriptor)
{
auto& vm = this->vm();
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 2. If P is "length", then
if (property_name.is_string() && property_name.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).
return set_length(property_descriptor);
}
// 3. Else if P is an array index, then
if (property_name.is_number()) {
if (property_key.is_number()) {
// a. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
// b. Assert: ! IsDataDescriptor(oldLenDesc) is true.
// c. Assert: oldLenDesc.[[Configurable]] is false.
@ -184,11 +184,11 @@ ThrowCompletionOr<bool> Array::internal_define_own_property(PropertyKey const& p
// f. Let index be ! ToUint32(P).
// g. If index ≥ oldLen and oldLenDesc.[[Writable]] is false, return false.
if (property_name.as_number() >= indexed_properties().array_like_size() && !m_length_writable)
if (property_key.as_number() >= indexed_properties().array_like_size() && !m_length_writable)
return false;
// h. Let succeeded be ! OrdinaryDefineOwnProperty(A, P, Desc).
auto succeeded = MUST(Object::internal_define_own_property(property_name, property_descriptor));
auto succeeded = MUST(Object::internal_define_own_property(property_key, property_descriptor));
// i. If succeeded is false, return false.
if (!succeeded)
@ -204,16 +204,16 @@ ThrowCompletionOr<bool> Array::internal_define_own_property(PropertyKey const& p
}
// 4. Return OrdinaryDefineOwnProperty(A, P, Desc).
return Object::internal_define_own_property(property_name, property_descriptor);
return Object::internal_define_own_property(property_key, property_descriptor);
}
// NON-STANDARD: Used to reject deletes to ephemeral (non-configurable) length property
ThrowCompletionOr<bool> Array::internal_delete(PropertyKey const& property_name)
ThrowCompletionOr<bool> Array::internal_delete(PropertyKey const& property_key)
{
auto& vm = this->vm();
if (property_name.is_string() && property_name.as_string() == vm.names.length.as_string())
if (property_key.is_string() && property_key.as_string() == vm.names.length.as_string())
return false;
return Object::internal_delete(property_name);
return Object::internal_delete(property_key);
}
// NON-STANDARD: Used to inject the ephemeral length property's key

View file

@ -173,10 +173,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::filter)
// 7. Repeat, while k < len,
for (; k < length; ++k) {
// a. Let Pk be ! ToString(𝔽(k)).
auto property_name = PropertyKey { k };
auto property_key = PropertyKey { k };
// b. Let kPresent be ? HasProperty(O, Pk).
auto k_present = TRY(object->has_property(property_name));
auto k_present = TRY(object->has_property(property_key));
// c. If kPresent is true, then
if (k_present) {
@ -223,15 +223,15 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::for_each)
// 5. Repeat, while k < len,
for (size_t k = 0; k < length; ++k) {
// a. Let Pk be ! ToString(𝔽(k)).
auto property_name = PropertyKey { k };
auto property_key = PropertyKey { k };
// b. Let kPresent be ? HasProperty(O, Pk).
auto k_present = TRY(object->has_property(property_name));
auto k_present = TRY(object->has_property(property_key));
// c. If kPresent is true, then
if (k_present) {
// i. Let kValue be ? Get(O, Pk).
auto k_value = TRY(object->get(property_name));
auto k_value = TRY(object->get(property_key));
// ii. Perform ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »).
TRY(call(global_object, callback_function.as_function(), this_arg, k_value, Value(k), object));
@ -267,21 +267,21 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::map)
// 6. Repeat, while k < len,
for (size_t k = 0; k < length; ++k) {
// a. Let Pk be ! ToString(𝔽(k)).
auto property_name = PropertyKey { k };
auto property_key = PropertyKey { k };
// b. Let kPresent be ? HasProperty(O, Pk).
auto k_present = TRY(object->has_property(property_name));
auto k_present = TRY(object->has_property(property_key));
// c. If kPresent is true, then
if (k_present) {
// i. Let kValue be ? Get(O, Pk).
auto k_value = TRY(object->get(property_name));
auto k_value = TRY(object->get(property_key));
// ii. Let mappedValue be ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »).
auto mapped_value = TRY(call(global_object, callback_function.as_function(), this_arg, k_value, Value(k), object));
// iii. Perform ? CreateDataPropertyOrThrow(A, Pk, mappedValue).
TRY(array->create_data_property_or_throw(property_name, mapped_value));
TRY(array->create_data_property_or_throw(property_key, mapped_value));
}
// d. Set k to k + 1.
@ -640,15 +640,15 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::index_of)
// 10. Repeat, while k < len,
for (; k < length; ++k) {
auto property_name = PropertyKey { k };
auto property_key = PropertyKey { k };
// a. Let kPresent be ? HasProperty(O, ! ToString(𝔽(k))).
auto k_present = TRY(object->has_property(property_name));
auto k_present = TRY(object->has_property(property_key));
// b. If kPresent is true, then
if (k_present) {
// i. Let elementK be ? Get(O, ! ToString(𝔽(k))).
auto element_k = TRY(object->get(property_name));
auto element_k = TRY(object->get(property_key));
// ii. Let same be IsStrictlyEqual(searchElement, elementK).
auto same = is_strictly_equal(search_element, element_k);
@ -704,15 +704,15 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce)
// b. Repeat, while kPresent is false and k < len,
for (; !k_present && k < length; ++k) {
// i. Let Pk be ! ToString(𝔽(k)).
auto property_name = PropertyKey { k };
auto property_key = PropertyKey { k };
// ii. Set kPresent to ? HasProperty(O, Pk).
k_present = TRY(object->has_property(property_name));
k_present = TRY(object->has_property(property_key));
// iii. If kPresent is true, then
if (k_present) {
// 1. Set accumulator to ? Get(O, Pk).
accumulator = TRY(object->get(property_name));
accumulator = TRY(object->get(property_key));
}
// iv. Set k to k + 1.
@ -726,15 +726,15 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce)
// 9. Repeat, while k < len,
for (; k < length; ++k) {
// a. Let Pk be ! ToString(𝔽(k)).
auto property_name = PropertyKey { k };
auto property_key = PropertyKey { k };
// b. Let kPresent be ? HasProperty(O, Pk).
auto k_present = TRY(object->has_property(property_name));
auto k_present = TRY(object->has_property(property_key));
// c. If kPresent is true, then
if (k_present) {
// i. Let kValue be ? Get(O, Pk).
auto k_value = TRY(object->get(property_name));
auto k_value = TRY(object->get(property_key));
// ii. Set accumulator to ? Call(callbackfn, undefined, « accumulator, kValue, 𝔽(k), O »).
accumulator = TRY(call(global_object, callback_function.as_function(), js_undefined(), accumulator, k_value, Value(k), object));
@ -786,15 +786,15 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce_right)
// b. Repeat, while kPresent is false and k ≥ 0,
for (; !k_present && k >= 0; --k) {
// i. Let Pk be ! ToString(𝔽(k)).
auto property_name = PropertyKey { k };
auto property_key = PropertyKey { k };
// ii. Set kPresent to ? HasProperty(O, Pk).
k_present = TRY(object->has_property(property_name));
k_present = TRY(object->has_property(property_key));
// iii. If kPresent is true, then
if (k_present) {
// 1. Set accumulator to ? Get(O, Pk).
accumulator = TRY(object->get(property_name));
accumulator = TRY(object->get(property_key));
}
// iv. Set k to k - 1.
@ -808,15 +808,15 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce_right)
// 9. Repeat, while k ≥ 0,
for (; k >= 0; --k) {
// a. Let Pk be ! ToString(𝔽(k)).
auto property_name = PropertyKey { k };
auto property_key = PropertyKey { k };
// b. Let kPresent be ? HasProperty(O, Pk).
auto k_present = TRY(object->has_property(property_name));
auto k_present = TRY(object->has_property(property_key));
// c. If kPresent is true, then
if (k_present) {
// i. Let kValue be ? Get(O, Pk).
auto k_value = TRY(object->get(property_name));
auto k_value = TRY(object->get(property_key));
// ii. Set accumulator to ? Call(callbackfn, undefined, « accumulator, kValue, 𝔽(k), O »).
accumulator = TRY(call(global_object, callback_function.as_function(), js_undefined(), accumulator, k_value, Value((size_t)k), object));
@ -1044,15 +1044,15 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::last_index_of)
// 8. Repeat, while k ≥ 0,
for (; k >= 0; --k) {
auto property_name = PropertyKey { k };
auto property_key = PropertyKey { k };
// a. Let kPresent be ? HasProperty(O, ! ToString(𝔽(k))).
auto k_present = TRY(object->has_property(property_name));
auto k_present = TRY(object->has_property(property_key));
// b. If kPresent is true, then
if (k_present) {
// i. Let elementK be ? Get(O, ! ToString(𝔽(k))).
auto element_k = TRY(object->get(property_name));
auto element_k = TRY(object->get(property_key));
// ii. Let same be IsStrictlyEqual(searchElement, elementK).
auto same = is_strictly_equal(search_element, element_k);
@ -1120,10 +1120,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find)
// 5. Repeat, while k < len,
for (size_t k = 0; k < length; ++k) {
// a. Let Pk be ! ToString(𝔽(k)).
auto property_name = PropertyKey { k };
auto property_key = PropertyKey { k };
// b. Let kValue be ? Get(O, Pk).
auto k_value = TRY(object->get(property_name));
auto k_value = TRY(object->get(property_key));
// c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)).
auto test_result = TRY(call(global_object, predicate.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
@ -1159,10 +1159,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_index)
// 5. Repeat, while k < len,
for (size_t k = 0; k < length; ++k) {
// a. Let Pk be ! ToString(𝔽(k)).
auto property_name = PropertyKey { k };
auto property_key = PropertyKey { k };
// b. Let kValue be ? Get(O, Pk).
auto k_value = TRY(object->get(property_name));
auto k_value = TRY(object->get(property_key));
// c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)).
auto test_result = TRY(call(global_object, predicate.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
@ -1198,10 +1198,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_last)
// 5. Repeat, while k ≥ 0,
for (i64 k = static_cast<i64>(length) - 1; k >= 0; --k) {
// a. Let Pk be ! ToString(𝔽(k)).
auto property_name = PropertyKey { k };
auto property_key = PropertyKey { k };
// b. Let kValue be ? Get(O, Pk).
auto k_value = TRY(object->get(property_name));
auto k_value = TRY(object->get(property_key));
// c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)).
auto test_result = TRY(call(global_object, predicate.as_function(), this_arg, k_value, Value((double)k), object)).to_boolean();
@ -1237,10 +1237,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_last_index)
// 5. Repeat, while k ≥ 0,
for (i64 k = static_cast<i64>(length) - 1; k >= 0; --k) {
// a. Let Pk be ! ToString(𝔽(k)).
auto property_name = PropertyKey { k };
auto property_key = PropertyKey { k };
// b. Let kValue be ? Get(O, Pk).
auto k_value = TRY(object->get(property_name));
auto k_value = TRY(object->get(property_key));
// c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)).
auto test_result = TRY(call(global_object, predicate.as_function(), this_arg, k_value, Value((double)k), object)).to_boolean();
@ -1276,15 +1276,15 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::some)
// 5. Repeat, while k < len,
for (size_t k = 0; k < length; ++k) {
// a. Let Pk be ! ToString(𝔽(k)).
auto property_name = PropertyKey { k };
auto property_key = PropertyKey { k };
// b. Let kPresent be ? HasProperty(O, Pk).
auto k_present = TRY(object->has_property(property_name));
auto k_present = TRY(object->has_property(property_key));
// c. If kPresent is true, then
if (k_present) {
// i. Let kValue be ? Get(O, Pk).
auto k_value = TRY(object->get(property_name));
auto k_value = TRY(object->get(property_key));
// ii. Let testResult be ! ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
auto test_result = TRY(call(global_object, callback_function.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
@ -1321,15 +1321,15 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::every)
// 5. Repeat, while k < len,
for (size_t k = 0; k < length; ++k) {
// a. Let Pk be ! ToString(𝔽(k)).
auto property_name = PropertyKey { k };
auto property_key = PropertyKey { k };
// b. Let kPresent be ? HasProperty(O, Pk).
auto k_present = TRY(object->has_property(property_name));
auto k_present = TRY(object->has_property(property_key));
// c. If kPresent is true, then
if (k_present) {
// i. Let kValue be ? Get(O, Pk).
auto k_value = TRY(object->get(property_name));
auto k_value = TRY(object->get(property_key));
// ii. Let testResult be ! ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
auto test_result = TRY(call(global_object, callback_function.as_function(), this_arg, k_value, Value(k), object)).to_boolean();

View file

@ -297,8 +297,8 @@ void ECMAScriptFunctionObject::visit_edges(Visitor& visitor)
visitor.visit(m_home_object);
for (auto& field : m_fields) {
if (auto* property_name_ptr = field.name.get_pointer<PropertyKey>(); property_name_ptr && property_name_ptr->is_symbol())
visitor.visit(property_name_ptr->as_symbol());
if (auto* property_key_ptr = field.name.get_pointer<PropertyKey>(); property_key_ptr && property_key_ptr->is_symbol())
visitor.visit(property_key_ptr->as_symbol());
visitor.visit(field.initializer);
}

View file

@ -143,22 +143,22 @@ private:
};
template<typename ConstructorType>
inline void GlobalObject::initialize_constructor(PropertyKey const& property_name, ConstructorType*& constructor, Object* prototype)
inline void GlobalObject::initialize_constructor(PropertyKey const& property_key, ConstructorType*& constructor, Object* prototype)
{
auto& vm = this->vm();
constructor = heap().allocate<ConstructorType>(*this, *this);
constructor->define_direct_property(vm.names.name, js_string(heap(), property_name.as_string()), Attribute::Configurable);
constructor->define_direct_property(vm.names.name, js_string(heap(), property_key.as_string()), Attribute::Configurable);
if (prototype)
prototype->define_direct_property(vm.names.constructor, constructor, Attribute::Writable | Attribute::Configurable);
}
template<typename ConstructorType>
inline void GlobalObject::add_constructor(PropertyKey const& property_name, ConstructorType*& constructor, Object* prototype)
inline void GlobalObject::add_constructor(PropertyKey const& property_key, ConstructorType*& constructor, Object* prototype)
{
// Some constructors are pre-initialized separately.
if (!constructor)
initialize_constructor(property_name, constructor, prototype);
define_direct_property(property_name, constructor, Attribute::Writable | Attribute::Configurable);
initialize_constructor(property_key, constructor, prototype);
define_direct_property(property_key, constructor, Attribute::Writable | Attribute::Configurable);
}
inline GlobalObject* Shape::global_object() const
@ -170,15 +170,15 @@ template<>
inline bool Object::fast_is<GlobalObject>() const { return is_global_object(); }
template<typename... Args>
[[nodiscard]] ALWAYS_INLINE ThrowCompletionOr<Value> Value::invoke(GlobalObject& global_object, PropertyKey const& property_name, Args... args)
[[nodiscard]] ALWAYS_INLINE ThrowCompletionOr<Value> Value::invoke(GlobalObject& global_object, PropertyKey const& property_key, Args... args)
{
if constexpr (sizeof...(Args) > 0) {
MarkedValueList arglist { global_object.vm().heap() };
(..., arglist.append(move(args)));
return invoke_internal(global_object, property_name, move(arglist));
return invoke_internal(global_object, property_key, move(arglist));
}
return invoke_internal(global_object, property_name, Optional<MarkedValueList> {});
return invoke_internal(global_object, property_key, Optional<MarkedValueList> {});
}
}

View file

@ -427,8 +427,8 @@ ThrowCompletionOr<Value> JSONObject::internalize_json_property(GlobalObject& glo
TRY(process_property(i));
} else {
auto property_list = TRY(value_object.enumerable_own_property_names(Object::PropertyKind::Key));
for (auto& property_name : property_list)
TRY(process_property(property_name.as_string().string()));
for (auto& property_key : property_list)
TRY(process_property(property_key.as_string().string()));
}
}

View file

@ -77,21 +77,21 @@ ThrowCompletionOr<bool> Object::is_extensible() const
// 7.3 Operations on Objects, https://tc39.es/ecma262/#sec-operations-on-objects
// 7.3.2 Get ( O, P ), https://tc39.es/ecma262/#sec-get-o-p
ThrowCompletionOr<Value> Object::get(PropertyKey const& property_name) const
ThrowCompletionOr<Value> Object::get(PropertyKey const& property_key) const
{
// 1. Assert: Type(O) is Object.
// 2. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 3. Return ? O.[[Get]](P, O).
return TRY(internal_get(property_name, this));
return TRY(internal_get(property_key, this));
}
// NOTE: 7.3.3 GetV ( V, P ) is implemented as Value::get().
// 7.3.4 Set ( O, P, V, Throw ), https://tc39.es/ecma262/#sec-set-o-p-v-throw
ThrowCompletionOr<bool> Object::set(PropertyKey const& property_name, Value value, ShouldThrowExceptions throw_exceptions)
ThrowCompletionOr<bool> Object::set(PropertyKey const& property_key, Value value, ShouldThrowExceptions throw_exceptions)
{
VERIFY(!value.is_empty());
auto& vm = this->vm();
@ -99,12 +99,12 @@ ThrowCompletionOr<bool> Object::set(PropertyKey const& property_name, Value valu
// 1. Assert: Type(O) is Object.
// 2. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 3. Assert: Type(Throw) is Boolean.
// 4. Let success be ? O.[[Set]](P, V, O).
auto success = TRY(internal_set(property_name, value, this));
auto success = TRY(internal_set(property_key, value, this));
// 5. If success is false and Throw is true, throw a TypeError exception.
if (!success && throw_exceptions == ShouldThrowExceptions::Yes) {
@ -117,12 +117,12 @@ ThrowCompletionOr<bool> Object::set(PropertyKey const& property_name, Value valu
}
// 7.3.5 CreateDataProperty ( O, P, V ), https://tc39.es/ecma262/#sec-createdataproperty
ThrowCompletionOr<bool> Object::create_data_property(PropertyKey const& property_name, Value value)
ThrowCompletionOr<bool> Object::create_data_property(PropertyKey const& property_key, Value value)
{
// 1. Assert: Type(O) is Object.
// 2. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 3. Let newDesc be the PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }.
auto new_descriptor = PropertyDescriptor {
@ -133,18 +133,18 @@ ThrowCompletionOr<bool> Object::create_data_property(PropertyKey const& property
};
// 4. Return ? O.[[DefineOwnProperty]](P, newDesc).
return internal_define_own_property(property_name, new_descriptor);
return internal_define_own_property(property_key, new_descriptor);
}
// 7.3.6 CreateMethodProperty ( O, P, V ), https://tc39.es/ecma262/#sec-createmethodproperty
ThrowCompletionOr<bool> Object::create_method_property(PropertyKey const& property_name, Value value)
ThrowCompletionOr<bool> Object::create_method_property(PropertyKey const& property_key, Value value)
{
VERIFY(!value.is_empty());
// 1. Assert: Type(O) is Object.
// 2. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 3. Let newDesc be the PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }.
auto new_descriptor = PropertyDescriptor {
@ -155,11 +155,11 @@ ThrowCompletionOr<bool> Object::create_method_property(PropertyKey const& proper
};
// 4. Return ? O.[[DefineOwnProperty]](P, newDesc).
return internal_define_own_property(property_name, new_descriptor);
return internal_define_own_property(property_key, new_descriptor);
}
// 7.3.7 CreateDataPropertyOrThrow ( O, P, V ), https://tc39.es/ecma262/#sec-createdatapropertyorthrow
ThrowCompletionOr<bool> Object::create_data_property_or_throw(PropertyKey const& property_name, Value value)
ThrowCompletionOr<bool> Object::create_data_property_or_throw(PropertyKey const& property_key, Value value)
{
VERIFY(!value.is_empty());
auto& vm = this->vm();
@ -167,10 +167,10 @@ ThrowCompletionOr<bool> Object::create_data_property_or_throw(PropertyKey const&
// 1. Assert: Type(O) is Object.
// 2. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 3. Let success be ? CreateDataProperty(O, P, V).
auto success = TRY(create_data_property(property_name, value));
auto success = TRY(create_data_property(property_key, value));
// 4. If success is false, throw a TypeError exception.
if (!success) {
@ -183,30 +183,30 @@ ThrowCompletionOr<bool> Object::create_data_property_or_throw(PropertyKey const&
}
// 7.3.8 CreateNonEnumerableDataPropertyOrThrow ( O, P, V ), https://tc39.es/ecma262/#sec-createnonenumerabledatapropertyorthrow
ThrowCompletionOr<bool> Object::create_non_enumerable_data_property_or_throw(PropertyKey const& property_name, Value value)
ThrowCompletionOr<bool> Object::create_non_enumerable_data_property_or_throw(PropertyKey const& property_key, Value value)
{
VERIFY(!value.is_empty());
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 1. Let newDesc be the PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }.
auto new_description = PropertyDescriptor { .value = value, .writable = true, .enumerable = false, .configurable = true };
// 2. Return ? DefinePropertyOrThrow(O, P, newDesc).
return define_property_or_throw(property_name, new_description);
return define_property_or_throw(property_key, new_description);
}
// 7.3.9 DefinePropertyOrThrow ( O, P, desc ), https://tc39.es/ecma262/#sec-definepropertyorthrow
ThrowCompletionOr<bool> Object::define_property_or_throw(PropertyKey const& property_name, PropertyDescriptor const& property_descriptor)
ThrowCompletionOr<bool> Object::define_property_or_throw(PropertyKey const& property_key, PropertyDescriptor const& property_descriptor)
{
auto& vm = this->vm();
// 1. Assert: Type(O) is Object.
// 2. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 3. Let success be ? O.[[DefineOwnProperty]](P, desc).
auto success = TRY(internal_define_own_property(property_name, property_descriptor));
auto success = TRY(internal_define_own_property(property_key, property_descriptor));
// 4. If success is false, throw a TypeError exception.
if (!success) {
@ -219,17 +219,17 @@ ThrowCompletionOr<bool> Object::define_property_or_throw(PropertyKey const& prop
}
// 7.3.10 DeletePropertyOrThrow ( O, P ), https://tc39.es/ecma262/#sec-deletepropertyorthrow
ThrowCompletionOr<bool> Object::delete_property_or_throw(PropertyKey const& property_name)
ThrowCompletionOr<bool> Object::delete_property_or_throw(PropertyKey const& property_key)
{
auto& vm = this->vm();
// 1. Assert: Type(O) is Object.
// 2. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 3. Let success be ? O.[[Delete]](P).
auto success = TRY(internal_delete(property_name));
auto success = TRY(internal_delete(property_key));
// 4. If success is false, throw a TypeError exception.
if (!success) {
@ -242,27 +242,27 @@ ThrowCompletionOr<bool> 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_name) const
ThrowCompletionOr<bool> Object::has_property(PropertyKey const& property_key) const
{
// 1. Assert: Type(O) is Object.
// 2. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 3. Return ? O.[[HasProperty]](P).
return internal_has_property(property_name);
return internal_has_property(property_key);
}
// 7.3.13 HasOwnProperty ( O, P ), https://tc39.es/ecma262/#sec-hasownproperty
ThrowCompletionOr<bool> Object::has_own_property(PropertyKey const& property_name) const
ThrowCompletionOr<bool> Object::has_own_property(PropertyKey const& property_key) const
{
// 1. Assert: Type(O) is Object.
// 2. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 3. Let desc be ? O.[[GetOwnProperty]](P).
auto descriptor = TRY(internal_get_own_property(property_name));
auto descriptor = TRY(internal_get_own_property(property_key));
// 4. If desc is undefined, return false.
if (!descriptor.has_value())
@ -296,10 +296,10 @@ ThrowCompletionOr<bool> Object::set_integrity_level(IntegrityLevel level)
if (level == IntegrityLevel::Sealed) {
// a. For each element k of keys, do
for (auto& key : keys) {
auto property_name = MUST(PropertyKey::from_value(global_object, key));
auto property_key = MUST(PropertyKey::from_value(global_object, key));
// i. Perform ? DefinePropertyOrThrow(O, k, PropertyDescriptor { [[Configurable]]: false }).
TRY(define_property_or_throw(property_name, { .configurable = false }));
TRY(define_property_or_throw(property_key, { .configurable = false }));
}
}
// 7. Else,
@ -308,10 +308,10 @@ ThrowCompletionOr<bool> Object::set_integrity_level(IntegrityLevel level)
// b. For each element k of keys, do
for (auto& key : keys) {
auto property_name = MUST(PropertyKey::from_value(global_object, key));
auto property_key = MUST(PropertyKey::from_value(global_object, key));
// i. Let currentDesc be ? O.[[GetOwnProperty]](k).
auto current_descriptor = TRY(internal_get_own_property(property_name));
auto current_descriptor = TRY(internal_get_own_property(property_key));
// ii. If currentDesc is not undefined, then
if (!current_descriptor.has_value())
@ -331,7 +331,7 @@ ThrowCompletionOr<bool> Object::set_integrity_level(IntegrityLevel level)
}
// 3. Perform ? DefinePropertyOrThrow(O, k, desc).
TRY(define_property_or_throw(property_name, descriptor));
TRY(define_property_or_throw(property_key, descriptor));
}
}
@ -360,10 +360,10 @@ ThrowCompletionOr<bool> Object::test_integrity_level(IntegrityLevel level) const
// 7. For each element k of keys, do
for (auto& key : keys) {
auto property_name = MUST(PropertyKey::from_value(global_object(), key));
auto property_key = MUST(PropertyKey::from_value(global_object(), key));
// a. Let currentDesc be ? O.[[GetOwnProperty]](k).
auto current_descriptor = TRY(internal_get_own_property(property_name));
auto current_descriptor = TRY(internal_get_own_property(property_key));
// b. If currentDesc is not undefined, then
if (!current_descriptor.has_value())
@ -405,10 +405,10 @@ ThrowCompletionOr<MarkedValueList> Object::enumerable_own_property_names(Propert
// a. If Type(key) is String, then
if (!key.is_string())
continue;
auto property_name = MUST(PropertyKey::from_value(global_object, key));
auto property_key = MUST(PropertyKey::from_value(global_object, key));
// i. Let desc be ? O.[[GetOwnProperty]](key).
auto descriptor = TRY(internal_get_own_property(property_name));
auto descriptor = TRY(internal_get_own_property(property_key));
// ii. If desc is not undefined and desc.[[Enumerable]] is true, then
if (descriptor.has_value() && *descriptor->enumerable) {
@ -420,7 +420,7 @@ ThrowCompletionOr<MarkedValueList> Object::enumerable_own_property_names(Propert
// 2. Else,
// a. Let value be ? Get(O, key).
auto value = TRY(get(property_name));
auto value = TRY(get(property_key));
// b. If kind is value, append value to properties.
if (kind == PropertyKind::Value) {
@ -560,8 +560,8 @@ ThrowCompletionOr<void> Object::define_field(Variant<PropertyKey, PrivateName> n
if (initializer)
init_value = TRY(call(global_object(), *initializer, this));
if (auto* property_name_ptr = name.get_pointer<PropertyKey>())
TRY(create_data_property_or_throw(*property_name_ptr, init_value));
if (auto* property_key_ptr = name.get_pointer<PropertyKey>())
TRY(create_data_property_or_throw(*property_key_ptr, init_value));
else
TRY(private_field_add(name.get<PrivateName>(), init_value));
@ -641,13 +641,13 @@ 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
ThrowCompletionOr<Optional<PropertyDescriptor>> Object::internal_get_own_property(PropertyKey const& property_name) const
ThrowCompletionOr<Optional<PropertyDescriptor>> Object::internal_get_own_property(PropertyKey const& property_key) const
{
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 2. If O does not have an own property with key P, return undefined.
auto maybe_storage_entry = storage_get(property_name);
auto maybe_storage_entry = storage_get(property_key);
if (!maybe_storage_entry.has_value())
return Optional<PropertyDescriptor> {};
@ -687,27 +687,27 @@ 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
ThrowCompletionOr<bool> Object::internal_define_own_property(PropertyKey const& property_name, PropertyDescriptor const& property_descriptor)
ThrowCompletionOr<bool> Object::internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& property_descriptor)
{
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 1. Let current be ? O.[[GetOwnProperty]](P).
auto current = TRY(internal_get_own_property(property_name));
auto current = TRY(internal_get_own_property(property_key));
// 2. Let extensible be ? IsExtensible(O).
auto extensible = TRY(is_extensible());
// 3. Return ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc, current).
return validate_and_apply_property_descriptor(this, property_name, extensible, property_descriptor, current);
return validate_and_apply_property_descriptor(this, property_key, extensible, property_descriptor, current);
}
// 10.1.7 [[HasProperty]] ( P ), https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-hasproperty-p
ThrowCompletionOr<bool> Object::internal_has_property(PropertyKey const& property_name) const
ThrowCompletionOr<bool> Object::internal_has_property(PropertyKey const& property_key) const
{
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 2. Let hasOwn be ? O.[[GetOwnProperty]](P).
auto has_own = TRY(internal_get_own_property(property_name));
auto has_own = TRY(internal_get_own_property(property_key));
// 3. If hasOwn is not undefined, return true.
if (has_own.has_value())
@ -719,7 +719,7 @@ ThrowCompletionOr<bool> Object::internal_has_property(PropertyKey const& propert
// 5. If parent is not null, then
if (parent) {
// a. Return ? parent.[[HasProperty]](P).
return parent->internal_has_property(property_name);
return parent->internal_has_property(property_key);
}
// 6. Return false.
@ -727,15 +727,15 @@ 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
ThrowCompletionOr<Value> Object::internal_get(PropertyKey const& property_name, Value receiver) const
ThrowCompletionOr<Value> Object::internal_get(PropertyKey const& property_key, Value receiver) const
{
VERIFY(!receiver.is_empty());
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 2. Let desc be ? O.[[GetOwnProperty]](P).
auto descriptor = TRY(internal_get_own_property(property_name));
auto descriptor = TRY(internal_get_own_property(property_key));
// 3. If desc is undefined, then
if (!descriptor.has_value()) {
@ -747,7 +747,7 @@ ThrowCompletionOr<Value> Object::internal_get(PropertyKey const& property_name,
return js_undefined();
// c. Return ? parent.[[Get]](P, Receiver).
return parent->internal_get(property_name, receiver);
return parent->internal_get(property_key, receiver);
}
// 4. If IsDataDescriptor(desc) is true, return desc.[[Value]].
@ -769,26 +769,26 @@ ThrowCompletionOr<Value> Object::internal_get(PropertyKey const& property_name,
}
// 10.1.9 [[Set]] ( P, V, Receiver ), https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-set-p-v-receiver
ThrowCompletionOr<bool> Object::internal_set(PropertyKey const& property_name, Value value, Value receiver)
ThrowCompletionOr<bool> Object::internal_set(PropertyKey const& property_key, Value value, Value receiver)
{
VERIFY(!value.is_empty());
VERIFY(!receiver.is_empty());
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 2. Let ownDesc be ? O.[[GetOwnProperty]](P).
auto own_descriptor = TRY(internal_get_own_property(property_name));
auto own_descriptor = TRY(internal_get_own_property(property_key));
// 3. Return OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc).
return ordinary_set_with_own_descriptor(property_name, value, receiver, own_descriptor);
return ordinary_set_with_own_descriptor(property_key, value, receiver, own_descriptor);
}
// 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_name, Value value, Value receiver, Optional<PropertyDescriptor> own_descriptor)
ThrowCompletionOr<bool> Object::ordinary_set_with_own_descriptor(PropertyKey const& property_key, Value value, Value receiver, Optional<PropertyDescriptor> own_descriptor)
{
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 2. If ownDesc is undefined, then
if (!own_descriptor.has_value()) {
@ -798,7 +798,7 @@ ThrowCompletionOr<bool> Object::ordinary_set_with_own_descriptor(PropertyKey con
// b. If parent is not null, then
if (parent) {
// i. Return ? parent.[[Set]](P, V, Receiver).
return TRY(parent->internal_set(property_name, value, receiver));
return TRY(parent->internal_set(property_key, value, receiver));
}
// c. Else,
else {
@ -823,7 +823,7 @@ ThrowCompletionOr<bool> Object::ordinary_set_with_own_descriptor(PropertyKey con
return false;
// c. Let existingDescriptor be ? Receiver.[[GetOwnProperty]](P).
auto existing_descriptor = TRY(receiver.as_object().internal_get_own_property(property_name));
auto existing_descriptor = TRY(receiver.as_object().internal_get_own_property(property_key));
// d. If existingDescriptor is not undefined, then
if (existing_descriptor.has_value()) {
@ -839,15 +839,15 @@ ThrowCompletionOr<bool> Object::ordinary_set_with_own_descriptor(PropertyKey con
auto value_descriptor = PropertyDescriptor { .value = value };
// iv. Return ? Receiver.[[DefineOwnProperty]](P, valueDesc).
return TRY(receiver.as_object().internal_define_own_property(property_name, value_descriptor));
return TRY(receiver.as_object().internal_define_own_property(property_key, value_descriptor));
}
// e. Else,
else {
// i. Assert: Receiver does not currently have a property P.
VERIFY(!receiver.as_object().storage_has(property_name));
VERIFY(!receiver.as_object().storage_has(property_key));
// ii. Return ? CreateDataProperty(Receiver, P, V).
return TRY(receiver.as_object().create_data_property(property_name, value));
return TRY(receiver.as_object().create_data_property(property_key, value));
}
}
@ -869,13 +869,13 @@ 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
ThrowCompletionOr<bool> Object::internal_delete(PropertyKey const& property_name)
ThrowCompletionOr<bool> Object::internal_delete(PropertyKey const& property_key)
{
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 2. Let desc be ? O.[[GetOwnProperty]](P).
auto descriptor = TRY(internal_get_own_property(property_name));
auto descriptor = TRY(internal_get_own_property(property_key));
// 3. If desc is undefined, return true.
if (!descriptor.has_value())
@ -884,7 +884,7 @@ ThrowCompletionOr<bool> Object::internal_delete(PropertyKey const& property_name
// 4. If desc.[[Configurable]] is true, then
if (*descriptor->configurable) {
// a. Remove the own property with name P from O.
storage_delete(property_name);
storage_delete(property_key);
// b. Return true.
return true;
@ -944,21 +944,21 @@ ThrowCompletionOr<bool> Object::set_immutable_prototype(Object* prototype)
return false;
}
Optional<ValueAndAttributes> Object::storage_get(PropertyKey const& property_name) const
Optional<ValueAndAttributes> Object::storage_get(PropertyKey const& property_key) const
{
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
Value value;
PropertyAttributes attributes;
if (property_name.is_number()) {
auto value_and_attributes = m_indexed_properties.get(property_name.as_number());
if (property_key.is_number()) {
auto value_and_attributes = m_indexed_properties.get(property_key.as_number());
if (!value_and_attributes.has_value())
return {};
value = value_and_attributes->value;
attributes = value_and_attributes->attributes;
} else {
auto metadata = shape().lookup(property_name.to_string_or_symbol());
auto metadata = shape().lookup(property_key.to_string_or_symbol());
if (!metadata.has_value())
return {};
value = m_storage[metadata->offset];
@ -967,28 +967,28 @@ Optional<ValueAndAttributes> Object::storage_get(PropertyKey const& property_nam
return ValueAndAttributes { .value = value, .attributes = attributes };
}
bool Object::storage_has(PropertyKey const& property_name) const
bool Object::storage_has(PropertyKey const& property_key) const
{
VERIFY(property_name.is_valid());
if (property_name.is_number())
return m_indexed_properties.has_index(property_name.as_number());
return shape().lookup(property_name.to_string_or_symbol()).has_value();
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();
}
void Object::storage_set(PropertyKey const& property_name, ValueAndAttributes const& value_and_attributes)
void Object::storage_set(PropertyKey const& property_key, ValueAndAttributes const& value_and_attributes)
{
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
auto [value, attributes] = value_and_attributes;
if (property_name.is_number()) {
auto index = property_name.as_number();
if (property_key.is_number()) {
auto index = property_key.as_number();
m_indexed_properties.put(index, value, attributes);
return;
}
auto property_name_string_or_symbol = property_name.to_string_or_symbol();
auto metadata = shape().lookup(property_name_string_or_symbol);
auto property_key_string_or_symbol = property_key.to_string_or_symbol();
auto metadata = shape().lookup(property_key_string_or_symbol);
if (!metadata.has_value()) {
if (!m_shape->is_unique() && shape().property_count() > 100) {
@ -998,9 +998,9 @@ void Object::storage_set(PropertyKey const& property_name, ValueAndAttributes co
}
if (m_shape->is_unique())
m_shape->add_property_to_unique_shape(property_name_string_or_symbol, attributes);
m_shape->add_property_to_unique_shape(property_key_string_or_symbol, attributes);
else
set_shape(*m_shape->create_put_transition(property_name_string_or_symbol, attributes));
set_shape(*m_shape->create_put_transition(property_key_string_or_symbol, attributes));
m_storage.append(value);
return;
@ -1008,28 +1008,28 @@ void Object::storage_set(PropertyKey const& property_name, ValueAndAttributes co
if (attributes != metadata->attributes) {
if (m_shape->is_unique())
m_shape->reconfigure_property_in_unique_shape(property_name_string_or_symbol, attributes);
m_shape->reconfigure_property_in_unique_shape(property_key_string_or_symbol, attributes);
else
set_shape(*m_shape->create_configure_transition(property_name_string_or_symbol, attributes));
set_shape(*m_shape->create_configure_transition(property_key_string_or_symbol, attributes));
}
m_storage[metadata->offset] = value;
}
void Object::storage_delete(PropertyKey const& property_name)
void Object::storage_delete(PropertyKey const& property_key)
{
VERIFY(property_name.is_valid());
VERIFY(storage_has(property_name));
VERIFY(property_key.is_valid());
VERIFY(storage_has(property_key));
if (property_name.is_number())
return m_indexed_properties.remove(property_name.as_number());
if (property_key.is_number())
return m_indexed_properties.remove(property_key.as_number());
auto metadata = shape().lookup(property_name.to_string_or_symbol());
auto metadata = shape().lookup(property_key.to_string_or_symbol());
VERIFY(metadata.has_value());
ensure_shape_is_unique();
shape().remove_property_from_unique_shape(property_name.to_string_or_symbol(), metadata->offset);
shape().remove_property_from_unique_shape(property_key.to_string_or_symbol(), metadata->offset);
m_storage.remove(metadata->offset);
}
@ -1044,43 +1044,43 @@ void Object::set_prototype(Object* new_prototype)
m_shape = shape.create_prototype_transition(new_prototype);
}
void Object::define_native_accessor(PropertyKey const& property_name, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> getter, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> setter, PropertyAttributes attribute)
void Object::define_native_accessor(PropertyKey const& property_key, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> getter, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> setter, PropertyAttributes attribute)
{
auto& vm = this->vm();
String formatted_property_name;
if (property_name.is_number()) {
formatted_property_name = property_name.to_string();
} else if (property_name.is_string()) {
formatted_property_name = property_name.as_string();
String formatted_property_key;
if (property_key.is_number()) {
formatted_property_key = property_key.to_string();
} else if (property_key.is_string()) {
formatted_property_key = property_key.as_string();
} else {
formatted_property_name = String::formatted("[{}]", property_name.as_symbol()->description());
formatted_property_key = String::formatted("[{}]", property_key.as_symbol()->description());
}
FunctionObject* getter_function = nullptr;
if (getter) {
auto name = String::formatted("get {}", formatted_property_name);
auto name = String::formatted("get {}", formatted_property_key);
getter_function = NativeFunction::create(global_object(), name, move(getter));
getter_function->define_direct_property(vm.names.length, Value(0), Attribute::Configurable);
getter_function->define_direct_property(vm.names.name, js_string(vm, name), Attribute::Configurable);
}
FunctionObject* setter_function = nullptr;
if (setter) {
auto name = String::formatted("set {}", formatted_property_name);
auto name = String::formatted("set {}", formatted_property_key);
setter_function = NativeFunction::create(global_object(), name, move(setter));
setter_function->define_direct_property(vm.names.length, Value(1), Attribute::Configurable);
setter_function->define_direct_property(vm.names.name, js_string(vm, name), Attribute::Configurable);
}
return define_direct_accessor(property_name, getter_function, setter_function, attribute);
return define_direct_accessor(property_key, getter_function, setter_function, attribute);
}
void Object::define_direct_accessor(PropertyKey const& property_name, FunctionObject* getter, FunctionObject* setter, PropertyAttributes attributes)
void Object::define_direct_accessor(PropertyKey const& property_key, FunctionObject* getter, FunctionObject* setter, PropertyAttributes attributes)
{
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
auto existing_property = storage_get(property_name).value_or({}).value;
auto existing_property = storage_get(property_key).value_or({}).value;
auto* accessor = existing_property.is_accessor() ? &existing_property.as_accessor() : nullptr;
if (!accessor) {
accessor = Accessor::create(vm(), getter, setter);
define_direct_property(property_name, accessor, attributes);
define_direct_property(property_key, accessor, attributes);
} else {
if (getter)
accessor->set_getter(getter);
@ -1098,11 +1098,11 @@ void Object::ensure_shape_is_unique()
}
// Simple side-effect free property lookup, following the prototype chain. Non-standard.
Value Object::get_without_side_effects(const PropertyKey& property_name) const
Value Object::get_without_side_effects(const PropertyKey& property_key) const
{
auto* object = this;
while (object) {
auto value_and_attributes = object->storage_get(property_name);
auto value_and_attributes = object->storage_get(property_key);
if (value_and_attributes.has_value())
return value_and_attributes->value;
object = object->prototype();
@ -1110,19 +1110,19 @@ Value Object::get_without_side_effects(const PropertyKey& property_name) const
return {};
}
void Object::define_native_function(PropertyKey const& property_name, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> native_function, i32 length, PropertyAttributes attribute)
void Object::define_native_function(PropertyKey const& property_key, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> native_function, i32 length, PropertyAttributes attribute)
{
auto& vm = this->vm();
String function_name;
if (property_name.is_string()) {
function_name = property_name.as_string();
if (property_key.is_string()) {
function_name = property_key.as_string();
} else {
function_name = String::formatted("[{}]", property_name.as_symbol()->description());
function_name = String::formatted("[{}]", property_key.as_symbol()->description());
}
auto* function = NativeFunction::create(global_object(), function_name, move(native_function));
function->define_direct_property(vm.names.length, Value(length), Attribute::Configurable);
function->define_direct_property(vm.names.name, js_string(vm, function_name), Attribute::Configurable);
define_direct_property(property_name, function, attribute);
define_direct_property(property_key, function, attribute);
}
// 20.1.2.3.1 ObjectDefineProperties ( O, Properties ), https://tc39.es/ecma262/#sec-objectdefineproperties
@ -1148,21 +1148,21 @@ ThrowCompletionOr<Object*> Object::define_properties(Value properties)
// 5. For each element nextKey of keys, do
for (auto& next_key : keys) {
auto property_name = MUST(PropertyKey::from_value(global_object, next_key));
auto property_key = MUST(PropertyKey::from_value(global_object, next_key));
// a. Let propDesc be ? props.[[GetOwnProperty]](nextKey).
auto property_descriptor = TRY(props->internal_get_own_property(property_name));
auto property_descriptor = TRY(props->internal_get_own_property(property_key));
// b. If propDesc is not undefined and propDesc.[[Enumerable]] is true, then
if (property_descriptor.has_value() && *property_descriptor->enumerable) {
// i. Let descObj be ? Get(props, nextKey).
auto descriptor_object = TRY(props->get(property_name));
auto descriptor_object = TRY(props->get(property_key));
// ii. Let desc be ? ToPropertyDescriptor(descObj).
auto descriptor = TRY(to_property_descriptor(global_object, descriptor_object));
// iii. Append the pair (a two element List) consisting of nextKey and desc to the end of descriptors.
descriptors.append({ property_name, descriptor });
descriptors.append({ property_key, descriptor });
}
}

View file

@ -145,7 +145,7 @@ public:
Value get_without_side_effects(const PropertyKey&) const;
void define_direct_property(PropertyKey const& property_name, Value value, PropertyAttributes attributes) { storage_set(property_name, { value, attributes }); };
void define_direct_property(PropertyKey const& property_key, Value value, PropertyAttributes attributes) { storage_set(property_key, { value, attributes }); };
void define_direct_accessor(PropertyKey const&, FunctionObject* getter, FunctionObject* setter, PropertyAttributes attributes);
void define_native_function(PropertyKey const&, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)>, i32 length, PropertyAttributes attributes);

View file

@ -277,17 +277,17 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptors)
// 4. For each element key of ownKeys, do
for (auto& key : own_keys) {
auto property_name = MUST(PropertyKey::from_value(global_object, key));
auto property_key = MUST(PropertyKey::from_value(global_object, key));
// a. Let desc be ? obj.[[GetOwnProperty]](key).
auto desc = TRY(object->internal_get_own_property(property_name));
auto desc = TRY(object->internal_get_own_property(property_key));
// b. Let descriptor be ! FromPropertyDescriptor(desc).
auto descriptor = from_property_descriptor(global_object, desc);
// c. If descriptor is not undefined, perform ! CreateDataPropertyOrThrow(descriptors, key, descriptor).
if (!descriptor.is_undefined())
MUST(descriptors->create_data_property_or_throw(property_name, descriptor));
MUST(descriptors->create_data_property_or_throw(property_key, descriptor));
}
// 5. Return descriptors.
@ -411,20 +411,20 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::assign)
// iii. For each element nextKey of keys, do
for (auto& next_key : keys) {
auto property_name = MUST(PropertyKey::from_value(global_object, next_key));
auto property_key = MUST(PropertyKey::from_value(global_object, next_key));
// 1. Let desc be ? from.[[GetOwnProperty]](nextKey).
auto desc = TRY(from->internal_get_own_property(property_name));
auto desc = TRY(from->internal_get_own_property(property_key));
// 2. If desc is not undefined and desc.[[Enumerable]] is true, then
if (!desc.has_value() || !*desc->enumerable)
continue;
// a. Let propValue be ? Get(from, nextKey).
auto prop_value = TRY(from->get(property_name));
auto prop_value = TRY(from->get(property_key));
// b. Perform ? Set(to, nextKey, propValue, true).
TRY(to->set(property_name, prop_value, Object::ShouldThrowExceptions::Yes));
TRY(to->set(property_key, prop_value, Object::ShouldThrowExceptions::Yes));
}
}

View file

@ -225,13 +225,13 @@ struct Traits<JS::PropertyKey> : public GenericTraits<JS::PropertyKey> {
template<>
struct Formatter<JS::PropertyKey> : Formatter<StringView> {
ErrorOr<void> format(FormatBuilder& builder, JS::PropertyKey const& property_name)
ErrorOr<void> format(FormatBuilder& builder, JS::PropertyKey const& property_key)
{
if (!property_name.is_valid())
if (!property_key.is_valid())
return Formatter<StringView>::format(builder, "<invalid PropertyKey>");
if (property_name.is_number())
return Formatter<StringView>::format(builder, String::number(property_name.as_number()));
return Formatter<StringView>::format(builder, property_name.to_string_or_symbol().to_display_string());
if (property_key.is_number())
return Formatter<StringView>::format(builder, String::number(property_key.as_number()));
return Formatter<StringView>::format(builder, property_key.to_string_or_symbol().to_display_string());
}
};

View file

@ -31,17 +31,17 @@ ProxyObject::~ProxyObject()
{
}
static Value property_name_to_value(VM& vm, PropertyKey const& name)
static Value property_key_to_value(VM& vm, PropertyKey const& property_key)
{
VERIFY(name.is_valid());
if (name.is_symbol())
return name.as_symbol();
VERIFY(property_key.is_valid());
if (property_key.is_symbol())
return property_key.as_symbol();
if (name.is_string())
return js_string(vm, name.as_string());
if (property_key.is_string())
return js_string(vm, property_key.as_string());
VERIFY(name.is_number());
return js_string(vm, String::number(name.as_number()));
VERIFY(property_key.is_number());
return js_string(vm, String::number(property_key.as_number()));
}
// 10.5.1 [[GetPrototypeOf]] ( ), https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof
@ -223,13 +223,13 @@ ThrowCompletionOr<bool> ProxyObject::internal_prevent_extensions()
}
// 10.5.5 [[GetOwnProperty]] ( P ), https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p
ThrowCompletionOr<Optional<PropertyDescriptor>> ProxyObject::internal_get_own_property(const PropertyKey& property_name) const
ThrowCompletionOr<Optional<PropertyDescriptor>> ProxyObject::internal_get_own_property(const PropertyKey& property_key) const
{
auto& vm = this->vm();
auto& global_object = this->global_object();
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 2. Let handler be O.[[ProxyHandler]].
@ -246,18 +246,18 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> ProxyObject::internal_get_own_pr
// 7. If trap is undefined, then
if (!trap) {
// a. Return ? target.[[GetOwnProperty]](P).
return m_target.internal_get_own_property(property_name);
return m_target.internal_get_own_property(property_key);
}
// 8. Let trapResultObj be ? Call(trap, handler, « target, P »).
auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_name_to_value(vm, property_name)));
auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key)));
// 9. If Type(trapResultObj) is neither Object nor Undefined, throw a TypeError exception.
if (!trap_result.is_object() && !trap_result.is_undefined())
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyGetOwnDescriptorReturn);
// 10. Let targetDesc be ? target.[[GetOwnProperty]](P).
auto target_descriptor = TRY(m_target.internal_get_own_property(property_name));
auto target_descriptor = TRY(m_target.internal_get_own_property(property_key));
// 11. If trapResultObj is undefined, then
if (trap_result.is_undefined()) {
@ -316,13 +316,13 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> ProxyObject::internal_get_own_pr
}
// 10.5.6 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc
ThrowCompletionOr<bool> ProxyObject::internal_define_own_property(PropertyKey const& property_name, PropertyDescriptor const& property_descriptor)
ThrowCompletionOr<bool> ProxyObject::internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& property_descriptor)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 2. Let handler be O.[[ProxyHandler]].
@ -339,21 +339,21 @@ ThrowCompletionOr<bool> ProxyObject::internal_define_own_property(PropertyKey co
// 7. If trap is undefined, then
if (!trap) {
// a. Return ? target.[[DefineOwnProperty]](P, Desc).
return m_target.internal_define_own_property(property_name, property_descriptor);
return m_target.internal_define_own_property(property_key, property_descriptor);
}
// 8. Let descObj be FromPropertyDescriptor(Desc).
auto descriptor_object = from_property_descriptor(global_object, property_descriptor);
// 9. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P, descObj »)).
auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_name_to_value(vm, property_name), descriptor_object)).to_boolean();
auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key), descriptor_object)).to_boolean();
// 10. If booleanTrapResult is false, return false.
if (!trap_result)
return false;
// 11. Let targetDesc be ? target.[[GetOwnProperty]](P).
auto target_descriptor = TRY(m_target.internal_get_own_property(property_name));
auto target_descriptor = TRY(m_target.internal_get_own_property(property_key));
// 12. Let extensibleTarget be ? IsExtensible(target).
auto extensible_target = TRY(m_target.is_extensible());
@ -400,13 +400,13 @@ ThrowCompletionOr<bool> ProxyObject::internal_define_own_property(PropertyKey co
}
// 10.5.7 [[HasProperty]] ( P ), https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-hasproperty-p
ThrowCompletionOr<bool> ProxyObject::internal_has_property(PropertyKey const& property_name) const
ThrowCompletionOr<bool> ProxyObject::internal_has_property(PropertyKey const& property_key) const
{
auto& vm = this->vm();
auto& global_object = this->global_object();
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 2. Let handler be O.[[ProxyHandler]].
@ -423,16 +423,16 @@ ThrowCompletionOr<bool> ProxyObject::internal_has_property(PropertyKey const& pr
// 7. If trap is undefined, then
if (!trap) {
// a. Return ? target.[[HasProperty]](P).
return m_target.internal_has_property(property_name);
return m_target.internal_has_property(property_key);
}
// 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P »)).
auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_name_to_value(vm, property_name))).to_boolean();
auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key))).to_boolean();
// 9. If booleanTrapResult is false, then
if (!trap_result) {
// a. Let targetDesc be ? target.[[GetOwnProperty]](P).
auto target_descriptor = TRY(m_target.internal_get_own_property(property_name));
auto target_descriptor = TRY(m_target.internal_get_own_property(property_key));
// b. If targetDesc is not undefined, then
if (target_descriptor.has_value()) {
@ -454,7 +454,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_has_property(PropertyKey const& pr
}
// 10.5.8 [[Get]] ( P, Receiver ), https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver
ThrowCompletionOr<Value> ProxyObject::internal_get(PropertyKey const& property_name, Value receiver) const
ThrowCompletionOr<Value> ProxyObject::internal_get(PropertyKey const& property_key, Value receiver) const
{
VERIFY(!receiver.is_empty());
@ -462,7 +462,7 @@ ThrowCompletionOr<Value> ProxyObject::internal_get(PropertyKey const& property_n
auto& global_object = this->global_object();
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 2. Let handler be O.[[ProxyHandler]].
@ -495,14 +495,14 @@ ThrowCompletionOr<Value> ProxyObject::internal_get(PropertyKey const& property_n
// 7. If trap is undefined, then
if (!trap) {
// a. Return ? target.[[Get]](P, Receiver).
return m_target.internal_get(property_name, receiver);
return m_target.internal_get(property_key, receiver);
}
// 8. Let trapResult be ? Call(trap, handler, « target, P, Receiver »).
auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_name_to_value(vm, property_name), receiver));
auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key), receiver));
// 9. Let targetDesc be ? target.[[GetOwnProperty]](P).
auto target_descriptor = TRY(m_target.internal_get_own_property(property_name));
auto target_descriptor = TRY(m_target.internal_get_own_property(property_key));
// 10. If targetDesc is not undefined and targetDesc.[[Configurable]] is false, then
if (target_descriptor.has_value() && !*target_descriptor->configurable) {
@ -525,7 +525,7 @@ ThrowCompletionOr<Value> ProxyObject::internal_get(PropertyKey const& property_n
}
// 10.5.9 [[Set]] ( P, V, Receiver ), https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver
ThrowCompletionOr<bool> ProxyObject::internal_set(PropertyKey const& property_name, Value value, Value receiver)
ThrowCompletionOr<bool> ProxyObject::internal_set(PropertyKey const& property_key, Value value, Value receiver)
{
VERIFY(!value.is_empty());
VERIFY(!receiver.is_empty());
@ -534,7 +534,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_set(PropertyKey const& property_na
auto& global_object = this->global_object();
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 2. Let handler be O.[[ProxyHandler]].
@ -551,18 +551,18 @@ ThrowCompletionOr<bool> ProxyObject::internal_set(PropertyKey const& property_na
// 7. If trap is undefined, then
if (!trap) {
// a. Return ? target.[[Set]](P, V, Receiver).
return m_target.internal_set(property_name, value, receiver);
return m_target.internal_set(property_key, value, receiver);
}
// 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P, V, Receiver »)).
auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_name_to_value(vm, property_name), value, receiver)).to_boolean();
auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key), value, receiver)).to_boolean();
// 9. If booleanTrapResult is false, return false.
if (!trap_result)
return false;
// 10. Let targetDesc be ? target.[[GetOwnProperty]](P).
auto target_descriptor = TRY(m_target.internal_get_own_property(property_name));
auto target_descriptor = TRY(m_target.internal_get_own_property(property_key));
// 11. If targetDesc is not undefined and targetDesc.[[Configurable]] is false, then
if (target_descriptor.has_value() && !*target_descriptor->configurable) {
@ -585,13 +585,13 @@ ThrowCompletionOr<bool> ProxyObject::internal_set(PropertyKey const& property_na
}
// 10.5.10 [[Delete]] ( P ), https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-delete-p
ThrowCompletionOr<bool> ProxyObject::internal_delete(PropertyKey const& property_name)
ThrowCompletionOr<bool> ProxyObject::internal_delete(PropertyKey const& property_key)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 2. Let handler be O.[[ProxyHandler]].
@ -608,18 +608,18 @@ ThrowCompletionOr<bool> ProxyObject::internal_delete(PropertyKey const& property
// 7. If trap is undefined, then
if (!trap) {
// a. Return ? target.[[Delete]](P).
return m_target.internal_delete(property_name);
return m_target.internal_delete(property_key);
}
// 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P »)).
auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_name_to_value(vm, property_name))).to_boolean();
auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key))).to_boolean();
// 9. If booleanTrapResult is false, return false.
if (!trap_result)
return false;
// 10. Let targetDesc be ? target.[[GetOwnProperty]](P).
auto target_descriptor = TRY(m_target.internal_get_own_property(property_name));
auto target_descriptor = TRY(m_target.internal_get_own_property(property_key));
// 11. If targetDesc is undefined, return true.
if (!target_descriptor.has_value())

View file

@ -53,24 +53,24 @@ Shape* Shape::get_or_prune_cached_prototype_transition(Object* prototype)
return it->value;
}
Shape* Shape::create_put_transition(const StringOrSymbol& property_name, PropertyAttributes attributes)
Shape* Shape::create_put_transition(const StringOrSymbol& property_key, PropertyAttributes attributes)
{
TransitionKey key { property_name, attributes };
TransitionKey key { property_key, attributes };
if (auto* existing_shape = get_or_prune_cached_forward_transition(key))
return existing_shape;
auto* new_shape = heap().allocate_without_global_object<Shape>(*this, property_name, attributes, TransitionType::Put);
auto* new_shape = heap().allocate_without_global_object<Shape>(*this, property_key, attributes, TransitionType::Put);
if (!m_forward_transitions)
m_forward_transitions = make<HashMap<TransitionKey, WeakPtr<Shape>>>();
m_forward_transitions->set(key, new_shape);
return new_shape;
}
Shape* Shape::create_configure_transition(const StringOrSymbol& property_name, PropertyAttributes attributes)
Shape* Shape::create_configure_transition(const StringOrSymbol& property_key, PropertyAttributes attributes)
{
TransitionKey key { property_name, attributes };
TransitionKey key { property_key, attributes };
if (auto* existing_shape = get_or_prune_cached_forward_transition(key))
return existing_shape;
auto* new_shape = heap().allocate_without_global_object<Shape>(*this, property_name, attributes, TransitionType::Configure);
auto* new_shape = heap().allocate_without_global_object<Shape>(*this, property_key, attributes, TransitionType::Configure);
if (!m_forward_transitions)
m_forward_transitions = make<HashMap<TransitionKey, WeakPtr<Shape>>>();
m_forward_transitions->set(key, new_shape);
@ -97,10 +97,10 @@ Shape::Shape(Object& global_object)
{
}
Shape::Shape(Shape& previous_shape, const StringOrSymbol& property_name, PropertyAttributes attributes, TransitionType transition_type)
Shape::Shape(Shape& previous_shape, const StringOrSymbol& property_key, PropertyAttributes attributes, TransitionType transition_type)
: m_global_object(previous_shape.m_global_object)
, m_previous(&previous_shape)
, m_property_name(property_name)
, m_property_key(property_key)
, m_prototype(previous_shape.m_prototype)
, m_property_count(transition_type == TransitionType::Put ? previous_shape.m_property_count + 1 : previous_shape.m_property_count)
, m_attributes(attributes)
@ -127,18 +127,18 @@ void Shape::visit_edges(Cell::Visitor& visitor)
visitor.visit(m_global_object);
visitor.visit(m_prototype);
visitor.visit(m_previous);
m_property_name.visit_edges(visitor);
m_property_key.visit_edges(visitor);
if (m_property_table) {
for (auto& it : *m_property_table)
it.key.visit_edges(visitor);
}
}
Optional<PropertyMetadata> Shape::lookup(const StringOrSymbol& property_name) const
Optional<PropertyMetadata> Shape::lookup(const StringOrSymbol& property_key) const
{
if (m_property_count == 0)
return {};
auto property = property_table().get(property_name);
auto property = property_table().get(property_key);
if (!property.has_value())
return {};
return property;
@ -183,46 +183,46 @@ void Shape::ensure_property_table() const
for (ssize_t i = transition_chain.size() - 1; i >= 0; --i) {
auto* shape = transition_chain[i];
if (!shape->m_property_name.is_valid()) {
if (!shape->m_property_key.is_valid()) {
// Ignore prototype transitions as they don't affect the key map.
continue;
}
if (shape->m_transition_type == TransitionType::Put) {
m_property_table->set(shape->m_property_name, { next_offset++, shape->m_attributes });
m_property_table->set(shape->m_property_key, { next_offset++, shape->m_attributes });
} else if (shape->m_transition_type == TransitionType::Configure) {
auto it = m_property_table->find(shape->m_property_name);
auto it = m_property_table->find(shape->m_property_key);
VERIFY(it != m_property_table->end());
it->value.attributes = shape->m_attributes;
}
}
}
void Shape::add_property_to_unique_shape(const StringOrSymbol& property_name, PropertyAttributes attributes)
void Shape::add_property_to_unique_shape(const StringOrSymbol& property_key, PropertyAttributes attributes)
{
VERIFY(is_unique());
VERIFY(m_property_table);
VERIFY(!m_property_table->contains(property_name));
m_property_table->set(property_name, { static_cast<u32>(m_property_table->size()), attributes });
VERIFY(!m_property_table->contains(property_key));
m_property_table->set(property_key, { static_cast<u32>(m_property_table->size()), attributes });
VERIFY(m_property_count < NumericLimits<u32>::max());
++m_property_count;
}
void Shape::reconfigure_property_in_unique_shape(const StringOrSymbol& property_name, PropertyAttributes attributes)
void Shape::reconfigure_property_in_unique_shape(const StringOrSymbol& property_key, PropertyAttributes attributes)
{
VERIFY(is_unique());
VERIFY(m_property_table);
auto it = m_property_table->find(property_name);
auto it = m_property_table->find(property_key);
VERIFY(it != m_property_table->end());
it->value.attributes = attributes;
m_property_table->set(property_name, it->value);
m_property_table->set(property_key, it->value);
}
void Shape::remove_property_from_unique_shape(const StringOrSymbol& property_name, size_t offset)
void Shape::remove_property_from_unique_shape(const StringOrSymbol& property_key, size_t offset)
{
VERIFY(is_unique());
VERIFY(m_property_table);
if (m_property_table->remove(property_name))
if (m_property_table->remove(property_key))
--m_property_count;
for (auto& it : *m_property_table) {
VERIFY(it.value.offset != offset);
@ -231,20 +231,20 @@ void Shape::remove_property_from_unique_shape(const StringOrSymbol& property_nam
}
}
void Shape::add_property_without_transition(StringOrSymbol const& property_name, PropertyAttributes attributes)
void Shape::add_property_without_transition(StringOrSymbol const& property_key, PropertyAttributes attributes)
{
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
ensure_property_table();
if (m_property_table->set(property_name, { 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());
++m_property_count;
}
}
FLATTEN void Shape::add_property_without_transition(PropertyKey const& property_name, PropertyAttributes attributes)
FLATTEN void Shape::add_property_without_transition(PropertyKey const& property_key, PropertyAttributes attributes)
{
VERIFY(property_name.is_valid());
add_property_without_transition(property_name.to_string_or_symbol(), attributes);
VERIFY(property_key.is_valid());
add_property_without_transition(property_key.to_string_or_symbol(), attributes);
}
}

View file

@ -24,12 +24,12 @@ struct PropertyMetadata {
};
struct TransitionKey {
StringOrSymbol property_name;
StringOrSymbol property_key;
PropertyAttributes attributes { 0 };
bool operator==(const TransitionKey& other) const
{
return property_name == other.property_name && attributes == other.attributes;
return property_key == other.property_key && attributes == other.attributes;
}
};
@ -50,7 +50,7 @@ public:
explicit Shape(ShapeWithoutGlobalObjectTag);
explicit Shape(Object& global_object);
Shape(Shape& previous_shape, const StringOrSymbol& property_name, PropertyAttributes attributes, TransitionType);
Shape(Shape& previous_shape, const StringOrSymbol& property_key, PropertyAttributes attributes, TransitionType);
Shape(Shape& previous_shape, Object* new_prototype);
Shape* create_put_transition(const StringOrSymbol&, PropertyAttributes attributes);
@ -83,7 +83,7 @@ public:
void remove_property_from_unique_shape(const StringOrSymbol&, size_t offset);
void add_property_to_unique_shape(const StringOrSymbol&, PropertyAttributes attributes);
void reconfigure_property_in_unique_shape(const StringOrSymbol& property_name, PropertyAttributes attributes);
void reconfigure_property_in_unique_shape(const StringOrSymbol& property_key, PropertyAttributes attributes);
private:
virtual const char* class_name() const override { return "Shape"; }
@ -101,7 +101,7 @@ private:
OwnPtr<HashMap<TransitionKey, WeakPtr<Shape>>> m_forward_transitions;
OwnPtr<HashMap<Object*, WeakPtr<Shape>>> m_prototype_transitions;
Shape* m_previous { nullptr };
StringOrSymbol m_property_name;
StringOrSymbol m_property_key;
Object* m_prototype { nullptr };
u32 m_property_count { 0 };
@ -116,6 +116,6 @@ template<>
struct AK::Traits<JS::TransitionKey> : public GenericTraits<JS::TransitionKey> {
static unsigned hash(const JS::TransitionKey& key)
{
return pair_int_hash(key.attributes.bits(), Traits<JS::StringOrSymbol>::hash(key.property_name));
return pair_int_hash(key.attributes.bits(), Traits<JS::StringOrSymbol>::hash(key.property_key));
}
};

View file

@ -44,20 +44,20 @@ void StringObject::visit_edges(Cell::Visitor& visitor)
}
// 10.4.3.5 StringGetOwnProperty ( S, P ), https://tc39.es/ecma262/#sec-stringgetownproperty
static Optional<PropertyDescriptor> string_get_own_property(GlobalObject& global_object, StringObject const& string, PropertyKey const& property_name)
static Optional<PropertyDescriptor> string_get_own_property(GlobalObject& global_object, StringObject const& string, PropertyKey const& property_key)
{
// 1. Assert: S is an Object that has a [[StringData]] internal slot.
// 2. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 3. If Type(P) is not 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_name.is_string()' would be wrong.
if (property_name.is_symbol())
// this is not the case for PropertyKey, so '!property_key.is_string()' would be wrong.
if (property_key.is_symbol())
return {};
// 4. Let index be ! CanonicalNumericIndexString(P).
auto index = canonical_numeric_index_string(global_object, property_name);
auto index = canonical_numeric_index_string(global_object, property_key);
// 5. If index is undefined, return undefined.
if (index.is_undefined())
return {};
@ -92,29 +92,29 @@ static Optional<PropertyDescriptor> string_get_own_property(GlobalObject& global
}
// 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_name) const
ThrowCompletionOr<Optional<PropertyDescriptor>> StringObject::internal_get_own_property(PropertyKey const& property_key) const
{
// Assert: IsPropertyKey(P) is true.
// 2. Let desc be OrdinaryGetOwnProperty(S, P).
auto descriptor = MUST(Object::internal_get_own_property(property_name));
auto descriptor = MUST(Object::internal_get_own_property(property_key));
// 3. If desc is not undefined, return desc.
if (descriptor.has_value())
return descriptor;
// 4. Return ! StringGetOwnProperty(S, P).
return string_get_own_property(global_object(), *this, property_name);
return string_get_own_property(global_object(), *this, property_key);
}
// 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_name, PropertyDescriptor const& property_descriptor)
ThrowCompletionOr<bool> StringObject::internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& property_descriptor)
{
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 2. Let stringDesc be ! StringGetOwnProperty(S, P).
auto string_descriptor = string_get_own_property(global_object(), *this, property_name);
auto string_descriptor = string_get_own_property(global_object(), *this, property_key);
// 3. If stringDesc is not undefined, then
if (string_descriptor.has_value()) {
@ -126,7 +126,7 @@ ThrowCompletionOr<bool> StringObject::internal_define_own_property(PropertyKey c
}
// 4. Return ! OrdinaryDefineOwnProperty(S, P, Desc).
return Object::internal_define_own_property(property_name, property_descriptor);
return Object::internal_define_own_property(property_key, property_descriptor);
}
// 10.4.3.3 [[OwnPropertyKeys]] ( ), https://tc39.es/ecma262/#sec-string-exotic-objects-ownpropertykeys

View file

@ -993,15 +993,15 @@ ThrowCompletionOr<Object*> default_merge_fields(GlobalObject& global_object, Obj
for (auto& next_key : original_keys) {
// a. If nextKey is not "month" or "monthCode", then
if (next_key.as_string().string() != vm.names.month.as_string() && next_key.as_string().string() != vm.names.monthCode.as_string()) {
auto property_name = MUST(PropertyKey::from_value(global_object, next_key));
auto property_key = MUST(PropertyKey::from_value(global_object, next_key));
// i. Let propValue be ? Get(fields, nextKey).
auto prop_value = TRY(fields.get(property_name));
auto prop_value = TRY(fields.get(property_key));
// ii. If propValue is not undefined, then
if (!prop_value.is_undefined()) {
// 1. Perform ! CreateDataPropertyOrThrow(merged, nextKey, propValue).
MUST(merged->create_data_property_or_throw(property_name, prop_value));
MUST(merged->create_data_property_or_throw(property_key, prop_value));
}
}
}
@ -1014,15 +1014,15 @@ ThrowCompletionOr<Object*> default_merge_fields(GlobalObject& global_object, Obj
// 5. For each element nextKey of newKeys, do
for (auto& next_key : new_keys) {
auto property_name = MUST(PropertyKey::from_value(global_object, next_key));
auto property_key = MUST(PropertyKey::from_value(global_object, next_key));
// a. Let propValue be ? Get(additionalFields, nextKey).
auto prop_value = TRY(additional_fields.get(property_name));
auto prop_value = TRY(additional_fields.get(property_key));
// b. If propValue is not undefined, then
if (!prop_value.is_undefined()) {
// i. Perform ! CreateDataPropertyOrThrow(merged, nextKey, propValue).
MUST(merged->create_data_property_or_throw(property_name, prop_value));
MUST(merged->create_data_property_or_throw(property_key, prop_value));
}
// See comment above.

View file

@ -183,10 +183,10 @@ class TypedArray : public TypedArrayBase {
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_name) const override
virtual ThrowCompletionOr<Optional<PropertyDescriptor>> internal_get_own_property(PropertyKey const& property_key) const override
{
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 2. Assert: O is an Integer-Indexed exotic object.
@ -196,9 +196,9 @@ public:
// 3. If Type(P) is String, then
// NOTE: This includes an implementation-defined optimization, see note above!
if (property_name.is_string() || property_name.is_number()) {
if (property_key.is_string() || property_key.is_number()) {
// a. Let numericIndex be ! CanonicalNumericIndexString(P).
auto numeric_index = canonical_numeric_index_string(global_object(), property_name);
auto numeric_index = canonical_numeric_index_string(global_object(), property_key);
// b. If numericIndex is not undefined, then
if (!numeric_index.is_undefined()) {
// i. Let value be ! IntegerIndexedElementGet(O, numericIndex).
@ -219,14 +219,14 @@ public:
}
// 4. Return OrdinaryGetOwnProperty(O, P).
return Object::internal_get_own_property(property_name);
return Object::internal_get_own_property(property_key);
}
// 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_name) const override
virtual ThrowCompletionOr<bool> internal_has_property(PropertyKey const& property_key) const override
{
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 2. Assert: O is an Integer-Indexed exotic object.
@ -236,23 +236,23 @@ public:
// 3. If Type(P) is String, then
// NOTE: This includes an implementation-defined optimization, see note above!
if (property_name.is_string() || property_name.is_number()) {
if (property_key.is_string() || property_key.is_number()) {
// a. Let numericIndex be ! CanonicalNumericIndexString(P).
auto numeric_index = canonical_numeric_index_string(global_object(), property_name);
auto numeric_index = canonical_numeric_index_string(global_object(), property_key);
// b. If numericIndex is not undefined, return ! IsValidIntegerIndex(O, numericIndex).
if (!numeric_index.is_undefined())
return is_valid_integer_index(*this, numeric_index);
}
// 4. Return ? OrdinaryHasProperty(O, P).
return Object::internal_has_property(property_name);
return Object::internal_has_property(property_key);
}
// 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_name, PropertyDescriptor const& property_descriptor) override
virtual ThrowCompletionOr<bool> internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& property_descriptor) override
{
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 2. Assert: O is an Integer-Indexed exotic object.
@ -262,9 +262,9 @@ public:
// 3. If Type(P) is String, then
// NOTE: This includes an implementation-defined optimization, see note above!
if (property_name.is_string() || property_name.is_number()) {
if (property_key.is_string() || property_key.is_number()) {
// a. Let numericIndex be ! CanonicalNumericIndexString(P).
auto numeric_index = canonical_numeric_index_string(global_object(), property_name);
auto numeric_index = canonical_numeric_index_string(global_object(), property_key);
// b. If numericIndex is not undefined, then
if (!numeric_index.is_undefined()) {
// i. If ! IsValidIntegerIndex(O, numericIndex) is false, return false.
@ -297,25 +297,25 @@ public:
}
// 4. Return ! OrdinaryDefineOwnProperty(O, P, Desc).
return Object::internal_define_own_property(property_name, property_descriptor);
return Object::internal_define_own_property(property_key, property_descriptor);
}
// 10.4.5.4 [[Get]] ( P, Receiver ), 10.4.5.4 [[Get]] ( P, Receiver )
virtual ThrowCompletionOr<Value> internal_get(PropertyKey const& property_name, Value receiver) const override
virtual ThrowCompletionOr<Value> internal_get(PropertyKey const& property_key, Value receiver) const override
{
VERIFY(!receiver.is_empty());
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
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.
// 2. If Type(P) is String, then
// NOTE: This includes an implementation-defined optimization, see note above!
if (property_name.is_string() || property_name.is_number()) {
if (property_key.is_string() || property_key.is_number()) {
// a. Let numericIndex be ! CanonicalNumericIndexString(P).
auto numeric_index = canonical_numeric_index_string(global_object(), property_name);
auto numeric_index = canonical_numeric_index_string(global_object(), property_key);
// b. If numericIndex is not undefined, then
if (!numeric_index.is_undefined()) {
// i. Return ! IntegerIndexedElementGet(O, numericIndex).
@ -324,26 +324,26 @@ public:
}
// 3. Return ? OrdinaryGet(O, P, Receiver).
return Object::internal_get(property_name, receiver);
return Object::internal_get(property_key, receiver);
}
// 10.4.5.5 [[Set]] ( P, V, Receiver ), https://tc39.es/ecma262/#sec-integer-indexed-exotic-objects-set-p-v-receiver
virtual ThrowCompletionOr<bool> internal_set(PropertyKey const& property_name, Value value, Value receiver) override
virtual ThrowCompletionOr<bool> internal_set(PropertyKey const& property_key, Value value, Value receiver) override
{
VERIFY(!value.is_empty());
VERIFY(!receiver.is_empty());
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
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.
// 2. If Type(P) is String, then
// NOTE: This includes an implementation-defined optimization, see note above!
if (property_name.is_string() || property_name.is_number()) {
if (property_key.is_string() || property_key.is_number()) {
// a. Let numericIndex be ! CanonicalNumericIndexString(P).
auto numeric_index = canonical_numeric_index_string(global_object(), property_name);
auto numeric_index = canonical_numeric_index_string(global_object(), property_key);
// b. If numericIndex is not undefined, then
if (!numeric_index.is_undefined()) {
// i. Perform ? IntegerIndexedElementSet(O, numericIndex, V).
@ -355,14 +355,14 @@ public:
}
// 3. Return ? OrdinarySet(O, P, V, Receiver).
return Object::internal_set(property_name, value, receiver);
return Object::internal_set(property_key, value, receiver);
}
// 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_name) override
virtual ThrowCompletionOr<bool> internal_delete(PropertyKey const& property_key) override
{
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 2. Assert: O is an Integer-Indexed exotic object.
// NOTE: If the property name is a number type (An implementation-defined optimized
@ -371,9 +371,9 @@ public:
// 3. If Type(P) is String, then
// NOTE: This includes an implementation-defined optimization, see note above!
if (property_name.is_string() || property_name.is_number()) {
if (property_key.is_string() || property_key.is_number()) {
// a. Let numericIndex be ! CanonicalNumericIndexString(P).
auto numeric_index = canonical_numeric_index_string(global_object(), property_name);
auto numeric_index = canonical_numeric_index_string(global_object(), property_key);
// b. If numericIndex is not undefined, then
if (!numeric_index.is_undefined()) {
// i. If ! IsValidIntegerIndex(O, numericIndex) is false, return true; else return false.
@ -384,7 +384,7 @@ public:
}
// 4. Return ? OrdinaryDelete(O, P).
return Object::internal_delete(property_name);
return Object::internal_delete(property_key);
}
// 10.4.5.7 [[OwnPropertyKeys]] ( ), https://tc39.es/ecma262/#sec-integer-indexed-exotic-objects-ownpropertykeys

View file

@ -804,28 +804,28 @@ ThrowCompletionOr<double> Value::to_integer_or_infinity(GlobalObject& global_obj
}
// 7.3.3 GetV ( V, P ), https://tc39.es/ecma262/#sec-getv
ThrowCompletionOr<Value> Value::get(GlobalObject& global_object, PropertyKey const& property_name) const
ThrowCompletionOr<Value> Value::get(GlobalObject& global_object, PropertyKey const& property_key) const
{
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 2. Let O be ? ToObject(V).
auto* object = TRY(to_object(global_object));
// 3. Return ? O.[[Get]](P, V).
return TRY(object->internal_get(property_name, *this));
return TRY(object->internal_get(property_key, *this));
}
// 7.3.11 GetMethod ( V, P ), https://tc39.es/ecma262/#sec-getmethod
ThrowCompletionOr<FunctionObject*> Value::get_method(GlobalObject& global_object, PropertyKey const& property_name) const
ThrowCompletionOr<FunctionObject*> Value::get_method(GlobalObject& global_object, PropertyKey const& property_key) const
{
auto& vm = global_object.vm();
// 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid());
VERIFY(property_key.is_valid());
// 2. Let func be ? GetV(V, P).
auto function = TRY(get(global_object, property_name));
auto function = TRY(get(global_object, property_key));
// 3. If func is either undefined or null, return undefined.
if (function.is_nullish())
@ -1569,10 +1569,10 @@ ThrowCompletionOr<TriState> is_less_than(GlobalObject& global_object, bool left_
}
// 7.3.21 Invoke ( V, P [ , argumentsList ] ), https://tc39.es/ecma262/#sec-invoke
ThrowCompletionOr<Value> Value::invoke_internal(GlobalObject& global_object, JS::PropertyKey const& property_name, Optional<MarkedValueList> arguments)
ThrowCompletionOr<Value> Value::invoke_internal(GlobalObject& global_object, JS::PropertyKey const& property_key, Optional<MarkedValueList> arguments)
{
auto& vm = global_object.vm();
auto property = TRY(get(global_object, property_name));
auto property = TRY(get(global_object, property_key));
if (!property.is_function())
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, property.to_string_without_side_effects());

View file

@ -347,7 +347,7 @@ public:
bool operator==(Value const&) const;
template<typename... Args>
[[nodiscard]] ALWAYS_INLINE ThrowCompletionOr<Value> invoke(GlobalObject& global_object, PropertyKey const& property_name, Args... args);
[[nodiscard]] ALWAYS_INLINE ThrowCompletionOr<Value> invoke(GlobalObject& global_object, PropertyKey const& property_key, Args... args);
private:
Type m_type { Type::Empty };