From 0efa98a57a5a7bee63ed284fc38feccfc5ca9e62 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Sat, 2 Aug 2025 19:27:29 -0400 Subject: [PATCH] LibJS+LibWeb+WebContent: Port JS::PropertyKey to UTF-16 This has quite a lot of fall out. But the majority of it is just type or UDL substitution, where the changes just fall through to other function calls. By changing property key storage to UTF-16, the main affected areas are: * NativeFunction names must now be UTF-16 * Bytecode identifiers must now be UTF-16 * Module/binding names must now be UTF-16 --- Libraries/LibJS/AST.cpp | 98 ++++++++++--------- Libraries/LibJS/AST.h | 8 +- Libraries/LibJS/Bytecode/Executable.h | 8 +- Libraries/LibJS/Bytecode/Generator.h | 7 +- Libraries/LibJS/Bytecode/IdentifierTable.cpp | 4 +- Libraries/LibJS/Bytecode/IdentifierTable.h | 8 +- Libraries/LibJS/Bytecode/Interpreter.cpp | 24 ++--- Libraries/LibJS/Bytecode/Interpreter.h | 2 +- Libraries/LibJS/Console.cpp | 2 +- Libraries/LibJS/Contrib/Test262/262Object.cpp | 16 +-- .../LibJS/Contrib/Test262/AgentObject.cpp | 4 +- .../LibJS/Contrib/Test262/GlobalObject.cpp | 4 +- Libraries/LibJS/Contrib/Test262/IsHTMLDDA.cpp | 2 +- Libraries/LibJS/MarkupGenerator.cpp | 2 +- Libraries/LibJS/Module.cpp | 6 +- Libraries/LibJS/Module.h | 12 +-- .../LibJS/Runtime/AbstractOperations.cpp | 88 +++++++++-------- Libraries/LibJS/Runtime/AbstractOperations.h | 2 +- Libraries/LibJS/Runtime/ArgumentsObject.cpp | 2 +- Libraries/LibJS/Runtime/ArgumentsObject.h | 4 +- Libraries/LibJS/Runtime/CommonPropertyNames.h | 42 ++++---- .../LibJS/Runtime/DeclarativeEnvironment.cpp | 18 ++-- .../LibJS/Runtime/DeclarativeEnvironment.h | 30 +++--- .../Runtime/ECMAScriptFunctionObject.cpp | 44 +++++---- .../LibJS/Runtime/ECMAScriptFunctionObject.h | 18 ++-- Libraries/LibJS/Runtime/Environment.h | 14 +-- Libraries/LibJS/Runtime/Error.h | 1 + .../LibJS/Runtime/FunctionConstructor.cpp | 2 +- Libraries/LibJS/Runtime/FunctionObject.cpp | 10 +- Libraries/LibJS/Runtime/GlobalEnvironment.cpp | 26 ++--- Libraries/LibJS/Runtime/GlobalEnvironment.h | 26 ++--- .../LibJS/Runtime/Intl/DurationFormat.cpp | 6 +- Libraries/LibJS/Runtime/Intl/DurationFormat.h | 2 +- Libraries/LibJS/Runtime/Intrinsics.cpp | 2 +- Libraries/LibJS/Runtime/JSONObject.cpp | 32 +++--- Libraries/LibJS/Runtime/JSONObject.h | 4 +- Libraries/LibJS/Runtime/ModuleEnvironment.cpp | 10 +- Libraries/LibJS/Runtime/ModuleEnvironment.h | 14 +-- .../LibJS/Runtime/ModuleNamespaceObject.cpp | 6 +- .../LibJS/Runtime/ModuleNamespaceObject.h | 6 +- Libraries/LibJS/Runtime/NativeFunction.cpp | 6 +- Libraries/LibJS/Runtime/NativeFunction.h | 18 ++-- Libraries/LibJS/Runtime/Object.cpp | 6 +- Libraries/LibJS/Runtime/ObjectEnvironment.cpp | 14 +-- Libraries/LibJS/Runtime/ObjectEnvironment.h | 14 +-- .../LibJS/Runtime/PrivateEnvironment.cpp | 4 +- Libraries/LibJS/Runtime/PrivateEnvironment.h | 12 +-- Libraries/LibJS/Runtime/PropertyKey.h | 46 ++++----- Libraries/LibJS/Runtime/Reference.cpp | 2 +- Libraries/LibJS/Runtime/Reference.h | 4 +- Libraries/LibJS/Runtime/RegExpPrototype.cpp | 6 +- Libraries/LibJS/Runtime/ShadowRealm.cpp | 8 +- Libraries/LibJS/Runtime/StringConstructor.cpp | 2 +- Libraries/LibJS/Runtime/Symbol.cpp | 12 +-- Libraries/LibJS/Runtime/Symbol.h | 14 +-- Libraries/LibJS/Runtime/SymbolConstructor.cpp | 6 +- Libraries/LibJS/Runtime/SymbolPrototype.cpp | 2 +- Libraries/LibJS/Runtime/Temporal/Calendar.cpp | 2 +- Libraries/LibJS/Runtime/TypedArray.cpp | 3 +- Libraries/LibJS/Runtime/TypedArray.h | 4 +- .../LibJS/Runtime/TypedArrayConstructor.cpp | 2 +- .../LibJS/Runtime/TypedArrayConstructor.h | 2 +- Libraries/LibJS/Runtime/VM.cpp | 6 +- Libraries/LibJS/Runtime/VM.h | 10 +- Libraries/LibJS/Runtime/Value.cpp | 6 +- Libraries/LibJS/SourceTextModule.cpp | 56 ++++++----- Libraries/LibJS/SourceTextModule.h | 4 +- Libraries/LibJS/SyntheticModule.cpp | 12 +-- Libraries/LibJS/SyntheticModule.h | 10 +- Libraries/LibTest/JavaScriptTestRunner.h | 17 ++-- .../LibTest/JavaScriptTestRunnerMain.cpp | 2 +- .../LibWeb/Animations/KeyframeEffect.cpp | 11 ++- Libraries/LibWeb/Bindings/MainThreadVM.cpp | 4 +- Libraries/LibWeb/Bindings/PlatformObject.cpp | 12 +-- Libraries/LibWeb/Crypto/Crypto.cpp | 2 +- Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp | 72 +++++++------- Libraries/LibWeb/Crypto/CryptoAlgorithms.h | 2 +- Libraries/LibWeb/Crypto/CryptoBindings.cpp | 34 +++---- Libraries/LibWeb/Crypto/CryptoKey.cpp | 6 +- Libraries/LibWeb/Crypto/KeyAlgorithms.cpp | 16 +-- Libraries/LibWeb/Crypto/SubtleCrypto.cpp | 4 +- Libraries/LibWeb/DOM/Document.cpp | 2 +- Libraries/LibWeb/DOM/Element.cpp | 2 +- Libraries/LibWeb/DOM/EventDispatcher.cpp | 2 +- Libraries/LibWeb/DOM/EventTarget.cpp | 4 +- Libraries/LibWeb/DOM/NodeIterator.cpp | 2 +- Libraries/LibWeb/DOM/TreeWalker.cpp | 2 +- .../LibWeb/HTML/Canvas/CanvasSettings.cpp | 10 +- .../CustomElements/CustomElementRegistry.cpp | 4 +- Libraries/LibWeb/HTML/HTMLAllCollection.cpp | 4 +- Libraries/LibWeb/HTML/HTMLDialogElement.cpp | 4 +- Libraries/LibWeb/HTML/HTMLElement.cpp | 2 +- Libraries/LibWeb/HTML/HTMLInputElement.cpp | 24 ++--- Libraries/LibWeb/HTML/Scripting/ImportMap.cpp | 22 ++--- Libraries/LibWeb/HTML/StructuredSerialize.cpp | 12 +-- .../LibWeb/HTML/UniversalGlobalScope.cpp | 4 +- Libraries/LibWeb/HTML/Window.cpp | 2 +- .../LibWeb/HTML/WindowOrWorkerGlobalScope.cpp | 2 +- Libraries/LibWeb/HTML/WindowProxy.cpp | 2 +- Libraries/LibWeb/IndexedDB/IDBFactory.cpp | 4 +- .../LibWeb/IndexedDB/Internal/Algorithms.cpp | 18 ++-- Libraries/LibWeb/Infra/JSON.cpp | 2 +- Libraries/LibWeb/Internals/Internals.cpp | 4 +- .../MediaCapabilities.cpp | 6 +- .../LibWeb/Streams/AbstractOperations.cpp | 2 +- Libraries/LibWeb/Streams/Transformer.cpp | 16 +-- Libraries/LibWeb/Streams/UnderlyingSink.cpp | 12 +-- Libraries/LibWeb/Streams/UnderlyingSource.cpp | 12 +-- Libraries/LibWeb/WebAssembly/Instance.cpp | 12 ++- Libraries/LibWeb/WebAssembly/WebAssembly.cpp | 28 +++--- Libraries/LibWeb/WebAssembly/WebAssembly.h | 6 +- Libraries/LibWeb/WebDriver/Contexts.cpp | 6 +- .../LibWeb/WebDriver/ElementReference.cpp | 4 +- Libraries/LibWeb/WebDriver/ExecuteScript.cpp | 2 +- Libraries/LibWeb/WebDriver/JSON.cpp | 2 +- .../LibWeb/WebGL/WebGLContextAttributes.cpp | 18 ++-- .../LibWeb/WebIDL/AbstractOperations.cpp | 2 +- Libraries/LibWeb/WebIDL/AbstractOperations.h | 2 +- Libraries/LibWeb/WebIDL/ExceptionOr.h | 2 +- .../LibWeb/WebIDL/OverloadResolution.cpp | 2 +- Meta/Lagom/Fuzzers/FuzzilliJs.cpp | 4 +- .../BindingsGenerator/IDLGenerators.cpp | 44 ++++----- .../GenerateWindowOrWorkerInterfaces.cpp | 12 +-- .../ConsoleGlobalEnvironmentExtensions.cpp | 8 +- Services/WebContent/DevToolsConsoleClient.cpp | 2 +- Services/WebContent/WebDriverConnection.cpp | 2 +- Services/WebContent/WebUIConnection.cpp | 2 +- Tests/LibJS/test-js.cpp | 2 +- Tests/LibWasm/test-wasm.cpp | 8 +- Utilities/js.cpp | 41 ++++---- Utilities/test262-runner.cpp | 8 +- 131 files changed, 766 insertions(+), 726 deletions(-) diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp index c86e452452..00e9de1515 100644 --- a/Libraries/LibJS/AST.cpp +++ b/Libraries/LibJS/AST.cpp @@ -64,7 +64,7 @@ static void print_indent(int indent) out("{}", ByteString::repeated(' ', indent * 2)); } -static void update_function_name(Value value, FlyString const& name) +static void update_function_name(Value value, Utf16FlyString const& name) { if (!value.is_function()) return; @@ -88,20 +88,23 @@ void LabelledStatement::dump(int indent) const } // 15.2.5 Runtime Semantics: InstantiateOrdinaryFunctionExpression, https://tc39.es/ecma262/#sec-runtime-semantics-instantiateordinaryfunctionexpression -Value FunctionExpression::instantiate_ordinary_function_expression(VM& vm, FlyString given_name) const +Value FunctionExpression::instantiate_ordinary_function_expression(VM& vm, Utf16FlyString given_name) const { auto& realm = *vm.current_realm(); if (given_name.is_empty()) - given_name = ""_fly_string; + given_name = Utf16FlyString {}; + auto has_own_name = !name().is_empty(); - auto const used_name = has_own_name ? name() : given_name; + auto own_name = Utf16FlyString::from_utf8(name()); + auto const& used_name = has_own_name ? own_name : given_name; + auto environment = GC::Ref { *vm.running_execution_context().lexical_environment }; if (has_own_name) { VERIFY(environment); environment = new_declarative_environment(*environment); - MUST(environment->create_immutable_binding(vm, name(), false)); + MUST(environment->create_immutable_binding(vm, own_name, false)); } auto private_environment = vm.running_execution_context().private_environment; @@ -112,7 +115,7 @@ Value FunctionExpression::instantiate_ordinary_function_expression(VM& vm, FlySt // FIXME: 7. Perform MakeConstructor(closure). if (has_own_name) - MUST(environment->initialize_binding(vm, name(), closure, Environment::InitializeBindingHint::Normal)); + MUST(environment->initialize_binding(vm, own_name, closure, Environment::InitializeBindingHint::Normal)); return closure; } @@ -134,7 +137,7 @@ static ThrowCompletionOr class_key_to_property_name(VM& vm, Ex auto& private_identifier = static_cast(key); auto private_environment = vm.running_execution_context().private_environment; VERIFY(private_environment); - return ClassElementName { private_environment->resolve_private_identifier(private_identifier.string()) }; + return ClassElementName { private_environment->resolve_private_identifier(Utf16FlyString::from_utf8(private_identifier.string())) }; } VERIFY(!prop_key.is_special_empty_value()); @@ -153,7 +156,7 @@ ThrowCompletionOr ClassMethod::class_element_evaluatio auto& method_function = *ECMAScriptFunctionObject::create_from_function_node( *m_function, - m_function->name(), + Utf16String::from_utf8(m_function->name()), *vm.current_realm(), vm.lexical_environment(), vm.running_execution_context().private_environment); @@ -161,22 +164,22 @@ ThrowCompletionOr ClassMethod::class_element_evaluatio auto method_value = Value(&method_function); method_function.make_method(target); - auto set_function_name = [&](ByteString prefix = "") { + auto set_function_name = [&](StringView prefix = {}) { auto name = property_key_or_private_name.visit( - [&](PropertyKey const& property_key) -> String { + [&](PropertyKey const& property_key) { if (property_key.is_symbol()) { auto description = property_key.as_symbol()->description(); if (!description.has_value() || description->is_empty()) - return ""_string; - return MUST(String::formatted("[{}]", *description)); + return Utf16String {}; + return Utf16String::formatted("[{}]", *description); } return property_key.to_string(); }, - [&](PrivateName const& private_name) -> String { - return private_name.description.to_string(); + [&](PrivateName const& private_name) { + return private_name.description.to_utf16_string(); }); - update_function_name(method_value, MUST(String::formatted("{}{}{}", prefix, prefix.is_empty() ? "" : " ", name))); + update_function_name(method_value, Utf16String::formatted("{}{}{}", prefix, prefix.is_empty() ? "" : " ", name)); }; if (property_key_or_private_name.has()) { @@ -187,11 +190,11 @@ ThrowCompletionOr ClassMethod::class_element_evaluatio 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"); + set_function_name("get"sv); TRY(target.define_property_or_throw(property_key, { .get = &method_function, .enumerable = true, .configurable = true })); break; case ClassMethod::Kind::Setter: - set_function_name("set"); + set_function_name("set"sv); TRY(target.define_property_or_throw(property_key, { .set = &method_function, .enumerable = true, .configurable = true })); break; default: @@ -206,10 +209,10 @@ ThrowCompletionOr ClassMethod::class_element_evaluatio set_function_name(); return ClassValue { PrivateElement { private_name, PrivateElement::Kind::Method, method_value } }; case Kind::Getter: - set_function_name("get"); + set_function_name("get"sv); return ClassValue { PrivateElement { private_name, PrivateElement::Kind::Accessor, Value(Accessor::create(vm, &method_function, nullptr)) } }; case Kind::Setter: - set_function_name("set"); + set_function_name("set"sv); return ClassValue { PrivateElement { private_name, PrivateElement::Kind::Accessor, Value(Accessor::create(vm, nullptr, &method_function)) } }; default: VERIFY_NOT_REACHED(); @@ -242,19 +245,19 @@ ThrowCompletionOr ClassField::class_element_evaluation } else { auto copy_initializer = m_initializer; auto name = property_key_or_private_name.visit( - [&](PropertyKey const& property_key) -> String { + [&](PropertyKey const& property_key) { return property_key.to_string(); }, - [&](PrivateName const& private_name) -> String { - return private_name.description.to_string(); + [&](PrivateName const& private_name) { + return private_name.description.to_utf16_string(); }); // FIXME: A potential optimization is not creating the functions here since these are never directly accessible. - auto function_code = create_ast_node(m_initializer->source_range(), copy_initializer.release_nonnull(), name); + auto function_code = create_ast_node(m_initializer->source_range(), copy_initializer.release_nonnull(), name.to_utf8_but_should_be_ported_to_utf16()); FunctionParsingInsights parsing_insights; parsing_insights.uses_this_from_environment = true; parsing_insights.uses_this = true; - auto function = ECMAScriptFunctionObject::create(realm, "field"_string, ByteString::empty(), *function_code, FunctionParameters::empty(), 0, {}, vm.lexical_environment(), vm.running_execution_context().private_environment, FunctionKind::Normal, true, parsing_insights, false, property_key_or_private_name); + auto function = ECMAScriptFunctionObject::create(realm, "field"_utf16_fly_string, ByteString::empty(), *function_code, FunctionParameters::empty(), 0, {}, vm.lexical_environment(), vm.running_execution_context().private_environment, FunctionKind::Normal, true, parsing_insights, false, property_key_or_private_name); function->make_method(target); initializer = function; } @@ -303,7 +306,7 @@ ThrowCompletionOr StaticInitializer::class_element_eva FunctionParsingInsights parsing_insights; parsing_insights.uses_this_from_environment = true; parsing_insights.uses_this = true; - auto body_function = ECMAScriptFunctionObject::create(realm, ""_string, ByteString::empty(), *m_function_body, FunctionParameters::empty(), 0, m_function_body->local_variables_names(), lexical_environment, private_environment, FunctionKind::Normal, true, parsing_insights, false); + auto body_function = ECMAScriptFunctionObject::create(realm, {}, ByteString::empty(), *m_function_body, FunctionParameters::empty(), 0, m_function_body->local_variables_names(), lexical_environment, private_environment, FunctionKind::Normal, true, parsing_insights, false); // 6. Perform MakeMethod(bodyFunction, homeObject). body_function->make_method(home_object); @@ -312,7 +315,7 @@ ThrowCompletionOr StaticInitializer::class_element_eva return ClassValue { normal_completion(body_function) }; } -ThrowCompletionOr ClassExpression::create_class_constructor(VM& vm, Environment* class_environment, Environment* environment, Value super_class, ReadonlySpan element_keys, Optional const& binding_name, FlyString const& class_name) const +ThrowCompletionOr ClassExpression::create_class_constructor(VM& vm, Environment* class_environment, Environment* environment, Value super_class, ReadonlySpan element_keys, Optional const& binding_name, Utf16FlyString const& class_name) const { auto& realm = *vm.current_realm(); @@ -352,7 +355,7 @@ ThrowCompletionOr ClassExpression::create_class_const auto const& constructor = *m_constructor; auto class_constructor = ECMAScriptFunctionObject::create_from_function_node( constructor, - constructor.name(), + Utf16FlyString::from_utf8(constructor.name()), realm, vm.lexical_environment(), vm.running_execution_context().private_environment); @@ -1632,13 +1635,14 @@ void ScopeNode::block_declaration_instantiation(VM& vm, Environment* environment // NOTE: Due to the use of MUST with `create_immutable_binding` and `create_mutable_binding` below, // an exception should not result from `for_each_bound_name`. // a. For each element dn of the BoundNames of d, do - MUST(declaration.for_each_bound_identifier([&](auto const& identifier) { + MUST(declaration.for_each_bound_identifier([&](Identifier const& identifier) { if (identifier.is_local()) { // NOTE: No need to create bindings for local variables as their values are not stored in an environment. return; } - auto const& name = identifier.string(); + auto name = Utf16FlyString::from_utf8(identifier.string()); + // i. If IsConstantDeclaration of d is true, then if (is_constant_declaration) { // 1. Perform ! env.CreateImmutableBinding(dn, true). @@ -1660,7 +1664,7 @@ void ScopeNode::block_declaration_instantiation(VM& vm, Environment* environment // ii. Let fo be InstantiateFunctionObject of d with arguments env and privateEnv. auto function = ECMAScriptFunctionObject::create_from_function_node( function_declaration, - function_declaration.name(), + Utf16FlyString::from_utf8(function_declaration.name()), realm, environment, private_environment); @@ -1678,7 +1682,7 @@ void ScopeNode::block_declaration_instantiation(VM& vm, Environment* environment } } else { VERIFY(is(*environment)); - static_cast(*environment).initialize_or_set_mutable_binding({}, vm, function_declaration.name(), function); + static_cast(*environment).initialize_or_set_mutable_binding({}, vm, function->name(), function); } } })); @@ -1693,7 +1697,7 @@ ThrowCompletionOr Program::global_declaration_instantiation(VM& vm, Global // 2. Let varNames be the VarDeclaredNames of script. // 3. For each element name of lexNames, do TRY(for_each_lexically_declared_identifier([&](Identifier const& identifier) -> ThrowCompletionOr { - auto const& name = identifier.string(); + auto name = Utf16FlyString::from_utf8(identifier.string()); // a. If HasLexicalDeclaration(env, name) is true, throw a SyntaxError exception. if (global_environment.has_lexical_declaration(name)) @@ -1713,9 +1717,9 @@ ThrowCompletionOr Program::global_declaration_instantiation(VM& vm, Global })); // 4. For each element name of varNames, do - TRY(for_each_var_declared_identifier([&](auto const& identifier) -> ThrowCompletionOr { + TRY(for_each_var_declared_identifier([&](Identifier const& identifier) -> ThrowCompletionOr { // a. If env.HasLexicalDeclaration(name) is true, throw a SyntaxError exception. - if (global_environment.has_lexical_declaration(identifier.string())) + if (global_environment.has_lexical_declaration(Utf16FlyString::from_utf8(identifier.string()))) return vm.throw_completion(ErrorType::TopLevelVariableAlreadyDeclared, identifier.string()); return {}; @@ -1726,11 +1730,13 @@ ThrowCompletionOr Program::global_declaration_instantiation(VM& vm, Global Vector functions_to_initialize; // 7. Let declaredFunctionNames be a new empty List. - HashTable declared_function_names; + HashTable declared_function_names; // 8. For each element d of varDeclarations, in reverse List order, do TRY(for_each_var_function_declaration_in_reverse_order([&](FunctionDeclaration const& function) -> ThrowCompletionOr { + auto function_name = Utf16FlyString::from_utf8(function.name()); + // a. If d is neither a VariableDeclaration nor a ForBinding nor a BindingIdentifier, then // i. Assert: d is either a FunctionDeclaration, a GeneratorDeclaration, an AsyncFunctionDeclaration, or an AsyncGeneratorDeclaration. // Note: This is checked in for_each_var_function_declaration_in_reverse_order. @@ -1740,11 +1746,11 @@ ThrowCompletionOr Program::global_declaration_instantiation(VM& vm, Global // iii. Let fn be the sole element of the BoundNames of d. // iv. If fn is not an element of declaredFunctionNames, then - if (declared_function_names.set(function.name()) != AK::HashSetResult::InsertedNewEntry) + if (declared_function_names.set(function_name) != AK::HashSetResult::InsertedNewEntry) return {}; // 1. Let fnDefinable be ? env.CanDeclareGlobalFunction(fn). - auto function_definable = TRY(global_environment.can_declare_global_function(function.name())); + auto function_definable = TRY(global_environment.can_declare_global_function(function_name)); // 2. If fnDefinable is false, throw a TypeError exception. if (!function_definable) @@ -1761,7 +1767,7 @@ ThrowCompletionOr Program::global_declaration_instantiation(VM& vm, Global })); // 9. Let declaredVarNames be a new empty List. - HashTable declared_var_names; + HashTable declared_var_names; // 10. For each element d of varDeclarations, do TRY(for_each_var_scoped_variable_declaration([&](Declaration const& declaration) { @@ -1769,8 +1775,9 @@ ThrowCompletionOr Program::global_declaration_instantiation(VM& vm, Global // Note: This is done in for_each_var_scoped_variable_declaration. // i. For each String vn of the BoundNames of d, do - return declaration.for_each_bound_identifier([&](auto const& identifier) -> ThrowCompletionOr { - auto const& name = identifier.string(); + return declaration.for_each_bound_identifier([&](Identifier const& identifier) -> ThrowCompletionOr { + auto name = Utf16FlyString::from_utf8(identifier.string()); + // 1. If vn is not an element of declaredFunctionNames, then if (declared_function_names.contains(name)) return {}; @@ -1799,7 +1806,7 @@ ThrowCompletionOr Program::global_declaration_instantiation(VM& vm, Global // b. For each FunctionDeclaration f that is directly contained in the StatementList of a Block, CaseClause, or DefaultClause Contained within script, do TRY(for_each_function_hoistable_with_annexB_extension([&](FunctionDeclaration& function_declaration) -> ThrowCompletionOr { // i. Let F be StringValue of the BindingIdentifier of f. - auto function_name = function_declaration.name(); + auto function_name = Utf16FlyString::from_utf8(function_declaration.name()); // ii. If replacing the FunctionDeclaration f with a VariableStatement that has F as a BindingIdentifier would not produce any Early Errors for script, then // Note: This step is already performed during parsing and for_each_function_hoistable_with_annexB_extension so this always passes here. @@ -1850,8 +1857,9 @@ ThrowCompletionOr Program::global_declaration_instantiation(VM& vm, Global TRY(for_each_lexically_scoped_declaration([&](Declaration const& declaration) { // a. NOTE: Lexically declared names are only instantiated here but not initialized. // b. For each element dn of the BoundNames of d, do - return declaration.for_each_bound_identifier([&](auto const& identifier) -> ThrowCompletionOr { - auto const& name = identifier.string(); + return declaration.for_each_bound_identifier([&](Identifier const& identifier) -> ThrowCompletionOr { + auto name = Utf16FlyString::from_utf8(identifier.string()); + // i. If IsConstantDeclaration of d is true, then if (declaration.is_constant_declaration()) { // 1. Perform ? env.CreateImmutableBinding(dn, true). @@ -1876,13 +1884,13 @@ ThrowCompletionOr Program::global_declaration_instantiation(VM& vm, Global // b. Let fo be InstantiateFunctionObject of f with arguments env and privateEnv. auto function = ECMAScriptFunctionObject::create_from_function_node( declaration, - declaration.name(), + Utf16FlyString::from_utf8(declaration.name()), realm, &global_environment, private_environment); // c. Perform ? env.CreateGlobalFunctionBinding(fn, fo, false). - TRY(global_environment.create_global_function_binding(declaration.name(), function, false)); + TRY(global_environment.create_global_function_binding(function->name(), function, false)); } // 17. For each String vn of declaredVarNames, do diff --git a/Libraries/LibJS/AST.h b/Libraries/LibJS/AST.h index 1f1b81063c..303a90f07f 100644 --- a/Libraries/LibJS/AST.h +++ b/Libraries/LibJS/AST.h @@ -797,7 +797,7 @@ public: bool uses_this_from_environment() const { return m_parsing_insights.uses_this_from_environment; } virtual bool has_name() const = 0; - virtual Value instantiate_ordinary_function_expression(VM&, FlyString given_name) const = 0; + virtual Value instantiate_ordinary_function_expression(VM&, Utf16FlyString given_name) const = 0; RefPtr shared_data() const; void set_shared_data(RefPtr) const; @@ -847,7 +847,7 @@ public: void set_should_do_additional_annexB_steps() { m_is_hoisted = true; } bool has_name() const override { return true; } - Value instantiate_ordinary_function_expression(VM&, FlyString) const override { VERIFY_NOT_REACHED(); } + Value instantiate_ordinary_function_expression(VM&, Utf16FlyString) const override { VERIFY_NOT_REACHED(); } virtual ~FunctionDeclaration() { } @@ -874,7 +874,7 @@ public: bool has_name() const override { return !name().is_empty(); } - Value instantiate_ordinary_function_expression(VM&, FlyString given_name) const override; + Value instantiate_ordinary_function_expression(VM&, Utf16FlyString given_name) const override; virtual ~FunctionExpression() { } @@ -1518,7 +1518,7 @@ public: bool has_name() const { return m_name; } - ThrowCompletionOr create_class_constructor(VM&, Environment* class_environment, Environment* environment, Value super_class, ReadonlySpan element_keys, Optional const& binding_name = {}, FlyString const& class_name = {}) const; + ThrowCompletionOr create_class_constructor(VM&, Environment* class_environment, Environment* environment, Value super_class, ReadonlySpan element_keys, Optional const& binding_name = {}, Utf16FlyString const& class_name = {}) const; private: virtual bool is_class_expression() const override { return true; } diff --git a/Libraries/LibJS/Bytecode/Executable.h b/Libraries/LibJS/Bytecode/Executable.h index 950ae61cb6..912a67cdd9 100644 --- a/Libraries/LibJS/Bytecode/Executable.h +++ b/Libraries/LibJS/Bytecode/Executable.h @@ -6,10 +6,10 @@ #pragma once -#include #include #include #include +#include #include #include #include @@ -67,7 +67,7 @@ public: virtual ~Executable() override; - FlyString name; + Utf16FlyString name; Vector bytecode; Vector property_lookup_caches; Vector global_variable_caches; @@ -99,9 +99,9 @@ public: Optional length_identifier; String const& get_string(StringTableIndex index) const { return string_table->get(index); } - FlyString const& get_identifier(IdentifierTableIndex index) const { return identifier_table->get(index); } + Utf16FlyString const& get_identifier(IdentifierTableIndex index) const { return identifier_table->get(index); } - Optional get_identifier(Optional const& index) const + Optional get_identifier(Optional const& index) const { if (!index.has_value()) return {}; diff --git a/Libraries/LibJS/Bytecode/Generator.h b/Libraries/LibJS/Bytecode/Generator.h index e0cb070ac7..39cc90e218 100644 --- a/Libraries/LibJS/Bytecode/Generator.h +++ b/Libraries/LibJS/Bytecode/Generator.h @@ -212,7 +212,12 @@ public: return m_regex_table->insert(move(regex)); } - IdentifierTableIndex intern_identifier(FlyString string) + IdentifierTableIndex intern_identifier(FlyString const& string) + { + return intern_identifier(Utf16FlyString::from_utf8(string)); + } + + IdentifierTableIndex intern_identifier(Utf16FlyString string) { return m_identifier_table->insert(move(string)); } diff --git a/Libraries/LibJS/Bytecode/IdentifierTable.cpp b/Libraries/LibJS/Bytecode/IdentifierTable.cpp index 033d8dc6d8..a84d0ea2bf 100644 --- a/Libraries/LibJS/Bytecode/IdentifierTable.cpp +++ b/Libraries/LibJS/Bytecode/IdentifierTable.cpp @@ -8,14 +8,14 @@ namespace JS::Bytecode { -IdentifierTableIndex IdentifierTable::insert(FlyString string) +IdentifierTableIndex IdentifierTable::insert(Utf16FlyString string) { m_identifiers.append(move(string)); VERIFY(m_identifiers.size() <= NumericLimits::max()); return { static_cast(m_identifiers.size() - 1) }; } -FlyString const& IdentifierTable::get(IdentifierTableIndex index) const +Utf16FlyString const& IdentifierTable::get(IdentifierTableIndex index) const { return m_identifiers[index.value]; } diff --git a/Libraries/LibJS/Bytecode/IdentifierTable.h b/Libraries/LibJS/Bytecode/IdentifierTable.h index 5c1f1703ca..0d6f549bc8 100644 --- a/Libraries/LibJS/Bytecode/IdentifierTable.h +++ b/Libraries/LibJS/Bytecode/IdentifierTable.h @@ -7,7 +7,7 @@ #pragma once #include -#include +#include #include namespace JS::Bytecode { @@ -25,13 +25,13 @@ class IdentifierTable { public: IdentifierTable() = default; - IdentifierTableIndex insert(FlyString); - FlyString const& get(IdentifierTableIndex) const; + IdentifierTableIndex insert(Utf16FlyString); + Utf16FlyString const& get(IdentifierTableIndex) const; void dump() const; bool is_empty() const { return m_identifiers.is_empty(); } private: - Vector m_identifiers; + Vector m_identifiers; }; } diff --git a/Libraries/LibJS/Bytecode/Interpreter.cpp b/Libraries/LibJS/Bytecode/Interpreter.cpp index e4ea710e62..a4e7bd8a49 100644 --- a/Libraries/LibJS/Bytecode/Interpreter.cpp +++ b/Libraries/LibJS/Bytecode/Interpreter.cpp @@ -821,7 +821,7 @@ void Interpreter::enter_object_environment(Object& object) running_execution_context().lexical_environment = new_object_environment(object, true, old_environment); } -ThrowCompletionOr> compile(VM& vm, ASTNode const& node, FunctionKind kind, FlyString const& name) +ThrowCompletionOr> compile(VM& vm, ASTNode const& node, FunctionKind kind, Utf16FlyString const& name) { auto executable_result = Bytecode::Generator::generate_from_ast_node(vm, node, kind); if (executable_result.is_error()) @@ -1201,7 +1201,7 @@ inline ThrowCompletionOr get_global(Interpreter& interpreter, IdentifierT return vm.throw_completion(ErrorType::UnknownIdentifier, identifier); } -inline ThrowCompletionOr put_by_property_key(VM& vm, Value base, Value this_value, Value value, Optional const& base_identifier, PropertyKey name, Op::PropertyKind kind, PropertyLookupCache* caches = nullptr) +inline ThrowCompletionOr put_by_property_key(VM& vm, Value base, Value this_value, Value value, Optional const& base_identifier, PropertyKey name, Op::PropertyKind kind, PropertyLookupCache* caches = nullptr) { // Better error message than to_object would give if (vm.in_strict_mode() && base.is_nullish()) @@ -1221,14 +1221,14 @@ inline ThrowCompletionOr put_by_property_key(VM& vm, Value base, Value thi case Op::PropertyKind::Getter: { auto& function = value.as_function(); if (is(function) && static_cast(function).name().is_empty()) - static_cast(&function)->set_name(MUST(String::formatted("get {}", name))); + static_cast(&function)->set_name(Utf16String::formatted("get {}", name)); object->define_direct_accessor(name, &function, nullptr, Attribute::Configurable | Attribute::Enumerable); break; } case Op::PropertyKind::Setter: { auto& function = value.as_function(); if (is(function) && static_cast(function).name().is_empty()) - static_cast(&function)->set_name(MUST(String::formatted("set {}", name))); + static_cast(&function)->set_name(Utf16String::formatted("set {}", name)); object->define_direct_accessor(name, nullptr, &function, Attribute::Configurable | Attribute::Enumerable); break; } @@ -1354,14 +1354,14 @@ inline Value new_function(VM& vm, FunctionNode const& function_node, Optional put_by_value(VM& vm, Value base, Optional const& base_identifier, Value property_key_value, Value value, Op::PropertyKind kind) +inline ThrowCompletionOr put_by_value(VM& vm, Value base, Optional const& base_identifier, Value property_key_value, Value value, Op::PropertyKind kind) { // OPTIMIZATION: Fast path for simple Int32 indexes in array-like objects. if ((kind == Op::PropertyKind::KeyValue || kind == Op::PropertyKind::DirectKeyValue) @@ -1496,7 +1496,7 @@ struct CalleeAndThis { Value this_value; }; -inline ThrowCompletionOr get_callee_and_this_from_environment(Bytecode::Interpreter& interpreter, FlyString const& name, EnvironmentCoordinate& cache) +inline ThrowCompletionOr get_callee_and_this_from_environment(Bytecode::Interpreter& interpreter, Utf16FlyString const& name, EnvironmentCoordinate& cache) { auto& vm = interpreter.vm(); @@ -1583,7 +1583,7 @@ inline Span argument_list_evaluation(Interpreter& interpreter, Value argu return argument_values; } -inline ThrowCompletionOr create_variable(VM& vm, FlyString const& name, Op::EnvironmentMode mode, bool is_global, bool is_immutable, bool is_strict) +inline ThrowCompletionOr create_variable(VM& vm, Utf16FlyString const& name, Op::EnvironmentMode mode, bool is_global, bool is_immutable, bool is_strict) { if (mode == Op::EnvironmentMode::Lexical) { VERIFY(!is_global); @@ -1612,17 +1612,17 @@ inline ThrowCompletionOr create_variable(VM& vm, FlyString const& name, Op inline ThrowCompletionOr new_class(VM& vm, Value super_class, ClassExpression const& class_expression, Optional const& lhs_name, ReadonlySpan element_keys) { auto& interpreter = vm.bytecode_interpreter(); - auto name = class_expression.name(); // NOTE: NewClass expects classEnv to be active lexical environment auto* class_environment = vm.lexical_environment(); vm.running_execution_context().lexical_environment = vm.running_execution_context().saved_lexical_environments.take_last(); - Optional binding_name; - FlyString class_name; + Optional binding_name; + Utf16FlyString class_name; if (!class_expression.has_name() && lhs_name.has_value()) { class_name = interpreter.current_executable().get_identifier(lhs_name.value()); } else { + auto name = Utf16FlyString::from_utf8(class_expression.name()); binding_name = name; class_name = name; } diff --git a/Libraries/LibJS/Bytecode/Interpreter.h b/Libraries/LibJS/Bytecode/Interpreter.h index 8e305741b4..766cf5a97f 100644 --- a/Libraries/LibJS/Bytecode/Interpreter.h +++ b/Libraries/LibJS/Bytecode/Interpreter.h @@ -107,7 +107,7 @@ private: JS_API extern bool g_dump_bytecode; -ThrowCompletionOr> compile(VM&, ASTNode const&, JS::FunctionKind kind, FlyString const& name); +ThrowCompletionOr> compile(VM&, ASTNode const&, JS::FunctionKind kind, Utf16FlyString const& name); ThrowCompletionOr> compile(VM&, ECMAScriptFunctionObject const&); } diff --git a/Libraries/LibJS/Console.cpp b/Libraries/LibJS/Console.cpp index 44468a45e7..869dbb5267 100644 --- a/Libraries/LibJS/Console.cpp +++ b/Libraries/LibJS/Console.cpp @@ -172,7 +172,7 @@ static ThrowCompletionOr> create_table_row(Realm& realm, Value r // 2. Set `row["(index)"]` to `rowIndex` { - auto key = PropertyKey { "(index)"_fly_string, PropertyKey::StringMayBeNumber::No }; + auto key = PropertyKey { "(index)"_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; TRY(row->set(key, row_index, Object::ShouldThrowExceptions::No)); add_column(key); diff --git a/Libraries/LibJS/Contrib/Test262/262Object.cpp b/Libraries/LibJS/Contrib/Test262/262Object.cpp index c3a8ec8010..f2bb308e19 100644 --- a/Libraries/LibJS/Contrib/Test262/262Object.cpp +++ b/Libraries/LibJS/Contrib/Test262/262Object.cpp @@ -36,15 +36,15 @@ void $262Object::initialize(Realm& realm) m_is_htmldda = realm.create(realm); u8 attr = Attribute::Writable | Attribute::Configurable; - define_native_function(realm, "clearKeptObjects"_fly_string, clear_kept_objects, 0, attr); - define_native_function(realm, "createRealm"_fly_string, create_realm, 0, attr); - define_native_function(realm, "detachArrayBuffer"_fly_string, detach_array_buffer, 1, attr); - define_native_function(realm, "evalScript"_fly_string, eval_script, 1, attr); + define_native_function(realm, "clearKeptObjects"_utf16_fly_string, clear_kept_objects, 0, attr); + define_native_function(realm, "createRealm"_utf16_fly_string, create_realm, 0, attr); + define_native_function(realm, "detachArrayBuffer"_utf16_fly_string, detach_array_buffer, 1, attr); + define_native_function(realm, "evalScript"_utf16_fly_string, eval_script, 1, attr); - define_direct_property("agent"_fly_string, m_agent, attr); - define_direct_property("gc"_fly_string, realm.global_object().get_without_side_effects("gc"_fly_string), attr); - define_direct_property("global"_fly_string, &realm.global_object(), attr); - define_direct_property("IsHTMLDDA"_fly_string, m_is_htmldda, attr); + define_direct_property("agent"_utf16_fly_string, m_agent, attr); + define_direct_property("gc"_utf16_fly_string, realm.global_object().get_without_side_effects("gc"_utf16_fly_string), attr); + define_direct_property("global"_utf16_fly_string, &realm.global_object(), attr); + define_direct_property("IsHTMLDDA"_utf16_fly_string, m_is_htmldda, attr); } void $262Object::visit_edges(Cell::Visitor& visitor) diff --git a/Libraries/LibJS/Contrib/Test262/AgentObject.cpp b/Libraries/LibJS/Contrib/Test262/AgentObject.cpp index 95bb7efda6..538cf54497 100644 --- a/Libraries/LibJS/Contrib/Test262/AgentObject.cpp +++ b/Libraries/LibJS/Contrib/Test262/AgentObject.cpp @@ -24,8 +24,8 @@ void AgentObject::initialize(JS::Realm& realm) Base::initialize(realm); u8 attr = Attribute::Writable | Attribute::Configurable; - define_native_function(realm, "monotonicNow"_fly_string, monotonic_now, 0, attr); - define_native_function(realm, "sleep"_fly_string, sleep, 1, attr); + define_native_function(realm, "monotonicNow"_utf16_fly_string, monotonic_now, 0, attr); + define_native_function(realm, "sleep"_utf16_fly_string, sleep, 1, attr); // TODO: broadcast // TODO: getReport // TODO: start diff --git a/Libraries/LibJS/Contrib/Test262/GlobalObject.cpp b/Libraries/LibJS/Contrib/Test262/GlobalObject.cpp index f1a5f1d14a..b4b099cd06 100644 --- a/Libraries/LibJS/Contrib/Test262/GlobalObject.cpp +++ b/Libraries/LibJS/Contrib/Test262/GlobalObject.cpp @@ -24,8 +24,8 @@ void GlobalObject::initialize(Realm& realm) // https://github.com/tc39/test262/blob/master/INTERPRETING.md#host-defined-functions u8 attr = Attribute::Writable | Attribute::Configurable; - define_native_function(realm, "print"_fly_string, print, 1, attr); - define_direct_property("$262"_fly_string, m_$262, attr); + define_native_function(realm, "print"_utf16_fly_string, print, 1, attr); + define_direct_property("$262"_utf16_fly_string, m_$262, attr); } void GlobalObject::visit_edges(Cell::Visitor& visitor) diff --git a/Libraries/LibJS/Contrib/Test262/IsHTMLDDA.cpp b/Libraries/LibJS/Contrib/Test262/IsHTMLDDA.cpp index a6ba88506d..02d5e964a3 100644 --- a/Libraries/LibJS/Contrib/Test262/IsHTMLDDA.cpp +++ b/Libraries/LibJS/Contrib/Test262/IsHTMLDDA.cpp @@ -13,7 +13,7 @@ GC_DEFINE_ALLOCATOR(IsHTMLDDA); IsHTMLDDA::IsHTMLDDA(Realm& realm) // NativeFunction without prototype is currently not possible (only due to the lack of a ctor that supports it) - : NativeFunction("IsHTMLDDA"_fly_string, realm.intrinsics().function_prototype()) + : NativeFunction("IsHTMLDDA"_utf16_fly_string, realm.intrinsics().function_prototype()) { } diff --git a/Libraries/LibJS/MarkupGenerator.cpp b/Libraries/LibJS/MarkupGenerator.cpp index e3308faabd..672407f7bb 100644 --- a/Libraries/LibJS/MarkupGenerator.cpp +++ b/Libraries/LibJS/MarkupGenerator.cpp @@ -124,7 +124,7 @@ ErrorOr MarkupGenerator::object_to_html(Object const& object, StringBuilde size_t index = 0; for (auto& it : object.shape().property_table()) { - TRY(html_output.try_append(TRY(wrap_string_in_style(TRY(String::formatted("\"{}\"", escape_html_entities(it.key.to_string()))), StyleType::String)))); + TRY(html_output.try_append(TRY(wrap_string_in_style(TRY(String::formatted("\"{}\"", it.key.to_string().escape_html_entities())), StyleType::String)))); TRY(html_output.try_append(TRY(wrap_string_in_style(": "sv, StyleType::Punctuation)))); TRY(value_to_html(object.get_direct(it.value.offset), html_output, seen_objects)); if (index != object.shape().property_count() - 1) diff --git a/Libraries/LibJS/Module.cpp b/Libraries/LibJS/Module.cpp index c81e2fdbd8..0dacda66d1 100644 --- a/Libraries/LibJS/Module.cpp +++ b/Libraries/LibJS/Module.cpp @@ -155,7 +155,7 @@ GC::Ref Module::get_module_namespace(VM& vm) auto exported_names = get_exported_names(vm); // b. Let unambiguousNames be a new empty List. - Vector unambiguous_names; + Vector unambiguous_names; // c. For each element name of exportedNames, do for (auto& name : exported_names) { @@ -175,14 +175,14 @@ GC::Ref Module::get_module_namespace(VM& vm) return *namespace_; } -Vector Module::get_exported_names(VM& vm) +Vector Module::get_exported_names(VM& vm) { HashTable export_star_set; return get_exported_names(vm, export_star_set); } // 10.4.6.12 ModuleNamespaceCreate ( module, exports ), https://tc39.es/ecma262/#sec-modulenamespacecreate -GC::Ref Module::module_namespace_create(Vector unambiguous_names) +GC::Ref Module::module_namespace_create(Vector unambiguous_names) { auto& realm = this->realm(); diff --git a/Libraries/LibJS/Module.h b/Libraries/LibJS/Module.h index 9dd50e9e92..f26f26f0c1 100644 --- a/Libraries/LibJS/Module.h +++ b/Libraries/LibJS/Module.h @@ -7,7 +7,7 @@ #pragma once -#include +#include #include #include #include @@ -39,7 +39,7 @@ struct ResolvedBinding { Type type { Null }; GC::Ptr module; - FlyString export_name; + Utf16FlyString export_name; bool is_valid() const { @@ -110,10 +110,10 @@ public: virtual ThrowCompletionOr link(VM& vm) = 0; virtual ThrowCompletionOr> evaluate(VM& vm) = 0; - Vector get_exported_names(VM& vm); - virtual Vector get_exported_names(VM& vm, HashTable& export_star_set) = 0; + Vector get_exported_names(VM& vm); + virtual Vector get_exported_names(VM& vm, HashTable& export_star_set) = 0; - virtual ResolvedBinding resolve_export(VM& vm, FlyString const& export_name, Vector resolve_set = {}) = 0; + virtual ResolvedBinding resolve_export(VM& vm, Utf16FlyString const& export_name, Vector resolve_set = {}) = 0; virtual ThrowCompletionOr inner_module_linking(VM& vm, Vector& stack, u32 index); virtual ThrowCompletionOr inner_module_evaluation(VM& vm, Vector& stack, u32 index); @@ -131,7 +131,7 @@ protected: } private: - GC::Ref module_namespace_create(Vector unambiguous_names); + GC::Ref module_namespace_create(Vector unambiguous_names); ThrowCompletionOr evaluate_module_sync(VM&); // These handles are only safe as long as the VM they live in is valid. diff --git a/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Libraries/LibJS/Runtime/AbstractOperations.cpp index 4fed21face..e018127ba0 100644 --- a/Libraries/LibJS/Runtime/AbstractOperations.cpp +++ b/Libraries/LibJS/Runtime/AbstractOperations.cpp @@ -225,7 +225,7 @@ ThrowCompletionOr get_function_realm(VM& vm, FunctionObject const& funct } // 8.5.2.1 InitializeBoundName ( name, value, environment ), https://tc39.es/ecma262/#sec-initializeboundname -ThrowCompletionOr initialize_bound_name(VM& vm, FlyString const& name, Value value, Environment* environment) +ThrowCompletionOr initialize_bound_name(VM& vm, Utf16FlyString const& name, Value value, Environment* environment) { // 1. If environment is not undefined, then if (environment) { @@ -252,7 +252,7 @@ ThrowCompletionOr initialize_bound_name(VM& vm, FlyString const& name, Val bool is_compatible_property_descriptor(bool extensible, PropertyDescriptor const& descriptor, Optional const& current) { // 1. Return ValidateAndApplyPropertyDescriptor(undefined, "", Extensible, Desc, Current). - return validate_and_apply_property_descriptor(nullptr, FlyString {}, extensible, descriptor, current); + return validate_and_apply_property_descriptor(nullptr, Utf16FlyString {}, extensible, descriptor, current); } // 10.1.6.3 ValidateAndApplyPropertyDescriptor ( O, P, extensible, Desc, current ), https://tc39.es/ecma262/#sec-validateandapplypropertydescriptor @@ -701,7 +701,7 @@ ThrowCompletionOr perform_eval(VM& vm, Value x, CallerMode strict_caller, if (executable_result.is_error()) return vm.throw_completion(ErrorType::NotImplemented, TRY_OR_THROW_OOM(vm, executable_result.error().to_string())); auto executable = executable_result.release_value(); - executable->name = "eval"_fly_string; + executable->name = "eval"_utf16_fly_string; if (Bytecode::g_dump_bytecode) executable->dump(); @@ -770,9 +770,11 @@ ThrowCompletionOr eval_declaration_instantiation(VM& vm, Program const& pr // a. If varEnv is a global Environment Record, then if (global_var_environment) { // i. For each element name of varNames, do - TRY(program.for_each_var_declared_identifier([&](auto const& identifier) -> ThrowCompletionOr { + TRY(program.for_each_var_declared_identifier([&](Identifier const& identifier) -> ThrowCompletionOr { + auto name = Utf16FlyString::from_utf8(identifier.string()); + // 1. If varEnv.HasLexicalDeclaration(name) is true, throw a SyntaxError exception. - if (global_var_environment->has_lexical_declaration(identifier.string())) + if (global_var_environment->has_lexical_declaration(name)) return vm.throw_completion(ErrorType::TopLevelVariableAlreadyDeclared, identifier.string()); // 2. NOTE: eval will not create a global var declaration that would be shadowed by a global lexical declaration. @@ -790,8 +792,9 @@ ThrowCompletionOr eval_declaration_instantiation(VM& vm, Program const& pr if (!is(*this_environment)) { // 1. NOTE: The environment of with statements cannot contain any lexical declaration so it doesn't need to be checked for var/let hoisting conflicts. // 2. For each element name of varNames, do - TRY(program.for_each_var_declared_identifier([&](auto const& identifier) -> ThrowCompletionOr { - auto const& name = identifier.string(); + TRY(program.for_each_var_declared_identifier([&](Identifier const& identifier) -> ThrowCompletionOr { + auto name = Utf16FlyString::from_utf8(identifier.string()); + // a. If ! thisEnv.HasBinding(name) is true, then if (MUST(this_environment->has_binding(name))) { // i. Throw a SyntaxError exception. @@ -824,10 +827,12 @@ ThrowCompletionOr eval_declaration_instantiation(VM& vm, Program const& pr Vector functions_to_initialize; // 9. Let declaredFunctionNames be a new empty List. - HashTable declared_function_names; + HashTable declared_function_names; // 10. For each element d of varDeclarations, in reverse List order, do TRY(program.for_each_var_function_declaration_in_reverse_order([&](FunctionDeclaration const& function) -> ThrowCompletionOr { + auto function_name = Utf16FlyString::from_utf8(function.name()); + // a. If d is neither a VariableDeclaration nor a ForBinding nor a BindingIdentifier, then // i. Assert: d is either a FunctionDeclaration, a GeneratorDeclaration, an AsyncFunctionDeclaration, or an AsyncGeneratorDeclaration. // Note: This is done by for_each_var_function_declaration_in_reverse_order. @@ -835,18 +840,17 @@ ThrowCompletionOr eval_declaration_instantiation(VM& vm, Program const& pr // ii. NOTE: If there are multiple function declarations for the same name, the last declaration is used. // iii. Let fn be the sole element of the BoundNames of d. // iv. If fn is not an element of declaredFunctionNames, then - if (declared_function_names.set(function.name()) != AK::HashSetResult::InsertedNewEntry) + if (declared_function_names.set(function_name) != AK::HashSetResult::InsertedNewEntry) return {}; // 1. If varEnv is a global Environment Record, then if (global_var_environment) { // a. Let fnDefinable be ? varEnv.CanDeclareGlobalFunction(fn). - - auto function_definable = TRY(global_var_environment->can_declare_global_function(function.name())); + auto function_definable = TRY(global_var_environment->can_declare_global_function(function_name)); // b. If fnDefinable is false, throw a TypeError exception. if (!function_definable) - return vm.throw_completion(ErrorType::CannotDeclareGlobalFunction, function.name()); + return vm.throw_completion(ErrorType::CannotDeclareGlobalFunction, function_name); } // 2. Append fn to declaredFunctionNames. @@ -865,12 +869,12 @@ ThrowCompletionOr eval_declaration_instantiation(VM& vm, Program const& pr if (!strict) { // a. Let declaredFunctionOrVarNames be the list-concatenation of declaredFunctionNames and declaredVarNames. // The spec here uses 'declaredVarNames' but that has not been declared yet. - HashTable hoisted_functions; + HashTable hoisted_functions; // b. For each FunctionDeclaration f that is directly contained in the StatementList of a Block, CaseClause, or DefaultClause Contained within body, do TRY(program.for_each_function_hoistable_with_annexB_extension([&](FunctionDeclaration& function_declaration) -> ThrowCompletionOr { // i. Let F be StringValue of the BindingIdentifier of f. - auto function_name = function_declaration.name(); + auto function_name = Utf16FlyString::from_utf8(function_declaration.name()); // ii. If replacing the FunctionDeclaration f with a VariableStatement that has F as a BindingIdentifier would not produce any Early Errors for body, then // Note: This is checked during parsing and for_each_function_hoistable_with_annexB_extension so it always passes here. @@ -956,7 +960,7 @@ ThrowCompletionOr eval_declaration_instantiation(VM& vm, Program const& pr } // 12. Let declaredVarNames be a new empty List. - HashTable declared_var_names; + HashTable declared_var_names; // 13. For each element d of varDeclarations, do TRY(program.for_each_var_scoped_variable_declaration([&](VariableDeclaration const& declaration) { @@ -964,8 +968,8 @@ ThrowCompletionOr eval_declaration_instantiation(VM& vm, Program const& pr // Note: This is handled by for_each_var_scoped_variable_declaration. // i. For each String vn of the BoundNames of d, do - return declaration.for_each_bound_identifier([&](auto const& identifier) -> ThrowCompletionOr { - auto const& name = identifier.string(); + return declaration.for_each_bound_identifier([&](Identifier const& identifier) -> ThrowCompletionOr { + auto name = Utf16FlyString::from_utf8(identifier.string()); // 1. If vn is not an element of declaredFunctionNames, then if (!declared_function_names.contains(name)) { @@ -995,8 +999,8 @@ ThrowCompletionOr eval_declaration_instantiation(VM& vm, Program const& pr // a. NOTE: Lexically declared names are only instantiated here but not initialized. // b. For each element dn of the BoundNames of d, do - return declaration.for_each_bound_identifier([&](auto const& identifier) -> ThrowCompletionOr { - auto const& name = identifier.string(); + return declaration.for_each_bound_identifier([&](Identifier const& identifier) -> ThrowCompletionOr { + auto name = Utf16FlyString::from_utf8(identifier.string()); // i. If IsConstantDeclaration of d is true, then if (declaration.is_constant_declaration()) { @@ -1016,12 +1020,14 @@ ThrowCompletionOr eval_declaration_instantiation(VM& vm, Program const& pr // NOTE: We iterate in reverse order since we appended the functions // instead of prepending. We append because prepending is much slower // and we only use the created vector here. - for (auto& declaration : functions_to_initialize.in_reverse()) { + for (auto const& declaration : functions_to_initialize.in_reverse()) { + auto declaration_name = Utf16FlyString::from_utf8(declaration.name()); + // a. Let fn be the sole element of the BoundNames of f. // b. Let fo be InstantiateFunctionObject of f with arguments lexEnv and privateEnv. auto function = ECMAScriptFunctionObject::create_from_function_node( declaration, - declaration.name(), + declaration_name, realm, lexical_environment, private_environment); @@ -1029,32 +1035,31 @@ ThrowCompletionOr eval_declaration_instantiation(VM& vm, Program const& pr // c. If varEnv is a global Environment Record, then if (global_var_environment) { // i. Perform ? varEnv.CreateGlobalFunctionBinding(fn, fo, true). - TRY(global_var_environment->create_global_function_binding(declaration.name(), function, true)); + TRY(global_var_environment->create_global_function_binding(declaration_name, function, true)); } // d. Else, else { // i. Let bindingExists be ! varEnv.HasBinding(fn). - auto binding_exists = MUST(variable_environment->has_binding(declaration.name())); + auto binding_exists = MUST(variable_environment->has_binding(declaration_name)); // ii. If bindingExists is false, then if (!binding_exists) { // 1. NOTE: The following invocation cannot return an abrupt completion because of the validation preceding step 14. // 2. Perform ! varEnv.CreateMutableBinding(fn, true). - MUST(variable_environment->create_mutable_binding(vm, declaration.name(), true)); + MUST(variable_environment->create_mutable_binding(vm, declaration_name, true)); // 3. Perform ! varEnv.InitializeBinding(fn, fo, normal). - MUST(variable_environment->initialize_binding(vm, declaration.name(), function, Environment::InitializeBindingHint::Normal)); + MUST(variable_environment->initialize_binding(vm, declaration_name, function, Environment::InitializeBindingHint::Normal)); } // iii. Else, else { // 1. Perform ! varEnv.SetMutableBinding(fn, fo, false). - MUST(variable_environment->set_mutable_binding(vm, declaration.name(), function, false)); + MUST(variable_environment->set_mutable_binding(vm, declaration_name, function, false)); } } } // 18. For each String vn of declaredVarNames, do - for (auto& var_name : declared_var_names) { // a. If varEnv is a global Environment Record, then if (global_var_environment) { @@ -1165,15 +1170,15 @@ Object* create_mapped_arguments_object(VM& vm, FunctionObject& function, Nonnull // and getter/setter behavior itself without extra GC allocations. // 17. Let mappedNames be a new empty List. - HashTable seen_names; - Vector mapped_names; + HashTable seen_names; + Vector mapped_names; // 18. Set index to numberOfParameters - 1. // 19. Repeat, while index ≥ 0, VERIFY(formals->size() <= NumericLimits::max()); for (i32 index = static_cast(formals->size()) - 1; index >= 0; --index) { // a. Let name be parameterNames[index]. - auto const& name = formals->parameters()[index].binding.get>()->string(); + auto name = Utf16FlyString::from_utf8(formals->parameters()[index].binding.get>()->string()); // b. If name is not an element of mappedNames, then if (seen_names.contains(name)) @@ -1229,22 +1234,23 @@ CanonicalIndex canonical_numeric_index_string(PropertyKey const& property_key, C // already covered it with the is_number() == true path. if (argument.is_empty()) return CanonicalIndex(CanonicalIndex::Type::Undefined, 0); + u32 current_index = 0; - auto const* characters = argument.bytes_as_string_view().characters_without_null_termination(); - auto const length = argument.bytes_as_string_view().length(); - if (characters[current_index] == '-') { + + if (argument.code_unit_at(current_index) == '-') { current_index++; - if (current_index == length) + if (current_index == argument.length_in_code_units()) return CanonicalIndex(CanonicalIndex::Type::Undefined, 0); } - if (characters[current_index] == '0') { + + if (argument.code_unit_at(current_index) == '0') { current_index++; - if (current_index == length) + if (current_index == argument.length_in_code_units()) return CanonicalIndex(CanonicalIndex::Type::Numeric, 0); - if (characters[current_index] != '.') + if (argument.code_unit_at(current_index) != '.') return CanonicalIndex(CanonicalIndex::Type::Undefined, 0); current_index++; - if (current_index == length) + if (current_index == argument.length_in_code_units()) return CanonicalIndex(CanonicalIndex::Type::Undefined, 0); } @@ -1253,11 +1259,11 @@ CanonicalIndex canonical_numeric_index_string(PropertyKey const& property_key, C return CanonicalIndex(CanonicalIndex::Type::Numeric, 0); // Short circuit any string that doesn't start with digits - if (char first_non_zero = characters[current_index]; first_non_zero < '0' || first_non_zero > '9') + if (auto first_non_zero = argument.code_unit_at(current_index); first_non_zero < '0' || first_non_zero > '9') return CanonicalIndex(CanonicalIndex::Type::Undefined, 0); // 2. Let n be ! ToNumber(argument). - auto maybe_double = argument.bytes_as_string_view().to_number(AK::TrimWhitespace::No); + auto maybe_double = argument.to_number(AK::TrimWhitespace::No); if (!maybe_double.has_value()) return CanonicalIndex(CanonicalIndex::Type::Undefined, 0); @@ -1417,7 +1423,7 @@ ThrowCompletionOr get_substitution(VM& vm, Utf16View const& matched, Utf // 2. Let groupName be the substring of templateRemainder from 2 to gtPos. auto group_name_view = template_remainder.substring_view(2, *greater_than_position - 2); - auto group_name = MUST(group_name_view.to_utf8()); + auto group_name = Utf16String::from_utf16(group_name_view); // 3. Assert: namedCaptures is an Object. VERIFY(named_captures.is_object()); diff --git a/Libraries/LibJS/Runtime/AbstractOperations.h b/Libraries/LibJS/Runtime/AbstractOperations.h index d82bc4578d..406230e864 100644 --- a/Libraries/LibJS/Runtime/AbstractOperations.h +++ b/Libraries/LibJS/Runtime/AbstractOperations.h @@ -39,7 +39,7 @@ JS_API ThrowCompletionOr length_of_array_like(VM&, Object const&); ThrowCompletionOr> create_list_from_array_like(VM&, Value, Function(Value)> = {}); ThrowCompletionOr species_constructor(VM&, Object const&, FunctionObject& default_constructor); JS_API ThrowCompletionOr get_function_realm(VM&, FunctionObject const&); -ThrowCompletionOr initialize_bound_name(VM&, FlyString const&, Value, Environment*); +ThrowCompletionOr initialize_bound_name(VM&, Utf16FlyString const&, Value, Environment*); bool is_compatible_property_descriptor(bool extensible, PropertyDescriptor const&, Optional const& current); bool validate_and_apply_property_descriptor(Object*, PropertyKey const&, bool extensible, PropertyDescriptor const&, Optional const& current); JS_API ThrowCompletionOr get_prototype_from_constructor(VM&, FunctionObject const& constructor, GC::Ref (Intrinsics::*intrinsic_default_prototype)()); diff --git a/Libraries/LibJS/Runtime/ArgumentsObject.cpp b/Libraries/LibJS/Runtime/ArgumentsObject.cpp index 642200585d..b7e1e21be7 100644 --- a/Libraries/LibJS/Runtime/ArgumentsObject.cpp +++ b/Libraries/LibJS/Runtime/ArgumentsObject.cpp @@ -181,7 +181,7 @@ ThrowCompletionOr ArgumentsObject::internal_define_own_property(PropertyKe void ArgumentsObject::delete_from_parameter_map(PropertyKey const& property_key) { - m_mapped_names[property_key.as_number()] = FlyString {}; + m_mapped_names[property_key.as_number()] = Utf16FlyString {}; } Value ArgumentsObject::get_from_parameter_map(PropertyKey const& property_key) const diff --git a/Libraries/LibJS/Runtime/ArgumentsObject.h b/Libraries/LibJS/Runtime/ArgumentsObject.h index b6cafebec4..0fe22ff49c 100644 --- a/Libraries/LibJS/Runtime/ArgumentsObject.h +++ b/Libraries/LibJS/Runtime/ArgumentsObject.h @@ -26,7 +26,7 @@ public: virtual ThrowCompletionOr internal_set(PropertyKey const&, Value value, Value receiver, CacheablePropertyMetadata*, PropertyLookupPhase) override; virtual ThrowCompletionOr internal_delete(PropertyKey const&) override; - void set_mapped_names(Vector mapped_names) { m_mapped_names = move(mapped_names); } + void set_mapped_names(Vector mapped_names) { m_mapped_names = move(mapped_names); } private: ArgumentsObject(Realm&, Environment&); @@ -39,7 +39,7 @@ private: virtual void visit_edges(Cell::Visitor&) override; GC::Ref m_environment; - Vector m_mapped_names; + Vector m_mapped_names; }; } diff --git a/Libraries/LibJS/Runtime/CommonPropertyNames.h b/Libraries/LibJS/Runtime/CommonPropertyNames.h index 348f10e377..4c3d67cd33 100644 --- a/Libraries/LibJS/Runtime/CommonPropertyNames.h +++ b/Libraries/LibJS/Runtime/CommonPropertyNames.h @@ -607,35 +607,35 @@ namespace JS { P(zonedDateTimeISO) struct CommonPropertyNames { - PropertyKey and_ { "and"_fly_string, PropertyKey::StringMayBeNumber::No }; - PropertyKey catch_ { "catch"_fly_string, PropertyKey::StringMayBeNumber::No }; - PropertyKey delete_ { "delete"_fly_string, PropertyKey::StringMayBeNumber::No }; - PropertyKey for_ { "for"_fly_string, PropertyKey::StringMayBeNumber::No }; - PropertyKey or_ { "or"_fly_string, PropertyKey::StringMayBeNumber::No }; - PropertyKey register_ { "register"_fly_string, PropertyKey::StringMayBeNumber::No }; - PropertyKey return_ { "return"_fly_string, PropertyKey::StringMayBeNumber::No }; - PropertyKey throw_ { "throw"_fly_string, PropertyKey::StringMayBeNumber::No }; - PropertyKey try_ { "try"_fly_string, PropertyKey::StringMayBeNumber::No }; - PropertyKey union_ { "union"_fly_string, PropertyKey::StringMayBeNumber::No }; - PropertyKey xor_ { "xor"_fly_string, PropertyKey::StringMayBeNumber::No }; - PropertyKey inputAlias { "$_"_fly_string, PropertyKey::StringMayBeNumber::No }; - PropertyKey lastMatchAlias { "$&"_fly_string, PropertyKey::StringMayBeNumber::No }; - PropertyKey lastParenAlias { "$+"_fly_string, PropertyKey::StringMayBeNumber::No }; - PropertyKey leftContextAlias { "$`"_fly_string, PropertyKey::StringMayBeNumber::No }; - PropertyKey rightContextAlias { "$'"_fly_string, PropertyKey::StringMayBeNumber::No }; -#define __ENUMERATE(x) PropertyKey x { #x##_fly_string, PropertyKey::StringMayBeNumber::No }; + PropertyKey and_ { "and"_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; + PropertyKey catch_ { "catch"_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; + PropertyKey delete_ { "delete"_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; + PropertyKey for_ { "for"_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; + PropertyKey or_ { "or"_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; + PropertyKey register_ { "register"_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; + PropertyKey return_ { "return"_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; + PropertyKey throw_ { "throw"_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; + PropertyKey try_ { "try"_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; + PropertyKey union_ { "union"_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; + PropertyKey xor_ { "xor"_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; + PropertyKey inputAlias { "$_"_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; + PropertyKey lastMatchAlias { "$&"_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; + PropertyKey lastParenAlias { "$+"_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; + PropertyKey leftContextAlias { "$`"_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; + PropertyKey rightContextAlias { "$'"_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; +#define __ENUMERATE(x) PropertyKey x { #x##_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; ENUMERATE_STANDARD_PROPERTY_NAMES(__ENUMERATE) #undef __ENUMERATE -#define __JS_ENUMERATE(x, a, b, c, t) PropertyKey x { #x##_fly_string, PropertyKey::StringMayBeNumber::No }; +#define __JS_ENUMERATE(x, a, b, c, t) PropertyKey x { #x##_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; JS_ENUMERATE_BUILTIN_TYPES #undef __JS_ENUMERATE -#define __JS_ENUMERATE(x, a, b, c) PropertyKey x { #x##_fly_string, PropertyKey::StringMayBeNumber::No }; +#define __JS_ENUMERATE(x, a, b, c) PropertyKey x { #x##_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; JS_ENUMERATE_INTL_OBJECTS #undef __JS_ENUMERATE -#define __JS_ENUMERATE(x, a, b, c) PropertyKey x { #x##_fly_string, PropertyKey::StringMayBeNumber::No }; +#define __JS_ENUMERATE(x, a, b, c) PropertyKey x { #x##_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; JS_ENUMERATE_TEMPORAL_OBJECTS #undef __JS_ENUMERATE -#define __JS_ENUMERATE(x, a) PropertyKey x { #x##_fly_string, PropertyKey::StringMayBeNumber::No }; +#define __JS_ENUMERATE(x, a) PropertyKey x { #x##_utf16_fly_string, PropertyKey::StringMayBeNumber::No }; JS_ENUMERATE_WELL_KNOWN_SYMBOLS #undef __JS_ENUMERATE }; diff --git a/Libraries/LibJS/Runtime/DeclarativeEnvironment.cpp b/Libraries/LibJS/Runtime/DeclarativeEnvironment.cpp index d17141b1ed..fb4cd0a20a 100644 --- a/Libraries/LibJS/Runtime/DeclarativeEnvironment.cpp +++ b/Libraries/LibJS/Runtime/DeclarativeEnvironment.cpp @@ -52,7 +52,7 @@ void DeclarativeEnvironment::visit_edges(Visitor& visitor) } // 9.1.1.1.1 HasBinding ( N ), https://tc39.es/ecma262/#sec-declarative-environment-records-hasbinding-n -ThrowCompletionOr DeclarativeEnvironment::has_binding(FlyString const& name, Optional* out_index) const +ThrowCompletionOr DeclarativeEnvironment::has_binding(Utf16FlyString const& name, Optional* out_index) const { auto binding_and_index = find_binding_and_index(name); if (!binding_and_index.has_value()) @@ -63,7 +63,7 @@ ThrowCompletionOr DeclarativeEnvironment::has_binding(FlyString const& nam } // 9.1.1.1.2 CreateMutableBinding ( N, D ), https://tc39.es/ecma262/#sec-declarative-environment-records-createmutablebinding-n-d -ThrowCompletionOr DeclarativeEnvironment::create_mutable_binding(VM&, FlyString const& name, bool can_be_deleted) +ThrowCompletionOr DeclarativeEnvironment::create_mutable_binding(VM&, Utf16FlyString const& name, bool can_be_deleted) { // 1. Assert: envRec does not already have a binding for N. // NOTE: We skip this to avoid O(n) traversal of m_bindings. @@ -86,7 +86,7 @@ ThrowCompletionOr DeclarativeEnvironment::create_mutable_binding(VM&, FlyS } // 9.1.1.1.3 CreateImmutableBinding ( N, S ), https://tc39.es/ecma262/#sec-declarative-environment-records-createimmutablebinding-n-s -ThrowCompletionOr DeclarativeEnvironment::create_immutable_binding(VM&, FlyString const& name, bool strict) +ThrowCompletionOr DeclarativeEnvironment::create_immutable_binding(VM&, Utf16FlyString const& name, bool strict) { // 1. Assert: envRec does not already have a binding for N. // NOTE: We skip this to avoid O(n) traversal of m_bindings. @@ -110,7 +110,7 @@ ThrowCompletionOr DeclarativeEnvironment::create_immutable_binding(VM&, Fl // 9.1.1.1.4 InitializeBinding ( N, V ), https://tc39.es/ecma262/#sec-declarative-environment-records-initializebinding-n-v // 4.1.1.1.1 InitializeBinding ( N, V, hint ), https://tc39.es/proposal-explicit-resource-management/#sec-declarative-environment-records -ThrowCompletionOr DeclarativeEnvironment::initialize_binding(VM& vm, FlyString const& name, Value value, Environment::InitializeBindingHint hint) +ThrowCompletionOr DeclarativeEnvironment::initialize_binding(VM& vm, Utf16FlyString const& name, Value value, Environment::InitializeBindingHint hint) { return initialize_binding_direct(vm, find_binding_and_index(name)->index().value(), value, hint); } @@ -137,7 +137,7 @@ ThrowCompletionOr DeclarativeEnvironment::initialize_binding_direct(VM& vm } // 9.1.1.1.5 SetMutableBinding ( N, V, S ), https://tc39.es/ecma262/#sec-declarative-environment-records-setmutablebinding-n-v-s -ThrowCompletionOr DeclarativeEnvironment::set_mutable_binding(VM& vm, FlyString const& name, Value value, bool strict) +ThrowCompletionOr DeclarativeEnvironment::set_mutable_binding(VM& vm, Utf16FlyString const& name, Value value, bool strict) { // 1. If envRec does not have a binding for N, then auto binding_and_index = find_binding_and_index(name); @@ -187,7 +187,7 @@ ThrowCompletionOr DeclarativeEnvironment::set_mutable_binding_direct(VM& v } // 9.1.1.1.6 GetBindingValue ( N, S ), https://tc39.es/ecma262/#sec-declarative-environment-records-getbindingvalue-n-s -ThrowCompletionOr DeclarativeEnvironment::get_binding_value(VM& vm, FlyString const& name, [[maybe_unused]] bool strict) +ThrowCompletionOr DeclarativeEnvironment::get_binding_value(VM& vm, Utf16FlyString const& name, [[maybe_unused]] bool strict) { // 1. Assert: envRec has a binding for N. auto binding_and_index = find_binding_and_index(name); @@ -198,7 +198,7 @@ ThrowCompletionOr DeclarativeEnvironment::get_binding_value(VM& vm, FlySt } // 9.1.1.1.7 DeleteBinding ( N ), https://tc39.es/ecma262/#sec-declarative-environment-records-deletebinding-n -ThrowCompletionOr DeclarativeEnvironment::delete_binding(VM&, FlyString const& name) +ThrowCompletionOr DeclarativeEnvironment::delete_binding(VM&, Utf16FlyString const& name) { // 1. Assert: envRec has a binding for the name that is the value of N. auto binding_and_index = find_binding_and_index(name); @@ -218,7 +218,7 @@ ThrowCompletionOr DeclarativeEnvironment::delete_binding(VM&, FlyString co return true; } -ThrowCompletionOr DeclarativeEnvironment::initialize_or_set_mutable_binding(VM& vm, FlyString const& name, Value value) +ThrowCompletionOr DeclarativeEnvironment::initialize_or_set_mutable_binding(VM& vm, Utf16FlyString const& name, Value value) { auto binding_and_index = find_binding_and_index(name); VERIFY(binding_and_index.has_value()); @@ -230,7 +230,7 @@ ThrowCompletionOr DeclarativeEnvironment::initialize_or_set_mutable_bindin return {}; } -void DeclarativeEnvironment::initialize_or_set_mutable_binding(Badge, VM& vm, FlyString const& name, Value value) +void DeclarativeEnvironment::initialize_or_set_mutable_binding(Badge, VM& vm, Utf16FlyString const& name, Value value) { MUST(initialize_or_set_mutable_binding(vm, name, value)); } diff --git a/Libraries/LibJS/Runtime/DeclarativeEnvironment.h b/Libraries/LibJS/Runtime/DeclarativeEnvironment.h index 639b78fb5e..1ea6ae9a19 100644 --- a/Libraries/LibJS/Runtime/DeclarativeEnvironment.h +++ b/Libraries/LibJS/Runtime/DeclarativeEnvironment.h @@ -6,8 +6,8 @@ #pragma once -#include #include +#include #include #include #include @@ -20,7 +20,7 @@ class DeclarativeEnvironment : public Environment { GC_DECLARE_ALLOCATOR(DeclarativeEnvironment); struct Binding { - FlyString name; + Utf16FlyString name; Value value; bool strict { false }; bool mutable_ { false }; @@ -33,21 +33,21 @@ public: virtual ~DeclarativeEnvironment() override = default; - virtual ThrowCompletionOr has_binding(FlyString const& name, Optional* = nullptr) const override final; - virtual ThrowCompletionOr create_mutable_binding(VM&, FlyString const& name, bool can_be_deleted) override final; - virtual ThrowCompletionOr create_immutable_binding(VM&, FlyString const& name, bool strict) override final; - virtual ThrowCompletionOr initialize_binding(VM&, FlyString const& name, Value, InitializeBindingHint) override final; - virtual ThrowCompletionOr set_mutable_binding(VM&, FlyString const& name, Value, bool strict) override final; - virtual ThrowCompletionOr get_binding_value(VM&, FlyString const& name, bool strict) override; - virtual ThrowCompletionOr delete_binding(VM&, FlyString const& name) override; + virtual ThrowCompletionOr has_binding(Utf16FlyString const& name, Optional* = nullptr) const override final; + virtual ThrowCompletionOr create_mutable_binding(VM&, Utf16FlyString const& name, bool can_be_deleted) override final; + virtual ThrowCompletionOr create_immutable_binding(VM&, Utf16FlyString const& name, bool strict) override final; + virtual ThrowCompletionOr initialize_binding(VM&, Utf16FlyString const& name, Value, InitializeBindingHint) override final; + virtual ThrowCompletionOr set_mutable_binding(VM&, Utf16FlyString const& name, Value, bool strict) override final; + virtual ThrowCompletionOr get_binding_value(VM&, Utf16FlyString const& name, bool strict) override; + virtual ThrowCompletionOr delete_binding(VM&, Utf16FlyString const& name) override; - void initialize_or_set_mutable_binding(Badge, VM&, FlyString const& name, Value value); - ThrowCompletionOr initialize_or_set_mutable_binding(VM&, FlyString const& name, Value value); + void initialize_or_set_mutable_binding(Badge, VM&, Utf16FlyString const& name, Value value); + ThrowCompletionOr initialize_or_set_mutable_binding(VM&, Utf16FlyString const& name, Value value); // This is not a method defined in the spec! Do not use this in any LibJS (or other spec related) code. - [[nodiscard]] Vector bindings() const + [[nodiscard]] Vector bindings() const { - Vector names; + Vector names; names.ensure_capacity(m_bindings.size()); for (auto const& binding : m_bindings) @@ -114,7 +114,7 @@ protected: friend class ModuleEnvironment; - virtual Optional find_binding_and_index(FlyString const& name) const + virtual Optional find_binding_and_index(Utf16FlyString const& name) const { if (auto it = m_bindings_assoc.find(name); it != m_bindings_assoc.end()) { return BindingAndIndex { const_cast(&m_bindings.at(it->value)), it->value }; @@ -125,7 +125,7 @@ protected: private: Vector m_bindings; - HashMap m_bindings_assoc; + HashMap m_bindings_assoc; DisposeCapability m_dispose_capability; u64 m_environment_serial_number { 0 }; diff --git a/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp b/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp index 7be4db2550..e427399582 100644 --- a/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp +++ b/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp @@ -33,7 +33,7 @@ namespace JS { GC_DEFINE_ALLOCATOR(ECMAScriptFunctionObject); -GC::Ref ECMAScriptFunctionObject::create(Realm& realm, FlyString name, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr parameters, i32 function_length, Vector local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, FunctionParsingInsights parsing_insights, bool is_arrow_function, Variant class_field_initializer_name) +GC::Ref ECMAScriptFunctionObject::create(Realm& realm, Utf16FlyString name, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr parameters, i32 function_length, Vector local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, FunctionParsingInsights parsing_insights, bool is_arrow_function, Variant class_field_initializer_name) { Object* prototype = nullptr; switch (kind) { @@ -73,7 +73,7 @@ GC::Ref ECMAScriptFunctionObject::create(Realm& realm, *prototype); } -GC::Ref ECMAScriptFunctionObject::create(Realm& realm, FlyString name, Object& prototype, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr parameters, i32 function_length, Vector local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, FunctionParsingInsights parsing_insights, bool is_arrow_function, Variant class_field_initializer_name) +GC::Ref ECMAScriptFunctionObject::create(Realm& realm, Utf16FlyString name, Object& prototype, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr parameters, i32 function_length, Vector local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, FunctionParsingInsights parsing_insights, bool is_arrow_function, Variant class_field_initializer_name) { auto shared_data = adopt_ref(*new SharedFunctionInstanceData( realm.vm(), @@ -97,7 +97,7 @@ GC::Ref ECMAScriptFunctionObject::create(Realm& realm, GC::Ref ECMAScriptFunctionObject::create_from_function_node( FunctionNode const& function_node, - FlyString name, + Utf16FlyString name, GC::Ref realm, GC::Ptr parent_environment, GC::Ptr private_environment) @@ -145,7 +145,7 @@ GC::Ref ECMAScriptFunctionObject::create_from_function SharedFunctionInstanceData::SharedFunctionInstanceData( VM& vm, FunctionKind kind, - FlyString name, + Utf16FlyString name, i32 function_length, NonnullRefPtr formal_parameters, NonnullRefPtr ecmascript_code, @@ -210,7 +210,7 @@ SharedFunctionInstanceData::SharedFunctionInstanceData( parameter.binding.visit( [&](Identifier const& identifier) { - if (m_parameter_names.set(identifier.string(), identifier.is_local() ? ParameterIsLocal::Yes : ParameterIsLocal::No) != AK::HashSetResult::InsertedNewEntry) + if (m_parameter_names.set(Utf16FlyString::from_utf8(identifier.string()), identifier.is_local() ? ParameterIsLocal::Yes : ParameterIsLocal::No) != AK::HashSetResult::InsertedNewEntry) m_has_duplicates = true; else if (!identifier.is_local()) ++parameters_in_environment; @@ -221,7 +221,7 @@ SharedFunctionInstanceData::SharedFunctionInstanceData( // NOTE: Nothing in the callback throws an exception. MUST(pattern->for_each_bound_identifier([&](auto& identifier) { - if (m_parameter_names.set(identifier.string(), identifier.is_local() ? ParameterIsLocal::Yes : ParameterIsLocal::No) != AK::HashSetResult::InsertedNewEntry) + if (m_parameter_names.set(Utf16FlyString::from_utf8(identifier.string()), identifier.is_local() ? ParameterIsLocal::Yes : ParameterIsLocal::No) != AK::HashSetResult::InsertedNewEntry) m_has_duplicates = true; else if (!identifier.is_local()) ++parameters_in_environment; @@ -244,7 +244,7 @@ SharedFunctionInstanceData::SharedFunctionInstanceData( m_arguments_object_needed = false; } - HashTable function_names; + HashTable function_names; // 18. Else if hasParameterExpressions is false, then // a. If functionNames contains "arguments" or lexicalNames contains "arguments", then @@ -253,7 +253,9 @@ SharedFunctionInstanceData::SharedFunctionInstanceData( if (scope_body) { // NOTE: Nothing in the callback throws an exception. MUST(scope_body->for_each_var_function_declaration_in_reverse_order([&](FunctionDeclaration const& function) { - if (function_names.set(function.name()) == AK::HashSetResult::InsertedNewEntry) + auto name = Utf16FlyString::from_utf8(function.name()); + + if (function_names.set(name) == AK::HashSetResult::InsertedNewEntry) m_functions_to_initialize.append(function); })); @@ -293,7 +295,7 @@ SharedFunctionInstanceData::SharedFunctionInstanceData( *environment_size += parameters_in_environment; - HashMap parameter_bindings; + HashMap parameter_bindings; auto arguments_object_needs_binding = m_arguments_object_needed && !m_local_variables_names.first_matching([](auto const& local) { return local.declaration_kind == LocalVariable::DeclarationKind::ArgumentsObject; }).has_value(); @@ -310,7 +312,7 @@ SharedFunctionInstanceData::SharedFunctionInstanceData( // a. Let parameterBindings be parameterNames. } - HashMap instantiated_var_names; + HashMap instantiated_var_names; size_t* var_environment_size = nullptr; @@ -321,9 +323,9 @@ SharedFunctionInstanceData::SharedFunctionInstanceData( if (scope_body) { // c. For each element n of varNames, do - MUST(scope_body->for_each_var_declared_identifier([&](auto const& id) { + MUST(scope_body->for_each_var_declared_identifier([&](Identifier const& id) { // i. If instantiatedVarNames does not contain n, then - if (instantiated_var_names.set(id.string(), id.is_local() ? ParameterIsLocal::Yes : ParameterIsLocal::No) == AK::HashSetResult::InsertedNewEntry) { + if (instantiated_var_names.set(Utf16FlyString::from_utf8(id.string()), id.is_local() ? ParameterIsLocal::Yes : ParameterIsLocal::No) == AK::HashSetResult::InsertedNewEntry) { // 1. Append n to instantiatedVarNames. // Following steps will be executed in function_declaration_instantiation: // 2. Perform ! env.CreateMutableBinding(n, false). @@ -353,16 +355,18 @@ SharedFunctionInstanceData::SharedFunctionInstanceData( // NOTE: Steps a, b, c and d are executed in function_declaration_instantiation. // e. For each element n of varNames, do if (scope_body) { - MUST(scope_body->for_each_var_declared_identifier([&](auto const& id) { + MUST(scope_body->for_each_var_declared_identifier([&](Identifier const& id) { + auto name = Utf16FlyString::from_utf8(id.string()); + // 1. Append n to instantiatedVarNames. // Following steps will be executed in function_declaration_instantiation: // 2. Perform ! env.CreateMutableBinding(n, false). // 3. Perform ! env.InitializeBinding(n, undefined). - if (instantiated_var_names.set(id.string(), id.is_local() ? ParameterIsLocal::Yes : ParameterIsLocal::No) == AK::HashSetResult::InsertedNewEntry) { + if (instantiated_var_names.set(name, id.is_local() ? ParameterIsLocal::Yes : ParameterIsLocal::No) == AK::HashSetResult::InsertedNewEntry) { m_var_names_to_initialize_binding.append({ .identifier = id, - .parameter_binding = parameter_bindings.contains(id.string()), - .function_name = function_names.contains(id.string()), + .parameter_binding = parameter_bindings.contains(name), + .function_name = function_names.contains(name), }); if (!id.is_local()) @@ -376,7 +380,7 @@ SharedFunctionInstanceData::SharedFunctionInstanceData( // B.3.2.1 Changes to FunctionDeclarationInstantiation, https://tc39.es/ecma262/#sec-web-compat-functiondeclarationinstantiation if (!m_strict && scope_body) { MUST(scope_body->for_each_function_hoistable_with_annexB_extension([&](FunctionDeclaration& function_declaration) { - auto function_name = function_declaration.name(); + auto function_name = Utf16FlyString::from_utf8(function_declaration.name()); if (parameter_bindings.contains(function_name)) return; @@ -826,7 +830,7 @@ void async_block_start(VM& vm, T const& async_body, PromiseCapability const& pro auto& running_context = vm.running_execution_context(); // 2. Let closure be a new Abstract Closure with no parameters that captures promiseCapability and asyncBody and performs the following steps when called: - auto closure = NativeFunction::create(realm, ""_fly_string, [&async_body, &promise_capability](auto& vm) -> ThrowCompletionOr { + auto closure = NativeFunction::create(realm, {}, [&async_body, &promise_capability](auto& vm) -> ThrowCompletionOr { Completion result; // a. Let acAsyncContext be the running execution context. @@ -834,7 +838,7 @@ void async_block_start(VM& vm, T const& async_body, PromiseCapability const& pro // b. If asyncBody is a Parse Node, then if constexpr (!IsSame>) { // i. Let result be Completion(Evaluation of asyncBody). - auto maybe_executable = Bytecode::compile(vm, async_body, FunctionKind::Async, "AsyncBlockStart"_fly_string); + auto maybe_executable = Bytecode::compile(vm, async_body, FunctionKind::Async, "AsyncBlockStart"_utf16_fly_string); if (maybe_executable.is_error()) result = maybe_executable.release_error(); else @@ -931,7 +935,7 @@ ThrowCompletionOr ECMAScriptFunctionObject::ordinary_call_evaluate_body(V return generator_object; } -void ECMAScriptFunctionObject::set_name(FlyString const& name) +void ECMAScriptFunctionObject::set_name(Utf16FlyString const& name) { auto& vm = this->vm(); const_cast(shared_data()).m_name = name; diff --git a/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h b/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h index 8b0cca22f8..9f5a2f1a53 100644 --- a/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h +++ b/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h @@ -39,7 +39,7 @@ public: SharedFunctionInstanceData( VM& vm, FunctionKind, - FlyString name, + Utf16FlyString name, i32 function_length, NonnullRefPtr, NonnullRefPtr ecmascript_code, @@ -52,7 +52,7 @@ public: RefPtr m_formal_parameters; // [[FormalParameters]] RefPtr m_ecmascript_code; // [[ECMAScriptCode]] - FlyString m_name; + Utf16FlyString m_name; ByteString m_source_text; // [[SourceText]] Vector m_local_variables_names; @@ -81,13 +81,13 @@ public: No, Yes, }; - HashMap m_parameter_names; + HashMap m_parameter_names; Vector m_functions_to_initialize; bool m_arguments_object_needed { false }; bool m_function_environment_needed { false }; bool m_uses_this { false }; Vector m_var_names_to_initialize_binding; - Vector m_function_names_to_initialize_binding; + Vector m_function_names_to_initialize_binding; size_t m_function_environment_bindings_count { 0 }; size_t m_var_environment_bindings_count { 0 }; @@ -104,12 +104,12 @@ class JS_API ECMAScriptFunctionObject final : public FunctionObject { GC_DECLARE_ALLOCATOR(ECMAScriptFunctionObject); public: - static GC::Ref create(Realm&, FlyString name, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr parameters, i32 function_length, Vector local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, FunctionParsingInsights, bool is_arrow_function = false, Variant class_field_initializer_name = {}); - static GC::Ref create(Realm&, FlyString name, Object& prototype, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr parameters, i32 function_length, Vector local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, FunctionParsingInsights, bool is_arrow_function = false, Variant class_field_initializer_name = {}); + static GC::Ref create(Realm&, Utf16FlyString name, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr parameters, i32 function_length, Vector local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, FunctionParsingInsights, bool is_arrow_function = false, Variant class_field_initializer_name = {}); + static GC::Ref create(Realm&, Utf16FlyString name, Object& prototype, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr parameters, i32 function_length, Vector local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, FunctionParsingInsights, bool is_arrow_function = false, Variant class_field_initializer_name = {}); [[nodiscard]] static GC::Ref create_from_function_node( FunctionNode const&, - FlyString name, + Utf16FlyString name, GC::Ref, GC::Ptr parent_environment, GC::Ptr); @@ -129,8 +129,8 @@ public: Statement const& ecmascript_code() const { return *shared_data().m_ecmascript_code; } [[nodiscard]] virtual FunctionParameters const& formal_parameters() const override { return *shared_data().m_formal_parameters; } - FlyString const& name() const { return shared_data().m_name; } - void set_name(FlyString const& name); + Utf16FlyString const& name() const { return shared_data().m_name; } + void set_name(Utf16FlyString const& name); void set_is_class_constructor() { const_cast(shared_data()).m_is_class_constructor = true; } diff --git a/Libraries/LibJS/Runtime/Environment.h b/Libraries/LibJS/Runtime/Environment.h index c69700123d..2b77ebae81 100644 --- a/Libraries/LibJS/Runtime/Environment.h +++ b/Libraries/LibJS/Runtime/Environment.h @@ -35,13 +35,13 @@ public: virtual Object* with_base_object() const { return nullptr; } - virtual ThrowCompletionOr has_binding([[maybe_unused]] FlyString const& name, [[maybe_unused]] Optional* out_index = nullptr) const = 0; - virtual ThrowCompletionOr create_mutable_binding(VM&, [[maybe_unused]] FlyString const& name, [[maybe_unused]] bool can_be_deleted) = 0; - virtual ThrowCompletionOr create_immutable_binding(VM&, [[maybe_unused]] FlyString const& name, [[maybe_unused]] bool strict) = 0; - virtual ThrowCompletionOr initialize_binding(VM&, [[maybe_unused]] FlyString const& name, Value, InitializeBindingHint) = 0; - virtual ThrowCompletionOr set_mutable_binding(VM&, [[maybe_unused]] FlyString const& name, Value, [[maybe_unused]] bool strict) = 0; - virtual ThrowCompletionOr get_binding_value(VM&, [[maybe_unused]] FlyString const& name, [[maybe_unused]] bool strict) = 0; - virtual ThrowCompletionOr delete_binding(VM&, [[maybe_unused]] FlyString const& name) = 0; + virtual ThrowCompletionOr has_binding([[maybe_unused]] Utf16FlyString const& name, [[maybe_unused]] Optional* out_index = nullptr) const = 0; + virtual ThrowCompletionOr create_mutable_binding(VM&, [[maybe_unused]] Utf16FlyString const& name, [[maybe_unused]] bool can_be_deleted) = 0; + virtual ThrowCompletionOr create_immutable_binding(VM&, [[maybe_unused]] Utf16FlyString const& name, [[maybe_unused]] bool strict) = 0; + virtual ThrowCompletionOr initialize_binding(VM&, [[maybe_unused]] Utf16FlyString const& name, Value, InitializeBindingHint) = 0; + virtual ThrowCompletionOr set_mutable_binding(VM&, [[maybe_unused]] Utf16FlyString const& name, Value, [[maybe_unused]] bool strict) = 0; + virtual ThrowCompletionOr get_binding_value(VM&, [[maybe_unused]] Utf16FlyString const& name, [[maybe_unused]] bool strict) = 0; + virtual ThrowCompletionOr delete_binding(VM&, [[maybe_unused]] Utf16FlyString const& name) = 0; // [[OuterEnv]] Environment* outer_environment() { return m_outer_environment; } diff --git a/Libraries/LibJS/Runtime/Error.h b/Libraries/LibJS/Runtime/Error.h index a3f1146b42..148d35f065 100644 --- a/Libraries/LibJS/Runtime/Error.h +++ b/Libraries/LibJS/Runtime/Error.h @@ -7,6 +7,7 @@ #pragma once +#include #include #include #include diff --git a/Libraries/LibJS/Runtime/FunctionConstructor.cpp b/Libraries/LibJS/Runtime/FunctionConstructor.cpp index ef31a36448..cc15696cb4 100644 --- a/Libraries/LibJS/Runtime/FunctionConstructor.cpp +++ b/Libraries/LibJS/Runtime/FunctionConstructor.cpp @@ -200,7 +200,7 @@ ThrowCompletionOr> FunctionConstructor::create // 28. Let F be OrdinaryFunctionCreate(proto, sourceText, parameters, body, non-lexical-this, env, privateEnv). parsing_insights.might_need_arguments_object = true; - auto function = ECMAScriptFunctionObject::create(realm, "anonymous"_fly_string, *prototype, move(source_text), expr->body(), expr->parameters(), expr->function_length(), expr->local_variables_names(), &environment, private_environment, expr->kind(), expr->is_strict_mode(), parsing_insights); + auto function = ECMAScriptFunctionObject::create(realm, "anonymous"_utf16_fly_string, *prototype, move(source_text), expr->body(), expr->parameters(), expr->function_length(), expr->local_variables_names(), &environment, private_environment, expr->kind(), expr->is_strict_mode(), parsing_insights); // FIXME: Remove the name argument from create() and do this instead. // 29. Perform SetFunctionName(F, "anonymous"). diff --git a/Libraries/LibJS/Runtime/FunctionObject.cpp b/Libraries/LibJS/Runtime/FunctionObject.cpp index b563ded268..76c66443c4 100644 --- a/Libraries/LibJS/Runtime/FunctionObject.cpp +++ b/Libraries/LibJS/Runtime/FunctionObject.cpp @@ -28,7 +28,7 @@ GC::Ref FunctionObject::make_function_name(Variantvm(); - String name; + Utf16String name; // 2. If Type(name) is Symbol, then if (auto const* property_key = name_arg.get_pointer(); property_key && property_key->is_symbol()) { @@ -37,15 +37,15 @@ GC::Ref FunctionObject::make_function_name(Variant()) { // a. Set name to name.[[Description]]. - name = private_name->description.to_string(); + name = private_name->description.to_utf16_string(); } // NOTE: This is necessary as we use a different parameter name. else { @@ -61,7 +61,7 @@ GC::Ref FunctionObject::make_function_name(Variant(this)) { diff --git a/Libraries/LibJS/Runtime/GlobalEnvironment.cpp b/Libraries/LibJS/Runtime/GlobalEnvironment.cpp index 51d949be80..6ae9cb5aa8 100644 --- a/Libraries/LibJS/Runtime/GlobalEnvironment.cpp +++ b/Libraries/LibJS/Runtime/GlobalEnvironment.cpp @@ -41,7 +41,7 @@ ThrowCompletionOr GlobalEnvironment::get_this_binding(VM&) const } // 9.1.1.4.1 HasBinding ( N ), https://tc39.es/ecma262/#sec-global-environment-records-hasbinding-n -ThrowCompletionOr GlobalEnvironment::has_binding(FlyString const& name, Optional*) const +ThrowCompletionOr GlobalEnvironment::has_binding(Utf16FlyString const& name, Optional*) const { // 1. Let DclRec be envRec.[[DeclarativeRecord]]. // 2. If ! DclRec.HasBinding(N) is true, return true. @@ -54,7 +54,7 @@ ThrowCompletionOr GlobalEnvironment::has_binding(FlyString const& name, Op } // 9.1.1.4.2 CreateMutableBinding ( N, D ), https://tc39.es/ecma262/#sec-global-environment-records-createmutablebinding-n-d -ThrowCompletionOr GlobalEnvironment::create_mutable_binding(VM& vm, FlyString const& name, bool can_be_deleted) +ThrowCompletionOr GlobalEnvironment::create_mutable_binding(VM& vm, Utf16FlyString const& name, bool can_be_deleted) { // 1. Let DclRec be envRec.[[DeclarativeRecord]]. // 2. If ! DclRec.HasBinding(N) is true, throw a TypeError exception. @@ -66,7 +66,7 @@ ThrowCompletionOr GlobalEnvironment::create_mutable_binding(VM& vm, FlyStr } // 9.1.1.4.3 CreateImmutableBinding ( N, S ), https://tc39.es/ecma262/#sec-global-environment-records-createimmutablebinding-n-s -ThrowCompletionOr GlobalEnvironment::create_immutable_binding(VM& vm, FlyString const& name, bool strict) +ThrowCompletionOr GlobalEnvironment::create_immutable_binding(VM& vm, Utf16FlyString const& name, bool strict) { // 1. Let DclRec be envRec.[[DeclarativeRecord]]. // 2. If ! DclRec.HasBinding(N) is true, throw a TypeError exception. @@ -78,7 +78,7 @@ ThrowCompletionOr GlobalEnvironment::create_immutable_binding(VM& vm, FlyS } // 9.1.1.4.4 InitializeBinding ( N, V, hint ), https://tc39.es/ecma262/#sec-global-environment-records-initializebinding-n-v -ThrowCompletionOr GlobalEnvironment::initialize_binding(VM& vm, FlyString const& name, Value value, InitializeBindingHint hint) +ThrowCompletionOr GlobalEnvironment::initialize_binding(VM& vm, Utf16FlyString const& name, Value value, InitializeBindingHint hint) { // 1. Let DclRec be envRec.[[DeclarativeRecord]]. // 2. If ! DclRec.HasBinding(N) is true, then @@ -96,7 +96,7 @@ ThrowCompletionOr GlobalEnvironment::initialize_binding(VM& vm, FlyString } // 9.1.1.4.5 SetMutableBinding ( N, V, S ), https://tc39.es/ecma262/#sec-global-environment-records-setmutablebinding-n-v-s -ThrowCompletionOr GlobalEnvironment::set_mutable_binding(VM& vm, FlyString const& name, Value value, bool strict) +ThrowCompletionOr GlobalEnvironment::set_mutable_binding(VM& vm, Utf16FlyString const& name, Value value, bool strict) { // 1. Let DclRec be envRec.[[DeclarativeRecord]]. // 2. If ! DclRec.HasBinding(N) is true, then @@ -111,7 +111,7 @@ ThrowCompletionOr GlobalEnvironment::set_mutable_binding(VM& vm, FlyString } // 9.1.1.4.6 GetBindingValue ( N, S ), https://tc39.es/ecma262/#sec-global-environment-records-getbindingvalue-n-s -ThrowCompletionOr GlobalEnvironment::get_binding_value(VM& vm, FlyString const& name, bool strict) +ThrowCompletionOr GlobalEnvironment::get_binding_value(VM& vm, Utf16FlyString const& name, bool strict) { // 1. Let DclRec be envRec.[[DeclarativeRecord]]. // 2. If ! DclRec.HasBinding(N) is true, then @@ -129,7 +129,7 @@ ThrowCompletionOr GlobalEnvironment::get_binding_value(VM& vm, FlyString } // 9.1.1.4.7 DeleteBinding ( N ), https://tc39.es/ecma262/#sec-global-environment-records-deletebinding-n -ThrowCompletionOr GlobalEnvironment::delete_binding(VM& vm, FlyString const& name) +ThrowCompletionOr GlobalEnvironment::delete_binding(VM& vm, Utf16FlyString const& name) { // 1. Let DclRec be envRec.[[DeclarativeRecord]]. // 2. If ! DclRec.HasBinding(N) is true, then @@ -155,7 +155,7 @@ ThrowCompletionOr GlobalEnvironment::delete_binding(VM& vm, FlyString cons } // 9.1.1.4.12 HasLexicalDeclaration ( envRec, N ), https://tc39.es/ecma262/#sec-haslexicaldeclaration -bool GlobalEnvironment::has_lexical_declaration(FlyString const& name) const +bool GlobalEnvironment::has_lexical_declaration(Utf16FlyString const& name) const { // 1. Let DclRec be envRec.[[DeclarativeRecord]]. // 2. Return ! DclRec.HasBinding(N). @@ -163,7 +163,7 @@ bool GlobalEnvironment::has_lexical_declaration(FlyString const& name) const } // 9.1.1.4.13 HasRestrictedGlobalProperty ( envRec, N ), https://tc39.es/ecma262/#sec-hasrestrictedglobalproperty -ThrowCompletionOr GlobalEnvironment::has_restricted_global_property(FlyString const& name) const +ThrowCompletionOr GlobalEnvironment::has_restricted_global_property(Utf16FlyString const& name) const { // 1. Let ObjRec be envRec.[[ObjectRecord]]. // 2. Let globalObject be ObjRec.[[BindingObject]]. @@ -185,7 +185,7 @@ ThrowCompletionOr GlobalEnvironment::has_restricted_global_property(FlyStr } // 9.1.1.4.14 CanDeclareGlobalVar ( envRec, N ), https://tc39.es/ecma262/#sec-candeclareglobalvar -ThrowCompletionOr GlobalEnvironment::can_declare_global_var(FlyString const& name) const +ThrowCompletionOr GlobalEnvironment::can_declare_global_var(Utf16FlyString const& name) const { // 1. Let ObjRec be envRec.[[ObjectRecord]]. // 2. Let globalObject be ObjRec.[[BindingObject]]. @@ -203,7 +203,7 @@ ThrowCompletionOr GlobalEnvironment::can_declare_global_var(FlyString cons } // 9.1.1.4.15 CanDeclareGlobalFunction ( envRec, N ), https://tc39.es/ecma262/#sec-candeclareglobalfunction -ThrowCompletionOr GlobalEnvironment::can_declare_global_function(FlyString const& name) const +ThrowCompletionOr GlobalEnvironment::can_declare_global_function(Utf16FlyString const& name) const { // 1. Let ObjRec be envRec.[[ObjectRecord]]. // 2. Let globalObject be ObjRec.[[BindingObject]]. @@ -229,7 +229,7 @@ ThrowCompletionOr GlobalEnvironment::can_declare_global_function(FlyString } // 9.1.1.4.16 CreateGlobalVarBinding ( envRec, N, D ), https://tc39.es/ecma262/#sec-createglobalvarbinding -ThrowCompletionOr GlobalEnvironment::create_global_var_binding(FlyString const& name, bool can_be_deleted) +ThrowCompletionOr GlobalEnvironment::create_global_var_binding(Utf16FlyString const& name, bool can_be_deleted) { auto& vm = this->vm(); @@ -257,7 +257,7 @@ ThrowCompletionOr GlobalEnvironment::create_global_var_binding(FlyString c } // 9.1.1.4.17 CreateGlobalFunctionBinding ( envRec, N, V, D ), https://tc39.es/ecma262/#sec-createglobalfunctionbinding -ThrowCompletionOr GlobalEnvironment::create_global_function_binding(FlyString const& name, Value value, bool can_be_deleted) +ThrowCompletionOr GlobalEnvironment::create_global_function_binding(Utf16FlyString const& name, Value value, bool can_be_deleted) { // 1. Let ObjRec be envRec.[[ObjectRecord]]. // 2. Let globalObject be ObjRec.[[BindingObject]]. diff --git a/Libraries/LibJS/Runtime/GlobalEnvironment.h b/Libraries/LibJS/Runtime/GlobalEnvironment.h index 4c4220d0fb..93d30fb98d 100644 --- a/Libraries/LibJS/Runtime/GlobalEnvironment.h +++ b/Libraries/LibJS/Runtime/GlobalEnvironment.h @@ -19,24 +19,24 @@ public: virtual bool has_this_binding() const final { return true; } virtual ThrowCompletionOr get_this_binding(VM&) const final; - virtual ThrowCompletionOr has_binding(FlyString const& name, Optional* = nullptr) const override; - virtual ThrowCompletionOr create_mutable_binding(VM&, FlyString const& name, bool can_be_deleted) override; - virtual ThrowCompletionOr create_immutable_binding(VM&, FlyString const& name, bool strict) override; - virtual ThrowCompletionOr initialize_binding(VM&, FlyString const& name, Value, Environment::InitializeBindingHint) override; - virtual ThrowCompletionOr set_mutable_binding(VM&, FlyString const& name, Value, bool strict) override; - virtual ThrowCompletionOr get_binding_value(VM&, FlyString const& name, bool strict) override; - virtual ThrowCompletionOr delete_binding(VM&, FlyString const& name) override; + virtual ThrowCompletionOr has_binding(Utf16FlyString const& name, Optional* = nullptr) const override; + virtual ThrowCompletionOr create_mutable_binding(VM&, Utf16FlyString const& name, bool can_be_deleted) override; + virtual ThrowCompletionOr create_immutable_binding(VM&, Utf16FlyString const& name, bool strict) override; + virtual ThrowCompletionOr initialize_binding(VM&, Utf16FlyString const& name, Value, Environment::InitializeBindingHint) override; + virtual ThrowCompletionOr set_mutable_binding(VM&, Utf16FlyString const& name, Value, bool strict) override; + virtual ThrowCompletionOr get_binding_value(VM&, Utf16FlyString const& name, bool strict) override; + virtual ThrowCompletionOr delete_binding(VM&, Utf16FlyString const& name) override; ObjectEnvironment& object_record() { return *m_object_record; } Object& global_this_value() { return *m_global_this_value; } DeclarativeEnvironment& declarative_record() { return *m_declarative_record; } - bool has_lexical_declaration(FlyString const& name) const; - ThrowCompletionOr has_restricted_global_property(FlyString const& name) const; - ThrowCompletionOr can_declare_global_var(FlyString const& name) const; - ThrowCompletionOr can_declare_global_function(FlyString const& name) const; - ThrowCompletionOr create_global_var_binding(FlyString const& name, bool can_be_deleted); - ThrowCompletionOr create_global_function_binding(FlyString const& name, Value, bool can_be_deleted); + bool has_lexical_declaration(Utf16FlyString const& name) const; + ThrowCompletionOr has_restricted_global_property(Utf16FlyString const& name) const; + ThrowCompletionOr can_declare_global_var(Utf16FlyString const& name) const; + ThrowCompletionOr can_declare_global_function(Utf16FlyString const& name) const; + ThrowCompletionOr create_global_var_binding(Utf16FlyString const& name, bool can_be_deleted); + ThrowCompletionOr create_global_function_binding(Utf16FlyString const& name, Value, bool can_be_deleted); private: GlobalEnvironment(Object&, Object& this_value); diff --git a/Libraries/LibJS/Runtime/Intl/DurationFormat.cpp b/Libraries/LibJS/Runtime/Intl/DurationFormat.cpp index 58f6a87abb..acfa3a2df9 100644 --- a/Libraries/LibJS/Runtime/Intl/DurationFormat.cpp +++ b/Libraries/LibJS/Runtime/Intl/DurationFormat.cpp @@ -203,7 +203,7 @@ static GC::Ref construct_list_format(VM& vm, DurationFormat const& d // 13.5.6.1 ValidateDurationUnitStyle ( unit, style, display, prevStyle ), https://tc39.es/ecma402/#sec-validatedurationunitstyle // AD-HOC: Our implementation takes extra parameters for better exception messages. -static ThrowCompletionOr validate_duration_unit_style(VM& vm, PropertyKey const& unit, DurationFormat::ValueStyle style, DurationFormat::Display display, Optional previous_style, StringView display_field) +static ThrowCompletionOr validate_duration_unit_style(VM& vm, PropertyKey const& unit, DurationFormat::ValueStyle style, DurationFormat::Display display, Optional previous_style, Utf16View const& display_field) { // 1. If display is "always" and style is "fractional", throw a RangeError exception. if (display == DurationFormat::Display::Always && style == DurationFormat::ValueStyle::Fractional) @@ -277,7 +277,7 @@ ThrowCompletionOr get_duration_unit_options } // 5. Let displayField be the string-concatenation of unit and "Display". - auto display_field = MUST(String::formatted("{}Display", unit_property_key)); + auto display_field = Utf16String::formatted("{}Display", unit_property_key); // 6. Let display be ? GetOption(options, displayField, STRING, « "auto", "always" », displayDefault). auto display_value = TRY(get_option(vm, options, display_field, OptionType::String, { "auto"sv, "always"sv }, display_default)); @@ -922,7 +922,7 @@ Vector partition_duration_format_pattern(VM& vm, DurationFor for (auto& part : parts) { // a. Append the Record { [[Type]]: part.[[Type]], [[Value]]: part.[[Value]], [[Unit]]: numberFormatUnit } to list. - list.unchecked_append({ .type = part.type, .value = move(part.value), .unit = number_format_unit.as_string() }); + list.unchecked_append({ .type = part.type, .value = move(part.value), .unit = number_format_unit.as_string().view() }); } // 11. Append list to result. diff --git a/Libraries/LibJS/Runtime/Intl/DurationFormat.h b/Libraries/LibJS/Runtime/Intl/DurationFormat.h index b5a618b538..bd5c9e100c 100644 --- a/Libraries/LibJS/Runtime/Intl/DurationFormat.h +++ b/Libraries/LibJS/Runtime/Intl/DurationFormat.h @@ -179,7 +179,7 @@ static constexpr auto duration_instances_components = to_array get_duration_unit_options(VM&, DurationFormat::Unit unit, Object const& options, DurationFormat::Style base_style, ReadonlySpan styles_list, DurationFormat::ValueStyle digital_base, Optional previous_style, bool two_digit_hours); diff --git a/Libraries/LibJS/Runtime/Intrinsics.cpp b/Libraries/LibJS/Runtime/Intrinsics.cpp index 885de9e2ae..29268f4f0a 100644 --- a/Libraries/LibJS/Runtime/Intrinsics.cpp +++ b/Libraries/LibJS/Runtime/Intrinsics.cpp @@ -286,7 +286,7 @@ void Intrinsics::initialize_intrinsics(Realm& realm) realm, [](VM& vm) { return vm.throw_completion(ErrorType::RestrictedFunctionPropertiesAccess); }, - 0, FlyString {}, &realm); + 0, Utf16FlyString {}, &realm); m_throw_type_error_function->define_direct_property(vm.names.length, Value(0), 0); m_throw_type_error_function->define_direct_property(vm.names.name, PrimitiveString::create(vm, String {}), 0); MUST(m_throw_type_error_function->internal_prevent_extensions()); diff --git a/Libraries/LibJS/Runtime/JSONObject.cpp b/Libraries/LibJS/Runtime/JSONObject.cpp index 4c7205bfb0..b63d09f205 100644 --- a/Libraries/LibJS/Runtime/JSONObject.cpp +++ b/Libraries/LibJS/Runtime/JSONObject.cpp @@ -64,24 +64,24 @@ ThrowCompletionOr> JSONObject::stringify_impl(VM& vm, Value val if (is_array) { auto& replacer_object = replacer.as_object(); auto replacer_length = TRY(length_of_array_like(vm, replacer_object)); - Vector list; + Vector list; for (size_t i = 0; i < replacer_length; ++i) { auto replacer_value = TRY(replacer_object.get(i)); - Optional item; + Optional item; if (replacer_value.is_string()) { - item = replacer_value.as_string().utf8_string(); + item = replacer_value.as_string().utf16_string(); } else if (replacer_value.is_number()) { - item = MUST(replacer_value.to_string(vm)); + item = MUST(replacer_value.to_utf16_string(vm)); } else if (replacer_value.is_object()) { auto& value_object = replacer_value.as_object(); if (is(value_object) || is(value_object)) - item = TRY(replacer_value.to_string(vm)); + item = TRY(replacer_value.to_utf16_string(vm)); } if (item.has_value() && !list.contains_slow(*item)) { list.append(*item); } } - state.property_list = list; + state.property_list = move(list); } } } @@ -109,8 +109,8 @@ ThrowCompletionOr> JSONObject::stringify_impl(VM& vm, Value val } auto wrapper = Object::create(realm, realm.intrinsics().object_prototype()); - MUST(wrapper->create_data_property_or_throw(String {}, value)); - return serialize_json_property(vm, state, String {}, wrapper); + MUST(wrapper->create_data_property_or_throw(Utf16String {}, value)); + return serialize_json_property(vm, state, Utf16String {}, wrapper); } // 25.5.2 JSON.stringify ( value [ , replacer [ , space ] ] ), https://tc39.es/ecma262/#sec-json.stringify @@ -197,7 +197,7 @@ ThrowCompletionOr> JSONObject::serialize_json_property(VM& vm, // 8. If Type(value) is String, return QuoteJSONString(value). if (value.is_string()) - return quote_json_string(value.as_string().utf8_string()); + return quote_json_string(value.as_string().utf16_string_view()); // 9. If Type(value) is Number, then if (value.is_number()) { @@ -262,7 +262,7 @@ ThrowCompletionOr JSONObject::serialize_json_object(VM& vm, StringifySta } else { auto property_list = TRY(object.enumerable_own_property_names(PropertyKind::Key)); for (auto& property : property_list) - TRY(process_property(property.as_string().utf8_string())); + TRY(process_property(property.as_string().utf16_string())); } StringBuilder builder; if (property_strings.is_empty()) { @@ -360,15 +360,14 @@ ThrowCompletionOr JSONObject::serialize_json_array(VM& vm, StringifyStat } // 25.5.2.2 QuoteJSONString ( value ), https://tc39.es/ecma262/#sec-quotejsonstring -String JSONObject::quote_json_string(String string) +String JSONObject::quote_json_string(Utf16View const& string) { // 1. Let product be the String value consisting solely of the code unit 0x0022 (QUOTATION MARK). StringBuilder builder; builder.append('"'); // 2. For each code point C of StringToCodePoints(value), do - auto utf_view = Utf8View(string); - for (auto code_point : utf_view) { + for (auto code_point : string) { // a. If C is listed in the “Code Point” column of Table 70, then // i. Set product to the string-concatenation of product and the escape sequence for C as specified in the “Escape Sequence” column of the corresponding row. switch (code_point) { @@ -407,6 +406,7 @@ String JSONObject::quote_json_string(String string) } } } + // 3. Set product to the string-concatenation of product and the code unit 0x0022 (QUOTATION MARK). builder.append('"'); @@ -434,7 +434,7 @@ JS_DEFINE_NATIVE_FUNCTION(JSONObject::parse) auto root = Object::create(realm, realm.intrinsics().object_prototype()); // b. Let rootName be the empty String. - String root_name; + Utf16String root_name; // c. Perform ! CreateDataPropertyOrThrow(root, rootName, unfiltered). MUST(root->create_data_property_or_throw(root_name, unfiltered)); @@ -492,7 +492,7 @@ Object* JSONObject::parse_json_object(VM& vm, JsonObject const& json_object) auto& realm = *vm.current_realm(); auto object = Object::create(realm, realm.intrinsics().object_prototype()); json_object.for_each_member([&](auto& key, auto& value) { - object->define_direct_property(key, parse_json_value(vm, value), default_attributes); + object->define_direct_property(Utf16String::from_utf8(key), parse_json_value(vm, value), default_attributes); }); return object; } @@ -532,7 +532,7 @@ ThrowCompletionOr JSONObject::internalize_json_property(VM& vm, Object* h } else { auto property_list = TRY(value_object.enumerable_own_property_names(Object::PropertyKind::Key)); for (auto& property_key : property_list) - TRY(process_property(property_key.as_string().utf8_string())); + TRY(process_property(property_key.as_string().utf16_string())); } } diff --git a/Libraries/LibJS/Runtime/JSONObject.h b/Libraries/LibJS/Runtime/JSONObject.h index 23f142b886..e1615c9690 100644 --- a/Libraries/LibJS/Runtime/JSONObject.h +++ b/Libraries/LibJS/Runtime/JSONObject.h @@ -34,14 +34,14 @@ private: HashTable> seen_objects; String indent; String gap; - Optional> property_list; + Optional> property_list; }; // Stringify helpers static ThrowCompletionOr> serialize_json_property(VM&, StringifyState&, PropertyKey const& key, Object* holder); static ThrowCompletionOr serialize_json_object(VM&, StringifyState&, Object&); static ThrowCompletionOr serialize_json_array(VM&, StringifyState&, Object&); - static String quote_json_string(String); + static String quote_json_string(Utf16View const&); // Parse helpers static Object* parse_json_object(VM&, JsonObject const&); diff --git a/Libraries/LibJS/Runtime/ModuleEnvironment.cpp b/Libraries/LibJS/Runtime/ModuleEnvironment.cpp index 2f552be1b7..7f0ec7b9e0 100644 --- a/Libraries/LibJS/Runtime/ModuleEnvironment.cpp +++ b/Libraries/LibJS/Runtime/ModuleEnvironment.cpp @@ -20,7 +20,7 @@ ModuleEnvironment::ModuleEnvironment(Environment* outer_environment) } // 9.1.1.5.1 GetBindingValue ( N, S ), https://tc39.es/ecma262/#sec-module-environment-records-getbindingvalue-n-s -ThrowCompletionOr ModuleEnvironment::get_binding_value(VM& vm, FlyString const& name, bool strict) +ThrowCompletionOr ModuleEnvironment::get_binding_value(VM& vm, Utf16FlyString const& name, bool strict) { // 1. Assert: S is true. VERIFY(strict); @@ -51,7 +51,7 @@ ThrowCompletionOr ModuleEnvironment::get_binding_value(VM& vm, FlyString } // 9.1.1.5.2 DeleteBinding ( N ), https://tc39.es/ecma262/#sec-module-environment-records-deletebinding-n -ThrowCompletionOr ModuleEnvironment::delete_binding(VM&, FlyString const&) +ThrowCompletionOr ModuleEnvironment::delete_binding(VM&, Utf16FlyString const&) { // The DeleteBinding concrete method of a module Environment Record is never used within this specification. VERIFY_NOT_REACHED(); @@ -65,7 +65,7 @@ ThrowCompletionOr ModuleEnvironment::get_this_binding(VM&) const } // 9.1.1.5.5 CreateImportBinding ( N, M, N2 ), https://tc39.es/ecma262/#sec-createimportbinding -ThrowCompletionOr ModuleEnvironment::create_import_binding(FlyString name, Module* module, FlyString binding_name) +ThrowCompletionOr ModuleEnvironment::create_import_binding(Utf16FlyString name, Module* module, Utf16FlyString binding_name) { // 1. Assert: envRec does not already have a binding for N. VERIFY(!get_indirect_binding(name)); @@ -82,7 +82,7 @@ ThrowCompletionOr ModuleEnvironment::create_import_binding(FlyString name, return {}; } -ModuleEnvironment::IndirectBinding const* ModuleEnvironment::get_indirect_binding(FlyString const& name) const +ModuleEnvironment::IndirectBinding const* ModuleEnvironment::get_indirect_binding(Utf16FlyString const& name) const { auto binding_or_end = m_indirect_bindings.find_if([&](IndirectBinding const& binding) { return binding.name == name; @@ -93,7 +93,7 @@ ModuleEnvironment::IndirectBinding const* ModuleEnvironment::get_indirect_bindin return &(*binding_or_end); } -Optional ModuleEnvironment::find_binding_and_index(FlyString const& name) const +Optional ModuleEnvironment::find_binding_and_index(Utf16FlyString const& name) const { auto* indirect_binding = get_indirect_binding(name); if (indirect_binding != nullptr) { diff --git a/Libraries/LibJS/Runtime/ModuleEnvironment.h b/Libraries/LibJS/Runtime/ModuleEnvironment.h index daec2c0ca1..96f7a97180 100644 --- a/Libraries/LibJS/Runtime/ModuleEnvironment.h +++ b/Libraries/LibJS/Runtime/ModuleEnvironment.h @@ -22,11 +22,11 @@ public: // in Table 18 and share the same specifications for all of those methods except for // GetBindingValue, DeleteBinding, HasThisBinding and GetThisBinding. // In addition, module Environment Records support the methods listed in Table 24. - virtual ThrowCompletionOr get_binding_value(VM&, FlyString const& name, bool strict) override; - virtual ThrowCompletionOr delete_binding(VM&, FlyString const& name) override; + virtual ThrowCompletionOr get_binding_value(VM&, Utf16FlyString const& name, bool strict) override; + virtual ThrowCompletionOr delete_binding(VM&, Utf16FlyString const& name) override; virtual bool has_this_binding() const final { return true; } virtual ThrowCompletionOr get_this_binding(VM&) const final; - ThrowCompletionOr create_import_binding(FlyString name, Module* module, FlyString binding_name); + ThrowCompletionOr create_import_binding(Utf16FlyString name, Module* module, Utf16FlyString binding_name); private: explicit ModuleEnvironment(Environment* outer_environment); @@ -34,13 +34,13 @@ private: virtual void visit_edges(Visitor&) override; struct IndirectBinding { - FlyString name; + Utf16FlyString name; GC::Ptr module; - FlyString binding_name; + Utf16FlyString binding_name; }; - IndirectBinding const* get_indirect_binding(FlyString const& name) const; + IndirectBinding const* get_indirect_binding(Utf16FlyString const& name) const; - virtual Optional find_binding_and_index(FlyString const& name) const override; + virtual Optional find_binding_and_index(Utf16FlyString const& name) const override; // FIXME: Since we always access this via the name this could be a map. Vector m_indirect_bindings; diff --git a/Libraries/LibJS/Runtime/ModuleNamespaceObject.cpp b/Libraries/LibJS/Runtime/ModuleNamespaceObject.cpp index 7d467c743c..7a17843692 100644 --- a/Libraries/LibJS/Runtime/ModuleNamespaceObject.cpp +++ b/Libraries/LibJS/Runtime/ModuleNamespaceObject.cpp @@ -13,16 +13,14 @@ namespace JS { GC_DEFINE_ALLOCATOR(ModuleNamespaceObject); -ModuleNamespaceObject::ModuleNamespaceObject(Realm& realm, Module* module, Vector exports) +ModuleNamespaceObject::ModuleNamespaceObject(Realm& realm, Module* module, Vector exports) : Object(ConstructWithPrototypeTag::Tag, realm.intrinsics().object_prototype(), MayInterfereWithIndexedPropertyAccess::Yes) , m_module(module) , m_exports(move(exports)) { // Note: We just perform step 6 of 10.4.6.12 ModuleNamespaceCreate ( module, exports ), https://tc39.es/ecma262/#sec-modulenamespacecreate // 6. Let sortedExports be a List whose elements are the elements of exports ordered as if an Array of the same values had been sorted using %Array.prototype.sort% using undefined as comparefn. - quick_sort(m_exports, [&](FlyString const& lhs, FlyString const& rhs) { - return lhs.bytes_as_string_view() < rhs.bytes_as_string_view(); - }); + quick_sort(m_exports); } void ModuleNamespaceObject::initialize(Realm& realm) diff --git a/Libraries/LibJS/Runtime/ModuleNamespaceObject.h b/Libraries/LibJS/Runtime/ModuleNamespaceObject.h index 81b56852f5..b84997623c 100644 --- a/Libraries/LibJS/Runtime/ModuleNamespaceObject.h +++ b/Libraries/LibJS/Runtime/ModuleNamespaceObject.h @@ -33,12 +33,12 @@ public: virtual void initialize(Realm&) override; private: - ModuleNamespaceObject(Realm&, Module* module, Vector exports); + ModuleNamespaceObject(Realm&, Module* module, Vector exports); virtual void visit_edges(Visitor&) override; - GC::Ptr m_module; // [[Module]] - Vector m_exports; // [[Exports]] + GC::Ptr m_module; // [[Module]] + Vector m_exports; // [[Exports]] }; } diff --git a/Libraries/LibJS/Runtime/NativeFunction.cpp b/Libraries/LibJS/Runtime/NativeFunction.cpp index 2129f553a2..259bad65e0 100644 --- a/Libraries/LibJS/Runtime/NativeFunction.cpp +++ b/Libraries/LibJS/Runtime/NativeFunction.cpp @@ -68,7 +68,7 @@ GC::Ref NativeFunction::create(Realm& allocating_realm, Function return function; } -GC::Ref NativeFunction::create(Realm& realm, FlyString const& name, Function(VM&)> function) +GC::Ref NativeFunction::create(Realm& realm, Utf16FlyString const& name, Function(VM&)> function) { return realm.create(name, move(function), realm.intrinsics().function_prototype()); } @@ -91,7 +91,7 @@ NativeFunction::NativeFunction(Object& prototype) { } -NativeFunction::NativeFunction(FlyString name, AK::Function(VM&)> native_function, Object& prototype) +NativeFunction::NativeFunction(Utf16FlyString name, AK::Function(VM&)> native_function, Object& prototype) : FunctionObject(prototype) , m_name(move(name)) , m_native_function(move(native_function)) @@ -99,7 +99,7 @@ NativeFunction::NativeFunction(FlyString name, AK::Function create(Realm&, ESCAPING Function(VM&)> behaviour, i32 length, PropertyKey const& name = FlyString {}, Optional = {}, Optional const& prefix = {}, Optional builtin = {}); - static GC::Ref create(Realm&, FlyString const& name, ESCAPING Function(VM&)>); + static GC::Ref create(Realm&, ESCAPING Function(VM&)> behaviour, i32 length, PropertyKey const& name = Utf16FlyString {}, Optional = {}, Optional const& prefix = {}, Optional builtin = {}); + static GC::Ref create(Realm&, Utf16FlyString const& name, ESCAPING Function(VM&)>); virtual ~NativeFunction() override = default; @@ -36,13 +36,13 @@ public: virtual ThrowCompletionOr call(); virtual ThrowCompletionOr> construct(FunctionObject& new_target); - FlyString const& name() const { return m_name; } + Utf16FlyString const& name() const { return m_name; } virtual bool is_strict_mode() const override; virtual bool has_constructor() const override { return false; } virtual Realm* realm() const override { return m_realm; } - Optional const& initial_name() const { return m_initial_name; } - void set_initial_name(Badge, FlyString initial_name) { m_initial_name = move(initial_name); } + Optional const& initial_name() const { return m_initial_name; } + void set_initial_name(Badge, Utf16FlyString initial_name) { m_initial_name = move(initial_name); } bool is_array_prototype_next_builtin() const { return m_builtin.has_value() && *m_builtin == Bytecode::Builtin::ArrayIteratorPrototypeNext; } bool is_map_prototype_next_builtin() const { return m_builtin.has_value() && *m_builtin == Bytecode::Builtin::MapIteratorPrototypeNext; } @@ -50,9 +50,9 @@ public: bool is_string_prototype_next_builtin() const { return m_builtin.has_value() && *m_builtin == Bytecode::Builtin::StringIteratorPrototypeNext; } protected: - NativeFunction(FlyString name, Object& prototype); + NativeFunction(Utf16FlyString name, Object& prototype); NativeFunction(AK::Function(VM&)>, Object* prototype, Realm& realm, Optional builtin); - NativeFunction(FlyString name, AK::Function(VM&)>, Object& prototype); + NativeFunction(Utf16FlyString name, AK::Function(VM&)>, Object& prototype); explicit NativeFunction(Object& prototype); virtual void initialize(Realm&) override; @@ -61,9 +61,9 @@ protected: private: virtual bool is_native_function() const final { return true; } - FlyString m_name; + Utf16FlyString m_name; GC::Ptr m_name_string; - Optional m_initial_name; // [[InitialName]] + Optional m_initial_name; // [[InitialName]] Optional m_builtin; AK::Function(VM&)> m_native_function; GC::Ptr m_realm; diff --git a/Libraries/LibJS/Runtime/Object.cpp b/Libraries/LibJS/Runtime/Object.cpp index c82c3d664b..d372dc8d16 100644 --- a/Libraries/LibJS/Runtime/Object.cpp +++ b/Libraries/LibJS/Runtime/Object.cpp @@ -29,7 +29,7 @@ namespace JS { GC_DEFINE_ALLOCATOR(Object); -static HashMap, HashMap> s_intrinsics; +static HashMap, HashMap> s_intrinsics; // 10.1.12 OrdinaryObjectCreate ( proto [ , additionalInternalSlotsList ] ), https://tc39.es/ecma262/#sec-ordinaryobjectcreate GC::Ref Object::create(Realm& realm, Object* prototype) @@ -1407,7 +1407,7 @@ Optional Object::enumerate_object_properties(Function visited; + HashTable visited; auto const* target = this; while (target) { @@ -1415,7 +1415,7 @@ Optional Object::enumerate_object_properties(Functioninternal_get_own_property(property_key)); diff --git a/Libraries/LibJS/Runtime/ObjectEnvironment.cpp b/Libraries/LibJS/Runtime/ObjectEnvironment.cpp index 41b1b3a731..61b4ef9f4e 100644 --- a/Libraries/LibJS/Runtime/ObjectEnvironment.cpp +++ b/Libraries/LibJS/Runtime/ObjectEnvironment.cpp @@ -27,7 +27,7 @@ void ObjectEnvironment::visit_edges(Cell::Visitor& visitor) } // 9.1.1.2.1 HasBinding ( N ), https://tc39.es/ecma262/#sec-object-environment-records-hasbinding-n -ThrowCompletionOr ObjectEnvironment::has_binding(FlyString const& name, Optional*) const +ThrowCompletionOr ObjectEnvironment::has_binding(Utf16FlyString const& name, Optional*) const { auto& vm = this->vm(); @@ -62,7 +62,7 @@ ThrowCompletionOr ObjectEnvironment::has_binding(FlyString const& name, Op } // 9.1.1.2.2 CreateMutableBinding ( N, D ), https://tc39.es/ecma262/#sec-object-environment-records-createmutablebinding-n-d -ThrowCompletionOr ObjectEnvironment::create_mutable_binding(VM&, FlyString const& name, bool can_be_deleted) +ThrowCompletionOr ObjectEnvironment::create_mutable_binding(VM&, Utf16FlyString const& name, bool can_be_deleted) { // 1. Let bindingObject be envRec.[[BindingObject]]. // 2. Perform ? DefinePropertyOrThrow(bindingObject, N, PropertyDescriptor { [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D }). @@ -73,14 +73,14 @@ ThrowCompletionOr ObjectEnvironment::create_mutable_binding(VM&, FlyString } // 9.1.1.2.3 CreateImmutableBinding ( N, S ), https://tc39.es/ecma262/#sec-object-environment-records-createimmutablebinding-n-s -ThrowCompletionOr ObjectEnvironment::create_immutable_binding(VM&, FlyString const&, bool) +ThrowCompletionOr ObjectEnvironment::create_immutable_binding(VM&, Utf16FlyString const&, bool) { // "The CreateImmutableBinding concrete method of an object Environment Record is never used within this specification." VERIFY_NOT_REACHED(); } // 9.1.1.2.4 InitializeBinding ( N, V ), https://tc39.es/ecma262/#sec-object-environment-records-initializebinding-n-v -ThrowCompletionOr ObjectEnvironment::initialize_binding(VM& vm, FlyString const& name, Value value, Environment::InitializeBindingHint hint) +ThrowCompletionOr ObjectEnvironment::initialize_binding(VM& vm, Utf16FlyString const& name, Value value, Environment::InitializeBindingHint hint) { // 1. Assert: hint is normal. VERIFY(hint == Environment::InitializeBindingHint::Normal); @@ -93,7 +93,7 @@ ThrowCompletionOr ObjectEnvironment::initialize_binding(VM& vm, FlyString } // 9.1.1.2.5 SetMutableBinding ( N, V, S ), https://tc39.es/ecma262/#sec-object-environment-records-setmutablebinding-n-v-s -ThrowCompletionOr ObjectEnvironment::set_mutable_binding(VM&, FlyString const& name, Value value, bool strict) +ThrowCompletionOr ObjectEnvironment::set_mutable_binding(VM&, Utf16FlyString const& name, Value value, bool strict) { auto& vm = this->vm(); @@ -135,7 +135,7 @@ ThrowCompletionOr ObjectEnvironment::set_mutable_binding(VM&, FlyString co } // 9.1.1.2.6 GetBindingValue ( N, S ), https://tc39.es/ecma262/#sec-object-environment-records-getbindingvalue-n-s -ThrowCompletionOr ObjectEnvironment::get_binding_value(VM&, FlyString const& name, bool strict) +ThrowCompletionOr ObjectEnvironment::get_binding_value(VM&, Utf16FlyString const& name, bool strict) { auto& vm = this->vm(); @@ -164,7 +164,7 @@ ThrowCompletionOr ObjectEnvironment::get_binding_value(VM&, FlyString con } // 9.1.1.2.7 DeleteBinding ( N ), https://tc39.es/ecma262/#sec-object-environment-records-deletebinding-n -ThrowCompletionOr ObjectEnvironment::delete_binding(VM&, FlyString const& name) +ThrowCompletionOr ObjectEnvironment::delete_binding(VM&, Utf16FlyString const& name) { // 1. Let bindingObject be envRec.[[BindingObject]]. // 2. Return ? bindingObject.[[Delete]](N). diff --git a/Libraries/LibJS/Runtime/ObjectEnvironment.h b/Libraries/LibJS/Runtime/ObjectEnvironment.h index 509f6675ab..d1eeab4221 100644 --- a/Libraries/LibJS/Runtime/ObjectEnvironment.h +++ b/Libraries/LibJS/Runtime/ObjectEnvironment.h @@ -20,13 +20,13 @@ public: Yes, }; - virtual ThrowCompletionOr has_binding(FlyString const& name, Optional* = nullptr) const override; - virtual ThrowCompletionOr create_mutable_binding(VM&, FlyString const& name, bool can_be_deleted) override; - virtual ThrowCompletionOr create_immutable_binding(VM&, FlyString const& name, bool strict) override; - virtual ThrowCompletionOr initialize_binding(VM&, FlyString const& name, Value, Environment::InitializeBindingHint) override; - virtual ThrowCompletionOr set_mutable_binding(VM&, FlyString const& name, Value, bool strict) override; - virtual ThrowCompletionOr get_binding_value(VM&, FlyString const& name, bool strict) override; - virtual ThrowCompletionOr delete_binding(VM&, FlyString const& name) override; + virtual ThrowCompletionOr has_binding(Utf16FlyString const& name, Optional* = nullptr) const override; + virtual ThrowCompletionOr create_mutable_binding(VM&, Utf16FlyString const& name, bool can_be_deleted) override; + virtual ThrowCompletionOr create_immutable_binding(VM&, Utf16FlyString const& name, bool strict) override; + virtual ThrowCompletionOr initialize_binding(VM&, Utf16FlyString const& name, Value, Environment::InitializeBindingHint) override; + virtual ThrowCompletionOr set_mutable_binding(VM&, Utf16FlyString const& name, Value, bool strict) override; + virtual ThrowCompletionOr get_binding_value(VM&, Utf16FlyString const& name, bool strict) override; + virtual ThrowCompletionOr delete_binding(VM&, Utf16FlyString const& name) override; // 9.1.1.2.10 WithBaseObject ( ), https://tc39.es/ecma262/#sec-object-environment-records-withbaseobject virtual Object* with_base_object() const override diff --git a/Libraries/LibJS/Runtime/PrivateEnvironment.cpp b/Libraries/LibJS/Runtime/PrivateEnvironment.cpp index 45c5ab1ca7..b6310fba17 100644 --- a/Libraries/LibJS/Runtime/PrivateEnvironment.cpp +++ b/Libraries/LibJS/Runtime/PrivateEnvironment.cpp @@ -21,7 +21,7 @@ PrivateEnvironment::PrivateEnvironment(PrivateEnvironment* parent) // Note: we start at one such that 0 can be invalid / default initialized. u64 PrivateEnvironment::s_next_id = 1u; -PrivateName PrivateEnvironment::resolve_private_identifier(FlyString const& identifier) const +PrivateName PrivateEnvironment::resolve_private_identifier(Utf16FlyString const& identifier) const { auto name_or_end = find_private_name(identifier); @@ -34,7 +34,7 @@ PrivateName PrivateEnvironment::resolve_private_identifier(FlyString const& iden return m_outer_environment->resolve_private_identifier(identifier); } -void PrivateEnvironment::add_private_name(FlyString description) +void PrivateEnvironment::add_private_name(Utf16FlyString description) { if (!find_private_name(description).is_end()) return; diff --git a/Libraries/LibJS/Runtime/PrivateEnvironment.h b/Libraries/LibJS/Runtime/PrivateEnvironment.h index d79d6386cd..87311b86c3 100644 --- a/Libraries/LibJS/Runtime/PrivateEnvironment.h +++ b/Libraries/LibJS/Runtime/PrivateEnvironment.h @@ -6,8 +6,8 @@ #pragma once -#include #include +#include #include #include #include @@ -16,14 +16,14 @@ namespace JS { struct PrivateName { PrivateName() = default; - PrivateName(u64 unique_id, FlyString description) + PrivateName(u64 unique_id, Utf16FlyString description) : unique_id(unique_id) , description(move(description)) { } u64 unique_id { 0 }; - FlyString description; + Utf16FlyString description; bool operator==(PrivateName const& rhs) const; }; @@ -33,9 +33,9 @@ class PrivateEnvironment : public Cell { GC_DECLARE_ALLOCATOR(PrivateEnvironment); public: - PrivateName resolve_private_identifier(FlyString const& identifier) const; + PrivateName resolve_private_identifier(Utf16FlyString const& identifier) const; - void add_private_name(FlyString description); + void add_private_name(Utf16FlyString description); PrivateEnvironment* outer_environment() { return m_outer_environment; } PrivateEnvironment const* outer_environment() const { return m_outer_environment; } @@ -45,7 +45,7 @@ private: virtual void visit_edges(Visitor&) override; - auto find_private_name(FlyString const& description) const + auto find_private_name(Utf16FlyString const& description) const { return m_private_names.find_if([&](PrivateName const& private_name) { return private_name.description == description; diff --git a/Libraries/LibJS/Runtime/PropertyKey.h b/Libraries/LibJS/Runtime/PropertyKey.h index 94ed0c3f84..4712ac7338 100644 --- a/Libraries/LibJS/Runtime/PropertyKey.h +++ b/Libraries/LibJS/Runtime/PropertyKey.h @@ -7,7 +7,7 @@ #pragma once -#include +#include #include #include #include @@ -28,7 +28,7 @@ public: return PropertyKey { value.as_symbol() }; if (value.is_integral_number() && value.as_double() >= 0 && value.as_double() < NumericLimits::max()) return static_cast(value.as_double()); - return TRY(value.to_string(vm)); + return TRY(value.to_utf16_string(vm)); } static constexpr uintptr_t NORMAL_STRING_FLAG = 0; @@ -45,7 +45,7 @@ public: PropertyKey(PropertyKey const& other) { if (other.is_string()) - new (&m_string) FlyString(other.m_string); + new (&m_string) Utf16FlyString(other.m_string); else m_bits = other.m_bits; } @@ -53,7 +53,7 @@ public: PropertyKey(PropertyKey&& other) noexcept { if (other.is_string()) - new (&m_string) FlyString(move(other.m_string)); + new (&m_string) Utf16FlyString(move(other.m_string)); else m_bits = exchange(other.m_bits, 0); } @@ -66,30 +66,30 @@ public: VERIFY(index >= 0); if constexpr (NumericLimits::max() >= NumericLimits::max()) { if (index >= NumericLimits::max()) { - new (&m_string) FlyString { String::number(index) }; + new (&m_string) Utf16FlyString { Utf16String::number(index) }; return; } } m_number = static_cast(index) << 2 | NUMBER_FLAG; } - PropertyKey(FlyString string, StringMayBeNumber string_may_be_number = StringMayBeNumber::Yes) + PropertyKey(Utf16FlyString string, StringMayBeNumber string_may_be_number = StringMayBeNumber::Yes) { if (string_may_be_number == StringMayBeNumber::Yes) { - auto view = string.bytes_as_string_view(); - if (!view.is_empty() && !(view[0] == '0' && view.length() > 1)) { - auto property_index = view.to_number(TrimWhitespace::No); + if (!string.is_empty() && !(string.code_unit_at(0) == '0' && string.length_in_code_units() > 1)) { + auto property_index = string.to_number(TrimWhitespace::No); if (property_index.has_value() && property_index.value() < NumericLimits::max()) { m_number = static_cast(property_index.release_value()) << 2 | NUMBER_FLAG; return; } } } - new (&m_string) FlyString(move(string)); + + new (&m_string) Utf16FlyString(move(string)); } - PropertyKey(String const& string) - : PropertyKey(FlyString(string)) + PropertyKey(Utf16String const& string) + : PropertyKey(Utf16FlyString { string }) { } @@ -102,7 +102,7 @@ public: { if (this != &other) { if (is_string()) - m_string.~FlyString(); + m_string.~Utf16FlyString(); new (this) PropertyKey(other); } return *this; @@ -112,7 +112,7 @@ public: { if (this != &other) { if (is_string()) - m_string.~FlyString(); + m_string.~Utf16FlyString(); new (this) PropertyKey(move(other)); } return *this; @@ -121,7 +121,7 @@ public: ~PropertyKey() { if (is_string()) - m_string.~FlyString(); + m_string.~Utf16FlyString(); } u32 as_number() const @@ -130,7 +130,7 @@ public: return m_number >> 2; } - FlyString const& as_string() const + Utf16FlyString const& as_string() const { VERIFY(is_string()); return m_string; @@ -151,13 +151,13 @@ public: return Value { PrimitiveString::create(vm, String::number(as_number())) }; } - String to_string() const + Utf16String to_string() const { if (is_string()) - return as_string().to_string(); + return as_string().to_utf16_string(); if (is_symbol()) - return MUST(as_symbol()->descriptive_string()); - return String::number(as_number()); + return as_symbol()->descriptive_string(); + return Utf16String::number(as_number()); } void visit_edges(Cell::Visitor& visitor) const @@ -181,7 +181,7 @@ private: friend Traits; union { - FlyString m_string; + Utf16FlyString m_string; u64 m_number; Symbol const* m_symbol; uintptr_t m_bits; @@ -220,12 +220,12 @@ struct Traits : public DefaultTraits { }; template<> -struct Formatter : Formatter { +struct Formatter : Formatter { ErrorOr format(FormatBuilder& builder, JS::PropertyKey const& property_key) { if (property_key.is_number()) return builder.put_u64(property_key.as_number()); - return builder.put_string(property_key.to_string()); + return Formatter::format(builder, property_key.to_string()); } }; diff --git a/Libraries/LibJS/Runtime/Reference.cpp b/Libraries/LibJS/Runtime/Reference.cpp index b2e305acdd..7076a4a77e 100644 --- a/Libraries/LibJS/Runtime/Reference.cpp +++ b/Libraries/LibJS/Runtime/Reference.cpp @@ -208,7 +208,7 @@ ThrowCompletionOr Reference::initialize_referenced_binding(VM& vm, Value v } // 6.2.4.9 MakePrivateReference ( baseValue, privateIdentifier ), https://tc39.es/ecma262/#sec-makeprivatereference -Reference make_private_reference(VM& vm, Value base_value, FlyString const& private_identifier) +Reference make_private_reference(VM& vm, Value base_value, Utf16FlyString const& private_identifier) { // 1. Let privEnv be the running execution context's PrivateEnvironment. auto private_environment = vm.running_execution_context().private_environment; diff --git a/Libraries/LibJS/Runtime/Reference.h b/Libraries/LibJS/Runtime/Reference.h index 7864d4bb67..29c0aac2a7 100644 --- a/Libraries/LibJS/Runtime/Reference.h +++ b/Libraries/LibJS/Runtime/Reference.h @@ -13,7 +13,7 @@ namespace JS { -Reference make_private_reference(VM&, Value base_value, FlyString const& private_identifier); +Reference make_private_reference(VM&, Value base_value, Utf16FlyString const& private_identifier); class Reference { public: @@ -39,7 +39,7 @@ public: { } - Reference(Environment& base, FlyString referenced_name, bool strict = false, Optional environment_coordinate = {}) + Reference(Environment& base, Utf16FlyString referenced_name, bool strict = false, Optional environment_coordinate = {}) : m_base_type(BaseType::Environment) , m_base_environment(&base) , m_name(move(referenced_name)) diff --git a/Libraries/LibJS/Runtime/RegExpPrototype.cpp b/Libraries/LibJS/Runtime/RegExpPrototype.cpp index f033e36ae6..65876e7056 100644 --- a/Libraries/LibJS/Runtime/RegExpPrototype.cpp +++ b/Libraries/LibJS/Runtime/RegExpPrototype.cpp @@ -100,7 +100,7 @@ static Value get_match_index_pair(VM& vm, Utf16View const& string, Match const& } // 22.2.7.8 MakeMatchIndicesIndexPairArray ( S, indices, groupNames, hasGroups ), https://tc39.es/ecma262/#sec-makematchindicesindexpairarray -static Value make_match_indices_index_pair_array(VM& vm, Utf16View const& string, Vector> const& indices, HashMap const& group_names, bool has_groups) +static Value make_match_indices_index_pair_array(VM& vm, Utf16View const& string, Vector> const& indices, HashMap const& group_names, bool has_groups) { // Note: This implementation differs from the spec, but has the same behavior. // @@ -277,7 +277,7 @@ static ThrowCompletionOr regexp_builtin_exec(VM& vm, RegExpObject& regexp Vector captured_values; // 26. Let groupNames be a new empty List. - HashMap group_names; + HashMap group_names; // 27. Add match as the last element of indices. indices.append(move(match_indices)); @@ -334,7 +334,7 @@ static ThrowCompletionOr regexp_builtin_exec(VM& vm, RegExpObject& regexp // e. If the ith capture of R was defined with a GroupName, then if (capture.capture_group_name >= 0) { // i. Let s be the CapturingGroupName of the corresponding RegExpIdentifierName. - auto group_name = regex.parser_result.bytecode.get_string(capture.capture_group_name); + auto group_name = Utf16FlyString::from_utf8(regex.parser_result.bytecode.get_string(capture.capture_group_name)); // ii. Perform ! CreateDataPropertyOrThrow(groups, s, capturedValue). MUST(groups_object->create_data_property_or_throw(group_name, captured_value)); diff --git a/Libraries/LibJS/Runtime/ShadowRealm.cpp b/Libraries/LibJS/Runtime/ShadowRealm.cpp index 8420c8e58e..d6727ad87e 100644 --- a/Libraries/LibJS/Runtime/ShadowRealm.cpp +++ b/Libraries/LibJS/Runtime/ShadowRealm.cpp @@ -87,7 +87,7 @@ ThrowCompletionOr copy_name_and_length(VM& vm, FunctionObject& function, F target_name = PrimitiveString::create(vm, String {}); // 8. Perform SetFunctionName(F, targetName, prefix). - function.set_function_name({ target_name.as_string().utf8_string() }, move(prefix)); + function.set_function_name({ target_name.as_string().utf16_string() }, move(prefix)); return {}; } @@ -149,7 +149,7 @@ ThrowCompletionOr perform_shadow_realm_eval(VM& vm, Value source, Realm& // 5. If runningContext is not already suspended, suspend runningContext. // NOTE: This would be unused due to step 9 and is omitted for that reason. - auto maybe_executable = Bytecode::compile(vm, program, FunctionKind::Normal, "ShadowRealmEval"_fly_string); + auto maybe_executable = Bytecode::compile(vm, program, FunctionKind::Normal, "ShadowRealmEval"_utf16_fly_string); if (maybe_executable.is_error()) return vm.throw_completion(ErrorType::ShadowRealmEvaluateAbruptCompletion); auto executable = maybe_executable.release_value(); @@ -242,7 +242,7 @@ ThrowCompletionOr shadow_realm_import_value(VM& vm, String specifier_stri // NOTE: We don't support this concept yet. // 9. Let steps be the steps of an ExportGetter function as described below. - auto steps = [string = move(export_name_string)](auto& vm) -> ThrowCompletionOr { + auto steps = [string = Utf16String::from_utf8(export_name_string)](auto& vm) -> ThrowCompletionOr { // 1. Assert: exports is a module namespace exotic object. VERIFY(vm.argument(0).is_object()); auto& exports = vm.argument(0).as_object(); @@ -274,7 +274,7 @@ ThrowCompletionOr shadow_realm_import_value(VM& vm, String specifier_stri // 10. Let onFulfilled be CreateBuiltinFunction(steps, 1, "", « [[ExportNameString]] », callerRealm). // 11. Set onFulfilled.[[ExportNameString]] to exportNameString. - auto on_fulfilled = NativeFunction::create(realm, move(steps), 1, FlyString {}, &caller_realm); + auto on_fulfilled = NativeFunction::create(realm, move(steps), 1, Utf16FlyString {}, &caller_realm); // 12. Let promiseCapability be ! NewPromiseCapability(%Promise%). auto promise_capability = MUST(new_promise_capability(vm, realm.intrinsics().promise_constructor())); diff --git a/Libraries/LibJS/Runtime/StringConstructor.cpp b/Libraries/LibJS/Runtime/StringConstructor.cpp index 9b3de9f42c..b06b0d0215 100644 --- a/Libraries/LibJS/Runtime/StringConstructor.cpp +++ b/Libraries/LibJS/Runtime/StringConstructor.cpp @@ -54,7 +54,7 @@ ThrowCompletionOr StringConstructor::call() // 2. Else, // a. If NewTarget is undefined and value is a Symbol, return SymbolDescriptiveString(value). if (value.is_symbol()) - return PrimitiveString::create(vm, MUST(value.as_symbol().descriptive_string())); + return PrimitiveString::create(vm, value.as_symbol().descriptive_string()); // b. Let s be ? ToString(value). // 3. If NewTarget is undefined, return s. diff --git a/Libraries/LibJS/Runtime/Symbol.cpp b/Libraries/LibJS/Runtime/Symbol.cpp index b98fa8743d..8492877174 100644 --- a/Libraries/LibJS/Runtime/Symbol.cpp +++ b/Libraries/LibJS/Runtime/Symbol.cpp @@ -13,31 +13,31 @@ namespace JS { GC_DEFINE_ALLOCATOR(Symbol); -Symbol::Symbol(Optional description, bool is_global) +Symbol::Symbol(Optional description, bool is_global) : m_description(move(description)) , m_is_global(is_global) { } -GC::Ref Symbol::create(VM& vm, Optional description, bool is_global) +GC::Ref Symbol::create(VM& vm, Optional description, bool is_global) { return vm.heap().allocate(move(description), is_global); } // 20.4.3.3.1 SymbolDescriptiveString ( sym ), https://tc39.es/ecma262/#sec-symboldescriptivestring -ErrorOr Symbol::descriptive_string() const +Utf16String 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(String {}); + auto description = m_description.value_or({}); // 4. Return the string-concatenation of "Symbol(", desc, and ")". - return String::formatted("Symbol({})", description); + return Utf16String::formatted("Symbol({})", description); } // 20.4.5.1 KeyForSymbol ( sym ), https://tc39.es/ecma262/#sec-keyforsymbol -Optional Symbol::key() const +Optional Symbol::key() const { // 1. For each element e of the GlobalSymbolRegistry List, do // a. If SameValue(e.[[Symbol]], sym) is true, return e.[[Key]]. diff --git a/Libraries/LibJS/Runtime/Symbol.h b/Libraries/LibJS/Runtime/Symbol.h index 4159622bc7..0cd78520f7 100644 --- a/Libraries/LibJS/Runtime/Symbol.h +++ b/Libraries/LibJS/Runtime/Symbol.h @@ -7,7 +7,7 @@ #pragma once -#include +#include #include #include #include @@ -19,20 +19,20 @@ class JS_API Symbol final : public Cell { GC_DECLARE_ALLOCATOR(Symbol); public: - [[nodiscard]] static GC::Ref create(VM&, Optional description, bool is_global); + [[nodiscard]] static GC::Ref create(VM&, Optional description, bool is_global); virtual ~Symbol() = default; - Optional const& description() const { return m_description; } + Optional const& description() const { return m_description; } bool is_global() const { return m_is_global; } - ErrorOr descriptive_string() const; - Optional key() const; + Utf16String descriptive_string() const; + Optional key() const; private: - Symbol(Optional, bool); + Symbol(Optional, bool); - Optional m_description; + Optional m_description; bool m_is_global; }; diff --git a/Libraries/LibJS/Runtime/SymbolConstructor.cpp b/Libraries/LibJS/Runtime/SymbolConstructor.cpp index 0c3ff38a91..e91c27242b 100644 --- a/Libraries/LibJS/Runtime/SymbolConstructor.cpp +++ b/Libraries/LibJS/Runtime/SymbolConstructor.cpp @@ -47,8 +47,8 @@ ThrowCompletionOr SymbolConstructor::call() // 2. If description is undefined, let descString be undefined. // 3. Else, let descString be ? ToString(description). auto description_string = description.is_undefined() - ? Optional {} - : TRY(description.to_string(vm)); + ? Optional {} + : TRY(description.to_utf16_string(vm)); // 4. Return a new Symbol whose [[Description]] is descString. return Symbol::create(vm, move(description_string), false); @@ -65,7 +65,7 @@ ThrowCompletionOr> SymbolConstructor::construct(FunctionObject&) JS_DEFINE_NATIVE_FUNCTION(SymbolConstructor::for_) { // 1. Let stringKey be ? ToString(key). - auto string_key = TRY(vm.argument(0).to_string(vm)); + auto string_key = TRY(vm.argument(0).to_utf16_string(vm)); // 2. For each element e of the GlobalSymbolRegistry List, do auto result = vm.global_symbol_registry().get(string_key); diff --git a/Libraries/LibJS/Runtime/SymbolPrototype.cpp b/Libraries/LibJS/Runtime/SymbolPrototype.cpp index be686eb3d8..4148be42a1 100644 --- a/Libraries/LibJS/Runtime/SymbolPrototype.cpp +++ b/Libraries/LibJS/Runtime/SymbolPrototype.cpp @@ -79,7 +79,7 @@ JS_DEFINE_NATIVE_FUNCTION(SymbolPrototype::to_string) auto symbol = TRY(this_symbol_value(vm, vm.this_value())); // 2. Return SymbolDescriptiveString(sym). - return PrimitiveString::create(vm, TRY_OR_THROW_OOM(vm, symbol->descriptive_string())); + return PrimitiveString::create(vm, symbol->descriptive_string()); } // 20.4.3.4 Symbol.prototype.valueOf ( ), https://tc39.es/ecma262/#sec-symbol.prototype.valueof diff --git a/Libraries/LibJS/Runtime/Temporal/Calendar.cpp b/Libraries/LibJS/Runtime/Temporal/Calendar.cpp index 97e4ce6e7a..31967cc1e3 100644 --- a/Libraries/LibJS/Runtime/Temporal/Calendar.cpp +++ b/Libraries/LibJS/Runtime/Temporal/Calendar.cpp @@ -78,7 +78,7 @@ static Vector sorted_calendar_fields(VM& vm, CalendarFieldLis result.unchecked_append(data_for_field(field)); quick_sort(result, [](auto const& lhs, auto const& rhs) { - return StringView { lhs.property->as_string() } < StringView { rhs.property->as_string() }; + return lhs.property->as_string() < rhs.property->as_string(); }); return result; diff --git a/Libraries/LibJS/Runtime/TypedArray.cpp b/Libraries/LibJS/Runtime/TypedArray.cpp index d34d4b09cb..4f80cf8445 100644 --- a/Libraries/LibJS/Runtime/TypedArray.cpp +++ b/Libraries/LibJS/Runtime/TypedArray.cpp @@ -449,6 +449,7 @@ void TypedArrayBase::visit_edges(Visitor& visitor) GC_DEFINE_ALLOCATOR(ClassName); \ GC_DEFINE_ALLOCATOR(PrototypeName); \ GC_DEFINE_ALLOCATOR(ConstructorName); \ + \ ThrowCompletionOr> ClassName::create(Realm& realm, u32 length, FunctionObject& new_target) \ { \ auto* prototype = TRY(get_prototype_from_constructor(realm.vm(), new_target, &Intrinsics::snake_name##_prototype)); \ @@ -480,7 +481,7 @@ void TypedArrayBase::visit_edges(Visitor& visitor) { \ } \ \ - FlyString const& ClassName::element_name() const \ + Utf16FlyString const& ClassName::element_name() const \ { \ return vm().names.ClassName.as_string(); \ } \ diff --git a/Libraries/LibJS/Runtime/TypedArray.h b/Libraries/LibJS/Runtime/TypedArray.h index 3a9aa410c2..c87a9cd1ca 100644 --- a/Libraries/LibJS/Runtime/TypedArray.h +++ b/Libraries/LibJS/Runtime/TypedArray.h @@ -50,7 +50,7 @@ public: [[nodiscard]] Kind kind() const { return m_kind; } u32 element_size() const { return m_element_size; } - virtual FlyString const& element_name() const = 0; + virtual Utf16FlyString const& element_name() const = 0; // 25.1.3.11 IsUnclampedIntegerElementType ( type ), https://tc39.es/ecma262/#sec-isunclampedintegerelementtype virtual bool is_unclamped_integer_element_type() const = 0; @@ -524,7 +524,7 @@ ThrowCompletionOr compare_typed_array_elements(VM&, Value x, Value y, Fu static ThrowCompletionOr> create(Realm&, u32 length, FunctionObject& new_target); \ static ThrowCompletionOr> create(Realm&, u32 length); \ static GC::Ref create(Realm&, u32 length, ArrayBuffer& buffer); \ - virtual FlyString const& element_name() const override; \ + virtual Utf16FlyString const& element_name() const override; \ virtual GC::Ref intrinsic_constructor(Realm&) const override; \ \ protected: \ diff --git a/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp b/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp index bfefd1acaa..f75b178fbe 100644 --- a/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp +++ b/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp @@ -13,7 +13,7 @@ namespace JS { GC_DEFINE_ALLOCATOR(TypedArrayConstructor); -TypedArrayConstructor::TypedArrayConstructor(FlyString const& name, Object& prototype) +TypedArrayConstructor::TypedArrayConstructor(Utf16FlyString const& name, Object& prototype) : NativeFunction(name, prototype) { } diff --git a/Libraries/LibJS/Runtime/TypedArrayConstructor.h b/Libraries/LibJS/Runtime/TypedArrayConstructor.h index 3490b86b8d..843cf244e7 100644 --- a/Libraries/LibJS/Runtime/TypedArrayConstructor.h +++ b/Libraries/LibJS/Runtime/TypedArrayConstructor.h @@ -23,7 +23,7 @@ public: virtual ThrowCompletionOr> construct(FunctionObject& new_target) override; protected: - TypedArrayConstructor(FlyString const& name, Object& prototype); + TypedArrayConstructor(Utf16FlyString const& name, Object& prototype); private: virtual bool has_constructor() const override { return true; } diff --git a/Libraries/LibJS/Runtime/VM.cpp b/Libraries/LibJS/Runtime/VM.cpp index 1fa937c8f8..f6d8e60072 100644 --- a/Libraries/LibJS/Runtime/VM.cpp +++ b/Libraries/LibJS/Runtime/VM.cpp @@ -46,7 +46,7 @@ NonnullRefPtr VM::create() WellKnownSymbols well_known_symbols { #define __JS_ENUMERATE(SymbolName, snake_name) \ - Symbol::create(*vm, "Symbol." #SymbolName##_string, false), + Symbol::create(*vm, "Symbol." #SymbolName##_utf16, false), JS_ENUMERATE_WELL_KNOWN_SYMBOLS #undef __JS_ENUMERATE }; @@ -284,7 +284,7 @@ void VM::gather_roots(HashMap& roots) } // 9.1.2.1 GetIdentifierReference ( env, name, strict ), https://tc39.es/ecma262/#sec-getidentifierreference -ThrowCompletionOr VM::get_identifier_reference(Environment* environment, FlyString name, bool strict, size_t hops) +ThrowCompletionOr VM::get_identifier_reference(Environment* environment, Utf16FlyString name, bool strict, size_t hops) { // 1. If env is the value null, then if (!environment) { @@ -318,7 +318,7 @@ ThrowCompletionOr VM::get_identifier_reference(Environment* environme } // 9.4.2 ResolveBinding ( name [ , env ] ), https://tc39.es/ecma262/#sec-resolvebinding -ThrowCompletionOr VM::resolve_binding(FlyString const& name, Environment* environment) +ThrowCompletionOr VM::resolve_binding(Utf16FlyString const& name, Environment* environment) { // 1. If env is not present or if env is undefined, then if (!environment) { diff --git a/Libraries/LibJS/Runtime/VM.h b/Libraries/LibJS/Runtime/VM.h index 067b8c22ae..7c710e8f7b 100644 --- a/Libraries/LibJS/Runtime/VM.h +++ b/Libraries/LibJS/Runtime/VM.h @@ -196,14 +196,14 @@ public: StackInfo const& stack_info() const { return m_stack_info; } - HashMap> const& global_symbol_registry() const { return m_global_symbol_registry; } - HashMap>& global_symbol_registry() { return m_global_symbol_registry; } + HashMap> const& global_symbol_registry() const { return m_global_symbol_registry; } + HashMap>& global_symbol_registry() { return m_global_symbol_registry; } u32 execution_generation() const { return m_execution_generation; } void finish_execution_generation() { ++m_execution_generation; } - ThrowCompletionOr resolve_binding(FlyString const&, Environment* = nullptr); - ThrowCompletionOr get_identifier_reference(Environment*, FlyString, bool strict, size_t hops = 0); + ThrowCompletionOr resolve_binding(Utf16FlyString const&, Environment* = nullptr); + ThrowCompletionOr get_identifier_reference(Environment*, Utf16FlyString, bool strict, size_t hops = 0); // 5.2.3.2 Throw an Exception, https://tc39.es/ecma262/#sec-throw-an-exception template @@ -333,7 +333,7 @@ private: StackInfo m_stack_info; // GlobalSymbolRegistry, https://tc39.es/ecma262/#table-globalsymbolregistry-record-fields - HashMap> m_global_symbol_registry; + HashMap> m_global_symbol_registry; Vector()>>> m_promise_jobs; diff --git a/Libraries/LibJS/Runtime/Value.cpp b/Libraries/LibJS/Runtime/Value.cpp index 4de8e81051..f7d7387f78 100644 --- a/Libraries/LibJS/Runtime/Value.cpp +++ b/Libraries/LibJS/Runtime/Value.cpp @@ -383,7 +383,7 @@ String Value::to_string_without_side_effects() const case STRING_TAG: return as_string().utf8_string(); case SYMBOL_TAG: - return as_symbol().descriptive_string().release_value(); + return as_symbol().descriptive_string().to_utf8_but_should_be_ported_to_utf16(); case BIGINT_TAG: return as_bigint().to_string().release_value(); case OBJECT_TAG: @@ -909,7 +909,7 @@ ThrowCompletionOr Value::to_property_key(VM& vm) const // OPTIMIZATION: If this is already a string, we can skip all the ceremony. if (is_string()) - return PropertyKey { as_string().utf8_string() }; + return PropertyKey { as_string().utf16_string() }; // 1. Let key be ? ToPrimitive(argument, string). auto key = TRY(to_primitive(vm, PreferredType::String)); @@ -921,7 +921,7 @@ ThrowCompletionOr Value::to_property_key(VM& vm) const } // 3. Return ! ToString(key). - return MUST(key.to_string(vm)); + return MUST(key.to_utf16_string(vm)); } // 7.1.6 ToInt32 ( argument ), https://tc39.es/ecma262/#sec-toint32 diff --git a/Libraries/LibJS/SourceTextModule.cpp b/Libraries/LibJS/SourceTextModule.cpp index f598305b9a..f931994de4 100644 --- a/Libraries/LibJS/SourceTextModule.cpp +++ b/Libraries/LibJS/SourceTextModule.cpp @@ -262,7 +262,7 @@ Result, Vector> SourceTextModule::parse(S } // 16.2.1.7.2.1 GetExportedNames ( [ exportStarSet ] ), https://tc39.es/ecma262/#sec-getexportednames -Vector SourceTextModule::get_exported_names(VM& vm, HashTable& export_star_set) +Vector SourceTextModule::get_exported_names(VM& vm, HashTable& export_star_set) { dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] get_export_names of {}", filename()); @@ -285,7 +285,7 @@ Vector SourceTextModule::get_exported_names(VM& vm, HashTable exported_names; + Vector exported_names; // 6. For each ExportEntry Record e of module.[[LocalExportEntries]], do for (auto const& entry : m_local_export_entries) { @@ -296,7 +296,7 @@ Vector SourceTextModule::get_exported_names(VM& vm, HashTable SourceTextModule::get_exported_names(VM& vm, HashTable SourceTextModule::initialize_environment(VM& vm) VERIFY(entry.export_name.has_value()); // a. Let resolution be module.ResolveExport(e.[[ExportName]]). - auto resolution = resolve_export(vm, entry.export_name.value()); + auto resolution = resolve_export(vm, Utf16FlyString::from_utf8(entry.export_name.value())); // b. If resolution is either null or AMBIGUOUS, throw a SyntaxError exception. if (!resolution.is_valid()) @@ -371,6 +371,8 @@ ThrowCompletionOr SourceTextModule::initialize_environment(VM& vm) // 7. For each ImportEntry Record in of module.[[ImportEntries]], do for (auto const& import_entry : m_import_entries) { + auto local_name = Utf16FlyString::from_utf8(import_entry.local_name); + // a. Let importedModule be GetImportedModule(module, in.[[ModuleRequest]]). auto imported_module = get_imported_module(import_entry.module_request()); @@ -380,19 +382,21 @@ ThrowCompletionOr SourceTextModule::initialize_environment(VM& vm) auto namespace_ = imported_module->get_module_namespace(vm); // ii. Perform ! env.CreateImmutableBinding(in.[[LocalName]], true). - MUST(environment->create_immutable_binding(vm, import_entry.local_name, true)); + MUST(environment->create_immutable_binding(vm, local_name, true)); // iii. Perform ! env.InitializeBinding(in.[[LocalName]], namespace, normal). - MUST(environment->initialize_binding(vm, import_entry.local_name, namespace_, Environment::InitializeBindingHint::Normal)); + MUST(environment->initialize_binding(vm, local_name, namespace_, Environment::InitializeBindingHint::Normal)); } // c. Else, else { + auto import_name = Utf16FlyString::from_utf8(import_entry.import_name.value()); + // i. Let resolution be importedModule.ResolveExport(in.[[ImportName]]). - auto resolution = imported_module->resolve_export(vm, import_entry.import_name.value()); + auto resolution = imported_module->resolve_export(vm, import_name); // ii. If resolution is either null or AMBIGUOUS, throw a SyntaxError exception. if (!resolution.is_valid()) - return vm.throw_completion(ErrorType::InvalidOrAmbiguousExportEntry, import_entry.import_name); + return vm.throw_completion(ErrorType::InvalidOrAmbiguousExportEntry, import_name); // iii. If resolution.[[BindingName]] is NAMESPACE, then if (resolution.is_namespace()) { @@ -400,15 +404,15 @@ ThrowCompletionOr SourceTextModule::initialize_environment(VM& vm) auto namespace_ = resolution.module->get_module_namespace(vm); // 2. Perform ! env.CreateImmutableBinding(in.[[LocalName]], true). - MUST(environment->create_immutable_binding(vm, import_entry.local_name, true)); + MUST(environment->create_immutable_binding(vm, local_name, true)); // 3. Perform ! env.InitializeBinding(in.[[LocalName]], namespace, normal). - MUST(environment->initialize_binding(vm, import_entry.local_name, namespace_, Environment::InitializeBindingHint::Normal)); + MUST(environment->initialize_binding(vm, local_name, namespace_, Environment::InitializeBindingHint::Normal)); } // iv. Else, else { // 1. Perform env.CreateImportBinding(in.[[LocalName]], resolution.[[Module]], resolution.[[BindingName]]). - MUST(environment->create_import_binding(import_entry.local_name, resolution.module, resolution.export_name)); + MUST(environment->create_import_binding(local_name, resolution.module, resolution.export_name)); } } } @@ -447,14 +451,15 @@ ThrowCompletionOr SourceTextModule::initialize_environment(VM& vm) // NOTE: We just loop through them in step 21. // 20. Let declaredVarNames be a new empty List. - Vector declared_var_names; + Vector declared_var_names; // 21. For each element d of varDeclarations, do // a. For each element dn of the BoundNames of d, do // NOTE: Due to the use of MUST with `create_mutable_binding` and `initialize_binding` below, // an exception should not result from `for_each_var_declared_identifier`. - MUST(m_ecmascript_code->for_each_var_declared_identifier([&](auto const& identifier) { - auto const& name = identifier.string(); + MUST(m_ecmascript_code->for_each_var_declared_identifier([&](Identifier const& identifier) { + auto name = Utf16FlyString::from_utf8(identifier.string()); + // i. If dn is not an element of declaredVarNames, then if (!declared_var_names.contains_slow(name)) { // 1. Perform ! env.CreateMutableBinding(dn, false). @@ -478,8 +483,9 @@ ThrowCompletionOr SourceTextModule::initialize_environment(VM& vm) // NOTE: Due to the use of MUST in the callback, an exception should not result from `for_each_lexically_scoped_declaration`. MUST(m_ecmascript_code->for_each_lexically_scoped_declaration([&](Declaration const& declaration) { // a. For each element dn of the BoundNames of d, do - MUST(declaration.for_each_bound_identifier([&](auto const& identifier) { - auto const& name = identifier.string(); + MUST(declaration.for_each_bound_identifier([&](Identifier const& identifier) { + auto name = Utf16FlyString::from_utf8(identifier.string()); + // i. If IsConstantDeclaration of d is true, then if (declaration.is_constant_declaration()) { // 1. Perform ! env.CreateImmutableBinding(dn, true). @@ -504,7 +510,7 @@ ThrowCompletionOr SourceTextModule::initialize_environment(VM& vm) function_name = "default"_fly_string; auto function = ECMAScriptFunctionObject::create_from_function_node( function_declaration, - function_name, + Utf16FlyString::from_utf8(function_name), realm, environment, private_environment); @@ -522,11 +528,11 @@ ThrowCompletionOr SourceTextModule::initialize_environment(VM& vm) VERIFY(m_default_export->has_statement()); if (auto const& statement = m_default_export->statement(); !is(statement)) { - auto const& name = m_default_export->entries()[0].local_or_import_name; + auto name = Utf16FlyString::from_utf8(m_default_export->entries()[0].local_or_import_name.value()); dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] Adding default export to lexical declarations: local name: {}, Expression: {}", name, statement.class_name()); // 1. Perform ! env.CreateMutableBinding(dn, false). - MUST(environment->create_mutable_binding(vm, name.value(), false)); + MUST(environment->create_mutable_binding(vm, name, false)); // NOTE: Since this is not a function declaration 24.a.iii never applies } @@ -540,7 +546,7 @@ ThrowCompletionOr SourceTextModule::initialize_environment(VM& vm) } // 16.2.1.7.2.2 ResolveExport ( exportName [ , resolveSet ] ), https://tc39.es/ecma262/#sec-resolveexport -ResolvedBinding SourceTextModule::resolve_export(VM& vm, FlyString const& export_name, Vector resolve_set) +ResolvedBinding SourceTextModule::resolve_export(VM& vm, Utf16FlyString const& export_name, Vector resolve_set) { // 1. Assert: module.[[Status]] is not NEW. VERIFY(m_status != ModuleStatus::New); @@ -575,7 +581,7 @@ ResolvedBinding SourceTextModule::resolve_export(VM& vm, FlyString const& export return ResolvedBinding { ResolvedBinding::Type::BindingName, this, - entry.local_or_import_name.value(), + Utf16FlyString::from_utf8(entry.local_or_import_name.value()), }; } @@ -607,7 +613,7 @@ ResolvedBinding SourceTextModule::resolve_export(VM& vm, FlyString const& export // FIXME: What does this mean? / How do we check this // 2. Return importedModule.ResolveExport(e.[[ImportName]], resolveSet). - return imported_module->resolve_export(vm, entry.local_or_import_name.value(), resolve_set); + return imported_module->resolve_export(vm, Utf16FlyString::from_utf8(entry.local_or_import_name.value()), resolve_set); } } @@ -685,7 +691,7 @@ ThrowCompletionOr SourceTextModule::execute_module(VM& vm, GC::Ptr SourceTextModule::execute_module(VM& vm, GC::Ptrm_ecmascript_code, + realm(), "module code with top-level await"_utf16_fly_string, StringView {}, this->m_ecmascript_code, FunctionParameters::empty(), 0, {}, environment(), nullptr, FunctionKind::Async, true, parsing_insights); module_wrapper_function->set_is_module_wrapper(true); diff --git a/Libraries/LibJS/SourceTextModule.h b/Libraries/LibJS/SourceTextModule.h index ef155898af..80895f1896 100644 --- a/Libraries/LibJS/SourceTextModule.h +++ b/Libraries/LibJS/SourceTextModule.h @@ -26,8 +26,8 @@ public: Program const& parse_node() const { return *m_ecmascript_code; } - virtual Vector get_exported_names(VM& vm, HashTable& export_star_set) override; - virtual ResolvedBinding resolve_export(VM& vm, FlyString const& export_name, Vector resolve_set = {}) override; + virtual Vector get_exported_names(VM& vm, HashTable& export_star_set) override; + virtual ResolvedBinding resolve_export(VM& vm, Utf16FlyString const& export_name, Vector resolve_set = {}) override; Object* import_meta() { return m_import_meta; } void set_import_meta(Badge, Object* import_meta) { m_import_meta = import_meta; } diff --git a/Libraries/LibJS/SyntheticModule.cpp b/Libraries/LibJS/SyntheticModule.cpp index 6021257a1b..303f08e925 100644 --- a/Libraries/LibJS/SyntheticModule.cpp +++ b/Libraries/LibJS/SyntheticModule.cpp @@ -18,7 +18,7 @@ namespace JS { GC_DEFINE_ALLOCATOR(SyntheticModule); -SyntheticModule::SyntheticModule(Realm& realm, Vector export_names, SyntheticModule::EvaluationFunction evaluation_steps, ByteString filename) +SyntheticModule::SyntheticModule(Realm& realm, Vector export_names, SyntheticModule::EvaluationFunction evaluation_steps, ByteString filename) : Module(realm, move(filename)) , m_export_names(move(export_names)) , m_evaluation_steps(evaluation_steps) @@ -40,14 +40,14 @@ GC::Ref SyntheticModule::create_default_export_synthetic_module // performs the following steps when called: auto set_default_export = GC::create_function(realm.heap(), [default_export](SyntheticModule& module) -> ThrowCompletionOr { // a. Perform SetSyntheticModuleExport(module, "default", defaultExport). - TRY(module.set_synthetic_module_export("default"_fly_string, default_export)); + TRY(module.set_synthetic_module_export("default"_utf16_fly_string, default_export)); // b. Return NormalCompletion(UNUSED). return {}; }); // 2. Return the Synthetic Module Record { [[Realm]]: realm, [[Environment]]: empty, [[Namespace]]: empty, [[HostDefined]]: undefined, [[ExportNames]]: « "default" », [[EvaluationSteps]]: setDefaultExport }. - return realm.heap().allocate(realm, Vector { "default"_fly_string }, set_default_export, move(filename)); + return realm.heap().allocate(realm, Vector { "default"_utf16_fly_string }, set_default_export, move(filename)); } // 16.2.1.8.2 ParseJSONModule ( source ), https://tc39.es/ecma262/#sec-create-default-export-synthetic-module @@ -63,7 +63,7 @@ ThrowCompletionOr> parse_json_module(Realm& realm, StringView so } // 16.2.1.8.3 SetSyntheticModuleExport ( module, exportName, exportValue ), https://tc39.es/ecma262/#sec-setsyntheticmoduleexport -ThrowCompletionOr SyntheticModule::set_synthetic_module_export(FlyString const& export_name, Value export_value) +ThrowCompletionOr SyntheticModule::set_synthetic_module_export(Utf16FlyString const& export_name, Value export_value) { auto& vm = this->vm(); @@ -99,14 +99,14 @@ PromiseCapability& SyntheticModule::load_requested_modules(GC::Ptr SyntheticModule::get_exported_names(VM&, HashTable&) +Vector SyntheticModule::get_exported_names(VM&, HashTable&) { // 1. Return module.[[ExportNames]]. return m_export_names; } // 16.2.1.8.4.3 ResolveExport ( exportName ), https://tc39.es/ecma262/#sec-smr-resolveexport -ResolvedBinding SyntheticModule::resolve_export(VM&, FlyString const& export_name, Vector) +ResolvedBinding SyntheticModule::resolve_export(VM&, Utf16FlyString const& export_name, Vector) { // 1. If module.[[ExportNames]] does not contain exportName, return null. if (!m_export_names.contains_slow(export_name)) diff --git a/Libraries/LibJS/SyntheticModule.h b/Libraries/LibJS/SyntheticModule.h index 64efe6ba7e..1d5447eab0 100644 --- a/Libraries/LibJS/SyntheticModule.h +++ b/Libraries/LibJS/SyntheticModule.h @@ -22,20 +22,20 @@ public: static GC::Ref create_default_export_synthetic_module(Realm& realm, Value default_export, ByteString filename); - ThrowCompletionOr set_synthetic_module_export(FlyString const& export_name, Value export_value); + ThrowCompletionOr set_synthetic_module_export(Utf16FlyString const& export_name, Value export_value); virtual PromiseCapability& load_requested_modules(GC::Ptr) override; - virtual Vector get_exported_names(VM& vm, HashTable& export_star_set) override; - virtual ResolvedBinding resolve_export(VM& vm, FlyString const& export_name, Vector resolve_set) override; + virtual Vector get_exported_names(VM& vm, HashTable& export_star_set) override; + virtual ResolvedBinding resolve_export(VM& vm, Utf16FlyString const& export_name, Vector resolve_set) override; virtual ThrowCompletionOr link(VM& vm) override; virtual ThrowCompletionOr> evaluate(VM& vm) override; private: - SyntheticModule(Realm& realm, Vector export_names, EvaluationFunction evaluation_steps, ByteString filename); + SyntheticModule(Realm& realm, Vector export_names, EvaluationFunction evaluation_steps, ByteString filename); virtual void visit_edges(Cell::Visitor&) override; - Vector m_export_names; // [[ExportNames]] + Vector m_export_names; // [[ExportNames]] EvaluationFunction m_evaluation_steps; // [[EvaluationSteps]] }; diff --git a/Libraries/LibTest/JavaScriptTestRunner.h b/Libraries/LibTest/JavaScriptTestRunner.h index 9650c2f18d..92b20b4004 100644 --- a/Libraries/LibTest/JavaScriptTestRunner.h +++ b/Libraries/LibTest/JavaScriptTestRunner.h @@ -55,9 +55,9 @@ } \ } __testjs_register_##fn {}; -#define TESTJS_GLOBAL_FUNCTION(function, exposed_name, ...) \ - JS_DECLARE_NATIVE_FUNCTION(function); \ - __TESTJS_REGISTER_GLOBAL_FUNCTION(#exposed_name##_string, function, ##__VA_ARGS__); \ +#define TESTJS_GLOBAL_FUNCTION(function, exposed_name, ...) \ + JS_DECLARE_NATIVE_FUNCTION(function); \ + __TESTJS_REGISTER_GLOBAL_FUNCTION(#exposed_name##_utf16, function, ##__VA_ARGS__); \ JS_DEFINE_NATIVE_FUNCTION(function) #define TESTJS_MAIN_HOOK() \ @@ -114,7 +114,7 @@ struct FunctionWithLength { JS::ThrowCompletionOr (*function)(JS::VM&); size_t length { 0 }; }; -extern HashMap s_exposed_global_functions; +extern HashMap s_exposed_global_functions; extern ByteString g_test_root_fragment; extern ByteString g_test_root; extern int g_test_argc; @@ -182,11 +182,12 @@ inline void TestRunnerGlobalObject::initialize(JS::Realm& realm) { Base::initialize(realm); - define_direct_property("global"_fly_string, this, JS::Attribute::Enumerable); + define_direct_property("global"_utf16_fly_string, this, JS::Attribute::Enumerable); for (auto& entry : s_exposed_global_functions) { define_native_function( realm, - entry.key, [fn = entry.value.function](auto& vm) { + entry.key, + [fn = entry.value.function](auto& vm) { return fn(vm); }, entry.value.length, JS::default_attributes); @@ -239,7 +240,7 @@ inline AK::Result, ParserError> parse_module(Strin inline ErrorOr get_test_results(JS::Realm& realm) { - auto results = MUST(realm.global_object().get("__TestResults__"_fly_string)); + auto results = MUST(realm.global_object().get("__TestResults__"_utf16_fly_string)); auto maybe_json_string = MUST(JS::JSONObject::stringify_impl(*g_vm, results, JS::js_undefined(), JS::js_undefined())); if (maybe_json_string.has_value()) return JsonValue::from_string(*maybe_json_string); @@ -359,7 +360,7 @@ inline JSFileResult TestRunner::run_file_test(ByteString const& test_path) JSFileResult file_result { test_path.substring(m_test_root.length() + 1, test_path.length() - m_test_root.length() - 1) }; // Collect logged messages - auto user_output = MUST(realm->global_object().get("__UserOutput__"_fly_string)); + auto user_output = MUST(realm->global_object().get("__UserOutput__"_utf16_fly_string)); auto& arr = user_output.as_array(); for (auto& entry : arr.indexed_properties()) { diff --git a/Libraries/LibTest/JavaScriptTestRunnerMain.cpp b/Libraries/LibTest/JavaScriptTestRunnerMain.cpp index b155548a4b..6d96446e36 100644 --- a/Libraries/LibTest/JavaScriptTestRunnerMain.cpp +++ b/Libraries/LibTest/JavaScriptTestRunnerMain.cpp @@ -24,7 +24,7 @@ namespace JS { RefPtr<::JS::VM> g_vm; bool g_collect_on_every_allocation = false; ByteString g_currently_running_test; -HashMap s_exposed_global_functions; +HashMap s_exposed_global_functions; Function g_main_hook; HashMap> g_extra_args; IntermediateRunFileResult (*g_run_file)(ByteString const&, JS::Realm&, JS::ExecutionContext&) = nullptr; diff --git a/Libraries/LibWeb/Animations/KeyframeEffect.cpp b/Libraries/LibWeb/Animations/KeyframeEffect.cpp index 8657558b83..742afbb7de 100644 --- a/Libraries/LibWeb/Animations/KeyframeEffect.cpp +++ b/Libraries/LibWeb/Animations/KeyframeEffect.cpp @@ -105,13 +105,13 @@ static WebIDL::ExceptionOr> process_a_keyframe_like_object(JS:: return keyframe_output; auto& keyframe_object = keyframe_input.as_object(); - auto composite = TRY(keyframe_object.get("composite"_fly_string)); + auto composite = TRY(keyframe_object.get("composite"_utf16_fly_string)); if (composite.is_undefined()) composite = JS::PrimitiveString::create(vm, "auto"_string); - auto easing = TRY(keyframe_object.get("easing"_fly_string)); + auto easing = TRY(keyframe_object.get("easing"_utf16_fly_string)); if (easing.is_undefined()) easing = JS::PrimitiveString::create(vm, "linear"_string); - auto offset = TRY(keyframe_object.get("offset"_fly_string)); + auto offset = TRY(keyframe_object.get("offset"_utf16_fly_string)); if constexpr (AL == AllowLists::Yes) { keyframe_output.composite = TRY(convert_value_to_maybe_list(realm, composite, to_composite_operation)); @@ -186,7 +186,7 @@ static WebIDL::ExceptionOr> process_a_keyframe_like_object(JS:: // 1. Let raw value be the result of calling the [[Get]] internal method on keyframe input, with property name // as the property key and keyframe input as the receiver. // 2. Check the completion record of raw value. - JS::PropertyKey key { property_name, JS::PropertyKey::StringMayBeNumber::No }; + JS::PropertyKey key { Utf16FlyString::from_utf8(property_name), JS::PropertyKey::StringMayBeNumber::No }; auto raw_value = TRY(keyframe_object.has_property(key)) ? TRY(keyframe_object.get(key)) : *all_value; using PropertyValuesType = Conditional, String>; @@ -841,8 +841,9 @@ WebIDL::ExceptionOr> KeyframeEffect::get_keyframes() } for (auto const& [id, value] : keyframe.parsed_properties()) { + auto key = Utf16FlyString::from_utf8(CSS::camel_case_string_from_property_id(id)); auto value_string = JS::PrimitiveString::create(vm, value->to_string(CSS::SerializationMode::Normal)); - TRY(object->set(JS::PropertyKey { CSS::camel_case_string_from_property_id(id), JS::PropertyKey::StringMayBeNumber::No }, value_string, ShouldThrowExceptions::Yes)); + TRY(object->set(JS::PropertyKey { move(key), JS::PropertyKey::StringMayBeNumber::No }, value_string, ShouldThrowExceptions::Yes)); } m_keyframe_objects.append(object); diff --git a/Libraries/LibWeb/Bindings/MainThreadVM.cpp b/Libraries/LibWeb/Bindings/MainThreadVM.cpp index bd7b114678..13b05f61ac 100644 --- a/Libraries/LibWeb/Bindings/MainThreadVM.cpp +++ b/Libraries/LibWeb/Bindings/MainThreadVM.cpp @@ -411,8 +411,8 @@ void initialize_main_thread_vm(AgentType type) // 5. Return « Record { [[Key]]: "url", [[Value]]: urlString }, Record { [[Key]]: "resolve", [[Value]]: resolveFunction } ». HashMap meta; - meta.set("url"_fly_string, JS::PrimitiveString::create(vm, move(url_string))); - meta.set("resolve"_fly_string, resolve_function); + meta.set("url"_utf16_fly_string, JS::PrimitiveString::create(vm, move(url_string))); + meta.set("resolve"_utf16_fly_string, resolve_function); return meta; }; diff --git a/Libraries/LibWeb/Bindings/PlatformObject.cpp b/Libraries/LibWeb/Bindings/PlatformObject.cpp index 87daa2ca0d..17388c97d9 100644 --- a/Libraries/LibWeb/Bindings/PlatformObject.cpp +++ b/Libraries/LibWeb/Bindings/PlatformObject.cpp @@ -41,7 +41,7 @@ JS::ThrowCompletionOr PlatformObject::is_named_property_exposed_on_object( // 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. - if (!is_supported_property_name(property_key.to_string())) + if (!is_supported_property_name(property_key.to_string().to_utf8_but_should_be_ported_to_utf16())) return false; // 2. If O has an own property named P, then return false. @@ -118,7 +118,7 @@ JS::ThrowCompletionOr> PlatformObject::legacy_p // 1. If the result of running the named property visibility algorithm with property name P and object O is true, then: if (TRY(is_named_property_exposed_on_object(property_name))) { // FIXME: It's unfortunate that this is done twice, once in is_named_property_exposed_on_object and here. - auto property_name_string = property_name.to_string(); + auto property_name_string = property_name.to_string().to_utf8_but_should_be_ported_to_utf16(); // 1. Let operation be the operation used to declare the named property getter. // 2. Let value be an uninitialized variable. @@ -236,7 +236,7 @@ JS::ThrowCompletionOr PlatformObject::internal_set(JS::PropertyKey const& // 2. If O implements an interface with a named property setter and P is a String, then: if (m_legacy_platform_object_flags->has_named_property_setter && property_name.is_string()) { // 1. Invoke the named property setter on O with P and V. - TRY(throw_dom_exception_if_needed(vm, [&] { return invoke_named_property_setter(property_name.as_string(), value); })); + TRY(throw_dom_exception_if_needed(vm, [&] { return invoke_named_property_setter(property_name.as_string().view().to_utf8_but_should_be_ported_to_utf16(), value); })); // 2. Return true. return true; @@ -282,7 +282,7 @@ JS::ThrowCompletionOr PlatformObject::internal_define_own_property(JS::Pro // 2. If O supports named properties, O does not implement an interface with the [Global] extended attribute, P is a String, and P is not an unforgeable property name of O, then: // FIXME: Check if P is not an unforgeable property name of O if (m_legacy_platform_object_flags->supports_named_properties && !m_legacy_platform_object_flags->has_global_interface_extended_attribute && property_name.is_string()) { - auto const property_name_as_string = property_name.as_string(); + auto const property_name_as_string = property_name.as_string().view().to_utf8_but_should_be_ported_to_utf16(); // 1. Let creating be true if P is not a supported property name, and false otherwise. bool creating = !is_supported_property_name(property_name_as_string); @@ -351,7 +351,7 @@ JS::ThrowCompletionOr PlatformObject::internal_delete(JS::PropertyKey cons return false; // FIXME: It's unfortunate that this is done twice, once in is_named_property_exposed_on_object and here. - auto property_name_string = property_name.to_string(); + auto property_name_string = property_name.to_string().to_utf8_but_should_be_ported_to_utf16(); // 2. Let operation be the operation used to declare the named property deleter. // 3. If operation was defined without an identifier, then: @@ -423,7 +423,7 @@ JS::ThrowCompletionOr> PlatformObject::internal_own_pr // 3. If O supports named properties, then for each P of O’s supported property names that is visible according to the named property visibility algorithm, append P to keys. if (m_legacy_platform_object_flags->supports_named_properties) { for (auto& named_property : supported_property_names()) { - if (TRY(is_named_property_exposed_on_object(named_property))) + if (TRY(is_named_property_exposed_on_object(Utf16FlyString::from_utf8(named_property)))) keys.append(JS::PrimitiveString::create(vm, named_property)); } } diff --git a/Libraries/LibWeb/Crypto/Crypto.cpp b/Libraries/LibWeb/Crypto/Crypto.cpp index 9fc46f2a97..218bbee3ed 100644 --- a/Libraries/LibWeb/Crypto/Crypto.cpp +++ b/Libraries/LibWeb/Crypto/Crypto.cpp @@ -52,7 +52,7 @@ WebIDL::ExceptionOr> Crypto::get_random_values return WebIDL::TypeMismatchError::create(realm(), "array must be one of Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, or BigUint64Array"_string); auto const& typed_array = *array->bufferable_object().get>(); - if (!typed_array.element_name().is_one_of("Int8Array", "Uint8Array", "Uint8ClampedArray", "Int16Array", "Uint16Array", "Int32Array", "Uint32Array", "BigInt64Array", "BigUint64Array")) + if (!typed_array.element_name().is_one_of("Int8Array"sv, "Uint8Array"sv, "Uint8ClampedArray"sv, "Int16Array"sv, "Uint16Array"sv, "Int32Array"sv, "Uint32Array"sv, "BigInt64Array"sv, "BigUint64Array"sv)) return WebIDL::TypeMismatchError::create(realm(), "array must be one of Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, or BigUint64Array"_string); auto typed_array_record = JS::make_typed_array_with_buffer_witness_record(typed_array, JS::ArrayBuffer::Order::SeqCst); diff --git a/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp b/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp index 21b0510dce..70e4b9d514 100644 --- a/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp +++ b/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp @@ -287,7 +287,7 @@ JS::ThrowCompletionOr> AesCbcParams::from_value(J { auto& object = value.as_object(); - auto iv_value = TRY(object.get("iv"_fly_string)); + auto iv_value = TRY(object.get("iv"_utf16_fly_string)); if (!iv_value.is_object() || !(is(iv_value.as_object()) || is(iv_value.as_object()) || is(iv_value.as_object()))) return vm.throw_completion(JS::ErrorType::NotAnObjectOfType, "BufferSource"); auto iv = TRY_OR_THROW_OOM(vm, WebIDL::get_buffer_source_copy(iv_value.as_object())); @@ -301,12 +301,12 @@ JS::ThrowCompletionOr> AesCtrParams::from_value(J { auto& object = value.as_object(); - auto iv_value = TRY(object.get("counter"_fly_string)); + auto iv_value = TRY(object.get("counter"_utf16_fly_string)); if (!iv_value.is_object() || !(is(iv_value.as_object()) || is(iv_value.as_object()) || is(iv_value.as_object()))) return vm.throw_completion(JS::ErrorType::NotAnObjectOfType, "BufferSource"); auto iv = TRY_OR_THROW_OOM(vm, WebIDL::get_buffer_source_copy(iv_value.as_object())); - auto length_value = TRY(object.get("length"_fly_string)); + auto length_value = TRY(object.get("length"_utf16_fly_string)); auto length = TRY(length_value.to_u8(vm)); return adopt_own(*new AesCtrParams { iv, length }); @@ -318,22 +318,22 @@ JS::ThrowCompletionOr> AesGcmParams::from_value(J { auto& object = value.as_object(); - auto iv_value = TRY(object.get("iv"_fly_string)); + auto iv_value = TRY(object.get("iv"_utf16_fly_string)); if (!iv_value.is_object() || !(is(iv_value.as_object()) || is(iv_value.as_object()) || is(iv_value.as_object()))) return vm.throw_completion(JS::ErrorType::NotAnObjectOfType, "BufferSource"); auto iv = TRY_OR_THROW_OOM(vm, WebIDL::get_buffer_source_copy(iv_value.as_object())); auto maybe_additional_data = Optional {}; - if (MUST(object.has_property("additionalData"_fly_string))) { - auto additional_data_value = TRY(object.get("additionalData"_fly_string)); + if (MUST(object.has_property("additionalData"_utf16_fly_string))) { + auto additional_data_value = TRY(object.get("additionalData"_utf16_fly_string)); if (!additional_data_value.is_object() || !(is(additional_data_value.as_object()) || is(additional_data_value.as_object()) || is(additional_data_value.as_object()))) return vm.throw_completion(JS::ErrorType::NotAnObjectOfType, "BufferSource"); maybe_additional_data = TRY_OR_THROW_OOM(vm, WebIDL::get_buffer_source_copy(additional_data_value.as_object())); } auto maybe_tag_length = Optional {}; - if (MUST(object.has_property("tagLength"_fly_string))) { - auto tag_length_value = TRY(object.get("tagLength"_fly_string)); + if (MUST(object.has_property("tagLength"_utf16_fly_string))) { + auto tag_length_value = TRY(object.get("tagLength"_utf16_fly_string)); maybe_tag_length = TRY(tag_length_value.to_u8(vm)); } @@ -346,15 +346,15 @@ JS::ThrowCompletionOr> HKDFParams::from_value(JS: { auto& object = value.as_object(); - auto hash_value = TRY(object.get("hash"_fly_string)); + auto hash_value = TRY(object.get("hash"_utf16_fly_string)); auto hash = TRY(hash_algorithm_identifier_from_value(vm, hash_value)); - auto salt_value = TRY(object.get("salt"_fly_string)); + auto salt_value = TRY(object.get("salt"_utf16_fly_string)); if (!salt_value.is_object() || !(is(salt_value.as_object()) || is(salt_value.as_object()) || is(salt_value.as_object()))) return vm.throw_completion(JS::ErrorType::NotAnObjectOfType, "BufferSource"); auto salt = TRY_OR_THROW_OOM(vm, WebIDL::get_buffer_source_copy(salt_value.as_object())); - auto info_value = TRY(object.get("info"_fly_string)); + auto info_value = TRY(object.get("info"_utf16_fly_string)); if (!info_value.is_object() || !(is(info_value.as_object()) || is(info_value.as_object()) || is(info_value.as_object()))) return vm.throw_completion(JS::ErrorType::NotAnObjectOfType, "BufferSource"); auto info = TRY_OR_THROW_OOM(vm, WebIDL::get_buffer_source_copy(info_value.as_object())); @@ -368,17 +368,17 @@ JS::ThrowCompletionOr> PBKDF2Params::from_value(J { auto& object = value.as_object(); - auto salt_value = TRY(object.get("salt"_fly_string)); + auto salt_value = TRY(object.get("salt"_utf16_fly_string)); if (!salt_value.is_object() || !(is(salt_value.as_object()) || is(salt_value.as_object()) || is(salt_value.as_object()))) return vm.throw_completion(JS::ErrorType::NotAnObjectOfType, "BufferSource"); auto salt = TRY_OR_THROW_OOM(vm, WebIDL::get_buffer_source_copy(salt_value.as_object())); - auto iterations_value = TRY(object.get("iterations"_fly_string)); + auto iterations_value = TRY(object.get("iterations"_utf16_fly_string)); auto iterations = TRY(iterations_value.to_u32(vm)); - auto hash_value = TRY(object.get("hash"_fly_string)); + auto hash_value = TRY(object.get("hash"_utf16_fly_string)); auto hash = TRY(hash_algorithm_identifier_from_value(vm, hash_value)); return adopt_own(*new PBKDF2Params { salt, iterations, hash }); @@ -390,10 +390,10 @@ JS::ThrowCompletionOr> RsaKeyGenParams::from_valu { auto& object = value.as_object(); - auto modulus_length_value = TRY(object.get("modulusLength"_fly_string)); + auto modulus_length_value = TRY(object.get("modulusLength"_utf16_fly_string)); auto modulus_length = TRY(modulus_length_value.to_u32(vm)); - auto public_exponent_value = TRY(object.get("publicExponent"_fly_string)); + auto public_exponent_value = TRY(object.get("publicExponent"_utf16_fly_string)); GC::Ptr public_exponent; if (!public_exponent_value.is_object() || !is(public_exponent_value.as_object())) @@ -410,10 +410,10 @@ JS::ThrowCompletionOr> RsaHashedKeyGenParams::fro { auto& object = value.as_object(); - auto modulus_length_value = TRY(object.get("modulusLength"_fly_string)); + auto modulus_length_value = TRY(object.get("modulusLength"_utf16_fly_string)); auto modulus_length = TRY(modulus_length_value.to_u32(vm)); - auto public_exponent_value = TRY(object.get("publicExponent"_fly_string)); + auto public_exponent_value = TRY(object.get("publicExponent"_utf16_fly_string)); GC::Ptr public_exponent; if (!public_exponent_value.is_object() || !is(public_exponent_value.as_object())) @@ -421,7 +421,7 @@ JS::ThrowCompletionOr> RsaHashedKeyGenParams::fro public_exponent = static_cast(public_exponent_value.as_object()); - auto hash_value = TRY(object.get("hash"_fly_string)); + auto hash_value = TRY(object.get("hash"_utf16_fly_string)); auto hash = TRY(hash_algorithm_identifier_from_value(vm, hash_value)); return adopt_own(*new RsaHashedKeyGenParams { modulus_length, big_integer_from_api_big_integer(public_exponent), hash }); @@ -433,7 +433,7 @@ JS::ThrowCompletionOr> RsaHashedImportParams::fro { auto& object = value.as_object(); - auto hash_value = TRY(object.get("hash"_fly_string)); + auto hash_value = TRY(object.get("hash"_utf16_fly_string)); auto hash = TRY(hash_algorithm_identifier_from_value(vm, hash_value)); return adopt_own(*new RsaHashedImportParams { hash }); @@ -445,7 +445,7 @@ JS::ThrowCompletionOr> RsaOaepParams::from_value( { auto& object = value.as_object(); - auto label_value = TRY(object.get("label"_fly_string)); + auto label_value = TRY(object.get("label"_utf16_fly_string)); ByteBuffer label; if (!label_value.is_nullish()) { @@ -465,7 +465,7 @@ JS::ThrowCompletionOr> RsaPssParams::from_value(J { auto& object = value.as_object(); - auto salt_length_value = TRY(object.get("saltLength"_fly_string)); + auto salt_length_value = TRY(object.get("saltLength"_utf16_fly_string)); auto salt_length = TRY(salt_length_value.to_u32(vm)); return adopt_own(*new RsaPssParams { salt_length }); @@ -477,7 +477,7 @@ JS::ThrowCompletionOr> EcdsaParams::from_value(JS { auto& object = value.as_object(); - auto hash_value = TRY(object.get("hash"_fly_string)); + auto hash_value = TRY(object.get("hash"_utf16_fly_string)); auto hash = TRY(hash_algorithm_identifier_from_value(vm, hash_value)); return adopt_own(*new EcdsaParams { hash }); @@ -489,7 +489,7 @@ JS::ThrowCompletionOr> EcKeyGenParams::from_value { auto& object = value.as_object(); - auto curve_value = TRY(object.get("namedCurve"_fly_string)); + auto curve_value = TRY(object.get("namedCurve"_utf16_fly_string)); auto curve = TRY(curve_value.to_string(vm)); return adopt_own(*new EcKeyGenParams { curve }); @@ -501,7 +501,7 @@ JS::ThrowCompletionOr> AesKeyGenParams::from_valu { auto& object = value.as_object(); - auto length_value = TRY(object.get("length"_fly_string)); + auto length_value = TRY(object.get("length"_utf16_fly_string)); auto length = TRY(length_value.to_u16(vm)); return adopt_own(*new AesKeyGenParams { length }); @@ -513,7 +513,7 @@ JS::ThrowCompletionOr> AesDerivedKeyParams::from_ { auto& object = value.as_object(); - auto length_value = TRY(object.get("length"_fly_string)); + auto length_value = TRY(object.get("length"_utf16_fly_string)); auto length = TRY(length_value.to_u16(vm)); return adopt_own(*new AesDerivedKeyParams { length }); @@ -525,7 +525,7 @@ JS::ThrowCompletionOr> EcdhKeyDeriveParams::from_ { auto& object = value.as_object(); - auto key_value = TRY(object.get("public"_fly_string)); + auto key_value = TRY(object.get("public"_utf16_fly_string)); auto key_object = TRY(key_value.to_object(vm)); if (!is(*key_object)) { @@ -543,7 +543,7 @@ JS::ThrowCompletionOr> EcKeyImportParams::from_va { auto& object = value.as_object(); - auto named_curve_value = TRY(object.get("namedCurve"_fly_string)); + auto named_curve_value = TRY(object.get("namedCurve"_utf16_fly_string)); auto named_curve = TRY(named_curve_value.to_string(vm)); return adopt_own(*new EcKeyImportParams { named_curve }); @@ -555,12 +555,12 @@ JS::ThrowCompletionOr> HmacImportParams::from_val { auto& object = value.as_object(); - auto hash_value = TRY(object.get("hash"_fly_string)); + auto hash_value = TRY(object.get("hash"_utf16_fly_string)); auto hash = TRY(hash_algorithm_identifier_from_value(vm, hash_value)); auto maybe_length = Optional {}; - if (MUST(object.has_property("length"_fly_string))) { - auto length_value = TRY(object.get("length"_fly_string)); + if (MUST(object.has_property("length"_utf16_fly_string))) { + auto length_value = TRY(object.get("length"_utf16_fly_string)); maybe_length = TRY(length_value.to_u32(vm)); } @@ -573,12 +573,12 @@ JS::ThrowCompletionOr> HmacKeyGenParams::from_val { auto& object = value.as_object(); - auto hash_value = TRY(object.get("hash"_fly_string)); + auto hash_value = TRY(object.get("hash"_utf16_fly_string)); auto hash = TRY(hash_algorithm_identifier_from_value(vm, hash_value)); auto maybe_length = Optional {}; - if (MUST(object.has_property("length"_fly_string))) { - auto length_value = TRY(object.get("length"_fly_string)); + if (MUST(object.has_property("length"_utf16_fly_string))) { + auto length_value = TRY(object.get("length"_utf16_fly_string)); maybe_length = TRY(length_value.to_u32(vm)); } @@ -592,8 +592,8 @@ JS::ThrowCompletionOr> Ed448Params::from_value(JS auto& object = value.as_object(); auto maybe_context = Optional {}; - if (MUST(object.has_property("context"_fly_string))) { - auto context_value = TRY(object.get("context"_fly_string)); + if (MUST(object.has_property("context"_utf16_fly_string))) { + auto context_value = TRY(object.get("context"_utf16_fly_string)); if (!context_value.is_object() || !(is(context_value.as_object()) || is(context_value.as_object()) || is(context_value.as_object()))) return vm.throw_completion(JS::ErrorType::NotAnObjectOfType, "BufferSource"); maybe_context = TRY_OR_THROW_OOM(vm, WebIDL::get_buffer_source_copy(context_value.as_object())); diff --git a/Libraries/LibWeb/Crypto/CryptoAlgorithms.h b/Libraries/LibWeb/Crypto/CryptoAlgorithms.h index e926726157..ac18d3d047 100644 --- a/Libraries/LibWeb/Crypto/CryptoAlgorithms.h +++ b/Libraries/LibWeb/Crypto/CryptoAlgorithms.h @@ -34,7 +34,7 @@ struct HashAlgorithmIdentifier : public AlgorithmIdentifier { auto value = visit( [](String const& name) -> JS::ThrowCompletionOr { return name; }, [&](GC::Root const& obj) -> JS::ThrowCompletionOr { - auto name_property = TRY(obj->get("name"_fly_string)); + auto name_property = TRY(obj->get("name"_utf16_fly_string)); return name_property.to_string(vm); }); diff --git a/Libraries/LibWeb/Crypto/CryptoBindings.cpp b/Libraries/LibWeb/Crypto/CryptoBindings.cpp index ea88f15def..070c699704 100644 --- a/Libraries/LibWeb/Crypto/CryptoBindings.cpp +++ b/Libraries/LibWeb/Crypto/CryptoBindings.cpp @@ -91,63 +91,63 @@ JS::ThrowCompletionOr> JsonWebKey::to_object(JS::Realm& real auto object = JS::Object::create(realm, realm.intrinsics().object_prototype()); if (kty.has_value()) - TRY(object->create_data_property("kty"_fly_string, JS::PrimitiveString::create(vm, kty.value()))); + TRY(object->create_data_property("kty"_utf16_fly_string, JS::PrimitiveString::create(vm, kty.value()))); if (use.has_value()) - TRY(object->create_data_property("use"_fly_string, JS::PrimitiveString::create(vm, use.value()))); + TRY(object->create_data_property("use"_utf16_fly_string, JS::PrimitiveString::create(vm, use.value()))); if (key_ops.has_value()) { auto key_ops_array = JS::Array::create_from(realm, key_ops.value().span(), [&](auto& key_usage) -> JS::Value { return JS::PrimitiveString::create(realm.vm(), key_usage); }); - TRY(object->create_data_property("key_ops"_fly_string, move(key_ops_array))); + TRY(object->create_data_property("key_ops"_utf16_fly_string, move(key_ops_array))); } if (alg.has_value()) - TRY(object->create_data_property("alg"_fly_string, JS::PrimitiveString::create(vm, alg.value()))); + TRY(object->create_data_property("alg"_utf16_fly_string, JS::PrimitiveString::create(vm, alg.value()))); if (ext.has_value()) - TRY(object->create_data_property("ext"_fly_string, JS::Value(ext.value()))); + TRY(object->create_data_property("ext"_utf16_fly_string, JS::Value(ext.value()))); if (crv.has_value()) - TRY(object->create_data_property("crv"_fly_string, JS::PrimitiveString::create(vm, crv.value()))); + TRY(object->create_data_property("crv"_utf16_fly_string, JS::PrimitiveString::create(vm, crv.value()))); if (x.has_value()) - TRY(object->create_data_property("x"_fly_string, JS::PrimitiveString::create(vm, x.value()))); + TRY(object->create_data_property("x"_utf16_fly_string, JS::PrimitiveString::create(vm, x.value()))); if (y.has_value()) - TRY(object->create_data_property("y"_fly_string, JS::PrimitiveString::create(vm, y.value()))); + TRY(object->create_data_property("y"_utf16_fly_string, JS::PrimitiveString::create(vm, y.value()))); if (d.has_value()) - TRY(object->create_data_property("d"_fly_string, JS::PrimitiveString::create(vm, d.value()))); + TRY(object->create_data_property("d"_utf16_fly_string, JS::PrimitiveString::create(vm, d.value()))); if (n.has_value()) - TRY(object->create_data_property("n"_fly_string, JS::PrimitiveString::create(vm, n.value()))); + TRY(object->create_data_property("n"_utf16_fly_string, JS::PrimitiveString::create(vm, n.value()))); if (e.has_value()) - TRY(object->create_data_property("e"_fly_string, JS::PrimitiveString::create(vm, e.value()))); + TRY(object->create_data_property("e"_utf16_fly_string, JS::PrimitiveString::create(vm, e.value()))); if (p.has_value()) - TRY(object->create_data_property("p"_fly_string, JS::PrimitiveString::create(vm, p.value()))); + TRY(object->create_data_property("p"_utf16_fly_string, JS::PrimitiveString::create(vm, p.value()))); if (q.has_value()) - TRY(object->create_data_property("q"_fly_string, JS::PrimitiveString::create(vm, q.value()))); + TRY(object->create_data_property("q"_utf16_fly_string, JS::PrimitiveString::create(vm, q.value()))); if (dp.has_value()) - TRY(object->create_data_property("dp"_fly_string, JS::PrimitiveString::create(vm, dp.value()))); + TRY(object->create_data_property("dp"_utf16_fly_string, JS::PrimitiveString::create(vm, dp.value()))); if (dq.has_value()) - TRY(object->create_data_property("dq"_fly_string, JS::PrimitiveString::create(vm, dq.value()))); + TRY(object->create_data_property("dq"_utf16_fly_string, JS::PrimitiveString::create(vm, dq.value()))); if (qi.has_value()) - TRY(object->create_data_property("qi"_fly_string, JS::PrimitiveString::create(vm, qi.value()))); + TRY(object->create_data_property("qi"_utf16_fly_string, JS::PrimitiveString::create(vm, qi.value()))); if (oth.has_value()) { TODO(); } if (k.has_value()) - TRY(object->create_data_property("k"_fly_string, JS::PrimitiveString::create(vm, k.value()))); + TRY(object->create_data_property("k"_utf16_fly_string, JS::PrimitiveString::create(vm, k.value()))); return object; } diff --git a/Libraries/LibWeb/Crypto/CryptoKey.cpp b/Libraries/LibWeb/Crypto/CryptoKey.cpp index 5114c38e58..dd3e1c1723 100644 --- a/Libraries/LibWeb/Crypto/CryptoKey.cpp +++ b/Libraries/LibWeb/Crypto/CryptoKey.cpp @@ -75,7 +75,7 @@ void CryptoKey::set_usages(Vector usages) String CryptoKey::algorithm_name() const { if (m_algorithm_name.is_empty()) { - auto name = MUST(m_algorithm->get("name"_fly_string)); + auto name = MUST(m_algorithm->get("name"_utf16_fly_string)); m_algorithm_name = MUST(name.to_string(vm())); } return m_algorithm_name; @@ -95,8 +95,8 @@ CryptoKeyPair::CryptoKeyPair(JS::Realm& realm, GC::Ref public_key, GC void CryptoKeyPair::initialize(JS::Realm& realm) { - define_native_accessor(realm, "publicKey"_fly_string, public_key_getter, {}, JS::Attribute::Enumerable | JS::Attribute::Configurable); - define_native_accessor(realm, "privateKey"_fly_string, private_key_getter, {}, JS::Attribute::Enumerable | JS::Attribute::Configurable); + define_native_accessor(realm, "publicKey"_utf16_fly_string, public_key_getter, {}, JS::Attribute::Enumerable | JS::Attribute::Configurable); + define_native_accessor(realm, "privateKey"_utf16_fly_string, private_key_getter, {}, JS::Attribute::Enumerable | JS::Attribute::Configurable); Base::initialize(realm); } diff --git a/Libraries/LibWeb/Crypto/KeyAlgorithms.cpp b/Libraries/LibWeb/Crypto/KeyAlgorithms.cpp index 149f47aab2..3ebee32f45 100644 --- a/Libraries/LibWeb/Crypto/KeyAlgorithms.cpp +++ b/Libraries/LibWeb/Crypto/KeyAlgorithms.cpp @@ -49,7 +49,7 @@ KeyAlgorithm::KeyAlgorithm(JS::Realm& realm) void KeyAlgorithm::initialize(JS::Realm& realm) { - define_native_accessor(realm, "name"_fly_string, name_getter, {}, JS::Attribute::Enumerable | JS::Attribute::Configurable); + define_native_accessor(realm, "name"_utf16_fly_string, name_getter, {}, JS::Attribute::Enumerable | JS::Attribute::Configurable); Base::initialize(realm); } @@ -81,8 +81,8 @@ void RsaKeyAlgorithm::initialize(JS::Realm& realm) { Base::initialize(realm); - define_native_accessor(realm, "modulusLength"_fly_string, modulus_length_getter, {}, JS::Attribute::Enumerable | JS::Attribute::Configurable); - define_native_accessor(realm, "publicExponent"_fly_string, public_exponent_getter, {}, JS::Attribute::Enumerable | JS::Attribute::Configurable); + define_native_accessor(realm, "modulusLength"_utf16_fly_string, modulus_length_getter, {}, JS::Attribute::Enumerable | JS::Attribute::Configurable); + define_native_accessor(realm, "publicExponent"_utf16_fly_string, public_exponent_getter, {}, JS::Attribute::Enumerable | JS::Attribute::Configurable); } void RsaKeyAlgorithm::visit_edges(Visitor& visitor) @@ -133,7 +133,7 @@ void EcKeyAlgorithm::initialize(JS::Realm& realm) { Base::initialize(realm); - define_native_accessor(realm, "namedCurve"_fly_string, named_curve_getter, {}, JS::Attribute::Enumerable | JS::Attribute::Configurable); + define_native_accessor(realm, "namedCurve"_utf16_fly_string, named_curve_getter, {}, JS::Attribute::Enumerable | JS::Attribute::Configurable); } JS_DEFINE_NATIVE_FUNCTION(EcKeyAlgorithm::named_curve_getter) @@ -157,7 +157,7 @@ void RsaHashedKeyAlgorithm::initialize(JS::Realm& realm) { Base::initialize(realm); - define_native_accessor(realm, "hash"_fly_string, hash_getter, {}, JS::Attribute::Enumerable | JS::Attribute::Configurable); + define_native_accessor(realm, "hash"_utf16_fly_string, hash_getter, {}, JS::Attribute::Enumerable | JS::Attribute::Configurable); } JS_DEFINE_NATIVE_FUNCTION(RsaHashedKeyAlgorithm::hash_getter) @@ -191,7 +191,7 @@ void AesKeyAlgorithm::initialize(JS::Realm& realm) { Base::initialize(realm); - define_native_accessor(realm, "length"_fly_string, length_getter, {}, JS::Attribute::Enumerable | JS::Attribute::Configurable); + define_native_accessor(realm, "length"_utf16_fly_string, length_getter, {}, JS::Attribute::Enumerable | JS::Attribute::Configurable); } JS_DEFINE_NATIVE_FUNCTION(AesKeyAlgorithm::length_getter) @@ -214,8 +214,8 @@ HmacKeyAlgorithm::HmacKeyAlgorithm(JS::Realm& realm) void HmacKeyAlgorithm::initialize(JS::Realm& realm) { Base::initialize(realm); - define_native_accessor(realm, "hash"_fly_string, hash_getter, {}, JS::Attribute::Enumerable | JS::Attribute::Configurable); - define_native_accessor(realm, "length"_fly_string, length_getter, {}, JS::Attribute::Enumerable | JS::Attribute::Configurable); + define_native_accessor(realm, "hash"_utf16_fly_string, hash_getter, {}, JS::Attribute::Enumerable | JS::Attribute::Configurable); + define_native_accessor(realm, "length"_utf16_fly_string, length_getter, {}, JS::Attribute::Enumerable | JS::Attribute::Configurable); } void HmacKeyAlgorithm::visit_edges(JS::Cell::Visitor& visitor) diff --git a/Libraries/LibWeb/Crypto/SubtleCrypto.cpp b/Libraries/LibWeb/Crypto/SubtleCrypto.cpp index 59cdb938a5..7b98851560 100644 --- a/Libraries/LibWeb/Crypto/SubtleCrypto.cpp +++ b/Libraries/LibWeb/Crypto/SubtleCrypto.cpp @@ -72,7 +72,7 @@ WebIDL::ExceptionOr normalize_an_algorithm(JS:: // Return the result of running the normalize an algorithm algorithm, // with the alg set to a new Algorithm dictionary whose name attribute is alg, and with the op set to op. auto dictionary = GC::make_root(JS::Object::create(realm, realm.intrinsics().object_prototype())); - TRY(dictionary->create_data_property("name"_fly_string, JS::PrimitiveString::create(vm, algorithm.get()))); + TRY(dictionary->create_data_property("name"_utf16_fly_string, JS::PrimitiveString::create(vm, algorithm.get()))); return normalize_an_algorithm(realm, dictionary, operation); } @@ -89,7 +89,7 @@ WebIDL::ExceptionOr normalize_an_algorithm(JS:: // 3. If an error occurred, return the error and terminate this algorithm. // Note: We're not going to bother creating an Algorithm object, all we want is the name attribute so that we can // fetch the actual algorithm factory from the registeredAlgorithms map. - auto initial_algorithm = TRY(algorithm.get>()->get("name"_fly_string)); + auto initial_algorithm = TRY(algorithm.get>()->get("name"_utf16_fly_string)); if (initial_algorithm.is_undefined()) { return vm.throw_completion(JS::ErrorType::NotAnObjectOfType, "Algorithm"); diff --git a/Libraries/LibWeb/DOM/Document.cpp b/Libraries/LibWeb/DOM/Document.cpp index 1672e2ee82..ad7db8a4f7 100644 --- a/Libraries/LibWeb/DOM/Document.cpp +++ b/Libraries/LibWeb/DOM/Document.cpp @@ -4821,7 +4821,7 @@ void Document::start_intersection_observing_a_lazy_loading_element(Element& elem // 2. If doc's lazy load intersection observer is null, set it to a new IntersectionObserver instance, initialized as follows: if (!m_lazy_load_intersection_observer) { // - The callback is these steps, with arguments entries and observer: - auto callback = JS::NativeFunction::create(realm, ""_fly_string, [this](JS::VM& vm) -> JS::ThrowCompletionOr { + auto callback = JS::NativeFunction::create(realm, Utf16FlyString {}, [this](JS::VM& vm) -> JS::ThrowCompletionOr { // For each entry in entries using a method of iteration which does not trigger developer-modifiable array accessors or iteration hooks: auto& entries = as(vm.argument(0).as_object()); auto entries_length = MUST(MUST(entries.get(vm.names.length)).to_length(vm)); diff --git a/Libraries/LibWeb/DOM/Element.cpp b/Libraries/LibWeb/DOM/Element.cpp index 50df89c7aa..673a7d703b 100644 --- a/Libraries/LibWeb/DOM/Element.cpp +++ b/Libraries/LibWeb/DOM/Element.cpp @@ -2712,7 +2712,7 @@ void Element::enqueue_a_custom_element_callback_reaction(FlyString const& callba if (connected_callback) (void)WebIDL::invoke_callback(*connected_callback, this, WebIDL::ExceptionBehavior::Report, no_arguments); - return JS::js_undefined(); }, 0, FlyString {}, &realm()); + return JS::js_undefined(); }, 0, Utf16FlyString {}, &realm()); callback = realm().heap().allocate(steps, realm()); } diff --git a/Libraries/LibWeb/DOM/EventDispatcher.cpp b/Libraries/LibWeb/DOM/EventDispatcher.cpp index ec0cdc34ad..54d2aa0ff6 100644 --- a/Libraries/LibWeb/DOM/EventDispatcher.cpp +++ b/Libraries/LibWeb/DOM/EventDispatcher.cpp @@ -91,7 +91,7 @@ bool EventDispatcher::inner_invoke(Event& event, Vectorbody(), program->parameters(), program->function_length(), program->local_variables_names(), scope, nullptr, JS::FunctionKind::Normal, program->is_strict_mode(), + auto function = JS::ECMAScriptFunctionObject::create(realm, Utf16FlyString::from_utf8(name), builder.to_byte_string(), program->body(), program->parameters(), program->function_length(), program->local_variables_names(), scope, nullptr, JS::FunctionKind::Normal, program->is_strict_mode(), program->parsing_insights(), is_arrow_function); // 10. Remove settings object's realm execution context from the JavaScript execution context stack. @@ -617,7 +617,7 @@ void EventTarget::activate_event_handler(FlyString const& name, HTML::EventHandl TRY(event_target->process_event_handler_for_event(name, event)); return JS::js_undefined(); }, - 0, FlyString {}, &realm); + 0, Utf16FlyString {}, &realm); // NOTE: As per the spec, the callback context is arbitrary. auto callback = realm.heap().allocate(*callback_function, realm); diff --git a/Libraries/LibWeb/DOM/NodeIterator.cpp b/Libraries/LibWeb/DOM/NodeIterator.cpp index bdfb9d8ddf..5a7efe753e 100644 --- a/Libraries/LibWeb/DOM/NodeIterator.cpp +++ b/Libraries/LibWeb/DOM/NodeIterator.cpp @@ -169,7 +169,7 @@ JS::ThrowCompletionOr NodeIterator::filter(Node& node) // 6. Let result be the return value of call a user object’s operation with traverser’s filter, "acceptNode", and « node ». // If this throws an exception, then unset traverser’s active flag and rethrow the exception. - auto result = WebIDL::call_user_object_operation(m_filter->callback(), "acceptNode"_string, {}, { { &node } }); + auto result = WebIDL::call_user_object_operation(m_filter->callback(), "acceptNode"_utf16_fly_string, {}, { { &node } }); if (result.is_abrupt()) { m_active = false; return result; diff --git a/Libraries/LibWeb/DOM/TreeWalker.cpp b/Libraries/LibWeb/DOM/TreeWalker.cpp index 9a7d851adc..5840ac45d4 100644 --- a/Libraries/LibWeb/DOM/TreeWalker.cpp +++ b/Libraries/LibWeb/DOM/TreeWalker.cpp @@ -274,7 +274,7 @@ JS::ThrowCompletionOr TreeWalker::filter(Node& node) // 6. Let result be the return value of call a user object’s operation with traverser’s filter, "acceptNode", and « node ». // If this throws an exception, then unset traverser’s active flag and rethrow the exception. - auto result = WebIDL::call_user_object_operation(m_filter->callback(), "acceptNode"_string, {}, { { &node } }); + auto result = WebIDL::call_user_object_operation(m_filter->callback(), "acceptNode"_utf16_fly_string, {}, { { &node } }); if (result.is_abrupt()) { m_active = false; return result; diff --git a/Libraries/LibWeb/HTML/Canvas/CanvasSettings.cpp b/Libraries/LibWeb/HTML/Canvas/CanvasSettings.cpp index f8b81caa71..47c43bb2d3 100644 --- a/Libraries/LibWeb/HTML/Canvas/CanvasSettings.cpp +++ b/Libraries/LibWeb/HTML/Canvas/CanvasSettings.cpp @@ -22,13 +22,13 @@ JS::ThrowCompletionOr Web::HTML::Ca auto& value_object = value.as_object(); - JS::Value alpha = TRY(value_object.get("alpha"_fly_string)); + JS::Value alpha = TRY(value_object.get("alpha"_utf16_fly_string)); settings.alpha = alpha.is_undefined() ? true : alpha.to_boolean(); - JS::Value desynchronized = TRY(value_object.get("desynchronized"_fly_string)); + JS::Value desynchronized = TRY(value_object.get("desynchronized"_utf16_fly_string)); settings.desynchronized = desynchronized.is_undefined() ? false : desynchronized.to_boolean(); - JS::Value color_space = TRY(value_object.get("colorSpace"_fly_string)); + JS::Value color_space = TRY(value_object.get("colorSpace"_utf16_fly_string)); if (!color_space.is_undefined()) { auto color_space_string = TRY(color_space.to_string(vm)); if (color_space_string == "srgb"sv) @@ -39,7 +39,7 @@ JS::ThrowCompletionOr Web::HTML::Ca return vm.throw_completion(JS::ErrorType::InvalidEnumerationValue, color_space_string, "colorSpace"); } - JS::Value color_type = TRY(value_object.get("colorType"_fly_string)); + JS::Value color_type = TRY(value_object.get("colorType"_utf16_fly_string)); if (!color_type.is_undefined()) { auto color_type_string = TRY(color_type.to_string(vm)); if (color_type_string == "unorm8"sv) @@ -50,7 +50,7 @@ JS::ThrowCompletionOr Web::HTML::Ca return vm.throw_completion(JS::ErrorType::InvalidEnumerationValue, color_type_string, "colorType"); } - JS::Value will_read_frequently = TRY(value_object.get("willReadFrequently"_fly_string)); + JS::Value will_read_frequently = TRY(value_object.get("willReadFrequently"_utf16_fly_string)); settings.will_read_frequently = will_read_frequently.is_undefined() ? false : will_read_frequently.to_boolean(); return settings; diff --git a/Libraries/LibWeb/HTML/CustomElements/CustomElementRegistry.cpp b/Libraries/LibWeb/HTML/CustomElements/CustomElementRegistry.cpp index 6c4622687f..56b7fa7433 100644 --- a/Libraries/LibWeb/HTML/CustomElements/CustomElementRegistry.cpp +++ b/Libraries/LibWeb/HTML/CustomElements/CustomElementRegistry.cpp @@ -209,7 +209,7 @@ JS::ThrowCompletionOr CustomElementRegistry::define(String const& name, We // 4. For each callbackName of the keys of lifecycleCallbacks: for (auto const& callback_name : { CustomElementReactionNames::connectedCallback, CustomElementReactionNames::disconnectedCallback, CustomElementReactionNames::adoptedCallback, CustomElementReactionNames::connectedMoveCallback, CustomElementReactionNames::attributeChangedCallback }) { // 1. Let callbackValue be ? Get(prototype, callbackName). - auto callback_value = TRY(prototype.get(callback_name)); + auto callback_value = TRY(prototype.get(Utf16FlyString::from_utf8(callback_name))); // 2. If callbackValue is not undefined, then set the value of the entry in lifecycleCallbacks with key callbackName to the result of // converting callbackValue to the Web IDL Function callback type. @@ -260,7 +260,7 @@ JS::ThrowCompletionOr CustomElementRegistry::define(String const& name, We if (form_associated) { for (auto const& callback_name : { CustomElementReactionNames::formAssociatedCallback, CustomElementReactionNames::formResetCallback, CustomElementReactionNames::formDisabledCallback, CustomElementReactionNames::formStateRestoreCallback }) { // 1. Let callbackValue be ? Get(prototype, callbackName). - auto callback_value = TRY(prototype.get(callback_name)); + auto callback_value = TRY(prototype.get(Utf16FlyString::from_utf8(callback_name))); // 2. If callbackValue is not undefined, then set lifecycleCallbacks[callbackName] to the result of converting callbackValue // to the Web IDL Function callback type. diff --git a/Libraries/LibWeb/HTML/HTMLAllCollection.cpp b/Libraries/LibWeb/HTML/HTMLAllCollection.cpp index b13725e958..885422e32c 100644 --- a/Libraries/LibWeb/HTML/HTMLAllCollection.cpp +++ b/Libraries/LibWeb/HTML/HTMLAllCollection.cpp @@ -118,7 +118,7 @@ Variant, GC::Ref, Empty> HTMLAllColle return Empty {}; // 2. Return the result of getting the "all"-indexed or named element(s) from this, given nameOrIndex. - return get_the_all_indexed_or_named_elements(name_or_index.value()); + return get_the_all_indexed_or_named_elements(Utf16FlyString::from_utf8(name_or_index.value())); } // https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#dom-htmlallcollection-nameditem @@ -211,7 +211,7 @@ Variant, GC::Ref, Empty> HTMLAllColle } // 2. Return the result of getting the "all"-named element(s) from collection given nameOrIndex. - return get_the_all_named_elements(name_or_index.as_string()); + return get_the_all_named_elements(name_or_index.as_string().view().to_utf8_but_should_be_ported_to_utf16()); } Optional HTMLAllCollection::item_value(size_t index) const diff --git a/Libraries/LibWeb/HTML/HTMLDialogElement.cpp b/Libraries/LibWeb/HTML/HTMLDialogElement.cpp index e7405c69d1..e7b17ddb35 100644 --- a/Libraries/LibWeb/HTML/HTMLDialogElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLDialogElement.cpp @@ -412,7 +412,7 @@ void HTMLDialogElement::set_close_watcher() event.prevent_default(); return JS::js_undefined(); }, - 0, ""_fly_string, &realm()); + 0, Utf16FlyString {}, &realm()); auto cancel_callback = realm().heap().allocate(*cancel_callback_function, realm()); m_close_watcher->add_event_listener_without_options(HTML::EventNames::cancel, DOM::IDLEventListener::create(realm(), cancel_callback)); // - closeAction being to close the dialog given dialog, dialog's request close return value, and dialog's request close source element. @@ -422,7 +422,7 @@ void HTMLDialogElement::set_close_watcher() return JS::js_undefined(); }, - 0, ""_fly_string, &realm()); + 0, Utf16FlyString {}, &realm()); auto close_callback = realm().heap().allocate(*close_callback_function, realm()); m_close_watcher->add_event_listener_without_options(HTML::EventNames::close, DOM::IDLEventListener::create(realm(), close_callback)); // - getEnabledState being to return true if dialog's enable close watcher for requestClose() is true or dialog's computed closed-by state is not None; otherwise false. diff --git a/Libraries/LibWeb/HTML/HTMLElement.cpp b/Libraries/LibWeb/HTML/HTMLElement.cpp index bb5b9a8cec..67afa68e4e 100644 --- a/Libraries/LibWeb/HTML/HTMLElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLElement.cpp @@ -1432,7 +1432,7 @@ WebIDL::ExceptionOr HTMLElement::show_popover(ThrowExceptions throw_except return JS::js_undefined(); }, - 0, FlyString {}, &realm()); + 0, Utf16FlyString {}, &realm()); auto close_callback = realm().heap().allocate(*close_callback_function, realm()); m_popover_close_watcher->add_event_listener_without_options(HTML::EventNames::close, DOM::IDLEventListener::create(realm(), close_callback)); // - getEnabledState being to return true. diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Libraries/LibWeb/HTML/HTMLInputElement.cpp index 67b04258e1..44c752b4a8 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -1090,7 +1090,7 @@ void HTMLInputElement::create_text_input_shadow_tree() commit_pending_changes(); return JS::js_undefined(); }, - 0, FlyString {}, &realm()); + 0, Utf16FlyString {}, &realm()); auto mouseup_callback = realm().heap().allocate(*mouseup_callback_function, realm()); DOM::AddEventListenerOptions mouseup_listener_options; mouseup_listener_options.once = true; @@ -1103,7 +1103,7 @@ void HTMLInputElement::create_text_input_shadow_tree() } return JS::js_undefined(); }, - 0, FlyString {}, &realm()); + 0, Utf16FlyString {}, &realm()); auto step_up_callback = realm().heap().allocate(*up_callback_function, realm()); up_button->add_event_listener_without_options(UIEvents::EventNames::mousedown, DOM::IDLEventListener::create(realm(), step_up_callback)); up_button->add_event_listener_without_options(UIEvents::EventNames::mouseup, DOM::IDLEventListener::create(realm(), mouseup_callback)); @@ -1125,7 +1125,7 @@ void HTMLInputElement::create_text_input_shadow_tree() } return JS::js_undefined(); }, - 0, FlyString {}, &realm()); + 0, Utf16FlyString {}, &realm()); auto step_down_callback = realm().heap().allocate(*down_callback_function, realm()); down_button->add_event_listener_without_options(UIEvents::EventNames::mousedown, DOM::IDLEventListener::create(realm(), step_down_callback)); down_button->add_event_listener_without_options(UIEvents::EventNames::mouseup, DOM::IDLEventListener::create(realm(), mouseup_callback)); @@ -1186,7 +1186,7 @@ void HTMLInputElement::create_file_input_shadow_tree() return JS::js_undefined(); }; - auto on_button_click_function = JS::NativeFunction::create(realm, move(on_button_click), 0, FlyString {}, &realm); + auto on_button_click_function = JS::NativeFunction::create(realm, move(on_button_click), 0, Utf16FlyString {}, &realm); auto on_button_click_callback = realm.heap().allocate(on_button_click_function, realm); m_file_button->add_event_listener_without_options(UIEvents::EventNames::click, DOM::IDLEventListener::create(realm, on_button_click_callback)); @@ -1237,7 +1237,7 @@ void HTMLInputElement::create_range_input_shadow_tree() auto keydown_callback_function = JS::NativeFunction::create( realm(), [this](JS::VM& vm) { - auto key = MUST(vm.argument(0).get(vm, "key"_fly_string)).as_string().utf8_string(); + auto key = MUST(vm.argument(0).get(vm, "key"_utf16_fly_string)).as_string().utf8_string(); if (key == "ArrowLeft" || key == "ArrowDown") MUST(step_down()); @@ -1252,13 +1252,13 @@ void HTMLInputElement::create_range_input_shadow_tree() user_interaction_did_change_input_value(); return JS::js_undefined(); }, - 0, ""_fly_string, &realm()); + 0, Utf16FlyString {}, &realm()); auto keydown_callback = realm().heap().allocate(*keydown_callback_function, realm()); add_event_listener_without_options(UIEvents::EventNames::keydown, DOM::IDLEventListener::create(realm(), keydown_callback)); auto wheel_callback_function = JS::NativeFunction::create( realm(), [this](JS::VM& vm) { - auto delta_y = MUST(vm.argument(0).get(vm, "deltaY"_fly_string)).as_i32(); + auto delta_y = MUST(vm.argument(0).get(vm, "deltaY"_utf16_fly_string)).as_i32(); if (delta_y > 0) { MUST(step_down()); } else { @@ -1267,12 +1267,12 @@ void HTMLInputElement::create_range_input_shadow_tree() user_interaction_did_change_input_value(); return JS::js_undefined(); }, - 0, ""_fly_string, &realm()); + 0, Utf16FlyString {}, &realm()); auto wheel_callback = realm().heap().allocate(*wheel_callback_function, realm()); add_event_listener_without_options(UIEvents::EventNames::wheel, DOM::IDLEventListener::create(realm(), wheel_callback)); auto update_slider_by_mouse = [this](JS::VM& vm) { - auto client_x = MUST(vm.argument(0).get(vm, "clientX"_fly_string)).as_double(); + auto client_x = MUST(vm.argument(0).get(vm, "clientX"_utf16_fly_string)).as_double(); auto rect = get_bounding_client_rect(); double minimum = *min(); double maximum = *max(); @@ -1290,7 +1290,7 @@ void HTMLInputElement::create_range_input_shadow_tree() update_slider_by_mouse(vm); return JS::js_undefined(); }, - 0, ""_fly_string, &realm()); + 0, Utf16FlyString {}, &realm()); auto mousemove_callback = realm().heap().allocate(*mousemove_callback_function, realm()); auto mousemove_listener = DOM::IDLEventListener::create(realm(), mousemove_callback); auto& window = static_cast(relevant_global_object(*this)); @@ -1302,7 +1302,7 @@ void HTMLInputElement::create_range_input_shadow_tree() window.remove_event_listener_without_options(UIEvents::EventNames::mousemove, mousemove_listener); return JS::js_undefined(); }, - 0, ""_fly_string, &realm()); + 0, Utf16FlyString {}, &realm()); auto mouseup_callback = realm().heap().allocate(*mouseup_callback_function, realm()); DOM::AddEventListenerOptions mouseup_listener_options; mouseup_listener_options.once = true; @@ -1310,7 +1310,7 @@ void HTMLInputElement::create_range_input_shadow_tree() return JS::js_undefined(); }, - 0, ""_fly_string, &realm()); + 0, Utf16FlyString {}, &realm()); auto mousedown_callback = realm().heap().allocate(*mousedown_callback_function, realm()); add_event_listener_without_options(UIEvents::EventNames::mousedown, DOM::IDLEventListener::create(realm(), mousedown_callback)); } diff --git a/Libraries/LibWeb/HTML/Scripting/ImportMap.cpp b/Libraries/LibWeb/HTML/Scripting/ImportMap.cpp index 8ac9b91a0d..ca869a7031 100644 --- a/Libraries/LibWeb/HTML/Scripting/ImportMap.cpp +++ b/Libraries/LibWeb/HTML/Scripting/ImportMap.cpp @@ -34,8 +34,8 @@ WebIDL::ExceptionOr parse_import_map_string(JS::Realm& realm, ByteStr ModuleSpecifierMap sorted_and_normalized_imports; // 4. If parsed["imports"] exists, then: - if (TRY(parsed_object.has_property("imports"_fly_string))) { - auto imports = TRY(parsed_object.get("imports"_fly_string)); + if (TRY(parsed_object.has_property("imports"_utf16_fly_string))) { + auto imports = TRY(parsed_object.get("imports"_utf16_fly_string)); // If parsed["imports"] is not an ordered map, then throw a TypeError indicating that the value for the "imports" top-level key needs to be a JSON object. if (!imports.is_object()) @@ -49,8 +49,8 @@ WebIDL::ExceptionOr parse_import_map_string(JS::Realm& realm, ByteStr HashMap sorted_and_normalized_scopes; // 6. If parsed["scopes"] exists, then: - if (TRY(parsed_object.has_property("scopes"_fly_string))) { - auto scopes = TRY(parsed_object.get("scopes"_fly_string)); + if (TRY(parsed_object.has_property("scopes"_utf16_fly_string))) { + auto scopes = TRY(parsed_object.get("scopes"_utf16_fly_string)); // If parsed["scopes"] is not an ordered map, then throw a TypeError indicating that the value for the "scopes" top-level key needs to be a JSON object. if (!scopes.is_object()) @@ -64,8 +64,8 @@ WebIDL::ExceptionOr parse_import_map_string(JS::Realm& realm, ByteStr ModuleIntegrityMap normalized_integrity; // 8. If parsed["integrity"] exists, then: - if (TRY(parsed_object.has_property("integrity"_fly_string))) { - auto integrity = TRY(parsed_object.get("integrity"_fly_string)); + if (TRY(parsed_object.has_property("integrity"_utf16_fly_string))) { + auto integrity = TRY(parsed_object.get("integrity"_utf16_fly_string)); // 1. If parsed["integrity"] is not an ordered map, then throw a TypeError indicating that the value for the "integrity" top-level key needs to be a JSON object. if (!integrity.is_object()) @@ -77,7 +77,7 @@ WebIDL::ExceptionOr parse_import_map_string(JS::Realm& realm, ByteStr // 9. If parsed's keys contains any items besides "imports", "scopes", or "integrity", then the user agent should report a warning to the console indicating that an invalid top-level key was present in the import map. for (auto& key : parsed_object.shape().property_table().keys()) { - if (key.as_string().is_one_of("imports", "scopes", "integrity")) + if (key.as_string().is_one_of("imports"sv, "scopes"sv, "integrity"sv)) continue; auto& console = realm.intrinsics().console_object()->console(); @@ -127,7 +127,7 @@ WebIDL::ExceptionOr sort_and_normalise_module_specifier_map( auto value = TRY(original_map.get(specifier_key.as_string())); // 1. Let normalizedSpecifierKey be the result of normalizing a specifier key given specifierKey and baseURL. - auto normalized_specifier_key = normalize_specifier_key(realm, specifier_key.as_string(), base_url); + auto normalized_specifier_key = normalize_specifier_key(realm, specifier_key.as_string().view().to_utf8_but_should_be_ported_to_utf16(), base_url); // 2. If normalizedSpecifierKey is null, then continue. if (!normalized_specifier_key.has_value()) @@ -163,7 +163,7 @@ WebIDL::ExceptionOr sort_and_normalise_module_specifier_map( } // 6. If specifierKey ends with U+002F (/), and the serialization of addressURL does not end with U+002F (/), then: - if (specifier_key.as_string().bytes_as_string_view().ends_with("/"sv) && !address_url->serialize().ends_with('/')) { + if (specifier_key.as_string().view().ends_with("/"sv) && !address_url->serialize().ends_with('/')) { // 1. The user agent may report a warning to the console indicating that an invalid address was given for the specifier key specifierKey; since specifierKey ends with a slash, the address needs to as well. auto& console = realm.intrinsics().console_object()->console(); console.output_debug_message(JS::Console::LogLevel::Warn, @@ -199,7 +199,7 @@ WebIDL::ExceptionOr> sort_and_normalise_sc return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, String::formatted("The value of the scope with the prefix '{}' needs to be a JSON object.", scope_prefix.as_string()).release_value_but_fixme_should_propagate_errors() }; // 2. Let scopePrefixURL be the result of URL parsing scopePrefix with baseURL. - auto scope_prefix_url = DOMURL::parse(scope_prefix.as_string(), base_url); + auto scope_prefix_url = DOMURL::parse(scope_prefix.as_string().view().to_utf8_but_should_be_ported_to_utf16(), base_url); // 3. If scopePrefixURL is failure, then: if (!scope_prefix_url.has_value()) { @@ -232,7 +232,7 @@ WebIDL::ExceptionOr normalize_module_integrity_map(JS::Realm auto value = TRY(original_map.get(key.as_string())); // 1. Let resolvedURL be the result of resolving a URL-like module specifier given key and baseURL. - auto resolved_url = resolve_url_like_module_specifier(key.as_string().to_string().to_byte_string(), base_url); + auto resolved_url = resolve_url_like_module_specifier(key.as_string().view().to_utf8_but_should_be_ported_to_utf16(), base_url); // 2. If resolvedURL is null, then: if (!resolved_url.has_value()) { diff --git a/Libraries/LibWeb/HTML/StructuredSerialize.cpp b/Libraries/LibWeb/HTML/StructuredSerialize.cpp index 72ad2efc56..a4889719e5 100644 --- a/Libraries/LibWeb/HTML/StructuredSerialize.cpp +++ b/Libraries/LibWeb/HTML/StructuredSerialize.cpp @@ -223,7 +223,7 @@ static WebIDL::ExceptionOr serialize_viewed_array_buffer(JS::VM& vm, Trans if constexpr (IsSame) { data_holder.encode(ValueTag::ArrayBufferView); data_holder.append(move(buffer_serialized)); // [[ArrayBufferSerialized]] - data_holder.encode("DataView"_string); // [[Constructor]] + data_holder.encode("DataView"_utf16); // [[Constructor]] data_holder.encode(JS::get_view_byte_length(view_record)); data_holder.encode(view.byte_offset()); } @@ -235,8 +235,8 @@ static WebIDL::ExceptionOr serialize_viewed_array_buffer(JS::VM& vm, Trans // [[ArrayBufferSerialized]]: bufferSerialized, [[ByteLength]]: value.[[ByteLength]], // [[ByteOffset]]: value.[[ByteOffset]], [[ArrayLength]]: value.[[ArrayLength]] }. data_holder.encode(ValueTag::ArrayBufferView); - data_holder.append(move(buffer_serialized)); // [[ArrayBufferSerialized]] - data_holder.encode(view.element_name().to_string()); // [[Constructor]] + data_holder.append(move(buffer_serialized)); // [[ArrayBufferSerialized]] + data_holder.encode(view.element_name().to_utf16_string()); // [[Constructor]] data_holder.encode(JS::typed_array_byte_length(view_record)); data_holder.encode(view.byte_offset()); data_holder.encode(JS::typed_array_length(view_record)); @@ -542,7 +542,7 @@ public: auto output_value = TRY(structured_serialize_internal(m_vm, input_value, m_for_storage, m_memory)); // 3. Append { [[Key]]: key, [[Value]]: outputValue } to serialized.[[Properties]]. - serialized.encode(key.as_string().utf8_string()); + serialized.encode(key.as_string().utf16_string()); serialized.append(move(output_value)); ++property_count; @@ -724,7 +724,7 @@ public: auto array_buffer_value = TRY(deserialize()); auto& array_buffer = as(array_buffer_value.as_object()); - auto constructor_name = m_serialized.decode(); + auto constructor_name = m_serialized.decode(); auto byte_length = m_serialized.decode(); auto byte_offset = m_serialized.decode(); @@ -884,7 +884,7 @@ public: // 1. For each Record { [[Key]], [[Value]] } entry of serialized.[[Properties]]: for (u64 i = 0u; i < length; ++i) { - auto key = m_serialized.decode(); + auto key = m_serialized.decode(); // 1. Let deserializedValue be ? StructuredDeserialize(entry.[[Value]], targetRealm, memory). auto deserialized_value = TRY(deserialize()); diff --git a/Libraries/LibWeb/HTML/UniversalGlobalScope.cpp b/Libraries/LibWeb/HTML/UniversalGlobalScope.cpp index f68207876f..3dd6b3cdd2 100644 --- a/Libraries/LibWeb/HTML/UniversalGlobalScope.cpp +++ b/Libraries/LibWeb/HTML/UniversalGlobalScope.cpp @@ -118,7 +118,7 @@ GC::Ref UniversalGlobalScopeMixin::count_queuing_strategy_ }; // 2. Let F be ! CreateBuiltinFunction(steps, 0, "size", « », globalObject’s relevant Realm). - auto function = JS::NativeFunction::create(realm, move(steps), 0, "size"_fly_string, &realm); + auto function = JS::NativeFunction::create(realm, move(steps), 0, "size"_utf16_fly_string, &realm); // 3. Set globalObject’s count queuing strategy size function to a Function that represents a reference to F, with callback context equal to globalObject’s relevant settings object. // FIXME: Update spec comment to pass globalObject's relevant realm once Streams spec is updated for ShadowRealm spec @@ -143,7 +143,7 @@ GC::Ref UniversalGlobalScopeMixin::byte_length_queuing_str }; // 2. Let F be ! CreateBuiltinFunction(steps, 1, "size", « », globalObject’s relevant Realm). - auto function = JS::NativeFunction::create(realm, move(steps), 1, "size"_fly_string, &realm); + auto function = JS::NativeFunction::create(realm, move(steps), 1, "size"_utf16_fly_string, &realm); // 3. Set globalObject’s byte length queuing strategy size function to a Function that represents a reference to F, with callback context equal to globalObject’s relevant settings object. // FIXME: Update spec comment to pass globalObject's relevant realm once Streams spec is updated for ShadowRealm spec diff --git a/Libraries/LibWeb/HTML/Window.cpp b/Libraries/LibWeb/HTML/Window.cpp index 0414a15096..858aa7c4f4 100644 --- a/Libraries/LibWeb/HTML/Window.cpp +++ b/Libraries/LibWeb/HTML/Window.cpp @@ -748,7 +748,7 @@ WebIDL::ExceptionOr Window::initialize_web_interfaces(Badge(realm), JS::default_attributes); + define_direct_property("internals"_utf16_fly_string, realm.create(realm), JS::default_attributes); return {}; } diff --git a/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp b/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp index 00b57b339b..15fed8b7e9 100644 --- a/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp +++ b/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp @@ -867,7 +867,7 @@ void WindowOrWorkerGlobalScopeMixin::queue_the_performance_observer_task() // droppedEntriesCount if droppedEntriesCount is not null, otherwise unset. auto callback_options = JS::Object::create(realm, realm.intrinsics().object_prototype()); if (dropped_entries_count.has_value()) - MUST(callback_options->create_data_property("droppedEntriesCount"_fly_string, JS::Value(dropped_entries_count.value()))); + MUST(callback_options->create_data_property("droppedEntriesCount"_utf16_fly_string, JS::Value(dropped_entries_count.value()))); // 9. Call po’s observer callback with observerEntryList as the first argument, with po as the second // argument and as callback this value, and with callbackOptions as the third argument. diff --git a/Libraries/LibWeb/HTML/WindowProxy.cpp b/Libraries/LibWeb/HTML/WindowProxy.cpp index 777cc6ba04..9ed93ab18c 100644 --- a/Libraries/LibWeb/HTML/WindowProxy.cpp +++ b/Libraries/LibWeb/HTML/WindowProxy.cpp @@ -117,7 +117,7 @@ JS::ThrowCompletionOr> WindowProxy::internal_ge // 6. If property is undefined and P is in W's document-tree child navigable target name property set, then: auto navigable_property_set = m_window->document_tree_child_navigable_target_name_property_set(); - auto property_key_string = property_key.to_string(); + auto property_key_string = property_key.to_string().to_utf8_but_should_be_ported_to_utf16(); if (auto navigable = navigable_property_set.get(property_key_string); navigable.has_value()) { // 1. Let value be the active WindowProxy of the named object of W with the name P. diff --git a/Libraries/LibWeb/IndexedDB/IDBFactory.cpp b/Libraries/LibWeb/IndexedDB/IDBFactory.cpp index cb71f64889..ac7e79968c 100644 --- a/Libraries/LibWeb/IndexedDB/IDBFactory.cpp +++ b/Libraries/LibWeb/IndexedDB/IDBFactory.cpp @@ -219,10 +219,10 @@ GC::Ref IDBFactory::databases() auto info = JS::Object::create(realm, realm.intrinsics().object_prototype()); // 3. Set info’s name dictionary member to db’s name. - MUST(info->create_data_property("name"_fly_string, JS::PrimitiveString::create(realm.vm(), db->name()))); + MUST(info->create_data_property("name"_utf16_fly_string, JS::PrimitiveString::create(realm.vm(), db->name()))); // 4. Set info’s version dictionary member to db’s version. - MUST(info->create_data_property("version"_fly_string, JS::Value(db->version()))); + MUST(info->create_data_property("version"_utf16_fly_string, JS::Value(db->version()))); // 4. Append info to result. MUST(result->create_data_property_or_throw(i, info)); diff --git a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp index ae9f7b3ae6..fc3410279b 100644 --- a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp +++ b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp @@ -963,7 +963,7 @@ WebIDL::ExceptionOr> evaluate_key_path_on_a_value(JS::Realm& if (!value.is_object()) return Error::from_string_literal("Value is not an object during key path evaluation"); - auto identifier_property = String::from_utf8_without_validation(identifier.bytes()); + auto identifier_property = Utf16String::from_utf8_without_validation(identifier.bytes()); // 2. Let hop be ! HasOwnProperty(value, identifier). auto hop = MUST(value.as_object().has_own_property(identifier_property)); @@ -1020,19 +1020,21 @@ bool check_that_a_key_could_be_injected_into_a_value(JS::Realm& realm, JS::Value // 4. For each remaining identifier of identifiers, if any: for (auto const& identifier : identifiers) { + auto identifier_utf16 = Utf16FlyString::from_utf8(identifier); + // 1. If value is not an Object or an Array, return false. if (!(value.is_object() || MUST(value.is_array(realm.vm())))) return false; // 2. Let hop be ! HasOwnProperty(value, identifier). - auto hop = MUST(value.as_object().has_own_property(identifier)); + auto hop = MUST(value.as_object().has_own_property(identifier_utf16)); // 3. If hop is false, return true. if (!hop) return true; // 4. Let value be ! Get(value, identifier). - value = MUST(value.as_object().get(identifier)); + value = MUST(value.as_object().get(identifier_utf16)); } // 5. Return true if value is an Object or an Array, or false otherwise. @@ -1277,11 +1279,13 @@ void inject_a_key_into_a_value_using_a_key_path(JS::Realm& realm, JS::Value valu // 4. For each remaining identifier of identifiers: for (auto const& identifier : identifiers) { + auto identifier_utf16 = Utf16FlyString::from_utf8(identifier); + // 1. Assert: value is an Object or an Array. VERIFY(value.is_object() || MUST(value.is_array(realm.vm()))); // 2. Let hop be ! HasOwnProperty(value, identifier). - auto hop = MUST(value.as_object().has_own_property(identifier)); + auto hop = MUST(value.as_object().has_own_property(identifier_utf16)); // 3. If hop is false, then: if (!hop) { @@ -1289,14 +1293,14 @@ void inject_a_key_into_a_value_using_a_key_path(JS::Realm& realm, JS::Value valu auto o = JS::Object::create(realm, realm.intrinsics().object_prototype()); // 2. Let status be CreateDataProperty(value, identifier, o). - auto status = MUST(value.as_object().create_data_property(identifier, o)); + auto status = MUST(value.as_object().create_data_property(identifier_utf16, o)); // 3. Assert: status is true. VERIFY(status); } // 4. Let value be ! Get(value, identifier). - value = MUST(value.as_object().get(identifier)); + value = MUST(value.as_object().get(identifier_utf16)); } // 5. Assert: value is an Object or an Array. @@ -1306,7 +1310,7 @@ void inject_a_key_into_a_value_using_a_key_path(JS::Realm& realm, JS::Value valu auto key_value = convert_a_key_to_a_value(realm, key); // 7. Let status be CreateDataProperty(value, last, keyValue). - auto status = MUST(value.as_object().create_data_property(last, key_value)); + auto status = MUST(value.as_object().create_data_property(Utf16FlyString::from_utf8(last), key_value)); // 8. Assert: status is true. VERIFY(status); diff --git a/Libraries/LibWeb/Infra/JSON.cpp b/Libraries/LibWeb/Infra/JSON.cpp index 93e9767788..9910ea21aa 100644 --- a/Libraries/LibWeb/Infra/JSON.cpp +++ b/Libraries/LibWeb/Infra/JSON.cpp @@ -137,7 +137,7 @@ WebIDL::ExceptionOr serialize_javascript_value_to_json_bytes(JS::VM& auto map_value_js_value = convert_an_infra_value_to_a_json_compatible_javascript_value(realm, map_entry.value); // 3. Perform ! CreateDataPropertyOrThrow(jsValue, mapKey, mapValueJSValue). - MUST(js_value->create_data_property_or_throw(map_entry.key, map_value_js_value)); + MUST(js_value->create_data_property_or_throw(Utf16FlyString::from_utf8(map_entry.key), map_value_js_value)); } // 6. Return jsValue. diff --git a/Libraries/LibWeb/Internals/Internals.cpp b/Libraries/LibWeb/Internals/Internals.cpp index a890ba5a5f..5c09d49664 100644 --- a/Libraries/LibWeb/Internals/Internals.cpp +++ b/Libraries/LibWeb/Internals/Internals.cpp @@ -131,8 +131,8 @@ JS::Object* Internals::hit_test(double x, double y) auto result = active_document.paintable_box()->hit_test({ x, y }, Painting::HitTestType::Exact); if (result.has_value()) { auto hit_testing_result = JS::Object::create(realm(), nullptr); - hit_testing_result->define_direct_property("node"_fly_string, result->dom_node(), JS::default_attributes); - hit_testing_result->define_direct_property("indexInNode"_fly_string, JS::Value(result->index_in_node), JS::default_attributes); + hit_testing_result->define_direct_property("node"_utf16_fly_string, result->dom_node(), JS::default_attributes); + hit_testing_result->define_direct_property("indexInNode"_utf16_fly_string, JS::Value(result->index_in_node), JS::default_attributes); return hit_testing_result; } return nullptr; diff --git a/Libraries/LibWeb/MediaCapabilitiesAPI/MediaCapabilities.cpp b/Libraries/LibWeb/MediaCapabilitiesAPI/MediaCapabilities.cpp index 076a52ee15..dcda6fc3ee 100644 --- a/Libraries/LibWeb/MediaCapabilitiesAPI/MediaCapabilities.cpp +++ b/Libraries/LibWeb/MediaCapabilitiesAPI/MediaCapabilities.cpp @@ -236,9 +236,9 @@ GC::Ref MediaCapabilitiesDecodingInfo::to_object(JS::Realm& realm) // FIXME: Also include configuration in this object. - MUST(object->create_data_property("supported"_fly_string, JS::BooleanObject::create(realm, supported))); - MUST(object->create_data_property("smooth"_fly_string, JS::BooleanObject::create(realm, smooth))); - MUST(object->create_data_property("powerEfficient"_fly_string, JS::BooleanObject::create(realm, power_efficient))); + MUST(object->create_data_property("supported"_utf16_fly_string, JS::BooleanObject::create(realm, supported))); + MUST(object->create_data_property("smooth"_utf16_fly_string, JS::BooleanObject::create(realm, smooth))); + MUST(object->create_data_property("powerEfficient"_utf16_fly_string, JS::BooleanObject::create(realm, power_efficient))); return object; } diff --git a/Libraries/LibWeb/Streams/AbstractOperations.cpp b/Libraries/LibWeb/Streams/AbstractOperations.cpp index 2415940b52..483eac01da 100644 --- a/Libraries/LibWeb/Streams/AbstractOperations.cpp +++ b/Libraries/LibWeb/Streams/AbstractOperations.cpp @@ -97,7 +97,7 @@ static void add_message_event_listener(JS::Realm& realm, HTML::MessagePort& port return JS::js_undefined(); }; - auto function = JS::NativeFunction::create(realm, move(behavior), 1, FlyString {}, &realm); + auto function = JS::NativeFunction::create(realm, move(behavior), 1, Utf16FlyString {}, &realm); auto callback = realm.heap().allocate(function, realm); auto listener = DOM::IDLEventListener::create(realm, callback); diff --git a/Libraries/LibWeb/Streams/Transformer.cpp b/Libraries/LibWeb/Streams/Transformer.cpp index 89975c5872..9766afc26f 100644 --- a/Libraries/LibWeb/Streams/Transformer.cpp +++ b/Libraries/LibWeb/Streams/Transformer.cpp @@ -18,19 +18,19 @@ JS::ThrowCompletionOr Transformer::from_value(JS::VM& vm, JS::Value auto& object = value.as_object(); Transformer transformer { - .start = TRY(WebIDL::property_to_callback(vm, value, "start"_fly_string, WebIDL::OperationReturnsPromise::No)), - .transform = TRY(WebIDL::property_to_callback(vm, value, "transform"_fly_string, WebIDL::OperationReturnsPromise::Yes)), - .flush = TRY(WebIDL::property_to_callback(vm, value, "flush"_fly_string, WebIDL::OperationReturnsPromise::Yes)), - .cancel = TRY(WebIDL::property_to_callback(vm, value, "cancel"_fly_string, WebIDL::OperationReturnsPromise::Yes)), + .start = TRY(WebIDL::property_to_callback(vm, value, "start"_utf16_fly_string, WebIDL::OperationReturnsPromise::No)), + .transform = TRY(WebIDL::property_to_callback(vm, value, "transform"_utf16_fly_string, WebIDL::OperationReturnsPromise::Yes)), + .flush = TRY(WebIDL::property_to_callback(vm, value, "flush"_utf16_fly_string, WebIDL::OperationReturnsPromise::Yes)), + .cancel = TRY(WebIDL::property_to_callback(vm, value, "cancel"_utf16_fly_string, WebIDL::OperationReturnsPromise::Yes)), .readable_type = {}, .writable_type = {}, }; - if (TRY(object.has_property("readableType"_fly_string))) - transformer.readable_type = TRY(object.get("readableType"_fly_string)); + if (TRY(object.has_property("readableType"_utf16_fly_string))) + transformer.readable_type = TRY(object.get("readableType"_utf16_fly_string)); - if (TRY(object.has_property("writableType"_fly_string))) - transformer.writable_type = TRY(object.get("writableType"_fly_string)); + if (TRY(object.has_property("writableType"_utf16_fly_string))) + transformer.writable_type = TRY(object.get("writableType"_utf16_fly_string)); return transformer; } diff --git a/Libraries/LibWeb/Streams/UnderlyingSink.cpp b/Libraries/LibWeb/Streams/UnderlyingSink.cpp index a152f9acbc..ce8ace332f 100644 --- a/Libraries/LibWeb/Streams/UnderlyingSink.cpp +++ b/Libraries/LibWeb/Streams/UnderlyingSink.cpp @@ -18,15 +18,15 @@ JS::ThrowCompletionOr UnderlyingSink::from_value(JS::VM& vm, JS: auto& object = value.as_object(); UnderlyingSink underlying_sink { - .start = TRY(WebIDL::property_to_callback(vm, value, "start"_fly_string, WebIDL::OperationReturnsPromise::No)), - .write = TRY(WebIDL::property_to_callback(vm, value, "write"_fly_string, WebIDL::OperationReturnsPromise::Yes)), - .close = TRY(WebIDL::property_to_callback(vm, value, "close"_fly_string, WebIDL::OperationReturnsPromise::Yes)), - .abort = TRY(WebIDL::property_to_callback(vm, value, "abort"_fly_string, WebIDL::OperationReturnsPromise::Yes)), + .start = TRY(WebIDL::property_to_callback(vm, value, "start"_utf16_fly_string, WebIDL::OperationReturnsPromise::No)), + .write = TRY(WebIDL::property_to_callback(vm, value, "write"_utf16_fly_string, WebIDL::OperationReturnsPromise::Yes)), + .close = TRY(WebIDL::property_to_callback(vm, value, "close"_utf16_fly_string, WebIDL::OperationReturnsPromise::Yes)), + .abort = TRY(WebIDL::property_to_callback(vm, value, "abort"_utf16_fly_string, WebIDL::OperationReturnsPromise::Yes)), .type = {}, }; - if (TRY(object.has_property("type"_fly_string))) - underlying_sink.type = TRY(object.get("type"_fly_string)); + if (TRY(object.has_property("type"_utf16_fly_string))) + underlying_sink.type = TRY(object.get("type"_utf16_fly_string)); return underlying_sink; } diff --git a/Libraries/LibWeb/Streams/UnderlyingSource.cpp b/Libraries/LibWeb/Streams/UnderlyingSource.cpp index b2f6e65d1d..56df7c3aa3 100644 --- a/Libraries/LibWeb/Streams/UnderlyingSource.cpp +++ b/Libraries/LibWeb/Streams/UnderlyingSource.cpp @@ -21,14 +21,14 @@ JS::ThrowCompletionOr UnderlyingSource::from_value(JS::VM& vm, auto& object = value.as_object(); UnderlyingSource underlying_source { - .start = TRY(WebIDL::property_to_callback(vm, value, "start"_fly_string, WebIDL::OperationReturnsPromise::No)), - .pull = TRY(WebIDL::property_to_callback(vm, value, "pull"_fly_string, WebIDL::OperationReturnsPromise::Yes)), - .cancel = TRY(WebIDL::property_to_callback(vm, value, "cancel"_fly_string, WebIDL::OperationReturnsPromise::Yes)), + .start = TRY(WebIDL::property_to_callback(vm, value, "start"_utf16_fly_string, WebIDL::OperationReturnsPromise::No)), + .pull = TRY(WebIDL::property_to_callback(vm, value, "pull"_utf16_fly_string, WebIDL::OperationReturnsPromise::Yes)), + .cancel = TRY(WebIDL::property_to_callback(vm, value, "cancel"_utf16_fly_string, WebIDL::OperationReturnsPromise::Yes)), .type = {}, .auto_allocate_chunk_size = {}, }; - auto type_value = TRY(object.get("type"_fly_string)); + auto type_value = TRY(object.get("type"_utf16_fly_string)); if (!type_value.is_undefined()) { auto type_string = TRY(type_value.to_string(vm)); if (type_string == "bytes"sv) @@ -37,8 +37,8 @@ JS::ThrowCompletionOr UnderlyingSource::from_value(JS::VM& vm, return vm.throw_completion(MUST(String::formatted("Unknown stream type '{}'", type_value))); } - if (TRY(object.has_property("autoAllocateChunkSize"_fly_string))) { - auto value = TRY(object.get("autoAllocateChunkSize"_fly_string)); + if (TRY(object.has_property("autoAllocateChunkSize"_utf16_fly_string))) { + auto value = TRY(object.get("autoAllocateChunkSize"_utf16_fly_string)); underlying_source.auto_allocate_chunk_size = TRY(WebIDL::convert_to_int(vm, value, WebIDL::EnforceRange::Yes)); } diff --git a/Libraries/LibWeb/WebAssembly/Instance.cpp b/Libraries/LibWeb/WebAssembly/Instance.cpp index a819092e8c..833cdb9f7d 100644 --- a/Libraries/LibWeb/WebAssembly/Instance.cpp +++ b/Libraries/LibWeb/WebAssembly/Instance.cpp @@ -50,15 +50,17 @@ void Instance::initialize(JS::Realm& realm) // https://webassembly.github.io/spec/js-api/#create-an-exports-object for (auto& export_ : m_module_instance->exports()) { + auto name = Utf16FlyString::from_utf8(export_.name()); + export_.value().visit( [&](Wasm::FunctionAddress const& address) { Optional> object = m_function_instances.get(address); if (!object.has_value()) { - object = Detail::create_native_function(vm, address, MUST(String::from_byte_string(export_.name())), this); + object = Detail::create_native_function(vm, address, name, this); m_function_instances.set(address, *object); } - m_exports->define_direct_property(MUST(String::from_byte_string(export_.name())), *object, JS::default_attributes); + m_exports->define_direct_property(name, *object, JS::default_attributes); }, [&](Wasm::GlobalAddress const& address) { Optional> object = cache.get_global_instance(address); @@ -66,7 +68,7 @@ void Instance::initialize(JS::Realm& realm) object = realm.create(realm, address); } - m_exports->define_direct_property(MUST(String::from_byte_string(export_.name())), *object, JS::default_attributes); + m_exports->define_direct_property(name, *object, JS::default_attributes); }, [&](Wasm::MemoryAddress const& address) { Optional> object = m_memory_instances.get(address); @@ -75,7 +77,7 @@ void Instance::initialize(JS::Realm& realm) m_memory_instances.set(address, *object); } - m_exports->define_direct_property(MUST(String::from_byte_string(export_.name())), *object, JS::default_attributes); + m_exports->define_direct_property(name, *object, JS::default_attributes); }, [&](Wasm::TableAddress const& address) { Optional> object = m_table_instances.get(address); @@ -84,7 +86,7 @@ void Instance::initialize(JS::Realm& realm) m_table_instances.set(address, *object); } - m_exports->define_direct_property(MUST(String::from_byte_string(export_.name())), *object, JS::default_attributes); + m_exports->define_direct_property(name, *object, JS::default_attributes); }); } diff --git a/Libraries/LibWeb/WebAssembly/WebAssembly.cpp b/Libraries/LibWeb/WebAssembly/WebAssembly.cpp index bc32eb9b6d..4e633a9908 100644 --- a/Libraries/LibWeb/WebAssembly/WebAssembly.cpp +++ b/Libraries/LibWeb/WebAssembly/WebAssembly.cpp @@ -87,9 +87,9 @@ void initialize(JS::Object& self, JS::Realm&) // 2.2. ! DefineMethodProperty(namespaceObject, error, constructor, false). u8 attr = JS::Attribute::Writable | JS::Attribute::Configurable; -#define __WASM_ENUMERATE(ClassName, FullClassName, snake_name, PrototypeName, ConstructorName) \ - namespace_object.define_intrinsic_accessor(#ClassName##_fly_string, attr, [](auto& realm) -> JS::Value { \ - return &Bindings::ensure_web_constructor(realm, FullClassName##_fly_string); \ +#define __WASM_ENUMERATE(ClassName, FullClassName, snake_name, PrototypeName, ConstructorName) \ + namespace_object.define_intrinsic_accessor(#ClassName##_utf16_fly_string, attr, [](auto& realm) -> JS::Value { \ + return &Bindings::ensure_web_constructor(realm, FullClassName##_fly_string); \ }); WASM_ENUMERATE_NATIVE_ERRORS #undef __WASM_ENUMERATE @@ -233,7 +233,7 @@ JS::ThrowCompletionOr> instantiate_module(JS dbgln_if(LIBWEB_WASM_DEBUG, "Trying to resolve {}::{}", import_name.module, import_name.name); // 3.1. Let o be ? Get(importObject, moduleName). - auto value = TRY(import_object->get(MUST(String::from_byte_string(import_name.module)))); + auto value = TRY(import_object->get(Utf16FlyString::from_utf8(import_name.module))); // 3.2. If o is not an Object, throw a TypeError exception. if (!value.is_object()) @@ -241,7 +241,7 @@ JS::ThrowCompletionOr> instantiate_module(JS auto const& object = value.as_object(); // 3.3. Let v be ? Get(o, componentName). - auto import_ = TRY(object.get(MUST(String::from_byte_string(import_name.name)))); + auto import_ = TRY(object.get(Utf16FlyString::from_utf8(import_name.name))); TRY(import_name.type.visit( // 3.4. If externtype is of the form func functype, @@ -439,23 +439,23 @@ JS::ThrowCompletionOr> compile_a_webass GC_DEFINE_ALLOCATOR(ExportedWasmFunction); -GC::Ref ExportedWasmFunction::create(JS::Realm& realm, FlyString const& name, Function(JS::VM&)> behavior, Wasm::FunctionAddress exported_address) +GC::Ref ExportedWasmFunction::create(JS::Realm& realm, Utf16FlyString name, Function(JS::VM&)> behavior, Wasm::FunctionAddress exported_address) { auto prototype = realm.intrinsics().function_prototype(); return realm.create( - name, + move(name), move(behavior), exported_address, prototype); } -ExportedWasmFunction::ExportedWasmFunction(FlyString name, AK::Function(JS::VM&)> behavior, Wasm::FunctionAddress exported_address, JS::Object& prototype) +ExportedWasmFunction::ExportedWasmFunction(Utf16FlyString name, AK::Function(JS::VM&)> behavior, Wasm::FunctionAddress exported_address, JS::Object& prototype) : NativeFunction(move(name), move(behavior), prototype) , m_exported_address(exported_address) { } -JS::NativeFunction* create_native_function(JS::VM& vm, Wasm::FunctionAddress address, String const& name, Instance* instance) +JS::NativeFunction* create_native_function(JS::VM& vm, Wasm::FunctionAddress address, Utf16FlyString name, Instance* instance) { auto& realm = *vm.current_realm(); Optional type; @@ -466,7 +466,7 @@ JS::NativeFunction* create_native_function(JS::VM& vm, Wasm::FunctionAddress add auto function = ExportedWasmFunction::create( realm, - name, + move(name), [address, type = type.release_value(), instance](JS::VM& vm) -> JS::ThrowCompletionOr { (void)instance; auto& realm = *vm.current_realm(); @@ -619,7 +619,7 @@ JS::Value to_js_value(JS::VM& vm, Wasm::Value& wasm_value, Wasm::ValueType type) [](Wasm::HostFunction& host_function) { return host_function.name(); }); - return create_native_function(vm, address, MUST(String::from_byte_string(name))); + return create_native_function(vm, address, Utf16FlyString::from_utf8(name)); } case Wasm::ValueType::ExternReference: { auto ref_ = wasm_value.to(); @@ -760,8 +760,8 @@ GC::Ref instantiate_promise_of_module(JS::VM& vm, GC::Refdefine_direct_property("module"_fly_string, module, JS::default_attributes); - result->define_direct_property("instance"_fly_string, instance, JS::default_attributes); + result->define_direct_property("module"_utf16_fly_string, module, JS::default_attributes); + result->define_direct_property("instance"_utf16_fly_string, instance, JS::default_attributes); // 2. Resolve promise with result. WebIDL::resolve_promise(realm, promise, result); @@ -966,7 +966,7 @@ static JS::ThrowCompletionOr> wasm_ordinary_create_from_const #define DEFINE_WASM_NATIVE_ERROR_CONSTRUCTOR(ClassName, FullClassName, snake_name, PrototypeName, ConstructorName) \ GC_DEFINE_ALLOCATOR(ConstructorName); \ ConstructorName::ConstructorName(JS::Realm& realm) \ - : NativeFunction(#ClassName##_string, *realm.intrinsics().error_constructor()) \ + : NativeFunction(#ClassName##_utf16_fly_string, *realm.intrinsics().error_constructor()) \ { \ } \ \ diff --git a/Libraries/LibWeb/WebAssembly/WebAssembly.h b/Libraries/LibWeb/WebAssembly/WebAssembly.h index 2e7d11d65d..dfc81a80fa 100644 --- a/Libraries/LibWeb/WebAssembly/WebAssembly.h +++ b/Libraries/LibWeb/WebAssembly/WebAssembly.h @@ -74,13 +74,13 @@ class ExportedWasmFunction final : public JS::NativeFunction { GC_DECLARE_ALLOCATOR(ExportedWasmFunction); public: - static GC::Ref create(JS::Realm&, FlyString const& name, ESCAPING Function(JS::VM&)>, Wasm::FunctionAddress); + static GC::Ref create(JS::Realm&, Utf16FlyString name, ESCAPING Function(JS::VM&)>, Wasm::FunctionAddress); virtual ~ExportedWasmFunction() override = default; Wasm::FunctionAddress exported_address() const { return m_exported_address; } protected: - ExportedWasmFunction(FlyString name, AK::Function(JS::VM&)>, Wasm::FunctionAddress, Object& prototype); + ExportedWasmFunction(Utf16FlyString name, AK::Function(JS::VM&)>, Wasm::FunctionAddress, Object& prototype); private: Wasm::FunctionAddress m_exported_address; @@ -90,7 +90,7 @@ WebAssemblyCache& get_cache(JS::Realm&); JS::ThrowCompletionOr> instantiate_module(JS::VM&, Wasm::Module const&, GC::Ptr import_object); JS::ThrowCompletionOr> compile_a_webassembly_module(JS::VM&, ByteBuffer); -JS::NativeFunction* create_native_function(JS::VM&, Wasm::FunctionAddress address, String const& name, Instance* instance = nullptr); +JS::NativeFunction* create_native_function(JS::VM&, Wasm::FunctionAddress address, Utf16FlyString name, Instance* instance = nullptr); JS::ThrowCompletionOr to_webassembly_value(JS::VM&, JS::Value value, Wasm::ValueType const& type); Wasm::Value default_webassembly_value(JS::VM&, Wasm::ValueType type); JS::Value to_js_value(JS::VM&, Wasm::Value& wasm_value, Wasm::ValueType type); diff --git a/Libraries/LibWeb/WebDriver/Contexts.cpp b/Libraries/LibWeb/WebDriver/Contexts.cpp index 7bc96dfc52..8e2cb8fc30 100644 --- a/Libraries/LibWeb/WebDriver/Contexts.cpp +++ b/Libraries/LibWeb/WebDriver/Contexts.cpp @@ -14,10 +14,10 @@ namespace Web::WebDriver { // https://w3c.github.io/webdriver/#dfn-web-window-identifier -static JS::PropertyKey const WEB_WINDOW_IDENTIFIER { "window-fcc6-11e5-b4f8-330a88ab9d7f"_fly_string }; +static JS::PropertyKey const WEB_WINDOW_IDENTIFIER { "window-fcc6-11e5-b4f8-330a88ab9d7f"_utf16_fly_string }; // https://w3c.github.io/webdriver/#dfn-web-frame-identifier -static JS::PropertyKey const WEB_FRAME_IDENTIFIER { "frame-075b-4da1-b6ba-e579c2d3230a"_fly_string }; +static JS::PropertyKey const WEB_FRAME_IDENTIFIER { "frame-075b-4da1-b6ba-e579c2d3230a"_utf16_fly_string }; // https://w3c.github.io/webdriver/#dfn-windowproxy-reference-object JsonObject window_proxy_reference_object(HTML::WindowProxy const& window) @@ -39,7 +39,7 @@ JsonObject window_proxy_reference_object(HTML::WindowProxy const& window) // identifier // Associated window handle of the window’s browsing context. - object.set(identifier.as_string(), navigable->traversable_navigable()->window_handle()); + object.set(MUST(identifier.as_string().view().to_utf8()), navigable->traversable_navigable()->window_handle()); return object; } diff --git a/Libraries/LibWeb/WebDriver/ElementReference.cpp b/Libraries/LibWeb/WebDriver/ElementReference.cpp index ff3edad60a..a6848839f3 100644 --- a/Libraries/LibWeb/WebDriver/ElementReference.cpp +++ b/Libraries/LibWeb/WebDriver/ElementReference.cpp @@ -26,11 +26,11 @@ namespace Web::WebDriver { // https://w3c.github.io/webdriver/#dfn-web-element-identifier static String const web_element_identifier = "element-6066-11e4-a52e-4f735466cecf"_string; -static JS::PropertyKey web_element_identifier_key { web_element_identifier }; +static JS::PropertyKey web_element_identifier_key { Utf16FlyString::from_utf8(web_element_identifier) }; // https://w3c.github.io/webdriver/#dfn-shadow-root-identifier static String const shadow_root_identifier = "shadow-6066-11e4-a52e-4f735466cecf"_string; -static JS::PropertyKey shadow_root_identifier_key { shadow_root_identifier }; +static JS::PropertyKey shadow_root_identifier_key { Utf16FlyString::from_utf8(shadow_root_identifier) }; // https://w3c.github.io/webdriver/#dfn-browsing-context-group-node-map static HashMap, HashTable> browsing_context_group_node_map; diff --git a/Libraries/LibWeb/WebDriver/ExecuteScript.cpp b/Libraries/LibWeb/WebDriver/ExecuteScript.cpp index 1a0fefb093..edac5a08b4 100644 --- a/Libraries/LibWeb/WebDriver/ExecuteScript.cpp +++ b/Libraries/LibWeb/WebDriver/ExecuteScript.cpp @@ -84,7 +84,7 @@ static JS::ThrowCompletionOr execute_a_function_body(HTML::BrowsingCo // The result of parsing strict above. auto function = JS::ECMAScriptFunctionObject::create_from_function_node( function_expression, - ""_fly_string, + Utf16FlyString {}, realm, &global_scope, nullptr); diff --git a/Libraries/LibWeb/WebDriver/JSON.cpp b/Libraries/LibWeb/WebDriver/JSON.cpp index 6ae29a2809..06911f21b3 100644 --- a/Libraries/LibWeb/WebDriver/JSON.cpp +++ b/Libraries/LibWeb/WebDriver/JSON.cpp @@ -135,7 +135,7 @@ static ErrorOr clone_an_object(HTML::BrowsingConte if (result.is_array() && name.is_number()) result.as_array().set(name.as_number(), cloned_property_result.value()); else if (result.is_object()) - result.as_object().set(name.to_string(), cloned_property_result.value()); + result.as_object().set(name.to_string().to_utf8(), cloned_property_result.value()); } else { (void)result->set(name, cloned_property_result.value(), JS::Object::ShouldThrowExceptions::No); } diff --git a/Libraries/LibWeb/WebGL/WebGLContextAttributes.cpp b/Libraries/LibWeb/WebGL/WebGLContextAttributes.cpp index 5c9a7260df..98f76e3bb4 100644 --- a/Libraries/LibWeb/WebGL/WebGLContextAttributes.cpp +++ b/Libraries/LibWeb/WebGL/WebGLContextAttributes.cpp @@ -23,7 +23,7 @@ JS::ThrowCompletionOr convert_value_to_context_attribute if (value.is_nullish()) alpha = JS::js_undefined(); else - alpha = TRY(value.as_object().get("alpha"_fly_string)); + alpha = TRY(value.as_object().get("alpha"_utf16_fly_string)); bool alpha_value; if (!alpha.is_undefined()) @@ -37,7 +37,7 @@ JS::ThrowCompletionOr convert_value_to_context_attribute if (value.is_nullish()) antialias = JS::js_undefined(); else - antialias = TRY(value.as_object().get("antialias"_fly_string)); + antialias = TRY(value.as_object().get("antialias"_utf16_fly_string)); bool antialias_value; if (!antialias.is_undefined()) @@ -51,7 +51,7 @@ JS::ThrowCompletionOr convert_value_to_context_attribute if (value.is_nullish()) depth = JS::js_undefined(); else - depth = TRY(value.as_object().get("depth"_fly_string)); + depth = TRY(value.as_object().get("depth"_utf16_fly_string)); bool depth_value; if (!depth.is_undefined()) @@ -65,7 +65,7 @@ JS::ThrowCompletionOr convert_value_to_context_attribute if (value.is_nullish()) desynchronized = JS::js_undefined(); else - desynchronized = TRY(value.as_object().get("desynchronized"_fly_string)); + desynchronized = TRY(value.as_object().get("desynchronized"_utf16_fly_string)); bool desynchronized_value; @@ -80,7 +80,7 @@ JS::ThrowCompletionOr convert_value_to_context_attribute if (value.is_nullish()) fail_if_major_performance_caveat = JS::js_undefined(); else - fail_if_major_performance_caveat = TRY(value.as_object().get("failIfMajorPerformanceCaveat"_fly_string)); + fail_if_major_performance_caveat = TRY(value.as_object().get("failIfMajorPerformanceCaveat"_utf16_fly_string)); bool fail_if_major_performance_caveat_value; if (!fail_if_major_performance_caveat.is_undefined()) @@ -94,7 +94,7 @@ JS::ThrowCompletionOr convert_value_to_context_attribute if (value.is_nullish()) power_preference = JS::js_undefined(); else - power_preference = TRY(value.as_object().get("powerPreference"_fly_string)); + power_preference = TRY(value.as_object().get("powerPreference"_utf16_fly_string)); Bindings::WebGLPowerPreference power_preference_value { Bindings::WebGLPowerPreference::Default }; @@ -117,7 +117,7 @@ JS::ThrowCompletionOr convert_value_to_context_attribute if (value.is_nullish()) premultiplied_alpha = JS::js_undefined(); else - premultiplied_alpha = TRY(value.as_object().get("premultipliedAlpha"_fly_string)); + premultiplied_alpha = TRY(value.as_object().get("premultipliedAlpha"_utf16_fly_string)); bool premultiplied_alpha_value; @@ -132,7 +132,7 @@ JS::ThrowCompletionOr convert_value_to_context_attribute if (value.is_nullish()) preserve_drawing_buffer = JS::js_undefined(); else - preserve_drawing_buffer = TRY(value.as_object().get("preserveDrawingBuffer"_fly_string)); + preserve_drawing_buffer = TRY(value.as_object().get("preserveDrawingBuffer"_utf16_fly_string)); bool preserve_drawing_buffer_value; if (!preserve_drawing_buffer.is_undefined()) @@ -146,7 +146,7 @@ JS::ThrowCompletionOr convert_value_to_context_attribute if (value.is_nullish()) stencil = JS::js_undefined(); else - stencil = TRY(value.as_object().get("stencil"_fly_string)); + stencil = TRY(value.as_object().get("stencil"_utf16_fly_string)); bool stencil_value; diff --git a/Libraries/LibWeb/WebIDL/AbstractOperations.cpp b/Libraries/LibWeb/WebIDL/AbstractOperations.cpp index 10c475316f..cad409def2 100644 --- a/Libraries/LibWeb/WebIDL/AbstractOperations.cpp +++ b/Libraries/LibWeb/WebIDL/AbstractOperations.cpp @@ -141,7 +141,7 @@ inline JS::Completion clean_up_on_return(JS::Realm& stored_realm, JS::Realm& rel // https://webidl.spec.whatwg.org/#call-a-user-objects-operation // https://whatpr.org/webidl/1437.html#call-a-user-objects-operation -JS::Completion call_user_object_operation(CallbackType& callback, String const& operation_name, Optional this_argument, ReadonlySpan args) +JS::Completion call_user_object_operation(CallbackType& callback, Utf16FlyString const& operation_name, Optional this_argument, ReadonlySpan args) { // 1. Let completion be an uninitialized variable. JS::Completion completion; diff --git a/Libraries/LibWeb/WebIDL/AbstractOperations.h b/Libraries/LibWeb/WebIDL/AbstractOperations.h index b69da91c0c..c1860ca515 100644 --- a/Libraries/LibWeb/WebIDL/AbstractOperations.h +++ b/Libraries/LibWeb/WebIDL/AbstractOperations.h @@ -20,7 +20,7 @@ bool is_buffer_source_type(JS::Value); GC::Ptr underlying_buffer_source(JS::Object& buffer_source); ErrorOr get_buffer_source_copy(JS::Object const& buffer_source); -JS::Completion call_user_object_operation(CallbackType& callback, String const& operation_name, Optional this_argument, ReadonlySpan args); +JS::Completion call_user_object_operation(CallbackType& callback, Utf16FlyString const& operation_name, Optional this_argument, ReadonlySpan args); JS::ThrowCompletionOr to_string(JS::VM&, JS::Value); JS::ThrowCompletionOr to_utf16_string(JS::VM&, JS::Value); diff --git a/Libraries/LibWeb/WebIDL/ExceptionOr.h b/Libraries/LibWeb/WebIDL/ExceptionOr.h index a6444f7a44..b5bbdf7a22 100644 --- a/Libraries/LibWeb/WebIDL/ExceptionOr.h +++ b/Libraries/LibWeb/WebIDL/ExceptionOr.h @@ -170,7 +170,7 @@ struct Formatter : Formatter { if (value.is_object()) { auto& object = value.as_object(); - static const JS::PropertyKey message_property_key { "message"_fly_string }; + static const JS::PropertyKey message_property_key { "message"_utf16_fly_string }; auto has_message_or_error = object.has_own_property(message_property_key); if (!has_message_or_error.is_error() && has_message_or_error.value()) { auto message_object = object.get_without_side_effects(message_property_key); diff --git a/Libraries/LibWeb/WebIDL/OverloadResolution.cpp b/Libraries/LibWeb/WebIDL/OverloadResolution.cpp index a110ef9e1d..f720271334 100644 --- a/Libraries/LibWeb/WebIDL/OverloadResolution.cpp +++ b/Libraries/LibWeb/WebIDL/OverloadResolution.cpp @@ -228,7 +228,7 @@ JS::ThrowCompletionOr resolve_overload(JS::VM& vm, IDL::Effect // then remove from S all other entries. else if (value.is_object() && value.as_object().is_typed_array() && has_overload_with_argument_type_or_subtype_matching(overloads, i, [&](IDL::Type const& type) { - if (type.is_plain() && (type.name() == static_cast(value.as_object()).element_name().bytes_as_string_view() || type.name() == "BufferSource" || type.name() == "ArrayBufferView")) + if (type.is_plain() && (type.name() == static_cast(value.as_object()).element_name() || type.name() == "BufferSource" || type.name() == "ArrayBufferView")) return true; if (type.is_object()) return true; diff --git a/Meta/Lagom/Fuzzers/FuzzilliJs.cpp b/Meta/Lagom/Fuzzers/FuzzilliJs.cpp index c8526c8419..e2c05e213a 100644 --- a/Meta/Lagom/Fuzzers/FuzzilliJs.cpp +++ b/Meta/Lagom/Fuzzers/FuzzilliJs.cpp @@ -177,8 +177,8 @@ JS_DEFINE_NATIVE_FUNCTION(TestRunnerGlobalObject::fuzzilli) void TestRunnerGlobalObject::initialize(JS::Realm& realm) { Base::initialize(realm); - define_direct_property("global"_fly_string, this, JS::Attribute::Enumerable); - define_native_function(realm, "fuzzilli"_fly_string, fuzzilli, 2, JS::default_attributes); + define_direct_property("global"_utf16_fly_string, this, JS::Attribute::Enumerable); + define_native_function(realm, "fuzzilli"_utf16_fly_string, fuzzilli, 2, JS::default_attributes); } int main(int, char**) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index 2fbafb9b40..908cb08281 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -988,7 +988,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter dictionary_generator.append(R"~~~( auto @member_property_value_name@ = JS::js_undefined(); if (@js_name@@js_suffix@.is_object()) - @member_property_value_name@ = TRY(@js_name@@js_suffix@.as_object().get("@member_key@"_fly_string)); + @member_property_value_name@ = TRY(@js_name@@js_suffix@.as_object().get("@member_key@"_utf16_fly_string)); )~~~"); if (member.required) { dictionary_generator.append(R"~~~( @@ -1952,7 +1952,7 @@ static void generate_wrap_statement(SourceGenerator& generator, ByteString const // 2. For each key → value of D: for (auto const& [key, value] : @value@) { // 1. Let jsKey be key converted to a JavaScript value. - auto js_key = JS::PropertyKey { key }; + auto js_key = JS::PropertyKey { Utf16FlyString::from_utf8(key) }; // 2. Let jsValue be value converted to a JavaScript value. )~~~"); @@ -2110,11 +2110,11 @@ static void generate_wrap_statement(SourceGenerator& generator, ByteString const if (is_optional) { dictionary_generator.append(R"~~~( if (@wrapped_value_name@.has_value()) - MUST(dictionary_object@recursion_depth@->create_data_property("@member_key@"_fly_string, @wrapped_value_name@.release_value())); + MUST(dictionary_object@recursion_depth@->create_data_property("@member_key@"_utf16_fly_string, @wrapped_value_name@.release_value())); )~~~"); } else { dictionary_generator.append(R"~~~( - MUST(dictionary_object@recursion_depth@->create_data_property("@member_key@"_fly_string, @wrapped_value_name@)); + MUST(dictionary_object@recursion_depth@->create_data_property("@member_key@"_utf16_fly_string, @wrapped_value_name@)); )~~~"); } } @@ -3214,7 +3214,7 @@ static void collect_attribute_values_of_an_inheritance_stack(SourceGenerator& fu generate_wrap_statement(attribute_generator, return_value_name, attribute.type, interface_in_chain, ByteString::formatted("{}_wrapped =", return_value_name)); attribute_generator.append(R"~~~( - MUST(result->create_data_property("@attribute.name@"_fly_string, @attribute.return_value_name@_wrapped)); + MUST(result->create_data_property("@attribute.name@"_utf16_fly_string, @attribute.return_value_name@_wrapped)); )~~~"); } @@ -3225,7 +3225,7 @@ static void collect_attribute_values_of_an_inheritance_stack(SourceGenerator& fu generate_wrap_statement(constant_generator, constant.value, constant.type, interface_in_chain, ByteString::formatted("auto constant_{}_value =", constant.name)); constant_generator.append(R"~~~( - MUST(result->create_data_property("@constant.name@"_fly_string, constant_@constant.name@_value)); + MUST(result->create_data_property("@constant.name@"_utf16_fly_string, constant_@constant.name@_value)); )~~~"); } @@ -3375,7 +3375,7 @@ JS::ThrowCompletionOr> @named_properties_class@ // 4. If the result of running the named property visibility algorithm with property name P and object object is true, then: if (TRY(object.is_named_property_exposed_on_object(property_name))) { - auto property_name_string = property_name.to_string(); + auto property_name_string = property_name.to_string().to_utf8_but_should_be_ported_to_utf16(); // 1. Let operation be the operation used to declare the named property getter. // 2. Let value be an uninitialized variable. @@ -3578,7 +3578,7 @@ void @class_name@::initialize(JS::Realm& realm) if (attribute.extended_attributes.contains("FIXME")) { attribute_generator.set("attribute.name", attribute.name); attribute_generator.append(R"~~~( - @define_direct_property@("@attribute.name@"_fly_string, JS::js_undefined(), default_attributes | JS::Attribute::Unimplemented); + @define_direct_property@("@attribute.name@"_utf16_fly_string, JS::js_undefined(), default_attributes | JS::Attribute::Unimplemented); )~~~"); continue; } @@ -3593,12 +3593,12 @@ void @class_name@::initialize(JS::Realm& realm) if (attribute.extended_attributes.contains("Unscopable")) { attribute_generator.append(R"~~~( - MUST(unscopable_object->create_data_property("@attribute.name@"_fly_string, JS::Value(true))); + MUST(unscopable_object->create_data_property("@attribute.name@"_utf16_fly_string, JS::Value(true))); )~~~"); } attribute_generator.append(R"~~~( - @define_native_accessor@(realm, "@attribute.name@"_fly_string, @attribute.getter_callback@, @attribute.setter_callback@, default_attributes); + @define_native_accessor@(realm, "@attribute.name@"_utf16_fly_string, @attribute.getter_callback@, @attribute.setter_callback@, default_attributes); )~~~"); } @@ -3611,7 +3611,7 @@ void @class_name@::initialize(JS::Realm& realm) auto function_generator = generator_for_member(function.name, function.extended_attributes); function_generator.set("function.name", function.name); function_generator.append(R"~~~( - @define_direct_property@("@function.name@"_fly_string, JS::js_undefined(), default_attributes | JS::Attribute::Unimplemented); + @define_direct_property@("@function.name@"_utf16_fly_string, JS::js_undefined(), default_attributes | JS::Attribute::Unimplemented); )~~~"); } } @@ -3627,7 +3627,7 @@ void @class_name@::initialize(JS::Realm& realm) generate_wrap_statement(constant_generator, constant.value, constant.type, interface, ByteString::formatted("auto constant_{}_value =", constant.name)); constant_generator.append(R"~~~( - @define_direct_property@("@constant.name@"_fly_string, constant_@constant.name@_value, JS::Attribute::Enumerable); + @define_direct_property@("@constant.name@"_utf16_fly_string, constant_@constant.name@_value, JS::Attribute::Enumerable); )~~~"); } } @@ -3648,12 +3648,12 @@ void @class_name@::initialize(JS::Realm& realm) if (any_of(overload_set.value, [](auto const& function) { return function.extended_attributes.contains("Unscopable"); })) { VERIFY(all_of(overload_set.value, [](auto const& function) { return function.extended_attributes.contains("Unscopable"); })); function_generator.append(R"~~~( - MUST(unscopable_object->create_data_property("@function.name@"_fly_string, JS::Value(true))); + MUST(unscopable_object->create_data_property("@function.name@"_utf16_fly_string, JS::Value(true))); )~~~"); } function_generator.append(R"~~~( - @define_native_function@(realm, "@function.name@"_fly_string, @function.name:snakecase@, @function.length@, default_attributes); + @define_native_function@(realm, "@function.name@"_utf16_fly_string, @function.name:snakecase@, @function.length@, default_attributes); )~~~"); } @@ -3669,7 +3669,7 @@ void @class_name@::initialize(JS::Realm& realm) ? generator_for_member("stringifier"sv, *interface.stringifier_extended_attributes) : generator.fork(); stringifier_generator.append(R"~~~( - @define_native_function@(realm, "toString"_fly_string, to_string, 0, default_attributes); + @define_native_function@(realm, "toString"_utf16_fly_string, to_string, 0, default_attributes); )~~~"); } @@ -4425,7 +4425,7 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.setter_callback@) return vm.throw_completion(JS::ErrorType::BadArgCountOne, "@namespaced_name@ setter"); auto* impl = TRY(impl_from(vm)); - TRY(impl->internal_define_own_property("@attribute.name@"_fly_string, JS::PropertyDescriptor { .value = vm.argument(0), .writable = true })); + TRY(impl->internal_define_own_property("@attribute.name@"_utf16_fly_string, JS::PropertyDescriptor { .value = vm.argument(0), .writable = true })); return JS::js_undefined(); } )~~~"); @@ -4444,7 +4444,7 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.setter_callback@) auto receiver = TRY(throw_dom_exception_if_needed(vm, [&]() { return impl->@attribute.cpp_name@(); })); if (receiver != JS::js_null()) - TRY(receiver->set(JS::PropertyKey { "@put_forwards_identifier@"_fly_string, JS::PropertyKey::StringMayBeNumber::No }, value, JS::Object::ShouldThrowExceptions::Yes)); + TRY(receiver->set(JS::PropertyKey { "@put_forwards_identifier@"_utf16_fly_string, JS::PropertyKey::StringMayBeNumber::No }, value, JS::Object::ShouldThrowExceptions::Yes)); return JS::js_undefined(); } @@ -4925,7 +4925,7 @@ void @namespace_class@::initialize(JS::Realm& realm) function_generator.set("function.length", ByteString::number(get_shortest_function_length(overload_set.value))); function_generator.append(R"~~~( - define_native_function(realm, "@function.name@"_fly_string, @function.name:snakecase@, @function.length@, default_attributes); + define_native_function(realm, "@function.name@"_utf16_fly_string, @function.name:snakecase@, @function.length@, default_attributes); )~~~"); } @@ -5068,7 +5068,7 @@ static void define_the_operations(SourceGenerator& generator, HashMap(JS::Realm& realm) gen.set("owned_prototype_class", interface.prototype_class); gen.append(R"~~~( - namespace_object->define_intrinsic_accessor("@owned_interface_name@"_fly_string, attr, [](auto& realm) -> JS::Value { return &Bindings::ensure_web_constructor<@owned_prototype_class@>(realm, "@interface_name@.@owned_interface_name@"_fly_string); });)~~~"); + namespace_object->define_intrinsic_accessor("@owned_interface_name@"_utf16_fly_string, attr, [](auto& realm) -> JS::Value { return &Bindings::ensure_web_constructor<@owned_prototype_class@>(realm, "@interface_name@.@owned_interface_name@"_fly_string); });)~~~"); } gen.append(R"~~~( @@ -347,7 +347,7 @@ void add_@global_object_snake_name@_exposed_interfaces(JS::Object& global) gen.set("prototype_class", prototype_class); gen.append(R"~~~( - global.define_intrinsic_accessor("@interface_name@"_fly_string, attr, [](auto& realm) -> JS::Value { return &ensure_web_constructor<@prototype_class@>(realm, "@interface_name@"_fly_string); });)~~~"); + global.define_intrinsic_accessor("@interface_name@"_utf16_fly_string, attr, [](auto& realm) -> JS::Value { return &ensure_web_constructor<@prototype_class@>(realm, "@interface_name@"_fly_string); });)~~~"); // https://webidl.spec.whatwg.org/#LegacyWindowAlias if (legacy_alias_name.has_value()) { @@ -356,19 +356,19 @@ void add_@global_object_snake_name@_exposed_interfaces(JS::Object& global) for (auto legacy_alias_name : legacy_alias_names) { gen.set("interface_alias_name", legacy_alias_name.trim_whitespace()); gen.append(R"~~~( - global.define_intrinsic_accessor("@interface_alias_name@"_fly_string, attr, [](auto& realm) -> JS::Value { return &ensure_web_constructor<@prototype_class@>(realm, "@interface_name@"_fly_string); });)~~~"); + global.define_intrinsic_accessor("@interface_alias_name@"_utf16_fly_string, attr, [](auto& realm) -> JS::Value { return &ensure_web_constructor<@prototype_class@>(realm, "@interface_name@"_fly_string); });)~~~"); } } else { gen.set("interface_alias_name", *legacy_alias_name); gen.append(R"~~~( - global.define_intrinsic_accessor("@interface_alias_name@"_fly_string, attr, [](auto& realm) -> JS::Value { return &ensure_web_constructor<@prototype_class@>(realm, "@interface_name@"_fly_string); });)~~~"); + global.define_intrinsic_accessor("@interface_alias_name@"_utf16_fly_string, attr, [](auto& realm) -> JS::Value { return &ensure_web_constructor<@prototype_class@>(realm, "@interface_name@"_fly_string); });)~~~"); } } if (legacy_constructor.has_value()) { gen.set("legacy_interface_name", legacy_constructor->name); gen.append(R"~~~( - global.define_intrinsic_accessor("@legacy_interface_name@"_fly_string, attr, [](auto& realm) -> JS::Value { return &ensure_web_constructor<@prototype_class@>(realm, "@legacy_interface_name@"_fly_string); });)~~~"); + global.define_intrinsic_accessor("@legacy_interface_name@"_utf16_fly_string, attr, [](auto& realm) -> JS::Value { return &ensure_web_constructor<@prototype_class@>(realm, "@legacy_interface_name@"_fly_string); });)~~~"); } }; @@ -377,7 +377,7 @@ void add_@global_object_snake_name@_exposed_interfaces(JS::Object& global) gen.set("namespace_class", namespace_class); gen.append(R"~~~( - global.define_intrinsic_accessor("@interface_name@"_fly_string, attr, [](auto& realm) -> JS::Value { return &ensure_web_namespace<@namespace_class@>(realm, "@interface_name@"_fly_string); });)~~~"); + global.define_intrinsic_accessor("@interface_name@"_utf16_fly_string, attr, [](auto& realm) -> JS::Value { return &ensure_web_namespace<@namespace_class@>(realm, "@interface_name@"_fly_string); });)~~~"); }; for (auto& interface : exposed_interfaces) { diff --git a/Services/WebContent/ConsoleGlobalEnvironmentExtensions.cpp b/Services/WebContent/ConsoleGlobalEnvironmentExtensions.cpp index 7a97a30db3..191ff885ff 100644 --- a/Services/WebContent/ConsoleGlobalEnvironmentExtensions.cpp +++ b/Services/WebContent/ConsoleGlobalEnvironmentExtensions.cpp @@ -27,10 +27,10 @@ void ConsoleGlobalEnvironmentExtensions::initialize(JS::Realm& realm) { Base::initialize(realm); - define_native_accessor(realm, "$0"_fly_string, $0_getter, nullptr, 0); - define_native_accessor(realm, "$_"_fly_string, $__getter, nullptr, 0); - define_native_function(realm, "$"_fly_string, $_function, 2, JS::default_attributes); - define_native_function(realm, "$$"_fly_string, $$_function, 2, JS::default_attributes); + define_native_accessor(realm, "$0"_utf16_fly_string, $0_getter, nullptr, 0); + define_native_accessor(realm, "$_"_utf16_fly_string, $__getter, nullptr, 0); + define_native_function(realm, "$"_utf16_fly_string, $_function, 2, JS::default_attributes); + define_native_function(realm, "$$"_utf16_fly_string, $$_function, 2, JS::default_attributes); } void ConsoleGlobalEnvironmentExtensions::visit_edges(Visitor& visitor) diff --git a/Services/WebContent/DevToolsConsoleClient.cpp b/Services/WebContent/DevToolsConsoleClient.cpp index 0e390f942d..e9c4fa6011 100644 --- a/Services/WebContent/DevToolsConsoleClient.cpp +++ b/Services/WebContent/DevToolsConsoleClient.cpp @@ -78,7 +78,7 @@ static JsonValue serialize_js_value(JS::Realm& realm, JS::Value value) } if (value.is_symbol()) - return MUST(value.as_symbol().descriptive_string()); + return value.as_symbol().descriptive_string().to_utf8(); // FIXME: Handle serialization of object grips. For now, we stringify the object. if (value.is_object()) { diff --git a/Services/WebContent/WebDriverConnection.cpp b/Services/WebContent/WebDriverConnection.cpp index 0c35508508..443e3c1bc7 100644 --- a/Services/WebContent/WebDriverConnection.cpp +++ b/Services/WebContent/WebDriverConnection.cpp @@ -1342,7 +1342,7 @@ Messages::WebDriverClient::GetElementPropertyResponse WebDriverConnection::get_e // 5. Let property be the result of calling the Object.[[GetProperty]](name) on element. Web::HTML::TemporaryExecutionContext execution_context { current_browsing_context().active_document()->realm() }; - if (auto property_or_error = element->get(name); !property_or_error.is_throw_completion()) { + if (auto property_or_error = element->get(Utf16FlyString::from_utf8(name)); !property_or_error.is_throw_completion()) { auto property = property_or_error.release_value(); // 6. Let result be the value of property if not undefined, or null. diff --git a/Services/WebContent/WebUIConnection.cpp b/Services/WebContent/WebUIConnection.cpp index 4c45fe6a73..18ff753eaf 100644 --- a/Services/WebContent/WebUIConnection.cpp +++ b/Services/WebContent/WebUIConnection.cpp @@ -17,7 +17,7 @@ namespace WebContent { -static auto LADYBIRD_PROPERTY = JS::PropertyKey { "ladybird"_fly_string }; +static auto LADYBIRD_PROPERTY = JS::PropertyKey { "ladybird"_utf16_fly_string }; static auto WEB_UI_LOADED_EVENT = "WebUILoaded"_fly_string; static auto WEB_UI_MESSAGE_EVENT = "WebUIMessage"_fly_string; diff --git a/Tests/LibJS/test-js.cpp b/Tests/LibJS/test-js.cpp index eeeb2b8839..b74e833da2 100644 --- a/Tests/LibJS/test-js.cpp +++ b/Tests/LibJS/test-js.cpp @@ -82,7 +82,7 @@ TESTJS_GLOBAL_FUNCTION(mark_as_garbage, markAsGarbage) if (!outer_environment.has_value()) return vm.throw_completion(JS::ErrorType::UnknownIdentifier, variable_name.utf8_string_view()); - auto reference = TRY(vm.resolve_binding(variable_name.utf8_string(), outer_environment.value()->lexical_environment)); + auto reference = TRY(vm.resolve_binding(variable_name.utf16_string(), outer_environment.value()->lexical_environment)); auto value = TRY(reference.get_value(vm)); diff --git a/Tests/LibWasm/test-wasm.cpp b/Tests/LibWasm/test-wasm.cpp index bd37ae61d5..c15951d8f3 100644 --- a/Tests/LibWasm/test-wasm.cpp +++ b/Tests/LibWasm/test-wasm.cpp @@ -179,7 +179,7 @@ TESTJS_GLOBAL_FUNCTION(parse_webassembly_module, parseWebAssemblyModule) auto& module_object = static_cast(value.as_object()); for (auto& entry : module_object.module_instance().exports()) { // FIXME: Don't pretend that everything is a function - imports.set({ property.key.as_string().to_string().to_byte_string(), entry.name(), Wasm::TypeIndex(0) }, entry.value()); + imports.set({ property.key.as_string().to_utf16_string().to_byte_string(), entry.name(), Wasm::TypeIndex(0) }, entry.value()); } } } @@ -246,7 +246,7 @@ TESTJS_GLOBAL_FUNCTION(test_simd_vector, testSIMDVector) if (!is(*got)) return vm.throw_completion("Expected a TypedArray"sv); auto& got_array = static_cast(*got); - auto element_size = 128 / TRY(TRY(expected_array.get("length"_fly_string)).to_u32(vm)); + auto element_size = 128 / TRY(TRY(expected_array.get("length"_utf16_fly_string)).to_u32(vm)); size_t i = 0; for (auto it = expected_array.indexed_properties().begin(false); it != expected_array.indexed_properties().end(); ++it) { auto got_value = TRY(got_array.get(i++)); @@ -280,8 +280,8 @@ TESTJS_GLOBAL_FUNCTION(test_simd_vector, testSIMDVector) void WebAssemblyModule::initialize(JS::Realm& realm) { Base::initialize(realm); - define_native_function(realm, "getExport"_fly_string, get_export, 1, JS::default_attributes); - define_native_function(realm, "invoke"_fly_string, wasm_invoke, 1, JS::default_attributes); + define_native_function(realm, "getExport"_utf16_fly_string, get_export, 1, JS::default_attributes); + define_native_function(realm, "invoke"_utf16_fly_string, wasm_invoke, 1, JS::default_attributes); } JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::get_export) diff --git a/Utilities/js.cpp b/Utilities/js.cpp index 1d32250ccd..05aeb06d8a 100644 --- a/Utilities/js.cpp +++ b/Utilities/js.cpp @@ -266,9 +266,9 @@ static JS::ThrowCompletionOr load_ini_impl(JS::VM& vm) auto group_object = JS::Object::create(realm, realm.intrinsics().object_prototype()); for (auto const& key : config_file->keys(group)) { auto entry = config_file->read_entry(group, key); - group_object->define_direct_property(MUST(String::from_byte_string(key)), JS::PrimitiveString::create(vm, move(entry)), JS::Attribute::Enumerable | JS::Attribute::Configurable | JS::Attribute::Writable); + group_object->define_direct_property(Utf16String::from_utf8(key), JS::PrimitiveString::create(vm, move(entry)), JS::Attribute::Enumerable | JS::Attribute::Configurable | JS::Attribute::Writable); } - object->define_direct_property(MUST(String::from_byte_string(group)), group_object, JS::Attribute::Enumerable | JS::Attribute::Configurable | JS::Attribute::Writable); + object->define_direct_property(Utf16String::from_utf8(group), group_object, JS::Attribute::Enumerable | JS::Attribute::Configurable | JS::Attribute::Writable); } return object; } @@ -295,18 +295,18 @@ void ReplObject::initialize(JS::Realm& realm) { Base::initialize(realm); - define_direct_property("global"_fly_string, this, JS::Attribute::Enumerable); + define_direct_property("global"_utf16_fly_string, this, JS::Attribute::Enumerable); u8 attr = JS::Attribute::Configurable | JS::Attribute::Writable | JS::Attribute::Enumerable; - define_native_function(realm, "exit"_fly_string, exit_interpreter, 0, attr); - define_native_function(realm, "help"_fly_string, repl_help, 0, attr); - define_native_function(realm, "save"_fly_string, save_to_file, 1, attr); - define_native_function(realm, "loadINI"_fly_string, load_ini, 1, attr); - define_native_function(realm, "loadJSON"_fly_string, load_json, 1, attr); - define_native_function(realm, "print"_fly_string, print, 1, attr); + define_native_function(realm, "exit"_utf16_fly_string, exit_interpreter, 0, attr); + define_native_function(realm, "help"_utf16_fly_string, repl_help, 0, attr); + define_native_function(realm, "save"_utf16_fly_string, save_to_file, 1, attr); + define_native_function(realm, "loadINI"_utf16_fly_string, load_ini, 1, attr); + define_native_function(realm, "loadJSON"_utf16_fly_string, load_json, 1, attr); + define_native_function(realm, "print"_utf16_fly_string, print, 1, attr); define_native_accessor( realm, - "_"_fly_string, + "_"_utf16_fly_string, [](JS::VM&) { return g_last_value.value(); }, @@ -380,11 +380,11 @@ void ScriptObject::initialize(JS::Realm& realm) { Base::initialize(realm); - define_direct_property("global"_fly_string, this, JS::Attribute::Enumerable); + define_direct_property("global"_utf16_fly_string, this, JS::Attribute::Enumerable); u8 attr = JS::Attribute::Configurable | JS::Attribute::Writable | JS::Attribute::Enumerable; - define_native_function(realm, "loadINI"_fly_string, load_ini, 1, attr); - define_native_function(realm, "loadJSON"_fly_string, load_json, 1, attr); - define_native_function(realm, "print"_fly_string, print, 1, attr); + define_native_function(realm, "loadINI"_utf16_fly_string, load_ini, 1, attr); + define_native_function(realm, "loadJSON"_utf16_fly_string, load_json, 1, attr); + define_native_function(realm, "print"_utf16_fly_string, print, 1, attr); } JS_DEFINE_NATIVE_FUNCTION(ScriptObject::load_ini) @@ -744,11 +744,12 @@ static ErrorOr run_repl(bool gc_on_every_allocation, bool syntax_highlight) for (auto const& descriptor : shape.property_table()) { if (!descriptor.key.is_string()) continue; - auto key = descriptor.key.as_string(); + + auto key = descriptor.key.as_string().to_utf16_string().to_utf8_but_should_be_ported_to_utf16(); if (key.bytes_as_string_view().starts_with(property_pattern)) { Line::CompletionSuggestion completion { key, Line::CompletionSuggestion::ForSearch }; if (!results.contains_slow(completion)) { // hide duplicates - results.append(key.to_string().to_byte_string()); + results.append(key.to_byte_string()); results.last().invariant_offset = property_pattern.length(); } } @@ -758,9 +759,11 @@ static ErrorOr run_repl(bool gc_on_every_allocation, bool syntax_highlight) } }; + auto variable_name_utf16 = Utf16FlyString::from_utf8(variable_name); + switch (mode) { case CompleteProperty: { - auto reference_or_error = g_vm->resolve_binding(variable_name, &global_environment); + auto reference_or_error = g_vm->resolve_binding(variable_name_utf16, &global_environment); if (reference_or_error.is_error()) return {}; auto value_or_error = reference_or_error.value().get_value(*g_vm); @@ -782,8 +785,8 @@ static ErrorOr run_repl(bool gc_on_every_allocation, bool syntax_highlight) list_all_properties(variable.shape(), variable_name); for (auto const& name : global_environment.declarative_record().bindings()) { - if (name.bytes_as_string_view().starts_with(variable_name)) { - results.empend(name); + if (name.view().starts_with(variable_name_utf16.view())) { + results.empend(name.view().to_utf8_but_should_be_ported_to_utf16().to_byte_string()); results.last().invariant_offset = variable_name.bytes().size(); } } diff --git a/Utilities/test262-runner.cpp b/Utilities/test262-runner.cpp index 4869e4377a..0c983f8ce5 100644 --- a/Utilities/test262-runner.cpp +++ b/Utilities/test262-runner.cpp @@ -90,19 +90,19 @@ static ErrorOr run_program(InterpreterT& interpreter, ScriptOrM if (error_value.is_object()) { auto& object = error_value.as_object(); - auto name = object.get_without_side_effects("name"_fly_string); + auto name = object.get_without_side_effects("name"_utf16_fly_string); if (!name.is_undefined() && !name.is_accessor()) { error.type = name.to_string_without_side_effects(); } else { - auto constructor = object.get_without_side_effects("constructor"_fly_string); + auto constructor = object.get_without_side_effects("constructor"_utf16_fly_string); if (constructor.is_object()) { - name = constructor.as_object().get_without_side_effects("name"_fly_string); + name = constructor.as_object().get_without_side_effects("name"_utf16_fly_string); if (!name.is_undefined()) error.type = name.to_string_without_side_effects(); } } - auto message = object.get_without_side_effects("message"_fly_string); + auto message = object.get_without_side_effects("message"_utf16_fly_string); if (!message.is_undefined() && !message.is_accessor()) error.details = message.to_string_without_side_effects(); }