mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-03 08:08:43 +00:00
LibJS: Port the Identifier AST (and related) nodes to UTF-16
This eliminates quite a lot of UTF-8 / UTF-16 churn.
This commit is contained in:
parent
00182a2405
commit
b955c9b2a9
Notes:
github-actions[bot]
2025-08-13 13:57:20 +00:00
Author: https://github.com/trflynn89
Commit: b955c9b2a9
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5762
20 changed files with 206 additions and 238 deletions
|
@ -95,9 +95,9 @@ Value FunctionExpression::instantiate_ordinary_function_expression(VM& vm, Utf16
|
|||
if (given_name.is_empty())
|
||||
given_name = Utf16FlyString {};
|
||||
|
||||
auto has_own_name = !name().is_empty();
|
||||
auto own_name = name();
|
||||
auto has_own_name = !own_name.is_empty();
|
||||
|
||||
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 };
|
||||
|
@ -120,10 +120,10 @@ Value FunctionExpression::instantiate_ordinary_function_expression(VM& vm, Utf16
|
|||
return closure;
|
||||
}
|
||||
|
||||
Optional<String> CallExpression::expression_string() const
|
||||
Optional<Utf16String> CallExpression::expression_string() const
|
||||
{
|
||||
if (is<Identifier>(*m_callee))
|
||||
return static_cast<Identifier const&>(*m_callee).string().to_string();
|
||||
return static_cast<Identifier const&>(*m_callee).string().to_utf16_string();
|
||||
|
||||
if (is<MemberExpression>(*m_callee))
|
||||
return static_cast<MemberExpression const&>(*m_callee).to_string_approximation();
|
||||
|
@ -137,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(Utf16FlyString::from_utf8(private_identifier.string())) };
|
||||
return ClassElementName { private_environment->resolve_private_identifier(private_identifier.string()) };
|
||||
}
|
||||
|
||||
VERIFY(!prop_key.is_special_empty_value());
|
||||
|
@ -156,7 +156,7 @@ ThrowCompletionOr<ClassElement::ClassValue> ClassMethod::class_element_evaluatio
|
|||
|
||||
auto& method_function = *ECMAScriptFunctionObject::create_from_function_node(
|
||||
*m_function,
|
||||
Utf16String::from_utf8(m_function->name()),
|
||||
m_function->name(),
|
||||
*vm.current_realm(),
|
||||
vm.lexical_environment(),
|
||||
vm.running_execution_context().private_environment);
|
||||
|
@ -271,19 +271,19 @@ ThrowCompletionOr<ClassElement::ClassValue> ClassField::class_element_evaluation
|
|||
};
|
||||
}
|
||||
|
||||
static Optional<FlyString> nullopt_or_private_identifier_description(Expression const& expression)
|
||||
static Optional<Utf16FlyString> nullopt_or_private_identifier_description(Expression const& expression)
|
||||
{
|
||||
if (is<PrivateIdentifier>(expression))
|
||||
return static_cast<PrivateIdentifier const&>(expression).string();
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<FlyString> ClassField::private_bound_identifier() const
|
||||
Optional<Utf16FlyString> ClassField::private_bound_identifier() const
|
||||
{
|
||||
return nullopt_or_private_identifier_description(*m_key);
|
||||
}
|
||||
|
||||
Optional<FlyString> ClassMethod::private_bound_identifier() const
|
||||
Optional<Utf16FlyString> ClassMethod::private_bound_identifier() const
|
||||
{
|
||||
return nullopt_or_private_identifier_description(*m_key);
|
||||
}
|
||||
|
@ -355,7 +355,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> ClassExpression::create_class_const
|
|||
auto const& constructor = *m_constructor;
|
||||
auto class_constructor = ECMAScriptFunctionObject::create_from_function_node(
|
||||
constructor,
|
||||
Utf16FlyString::from_utf8(constructor.name()),
|
||||
constructor.name(),
|
||||
realm,
|
||||
vm.lexical_environment(),
|
||||
vm.running_execution_context().private_environment);
|
||||
|
@ -1244,16 +1244,17 @@ void MemberExpression::dump(int indent) const
|
|||
m_property->dump(indent + 1);
|
||||
}
|
||||
|
||||
String MemberExpression::to_string_approximation() const
|
||||
Utf16String MemberExpression::to_string_approximation() const
|
||||
{
|
||||
String object_string = "<object>"_string;
|
||||
Utf16View object_string = "<object>"sv;
|
||||
if (is<Identifier>(*m_object))
|
||||
object_string = static_cast<Identifier const&>(*m_object).string().to_string();
|
||||
object_string = static_cast<Identifier const&>(*m_object).string().view();
|
||||
|
||||
if (is_computed())
|
||||
return MUST(String::formatted("{}[<computed>]", object_string));
|
||||
return Utf16String::formatted("{}[<computed>]", object_string);
|
||||
if (is<PrivateIdentifier>(*m_property))
|
||||
return MUST(String::formatted("{}.{}", object_string, as<PrivateIdentifier>(*m_property).string()));
|
||||
return MUST(String::formatted("{}.{}", object_string, as<Identifier>(*m_property).string()));
|
||||
return Utf16String::formatted("{}.{}", object_string, as<PrivateIdentifier>(*m_property).string());
|
||||
return Utf16String::formatted("{}.{}", object_string, as<Identifier>(*m_property).string());
|
||||
}
|
||||
|
||||
bool MemberExpression::ends_in_private_name() const
|
||||
|
@ -1531,7 +1532,7 @@ void ScopeNode::add_hoisted_function(NonnullRefPtr<FunctionDeclaration const> de
|
|||
m_functions_hoistable_with_annexB_extension.append(move(declaration));
|
||||
}
|
||||
|
||||
FlyString ExportStatement::local_name_for_default = "*default*"_fly_string;
|
||||
Utf16FlyString ExportStatement::local_name_for_default = "*default*"_utf16_fly_string;
|
||||
|
||||
static void dump_assert_clauses(ModuleRequest const& request)
|
||||
{
|
||||
|
@ -1549,7 +1550,7 @@ void ExportStatement::dump(int indent) const
|
|||
print_indent(indent + 1);
|
||||
outln("(ExportEntries)");
|
||||
|
||||
auto string_or_null = [](Optional<FlyString> const& string) -> ByteString {
|
||||
auto string_or_null = []<typename T>(Optional<T> const& string) -> ByteString {
|
||||
if (!string.has_value()) {
|
||||
return "null";
|
||||
}
|
||||
|
@ -1597,7 +1598,7 @@ void ImportStatement::dump(int indent) const
|
|||
}
|
||||
}
|
||||
|
||||
bool ExportStatement::has_export(FlyString const& export_name) const
|
||||
bool ExportStatement::has_export(Utf16FlyString const& export_name) const
|
||||
{
|
||||
return any_of(m_entries.begin(), m_entries.end(), [&](auto& entry) {
|
||||
// Make sure that empty exported names does not overlap with anything
|
||||
|
@ -1607,7 +1608,7 @@ bool ExportStatement::has_export(FlyString const& export_name) const
|
|||
});
|
||||
}
|
||||
|
||||
bool ImportStatement::has_bound_name(FlyString const& name) const
|
||||
bool ImportStatement::has_bound_name(Utf16FlyString const& name) const
|
||||
{
|
||||
return any_of(m_entries.begin(), m_entries.end(), [&](auto& entry) {
|
||||
return entry.local_name == name;
|
||||
|
@ -1641,7 +1642,7 @@ void ScopeNode::block_declaration_instantiation(VM& vm, Environment* environment
|
|||
return;
|
||||
}
|
||||
|
||||
auto name = Utf16FlyString::from_utf8(identifier.string());
|
||||
auto const& name = identifier.string();
|
||||
|
||||
// i. If IsConstantDeclaration of d is true, then
|
||||
if (is_constant_declaration) {
|
||||
|
@ -1664,7 +1665,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,
|
||||
Utf16FlyString::from_utf8(function_declaration.name()),
|
||||
function_declaration.name(),
|
||||
realm,
|
||||
environment,
|
||||
private_environment);
|
||||
|
@ -1697,7 +1698,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 name = Utf16FlyString::from_utf8(identifier.string());
|
||||
auto const& name = identifier.string();
|
||||
|
||||
// a. If HasLexicalDeclaration(env, name) is true, throw a SyntaxError exception.
|
||||
if (global_environment.has_lexical_declaration(name))
|
||||
|
@ -1719,7 +1720,7 @@ ThrowCompletionOr<void> Program::global_declaration_instantiation(VM& vm, Global
|
|||
// 4. For each element name of varNames, do
|
||||
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(Utf16FlyString::from_utf8(identifier.string())))
|
||||
if (global_environment.has_lexical_declaration(identifier.string()))
|
||||
return vm.throw_completion<SyntaxError>(ErrorType::TopLevelVariableAlreadyDeclared, identifier.string());
|
||||
|
||||
return {};
|
||||
|
@ -1735,7 +1736,7 @@ ThrowCompletionOr<void> Program::global_declaration_instantiation(VM& vm, Global
|
|||
// 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());
|
||||
auto function_name = 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.
|
||||
|
@ -1754,7 +1755,7 @@ ThrowCompletionOr<void> Program::global_declaration_instantiation(VM& vm, Global
|
|||
|
||||
// 2. 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);
|
||||
|
||||
// 3. Append fn to declaredFunctionNames.
|
||||
// Note: Already done in step iv. above.
|
||||
|
@ -1776,7 +1777,7 @@ ThrowCompletionOr<void> Program::global_declaration_instantiation(VM& vm, Global
|
|||
|
||||
// i. For each String vn of the BoundNames of d, do
|
||||
return declaration.for_each_bound_identifier([&](Identifier const& identifier) -> ThrowCompletionOr<void> {
|
||||
auto name = Utf16FlyString::from_utf8(identifier.string());
|
||||
auto const& name = identifier.string();
|
||||
|
||||
// 1. If vn is not an element of declaredFunctionNames, then
|
||||
if (declared_function_names.contains(name))
|
||||
|
@ -1806,7 +1807,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 = Utf16FlyString::from_utf8(function_declaration.name());
|
||||
auto function_name = 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.
|
||||
|
@ -1858,7 +1859,7 @@ ThrowCompletionOr<void> Program::global_declaration_instantiation(VM& vm, Global
|
|||
// 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([&](Identifier const& identifier) -> ThrowCompletionOr<void> {
|
||||
auto name = Utf16FlyString::from_utf8(identifier.string());
|
||||
auto const& name = identifier.string();
|
||||
|
||||
// i. If IsConstantDeclaration of d is true, then
|
||||
if (declaration.is_constant_declaration()) {
|
||||
|
@ -1884,7 +1885,7 @@ 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,
|
||||
Utf16FlyString::from_utf8(declaration.name()),
|
||||
declaration.name(),
|
||||
realm,
|
||||
&global_environment,
|
||||
private_environment);
|
||||
|
@ -1903,7 +1904,7 @@ ThrowCompletionOr<void> Program::global_declaration_instantiation(VM& vm, Global
|
|||
return {};
|
||||
}
|
||||
|
||||
ModuleRequest::ModuleRequest(FlyString module_specifier_, Vector<ImportAttribute> attributes)
|
||||
ModuleRequest::ModuleRequest(Utf16FlyString module_specifier_, Vector<ImportAttribute> attributes)
|
||||
: module_specifier(move(module_specifier_))
|
||||
, attributes(move(attributes))
|
||||
{
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include <AK/FlyString.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <AK/Utf16FlyString.h>
|
||||
#include <AK/Utf16String.h>
|
||||
#include <AK/Variant.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibGC/Root.h>
|
||||
|
@ -343,7 +345,7 @@ public:
|
|||
ThrowCompletionOr<void> for_each_function_hoistable_with_annexB_extension(ThrowCompletionOrVoidCallback<FunctionDeclaration&>&& callback) const;
|
||||
|
||||
auto const& local_variables_names() const { return m_local_variables_names; }
|
||||
size_t add_local_variable(FlyString name, LocalVariable::DeclarationKind declaration_kind)
|
||||
size_t add_local_variable(Utf16FlyString name, LocalVariable::DeclarationKind declaration_kind)
|
||||
{
|
||||
auto index = m_local_variables_names.size();
|
||||
m_local_variables_names.append({ move(name), declaration_kind });
|
||||
|
@ -370,10 +372,10 @@ private:
|
|||
|
||||
// ImportEntry Record, https://tc39.es/ecma262/#table-importentry-record-fields
|
||||
struct ImportEntry {
|
||||
Optional<FlyString> import_name; // [[ImportName]]: stored string if Optional is not empty, NAMESPACE-OBJECT otherwise
|
||||
FlyString local_name; // [[LocalName]]
|
||||
Optional<Utf16FlyString> import_name; // [[ImportName]]: stored string if Optional is not empty, NAMESPACE-OBJECT otherwise
|
||||
Utf16FlyString local_name; // [[LocalName]]
|
||||
|
||||
ImportEntry(Optional<FlyString> import_name_, FlyString local_name_)
|
||||
ImportEntry(Optional<Utf16FlyString> import_name_, Utf16FlyString local_name_)
|
||||
: import_name(move(import_name_))
|
||||
, local_name(move(local_name_))
|
||||
{
|
||||
|
@ -407,7 +409,7 @@ public:
|
|||
|
||||
virtual Bytecode::CodeGenerationErrorOr<Optional<Bytecode::ScopedOperand>> generate_bytecode(Bytecode::Generator&, Optional<Bytecode::ScopedOperand> preferred_dst = {}) const override;
|
||||
|
||||
bool has_bound_name(FlyString const& name) const;
|
||||
bool has_bound_name(Utf16FlyString const& name) const;
|
||||
Vector<ImportEntry> const& entries() const { return m_entries; }
|
||||
ModuleRequest const& module_request() const { return m_module_request; }
|
||||
|
||||
|
@ -429,10 +431,10 @@ struct ExportEntry {
|
|||
EmptyNamedExport,
|
||||
} kind;
|
||||
|
||||
Optional<FlyString> export_name; // [[ExportName]]
|
||||
Optional<FlyString> local_or_import_name; // Either [[ImportName]] or [[LocalName]]
|
||||
Optional<Utf16FlyString> export_name; // [[ExportName]]
|
||||
Optional<Utf16FlyString> local_or_import_name; // Either [[ImportName]] or [[LocalName]]
|
||||
|
||||
ExportEntry(Kind export_kind, Optional<FlyString> export_name_, Optional<FlyString> local_or_import_name_)
|
||||
ExportEntry(Kind export_kind, Optional<Utf16FlyString> export_name_, Optional<Utf16FlyString> local_or_import_name_)
|
||||
: kind(export_kind)
|
||||
, export_name(move(export_name_))
|
||||
, local_or_import_name(move(local_or_import_name_))
|
||||
|
@ -444,7 +446,7 @@ struct ExportEntry {
|
|||
return m_module_request != nullptr;
|
||||
}
|
||||
|
||||
static ExportEntry indirect_export_entry(ModuleRequest const& module_request, Optional<FlyString> export_name, Optional<FlyString> import_name)
|
||||
static ExportEntry indirect_export_entry(ModuleRequest const& module_request, Optional<Utf16FlyString> export_name, Optional<Utf16FlyString> import_name)
|
||||
{
|
||||
ExportEntry entry { Kind::NamedExport, move(export_name), move(import_name) };
|
||||
entry.m_module_request = &module_request;
|
||||
|
@ -462,7 +464,7 @@ private:
|
|||
friend class ExportStatement;
|
||||
|
||||
public:
|
||||
static ExportEntry named_export(FlyString export_name, FlyString local_name)
|
||||
static ExportEntry named_export(Utf16FlyString export_name, Utf16FlyString local_name)
|
||||
{
|
||||
return ExportEntry { Kind::NamedExport, move(export_name), move(local_name) };
|
||||
}
|
||||
|
@ -472,7 +474,7 @@ public:
|
|||
return ExportEntry { Kind::ModuleRequestAllButDefault, {}, {} };
|
||||
}
|
||||
|
||||
static ExportEntry all_module_request(FlyString export_name)
|
||||
static ExportEntry all_module_request(Utf16FlyString export_name)
|
||||
{
|
||||
return ExportEntry { Kind::ModuleRequestAll, move(export_name), {} };
|
||||
}
|
||||
|
@ -485,7 +487,7 @@ public:
|
|||
|
||||
class ExportStatement final : public Statement {
|
||||
public:
|
||||
static FlyString local_name_for_default;
|
||||
static Utf16FlyString local_name_for_default;
|
||||
|
||||
ExportStatement(SourceRange source_range, RefPtr<ASTNode const> statement, Vector<ExportEntry> entries, bool is_default_export, Optional<ModuleRequest> module_request)
|
||||
: Statement(move(source_range))
|
||||
|
@ -504,7 +506,7 @@ public:
|
|||
|
||||
virtual Bytecode::CodeGenerationErrorOr<Optional<Bytecode::ScopedOperand>> generate_bytecode(Bytecode::Generator&, Optional<Bytecode::ScopedOperand> preferred_dst = {}) const override;
|
||||
|
||||
bool has_export(FlyString const& export_name) const;
|
||||
bool has_export(Utf16FlyString const& export_name) const;
|
||||
|
||||
bool has_statement() const { return m_statement; }
|
||||
Vector<ExportEntry> const& entries() const { return m_entries; }
|
||||
|
@ -676,13 +678,13 @@ struct BindingPattern : RefCounted<BindingPattern> {
|
|||
|
||||
class Identifier final : public Expression {
|
||||
public:
|
||||
explicit Identifier(SourceRange source_range, FlyString string)
|
||||
explicit Identifier(SourceRange source_range, Utf16FlyString string)
|
||||
: Expression(move(source_range))
|
||||
, m_string(move(string))
|
||||
{
|
||||
}
|
||||
|
||||
FlyString const& string() const { return m_string; }
|
||||
Utf16FlyString const& string() const { return m_string; }
|
||||
|
||||
struct Local {
|
||||
enum Type {
|
||||
|
@ -720,7 +722,7 @@ public:
|
|||
private:
|
||||
virtual bool is_identifier() const override { return true; }
|
||||
|
||||
FlyString m_string;
|
||||
Utf16FlyString m_string;
|
||||
|
||||
Optional<Local> m_local_index;
|
||||
bool m_is_global { false };
|
||||
|
@ -748,7 +750,7 @@ public:
|
|||
size_t size() const { return m_parameters.size(); }
|
||||
Vector<FunctionParameter> const& parameters() const { return m_parameters; }
|
||||
|
||||
Optional<size_t> get_index_of_parameter_name(FlyString const& name) const
|
||||
Optional<size_t> get_index_of_parameter_name(Utf16FlyString const& name) const
|
||||
{
|
||||
// Iterate backwards to return the last parameter with the same name
|
||||
for (int i = m_parameters.size() - 1; i >= 0; i--) {
|
||||
|
@ -780,7 +782,7 @@ struct FunctionParsingInsights {
|
|||
|
||||
class FunctionNode {
|
||||
public:
|
||||
FlyString name() const { return m_name ? m_name->string() : ""_fly_string; }
|
||||
Utf16FlyString name() const { return m_name ? m_name->string() : Utf16FlyString {}; }
|
||||
RefPtr<Identifier const> name_identifier() const { return m_name; }
|
||||
ByteString const& source_text() const { return m_source_text; }
|
||||
Statement const& body() const { return *m_body; }
|
||||
|
@ -1303,7 +1305,7 @@ private:
|
|||
|
||||
class StringLiteral final : public Expression {
|
||||
public:
|
||||
explicit StringLiteral(SourceRange source_range, String value)
|
||||
explicit StringLiteral(SourceRange source_range, Utf16String value)
|
||||
: Expression(move(source_range))
|
||||
, m_value(move(value))
|
||||
{
|
||||
|
@ -1312,12 +1314,12 @@ public:
|
|||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<Optional<Bytecode::ScopedOperand>> generate_bytecode(Bytecode::Generator&, Optional<Bytecode::ScopedOperand> preferred_dst = {}) const override;
|
||||
|
||||
String const& value() const { return m_value; }
|
||||
Utf16String const& value() const { return m_value; }
|
||||
|
||||
private:
|
||||
virtual bool is_string_literal() const override { return true; }
|
||||
|
||||
String m_value;
|
||||
Utf16String m_value;
|
||||
};
|
||||
|
||||
class NullLiteral final : public PrimitiveLiteral {
|
||||
|
@ -1367,20 +1369,20 @@ private:
|
|||
|
||||
class PrivateIdentifier final : public Expression {
|
||||
public:
|
||||
explicit PrivateIdentifier(SourceRange source_range, FlyString string)
|
||||
explicit PrivateIdentifier(SourceRange source_range, Utf16FlyString string)
|
||||
: Expression(move(source_range))
|
||||
, m_string(move(string))
|
||||
{
|
||||
}
|
||||
|
||||
FlyString const& string() const { return m_string; }
|
||||
Utf16FlyString const& string() const { return m_string; }
|
||||
|
||||
virtual void dump(int indent) const override;
|
||||
|
||||
virtual bool is_private_identifier() const override { return true; }
|
||||
|
||||
private:
|
||||
FlyString m_string;
|
||||
Utf16FlyString m_string;
|
||||
};
|
||||
|
||||
class ClassElement : public ASTNode {
|
||||
|
@ -1404,7 +1406,7 @@ public:
|
|||
using ClassValue = Variant<ClassFieldDefinition, Completion, PrivateElement>;
|
||||
virtual ThrowCompletionOr<ClassValue> class_element_evaluation(VM&, Object& home_object, Value) const = 0;
|
||||
|
||||
virtual Optional<FlyString> private_bound_identifier() const { return {}; }
|
||||
virtual Optional<Utf16FlyString> private_bound_identifier() const { return {}; }
|
||||
|
||||
private:
|
||||
bool m_is_static { false };
|
||||
|
@ -1432,7 +1434,7 @@ public:
|
|||
|
||||
virtual void dump(int indent) const override;
|
||||
virtual ThrowCompletionOr<ClassValue> class_element_evaluation(VM&, Object& home_object, Value property_key) const override;
|
||||
virtual Optional<FlyString> private_bound_identifier() const override;
|
||||
virtual Optional<Utf16FlyString> private_bound_identifier() const override;
|
||||
|
||||
private:
|
||||
virtual bool is_class_method() const override { return true; }
|
||||
|
@ -1458,7 +1460,7 @@ public:
|
|||
|
||||
virtual void dump(int indent) const override;
|
||||
virtual ThrowCompletionOr<ClassValue> class_element_evaluation(VM&, Object& home_object, Value property_key) const override;
|
||||
virtual Optional<FlyString> private_bound_identifier() const override;
|
||||
virtual Optional<Utf16FlyString> private_bound_identifier() const override;
|
||||
|
||||
private:
|
||||
NonnullRefPtr<Expression const> m_key;
|
||||
|
@ -1507,7 +1509,7 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
FlyString name() const { return m_name ? m_name->string() : ""_fly_string; }
|
||||
Utf16FlyString name() const { return m_name ? m_name->string() : Utf16FlyString {}; }
|
||||
|
||||
ByteString const& source_text() const { return m_source_text; }
|
||||
RefPtr<FunctionExpression const> constructor() const { return m_constructor; }
|
||||
|
@ -1547,7 +1549,7 @@ public:
|
|||
|
||||
virtual bool is_lexical_declaration() const override { return true; }
|
||||
|
||||
FlyString name() const { return m_class_expression->name(); }
|
||||
Utf16FlyString name() const { return m_class_expression->name(); }
|
||||
|
||||
private:
|
||||
virtual bool is_class_declaration() const override { return true; }
|
||||
|
@ -1651,7 +1653,7 @@ protected:
|
|||
|
||||
virtual bool is_call_expression() const override { return true; }
|
||||
|
||||
Optional<String> expression_string() const;
|
||||
Optional<Utf16String> expression_string() const;
|
||||
|
||||
NonnullRefPtr<Expression const> m_callee;
|
||||
};
|
||||
|
@ -1994,7 +1996,7 @@ public:
|
|||
Expression const& object() const { return *m_object; }
|
||||
Expression const& property() const { return *m_property; }
|
||||
|
||||
[[nodiscard]] String to_string_approximation() const;
|
||||
Utf16String to_string_approximation() const;
|
||||
|
||||
bool ends_in_private_name() const;
|
||||
|
||||
|
|
|
@ -1171,7 +1171,7 @@ Bytecode::CodeGenerationErrorOr<Optional<ScopedOperand>> ObjectExpression::gener
|
|||
|
||||
if (is<StringLiteral>(property->key())) {
|
||||
auto& string_literal = static_cast<StringLiteral const&>(property->key());
|
||||
Bytecode::IdentifierTableIndex key_name = generator.intern_identifier(MUST(FlyString::from_utf8(string_literal.value().bytes())));
|
||||
Bytecode::IdentifierTableIndex key_name = generator.intern_identifier(string_literal.value());
|
||||
|
||||
Optional<ScopedOperand> value;
|
||||
if (property_kind == Bytecode::Op::PropertyKind::ProtoSetter) {
|
||||
|
@ -1179,9 +1179,10 @@ Bytecode::CodeGenerationErrorOr<Optional<ScopedOperand>> ObjectExpression::gener
|
|||
} else {
|
||||
auto identifier = string_literal.value();
|
||||
if (property_kind == Bytecode::Op::PropertyKind::Getter)
|
||||
identifier = MUST(String::formatted("get {}", identifier));
|
||||
identifier = Utf16String::formatted("get {}", identifier);
|
||||
else if (property_kind == Bytecode::Op::PropertyKind::Setter)
|
||||
identifier = MUST(String::formatted("set {}", identifier));
|
||||
identifier = Utf16String::formatted("set {}", identifier);
|
||||
|
||||
auto name = generator.intern_identifier(identifier);
|
||||
value = TRY(generator.emit_named_evaluation_if_anonymous_function(property->value(), name));
|
||||
}
|
||||
|
@ -1769,7 +1770,7 @@ Bytecode::CodeGenerationErrorOr<Optional<ScopedOperand>> CallExpression::generat
|
|||
|
||||
Optional<Bytecode::StringTableIndex> expression_string_index;
|
||||
if (auto expression_string = this->expression_string(); expression_string.has_value())
|
||||
expression_string_index = generator.intern_string(expression_string.release_value());
|
||||
expression_string_index = generator.intern_string(expression_string->to_utf8_but_should_be_ported_to_utf16());
|
||||
|
||||
bool has_spread = any_of(arguments(), [](auto& argument) { return argument.is_spread; });
|
||||
auto dst = choose_dst(generator, preferred_dst);
|
||||
|
|
|
@ -915,7 +915,7 @@ static Optional<String> expression_identifier(Expression const& expression)
|
|||
{
|
||||
if (expression.is_identifier()) {
|
||||
auto const& identifier = static_cast<Identifier const&>(expression);
|
||||
return identifier.string().to_string();
|
||||
return identifier.string().view().to_utf8_but_should_be_ported_to_utf16();
|
||||
}
|
||||
|
||||
if (expression.is_numeric_literal()) {
|
||||
|
|
|
@ -1361,7 +1361,7 @@ inline Value new_function(VM& vm, FunctionNode const& function_node, Optional<Id
|
|||
} else {
|
||||
value = ECMAScriptFunctionObject::create_from_function_node(
|
||||
function_node,
|
||||
Utf16FlyString::from_utf8(function_node.name()),
|
||||
function_node.name(),
|
||||
*vm.current_realm(),
|
||||
vm.lexical_environment(),
|
||||
vm.running_execution_context().private_environment);
|
||||
|
@ -1622,9 +1622,8 @@ inline ThrowCompletionOr<ECMAScriptFunctionObject*> new_class(VM& vm, Value supe
|
|||
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;
|
||||
class_name = class_expression.name();
|
||||
binding_name = class_name;
|
||||
}
|
||||
|
||||
return TRY(class_expression.create_class_constructor(vm, class_environment, vm.lexical_environment(), super_class, element_keys, binding_name, class_name));
|
||||
|
|
|
@ -6,12 +6,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/FlyString.h>
|
||||
#include <AK/Utf16FlyString.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
struct LocalVariable {
|
||||
FlyString name;
|
||||
enum class DeclarationKind {
|
||||
Var,
|
||||
LetOrConst,
|
||||
|
@ -19,6 +18,8 @@ struct LocalVariable {
|
|||
ArgumentsObject,
|
||||
CatchClauseParameter
|
||||
};
|
||||
|
||||
Utf16FlyString name;
|
||||
DeclarationKind declaration_kind;
|
||||
};
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ void finish_loading_imported_module(ImportedModuleReferrer referrer, ModuleReque
|
|||
|
||||
// i. Append the Record { [[Specifier]]: specifier, [[Module]]: result.[[Value]] } to referrer.[[LoadedModules]].
|
||||
loaded_modules.append(ModuleWithSpecifier {
|
||||
.specifier = module_request.module_specifier.to_string(),
|
||||
.specifier = module_request.module_specifier.to_utf16_string(),
|
||||
.module = GC::Ref<Module>(*module) });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -237,7 +237,7 @@ public:
|
|||
ScopePusher* parent_scope() { return m_parent_scope; }
|
||||
ScopePusher const* parent_scope() const { return m_parent_scope; }
|
||||
|
||||
[[nodiscard]] bool has_declaration(FlyString const& name) const
|
||||
[[nodiscard]] bool has_declaration(Utf16FlyString const& name) const
|
||||
{
|
||||
return m_lexical_names.contains(name) || m_var_names.contains(name) || !m_functions_to_hoist.find_if([&name](auto& function) { return function->name() == name; }).is_end();
|
||||
}
|
||||
|
@ -496,7 +496,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
void throw_identifier_declared(FlyString const& name, NonnullRefPtr<Declaration const> const& declaration)
|
||||
void throw_identifier_declared(Utf16FlyString const& name, NonnullRefPtr<Declaration const> const& declaration)
|
||||
{
|
||||
m_parser.syntax_error(MUST(String::formatted("Identifier '{}' already declared", name)), declaration->source_range().start);
|
||||
}
|
||||
|
@ -509,17 +509,17 @@ private:
|
|||
ScopePusher* m_parent_scope { nullptr };
|
||||
ScopePusher* m_top_level_scope { nullptr };
|
||||
|
||||
HashTable<FlyString> m_lexical_names;
|
||||
HashTable<FlyString> m_var_names;
|
||||
HashTable<FlyString> m_function_names;
|
||||
HashTable<FlyString> m_catch_parameter_names;
|
||||
HashTable<Utf16FlyString> m_lexical_names;
|
||||
HashTable<Utf16FlyString> m_var_names;
|
||||
HashTable<Utf16FlyString> m_function_names;
|
||||
HashTable<Utf16FlyString> m_catch_parameter_names;
|
||||
|
||||
HashTable<FlyString> m_forbidden_lexical_names;
|
||||
HashTable<FlyString> m_forbidden_var_names;
|
||||
HashTable<Utf16FlyString> m_forbidden_lexical_names;
|
||||
HashTable<Utf16FlyString> m_forbidden_var_names;
|
||||
Vector<NonnullRefPtr<FunctionDeclaration const>> m_functions_to_hoist;
|
||||
|
||||
HashTable<FlyString> m_bound_names;
|
||||
HashTable<FlyString> m_function_parameters_candidates_for_local_variables;
|
||||
HashTable<Utf16FlyString> m_bound_names;
|
||||
HashTable<Utf16FlyString> m_function_parameters_candidates_for_local_variables;
|
||||
|
||||
struct IdentifierGroup {
|
||||
bool captured_by_nested_function { false };
|
||||
|
@ -529,7 +529,7 @@ private:
|
|||
Vector<NonnullRefPtr<Identifier>> identifiers;
|
||||
Optional<DeclarationKind> declaration_kind;
|
||||
};
|
||||
HashMap<FlyString, IdentifierGroup> m_identifier_groups;
|
||||
HashMap<Utf16FlyString, IdentifierGroup> m_identifier_groups;
|
||||
|
||||
RefPtr<FunctionParameters const> m_function_parameters;
|
||||
|
||||
|
@ -983,20 +983,11 @@ bool Parser::match_invalid_escaped_keyword() const
|
|||
return token_value != "let"sv;
|
||||
}
|
||||
|
||||
static constexpr AK::Array<StringView, 9> strict_reserved_words = { "implements"sv, "interface"sv, "let"sv, "package"sv, "private"sv, "protected"sv, "public"sv, "static"sv, "yield"sv };
|
||||
static auto strict_reserved_words = AK::Array { "implements"_utf16_fly_string, "interface"_utf16_fly_string, "let"_utf16_fly_string, "package"_utf16_fly_string, "private"_utf16_fly_string, "protected"_utf16_fly_string, "public"_utf16_fly_string, "static"_utf16_fly_string, "yield"_utf16_fly_string };
|
||||
|
||||
static bool is_strict_reserved_word(StringView str)
|
||||
static bool is_strict_reserved_word(Utf16FlyString const& str)
|
||||
{
|
||||
return any_of(strict_reserved_words, [&str](StringView word) {
|
||||
return word == str;
|
||||
});
|
||||
}
|
||||
|
||||
static bool is_strict_reserved_word(Utf16View const& str)
|
||||
{
|
||||
return any_of(strict_reserved_words, [&str](StringView word) {
|
||||
return word == str;
|
||||
});
|
||||
return strict_reserved_words.contains_slow(str);
|
||||
}
|
||||
|
||||
static bool is_simple_parameter_list(FunctionParameters const& parameters)
|
||||
|
@ -1090,7 +1081,8 @@ RefPtr<FunctionExpression const> Parser::try_parse_arrow_function_expression(boo
|
|||
syntax_error("BindingIdentifier may not be 'arguments' or 'eval' in strict mode"_string);
|
||||
if (is_async && token.value() == "await"sv)
|
||||
syntax_error("'await' is a reserved identifier in async functions"_string);
|
||||
auto identifier = create_ast_node<Identifier const>({ m_source_code, rule_start.position(), position() }, token.value().to_utf8_but_should_be_ported_to_utf16());
|
||||
|
||||
auto identifier = create_ast_node<Identifier const>({ m_source_code, rule_start.position(), position() }, token.fly_string_value());
|
||||
parameters = FunctionParameters::create(Vector<FunctionParameter> { FunctionParameter { identifier, {} } });
|
||||
}
|
||||
|
||||
|
@ -1475,7 +1467,7 @@ NonnullRefPtr<ClassExpression const> Parser::parse_class_expression(bool expect_
|
|||
switch (m_state.current_token.type()) {
|
||||
case TokenType::Identifier:
|
||||
name = consume().fly_string_value();
|
||||
property_key = create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, name.view().to_utf8_but_should_be_ported_to_utf16());
|
||||
property_key = create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, name.to_utf16_string());
|
||||
break;
|
||||
case TokenType::PrivateIdentifier:
|
||||
name = consume().fly_string_value();
|
||||
|
@ -1512,11 +1504,11 @@ NonnullRefPtr<ClassExpression const> Parser::parse_class_expression(bool expect_
|
|||
syntax_error(MUST(String::formatted("Duplicate private field or method named '{}'", name)));
|
||||
}
|
||||
|
||||
property_key = create_ast_node<PrivateIdentifier>({ m_source_code, rule_start.position(), position() }, name.view().to_utf8_but_should_be_ported_to_utf16());
|
||||
property_key = create_ast_node<PrivateIdentifier>({ m_source_code, rule_start.position(), position() }, name);
|
||||
break;
|
||||
case TokenType::StringLiteral: {
|
||||
auto string_literal = parse_string_literal(consume());
|
||||
name = Utf16FlyString::from_utf8(string_literal->value());
|
||||
name = string_literal->value();
|
||||
property_key = move(string_literal);
|
||||
break;
|
||||
}
|
||||
|
@ -1552,7 +1544,7 @@ NonnullRefPtr<ClassExpression const> Parser::parse_class_expression(bool expect_
|
|||
break;
|
||||
}
|
||||
|
||||
property_key = create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, name.view().to_utf8_but_should_be_ported_to_utf16());
|
||||
property_key = create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, name.to_utf16_string());
|
||||
} else if (match(TokenType::CurlyOpen) && is_static) {
|
||||
auto static_start = push_start();
|
||||
consume(TokenType::CurlyOpen);
|
||||
|
@ -1657,11 +1649,11 @@ NonnullRefPtr<ClassExpression const> Parser::parse_class_expression(bool expect_
|
|||
// this function does not.
|
||||
// So we use a custom version of SuperCall which doesn't use the @@iterator
|
||||
// method on %Array.prototype% visibly.
|
||||
auto argument_name = create_ast_node<Identifier const>({ m_source_code, rule_start.position(), position() }, "args"_fly_string);
|
||||
auto argument_name = create_ast_node<Identifier const>({ m_source_code, rule_start.position(), position() }, "args"_utf16_fly_string);
|
||||
auto super_call = create_ast_node<SuperCall>(
|
||||
{ m_source_code, rule_start.position(), position() },
|
||||
SuperCall::IsPartOfSyntheticConstructor::Yes,
|
||||
CallExpression::Argument { create_ast_node<Identifier>({ m_source_code, rule_start.position(), position() }, "args"_fly_string), true });
|
||||
CallExpression::Argument { create_ast_node<Identifier>({ m_source_code, rule_start.position(), position() }, "args"_utf16_fly_string), true });
|
||||
// NOTE: While the JS approximation above doesn't do `return super(...args)`, the
|
||||
// abstract closure is expected to capture and return the result, so we do need a
|
||||
// return statement here to create the correct completion.
|
||||
|
@ -1767,7 +1759,7 @@ Parser::PrimaryExpressionParseResult Parser::parse_primary_expression()
|
|||
if (auto arrow_function_result = try_arrow_function_parse_or_fail(position(), false))
|
||||
return { arrow_function_result.release_nonnull(), false };
|
||||
|
||||
auto string = m_state.current_token.value();
|
||||
auto string = m_state.current_token.fly_string_value();
|
||||
// This could be 'eval' or 'arguments' and thus needs a custom check (`eval[1] = true`)
|
||||
if (m_state.strict_mode && (string == "let"sv || is_strict_reserved_word(string)))
|
||||
syntax_error(MUST(String::formatted("Identifier must not be a reserved word in strict mode ('{}')", string)));
|
||||
|
@ -1852,7 +1844,7 @@ Parser::PrimaryExpressionParseResult Parser::parse_primary_expression()
|
|||
syntax_error(MUST(String::formatted("Reference to undeclared private field or method '{}'", m_state.current_token.value())));
|
||||
if (next_token().type() != TokenType::In)
|
||||
syntax_error("Cannot have a private identifier in expression if not followed by 'in'"_string);
|
||||
return { create_ast_node<PrivateIdentifier>({ m_source_code, rule_start.position(), position() }, consume().value().to_utf8_but_should_be_ported_to_utf16()) };
|
||||
return { create_ast_node<PrivateIdentifier>({ m_source_code, rule_start.position(), position() }, consume().fly_string_value()) };
|
||||
default:
|
||||
if (match_identifier_name())
|
||||
goto read_as_identifier;
|
||||
|
@ -2015,7 +2007,7 @@ NonnullRefPtr<Expression const> Parser::parse_property_key()
|
|||
} else {
|
||||
if (!match_identifier_name())
|
||||
expected("IdentifierName");
|
||||
return create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, consume().value().to_utf8_but_should_be_ported_to_utf16());
|
||||
return create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, consume().fly_string_value().to_utf16_string());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2083,7 +2075,7 @@ NonnullRefPtr<ObjectExpression const> Parser::parse_object_expression()
|
|||
property_type = ObjectProperty::Type::Setter;
|
||||
property_key = parse_property_key();
|
||||
} else {
|
||||
property_key = create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, identifier.value().to_utf8_but_should_be_ported_to_utf16());
|
||||
property_key = create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, identifier.fly_string_value().to_utf16_string());
|
||||
property_value = create_identifier_and_register_in_current_scope({ m_source_code, rule_start.position(), position() }, identifier.fly_string_value());
|
||||
}
|
||||
} else {
|
||||
|
@ -2092,7 +2084,7 @@ NonnullRefPtr<ObjectExpression const> Parser::parse_object_expression()
|
|||
|
||||
// 4. Else if propKey is the String value "__proto__" and if IsComputedPropertyKey of PropertyName is false, then
|
||||
// a. Let isProtoSetter be true.
|
||||
bool is_proto = (type == TokenType::StringLiteral || type == TokenType::Identifier) && is<StringLiteral>(*property_key) && static_cast<StringLiteral const&>(*property_key).value() == "__proto__";
|
||||
bool is_proto = (type == TokenType::StringLiteral || type == TokenType::Identifier) && is<StringLiteral>(*property_key) && static_cast<StringLiteral const&>(*property_key).value() == "__proto__"sv;
|
||||
|
||||
if (property_type == ObjectProperty::Type::Getter || property_type == ObjectProperty::Type::Setter) {
|
||||
if (!match(TokenType::ParenOpen)) {
|
||||
|
@ -2240,7 +2232,7 @@ NonnullRefPtr<StringLiteral const> Parser::parse_string_literal(Token const& tok
|
|||
}
|
||||
}
|
||||
|
||||
return create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, string.to_utf8_but_should_be_ported_to_utf16());
|
||||
return create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, move(string));
|
||||
}
|
||||
|
||||
NonnullRefPtr<TemplateLiteral const> Parser::parse_template_literal(bool is_tagged)
|
||||
|
@ -2252,7 +2244,7 @@ NonnullRefPtr<TemplateLiteral const> Parser::parse_template_literal(bool is_tagg
|
|||
Vector<NonnullRefPtr<Expression const>> raw_strings;
|
||||
|
||||
auto append_empty_string = [this, &rule_start, &expressions, &raw_strings, is_tagged]() {
|
||||
auto string_literal = create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, ""_string);
|
||||
auto string_literal = create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, Utf16String {});
|
||||
expressions.append(string_literal);
|
||||
if (is_tagged)
|
||||
raw_strings.append(string_literal);
|
||||
|
@ -2274,7 +2266,7 @@ NonnullRefPtr<TemplateLiteral const> Parser::parse_template_literal(bool is_tagg
|
|||
else
|
||||
expressions.append(move(parsed_string_value));
|
||||
if (is_tagged)
|
||||
raw_strings.append(create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, token.raw_template_value().to_utf8_but_should_be_ported_to_utf16()));
|
||||
raw_strings.append(create_ast_node<StringLiteral>({ m_source_code, rule_start.position(), position() }, token.raw_template_value()));
|
||||
} else if (match(TokenType::TemplateLiteralExprStart)) {
|
||||
consume(TokenType::TemplateLiteralExprStart);
|
||||
if (match(TokenType::TemplateLiteralExprEnd)) {
|
||||
|
@ -2492,12 +2484,12 @@ Parser::ExpressionResult Parser::parse_secondary_expression(NonnullRefPtr<Expres
|
|||
else if (is<SuperExpression>(*lhs))
|
||||
syntax_error(MUST(String::formatted("Cannot access private field or method '{}' on super", m_state.current_token.value())));
|
||||
|
||||
return create_ast_node<MemberExpression>({ m_source_code, rule_start.position(), position() }, move(lhs), create_ast_node<PrivateIdentifier>({ m_source_code, rule_start.position(), position() }, consume().value().to_utf8_but_should_be_ported_to_utf16()));
|
||||
return create_ast_node<MemberExpression>({ m_source_code, rule_start.position(), position() }, move(lhs), create_ast_node<PrivateIdentifier>({ m_source_code, rule_start.position(), position() }, consume().fly_string_value()));
|
||||
} else if (!match_identifier_name()) {
|
||||
expected("IdentifierName");
|
||||
}
|
||||
|
||||
return create_ast_node<MemberExpression>({ m_source_code, rule_start.position(), position() }, move(lhs), create_ast_node<Identifier>({ m_source_code, rule_start.position(), position() }, consume_and_allow_division().value().to_utf8_but_should_be_ported_to_utf16()));
|
||||
return create_ast_node<MemberExpression>({ m_source_code, rule_start.position(), position() }, move(lhs), create_ast_node<Identifier>({ m_source_code, rule_start.position(), position() }, consume_and_allow_division().fly_string_value()));
|
||||
case TokenType::BracketOpen: {
|
||||
consume(TokenType::BracketOpen);
|
||||
auto expression = create_ast_node<MemberExpression>({ m_source_code, rule_start.position(), position() }, move(lhs), parse_expression(0), true);
|
||||
|
@ -2861,7 +2853,7 @@ NonnullRefPtr<FunctionBody const> Parser::parse_function_body(NonnullRefPtr<Func
|
|||
|
||||
// If the function contains 'use strict' we need to check the parameters (again).
|
||||
if (function_body->in_strict_mode() || function_kind != FunctionKind::Normal) {
|
||||
Vector<StringView> parameter_names;
|
||||
Vector<Utf16View> parameter_names;
|
||||
for (auto& parameter : parameters->parameters()) {
|
||||
parameter.binding.visit(
|
||||
[&](Identifier const& identifier) {
|
||||
|
@ -3091,7 +3083,7 @@ NonnullRefPtr<FunctionParameters const> Parser::parse_formal_parameters(int& fun
|
|||
syntax_error(message, Position { token.line_number(), token.line_column() });
|
||||
break;
|
||||
}
|
||||
return create_ast_node<Identifier const>({ m_source_code, rule_start.position(), position() }, token.value().to_utf8_but_should_be_ported_to_utf16());
|
||||
return create_ast_node<Identifier const>({ m_source_code, rule_start.position(), position() }, token.fly_string_value());
|
||||
};
|
||||
|
||||
while (match(TokenType::CurlyOpen) || match(TokenType::BracketOpen) || match_identifier() || match(TokenType::TripleDot)) {
|
||||
|
@ -3139,7 +3131,7 @@ NonnullRefPtr<FunctionParameters const> Parser::parse_formal_parameters(int& fun
|
|||
return FunctionParameters::create(move(parameters));
|
||||
}
|
||||
|
||||
static AK::Array<FlyString, 36> s_reserved_words = { "break"_fly_string, "case"_fly_string, "catch"_fly_string, "class"_fly_string, "const"_fly_string, "continue"_fly_string, "debugger"_fly_string, "default"_fly_string, "delete"_fly_string, "do"_fly_string, "else"_fly_string, "enum"_fly_string, "export"_fly_string, "extends"_fly_string, "false"_fly_string, "finally"_fly_string, "for"_fly_string, "function"_fly_string, "if"_fly_string, "import"_fly_string, "in"_fly_string, "instanceof"_fly_string, "new"_fly_string, "null"_fly_string, "return"_fly_string, "super"_fly_string, "switch"_fly_string, "this"_fly_string, "throw"_fly_string, "true"_fly_string, "try"_fly_string, "typeof"_fly_string, "var"_fly_string, "void"_fly_string, "while"_fly_string, "with"_fly_string };
|
||||
static auto s_reserved_words = AK::Array { "break"_utf16_fly_string, "case"_utf16_fly_string, "catch"_utf16_fly_string, "class"_utf16_fly_string, "const"_utf16_fly_string, "continue"_utf16_fly_string, "debugger"_utf16_fly_string, "default"_utf16_fly_string, "delete"_utf16_fly_string, "do"_utf16_fly_string, "else"_utf16_fly_string, "enum"_utf16_fly_string, "export"_utf16_fly_string, "extends"_utf16_fly_string, "false"_utf16_fly_string, "finally"_utf16_fly_string, "for"_utf16_fly_string, "function"_utf16_fly_string, "if"_utf16_fly_string, "import"_utf16_fly_string, "in"_utf16_fly_string, "instanceof"_utf16_fly_string, "new"_utf16_fly_string, "null"_utf16_fly_string, "return"_utf16_fly_string, "super"_utf16_fly_string, "switch"_utf16_fly_string, "this"_utf16_fly_string, "throw"_utf16_fly_string, "true"_utf16_fly_string, "try"_utf16_fly_string, "typeof"_utf16_fly_string, "var"_utf16_fly_string, "void"_utf16_fly_string, "while"_utf16_fly_string, "with"_utf16_fly_string };
|
||||
|
||||
RefPtr<BindingPattern const> Parser::parse_binding_pattern(Parser::AllowDuplicates allow_duplicates, Parser::AllowMemberExpressions allow_member_expressions)
|
||||
{
|
||||
|
@ -3328,7 +3320,7 @@ RefPtr<BindingPattern const> Parser::parse_binding_pattern(Parser::AllowDuplicat
|
|||
pattern->entries = move(entries);
|
||||
pattern->kind = kind;
|
||||
|
||||
Vector<StringView> bound_names;
|
||||
Vector<Utf16View> bound_names;
|
||||
// NOTE: Nothing in the callback throws an exception.
|
||||
MUST(pattern->for_each_bound_identifier([&](auto& identifier) {
|
||||
auto const& name = identifier.string();
|
||||
|
@ -3603,7 +3595,7 @@ NonnullRefPtr<OptionalChain const> Parser::parse_optional_chain(NonnullRefPtr<Ex
|
|||
auto start = position();
|
||||
auto private_identifier = consume();
|
||||
chain.append(OptionalChain::PrivateMemberReference {
|
||||
create_ast_node<PrivateIdentifier>({ m_source_code, start, position() }, private_identifier.value().to_utf8_but_should_be_ported_to_utf16()),
|
||||
create_ast_node<PrivateIdentifier>({ m_source_code, start, position() }, private_identifier.fly_string_value()),
|
||||
OptionalChain::Mode::Optional });
|
||||
break;
|
||||
}
|
||||
|
@ -3620,7 +3612,7 @@ NonnullRefPtr<OptionalChain const> Parser::parse_optional_chain(NonnullRefPtr<Ex
|
|||
auto start = position();
|
||||
auto identifier = consume_and_allow_division();
|
||||
chain.append(OptionalChain::MemberReference {
|
||||
create_ast_node<Identifier>({ m_source_code, start, position() }, identifier.value().to_utf8_but_should_be_ported_to_utf16()),
|
||||
create_ast_node<Identifier>({ m_source_code, start, position() }, identifier.fly_string_value()),
|
||||
OptionalChain::Mode::Optional,
|
||||
});
|
||||
} else {
|
||||
|
@ -3639,14 +3631,14 @@ NonnullRefPtr<OptionalChain const> Parser::parse_optional_chain(NonnullRefPtr<Ex
|
|||
auto start = position();
|
||||
auto private_identifier = consume();
|
||||
chain.append(OptionalChain::PrivateMemberReference {
|
||||
create_ast_node<PrivateIdentifier>({ m_source_code, start, position() }, private_identifier.value().to_utf8_but_should_be_ported_to_utf16()),
|
||||
create_ast_node<PrivateIdentifier>({ m_source_code, start, position() }, private_identifier.fly_string_value()),
|
||||
OptionalChain::Mode::NotOptional,
|
||||
});
|
||||
} else if (match_identifier_name()) {
|
||||
auto start = position();
|
||||
auto identifier = consume_and_allow_division();
|
||||
chain.append(OptionalChain::MemberReference {
|
||||
create_ast_node<Identifier>({ m_source_code, start, position() }, identifier.value().to_utf8_but_should_be_ported_to_utf16()),
|
||||
create_ast_node<Identifier>({ m_source_code, start, position() }, identifier.fly_string_value()),
|
||||
OptionalChain::Mode::NotOptional,
|
||||
});
|
||||
} else {
|
||||
|
@ -3835,7 +3827,7 @@ NonnullRefPtr<CatchClause const> Parser::parse_catch_clause()
|
|||
if (should_expect_parameter && !parameter && !pattern_parameter)
|
||||
expected("an identifier or a binding pattern");
|
||||
|
||||
HashTable<FlyString> bound_names;
|
||||
HashTable<Utf16FlyString> bound_names;
|
||||
|
||||
if (pattern_parameter) {
|
||||
// NOTE: Nothing in the callback throws an exception.
|
||||
|
@ -4511,7 +4503,7 @@ Token Parser::consume(TokenType expected_type)
|
|||
}
|
||||
auto token = expected_type == TokenType::Identifier ? consume_and_allow_division() : consume();
|
||||
if (expected_type == TokenType::Identifier) {
|
||||
if (m_state.strict_mode && is_strict_reserved_word(token.value()))
|
||||
if (m_state.strict_mode && is_strict_reserved_word(token.fly_string_value()))
|
||||
syntax_error(MUST(String::formatted("Identifier must not be a reserved word in strict mode ('{}')", token.value())));
|
||||
}
|
||||
return token;
|
||||
|
@ -4585,19 +4577,6 @@ void Parser::discard_saved_state()
|
|||
m_saved_state.take_last();
|
||||
}
|
||||
|
||||
void Parser::check_identifier_name_for_assignment_validity(FlyString const& name, bool force_strict)
|
||||
{
|
||||
// FIXME: this is now called from multiple places maybe the error message should be dynamic?
|
||||
if (any_of(s_reserved_words, [&](auto& value) { return name == value; })) {
|
||||
syntax_error("Binding pattern target may not be a reserved word"_string);
|
||||
} else if (m_state.strict_mode || force_strict) {
|
||||
if (name.is_one_of("arguments"sv, "eval"sv))
|
||||
syntax_error("Binding pattern target may not be called 'arguments' or 'eval' in strict mode"_string);
|
||||
else if (is_strict_reserved_word(name))
|
||||
syntax_error(MUST(String::formatted("Binding pattern target may not be called '{}' in strict mode", name)));
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::check_identifier_name_for_assignment_validity(Utf16FlyString const& name, bool force_strict)
|
||||
{
|
||||
// FIXME: this is now called from multiple places maybe the error message should be dynamic?
|
||||
|
@ -4611,24 +4590,20 @@ void Parser::check_identifier_name_for_assignment_validity(Utf16FlyString const&
|
|||
}
|
||||
}
|
||||
|
||||
FlyString Parser::consume_string_value()
|
||||
Utf16FlyString Parser::consume_string_value()
|
||||
{
|
||||
VERIFY(match(TokenType::StringLiteral));
|
||||
auto string_token = consume();
|
||||
FlyString value = parse_string_literal(string_token)->value();
|
||||
auto value = parse_string_literal(string_token)->value();
|
||||
|
||||
// This also checks IsStringWellFormedUnicode which makes sure there is no unpaired surrogate
|
||||
// Surrogates are at least 3 bytes
|
||||
if (value.bytes().size() < 3)
|
||||
if (value.is_empty())
|
||||
return value;
|
||||
|
||||
Utf8View view { value.bytes_as_string_view().substring_view(value.bytes().size() - 3) };
|
||||
VERIFY(view.length() <= 3);
|
||||
auto codepoint = *view.begin();
|
||||
if (AK::UnicodeUtils::is_utf16_high_surrogate(codepoint)) {
|
||||
auto last_code_unit = value.code_unit_at(value.length_in_code_units() - 1);
|
||||
|
||||
if (AK::UnicodeUtils::is_utf16_high_surrogate(last_code_unit))
|
||||
syntax_error("StringValue ending with unpaired high surrogate"_string);
|
||||
VERIFY(view.length() == 1);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
@ -4640,7 +4615,7 @@ ModuleRequest Parser::parse_module_request()
|
|||
|
||||
if (!match(TokenType::StringLiteral)) {
|
||||
expected("ModuleSpecifier (string)");
|
||||
return ModuleRequest { "!!invalid!!"_fly_string };
|
||||
return ModuleRequest { "!!invalid!!"_utf16_fly_string };
|
||||
}
|
||||
|
||||
ModuleRequest request { consume_string_value() };
|
||||
|
@ -4652,12 +4627,12 @@ ModuleRequest Parser::parse_module_request()
|
|||
consume(TokenType::CurlyOpen);
|
||||
|
||||
while (!done() && !match(TokenType::CurlyClose)) {
|
||||
String key;
|
||||
Utf16String key;
|
||||
if (match(TokenType::StringLiteral)) {
|
||||
key = parse_string_literal(m_state.current_token)->value();
|
||||
consume();
|
||||
} else if (match_identifier_name()) {
|
||||
key = consume().value().to_utf8_but_should_be_ported_to_utf16();
|
||||
key = consume().fly_string_value().to_utf16_string();
|
||||
} else {
|
||||
expected("IdentifierName or StringValue as WithKey");
|
||||
consume();
|
||||
|
@ -4685,7 +4660,7 @@ ModuleRequest Parser::parse_module_request()
|
|||
return request;
|
||||
}
|
||||
|
||||
static FlyString default_string_value = "default"_fly_string;
|
||||
static auto default_string_value = "default"_utf16_fly_string;
|
||||
|
||||
// https://tc39.es/ecma262/#prod-ImportDeclaration
|
||||
NonnullRefPtr<ImportStatement const> Parser::parse_import_statement(Program& program)
|
||||
|
@ -4734,8 +4709,8 @@ NonnullRefPtr<ImportStatement const> Parser::parse_import_statement(Program& pro
|
|||
if (match_imported_binding()) {
|
||||
// ImportedDefaultBinding : ImportedBinding
|
||||
auto id_position = position();
|
||||
auto bound_name = consume().value().to_utf8_but_should_be_ported_to_utf16();
|
||||
entries_with_location.append({ { default_string_value, bound_name }, id_position });
|
||||
auto bound_name = consume().fly_string_value();
|
||||
entries_with_location.append({ { default_string_value, move(bound_name) }, id_position });
|
||||
|
||||
if (match(TokenType::Comma)) {
|
||||
consume(TokenType::Comma);
|
||||
|
@ -4757,8 +4732,8 @@ NonnullRefPtr<ImportStatement const> Parser::parse_import_statement(Program& pro
|
|||
|
||||
if (match_imported_binding()) {
|
||||
auto namespace_position = position();
|
||||
auto namespace_name = consume().value().to_utf8_but_should_be_ported_to_utf16();
|
||||
entries_with_location.append({ ImportEntry({}, namespace_name), namespace_position });
|
||||
auto namespace_name = consume().fly_string_value();
|
||||
entries_with_location.append({ ImportEntry({}, move(namespace_name)), namespace_position });
|
||||
} else {
|
||||
syntax_error(MUST(String::formatted("Unexpected token: {}", m_state.current_token.name())));
|
||||
}
|
||||
|
@ -4773,16 +4748,16 @@ NonnullRefPtr<ImportStatement const> Parser::parse_import_statement(Program& pro
|
|||
// ImportSpecifier : ImportedBinding
|
||||
auto require_as = !match_imported_binding();
|
||||
auto name_position = position();
|
||||
auto name = consume().value().to_utf8_but_should_be_ported_to_utf16();
|
||||
auto name = consume().fly_string_value();
|
||||
|
||||
if (match_as()) {
|
||||
consume(TokenType::Identifier);
|
||||
|
||||
auto alias_position = position();
|
||||
auto alias = consume_identifier().value().to_utf8_but_should_be_ported_to_utf16();
|
||||
auto alias = consume_identifier().fly_string_value();
|
||||
check_identifier_name_for_assignment_validity(alias);
|
||||
|
||||
entries_with_location.append({ { name, alias }, alias_position });
|
||||
entries_with_location.append({ { move(name), move(alias) }, alias_position });
|
||||
} else if (require_as) {
|
||||
syntax_error(MUST(String::formatted("Unexpected reserved word '{}'", name)));
|
||||
} else {
|
||||
|
@ -4800,10 +4775,10 @@ NonnullRefPtr<ImportStatement const> Parser::parse_import_statement(Program& pro
|
|||
consume(TokenType::Identifier);
|
||||
|
||||
auto alias_position = position();
|
||||
auto alias = consume_identifier().value().to_utf8_but_should_be_ported_to_utf16();
|
||||
auto alias = consume_identifier().fly_string_value();
|
||||
check_identifier_name_for_assignment_validity(alias);
|
||||
|
||||
entries_with_location.append({ { move(name), alias }, alias_position });
|
||||
entries_with_location.append({ { move(name), move(alias) }, alias_position });
|
||||
} else {
|
||||
expected("identifier");
|
||||
break;
|
||||
|
@ -4892,7 +4867,7 @@ NonnullRefPtr<ExportStatement const> Parser::parse_export_statement(Program& pro
|
|||
auto default_position = position();
|
||||
consume(TokenType::Default);
|
||||
|
||||
Optional<FlyString> local_name;
|
||||
Optional<Utf16FlyString> local_name;
|
||||
|
||||
auto lookahead_token = next_token();
|
||||
|
||||
|
@ -4992,7 +4967,7 @@ NonnullRefPtr<ExportStatement const> Parser::parse_export_statement(Program& pro
|
|||
}
|
||||
} else {
|
||||
expected("Declaration or assignment expression");
|
||||
local_name = "!!invalid!!"_fly_string;
|
||||
local_name = "!!invalid!!"_utf16_fly_string;
|
||||
}
|
||||
|
||||
if (!local_name.has_value())
|
||||
|
@ -5006,13 +4981,13 @@ NonnullRefPtr<ExportStatement const> Parser::parse_export_statement(Program& pro
|
|||
Required
|
||||
} check_for_from { FromSpecifier::NotAllowed };
|
||||
|
||||
auto parse_module_export_name = [&](bool lhs) -> FlyString {
|
||||
auto parse_module_export_name = [&](bool lhs) -> Utf16FlyString {
|
||||
// https://tc39.es/ecma262/#prod-ModuleExportName
|
||||
// ModuleExportName :
|
||||
// IdentifierName
|
||||
// StringLiteral
|
||||
if (match_identifier_name()) {
|
||||
return consume().value().to_utf8_but_should_be_ported_to_utf16();
|
||||
return consume().fly_string_value();
|
||||
}
|
||||
if (match(TokenType::StringLiteral)) {
|
||||
// It is a Syntax Error if ReferencedBindings of NamedExports contains any StringLiterals.
|
||||
|
@ -5139,7 +5114,7 @@ NonnullRefPtr<ExportStatement const> Parser::parse_export_statement(Program& pro
|
|||
|
||||
for (auto& entry : entries_with_location) {
|
||||
for (auto& export_statement : program.exports()) {
|
||||
if (export_statement->has_export(entry.entry.export_name.value_or(""_fly_string)))
|
||||
if (export_statement->has_export(entry.entry.export_name.value_or({})))
|
||||
syntax_error(MUST(String::formatted("Duplicate export with name: '{}'", entry.entry.export_name)), entry.position);
|
||||
}
|
||||
|
||||
|
@ -5231,7 +5206,7 @@ Parser::ForbiddenTokens Parser::ForbiddenTokens::forbid(std::initializer_list<To
|
|||
template JS_API NonnullRefPtr<FunctionExpression> Parser::parse_function_node(u16, Optional<Position> const&);
|
||||
template NonnullRefPtr<FunctionDeclaration> Parser::parse_function_node(u16, Optional<Position> const&);
|
||||
|
||||
NonnullRefPtr<Identifier const> Parser::create_identifier_and_register_in_current_scope(SourceRange range, FlyString string, Optional<DeclarationKind> declaration_kind)
|
||||
NonnullRefPtr<Identifier const> Parser::create_identifier_and_register_in_current_scope(SourceRange range, Utf16FlyString string, Optional<DeclarationKind> declaration_kind)
|
||||
{
|
||||
auto id = create_ast_node<Identifier const>(move(range), move(string));
|
||||
if (m_state.current_scope_pusher)
|
||||
|
@ -5239,11 +5214,6 @@ NonnullRefPtr<Identifier const> Parser::create_identifier_and_register_in_curren
|
|||
return id;
|
||||
}
|
||||
|
||||
NonnullRefPtr<Identifier const> Parser::create_identifier_and_register_in_current_scope(SourceRange range, Utf16FlyString const& string, Optional<DeclarationKind> declaration_kind)
|
||||
{
|
||||
return create_identifier_and_register_in_current_scope(move(range), string.view().to_utf8_but_should_be_ported_to_utf16(), declaration_kind);
|
||||
}
|
||||
|
||||
Parser Parser::parse_function_body_from_string(ByteString const& body_string, u16 parse_options, NonnullRefPtr<FunctionParameters const> parameters, FunctionKind kind, FunctionParsingInsights& parsing_insights)
|
||||
{
|
||||
RefPtr<FunctionBody const> function_body;
|
||||
|
|
|
@ -245,7 +245,6 @@ private:
|
|||
|
||||
Token next_token() const;
|
||||
|
||||
void check_identifier_name_for_assignment_validity(FlyString const&, bool force_strict = false);
|
||||
void check_identifier_name_for_assignment_validity(Utf16FlyString const&, bool force_strict = false);
|
||||
|
||||
bool try_parse_arrow_function_expression_failed_at_position(Position const&) const;
|
||||
|
@ -256,7 +255,7 @@ private:
|
|||
bool parse_directive(ScopeNode& body);
|
||||
void parse_statement_list(ScopeNode& output_node, AllowLabelledFunction allow_labelled_functions = AllowLabelledFunction::No);
|
||||
|
||||
FlyString consume_string_value();
|
||||
Utf16FlyString consume_string_value();
|
||||
ModuleRequest parse_module_request();
|
||||
|
||||
struct RulePosition {
|
||||
|
@ -319,8 +318,7 @@ private:
|
|||
ParserState(Lexer, Program::Type);
|
||||
};
|
||||
|
||||
[[nodiscard]] NonnullRefPtr<Identifier const> create_identifier_and_register_in_current_scope(SourceRange range, FlyString string, Optional<DeclarationKind> = {});
|
||||
[[nodiscard]] NonnullRefPtr<Identifier const> create_identifier_and_register_in_current_scope(SourceRange range, Utf16FlyString const& string, Optional<DeclarationKind> = {});
|
||||
[[nodiscard]] NonnullRefPtr<Identifier const> create_identifier_and_register_in_current_scope(SourceRange range, Utf16FlyString string, Optional<DeclarationKind> = {});
|
||||
|
||||
NonnullRefPtr<SourceCode const> m_source_code;
|
||||
Vector<Position> m_rule_starts;
|
||||
|
|
|
@ -771,7 +771,7 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, Program const& pr
|
|||
if (global_var_environment) {
|
||||
// i. For each element name of varNames, do
|
||||
TRY(program.for_each_var_declared_identifier([&](Identifier const& identifier) -> ThrowCompletionOr<void> {
|
||||
auto name = Utf16FlyString::from_utf8(identifier.string());
|
||||
auto const& name = identifier.string();
|
||||
|
||||
// 1. If varEnv.HasLexicalDeclaration(name) is true, throw a SyntaxError exception.
|
||||
if (global_var_environment->has_lexical_declaration(name))
|
||||
|
@ -793,7 +793,7 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, Program const& pr
|
|||
// 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([&](Identifier const& identifier) -> ThrowCompletionOr<void> {
|
||||
auto name = Utf16FlyString::from_utf8(identifier.string());
|
||||
auto const& name = identifier.string();
|
||||
|
||||
// a. If ! thisEnv.HasBinding(name) is true, then
|
||||
if (MUST(this_environment->has_binding(name))) {
|
||||
|
@ -831,7 +831,7 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, Program const& pr
|
|||
|
||||
// 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());
|
||||
auto function_name = 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.
|
||||
|
@ -874,7 +874,7 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, Program const& pr
|
|||
// 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 = Utf16FlyString::from_utf8(function_declaration.name());
|
||||
auto function_name = 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.
|
||||
|
@ -969,7 +969,7 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, Program const& pr
|
|||
|
||||
// i. For each String vn of the BoundNames of d, do
|
||||
return declaration.for_each_bound_identifier([&](Identifier const& identifier) -> ThrowCompletionOr<void> {
|
||||
auto name = Utf16FlyString::from_utf8(identifier.string());
|
||||
auto const& name = identifier.string();
|
||||
|
||||
// 1. If vn is not an element of declaredFunctionNames, then
|
||||
if (!declared_function_names.contains(name)) {
|
||||
|
@ -1000,7 +1000,7 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, Program const& pr
|
|||
|
||||
// b. For each element dn of the BoundNames of d, do
|
||||
return declaration.for_each_bound_identifier([&](Identifier const& identifier) -> ThrowCompletionOr<void> {
|
||||
auto name = Utf16FlyString::from_utf8(identifier.string());
|
||||
auto const& name = identifier.string();
|
||||
|
||||
// i. If IsConstantDeclaration of d is true, then
|
||||
if (declaration.is_constant_declaration()) {
|
||||
|
@ -1021,7 +1021,7 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, Program const& pr
|
|||
// instead of prepending. We append because prepending is much slower
|
||||
// and we only use the created vector here.
|
||||
for (auto const& declaration : functions_to_initialize.in_reverse()) {
|
||||
auto declaration_name = Utf16FlyString::from_utf8(declaration.name());
|
||||
auto declaration_name = 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.
|
||||
|
@ -1178,7 +1178,7 @@ Object* create_mapped_arguments_object(VM& vm, FunctionObject& function, Nonnull
|
|||
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 name = Utf16FlyString::from_utf8(formals->parameters()[index].binding.get<NonnullRefPtr<Identifier const>>()->string());
|
||||
auto const& name = formals->parameters()[index].binding.get<NonnullRefPtr<Identifier const>>()->string();
|
||||
|
||||
// b. If name is not an element of mappedNames, then
|
||||
if (seen_names.contains(name))
|
||||
|
@ -1792,7 +1792,7 @@ ThrowCompletionOr<Value> perform_import_call(VM& vm, Value specifier, Value opti
|
|||
|
||||
// 8. Let specifierString be Completion(ToString(specifier)).
|
||||
// 9. IfAbruptRejectPromise(specifierString, promiseCapability).
|
||||
FlyString specifier_string = TRY_OR_REJECT(vm, promise_capability, specifier.to_string(vm));
|
||||
auto specifier_string = TRY_OR_REJECT(vm, promise_capability, specifier.to_utf16_string(vm));
|
||||
|
||||
// 10. Let attributes be a new empty List.
|
||||
Vector<ImportAttribute> attributes;
|
||||
|
@ -1850,7 +1850,7 @@ ThrowCompletionOr<Value> perform_import_call(VM& vm, Value specifier, Value opti
|
|||
}
|
||||
|
||||
// b. Append the ImportAttribute Record { [[Key]]: key, [[Value]]: value } to attributes.
|
||||
attributes.empend(key.as_string().utf8_string(), value.as_string().utf8_string());
|
||||
attributes.empend(key.as_string().utf16_string(), value.as_string().utf16_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -210,7 +210,7 @@ SharedFunctionInstanceData::SharedFunctionInstanceData(
|
|||
|
||||
parameter.binding.visit(
|
||||
[&](Identifier const& identifier) {
|
||||
if (m_parameter_names.set(Utf16FlyString::from_utf8(identifier.string()), identifier.is_local() ? ParameterIsLocal::Yes : ParameterIsLocal::No) != AK::HashSetResult::InsertedNewEntry)
|
||||
if (m_parameter_names.set(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(Utf16FlyString::from_utf8(identifier.string()), identifier.is_local() ? ParameterIsLocal::Yes : ParameterIsLocal::No) != AK::HashSetResult::InsertedNewEntry)
|
||||
if (m_parameter_names.set(identifier.string(), identifier.is_local() ? ParameterIsLocal::Yes : ParameterIsLocal::No) != AK::HashSetResult::InsertedNewEntry)
|
||||
m_has_duplicates = true;
|
||||
else if (!identifier.is_local())
|
||||
++parameters_in_environment;
|
||||
|
@ -253,9 +253,7 @@ 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) {
|
||||
auto name = Utf16FlyString::from_utf8(function.name());
|
||||
|
||||
if (function_names.set(name) == AK::HashSetResult::InsertedNewEntry)
|
||||
if (function_names.set(function.name()) == AK::HashSetResult::InsertedNewEntry)
|
||||
m_functions_to_initialize.append(function);
|
||||
}));
|
||||
|
||||
|
@ -325,7 +323,7 @@ SharedFunctionInstanceData::SharedFunctionInstanceData(
|
|||
// c. For each element n of varNames, do
|
||||
MUST(scope_body->for_each_var_declared_identifier([&](Identifier const& id) {
|
||||
// i. If instantiatedVarNames does not contain n, then
|
||||
if (instantiated_var_names.set(Utf16FlyString::from_utf8(id.string()), id.is_local() ? ParameterIsLocal::Yes : ParameterIsLocal::No) == AK::HashSetResult::InsertedNewEntry) {
|
||||
if (instantiated_var_names.set(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).
|
||||
|
@ -356,7 +354,7 @@ SharedFunctionInstanceData::SharedFunctionInstanceData(
|
|||
// e. For each element n of varNames, do
|
||||
if (scope_body) {
|
||||
MUST(scope_body->for_each_var_declared_identifier([&](Identifier const& id) {
|
||||
auto name = Utf16FlyString::from_utf8(id.string());
|
||||
auto const& name = id.string();
|
||||
|
||||
// 1. Append n to instantiatedVarNames.
|
||||
// Following steps will be executed in function_declaration_instantiation:
|
||||
|
@ -380,7 +378,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 = Utf16FlyString::from_utf8(function_declaration.name());
|
||||
auto function_name = function_declaration.name();
|
||||
if (parameter_bindings.contains(function_name))
|
||||
return;
|
||||
|
||||
|
|
|
@ -7,21 +7,21 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/FlyString.h>
|
||||
#include <AK/Utf16FlyString.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibJS/Module.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
struct ModuleWithSpecifier {
|
||||
String specifier; // [[Specifier]]
|
||||
Utf16String specifier; // [[Specifier]]
|
||||
GC::Ref<Module> module; // [[Module]]
|
||||
};
|
||||
|
||||
// https://tc39.es/ecma262/#importattribute-record
|
||||
struct ImportAttribute {
|
||||
String key;
|
||||
String value;
|
||||
Utf16String key;
|
||||
Utf16String value;
|
||||
|
||||
bool operator==(ImportAttribute const&) const = default;
|
||||
};
|
||||
|
@ -30,19 +30,19 @@ struct ImportAttribute {
|
|||
struct ModuleRequest {
|
||||
ModuleRequest() = default;
|
||||
|
||||
explicit ModuleRequest(FlyString specifier)
|
||||
explicit ModuleRequest(Utf16FlyString specifier)
|
||||
: module_specifier(move(specifier))
|
||||
{
|
||||
}
|
||||
|
||||
ModuleRequest(FlyString specifier, Vector<ImportAttribute> attributes);
|
||||
ModuleRequest(Utf16FlyString specifier, Vector<ImportAttribute> attributes);
|
||||
|
||||
void add_attribute(String key, String value)
|
||||
void add_attribute(Utf16String key, Utf16String value)
|
||||
{
|
||||
attributes.empend(move(key), move(value));
|
||||
}
|
||||
|
||||
FlyString module_specifier; // [[Specifier]]
|
||||
Utf16FlyString module_specifier; // [[Specifier]]
|
||||
Vector<ImportAttribute> attributes; // [[Attributes]]
|
||||
|
||||
bool operator==(ModuleRequest const&) const = default;
|
||||
|
|
|
@ -211,7 +211,7 @@ ThrowCompletionOr<Value> perform_shadow_realm_eval(VM& vm, Value source, Realm&
|
|||
}
|
||||
|
||||
// 3.1.4 ShadowRealmImportValue ( specifierString: a String, exportNameString: a String, callerRealm: a Realm Record, evalRealm: a Realm Record, evalContext: an execution context, ), https://tc39.es/proposal-shadowrealm/#sec-shadowrealmimportvalue
|
||||
ThrowCompletionOr<Value> shadow_realm_import_value(VM& vm, String specifier_string, String export_name_string, Realm& caller_realm, Realm& eval_realm)
|
||||
ThrowCompletionOr<Value> shadow_realm_import_value(VM& vm, Utf16FlyString specifier_string, Utf16FlyString export_name_string, Realm& caller_realm, Realm& eval_realm)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
|
@ -232,7 +232,7 @@ ThrowCompletionOr<Value> shadow_realm_import_value(VM& vm, String specifier_stri
|
|||
auto referrer = GC::Ref { *eval_context->realm };
|
||||
|
||||
// 7. Perform HostLoadImportedModule(referrer, specifierString, empty, innerCapability).
|
||||
vm.host_load_imported_module(referrer, ModuleRequest { specifier_string }, nullptr, inner_capability);
|
||||
vm.host_load_imported_module(referrer, ModuleRequest { move(specifier_string) }, nullptr, inner_capability);
|
||||
|
||||
// 7. Suspend evalContext and remove it from the execution context stack.
|
||||
// NOTE: We don't support this concept yet.
|
||||
|
@ -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 = Utf16String::from_utf8(export_name_string)](auto& vm) -> ThrowCompletionOr<Value> {
|
||||
auto steps = [string = move(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();
|
||||
|
|
|
@ -35,7 +35,7 @@ private:
|
|||
|
||||
ThrowCompletionOr<void> copy_name_and_length(VM&, FunctionObject& function, FunctionObject& target, Optional<StringView> prefix = {}, Optional<unsigned> arg_count = {});
|
||||
ThrowCompletionOr<Value> perform_shadow_realm_eval(VM&, Value source, Realm& caller_realm, Realm& eval_realm);
|
||||
ThrowCompletionOr<Value> shadow_realm_import_value(VM&, String specifier_string, String export_name_string, Realm& caller_realm, Realm& eval_realm);
|
||||
ThrowCompletionOr<Value> shadow_realm_import_value(VM&, Utf16FlyString specifier_string, Utf16FlyString export_name_string, Realm& caller_realm, Realm& eval_realm);
|
||||
ThrowCompletionOr<Value> get_wrapped_value(VM&, Realm& caller_realm, Value);
|
||||
NonnullOwnPtr<ExecutionContext> get_shadow_realm_context(Realm& shadow_realm, bool strict_eval, u32 registers_and_constants_and_locals_count);
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ JS_DEFINE_NATIVE_FUNCTION(ShadowRealmPrototype::import_value)
|
|||
auto object = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let specifierString be ? ToString(specifier).
|
||||
auto specifier_string = TRY(specifier.to_string(vm));
|
||||
auto specifier_string = TRY(specifier.to_utf16_string(vm));
|
||||
|
||||
// 4. If Type(exportName) is not String, throw a TypeError exception.
|
||||
if (!export_name.is_string())
|
||||
|
@ -77,7 +77,7 @@ JS_DEFINE_NATIVE_FUNCTION(ShadowRealmPrototype::import_value)
|
|||
auto& eval_realm = object->shadow_realm();
|
||||
|
||||
// 7. Return ShadowRealmImportValue(specifierString, exportName, callerRealm, evalRealm).
|
||||
return shadow_realm_import_value(vm, move(specifier_string), export_name.as_string().utf8_string(), *caller_realm, eval_realm);
|
||||
return shadow_realm_import_value(vm, specifier_string, export_name.as_string().utf16_string(), *caller_realm, eval_realm);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ VM::VM(ErrorMessages error_messages)
|
|||
};
|
||||
|
||||
host_get_supported_import_attributes = [&] {
|
||||
return Vector<String> { "type"_string };
|
||||
return Vector<Utf16String> { "type"_utf16 };
|
||||
};
|
||||
|
||||
// 1 HostGetCodeForEval ( argument ), https://tc39.es/proposal-dynamic-code-brand-checks/#sec-hostgetcodeforeval
|
||||
|
@ -523,7 +523,7 @@ ScriptOrModule VM::get_active_script_or_module() const
|
|||
return m_execution_context_stack[0]->script_or_module;
|
||||
}
|
||||
|
||||
VM::StoredModule* VM::get_stored_module(ImportedModuleReferrer const&, ByteString const& filename, String const&)
|
||||
VM::StoredModule* VM::get_stored_module(ImportedModuleReferrer const&, ByteString const& filename, Utf16String const&)
|
||||
{
|
||||
// Note the spec says:
|
||||
// If this operation is called multiple times with the same (referrer, specifier) pair and it performs
|
||||
|
@ -582,7 +582,7 @@ ThrowCompletionOr<void> VM::link_and_eval_module(CyclicModule& module)
|
|||
return {};
|
||||
}
|
||||
|
||||
static ByteString resolve_module_filename(StringView filename, StringView module_type)
|
||||
static ByteString resolve_module_filename(StringView filename, Utf16View const& module_type)
|
||||
{
|
||||
auto extensions = Vector<StringView, 2> { "js"sv, "mjs"sv };
|
||||
if (module_type == "json"sv)
|
||||
|
@ -635,7 +635,7 @@ void VM::load_imported_module(ImportedModuleReferrer referrer, ModuleRequest con
|
|||
return;
|
||||
}
|
||||
|
||||
String module_type;
|
||||
Utf16String module_type;
|
||||
for (auto& attribute : module_request.attributes) {
|
||||
if (attribute.key == "type"sv) {
|
||||
module_type = attribute.value;
|
||||
|
@ -662,7 +662,7 @@ void VM::load_imported_module(ImportedModuleReferrer referrer, ModuleRequest con
|
|||
});
|
||||
|
||||
LexicalPath base_path { base_filename };
|
||||
auto filename = LexicalPath::absolute_path(base_path.dirname(), module_request.module_specifier);
|
||||
auto filename = LexicalPath::absolute_path(base_path.dirname(), MUST(module_request.module_specifier.view().to_byte_string()));
|
||||
|
||||
dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] base path: '{}'", base_path);
|
||||
dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] initial filename: '{}'", filename);
|
||||
|
|
|
@ -283,7 +283,7 @@ public:
|
|||
Function<HashMap<PropertyKey, Value>(SourceTextModule&)> host_get_import_meta_properties;
|
||||
Function<void(Object*, SourceTextModule const&)> host_finalize_import_meta;
|
||||
|
||||
Function<Vector<String>()> host_get_supported_import_attributes;
|
||||
Function<Vector<Utf16String>()> host_get_supported_import_attributes;
|
||||
|
||||
void set_dynamic_imports_allowed(bool value) { m_dynamic_imports_allowed = value; }
|
||||
|
||||
|
@ -351,7 +351,7 @@ private:
|
|||
bool has_once_started_linking { false };
|
||||
};
|
||||
|
||||
StoredModule* get_stored_module(ImportedModuleReferrer const& script_or_module, ByteString const& filename, String const& type);
|
||||
StoredModule* get_stored_module(ImportedModuleReferrer const& script_or_module, ByteString const& filename, Utf16String const& type);
|
||||
|
||||
Vector<StoredModule> m_loaded_modules;
|
||||
|
||||
|
|
|
@ -296,7 +296,7 @@ Vector<Utf16FlyString> SourceTextModule::get_exported_names(VM& vm, HashTable<Mo
|
|||
VERIFY(entry.export_name.has_value());
|
||||
|
||||
// c. Append e.[[ExportName]] to exportedNames.
|
||||
exported_names.empend(Utf16FlyString::from_utf8(entry.export_name.value()));
|
||||
exported_names.empend(entry.export_name.value());
|
||||
}
|
||||
|
||||
// 7. For each ExportEntry Record e of module.[[IndirectExportEntries]], do
|
||||
|
@ -308,7 +308,7 @@ Vector<Utf16FlyString> SourceTextModule::get_exported_names(VM& vm, HashTable<Mo
|
|||
VERIFY(entry.export_name.has_value());
|
||||
|
||||
// c. Append e.[[ExportName]] to exportedNames.
|
||||
exported_names.empend(Utf16FlyString::from_utf8(entry.export_name.value()));
|
||||
exported_names.empend(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, Utf16FlyString::from_utf8(entry.export_name.value()));
|
||||
auto resolution = resolve_export(vm, entry.export_name.value());
|
||||
|
||||
// b. If resolution is either null or AMBIGUOUS, throw a SyntaxError exception.
|
||||
if (!resolution.is_valid())
|
||||
|
@ -371,8 +371,6 @@ 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());
|
||||
|
||||
|
@ -382,14 +380,14 @@ 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, local_name, true));
|
||||
MUST(environment->create_immutable_binding(vm, import_entry.local_name, true));
|
||||
|
||||
// iii. Perform ! env.InitializeBinding(in.[[LocalName]], namespace, normal).
|
||||
MUST(environment->initialize_binding(vm, local_name, namespace_, Environment::InitializeBindingHint::Normal));
|
||||
MUST(environment->initialize_binding(vm, import_entry.local_name, namespace_, Environment::InitializeBindingHint::Normal));
|
||||
}
|
||||
// c. Else,
|
||||
else {
|
||||
auto import_name = Utf16FlyString::from_utf8(import_entry.import_name.value());
|
||||
auto const& import_name = import_entry.import_name.value();
|
||||
|
||||
// i. Let resolution be importedModule.ResolveExport(in.[[ImportName]]).
|
||||
auto resolution = imported_module->resolve_export(vm, import_name);
|
||||
|
@ -404,15 +402,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, local_name, true));
|
||||
MUST(environment->create_immutable_binding(vm, import_entry.local_name, true));
|
||||
|
||||
// 3. Perform ! env.InitializeBinding(in.[[LocalName]], namespace, normal).
|
||||
MUST(environment->initialize_binding(vm, local_name, namespace_, Environment::InitializeBindingHint::Normal));
|
||||
MUST(environment->initialize_binding(vm, import_entry.local_name, namespace_, Environment::InitializeBindingHint::Normal));
|
||||
}
|
||||
// iv. Else,
|
||||
else {
|
||||
// 1. Perform env.CreateImportBinding(in.[[LocalName]], resolution.[[Module]], resolution.[[BindingName]]).
|
||||
MUST(environment->create_import_binding(local_name, resolution.module, resolution.export_name));
|
||||
MUST(environment->create_import_binding(import_entry.local_name, resolution.module, resolution.export_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -458,7 +456,7 @@ ThrowCompletionOr<void> SourceTextModule::initialize_environment(VM& vm)
|
|||
// 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([&](Identifier const& identifier) {
|
||||
auto name = Utf16FlyString::from_utf8(identifier.string());
|
||||
auto const& name = identifier.string();
|
||||
|
||||
// i. If dn is not an element of declaredVarNames, then
|
||||
if (!declared_var_names.contains_slow(name)) {
|
||||
|
@ -484,7 +482,7 @@ ThrowCompletionOr<void> SourceTextModule::initialize_environment(VM& vm)
|
|||
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([&](Identifier const& identifier) {
|
||||
auto name = Utf16FlyString::from_utf8(identifier.string());
|
||||
auto const& name = identifier.string();
|
||||
|
||||
// i. If IsConstantDeclaration of d is true, then
|
||||
if (declaration.is_constant_declaration()) {
|
||||
|
@ -505,12 +503,12 @@ ThrowCompletionOr<void> SourceTextModule::initialize_environment(VM& vm)
|
|||
// 1. Let fo be InstantiateFunctionObject of d with arguments env and privateEnv.
|
||||
// NOTE: Special case if the function is a default export of an anonymous function
|
||||
// it has name "*default*" but internally should have name "default".
|
||||
FlyString function_name = function_declaration.name();
|
||||
auto function_name = function_declaration.name();
|
||||
if (function_name == ExportStatement::local_name_for_default)
|
||||
function_name = "default"_fly_string;
|
||||
function_name = "default"_utf16_fly_string;
|
||||
auto function = ECMAScriptFunctionObject::create_from_function_node(
|
||||
function_declaration,
|
||||
Utf16FlyString::from_utf8(function_name),
|
||||
move(function_name),
|
||||
realm,
|
||||
environment,
|
||||
private_environment);
|
||||
|
@ -528,7 +526,7 @@ 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 name = Utf16FlyString::from_utf8(m_default_export->entries()[0].local_or_import_name.value());
|
||||
auto const& name = 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).
|
||||
|
@ -581,7 +579,7 @@ ResolvedBinding SourceTextModule::resolve_export(VM& vm, Utf16FlyString const& e
|
|||
return ResolvedBinding {
|
||||
ResolvedBinding::Type::BindingName,
|
||||
this,
|
||||
Utf16FlyString::from_utf8(entry.local_or_import_name.value()),
|
||||
entry.local_or_import_name.value(),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -613,7 +611,7 @@ ResolvedBinding SourceTextModule::resolve_export(VM& vm, Utf16FlyString const& e
|
|||
// FIXME: What does this mean? / How do we check this
|
||||
|
||||
// 2. Return importedModule.ResolveExport(e.[[ImportName]], resolveSet).
|
||||
return imported_module->resolve_export(vm, Utf16FlyString::from_utf8(entry.local_or_import_name.value()), resolve_set);
|
||||
return imported_module->resolve_export(vm, entry.local_or_import_name.value(), resolve_set);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -418,9 +418,9 @@ void initialize_main_thread_vm(AgentType type)
|
|||
};
|
||||
|
||||
// 8.1.6.7.2 HostGetSupportedImportAttributes(), https://html.spec.whatwg.org/multipage/webappapis.html#hostgetsupportedimportassertions
|
||||
s_main_thread_vm->host_get_supported_import_attributes = []() -> Vector<String> {
|
||||
s_main_thread_vm->host_get_supported_import_attributes = []() -> Vector<Utf16String> {
|
||||
// 1. Return « "type" ».
|
||||
return { "type"_string };
|
||||
return { "type"_utf16 };
|
||||
};
|
||||
|
||||
// 8.1.6.7.3 HostLoadImportedModule(referrer, moduleRequest, loadState, payload), https://html.spec.whatwg.org/multipage/webappapis.html#hostloadimportedmodule
|
||||
|
@ -494,7 +494,7 @@ void initialize_main_thread_vm(AgentType type)
|
|||
|
||||
// 2. Resolve a module specifier given referencingScript and moduleRequest.[[Specifier]], catching any
|
||||
// exceptions. If they throw an exception, let resolutionError be the thrown exception.
|
||||
auto maybe_exception = HTML::resolve_module_specifier(referencing_script, module_request.module_specifier.to_string());
|
||||
auto maybe_exception = HTML::resolve_module_specifier(referencing_script, module_request.module_specifier.view().to_utf8_but_should_be_ported_to_utf16());
|
||||
|
||||
// 3. If the previous step threw an exception, then:
|
||||
if (maybe_exception.is_exception()) {
|
||||
|
@ -544,7 +544,7 @@ void initialize_main_thread_vm(AgentType type)
|
|||
|
||||
// 8. Let url be the result of resolving a module specifier given referencingScript and moduleRequest.[[Specifier]],
|
||||
// catching any exceptions. If they throw an exception, let resolutionError be the thrown exception.
|
||||
auto url = HTML::resolve_module_specifier(referencing_script, module_request.module_specifier.to_string());
|
||||
auto url = HTML::resolve_module_specifier(referencing_script, module_request.module_specifier.view().to_utf8_but_should_be_ported_to_utf16());
|
||||
|
||||
// 9. If the previous step threw an exception, then:
|
||||
if (url.is_exception()) {
|
||||
|
|
|
@ -76,7 +76,7 @@ String module_type_from_module_request(JS::ModuleRequest const& module_request)
|
|||
module_type = ""_string; // FIXME: This should be null!
|
||||
// 2. Otherwise, set moduleType to entry.[[Value]].
|
||||
else
|
||||
module_type = entry.value;
|
||||
module_type = entry.value.to_utf8_but_should_be_ported_to_utf16();
|
||||
}
|
||||
|
||||
// 3. Return moduleType.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue