mirror of
https://github.com/zebrajr/ladybird.git
synced 2025-12-06 00:19:53 +01:00
LibJS+LibWeb+WebContent: Port JS::PropertyKey to UTF-16
This has quite a lot of fall out. But the majority of it is just type or UDL substitution, where the changes just fall through to other function calls. By changing property key storage to UTF-16, the main affected areas are: * NativeFunction names must now be UTF-16 * Bytecode identifiers must now be UTF-16 * Module/binding names must now be UTF-16
This commit is contained in:
parent
cd276235d7
commit
0efa98a57a
|
|
@ -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<ClassElementName> class_key_to_property_name(VM& vm, Ex
|
|||
auto& private_identifier = static_cast<PrivateIdentifier const&>(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<ClassElement::ClassValue> 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<ClassElement::ClassValue> 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<PropertyKey>()) {
|
||||
|
|
@ -187,11 +190,11 @@ ThrowCompletionOr<ClassElement::ClassValue> 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<ClassElement::ClassValue> 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<ClassElement::ClassValue> 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<ClassFieldInitializerStatement>(m_initializer->source_range(), copy_initializer.release_nonnull(), name);
|
||||
auto function_code = create_ast_node<ClassFieldInitializerStatement>(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<ClassElement::ClassValue> 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<ClassElement::ClassValue> StaticInitializer::class_element_eva
|
|||
return ClassValue { normal_completion(body_function) };
|
||||
}
|
||||
|
||||
ThrowCompletionOr<ECMAScriptFunctionObject*> ClassExpression::create_class_constructor(VM& vm, Environment* class_environment, Environment* environment, Value super_class, ReadonlySpan<Value> element_keys, Optional<FlyString> const& binding_name, FlyString const& class_name) const
|
||||
ThrowCompletionOr<ECMAScriptFunctionObject*> ClassExpression::create_class_constructor(VM& vm, Environment* class_environment, Environment* environment, Value super_class, ReadonlySpan<Value> element_keys, Optional<Utf16FlyString> const& binding_name, Utf16FlyString const& class_name) const
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
|
|
@ -352,7 +355,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> 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<DeclarativeEnvironment>(*environment));
|
||||
static_cast<DeclarativeEnvironment&>(*environment).initialize_or_set_mutable_binding({}, vm, function_declaration.name(), function);
|
||||
static_cast<DeclarativeEnvironment&>(*environment).initialize_or_set_mutable_binding({}, vm, function->name(), function);
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
|
@ -1693,7 +1697,7 @@ ThrowCompletionOr<void> 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<void> {
|
||||
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<void> 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<void> {
|
||||
TRY(for_each_var_declared_identifier([&](Identifier const& identifier) -> ThrowCompletionOr<void> {
|
||||
// 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<SyntaxError>(ErrorType::TopLevelVariableAlreadyDeclared, identifier.string());
|
||||
|
||||
return {};
|
||||
|
|
@ -1726,11 +1730,13 @@ ThrowCompletionOr<void> Program::global_declaration_instantiation(VM& vm, Global
|
|||
Vector<FunctionDeclaration const&> functions_to_initialize;
|
||||
|
||||
// 7. Let declaredFunctionNames be a new empty List.
|
||||
HashTable<FlyString> declared_function_names;
|
||||
HashTable<Utf16FlyString> 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<void> {
|
||||
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<void> 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<void> Program::global_declaration_instantiation(VM& vm, Global
|
|||
}));
|
||||
|
||||
// 9. Let declaredVarNames be a new empty List.
|
||||
HashTable<FlyString> declared_var_names;
|
||||
HashTable<Utf16FlyString> 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<void> 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<void> {
|
||||
auto const& name = identifier.string();
|
||||
return declaration.for_each_bound_identifier([&](Identifier const& identifier) -> ThrowCompletionOr<void> {
|
||||
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<void> 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<void> {
|
||||
// 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<void> 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<void> {
|
||||
auto const& name = identifier.string();
|
||||
return declaration.for_each_bound_identifier([&](Identifier const& identifier) -> ThrowCompletionOr<void> {
|
||||
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<void> 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
|
||||
|
|
|
|||
|
|
@ -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<SharedFunctionInstanceData> shared_data() const;
|
||||
void set_shared_data(RefPtr<SharedFunctionInstanceData>) 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<ECMAScriptFunctionObject*> create_class_constructor(VM&, Environment* class_environment, Environment* environment, Value super_class, ReadonlySpan<Value> element_keys, Optional<FlyString> const& binding_name = {}, FlyString const& class_name = {}) const;
|
||||
ThrowCompletionOr<ECMAScriptFunctionObject*> create_class_constructor(VM&, Environment* class_environment, Environment* environment, Value super_class, ReadonlySpan<Value> element_keys, Optional<Utf16FlyString> const& binding_name = {}, Utf16FlyString const& class_name = {}) const;
|
||||
|
||||
private:
|
||||
virtual bool is_class_expression() const override { return true; }
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/FlyString.h>
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/NonnullOwnPtr.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/Utf16FlyString.h>
|
||||
#include <AK/WeakPtr.h>
|
||||
#include <LibGC/CellAllocator.h>
|
||||
#include <LibJS/Bytecode/IdentifierTable.h>
|
||||
|
|
@ -67,7 +67,7 @@ public:
|
|||
|
||||
virtual ~Executable() override;
|
||||
|
||||
FlyString name;
|
||||
Utf16FlyString name;
|
||||
Vector<u8> bytecode;
|
||||
Vector<PropertyLookupCache> property_lookup_caches;
|
||||
Vector<GlobalVariableCache> global_variable_caches;
|
||||
|
|
@ -99,9 +99,9 @@ public:
|
|||
Optional<IdentifierTableIndex> 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<FlyString const&> get_identifier(Optional<IdentifierTableIndex> const& index) const
|
||||
Optional<Utf16FlyString const&> get_identifier(Optional<IdentifierTableIndex> const& index) const
|
||||
{
|
||||
if (!index.has_value())
|
||||
return {};
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<u32>::max());
|
||||
return { static_cast<u32>(m_identifiers.size() - 1) };
|
||||
}
|
||||
|
||||
FlyString const& IdentifierTable::get(IdentifierTableIndex index) const
|
||||
Utf16FlyString const& IdentifierTable::get(IdentifierTableIndex index) const
|
||||
{
|
||||
return m_identifiers[index.value];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/DistinctNumeric.h>
|
||||
#include <AK/FlyString.h>
|
||||
#include <AK/Utf16FlyString.h>
|
||||
#include <AK/Vector.h>
|
||||
|
||||
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<FlyString> m_identifiers;
|
||||
Vector<Utf16FlyString> m_identifiers;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -821,7 +821,7 @@ void Interpreter::enter_object_environment(Object& object)
|
|||
running_execution_context().lexical_environment = new_object_environment(object, true, old_environment);
|
||||
}
|
||||
|
||||
ThrowCompletionOr<GC::Ref<Bytecode::Executable>> compile(VM& vm, ASTNode const& node, FunctionKind kind, FlyString const& name)
|
||||
ThrowCompletionOr<GC::Ref<Bytecode::Executable>> 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<Value> get_global(Interpreter& interpreter, IdentifierT
|
|||
return vm.throw_completion<ReferenceError>(ErrorType::UnknownIdentifier, identifier);
|
||||
}
|
||||
|
||||
inline ThrowCompletionOr<void> put_by_property_key(VM& vm, Value base, Value this_value, Value value, Optional<FlyString const&> const& base_identifier, PropertyKey name, Op::PropertyKind kind, PropertyLookupCache* caches = nullptr)
|
||||
inline ThrowCompletionOr<void> put_by_property_key(VM& vm, Value base, Value this_value, Value value, Optional<Utf16FlyString const&> 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<void> put_by_property_key(VM& vm, Value base, Value thi
|
|||
case Op::PropertyKind::Getter: {
|
||||
auto& function = value.as_function();
|
||||
if (is<ECMAScriptFunctionObject>(function) && static_cast<ECMAScriptFunctionObject const&>(function).name().is_empty())
|
||||
static_cast<ECMAScriptFunctionObject*>(&function)->set_name(MUST(String::formatted("get {}", name)));
|
||||
static_cast<ECMAScriptFunctionObject*>(&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<ECMAScriptFunctionObject>(function) && static_cast<ECMAScriptFunctionObject const&>(function).name().is_empty())
|
||||
static_cast<ECMAScriptFunctionObject*>(&function)->set_name(MUST(String::formatted("set {}", name)));
|
||||
static_cast<ECMAScriptFunctionObject*>(&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<Id
|
|||
Value value;
|
||||
|
||||
if (!function_node.has_name()) {
|
||||
FlyString name;
|
||||
Utf16FlyString name;
|
||||
if (lhs_name.has_value())
|
||||
name = vm.bytecode_interpreter().current_executable().get_identifier(lhs_name.value());
|
||||
value = function_node.instantiate_ordinary_function_expression(vm, name);
|
||||
} else {
|
||||
value = ECMAScriptFunctionObject::create_from_function_node(
|
||||
function_node,
|
||||
function_node.name(),
|
||||
Utf16FlyString::from_utf8(function_node.name()),
|
||||
*vm.current_realm(),
|
||||
vm.lexical_environment(),
|
||||
vm.running_execution_context().private_environment);
|
||||
|
|
@ -1375,7 +1375,7 @@ inline Value new_function(VM& vm, FunctionNode const& function_node, Optional<Id
|
|||
return value;
|
||||
}
|
||||
|
||||
inline ThrowCompletionOr<void> put_by_value(VM& vm, Value base, Optional<FlyString const&> const& base_identifier, Value property_key_value, Value value, Op::PropertyKind kind)
|
||||
inline ThrowCompletionOr<void> put_by_value(VM& vm, Value base, Optional<Utf16FlyString const&> 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<CalleeAndThis> get_callee_and_this_from_environment(Bytecode::Interpreter& interpreter, FlyString const& name, EnvironmentCoordinate& cache)
|
||||
inline ThrowCompletionOr<CalleeAndThis> get_callee_and_this_from_environment(Bytecode::Interpreter& interpreter, Utf16FlyString const& name, EnvironmentCoordinate& cache)
|
||||
{
|
||||
auto& vm = interpreter.vm();
|
||||
|
||||
|
|
@ -1583,7 +1583,7 @@ inline Span<Value> argument_list_evaluation(Interpreter& interpreter, Value argu
|
|||
return argument_values;
|
||||
}
|
||||
|
||||
inline ThrowCompletionOr<void> create_variable(VM& vm, FlyString const& name, Op::EnvironmentMode mode, bool is_global, bool is_immutable, bool is_strict)
|
||||
inline ThrowCompletionOr<void> 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<void> create_variable(VM& vm, FlyString const& name, Op
|
|||
inline ThrowCompletionOr<ECMAScriptFunctionObject*> new_class(VM& vm, Value super_class, ClassExpression const& class_expression, Optional<IdentifierTableIndex> const& lhs_name, ReadonlySpan<Value> 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<FlyString> binding_name;
|
||||
FlyString class_name;
|
||||
Optional<Utf16FlyString> 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ private:
|
|||
|
||||
JS_API extern bool g_dump_bytecode;
|
||||
|
||||
ThrowCompletionOr<GC::Ref<Bytecode::Executable>> compile(VM&, ASTNode const&, JS::FunctionKind kind, FlyString const& name);
|
||||
ThrowCompletionOr<GC::Ref<Bytecode::Executable>> compile(VM&, ASTNode const&, JS::FunctionKind kind, Utf16FlyString const& name);
|
||||
ThrowCompletionOr<GC::Ref<Bytecode::Executable>> compile(VM&, ECMAScriptFunctionObject const&);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ static ThrowCompletionOr<GC::Ref<Object>> 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);
|
||||
|
|
|
|||
|
|
@ -36,15 +36,15 @@ void $262Object::initialize(Realm& realm)
|
|||
m_is_htmldda = realm.create<IsHTMLDDA>(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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ ErrorOr<void> 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)
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ GC::Ref<Object> Module::get_module_namespace(VM& vm)
|
|||
auto exported_names = get_exported_names(vm);
|
||||
|
||||
// b. Let unambiguousNames be a new empty List.
|
||||
Vector<FlyString> unambiguous_names;
|
||||
Vector<Utf16FlyString> unambiguous_names;
|
||||
|
||||
// c. For each element name of exportedNames, do
|
||||
for (auto& name : exported_names) {
|
||||
|
|
@ -175,14 +175,14 @@ GC::Ref<Object> Module::get_module_namespace(VM& vm)
|
|||
return *namespace_;
|
||||
}
|
||||
|
||||
Vector<FlyString> Module::get_exported_names(VM& vm)
|
||||
Vector<Utf16FlyString> Module::get_exported_names(VM& vm)
|
||||
{
|
||||
HashTable<Module const*> 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<Object> Module::module_namespace_create(Vector<FlyString> unambiguous_names)
|
||||
GC::Ref<Object> Module::module_namespace_create(Vector<Utf16FlyString> unambiguous_names)
|
||||
{
|
||||
auto& realm = this->realm();
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/FlyString.h>
|
||||
#include <AK/Utf16FlyString.h>
|
||||
#include <LibGC/Ptr.h>
|
||||
#include <LibJS/Export.h>
|
||||
#include <LibJS/ModuleLoading.h>
|
||||
|
|
@ -39,7 +39,7 @@ struct ResolvedBinding {
|
|||
|
||||
Type type { Null };
|
||||
GC::Ptr<Module> module;
|
||||
FlyString export_name;
|
||||
Utf16FlyString export_name;
|
||||
|
||||
bool is_valid() const
|
||||
{
|
||||
|
|
@ -110,10 +110,10 @@ public:
|
|||
virtual ThrowCompletionOr<void> link(VM& vm) = 0;
|
||||
virtual ThrowCompletionOr<GC::Ref<Promise>> evaluate(VM& vm) = 0;
|
||||
|
||||
Vector<FlyString> get_exported_names(VM& vm);
|
||||
virtual Vector<FlyString> get_exported_names(VM& vm, HashTable<Module const*>& export_star_set) = 0;
|
||||
Vector<Utf16FlyString> get_exported_names(VM& vm);
|
||||
virtual Vector<Utf16FlyString> get_exported_names(VM& vm, HashTable<Module const*>& export_star_set) = 0;
|
||||
|
||||
virtual ResolvedBinding resolve_export(VM& vm, FlyString const& export_name, Vector<ResolvedBinding> resolve_set = {}) = 0;
|
||||
virtual ResolvedBinding resolve_export(VM& vm, Utf16FlyString const& export_name, Vector<ResolvedBinding> resolve_set = {}) = 0;
|
||||
|
||||
virtual ThrowCompletionOr<u32> inner_module_linking(VM& vm, Vector<Module*>& stack, u32 index);
|
||||
virtual ThrowCompletionOr<u32> inner_module_evaluation(VM& vm, Vector<Module*>& stack, u32 index);
|
||||
|
|
@ -131,7 +131,7 @@ protected:
|
|||
}
|
||||
|
||||
private:
|
||||
GC::Ref<Object> module_namespace_create(Vector<FlyString> unambiguous_names);
|
||||
GC::Ref<Object> module_namespace_create(Vector<Utf16FlyString> unambiguous_names);
|
||||
ThrowCompletionOr<void> evaluate_module_sync(VM&);
|
||||
|
||||
// These handles are only safe as long as the VM they live in is valid.
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ ThrowCompletionOr<Realm*> get_function_realm(VM& vm, FunctionObject const& funct
|
|||
}
|
||||
|
||||
// 8.5.2.1 InitializeBoundName ( name, value, environment ), https://tc39.es/ecma262/#sec-initializeboundname
|
||||
ThrowCompletionOr<void> initialize_bound_name(VM& vm, FlyString const& name, Value value, Environment* environment)
|
||||
ThrowCompletionOr<void> 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<void> initialize_bound_name(VM& vm, FlyString const& name, Val
|
|||
bool is_compatible_property_descriptor(bool extensible, PropertyDescriptor const& descriptor, Optional<PropertyDescriptor> 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<Value> perform_eval(VM& vm, Value x, CallerMode strict_caller,
|
|||
if (executable_result.is_error())
|
||||
return vm.throw_completion<InternalError>(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<void> 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<void> {
|
||||
TRY(program.for_each_var_declared_identifier([&](Identifier const& identifier) -> ThrowCompletionOr<void> {
|
||||
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<SyntaxError>(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<void> eval_declaration_instantiation(VM& vm, Program const& pr
|
|||
if (!is<ObjectEnvironment>(*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<void> {
|
||||
auto const& name = identifier.string();
|
||||
TRY(program.for_each_var_declared_identifier([&](Identifier const& identifier) -> ThrowCompletionOr<void> {
|
||||
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<void> eval_declaration_instantiation(VM& vm, Program const& pr
|
|||
Vector<FunctionDeclaration const&> functions_to_initialize;
|
||||
|
||||
// 9. Let declaredFunctionNames be a new empty List.
|
||||
HashTable<FlyString> declared_function_names;
|
||||
HashTable<Utf16FlyString> 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<void> {
|
||||
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<void> 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<TypeError>(ErrorType::CannotDeclareGlobalFunction, function.name());
|
||||
return vm.throw_completion<TypeError>(ErrorType::CannotDeclareGlobalFunction, function_name);
|
||||
}
|
||||
|
||||
// 2. Append fn to declaredFunctionNames.
|
||||
|
|
@ -865,12 +869,12 @@ ThrowCompletionOr<void> 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<FlyString> hoisted_functions;
|
||||
HashTable<Utf16FlyString> 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<void> {
|
||||
// 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<void> eval_declaration_instantiation(VM& vm, Program const& pr
|
|||
}
|
||||
|
||||
// 12. Let declaredVarNames be a new empty List.
|
||||
HashTable<FlyString> declared_var_names;
|
||||
HashTable<Utf16FlyString> 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<void> 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<void> {
|
||||
auto const& name = identifier.string();
|
||||
return declaration.for_each_bound_identifier([&](Identifier const& identifier) -> ThrowCompletionOr<void> {
|
||||
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<void> 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<void> {
|
||||
auto const& name = identifier.string();
|
||||
return declaration.for_each_bound_identifier([&](Identifier const& identifier) -> ThrowCompletionOr<void> {
|
||||
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<void> 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<void> 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<FlyString> seen_names;
|
||||
Vector<FlyString> mapped_names;
|
||||
HashTable<Utf16FlyString> seen_names;
|
||||
Vector<Utf16FlyString> mapped_names;
|
||||
|
||||
// 18. Set index to numberOfParameters - 1.
|
||||
// 19. Repeat, while index ≥ 0,
|
||||
VERIFY(formals->size() <= NumericLimits<i32>::max());
|
||||
for (i32 index = static_cast<i32>(formals->size()) - 1; index >= 0; --index) {
|
||||
// a. Let name be parameterNames[index].
|
||||
auto const& name = formals->parameters()[index].binding.get<NonnullRefPtr<Identifier const>>()->string();
|
||||
auto name = Utf16FlyString::from_utf8(formals->parameters()[index].binding.get<NonnullRefPtr<Identifier const>>()->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<double>(AK::TrimWhitespace::No);
|
||||
auto maybe_double = argument.to_number<double>(AK::TrimWhitespace::No);
|
||||
if (!maybe_double.has_value())
|
||||
return CanonicalIndex(CanonicalIndex::Type::Undefined, 0);
|
||||
|
||||
|
|
@ -1417,7 +1423,7 @@ ThrowCompletionOr<String> 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());
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ JS_API ThrowCompletionOr<size_t> length_of_array_like(VM&, Object const&);
|
|||
ThrowCompletionOr<GC::RootVector<Value>> create_list_from_array_like(VM&, Value, Function<ThrowCompletionOr<void>(Value)> = {});
|
||||
ThrowCompletionOr<FunctionObject*> species_constructor(VM&, Object const&, FunctionObject& default_constructor);
|
||||
JS_API ThrowCompletionOr<Realm*> get_function_realm(VM&, FunctionObject const&);
|
||||
ThrowCompletionOr<void> initialize_bound_name(VM&, FlyString const&, Value, Environment*);
|
||||
ThrowCompletionOr<void> initialize_bound_name(VM&, Utf16FlyString const&, Value, Environment*);
|
||||
bool is_compatible_property_descriptor(bool extensible, PropertyDescriptor const&, Optional<PropertyDescriptor> const& current);
|
||||
bool validate_and_apply_property_descriptor(Object*, PropertyKey const&, bool extensible, PropertyDescriptor const&, Optional<PropertyDescriptor> const& current);
|
||||
JS_API ThrowCompletionOr<Object*> get_prototype_from_constructor(VM&, FunctionObject const& constructor, GC::Ref<Object> (Intrinsics::*intrinsic_default_prototype)());
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ ThrowCompletionOr<bool> 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
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public:
|
|||
virtual ThrowCompletionOr<bool> internal_set(PropertyKey const&, Value value, Value receiver, CacheablePropertyMetadata*, PropertyLookupPhase) override;
|
||||
virtual ThrowCompletionOr<bool> internal_delete(PropertyKey const&) override;
|
||||
|
||||
void set_mapped_names(Vector<FlyString> mapped_names) { m_mapped_names = move(mapped_names); }
|
||||
void set_mapped_names(Vector<Utf16FlyString> 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<Environment> m_environment;
|
||||
Vector<FlyString> m_mapped_names;
|
||||
Vector<Utf16FlyString> m_mapped_names;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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<bool> DeclarativeEnvironment::has_binding(FlyString const& name, Optional<size_t>* out_index) const
|
||||
ThrowCompletionOr<bool> DeclarativeEnvironment::has_binding(Utf16FlyString const& name, Optional<size_t>* out_index) const
|
||||
{
|
||||
auto binding_and_index = find_binding_and_index(name);
|
||||
if (!binding_and_index.has_value())
|
||||
|
|
@ -63,7 +63,7 @@ ThrowCompletionOr<bool> 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<void> DeclarativeEnvironment::create_mutable_binding(VM&, FlyString const& name, bool can_be_deleted)
|
||||
ThrowCompletionOr<void> 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<void> 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<void> DeclarativeEnvironment::create_immutable_binding(VM&, FlyString const& name, bool strict)
|
||||
ThrowCompletionOr<void> 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<void> 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<void> DeclarativeEnvironment::initialize_binding(VM& vm, FlyString const& name, Value value, Environment::InitializeBindingHint hint)
|
||||
ThrowCompletionOr<void> 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<void> 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<void> DeclarativeEnvironment::set_mutable_binding(VM& vm, FlyString const& name, Value value, bool strict)
|
||||
ThrowCompletionOr<void> 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<void> 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<Value> DeclarativeEnvironment::get_binding_value(VM& vm, FlyString const& name, [[maybe_unused]] bool strict)
|
||||
ThrowCompletionOr<Value> 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<Value> 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<bool> DeclarativeEnvironment::delete_binding(VM&, FlyString const& name)
|
||||
ThrowCompletionOr<bool> 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<bool> DeclarativeEnvironment::delete_binding(VM&, FlyString co
|
|||
return true;
|
||||
}
|
||||
|
||||
ThrowCompletionOr<void> DeclarativeEnvironment::initialize_or_set_mutable_binding(VM& vm, FlyString const& name, Value value)
|
||||
ThrowCompletionOr<void> 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<void> DeclarativeEnvironment::initialize_or_set_mutable_bindin
|
|||
return {};
|
||||
}
|
||||
|
||||
void DeclarativeEnvironment::initialize_or_set_mutable_binding(Badge<ScopeNode>, VM& vm, FlyString const& name, Value value)
|
||||
void DeclarativeEnvironment::initialize_or_set_mutable_binding(Badge<ScopeNode>, VM& vm, Utf16FlyString const& name, Value value)
|
||||
{
|
||||
MUST(initialize_or_set_mutable_binding(vm, name, value));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/FlyString.h>
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/Utf16FlyString.h>
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/Completion.h>
|
||||
#include <LibJS/Runtime/Environment.h>
|
||||
|
|
@ -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<bool> has_binding(FlyString const& name, Optional<size_t>* = nullptr) const override final;
|
||||
virtual ThrowCompletionOr<void> create_mutable_binding(VM&, FlyString const& name, bool can_be_deleted) override final;
|
||||
virtual ThrowCompletionOr<void> create_immutable_binding(VM&, FlyString const& name, bool strict) override final;
|
||||
virtual ThrowCompletionOr<void> initialize_binding(VM&, FlyString const& name, Value, InitializeBindingHint) override final;
|
||||
virtual ThrowCompletionOr<void> set_mutable_binding(VM&, FlyString const& name, Value, bool strict) override final;
|
||||
virtual ThrowCompletionOr<Value> get_binding_value(VM&, FlyString const& name, bool strict) override;
|
||||
virtual ThrowCompletionOr<bool> delete_binding(VM&, FlyString const& name) override;
|
||||
virtual ThrowCompletionOr<bool> has_binding(Utf16FlyString const& name, Optional<size_t>* = nullptr) const override final;
|
||||
virtual ThrowCompletionOr<void> create_mutable_binding(VM&, Utf16FlyString const& name, bool can_be_deleted) override final;
|
||||
virtual ThrowCompletionOr<void> create_immutable_binding(VM&, Utf16FlyString const& name, bool strict) override final;
|
||||
virtual ThrowCompletionOr<void> initialize_binding(VM&, Utf16FlyString const& name, Value, InitializeBindingHint) override final;
|
||||
virtual ThrowCompletionOr<void> set_mutable_binding(VM&, Utf16FlyString const& name, Value, bool strict) override final;
|
||||
virtual ThrowCompletionOr<Value> get_binding_value(VM&, Utf16FlyString const& name, bool strict) override;
|
||||
virtual ThrowCompletionOr<bool> delete_binding(VM&, Utf16FlyString const& name) override;
|
||||
|
||||
void initialize_or_set_mutable_binding(Badge<ScopeNode>, VM&, FlyString const& name, Value value);
|
||||
ThrowCompletionOr<void> initialize_or_set_mutable_binding(VM&, FlyString const& name, Value value);
|
||||
void initialize_or_set_mutable_binding(Badge<ScopeNode>, VM&, Utf16FlyString const& name, Value value);
|
||||
ThrowCompletionOr<void> 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<FlyString> bindings() const
|
||||
[[nodiscard]] Vector<Utf16FlyString> bindings() const
|
||||
{
|
||||
Vector<FlyString> names;
|
||||
Vector<Utf16FlyString> names;
|
||||
names.ensure_capacity(m_bindings.size());
|
||||
|
||||
for (auto const& binding : m_bindings)
|
||||
|
|
@ -114,7 +114,7 @@ protected:
|
|||
|
||||
friend class ModuleEnvironment;
|
||||
|
||||
virtual Optional<BindingAndIndex> find_binding_and_index(FlyString const& name) const
|
||||
virtual Optional<BindingAndIndex> 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<Binding*>(&m_bindings.at(it->value)), it->value };
|
||||
|
|
@ -125,7 +125,7 @@ protected:
|
|||
|
||||
private:
|
||||
Vector<Binding> m_bindings;
|
||||
HashMap<FlyString, size_t> m_bindings_assoc;
|
||||
HashMap<Utf16FlyString, size_t> m_bindings_assoc;
|
||||
DisposeCapability m_dispose_capability;
|
||||
|
||||
u64 m_environment_serial_number { 0 };
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ namespace JS {
|
|||
|
||||
GC_DEFINE_ALLOCATOR(ECMAScriptFunctionObject);
|
||||
|
||||
GC::Ref<ECMAScriptFunctionObject> ECMAScriptFunctionObject::create(Realm& realm, FlyString name, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, Vector<LocalVariable> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, FunctionParsingInsights parsing_insights, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
|
||||
GC::Ref<ECMAScriptFunctionObject> ECMAScriptFunctionObject::create(Realm& realm, Utf16FlyString name, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, Vector<LocalVariable> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, FunctionParsingInsights parsing_insights, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
|
||||
{
|
||||
Object* prototype = nullptr;
|
||||
switch (kind) {
|
||||
|
|
@ -73,7 +73,7 @@ GC::Ref<ECMAScriptFunctionObject> ECMAScriptFunctionObject::create(Realm& realm,
|
|||
*prototype);
|
||||
}
|
||||
|
||||
GC::Ref<ECMAScriptFunctionObject> ECMAScriptFunctionObject::create(Realm& realm, FlyString name, Object& prototype, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, Vector<LocalVariable> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, FunctionParsingInsights parsing_insights, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
|
||||
GC::Ref<ECMAScriptFunctionObject> ECMAScriptFunctionObject::create(Realm& realm, Utf16FlyString name, Object& prototype, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, Vector<LocalVariable> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, FunctionParsingInsights parsing_insights, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
|
||||
{
|
||||
auto shared_data = adopt_ref(*new SharedFunctionInstanceData(
|
||||
realm.vm(),
|
||||
|
|
@ -97,7 +97,7 @@ GC::Ref<ECMAScriptFunctionObject> ECMAScriptFunctionObject::create(Realm& realm,
|
|||
|
||||
GC::Ref<ECMAScriptFunctionObject> ECMAScriptFunctionObject::create_from_function_node(
|
||||
FunctionNode const& function_node,
|
||||
FlyString name,
|
||||
Utf16FlyString name,
|
||||
GC::Ref<Realm> realm,
|
||||
GC::Ptr<Environment> parent_environment,
|
||||
GC::Ptr<PrivateEnvironment> private_environment)
|
||||
|
|
@ -145,7 +145,7 @@ GC::Ref<ECMAScriptFunctionObject> ECMAScriptFunctionObject::create_from_function
|
|||
SharedFunctionInstanceData::SharedFunctionInstanceData(
|
||||
VM& vm,
|
||||
FunctionKind kind,
|
||||
FlyString name,
|
||||
Utf16FlyString name,
|
||||
i32 function_length,
|
||||
NonnullRefPtr<FunctionParameters const> formal_parameters,
|
||||
NonnullRefPtr<Statement const> 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<FlyString> function_names;
|
||||
HashTable<Utf16FlyString> 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<FlyString, ParameterIsLocal> parameter_bindings;
|
||||
HashMap<Utf16FlyString, ParameterIsLocal> 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<FlyString, ParameterIsLocal> instantiated_var_names;
|
||||
HashMap<Utf16FlyString, ParameterIsLocal> 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<Value> {
|
||||
auto closure = NativeFunction::create(realm, {}, [&async_body, &promise_capability](auto& vm) -> ThrowCompletionOr<Value> {
|
||||
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<T, GC::Function<Completion()>>) {
|
||||
// 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<Value> 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<SharedFunctionInstanceData&>(shared_data()).m_name = name;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public:
|
|||
SharedFunctionInstanceData(
|
||||
VM& vm,
|
||||
FunctionKind,
|
||||
FlyString name,
|
||||
Utf16FlyString name,
|
||||
i32 function_length,
|
||||
NonnullRefPtr<FunctionParameters const>,
|
||||
NonnullRefPtr<Statement const> ecmascript_code,
|
||||
|
|
@ -52,7 +52,7 @@ public:
|
|||
RefPtr<FunctionParameters const> m_formal_parameters; // [[FormalParameters]]
|
||||
RefPtr<Statement const> m_ecmascript_code; // [[ECMAScriptCode]]
|
||||
|
||||
FlyString m_name;
|
||||
Utf16FlyString m_name;
|
||||
ByteString m_source_text; // [[SourceText]]
|
||||
|
||||
Vector<LocalVariable> m_local_variables_names;
|
||||
|
|
@ -81,13 +81,13 @@ public:
|
|||
No,
|
||||
Yes,
|
||||
};
|
||||
HashMap<FlyString, ParameterIsLocal> m_parameter_names;
|
||||
HashMap<Utf16FlyString, ParameterIsLocal> m_parameter_names;
|
||||
Vector<FunctionDeclaration const&> m_functions_to_initialize;
|
||||
bool m_arguments_object_needed { false };
|
||||
bool m_function_environment_needed { false };
|
||||
bool m_uses_this { false };
|
||||
Vector<VariableNameToInitialize> m_var_names_to_initialize_binding;
|
||||
Vector<FlyString> m_function_names_to_initialize_binding;
|
||||
Vector<Utf16FlyString> 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<ECMAScriptFunctionObject> create(Realm&, FlyString name, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, Vector<LocalVariable> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, FunctionParsingInsights, bool is_arrow_function = false, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name = {});
|
||||
static GC::Ref<ECMAScriptFunctionObject> create(Realm&, FlyString name, Object& prototype, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, Vector<LocalVariable> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, FunctionParsingInsights, bool is_arrow_function = false, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name = {});
|
||||
static GC::Ref<ECMAScriptFunctionObject> create(Realm&, Utf16FlyString name, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, Vector<LocalVariable> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, FunctionParsingInsights, bool is_arrow_function = false, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name = {});
|
||||
static GC::Ref<ECMAScriptFunctionObject> create(Realm&, Utf16FlyString name, Object& prototype, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, Vector<LocalVariable> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, FunctionParsingInsights, bool is_arrow_function = false, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name = {});
|
||||
|
||||
[[nodiscard]] static GC::Ref<ECMAScriptFunctionObject> create_from_function_node(
|
||||
FunctionNode const&,
|
||||
FlyString name,
|
||||
Utf16FlyString name,
|
||||
GC::Ref<Realm>,
|
||||
GC::Ptr<Environment> parent_environment,
|
||||
GC::Ptr<PrivateEnvironment>);
|
||||
|
|
@ -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<SharedFunctionInstanceData&>(shared_data()).m_is_class_constructor = true; }
|
||||
|
||||
|
|
|
|||
|
|
@ -35,13 +35,13 @@ public:
|
|||
|
||||
virtual Object* with_base_object() const { return nullptr; }
|
||||
|
||||
virtual ThrowCompletionOr<bool> has_binding([[maybe_unused]] FlyString const& name, [[maybe_unused]] Optional<size_t>* out_index = nullptr) const = 0;
|
||||
virtual ThrowCompletionOr<void> create_mutable_binding(VM&, [[maybe_unused]] FlyString const& name, [[maybe_unused]] bool can_be_deleted) = 0;
|
||||
virtual ThrowCompletionOr<void> create_immutable_binding(VM&, [[maybe_unused]] FlyString const& name, [[maybe_unused]] bool strict) = 0;
|
||||
virtual ThrowCompletionOr<void> initialize_binding(VM&, [[maybe_unused]] FlyString const& name, Value, InitializeBindingHint) = 0;
|
||||
virtual ThrowCompletionOr<void> set_mutable_binding(VM&, [[maybe_unused]] FlyString const& name, Value, [[maybe_unused]] bool strict) = 0;
|
||||
virtual ThrowCompletionOr<Value> get_binding_value(VM&, [[maybe_unused]] FlyString const& name, [[maybe_unused]] bool strict) = 0;
|
||||
virtual ThrowCompletionOr<bool> delete_binding(VM&, [[maybe_unused]] FlyString const& name) = 0;
|
||||
virtual ThrowCompletionOr<bool> has_binding([[maybe_unused]] Utf16FlyString const& name, [[maybe_unused]] Optional<size_t>* out_index = nullptr) const = 0;
|
||||
virtual ThrowCompletionOr<void> create_mutable_binding(VM&, [[maybe_unused]] Utf16FlyString const& name, [[maybe_unused]] bool can_be_deleted) = 0;
|
||||
virtual ThrowCompletionOr<void> create_immutable_binding(VM&, [[maybe_unused]] Utf16FlyString const& name, [[maybe_unused]] bool strict) = 0;
|
||||
virtual ThrowCompletionOr<void> initialize_binding(VM&, [[maybe_unused]] Utf16FlyString const& name, Value, InitializeBindingHint) = 0;
|
||||
virtual ThrowCompletionOr<void> set_mutable_binding(VM&, [[maybe_unused]] Utf16FlyString const& name, Value, [[maybe_unused]] bool strict) = 0;
|
||||
virtual ThrowCompletionOr<Value> get_binding_value(VM&, [[maybe_unused]] Utf16FlyString const& name, [[maybe_unused]] bool strict) = 0;
|
||||
virtual ThrowCompletionOr<bool> delete_binding(VM&, [[maybe_unused]] Utf16FlyString const& name) = 0;
|
||||
|
||||
// [[OuterEnv]]
|
||||
Environment* outer_environment() { return m_outer_environment; }
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/FlyString.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibJS/Export.h>
|
||||
#include <LibJS/Runtime/Completion.h>
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ ThrowCompletionOr<GC::Ref<ECMAScriptFunctionObject>> 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").
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ GC::Ref<PrimitiveString> FunctionObject::make_function_name(Variant<PropertyKey,
|
|||
{
|
||||
auto& vm = this->vm();
|
||||
|
||||
String name;
|
||||
Utf16String name;
|
||||
|
||||
// 2. If Type(name) is Symbol, then
|
||||
if (auto const* property_key = name_arg.get_pointer<PropertyKey>(); property_key && property_key->is_symbol()) {
|
||||
|
|
@ -37,15 +37,15 @@ GC::Ref<PrimitiveString> FunctionObject::make_function_name(Variant<PropertyKey,
|
|||
|
||||
// b. If description is undefined, set name to the empty String.
|
||||
if (!description.has_value())
|
||||
name = ""_string;
|
||||
name = {};
|
||||
// c. Else, set name to the string-concatenation of "[", description, and "]".
|
||||
else
|
||||
name = MUST(String::formatted("[{}]", *description));
|
||||
name = Utf16String::formatted("[{}]", *description);
|
||||
}
|
||||
// 3. Else if name is a Private Name, then
|
||||
else if (auto const* private_name = name_arg.get_pointer<PrivateName>()) {
|
||||
// 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<PrimitiveString> FunctionObject::make_function_name(Variant<PropertyKey,
|
|||
// 5. If prefix is present, then
|
||||
if (prefix.has_value()) {
|
||||
// a. Set name to the string-concatenation of prefix, the code unit 0x0020 (SPACE), and name.
|
||||
name = MUST(String::formatted("{} {}", *prefix, name));
|
||||
name = Utf16String::formatted("{} {}", *prefix, name);
|
||||
|
||||
// b. If F has an [[InitialName]] internal slot, then
|
||||
if (is<NativeFunction>(this)) {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ ThrowCompletionOr<Value> GlobalEnvironment::get_this_binding(VM&) const
|
|||
}
|
||||
|
||||
// 9.1.1.4.1 HasBinding ( N ), https://tc39.es/ecma262/#sec-global-environment-records-hasbinding-n
|
||||
ThrowCompletionOr<bool> GlobalEnvironment::has_binding(FlyString const& name, Optional<size_t>*) const
|
||||
ThrowCompletionOr<bool> GlobalEnvironment::has_binding(Utf16FlyString const& name, Optional<size_t>*) const
|
||||
{
|
||||
// 1. Let DclRec be envRec.[[DeclarativeRecord]].
|
||||
// 2. If ! DclRec.HasBinding(N) is true, return true.
|
||||
|
|
@ -54,7 +54,7 @@ ThrowCompletionOr<bool> 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<void> GlobalEnvironment::create_mutable_binding(VM& vm, FlyString const& name, bool can_be_deleted)
|
||||
ThrowCompletionOr<void> 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<void> 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<void> GlobalEnvironment::create_immutable_binding(VM& vm, FlyString const& name, bool strict)
|
||||
ThrowCompletionOr<void> 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<void> 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<void> GlobalEnvironment::initialize_binding(VM& vm, FlyString const& name, Value value, InitializeBindingHint hint)
|
||||
ThrowCompletionOr<void> 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<void> 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<void> GlobalEnvironment::set_mutable_binding(VM& vm, FlyString const& name, Value value, bool strict)
|
||||
ThrowCompletionOr<void> 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<void> 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<Value> GlobalEnvironment::get_binding_value(VM& vm, FlyString const& name, bool strict)
|
||||
ThrowCompletionOr<Value> 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<Value> 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<bool> GlobalEnvironment::delete_binding(VM& vm, FlyString const& name)
|
||||
ThrowCompletionOr<bool> 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<bool> 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<bool> GlobalEnvironment::has_restricted_global_property(FlyString const& name) const
|
||||
ThrowCompletionOr<bool> 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<bool> GlobalEnvironment::has_restricted_global_property(FlyStr
|
|||
}
|
||||
|
||||
// 9.1.1.4.14 CanDeclareGlobalVar ( envRec, N ), https://tc39.es/ecma262/#sec-candeclareglobalvar
|
||||
ThrowCompletionOr<bool> GlobalEnvironment::can_declare_global_var(FlyString const& name) const
|
||||
ThrowCompletionOr<bool> 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<bool> GlobalEnvironment::can_declare_global_var(FlyString cons
|
|||
}
|
||||
|
||||
// 9.1.1.4.15 CanDeclareGlobalFunction ( envRec, N ), https://tc39.es/ecma262/#sec-candeclareglobalfunction
|
||||
ThrowCompletionOr<bool> GlobalEnvironment::can_declare_global_function(FlyString const& name) const
|
||||
ThrowCompletionOr<bool> 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<bool> GlobalEnvironment::can_declare_global_function(FlyString
|
|||
}
|
||||
|
||||
// 9.1.1.4.16 CreateGlobalVarBinding ( envRec, N, D ), https://tc39.es/ecma262/#sec-createglobalvarbinding
|
||||
ThrowCompletionOr<void> GlobalEnvironment::create_global_var_binding(FlyString const& name, bool can_be_deleted)
|
||||
ThrowCompletionOr<void> GlobalEnvironment::create_global_var_binding(Utf16FlyString const& name, bool can_be_deleted)
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
|
||||
|
|
@ -257,7 +257,7 @@ ThrowCompletionOr<void> GlobalEnvironment::create_global_var_binding(FlyString c
|
|||
}
|
||||
|
||||
// 9.1.1.4.17 CreateGlobalFunctionBinding ( envRec, N, V, D ), https://tc39.es/ecma262/#sec-createglobalfunctionbinding
|
||||
ThrowCompletionOr<void> GlobalEnvironment::create_global_function_binding(FlyString const& name, Value value, bool can_be_deleted)
|
||||
ThrowCompletionOr<void> 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]].
|
||||
|
|
|
|||
|
|
@ -19,24 +19,24 @@ public:
|
|||
virtual bool has_this_binding() const final { return true; }
|
||||
virtual ThrowCompletionOr<Value> get_this_binding(VM&) const final;
|
||||
|
||||
virtual ThrowCompletionOr<bool> has_binding(FlyString const& name, Optional<size_t>* = nullptr) const override;
|
||||
virtual ThrowCompletionOr<void> create_mutable_binding(VM&, FlyString const& name, bool can_be_deleted) override;
|
||||
virtual ThrowCompletionOr<void> create_immutable_binding(VM&, FlyString const& name, bool strict) override;
|
||||
virtual ThrowCompletionOr<void> initialize_binding(VM&, FlyString const& name, Value, Environment::InitializeBindingHint) override;
|
||||
virtual ThrowCompletionOr<void> set_mutable_binding(VM&, FlyString const& name, Value, bool strict) override;
|
||||
virtual ThrowCompletionOr<Value> get_binding_value(VM&, FlyString const& name, bool strict) override;
|
||||
virtual ThrowCompletionOr<bool> delete_binding(VM&, FlyString const& name) override;
|
||||
virtual ThrowCompletionOr<bool> has_binding(Utf16FlyString const& name, Optional<size_t>* = nullptr) const override;
|
||||
virtual ThrowCompletionOr<void> create_mutable_binding(VM&, Utf16FlyString const& name, bool can_be_deleted) override;
|
||||
virtual ThrowCompletionOr<void> create_immutable_binding(VM&, Utf16FlyString const& name, bool strict) override;
|
||||
virtual ThrowCompletionOr<void> initialize_binding(VM&, Utf16FlyString const& name, Value, Environment::InitializeBindingHint) override;
|
||||
virtual ThrowCompletionOr<void> set_mutable_binding(VM&, Utf16FlyString const& name, Value, bool strict) override;
|
||||
virtual ThrowCompletionOr<Value> get_binding_value(VM&, Utf16FlyString const& name, bool strict) override;
|
||||
virtual ThrowCompletionOr<bool> 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<bool> has_restricted_global_property(FlyString const& name) const;
|
||||
ThrowCompletionOr<bool> can_declare_global_var(FlyString const& name) const;
|
||||
ThrowCompletionOr<bool> can_declare_global_function(FlyString const& name) const;
|
||||
ThrowCompletionOr<void> create_global_var_binding(FlyString const& name, bool can_be_deleted);
|
||||
ThrowCompletionOr<void> create_global_function_binding(FlyString const& name, Value, bool can_be_deleted);
|
||||
bool has_lexical_declaration(Utf16FlyString const& name) const;
|
||||
ThrowCompletionOr<bool> has_restricted_global_property(Utf16FlyString const& name) const;
|
||||
ThrowCompletionOr<bool> can_declare_global_var(Utf16FlyString const& name) const;
|
||||
ThrowCompletionOr<bool> can_declare_global_function(Utf16FlyString const& name) const;
|
||||
ThrowCompletionOr<void> create_global_var_binding(Utf16FlyString const& name, bool can_be_deleted);
|
||||
ThrowCompletionOr<void> create_global_function_binding(Utf16FlyString const& name, Value, bool can_be_deleted);
|
||||
|
||||
private:
|
||||
GlobalEnvironment(Object&, Object& this_value);
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ static GC::Ref<ListFormat> 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<void> validate_duration_unit_style(VM& vm, PropertyKey const& unit, DurationFormat::ValueStyle style, DurationFormat::Display display, Optional<DurationFormat::ValueStyle> previous_style, StringView display_field)
|
||||
static ThrowCompletionOr<void> validate_duration_unit_style(VM& vm, PropertyKey const& unit, DurationFormat::ValueStyle style, DurationFormat::Display display, Optional<DurationFormat::ValueStyle> 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<DurationFormat::DurationUnitOptions> 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<DurationFormatPart> 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.
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ static constexpr auto duration_instances_components = to_array<DurationInstanceC
|
|||
struct DurationFormatPart {
|
||||
StringView type;
|
||||
Utf16String value;
|
||||
StringView unit;
|
||||
Utf16View unit;
|
||||
};
|
||||
|
||||
ThrowCompletionOr<DurationFormat::DurationUnitOptions> get_duration_unit_options(VM&, DurationFormat::Unit unit, Object const& options, DurationFormat::Style base_style, ReadonlySpan<StringView> styles_list, DurationFormat::ValueStyle digital_base, Optional<DurationFormat::ValueStyle> previous_style, bool two_digit_hours);
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ void Intrinsics::initialize_intrinsics(Realm& realm)
|
|||
realm, [](VM& vm) {
|
||||
return vm.throw_completion<TypeError>(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());
|
||||
|
|
|
|||
|
|
@ -64,24 +64,24 @@ ThrowCompletionOr<Optional<String>> 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<String> list;
|
||||
Vector<Utf16String> list;
|
||||
for (size_t i = 0; i < replacer_length; ++i) {
|
||||
auto replacer_value = TRY(replacer_object.get(i));
|
||||
Optional<String> item;
|
||||
Optional<Utf16String> 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<StringObject>(value_object) || is<NumberObject>(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<Optional<String>> 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<Optional<String>> 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<String> 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<String> 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<Value> 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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,14 +34,14 @@ private:
|
|||
HashTable<GC::Ptr<Object>> seen_objects;
|
||||
String indent;
|
||||
String gap;
|
||||
Optional<Vector<String>> property_list;
|
||||
Optional<Vector<Utf16String>> property_list;
|
||||
};
|
||||
|
||||
// Stringify helpers
|
||||
static ThrowCompletionOr<Optional<String>> serialize_json_property(VM&, StringifyState&, PropertyKey const& key, Object* holder);
|
||||
static ThrowCompletionOr<String> serialize_json_object(VM&, StringifyState&, Object&);
|
||||
static ThrowCompletionOr<String> 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&);
|
||||
|
|
|
|||
|
|
@ -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<Value> ModuleEnvironment::get_binding_value(VM& vm, FlyString const& name, bool strict)
|
||||
ThrowCompletionOr<Value> ModuleEnvironment::get_binding_value(VM& vm, Utf16FlyString const& name, bool strict)
|
||||
{
|
||||
// 1. Assert: S is true.
|
||||
VERIFY(strict);
|
||||
|
|
@ -51,7 +51,7 @@ ThrowCompletionOr<Value> 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<bool> ModuleEnvironment::delete_binding(VM&, FlyString const&)
|
||||
ThrowCompletionOr<bool> 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<Value> ModuleEnvironment::get_this_binding(VM&) const
|
|||
}
|
||||
|
||||
// 9.1.1.5.5 CreateImportBinding ( N, M, N2 ), https://tc39.es/ecma262/#sec-createimportbinding
|
||||
ThrowCompletionOr<void> ModuleEnvironment::create_import_binding(FlyString name, Module* module, FlyString binding_name)
|
||||
ThrowCompletionOr<void> 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<void> 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::BindingAndIndex> ModuleEnvironment::find_binding_and_index(FlyString const& name) const
|
||||
Optional<ModuleEnvironment::BindingAndIndex> ModuleEnvironment::find_binding_and_index(Utf16FlyString const& name) const
|
||||
{
|
||||
auto* indirect_binding = get_indirect_binding(name);
|
||||
if (indirect_binding != nullptr) {
|
||||
|
|
|
|||
|
|
@ -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<Value> get_binding_value(VM&, FlyString const& name, bool strict) override;
|
||||
virtual ThrowCompletionOr<bool> delete_binding(VM&, FlyString const& name) override;
|
||||
virtual ThrowCompletionOr<Value> get_binding_value(VM&, Utf16FlyString const& name, bool strict) override;
|
||||
virtual ThrowCompletionOr<bool> delete_binding(VM&, Utf16FlyString const& name) override;
|
||||
virtual bool has_this_binding() const final { return true; }
|
||||
virtual ThrowCompletionOr<Value> get_this_binding(VM&) const final;
|
||||
ThrowCompletionOr<void> create_import_binding(FlyString name, Module* module, FlyString binding_name);
|
||||
ThrowCompletionOr<void> 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> 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<BindingAndIndex> find_binding_and_index(FlyString const& name) const override;
|
||||
virtual Optional<BindingAndIndex> find_binding_and_index(Utf16FlyString const& name) const override;
|
||||
|
||||
// FIXME: Since we always access this via the name this could be a map.
|
||||
Vector<IndirectBinding> m_indirect_bindings;
|
||||
|
|
|
|||
|
|
@ -13,16 +13,14 @@ namespace JS {
|
|||
|
||||
GC_DEFINE_ALLOCATOR(ModuleNamespaceObject);
|
||||
|
||||
ModuleNamespaceObject::ModuleNamespaceObject(Realm& realm, Module* module, Vector<FlyString> exports)
|
||||
ModuleNamespaceObject::ModuleNamespaceObject(Realm& realm, Module* module, Vector<Utf16FlyString> 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)
|
||||
|
|
|
|||
|
|
@ -33,12 +33,12 @@ public:
|
|||
virtual void initialize(Realm&) override;
|
||||
|
||||
private:
|
||||
ModuleNamespaceObject(Realm&, Module* module, Vector<FlyString> exports);
|
||||
ModuleNamespaceObject(Realm&, Module* module, Vector<Utf16FlyString> exports);
|
||||
|
||||
virtual void visit_edges(Visitor&) override;
|
||||
|
||||
GC::Ptr<Module> m_module; // [[Module]]
|
||||
Vector<FlyString> m_exports; // [[Exports]]
|
||||
GC::Ptr<Module> m_module; // [[Module]]
|
||||
Vector<Utf16FlyString> m_exports; // [[Exports]]
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ GC::Ref<NativeFunction> NativeFunction::create(Realm& allocating_realm, Function
|
|||
return function;
|
||||
}
|
||||
|
||||
GC::Ref<NativeFunction> NativeFunction::create(Realm& realm, FlyString const& name, Function<ThrowCompletionOr<Value>(VM&)> function)
|
||||
GC::Ref<NativeFunction> NativeFunction::create(Realm& realm, Utf16FlyString const& name, Function<ThrowCompletionOr<Value>(VM&)> function)
|
||||
{
|
||||
return realm.create<NativeFunction>(name, move(function), realm.intrinsics().function_prototype());
|
||||
}
|
||||
|
|
@ -91,7 +91,7 @@ NativeFunction::NativeFunction(Object& prototype)
|
|||
{
|
||||
}
|
||||
|
||||
NativeFunction::NativeFunction(FlyString name, AK::Function<ThrowCompletionOr<Value>(VM&)> native_function, Object& prototype)
|
||||
NativeFunction::NativeFunction(Utf16FlyString name, AK::Function<ThrowCompletionOr<Value>(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<ThrowCompletionOr<Va
|
|||
{
|
||||
}
|
||||
|
||||
NativeFunction::NativeFunction(FlyString name, Object& prototype)
|
||||
NativeFunction::NativeFunction(Utf16FlyString name, Object& prototype)
|
||||
: FunctionObject(prototype)
|
||||
, m_name(move(name))
|
||||
, m_realm(&prototype.shape().realm())
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ class JS_API NativeFunction : public FunctionObject {
|
|||
GC_DECLARE_ALLOCATOR(NativeFunction);
|
||||
|
||||
public:
|
||||
static GC::Ref<NativeFunction> create(Realm&, ESCAPING Function<ThrowCompletionOr<Value>(VM&)> behaviour, i32 length, PropertyKey const& name = FlyString {}, Optional<Realm*> = {}, Optional<StringView> const& prefix = {}, Optional<Bytecode::Builtin> builtin = {});
|
||||
static GC::Ref<NativeFunction> create(Realm&, FlyString const& name, ESCAPING Function<ThrowCompletionOr<Value>(VM&)>);
|
||||
static GC::Ref<NativeFunction> create(Realm&, ESCAPING Function<ThrowCompletionOr<Value>(VM&)> behaviour, i32 length, PropertyKey const& name = Utf16FlyString {}, Optional<Realm*> = {}, Optional<StringView> const& prefix = {}, Optional<Bytecode::Builtin> builtin = {});
|
||||
static GC::Ref<NativeFunction> create(Realm&, Utf16FlyString const& name, ESCAPING Function<ThrowCompletionOr<Value>(VM&)>);
|
||||
|
||||
virtual ~NativeFunction() override = default;
|
||||
|
||||
|
|
@ -36,13 +36,13 @@ public:
|
|||
virtual ThrowCompletionOr<Value> call();
|
||||
virtual ThrowCompletionOr<GC::Ref<Object>> 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<FlyString> const& initial_name() const { return m_initial_name; }
|
||||
void set_initial_name(Badge<FunctionObject>, FlyString initial_name) { m_initial_name = move(initial_name); }
|
||||
Optional<Utf16FlyString> const& initial_name() const { return m_initial_name; }
|
||||
void set_initial_name(Badge<FunctionObject>, 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<ThrowCompletionOr<Value>(VM&)>, Object* prototype, Realm& realm, Optional<Bytecode::Builtin> builtin);
|
||||
NativeFunction(FlyString name, AK::Function<ThrowCompletionOr<Value>(VM&)>, Object& prototype);
|
||||
NativeFunction(Utf16FlyString name, AK::Function<ThrowCompletionOr<Value>(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<PrimitiveString> m_name_string;
|
||||
Optional<FlyString> m_initial_name; // [[InitialName]]
|
||||
Optional<Utf16FlyString> m_initial_name; // [[InitialName]]
|
||||
Optional<Bytecode::Builtin> m_builtin;
|
||||
AK::Function<ThrowCompletionOr<Value>(VM&)> m_native_function;
|
||||
GC::Ptr<Realm> m_realm;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ namespace JS {
|
|||
|
||||
GC_DEFINE_ALLOCATOR(Object);
|
||||
|
||||
static HashMap<GC::Ptr<Object const>, HashMap<FlyString, Object::IntrinsicAccessor>> s_intrinsics;
|
||||
static HashMap<GC::Ptr<Object const>, HashMap<Utf16FlyString, Object::IntrinsicAccessor>> s_intrinsics;
|
||||
|
||||
// 10.1.12 OrdinaryObjectCreate ( proto [ , additionalInternalSlotsList ] ), https://tc39.es/ecma262/#sec-ordinaryobjectcreate
|
||||
GC::Ref<Object> Object::create(Realm& realm, Object* prototype)
|
||||
|
|
@ -1407,7 +1407,7 @@ Optional<Completion> Object::enumerate_object_properties(Function<Optional<Compl
|
|||
// * Enumerating the properties of the target object includes enumerating properties of its prototype, and the prototype of the prototype, and so on, recursively.
|
||||
// * A property of a prototype is not processed if it has the same name as a property that has already been processed.
|
||||
|
||||
HashTable<FlyString> visited;
|
||||
HashTable<Utf16FlyString> visited;
|
||||
|
||||
auto const* target = this;
|
||||
while (target) {
|
||||
|
|
@ -1415,7 +1415,7 @@ Optional<Completion> Object::enumerate_object_properties(Function<Optional<Compl
|
|||
for (auto& key : own_keys) {
|
||||
if (!key.is_string())
|
||||
continue;
|
||||
FlyString property_key = key.as_string().utf8_string();
|
||||
Utf16FlyString property_key = key.as_string().utf16_string();
|
||||
if (visited.contains(property_key))
|
||||
continue;
|
||||
auto descriptor = TRY(target->internal_get_own_property(property_key));
|
||||
|
|
|
|||
|
|
@ -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<bool> ObjectEnvironment::has_binding(FlyString const& name, Optional<size_t>*) const
|
||||
ThrowCompletionOr<bool> ObjectEnvironment::has_binding(Utf16FlyString const& name, Optional<size_t>*) const
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ ThrowCompletionOr<bool> 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<void> ObjectEnvironment::create_mutable_binding(VM&, FlyString const& name, bool can_be_deleted)
|
||||
ThrowCompletionOr<void> 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<void> 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<void> ObjectEnvironment::create_immutable_binding(VM&, FlyString const&, bool)
|
||||
ThrowCompletionOr<void> 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<void> ObjectEnvironment::initialize_binding(VM& vm, FlyString const& name, Value value, Environment::InitializeBindingHint hint)
|
||||
ThrowCompletionOr<void> 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<void> 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<void> ObjectEnvironment::set_mutable_binding(VM&, FlyString const& name, Value value, bool strict)
|
||||
ThrowCompletionOr<void> ObjectEnvironment::set_mutable_binding(VM&, Utf16FlyString const& name, Value value, bool strict)
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
|
||||
|
|
@ -135,7 +135,7 @@ ThrowCompletionOr<void> 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<Value> ObjectEnvironment::get_binding_value(VM&, FlyString const& name, bool strict)
|
||||
ThrowCompletionOr<Value> ObjectEnvironment::get_binding_value(VM&, Utf16FlyString const& name, bool strict)
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
|
||||
|
|
@ -164,7 +164,7 @@ ThrowCompletionOr<Value> 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<bool> ObjectEnvironment::delete_binding(VM&, FlyString const& name)
|
||||
ThrowCompletionOr<bool> ObjectEnvironment::delete_binding(VM&, Utf16FlyString const& name)
|
||||
{
|
||||
// 1. Let bindingObject be envRec.[[BindingObject]].
|
||||
// 2. Return ? bindingObject.[[Delete]](N).
|
||||
|
|
|
|||
|
|
@ -20,13 +20,13 @@ public:
|
|||
Yes,
|
||||
};
|
||||
|
||||
virtual ThrowCompletionOr<bool> has_binding(FlyString const& name, Optional<size_t>* = nullptr) const override;
|
||||
virtual ThrowCompletionOr<void> create_mutable_binding(VM&, FlyString const& name, bool can_be_deleted) override;
|
||||
virtual ThrowCompletionOr<void> create_immutable_binding(VM&, FlyString const& name, bool strict) override;
|
||||
virtual ThrowCompletionOr<void> initialize_binding(VM&, FlyString const& name, Value, Environment::InitializeBindingHint) override;
|
||||
virtual ThrowCompletionOr<void> set_mutable_binding(VM&, FlyString const& name, Value, bool strict) override;
|
||||
virtual ThrowCompletionOr<Value> get_binding_value(VM&, FlyString const& name, bool strict) override;
|
||||
virtual ThrowCompletionOr<bool> delete_binding(VM&, FlyString const& name) override;
|
||||
virtual ThrowCompletionOr<bool> has_binding(Utf16FlyString const& name, Optional<size_t>* = nullptr) const override;
|
||||
virtual ThrowCompletionOr<void> create_mutable_binding(VM&, Utf16FlyString const& name, bool can_be_deleted) override;
|
||||
virtual ThrowCompletionOr<void> create_immutable_binding(VM&, Utf16FlyString const& name, bool strict) override;
|
||||
virtual ThrowCompletionOr<void> initialize_binding(VM&, Utf16FlyString const& name, Value, Environment::InitializeBindingHint) override;
|
||||
virtual ThrowCompletionOr<void> set_mutable_binding(VM&, Utf16FlyString const& name, Value, bool strict) override;
|
||||
virtual ThrowCompletionOr<Value> get_binding_value(VM&, Utf16FlyString const& name, bool strict) override;
|
||||
virtual ThrowCompletionOr<bool> 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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/FlyString.h>
|
||||
#include <AK/StringView.h>
|
||||
#include <AK/Utf16FlyString.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibGC/CellAllocator.h>
|
||||
#include <LibJS/Heap/Cell.h>
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/FlyString.h>
|
||||
#include <AK/Utf16FlyString.h>
|
||||
#include <LibJS/Runtime/Completion.h>
|
||||
#include <LibJS/Runtime/PrimitiveString.h>
|
||||
#include <LibJS/Runtime/Symbol.h>
|
||||
|
|
@ -28,7 +28,7 @@ public:
|
|||
return PropertyKey { value.as_symbol() };
|
||||
if (value.is_integral_number() && value.as_double() >= 0 && value.as_double() < NumericLimits<u32>::max())
|
||||
return static_cast<u32>(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<T>::max() >= NumericLimits<u32>::max()) {
|
||||
if (index >= NumericLimits<u32>::max()) {
|
||||
new (&m_string) FlyString { String::number(index) };
|
||||
new (&m_string) Utf16FlyString { Utf16String::number(index) };
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_number = static_cast<u64>(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<u32>(TrimWhitespace::No);
|
||||
if (!string.is_empty() && !(string.code_unit_at(0) == '0' && string.length_in_code_units() > 1)) {
|
||||
auto property_index = string.to_number<u32>(TrimWhitespace::No);
|
||||
if (property_index.has_value() && property_index.value() < NumericLimits<u32>::max()) {
|
||||
m_number = static_cast<u64>(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<PropertyKey>;
|
||||
|
||||
union {
|
||||
FlyString m_string;
|
||||
Utf16FlyString m_string;
|
||||
u64 m_number;
|
||||
Symbol const* m_symbol;
|
||||
uintptr_t m_bits;
|
||||
|
|
@ -220,12 +220,12 @@ struct Traits<JS::PropertyKey> : public DefaultTraits<JS::PropertyKey> {
|
|||
};
|
||||
|
||||
template<>
|
||||
struct Formatter<JS::PropertyKey> : Formatter<StringView> {
|
||||
struct Formatter<JS::PropertyKey> : Formatter<Utf16String> {
|
||||
ErrorOr<void> 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<Utf16String>::format(builder, property_key.to_string());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ ThrowCompletionOr<void> 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;
|
||||
|
|
|
|||
|
|
@ -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<EnvironmentCoordinate> environment_coordinate = {})
|
||||
Reference(Environment& base, Utf16FlyString referenced_name, bool strict = false, Optional<EnvironmentCoordinate> environment_coordinate = {})
|
||||
: m_base_type(BaseType::Environment)
|
||||
, m_base_environment(&base)
|
||||
, m_name(move(referenced_name))
|
||||
|
|
|
|||
|
|
@ -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<Optional<Match>> const& indices, HashMap<FlyString, Match> const& group_names, bool has_groups)
|
||||
static Value make_match_indices_index_pair_array(VM& vm, Utf16View const& string, Vector<Optional<Match>> const& indices, HashMap<Utf16FlyString, Match> const& group_names, bool has_groups)
|
||||
{
|
||||
// Note: This implementation differs from the spec, but has the same behavior.
|
||||
//
|
||||
|
|
@ -277,7 +277,7 @@ static ThrowCompletionOr<Value> regexp_builtin_exec(VM& vm, RegExpObject& regexp
|
|||
Vector<Utf16String> captured_values;
|
||||
|
||||
// 26. Let groupNames be a new empty List.
|
||||
HashMap<FlyString, Match> group_names;
|
||||
HashMap<Utf16FlyString, Match> group_names;
|
||||
|
||||
// 27. Add match as the last element of indices.
|
||||
indices.append(move(match_indices));
|
||||
|
|
@ -334,7 +334,7 @@ static ThrowCompletionOr<Value> 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));
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ ThrowCompletionOr<void> 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<Value> 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<TypeError>(ErrorType::ShadowRealmEvaluateAbruptCompletion);
|
||||
auto executable = maybe_executable.release_value();
|
||||
|
|
@ -242,7 +242,7 @@ ThrowCompletionOr<Value> 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<Value> {
|
||||
auto steps = [string = Utf16String::from_utf8(export_name_string)](auto& vm) -> ThrowCompletionOr<Value> {
|
||||
// 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<Value> 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()));
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ ThrowCompletionOr<Value> 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.
|
||||
|
|
|
|||
|
|
@ -13,31 +13,31 @@ namespace JS {
|
|||
|
||||
GC_DEFINE_ALLOCATOR(Symbol);
|
||||
|
||||
Symbol::Symbol(Optional<String> description, bool is_global)
|
||||
Symbol::Symbol(Optional<Utf16String> description, bool is_global)
|
||||
: m_description(move(description))
|
||||
, m_is_global(is_global)
|
||||
{
|
||||
}
|
||||
|
||||
GC::Ref<Symbol> Symbol::create(VM& vm, Optional<String> description, bool is_global)
|
||||
GC::Ref<Symbol> Symbol::create(VM& vm, Optional<Utf16String> description, bool is_global)
|
||||
{
|
||||
return vm.heap().allocate<Symbol>(move(description), is_global);
|
||||
}
|
||||
|
||||
// 20.4.3.3.1 SymbolDescriptiveString ( sym ), https://tc39.es/ecma262/#sec-symboldescriptivestring
|
||||
ErrorOr<String> 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<String> Symbol::key() const
|
||||
Optional<Utf16String> Symbol::key() const
|
||||
{
|
||||
// 1. For each element e of the GlobalSymbolRegistry List, do
|
||||
// a. If SameValue(e.[[Symbol]], sym) is true, return e.[[Key]].
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <AK/Utf16String.h>
|
||||
#include <LibGC/CellAllocator.h>
|
||||
#include <LibJS/Export.h>
|
||||
#include <LibJS/Heap/Cell.h>
|
||||
|
|
@ -19,20 +19,20 @@ class JS_API Symbol final : public Cell {
|
|||
GC_DECLARE_ALLOCATOR(Symbol);
|
||||
|
||||
public:
|
||||
[[nodiscard]] static GC::Ref<Symbol> create(VM&, Optional<String> description, bool is_global);
|
||||
[[nodiscard]] static GC::Ref<Symbol> create(VM&, Optional<Utf16String> description, bool is_global);
|
||||
|
||||
virtual ~Symbol() = default;
|
||||
|
||||
Optional<String> const& description() const { return m_description; }
|
||||
Optional<Utf16String> const& description() const { return m_description; }
|
||||
bool is_global() const { return m_is_global; }
|
||||
|
||||
ErrorOr<String> descriptive_string() const;
|
||||
Optional<String> key() const;
|
||||
Utf16String descriptive_string() const;
|
||||
Optional<Utf16String> key() const;
|
||||
|
||||
private:
|
||||
Symbol(Optional<String>, bool);
|
||||
Symbol(Optional<Utf16String>, bool);
|
||||
|
||||
Optional<String> m_description;
|
||||
Optional<Utf16String> m_description;
|
||||
bool m_is_global;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@ ThrowCompletionOr<Value> 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<String> {}
|
||||
: TRY(description.to_string(vm));
|
||||
? Optional<Utf16String> {}
|
||||
: 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<GC::Ref<Object>> 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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ static Vector<CalendarFieldData> 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;
|
||||
|
|
|
|||
|
|
@ -449,6 +449,7 @@ void TypedArrayBase::visit_edges(Visitor& visitor)
|
|||
GC_DEFINE_ALLOCATOR(ClassName); \
|
||||
GC_DEFINE_ALLOCATOR(PrototypeName); \
|
||||
GC_DEFINE_ALLOCATOR(ConstructorName); \
|
||||
\
|
||||
ThrowCompletionOr<GC::Ref<ClassName>> 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(); \
|
||||
} \
|
||||
|
|
|
|||
|
|
@ -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<double> compare_typed_array_elements(VM&, Value x, Value y, Fu
|
|||
static ThrowCompletionOr<GC::Ref<ClassName>> create(Realm&, u32 length, FunctionObject& new_target); \
|
||||
static ThrowCompletionOr<GC::Ref<ClassName>> create(Realm&, u32 length); \
|
||||
static GC::Ref<ClassName> create(Realm&, u32 length, ArrayBuffer& buffer); \
|
||||
virtual FlyString const& element_name() const override; \
|
||||
virtual Utf16FlyString const& element_name() const override; \
|
||||
virtual GC::Ref<NativeFunction> intrinsic_constructor(Realm&) const override; \
|
||||
\
|
||||
protected: \
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ public:
|
|||
virtual ThrowCompletionOr<GC::Ref<Object>> 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; }
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ NonnullRefPtr<VM> 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<GC::Cell*, GC::HeapRoot>& roots)
|
|||
}
|
||||
|
||||
// 9.1.2.1 GetIdentifierReference ( env, name, strict ), https://tc39.es/ecma262/#sec-getidentifierreference
|
||||
ThrowCompletionOr<Reference> VM::get_identifier_reference(Environment* environment, FlyString name, bool strict, size_t hops)
|
||||
ThrowCompletionOr<Reference> 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<Reference> VM::get_identifier_reference(Environment* environme
|
|||
}
|
||||
|
||||
// 9.4.2 ResolveBinding ( name [ , env ] ), https://tc39.es/ecma262/#sec-resolvebinding
|
||||
ThrowCompletionOr<Reference> VM::resolve_binding(FlyString const& name, Environment* environment)
|
||||
ThrowCompletionOr<Reference> VM::resolve_binding(Utf16FlyString const& name, Environment* environment)
|
||||
{
|
||||
// 1. If env is not present or if env is undefined, then
|
||||
if (!environment) {
|
||||
|
|
|
|||
|
|
@ -196,14 +196,14 @@ public:
|
|||
|
||||
StackInfo const& stack_info() const { return m_stack_info; }
|
||||
|
||||
HashMap<String, GC::Ref<Symbol>> const& global_symbol_registry() const { return m_global_symbol_registry; }
|
||||
HashMap<String, GC::Ref<Symbol>>& global_symbol_registry() { return m_global_symbol_registry; }
|
||||
HashMap<Utf16String, GC::Ref<Symbol>> const& global_symbol_registry() const { return m_global_symbol_registry; }
|
||||
HashMap<Utf16String, GC::Ref<Symbol>>& global_symbol_registry() { return m_global_symbol_registry; }
|
||||
|
||||
u32 execution_generation() const { return m_execution_generation; }
|
||||
void finish_execution_generation() { ++m_execution_generation; }
|
||||
|
||||
ThrowCompletionOr<Reference> resolve_binding(FlyString const&, Environment* = nullptr);
|
||||
ThrowCompletionOr<Reference> get_identifier_reference(Environment*, FlyString, bool strict, size_t hops = 0);
|
||||
ThrowCompletionOr<Reference> resolve_binding(Utf16FlyString const&, Environment* = nullptr);
|
||||
ThrowCompletionOr<Reference> 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<typename T, typename... Args>
|
||||
|
|
@ -333,7 +333,7 @@ private:
|
|||
StackInfo m_stack_info;
|
||||
|
||||
// GlobalSymbolRegistry, https://tc39.es/ecma262/#table-globalsymbolregistry-record-fields
|
||||
HashMap<String, GC::Ref<Symbol>> m_global_symbol_registry;
|
||||
HashMap<Utf16String, GC::Ref<Symbol>> m_global_symbol_registry;
|
||||
|
||||
Vector<GC::Ref<GC::Function<ThrowCompletionOr<Value>()>>> m_promise_jobs;
|
||||
|
||||
|
|
|
|||
|
|
@ -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<PropertyKey> 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<PropertyKey> 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
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ Result<GC::Ref<SourceTextModule>, Vector<ParserError>> SourceTextModule::parse(S
|
|||
}
|
||||
|
||||
// 16.2.1.7.2.1 GetExportedNames ( [ exportStarSet ] ), https://tc39.es/ecma262/#sec-getexportednames
|
||||
Vector<FlyString> SourceTextModule::get_exported_names(VM& vm, HashTable<Module const*>& export_star_set)
|
||||
Vector<Utf16FlyString> SourceTextModule::get_exported_names(VM& vm, HashTable<Module const*>& export_star_set)
|
||||
{
|
||||
dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] get_export_names of {}", filename());
|
||||
|
||||
|
|
@ -285,7 +285,7 @@ Vector<FlyString> SourceTextModule::get_exported_names(VM& vm, HashTable<Module
|
|||
export_star_set.set(this);
|
||||
|
||||
// 5. Let exportedNames be a new empty List.
|
||||
Vector<FlyString> exported_names;
|
||||
Vector<Utf16FlyString> 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<FlyString> SourceTextModule::get_exported_names(VM& vm, HashTable<Module
|
|||
VERIFY(entry.export_name.has_value());
|
||||
|
||||
// c. Append e.[[ExportName]] to exportedNames.
|
||||
exported_names.empend(entry.export_name.value());
|
||||
exported_names.empend(Utf16FlyString::from_utf8(entry.export_name.value()));
|
||||
}
|
||||
|
||||
// 7. For each ExportEntry Record e of module.[[IndirectExportEntries]], do
|
||||
|
|
@ -308,7 +308,7 @@ Vector<FlyString> SourceTextModule::get_exported_names(VM& vm, HashTable<Module
|
|||
VERIFY(entry.export_name.has_value());
|
||||
|
||||
// c. Append e.[[ExportName]] to exportedNames.
|
||||
exported_names.empend(entry.export_name.value());
|
||||
exported_names.empend(Utf16FlyString::from_utf8(entry.export_name.value()));
|
||||
}
|
||||
|
||||
// 8. For each ExportEntry Record e of module.[[StarExportEntries]], do
|
||||
|
|
@ -346,7 +346,7 @@ ThrowCompletionOr<void> 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<void> 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<void> 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<SyntaxError>(ErrorType::InvalidOrAmbiguousExportEntry, import_entry.import_name);
|
||||
return vm.throw_completion<SyntaxError>(ErrorType::InvalidOrAmbiguousExportEntry, import_name);
|
||||
|
||||
// iii. If resolution.[[BindingName]] is NAMESPACE, then
|
||||
if (resolution.is_namespace()) {
|
||||
|
|
@ -400,15 +404,15 @@ ThrowCompletionOr<void> 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<void> SourceTextModule::initialize_environment(VM& vm)
|
|||
// NOTE: We just loop through them in step 21.
|
||||
|
||||
// 20. Let declaredVarNames be a new empty List.
|
||||
Vector<FlyString> declared_var_names;
|
||||
Vector<Utf16FlyString> 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<void> 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<void> 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<void> SourceTextModule::initialize_environment(VM& vm)
|
|||
VERIFY(m_default_export->has_statement());
|
||||
|
||||
if (auto const& statement = m_default_export->statement(); !is<Declaration>(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<void> 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<ResolvedBinding> resolve_set)
|
||||
ResolvedBinding SourceTextModule::resolve_export(VM& vm, Utf16FlyString const& export_name, Vector<ResolvedBinding> 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<void> SourceTextModule::execute_module(VM& vm, GC::Ptr<Promise
|
|||
if (!m_has_top_level_await) {
|
||||
Completion result;
|
||||
|
||||
auto maybe_executable = Bytecode::compile(vm, m_ecmascript_code, FunctionKind::Normal, "ShadowRealmEval"_fly_string);
|
||||
auto maybe_executable = Bytecode::compile(vm, m_ecmascript_code, FunctionKind::Normal, "ShadowRealmEval"_utf16_fly_string);
|
||||
if (maybe_executable.is_error()) {
|
||||
result = maybe_executable.release_error();
|
||||
} else {
|
||||
|
|
@ -787,7 +793,7 @@ ThrowCompletionOr<void> SourceTextModule::execute_module(VM& vm, GC::Ptr<Promise
|
|||
parsing_insights.uses_this_from_environment = true;
|
||||
parsing_insights.uses_this = true;
|
||||
auto module_wrapper_function = ECMAScriptFunctionObject::create(
|
||||
realm(), "module code with top-level await"_fly_string, StringView {}, this->m_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);
|
||||
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ public:
|
|||
|
||||
Program const& parse_node() const { return *m_ecmascript_code; }
|
||||
|
||||
virtual Vector<FlyString> get_exported_names(VM& vm, HashTable<Module const*>& export_star_set) override;
|
||||
virtual ResolvedBinding resolve_export(VM& vm, FlyString const& export_name, Vector<ResolvedBinding> resolve_set = {}) override;
|
||||
virtual Vector<Utf16FlyString> get_exported_names(VM& vm, HashTable<Module const*>& export_star_set) override;
|
||||
virtual ResolvedBinding resolve_export(VM& vm, Utf16FlyString const& export_name, Vector<ResolvedBinding> resolve_set = {}) override;
|
||||
|
||||
Object* import_meta() { return m_import_meta; }
|
||||
void set_import_meta(Badge<VM>, Object* import_meta) { m_import_meta = import_meta; }
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ namespace JS {
|
|||
|
||||
GC_DEFINE_ALLOCATOR(SyntheticModule);
|
||||
|
||||
SyntheticModule::SyntheticModule(Realm& realm, Vector<FlyString> export_names, SyntheticModule::EvaluationFunction evaluation_steps, ByteString filename)
|
||||
SyntheticModule::SyntheticModule(Realm& realm, Vector<Utf16FlyString> 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> 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<void> {
|
||||
// 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<SyntheticModule>(realm, Vector<FlyString> { "default"_fly_string }, set_default_export, move(filename));
|
||||
return realm.heap().allocate<SyntheticModule>(realm, Vector<Utf16FlyString> { "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<GC::Ref<Module>> parse_json_module(Realm& realm, StringView so
|
|||
}
|
||||
|
||||
// 16.2.1.8.3 SetSyntheticModuleExport ( module, exportName, exportValue ), https://tc39.es/ecma262/#sec-setsyntheticmoduleexport
|
||||
ThrowCompletionOr<void> SyntheticModule::set_synthetic_module_export(FlyString const& export_name, Value export_value)
|
||||
ThrowCompletionOr<void> 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<GraphLoadingS
|
|||
}
|
||||
|
||||
// 16.2.1.8.4.2 GetExportedNames ( ), https://tc39.es/ecma262/#sec-smr-getexportednames
|
||||
Vector<FlyString> SyntheticModule::get_exported_names(VM&, HashTable<Module const*>&)
|
||||
Vector<Utf16FlyString> SyntheticModule::get_exported_names(VM&, HashTable<Module const*>&)
|
||||
{
|
||||
// 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>)
|
||||
ResolvedBinding SyntheticModule::resolve_export(VM&, Utf16FlyString const& export_name, Vector<ResolvedBinding>)
|
||||
{
|
||||
// 1. If module.[[ExportNames]] does not contain exportName, return null.
|
||||
if (!m_export_names.contains_slow(export_name))
|
||||
|
|
|
|||
|
|
@ -22,20 +22,20 @@ public:
|
|||
|
||||
static GC::Ref<SyntheticModule> create_default_export_synthetic_module(Realm& realm, Value default_export, ByteString filename);
|
||||
|
||||
ThrowCompletionOr<void> set_synthetic_module_export(FlyString const& export_name, Value export_value);
|
||||
ThrowCompletionOr<void> set_synthetic_module_export(Utf16FlyString const& export_name, Value export_value);
|
||||
|
||||
virtual PromiseCapability& load_requested_modules(GC::Ptr<GraphLoadingState::HostDefined>) override;
|
||||
virtual Vector<FlyString> get_exported_names(VM& vm, HashTable<Module const*>& export_star_set) override;
|
||||
virtual ResolvedBinding resolve_export(VM& vm, FlyString const& export_name, Vector<ResolvedBinding> resolve_set) override;
|
||||
virtual Vector<Utf16FlyString> get_exported_names(VM& vm, HashTable<Module const*>& export_star_set) override;
|
||||
virtual ResolvedBinding resolve_export(VM& vm, Utf16FlyString const& export_name, Vector<ResolvedBinding> resolve_set) override;
|
||||
virtual ThrowCompletionOr<void> link(VM& vm) override;
|
||||
virtual ThrowCompletionOr<GC::Ref<Promise>> evaluate(VM& vm) override;
|
||||
|
||||
private:
|
||||
SyntheticModule(Realm& realm, Vector<FlyString> export_names, EvaluationFunction evaluation_steps, ByteString filename);
|
||||
SyntheticModule(Realm& realm, Vector<Utf16FlyString> export_names, EvaluationFunction evaluation_steps, ByteString filename);
|
||||
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
Vector<FlyString> m_export_names; // [[ExportNames]]
|
||||
Vector<Utf16FlyString> m_export_names; // [[ExportNames]]
|
||||
EvaluationFunction m_evaluation_steps; // [[EvaluationSteps]]
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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<JS::Value> (*function)(JS::VM&);
|
||||
size_t length { 0 };
|
||||
};
|
||||
extern HashMap<String, FunctionWithLength> s_exposed_global_functions;
|
||||
extern HashMap<Utf16String, FunctionWithLength> 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<GC::Ref<JS::SourceTextModule>, ParserError> parse_module(Strin
|
|||
|
||||
inline ErrorOr<JsonValue> 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()) {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace JS {
|
|||
RefPtr<::JS::VM> g_vm;
|
||||
bool g_collect_on_every_allocation = false;
|
||||
ByteString g_currently_running_test;
|
||||
HashMap<String, FunctionWithLength> s_exposed_global_functions;
|
||||
HashMap<Utf16String, FunctionWithLength> s_exposed_global_functions;
|
||||
Function<void()> g_main_hook;
|
||||
HashMap<bool*, Tuple<ByteString, ByteString, char>> g_extra_args;
|
||||
IntermediateRunFileResult (*g_run_file)(ByteString const&, JS::Realm&, JS::ExecutionContext&) = nullptr;
|
||||
|
|
|
|||
|
|
@ -105,13 +105,13 @@ static WebIDL::ExceptionOr<KeyframeType<AL>> 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<KeyframeType<AL>> 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<AL == AllowLists::Yes, Vector<String>, String>;
|
||||
|
|
@ -841,8 +841,9 @@ WebIDL::ExceptionOr<GC::RootVector<JS::Object*>> 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);
|
||||
|
|
|
|||
|
|
@ -411,8 +411,8 @@ void initialize_main_thread_vm(AgentType type)
|
|||
|
||||
// 5. Return « Record { [[Key]]: "url", [[Value]]: urlString }, Record { [[Key]]: "resolve", [[Value]]: resolveFunction } ».
|
||||
HashMap<JS::PropertyKey, JS::Value> 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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ JS::ThrowCompletionOr<bool> 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<Optional<JS::PropertyDescriptor>> 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<bool> 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<bool> 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<bool> 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<GC::RootVector<JS::Value>> 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));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ WebIDL::ExceptionOr<GC::Root<WebIDL::ArrayBufferView>> 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<GC::Ref<JS::TypedArrayBase>>();
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> 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<JS::TypedArrayBase>(iv_value.as_object()) || is<JS::ArrayBuffer>(iv_value.as_object()) || is<JS::DataView>(iv_value.as_object())))
|
||||
return vm.throw_completion<JS::TypeError>(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<NonnullOwnPtr<AlgorithmParams>> 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<JS::TypedArrayBase>(iv_value.as_object()) || is<JS::ArrayBuffer>(iv_value.as_object()) || is<JS::DataView>(iv_value.as_object())))
|
||||
return vm.throw_completion<JS::TypeError>(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<AlgorithmParams>(*new AesCtrParams { iv, length });
|
||||
|
|
@ -318,22 +318,22 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> 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<JS::TypedArrayBase>(iv_value.as_object()) || is<JS::ArrayBuffer>(iv_value.as_object()) || is<JS::DataView>(iv_value.as_object())))
|
||||
return vm.throw_completion<JS::TypeError>(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<ByteBuffer> {};
|
||||
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<JS::TypedArrayBase>(additional_data_value.as_object()) || is<JS::ArrayBuffer>(additional_data_value.as_object()) || is<JS::DataView>(additional_data_value.as_object())))
|
||||
return vm.throw_completion<JS::TypeError>(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<u8> {};
|
||||
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<NonnullOwnPtr<AlgorithmParams>> 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<JS::TypedArrayBase>(salt_value.as_object()) || is<JS::ArrayBuffer>(salt_value.as_object()) || is<JS::DataView>(salt_value.as_object())))
|
||||
return vm.throw_completion<JS::TypeError>(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<JS::TypedArrayBase>(info_value.as_object()) || is<JS::ArrayBuffer>(info_value.as_object()) || is<JS::DataView>(info_value.as_object())))
|
||||
return vm.throw_completion<JS::TypeError>(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<NonnullOwnPtr<AlgorithmParams>> 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<JS::TypedArrayBase>(salt_value.as_object()) || is<JS::ArrayBuffer>(salt_value.as_object()) || is<JS::DataView>(salt_value.as_object())))
|
||||
return vm.throw_completion<JS::TypeError>(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<AlgorithmParams>(*new PBKDF2Params { salt, iterations, hash });
|
||||
|
|
@ -390,10 +390,10 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> 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<JS::Uint8Array> public_exponent;
|
||||
|
||||
if (!public_exponent_value.is_object() || !is<JS::Uint8Array>(public_exponent_value.as_object()))
|
||||
|
|
@ -410,10 +410,10 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> 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<JS::Uint8Array> public_exponent;
|
||||
|
||||
if (!public_exponent_value.is_object() || !is<JS::Uint8Array>(public_exponent_value.as_object()))
|
||||
|
|
@ -421,7 +421,7 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> RsaHashedKeyGenParams::fro
|
|||
|
||||
public_exponent = static_cast<JS::Uint8Array&>(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<AlgorithmParams>(*new RsaHashedKeyGenParams { modulus_length, big_integer_from_api_big_integer(public_exponent), hash });
|
||||
|
|
@ -433,7 +433,7 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> 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<AlgorithmParams>(*new RsaHashedImportParams { hash });
|
||||
|
|
@ -445,7 +445,7 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> 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<NonnullOwnPtr<AlgorithmParams>> 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<AlgorithmParams>(*new RsaPssParams { salt_length });
|
||||
|
|
@ -477,7 +477,7 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> 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<AlgorithmParams>(*new EcdsaParams { hash });
|
||||
|
|
@ -489,7 +489,7 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> 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<AlgorithmParams>(*new EcKeyGenParams { curve });
|
||||
|
|
@ -501,7 +501,7 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> 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<AlgorithmParams>(*new AesKeyGenParams { length });
|
||||
|
|
@ -513,7 +513,7 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> 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<AlgorithmParams>(*new AesDerivedKeyParams { length });
|
||||
|
|
@ -525,7 +525,7 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> 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<CryptoKey>(*key_object)) {
|
||||
|
|
@ -543,7 +543,7 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> 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<AlgorithmParams>(*new EcKeyImportParams { named_curve });
|
||||
|
|
@ -555,12 +555,12 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> 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<WebIDL::UnsignedLong> {};
|
||||
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<NonnullOwnPtr<AlgorithmParams>> 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<WebIDL::UnsignedLong> {};
|
||||
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<NonnullOwnPtr<AlgorithmParams>> Ed448Params::from_value(JS
|
|||
auto& object = value.as_object();
|
||||
|
||||
auto maybe_context = Optional<ByteBuffer> {};
|
||||
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<JS::TypedArrayBase>(context_value.as_object()) || is<JS::ArrayBuffer>(context_value.as_object()) || is<JS::DataView>(context_value.as_object())))
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "BufferSource");
|
||||
maybe_context = TRY_OR_THROW_OOM(vm, WebIDL::get_buffer_source_copy(context_value.as_object()));
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ struct HashAlgorithmIdentifier : public AlgorithmIdentifier {
|
|||
auto value = visit(
|
||||
[](String const& name) -> JS::ThrowCompletionOr<String> { return name; },
|
||||
[&](GC::Root<JS::Object> const& obj) -> JS::ThrowCompletionOr<String> {
|
||||
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);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -91,63 +91,63 @@ JS::ThrowCompletionOr<GC::Ref<JS::Object>> 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<String>(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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ void CryptoKey::set_usages(Vector<Bindings::KeyUsage> 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<CryptoKey> 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ WebIDL::ExceptionOr<NormalizedAlgorithmAndParameter> 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<String>())));
|
||||
TRY(dictionary->create_data_property("name"_utf16_fly_string, JS::PrimitiveString::create(vm, algorithm.get<String>())));
|
||||
|
||||
return normalize_an_algorithm(realm, dictionary, operation);
|
||||
}
|
||||
|
|
@ -89,7 +89,7 @@ WebIDL::ExceptionOr<NormalizedAlgorithmAndParameter> 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<GC::Root<JS::Object>>()->get("name"_fly_string));
|
||||
auto initial_algorithm = TRY(algorithm.get<GC::Root<JS::Object>>()->get("name"_utf16_fly_string));
|
||||
|
||||
if (initial_algorithm.is_undefined()) {
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "Algorithm");
|
||||
|
|
|
|||
|
|
@ -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<JS::Value> {
|
||||
auto callback = JS::NativeFunction::create(realm, Utf16FlyString {}, [this](JS::VM& vm) -> JS::ThrowCompletionOr<JS::Value> {
|
||||
// For each entry in entries using a method of iteration which does not trigger developer-modifiable array accessors or iteration hooks:
|
||||
auto& entries = as<JS::Array>(vm.argument(0).as_object());
|
||||
auto entries_length = MUST(MUST(entries.get(vm.names.length)).to_length(vm));
|
||||
|
|
|
|||
|
|
@ -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<WebIDL::CallbackType>(steps, realm());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ bool EventDispatcher::inner_invoke(Event& event, Vector<GC::Root<DOM::DOMEventLi
|
|||
// FIXME: These should be wrapped for us in call_user_object_operation, but it currently doesn't do that.
|
||||
auto* this_value = event.current_target().ptr();
|
||||
auto* wrapped_event = &event;
|
||||
auto result = WebIDL::call_user_object_operation(callback, "handleEvent"_string, this_value, { { wrapped_event } });
|
||||
auto result = WebIDL::call_user_object_operation(callback, "handleEvent"_utf16_fly_string, this_value, { { wrapped_event } });
|
||||
|
||||
// If this throws an exception, then:
|
||||
if (result.is_error()) {
|
||||
|
|
|
|||
|
|
@ -516,7 +516,7 @@ WebIDL::CallbackType* EventTarget::get_current_value_of_event_handler(FlyString
|
|||
|
||||
// 6. Return scope. (NOTE: Not necessary)
|
||||
|
||||
auto function = JS::ECMAScriptFunctionObject::create(realm, 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(),
|
||||
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<WebIDL::CallbackType>(*callback_function, realm);
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ JS::ThrowCompletionOr<NodeFilter::Result> 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;
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@ JS::ThrowCompletionOr<NodeFilter::Result> 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;
|
||||
|
|
|
|||
|
|
@ -22,13 +22,13 @@ JS::ThrowCompletionOr<Web::HTML::CanvasRenderingContext2DSettings> 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::CanvasRenderingContext2DSettings> Web::HTML::Ca
|
|||
return vm.throw_completion<JS::TypeError>(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::CanvasRenderingContext2DSettings> Web::HTML::Ca
|
|||
return vm.throw_completion<JS::TypeError>(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;
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ JS::ThrowCompletionOr<void> 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<void> 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.
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ Variant<GC::Ref<DOM::HTMLCollection>, GC::Ref<DOM::Element>, 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<DOM::HTMLCollection>, GC::Ref<DOM::Element>, 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<JS::Value> HTMLAllCollection::item_value(size_t index) const
|
||||
|
|
|
|||
|
|
@ -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<WebIDL::CallbackType>(*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<WebIDL::CallbackType>(*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.
|
||||
|
|
|
|||
|
|
@ -1432,7 +1432,7 @@ WebIDL::ExceptionOr<void> HTMLElement::show_popover(ThrowExceptions throw_except
|
|||
|
||||
return JS::js_undefined();
|
||||
},
|
||||
0, FlyString {}, &realm());
|
||||
0, Utf16FlyString {}, &realm());
|
||||
auto close_callback = realm().heap().allocate<WebIDL::CallbackType>(*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.
|
||||
|
|
|
|||
|
|
@ -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<WebIDL::CallbackType>(*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<WebIDL::CallbackType>(*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<WebIDL::CallbackType>(*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<WebIDL::CallbackType>(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<WebIDL::CallbackType>(*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<WebIDL::CallbackType>(*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<WebIDL::CallbackType>(*mousemove_callback_function, realm());
|
||||
auto mousemove_listener = DOM::IDLEventListener::create(realm(), mousemove_callback);
|
||||
auto& window = static_cast<HTML::Window&>(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<WebIDL::CallbackType>(*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<WebIDL::CallbackType>(*mousedown_callback_function, realm());
|
||||
add_event_listener_without_options(UIEvents::EventNames::mousedown, DOM::IDLEventListener::create(realm(), mousedown_callback));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ WebIDL::ExceptionOr<ImportMap> 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<ImportMap> parse_import_map_string(JS::Realm& realm, ByteStr
|
|||
HashMap<URL::URL, ModuleSpecifierMap> 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<ImportMap> 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<ImportMap> 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<ModuleSpecifierMap> 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<ModuleSpecifierMap> 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<HashMap<URL::URL, ModuleSpecifierMap>> 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<ModuleIntegrityMap> 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()) {
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ static WebIDL::ExceptionOr<void> serialize_viewed_array_buffer(JS::VM& vm, Trans
|
|||
if constexpr (IsSame<ViewType, JS::DataView>) {
|
||||
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<void> 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<JS::ArrayBuffer>(array_buffer_value.as_object());
|
||||
|
||||
auto constructor_name = m_serialized.decode<String>();
|
||||
auto constructor_name = m_serialized.decode<Utf16String>();
|
||||
auto byte_length = m_serialized.decode<u32>();
|
||||
auto byte_offset = m_serialized.decode<u32>();
|
||||
|
||||
|
|
@ -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<String>();
|
||||
auto key = m_serialized.decode<Utf16String>();
|
||||
|
||||
// 1. Let deserializedValue be ? StructuredDeserialize(entry.[[Value]], targetRealm, memory).
|
||||
auto deserialized_value = TRY(deserialize());
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ GC::Ref<WebIDL::CallbackType> 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<WebIDL::CallbackType> 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
|
||||
|
|
|
|||
|
|
@ -748,7 +748,7 @@ WebIDL::ExceptionOr<void> Window::initialize_web_interfaces(Badge<WindowEnvironm
|
|||
WindowOrWorkerGlobalScopeMixin::initialize(realm);
|
||||
|
||||
if (s_internals_object_exposed)
|
||||
define_direct_property("internals"_fly_string, realm.create<Internals::Internals>(realm), JS::default_attributes);
|
||||
define_direct_property("internals"_utf16_fly_string, realm.create<Internals::Internals>(realm), JS::default_attributes);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> 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.
|
||||
|
|
|
|||
|
|
@ -219,10 +219,10 @@ GC::Ref<WebIDL::Promise> 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));
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user