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(); }