summaryrefslogtreecommitdiff
path: root/Userland/Libraries
diff options
context:
space:
mode:
authorIdan Horowitz <idan.horowitz@gmail.com>2021-06-05 15:22:11 +0300
committerLinus Groh <mail@linusgroh.de>2021-06-05 14:15:28 +0100
commiteb0b1c432a0e9aa5a220c460e95694dd3fbb67b8 (patch)
treea5aab6675ee19faa4a909c40dc6c34dac67700d3 /Userland/Libraries
parente72e621d89fee1d368f294eb239fa4fe54a1b5f2 (diff)
downloadserenity-eb0b1c432a0e9aa5a220c460e95694dd3fbb67b8.zip
LibJS: Replace StringOrSymbol::from_value with Value::to_property_key
This is a more specification compliant implementation of the abstract operation 7.1.19 ToPropertyKey which should handle boxed symbols correctly.
Diffstat (limited to 'Userland/Libraries')
-rw-r--r--Userland/Libraries/LibJS/AST.cpp6
-rw-r--r--Userland/Libraries/LibJS/Forward.h1
-rw-r--r--Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp10
-rw-r--r--Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp8
-rw-r--r--Userland/Libraries/LibJS/Runtime/ReflectObject.cpp6
-rw-r--r--Userland/Libraries/LibJS/Runtime/StringOrSymbol.h12
-rw-r--r--Userland/Libraries/LibJS/Runtime/Value.cpp14
-rw-r--r--Userland/Libraries/LibJS/Runtime/Value.h1
8 files changed, 29 insertions, 29 deletions
diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp
index 9e7edf8a40..43fb32dc9d 100644
--- a/Userland/Libraries/LibJS/AST.cpp
+++ b/Userland/Libraries/LibJS/AST.cpp
@@ -824,15 +824,15 @@ Value ClassExpression::execute(Interpreter& interpreter, GlobalObject& global_ob
switch (method.kind()) {
case ClassMethod::Kind::Method:
- target.define_property(StringOrSymbol::from_value(global_object, key), method_value);
+ target.define_property(key.to_property_key(global_object), method_value);
break;
case ClassMethod::Kind::Getter:
update_function_name(method_value, String::formatted("get {}", get_function_name(global_object, key)));
- target.define_accessor(StringOrSymbol::from_value(global_object, key), &method_function, nullptr, Attribute::Configurable | Attribute::Enumerable);
+ target.define_accessor(key.to_property_key(global_object), &method_function, nullptr, Attribute::Configurable | Attribute::Enumerable);
break;
case ClassMethod::Kind::Setter:
update_function_name(method_value, String::formatted("set {}", get_function_name(global_object, key)));
- target.define_accessor(StringOrSymbol::from_value(global_object, key), nullptr, &method_function, Attribute::Configurable | Attribute::Enumerable);
+ target.define_accessor(key.to_property_key(global_object), nullptr, &method_function, Attribute::Configurable | Attribute::Enumerable);
break;
default:
VERIFY_NOT_REACHED();
diff --git a/Userland/Libraries/LibJS/Forward.h b/Userland/Libraries/LibJS/Forward.h
index 835d2b84a4..727560b3ff 100644
--- a/Userland/Libraries/LibJS/Forward.h
+++ b/Userland/Libraries/LibJS/Forward.h
@@ -130,6 +130,7 @@ class ScopeNode;
class ScopeObject;
class Shape;
class Statement;
+class StringOrSymbol;
class Symbol;
class Token;
class VM;
diff --git a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp b/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp
index fddded47f1..17f2a3fcb2 100644
--- a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp
+++ b/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp
@@ -202,14 +202,14 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::define_property_)
vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObject, "Object argument");
return {};
}
+ auto property_key = vm.argument(1).to_property_key(global_object);
+ if (vm.exception())
+ return {};
if (!vm.argument(2).is_object()) {
vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObject, "Descriptor argument");
return {};
}
auto& object = vm.argument(0).as_object();
- auto property_key = StringOrSymbol::from_value(global_object, vm.argument(1));
- if (vm.exception())
- return {};
auto& descriptor = vm.argument(2).as_object();
if (!object.define_property(property_key, descriptor)) {
if (!vm.exception()) {
@@ -316,10 +316,10 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::has_own)
auto* object = vm.argument(0).to_object(global_object);
if (vm.exception())
return {};
- auto string_or_symbol = StringOrSymbol::from_value(global_object, vm.argument(1));
+ auto property_key = vm.argument(1).to_property_key(global_object);
if (vm.exception())
return {};
- return Value(object->has_own_property(string_or_symbol));
+ return Value(object->has_own_property(property_key));
}
}
diff --git a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp
index 1ca204825f..d00de438c4 100644
--- a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp
@@ -43,13 +43,13 @@ ObjectPrototype::~ObjectPrototype()
JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::has_own_property)
{
+ auto property_key = vm.argument(0).to_property_key(global_object);
+ if (vm.exception())
+ return {};
auto* this_object = vm.this_value(global_object).to_object(global_object);
if (!this_object)
return {};
- auto string_or_symbol = StringOrSymbol::from_value(global_object, vm.argument(0));
- if (vm.exception())
- return {};
- return Value(this_object->has_own_property(string_or_symbol));
+ return Value(this_object->has_own_property(property_key));
}
JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::to_string)
diff --git a/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp b/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp
index 1dfd68d14f..3e7f911db6 100644
--- a/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp
+++ b/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp
@@ -124,13 +124,13 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::define_property)
auto* target = get_target_object_from(global_object, "defineProperty");
if (!target)
return {};
+ auto property_key = vm.argument(1).to_property_key(global_object);
+ if (vm.exception())
+ return {};
if (!vm.argument(2).is_object()) {
vm.throw_exception<TypeError>(global_object, ErrorType::ReflectBadDescriptorArgument);
return {};
}
- auto property_key = StringOrSymbol::from_value(global_object, vm.argument(1));
- if (vm.exception())
- return {};
auto& descriptor = vm.argument(2).as_object();
auto success = target->define_property(property_key, descriptor, false);
if (vm.exception())
diff --git a/Userland/Libraries/LibJS/Runtime/StringOrSymbol.h b/Userland/Libraries/LibJS/Runtime/StringOrSymbol.h
index e6ba1dfba6..52ea30065c 100644
--- a/Userland/Libraries/LibJS/Runtime/StringOrSymbol.h
+++ b/Userland/Libraries/LibJS/Runtime/StringOrSymbol.h
@@ -15,18 +15,6 @@ namespace JS {
class StringOrSymbol {
public:
- static StringOrSymbol from_value(GlobalObject& global_object, Value value)
- {
- if (value.is_empty())
- return {};
- if (value.is_symbol())
- return &value.as_symbol();
- auto string = value.to_string(global_object);
- if (string.is_null())
- return {};
- return string;
- }
-
StringOrSymbol() = default;
StringOrSymbol(const char* chars)
diff --git a/Userland/Libraries/LibJS/Runtime/Value.cpp b/Userland/Libraries/LibJS/Runtime/Value.cpp
index 62e7c9d19d..c63d9b7fbb 100644
--- a/Userland/Libraries/LibJS/Runtime/Value.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Value.cpp
@@ -543,6 +543,16 @@ double Value::to_double(GlobalObject& global_object) const
return number.as_double();
}
+StringOrSymbol Value::to_property_key(GlobalObject& global_object) const
+{
+ auto key = to_primitive(global_object, PreferredType::String);
+ if (global_object.vm().exception())
+ return {};
+ if (key.is_symbol())
+ return &key.as_symbol();
+ return to_string(global_object);
+}
+
i32 Value::to_i32_slow_case(GlobalObject& global_object) const
{
VERIFY(type() != Type::Int32);
@@ -1008,10 +1018,10 @@ Value in(GlobalObject& global_object, Value lhs, Value rhs)
global_object.vm().throw_exception<TypeError>(global_object, ErrorType::InOperatorWithObject);
return {};
}
- auto lhs_string_or_symbol = StringOrSymbol::from_value(global_object, lhs);
+ auto lhs_property_key = lhs.to_property_key(global_object);
if (global_object.vm().exception())
return {};
- return Value(rhs.as_object().has_property(lhs_string_or_symbol));
+ return Value(rhs.as_object().has_property(lhs_property_key));
}
Value instance_of(GlobalObject& global_object, Value lhs, Value rhs)
diff --git a/Userland/Libraries/LibJS/Runtime/Value.h b/Userland/Libraries/LibJS/Runtime/Value.h
index af7b6dfd56..37cbf2cfcc 100644
--- a/Userland/Libraries/LibJS/Runtime/Value.h
+++ b/Userland/Libraries/LibJS/Runtime/Value.h
@@ -260,6 +260,7 @@ public:
Value to_number(GlobalObject&) const;
BigInt* to_bigint(GlobalObject&) const;
double to_double(GlobalObject&) const;
+ StringOrSymbol to_property_key(GlobalObject&) const;
i32 to_i32(GlobalObject& global_object) const
{
if (m_type == Type::Int32)