Kaynağa Gözat

LibJS: Port Symbol to String

This includes the VM's global_symbol_registry HashMap, which can now
store String keys.
Linus Groh 2 yıl önce
ebeveyn
işleme
a8bf2f8e4c

+ 1 - 1
Userland/Libraries/LibJS/AST.cpp

@@ -97,7 +97,7 @@ static void update_function_name(Value value, DeprecatedFlyString const& name)
 static ThrowCompletionOr<DeprecatedString> get_function_property_name(PropertyKey key)
 {
     if (key.is_symbol())
-        return DeprecatedString::formatted("[{}]", key.as_symbol()->description().value_or(""));
+        return DeprecatedString::formatted("[{}]", key.as_symbol()->description().value_or(String {}));
     return key.to_string();
 }
 

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Reference.cpp

@@ -216,7 +216,7 @@ DeprecatedString Reference::to_deprecated_string() const
     if (!m_name.is_valid())
         builder.append("<invalid>"sv);
     else if (m_name.is_symbol())
-        builder.appendff("{}", m_name.as_symbol()->descriptive_string());
+        builder.appendff("{}", m_name.as_symbol()->descriptive_string().release_value_but_fixme_should_propagate_errors());
     else
         builder.appendff("{}", m_name.to_string());
     builder.appendff(", Strict={}", m_strict);

+ 1 - 1
Userland/Libraries/LibJS/Runtime/StringConstructor.cpp

@@ -47,7 +47,7 @@ ThrowCompletionOr<Value> StringConstructor::call()
     if (!vm.argument_count())
         return PrimitiveString::create(vm, String {});
     if (vm.argument(0).is_symbol())
-        return PrimitiveString::create(vm, vm.argument(0).as_symbol().descriptive_string());
+        return PrimitiveString::create(vm, TRY_OR_THROW_OOM(vm, vm.argument(0).as_symbol().descriptive_string()));
     return TRY(vm.argument(0).to_primitive_string(vm));
 }
 

+ 1 - 1
Userland/Libraries/LibJS/Runtime/StringOrSymbol.h

@@ -79,7 +79,7 @@ public:
         if (is_string())
             return as_string();
         if (is_symbol())
-            return as_symbol()->descriptive_string();
+            return as_symbol()->descriptive_string().release_value_but_fixme_should_propagate_errors().to_deprecated_string();
         VERIFY_NOT_REACHED();
     }
 

+ 5 - 5
Userland/Libraries/LibJS/Runtime/Symbol.cpp

@@ -11,27 +11,27 @@
 
 namespace JS {
 
-Symbol::Symbol(Optional<DeprecatedString> description, bool is_global)
+Symbol::Symbol(Optional<String> description, bool is_global)
     : m_description(move(description))
     , m_is_global(is_global)
 {
 }
 
-NonnullGCPtr<Symbol> Symbol::create(VM& vm, Optional<DeprecatedString> description, bool is_global)
+NonnullGCPtr<Symbol> Symbol::create(VM& vm, Optional<String> description, bool is_global)
 {
     return vm.heap().allocate_without_realm<Symbol>(move(description), is_global);
 }
 
 // 20.4.3.3.1 SymbolDescriptiveString ( sym ), https://tc39.es/ecma262/#sec-symboldescriptivestring
-DeprecatedString Symbol::descriptive_string() const
+ErrorOr<String> Symbol::descriptive_string() const
 {
     // 1. Let desc be sym's [[Description]] value.
     // 2. If desc is undefined, set desc to the empty String.
     // 3. Assert: desc is a String.
-    auto description = m_description.value_or("");
+    auto description = m_description.value_or(String {});
 
     // 4. Return the string-concatenation of "Symbol(", desc, and ")".
-    return DeprecatedString::formatted("Symbol({})", description);
+    return String::formatted("Symbol({})", description);
 }
 
 }

+ 6 - 7
Userland/Libraries/LibJS/Runtime/Symbol.h

@@ -7,8 +7,7 @@
 
 #pragma once
 
-#include <AK/DeprecatedString.h>
-#include <AK/StringView.h>
+#include <AK/String.h>
 #include <LibJS/Heap/Cell.h>
 
 namespace JS {
@@ -17,19 +16,19 @@ class Symbol final : public Cell {
     JS_CELL(Symbol, Cell);
 
 public:
-    [[nodiscard]] static NonnullGCPtr<Symbol> create(VM&, Optional<DeprecatedString> description, bool is_global);
+    [[nodiscard]] static NonnullGCPtr<Symbol> create(VM&, Optional<String> description, bool is_global);
 
     virtual ~Symbol() = default;
 
-    Optional<DeprecatedString> const& description() const { return m_description; }
+    Optional<String> const& description() const { return m_description; }
     bool is_global() const { return m_is_global; }
 
-    DeprecatedString descriptive_string() const;
+    ErrorOr<String> descriptive_string() const;
 
 private:
-    Symbol(Optional<DeprecatedString>, bool);
+    Symbol(Optional<String>, bool);
 
-    Optional<DeprecatedString> m_description;
+    Optional<String> m_description;
     bool m_is_global;
 };
 

+ 3 - 3
Userland/Libraries/LibJS/Runtime/SymbolConstructor.cpp

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org>
- * Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2022-2023, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -44,7 +44,7 @@ ThrowCompletionOr<Value> SymbolConstructor::call()
     auto& vm = this->vm();
     if (vm.argument(0).is_undefined())
         return Symbol::create(vm, {}, false);
-    return Symbol::create(vm, TRY(vm.argument(0).to_deprecated_string(vm)), false);
+    return Symbol::create(vm, TRY(vm.argument(0).to_string(vm)), false);
 }
 
 // 20.4.1.1 Symbol ( [ description ] ), https://tc39.es/ecma262/#sec-symbol-description
@@ -57,7 +57,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> SymbolConstructor::construct(FunctionObj
 JS_DEFINE_NATIVE_FUNCTION(SymbolConstructor::for_)
 {
     // 1. Let stringKey be ? ToString(key).
-    auto string_key = TRY(vm.argument(0).to_deprecated_string(vm));
+    auto string_key = TRY(vm.argument(0).to_string(vm));
 
     // 2. For each element e of the GlobalSymbolRegistry List, do
     auto result = vm.global_symbol_registry().get(string_key);

+ 1 - 1
Userland/Libraries/LibJS/Runtime/SymbolPrototype.cpp

@@ -63,7 +63,7 @@ JS_DEFINE_NATIVE_FUNCTION(SymbolPrototype::description_getter)
 JS_DEFINE_NATIVE_FUNCTION(SymbolPrototype::to_string)
 {
     auto* symbol = TRY(this_symbol_value(vm, vm.this_value()));
-    return PrimitiveString::create(vm, symbol->descriptive_string());
+    return PrimitiveString::create(vm, TRY_OR_THROW_OOM(vm, symbol->descriptive_string()));
 }
 
 // 20.4.3.4 Symbol.prototype.valueOf ( ), https://tc39.es/ecma262/#sec-symbol.prototype.valueof

+ 3 - 2
Userland/Libraries/LibJS/Runtime/VM.cpp

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
- * Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2020-2023, Linus Groh <linusg@serenityos.org>
  * Copyright (c) 2021-2022, David Tuin <davidot@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
@@ -10,6 +10,7 @@
 #include <AK/Debug.h>
 #include <AK/LexicalPath.h>
 #include <AK/ScopeGuard.h>
+#include <AK/String.h>
 #include <AK/StringBuilder.h>
 #include <LibCore/File.h>
 #include <LibJS/AST.h>
@@ -149,7 +150,7 @@ VM::VM(OwnPtr<CustomData> custom_data)
     };
 
 #define __JS_ENUMERATE(SymbolName, snake_name) \
-    m_well_known_symbol_##snake_name = Symbol::create(*this, "Symbol." #SymbolName, false);
+    m_well_known_symbol_##snake_name = Symbol::create(*this, String::from_utf8("Symbol." #SymbolName##sv).release_value_but_fixme_should_propagate_errors(), false);
     JS_ENUMERATE_WELL_KNOWN_SYMBOLS
 #undef __JS_ENUMERATE
 }

+ 4 - 4
Userland/Libraries/LibJS/Runtime/VM.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- * Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2020-2023, Linus Groh <linusg@serenityos.org>
  * Copyright (c) 2021-2022, David Tuin <davidot@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
@@ -176,8 +176,8 @@ public:
 
     StackInfo const& stack_info() const { return m_stack_info; };
 
-    HashMap<DeprecatedString, NonnullGCPtr<Symbol>> const& global_symbol_registry() const { return m_global_symbol_registry; }
-    HashMap<DeprecatedString, NonnullGCPtr<Symbol>>& global_symbol_registry() { return m_global_symbol_registry; }
+    HashMap<String, NonnullGCPtr<Symbol>> const& global_symbol_registry() const { return m_global_symbol_registry; }
+    HashMap<String, NonnullGCPtr<Symbol>>& global_symbol_registry() { return m_global_symbol_registry; }
 
     u32 execution_generation() const { return m_execution_generation; }
     void finish_execution_generation() { ++m_execution_generation; }
@@ -277,7 +277,7 @@ private:
     StackInfo m_stack_info;
 
     // GlobalSymbolRegistry, https://tc39.es/ecma262/#table-globalsymbolregistry-record-fields
-    HashMap<DeprecatedString, NonnullGCPtr<Symbol>> m_global_symbol_registry;
+    HashMap<String, NonnullGCPtr<Symbol>> m_global_symbol_registry;
 
     Vector<Function<ThrowCompletionOr<Value>()>> m_promise_jobs;
 

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Value.cpp

@@ -372,7 +372,7 @@ DeprecatedString Value::to_string_without_side_effects() const
     case STRING_TAG:
         return MUST(as_string().deprecated_string());
     case SYMBOL_TAG:
-        return as_symbol().descriptive_string();
+        return as_symbol().descriptive_string().release_value_but_fixme_should_propagate_errors().to_deprecated_string();
     case BIGINT_TAG:
         return as_bigint().to_deprecated_string();
     case OBJECT_TAG: