summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Userland/Libraries/LibJS/Bytecode/Op.h1
-rw-r--r--Userland/Libraries/LibJS/Runtime/Map.h1
-rw-r--r--Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp24
-rw-r--r--Userland/Libraries/LibJS/Runtime/PrimitiveString.h3
-rw-r--r--Userland/Libraries/LibJS/Runtime/Reference.cpp15
-rw-r--r--Userland/Libraries/LibJS/Runtime/Value.h22
-rw-r--r--Userland/Libraries/LibJS/Runtime/ValueTraits.h35
7 files changed, 77 insertions, 24 deletions
diff --git a/Userland/Libraries/LibJS/Bytecode/Op.h b/Userland/Libraries/LibJS/Bytecode/Op.h
index 3472e5b28a..666ce7e2f9 100644
--- a/Userland/Libraries/LibJS/Bytecode/Op.h
+++ b/Userland/Libraries/LibJS/Bytecode/Op.h
@@ -18,6 +18,7 @@
#include <LibJS/Runtime/Environment.h>
#include <LibJS/Runtime/EnvironmentCoordinate.h>
#include <LibJS/Runtime/Value.h>
+#include <LibJS/Runtime/ValueTraits.h>
namespace JS::Bytecode::Op {
diff --git a/Userland/Libraries/LibJS/Runtime/Map.h b/Userland/Libraries/LibJS/Runtime/Map.h
index 476aa7bee7..3cce53cfab 100644
--- a/Userland/Libraries/LibJS/Runtime/Map.h
+++ b/Userland/Libraries/LibJS/Runtime/Map.h
@@ -12,6 +12,7 @@
#include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/Object.h>
#include <LibJS/Runtime/Value.h>
+#include <LibJS/Runtime/ValueTraits.h>
namespace JS {
diff --git a/Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp b/Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp
index 063c518f4a..b2d328677c 100644
--- a/Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp
+++ b/Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp
@@ -4,9 +4,13 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
+#include "LibJS/Runtime/Value.h"
#include <AK/CharacterTypes.h>
#include <AK/Utf16View.h>
+#include <LibJS/Runtime/AbstractOperations.h>
+#include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/PrimitiveString.h>
+#include <LibJS/Runtime/PropertyKey.h>
#include <LibJS/Runtime/VM.h>
namespace JS {
@@ -51,6 +55,26 @@ Utf16View PrimitiveString::utf16_string_view() const
return utf16_string().view();
}
+Optional<Value> PrimitiveString::get(GlobalObject& global_object, PropertyKey const& property_key) const
+{
+ if (property_key.is_symbol())
+ return {};
+ if (property_key.is_string()) {
+ if (property_key.as_string() == global_object.vm().names.length.as_string()) {
+ auto length = utf16_string().length_in_code_units();
+ return Value(static_cast<double>(length));
+ }
+ }
+ auto index = canonical_numeric_index_string(property_key);
+ if (!index.has_value())
+ return {};
+ auto str = utf16_string_view();
+ auto length = str.length_in_code_units();
+ if (length <= *index)
+ return {};
+ return js_string(vm(), str.substring_view(*index, 1));
+}
+
PrimitiveString* js_string(Heap& heap, Utf16View const& view)
{
return js_string(heap, Utf16String(view));
diff --git a/Userland/Libraries/LibJS/Runtime/PrimitiveString.h b/Userland/Libraries/LibJS/Runtime/PrimitiveString.h
index dd15cb4d49..e293c259be 100644
--- a/Userland/Libraries/LibJS/Runtime/PrimitiveString.h
+++ b/Userland/Libraries/LibJS/Runtime/PrimitiveString.h
@@ -7,7 +7,9 @@
#pragma once
#include <AK/String.h>
+#include <LibJS/Forward.h>
#include <LibJS/Heap/Cell.h>
+#include <LibJS/Runtime/Value.h>
#include <LibJS/Runtime/Utf16String.h>
namespace JS {
@@ -28,6 +30,7 @@ public:
Utf16View utf16_string_view() const;
bool has_utf16_string() const { return m_has_utf16_string; }
+ Optional<Value> get(GlobalObject&, PropertyKey const&) const;
private:
virtual const char* class_name() const override { return "PrimitiveString"; }
diff --git a/Userland/Libraries/LibJS/Runtime/Reference.cpp b/Userland/Libraries/LibJS/Runtime/Reference.cpp
index 8986511909..f9a25872ca 100644
--- a/Userland/Libraries/LibJS/Runtime/Reference.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Reference.cpp
@@ -63,15 +63,26 @@ ThrowCompletionOr<Value> Reference::get_value(GlobalObject& global_object) const
return throw_reference_error(global_object);
if (is_property_reference()) {
- auto* base_obj = TRY(m_base_value.to_object(global_object));
-
if (is_private_reference()) {
// FIXME: We need to be able to specify the receiver for this
// if we want to use it in error messages in future
// as things currently stand this does the "wrong thing" but
// the error is unobservable
+ auto base_obj = TRY(m_base_value.to_object(global_object));
return base_obj->private_get(m_private_name);
}
+ Object* base_obj = nullptr;
+ if (m_base_value.is_string()) {
+ auto string_value = m_base_value.as_string().get(global_object, m_name);
+ if (string_value.has_value())
+ return *string_value;
+ base_obj = global_object.string_prototype();
+ } else if (m_base_value.is_number())
+ base_obj = global_object.number_prototype();
+ else if (m_base_value.is_boolean())
+ base_obj = global_object.boolean_prototype();
+ else
+ base_obj = TRY(m_base_value.to_object(global_object));
return base_obj->internal_get(m_name, m_base_value);
}
diff --git a/Userland/Libraries/LibJS/Runtime/Value.h b/Userland/Libraries/LibJS/Runtime/Value.h
index 6a001cf9b0..fca480e91e 100644
--- a/Userland/Libraries/LibJS/Runtime/Value.h
+++ b/Userland/Libraries/LibJS/Runtime/Value.h
@@ -18,7 +18,6 @@
#include <AK/Types.h>
#include <LibJS/Forward.h>
#include <LibJS/Runtime/BigInt.h>
-#include <LibJS/Runtime/PrimitiveString.h>
#include <LibJS/Runtime/Utf16String.h>
#include <math.h>
@@ -435,27 +434,6 @@ ThrowCompletionOr<TriState> is_less_than(GlobalObject&, bool left_first, Value l
inline bool Value::operator==(Value const& value) const { return same_value(*this, value); }
-struct ValueTraits : public Traits<Value> {
- static unsigned hash(Value value)
- {
- VERIFY(!value.is_empty());
- if (value.is_string())
- return value.as_string().string().hash();
-
- if (value.is_bigint())
- return value.as_bigint().big_integer().hash();
-
- if (value.is_negative_zero())
- value = Value(0);
-
- return u64_hash(value.encoded()); // FIXME: Is this the best way to hash pointers, doubles & ints?
- }
- static bool equals(const Value a, const Value b)
- {
- return same_value_zero(a, b);
- }
-};
-
}
namespace AK {
diff --git a/Userland/Libraries/LibJS/Runtime/ValueTraits.h b/Userland/Libraries/LibJS/Runtime/ValueTraits.h
new file mode 100644
index 0000000000..14e2dfd23c
--- /dev/null
+++ b/Userland/Libraries/LibJS/Runtime/ValueTraits.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <LibJS/Runtime/PrimitiveString.h>
+#include <LibJS/Runtime/Value.h>
+
+namespace JS {
+struct ValueTraits : public Traits<Value> {
+ static unsigned hash(Value value)
+ {
+ VERIFY(!value.is_empty());
+ if (value.is_string())
+ return value.as_string().string().hash();
+
+ if (value.is_bigint())
+ return value.as_bigint().big_integer().hash();
+
+ if (value.is_negative_zero())
+ value = Value(0);
+
+ return u64_hash(value.encoded()); // FIXME: Is this the best way to hash pointers, doubles & ints?
+ }
+ static bool equals(const Value a, const Value b)
+ {
+ return same_value_zero(a, b);
+ }
+};
+
+}