mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-04 05:20:30 +00:00
LibJS: Rip out the AST interpreter :^)
This has been superseded by the bytecode VM, which is both faster and more capable.
This commit is contained in:
parent
fcc72a787b
commit
2eaa528a0e
Notes:
sideshowbarker
2024-07-17 02:14:39 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/2eaa528a0e Pull-request: https://github.com/SerenityOS/serenity/pull/20421
41 changed files with 147 additions and 3734 deletions
|
@ -15,7 +15,6 @@
|
|||
#include <LibJS/Bytecode/Generator.h>
|
||||
#include <LibJS/Bytecode/Interpreter.h>
|
||||
#include <LibJS/Console.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Parser.h>
|
||||
#include <LibJS/Print.h>
|
||||
#include <LibJS/Runtime/ConsoleObject.h>
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
#include <LibJS/Bytecode/Generator.h>
|
||||
#include <LibJS/Bytecode/Interpreter.h>
|
||||
#include <LibJS/Contrib/Test262/GlobalObject.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Parser.h>
|
||||
#include <LibJS/Runtime/VM.h>
|
||||
#include <LibJS/Script.h>
|
||||
#include <LibJS/SourceTextModule.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
@ -206,27 +206,28 @@ static Result<void, TestError> run_test(StringView source, StringView filepath,
|
|||
|
||||
auto vm = MUST(JS::VM::create());
|
||||
vm->enable_default_host_import_module_dynamically_hook();
|
||||
auto ast_interpreter = JS::Interpreter::create<JS::Test262::GlobalObject>(*vm);
|
||||
auto& realm = ast_interpreter->realm();
|
||||
|
||||
auto program_or_error = parse_program(realm, source, filepath, metadata.program_type);
|
||||
JS::GCPtr<JS::Realm> realm;
|
||||
JS::GCPtr<JS::Test262::GlobalObject> global_object;
|
||||
auto root_execution_context = MUST(JS::Realm::initialize_host_defined_realm(
|
||||
*vm,
|
||||
[&](JS::Realm& realm_) -> JS::GlobalObject* {
|
||||
realm = &realm_;
|
||||
global_object = vm->heap().allocate_without_realm<JS::Test262::GlobalObject>(realm_);
|
||||
return global_object;
|
||||
},
|
||||
nullptr));
|
||||
|
||||
auto program_or_error = parse_program(*realm, source, filepath, metadata.program_type);
|
||||
if (program_or_error.is_error())
|
||||
return program_or_error.release_error();
|
||||
|
||||
auto* bytecode_interpreter = vm->bytecode_interpreter_if_exists();
|
||||
|
||||
auto run_with_interpreter = [&](ScriptOrModuleProgram& program) {
|
||||
if (bytecode_interpreter)
|
||||
return run_program(*bytecode_interpreter, program);
|
||||
return run_program(*ast_interpreter, program);
|
||||
};
|
||||
|
||||
for (auto& harness_file : metadata.harness_files) {
|
||||
auto harness_program_or_error = parse_harness_files(realm, harness_file);
|
||||
auto harness_program_or_error = parse_harness_files(*realm, harness_file);
|
||||
if (harness_program_or_error.is_error())
|
||||
return harness_program_or_error.release_error();
|
||||
ScriptOrModuleProgram harness_program { harness_program_or_error.release_value() };
|
||||
auto result = run_with_interpreter(harness_program);
|
||||
auto result = run_program(vm->bytecode_interpreter(), harness_program);
|
||||
if (result.is_error()) {
|
||||
return TestError {
|
||||
NegativePhase::Harness,
|
||||
|
@ -237,7 +238,7 @@ static Result<void, TestError> run_test(StringView source, StringView filepath,
|
|||
}
|
||||
}
|
||||
|
||||
return run_with_interpreter(program_or_error.value());
|
||||
return run_program(vm->bytecode_interpreter(), program_or_error.value());
|
||||
}
|
||||
|
||||
static Result<TestMetadata, DeprecatedString> extract_metadata(StringView source)
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include <AK/URL.h>
|
||||
#include <LibDesktop/AppFile.h>
|
||||
#include <LibGUI/Desktop.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/VM.h>
|
||||
#include <LibThreading/BackgroundAction.h>
|
||||
#include <typeinfo>
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include <LibGUI/TabWidget.h>
|
||||
#include <LibGUI/ToolbarContainer.h>
|
||||
#include <LibGUI/Widget.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibWeb/CSS/PreferredColorScheme.h>
|
||||
#include <LibWeb/Dump.h>
|
||||
#include <LibWeb/Layout/Viewport.h>
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#include <LibGUI/Toolbar.h>
|
||||
#include <LibGUI/ToolbarContainer.h>
|
||||
#include <LibGUI/Window.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibWeb/HTML/BrowsingContext.h>
|
||||
#include <LibWeb/HTML/SyntaxHighlighter/SyntaxHighlighter.h>
|
||||
#include <LibWeb/Layout/BlockContainer.h>
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include <AK/WeakPtr.h>
|
||||
#include <AK/Weakable.h>
|
||||
#include <LibCore/EventReceiver.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
|
||||
namespace Spreadsheet {
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -53,7 +53,6 @@ public:
|
|||
// NOTE: This is here to stop ASAN complaining about mismatch between new/delete sizes in ASTNodeWithTailArray.
|
||||
void operator delete(void* ptr) { ::operator delete(ptr); }
|
||||
|
||||
virtual Completion execute(Interpreter&) const = 0;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const;
|
||||
virtual void dump(int indent) const;
|
||||
|
||||
|
@ -166,7 +165,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) const;
|
||||
|
@ -197,7 +195,6 @@ class IterationStatement : public Statement {
|
|||
public:
|
||||
using Statement::Statement;
|
||||
|
||||
virtual Completion loop_evaluation(Interpreter&, Vector<DeprecatedFlyString> const&) const = 0;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) const;
|
||||
|
||||
private:
|
||||
|
@ -210,7 +207,6 @@ public:
|
|||
: Statement(source_range)
|
||||
{
|
||||
}
|
||||
Completion execute(Interpreter&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
};
|
||||
|
||||
|
@ -220,7 +216,6 @@ public:
|
|||
: Statement(source_range)
|
||||
{
|
||||
}
|
||||
Completion execute(Interpreter&) const override { return {}; }
|
||||
};
|
||||
|
||||
class ExpressionStatement final : public Statement {
|
||||
|
@ -231,7 +226,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -298,8 +292,6 @@ public:
|
|||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
Completion evaluate_statements(Interpreter&) const;
|
||||
|
||||
void add_var_scoped_declaration(NonnullRefPtr<Declaration const> variables);
|
||||
void add_lexical_declaration(NonnullRefPtr<Declaration const> variables);
|
||||
void add_hoisted_function(NonnullRefPtr<FunctionDeclaration const> declaration);
|
||||
|
@ -384,8 +376,6 @@ public:
|
|||
entry.m_module_request = &m_module_request;
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
|
||||
virtual void dump(int indent) const override;
|
||||
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
@ -483,8 +473,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
|
||||
virtual void dump(int indent) const override;
|
||||
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
@ -528,8 +516,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
|
||||
bool is_strict_mode() const { return m_is_strict_mode; }
|
||||
void set_strict_mode() { m_is_strict_mode = true; }
|
||||
|
||||
|
@ -575,7 +561,6 @@ public:
|
|||
: ScopeNode(source_range)
|
||||
{
|
||||
}
|
||||
Completion execute(Interpreter&) const override;
|
||||
};
|
||||
|
||||
class FunctionBody final : public ScopeNode {
|
||||
|
@ -589,8 +574,6 @@ public:
|
|||
|
||||
bool in_strict_mode() const { return m_in_strict_mode; }
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
|
||||
private:
|
||||
bool m_in_strict_mode { false };
|
||||
};
|
||||
|
@ -601,7 +584,6 @@ public:
|
|||
: ASTNode(source_range)
|
||||
{
|
||||
}
|
||||
virtual ThrowCompletionOr<Reference> to_reference(Interpreter&) const;
|
||||
};
|
||||
|
||||
class Declaration : public Statement {
|
||||
|
@ -625,7 +607,6 @@ public:
|
|||
: Declaration(source_range)
|
||||
{
|
||||
}
|
||||
Completion execute(Interpreter&) const override { return {}; }
|
||||
|
||||
ThrowCompletionOr<void> for_each_bound_identifier(ThrowCompletionOrVoidCallback<Identifier const&>&&) const override
|
||||
{
|
||||
|
@ -681,9 +662,7 @@ public:
|
|||
bool is_global() const { return m_is_global; }
|
||||
void set_is_global() { m_is_global = true; }
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual ThrowCompletionOr<Reference> to_reference(Interpreter&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
private:
|
||||
|
@ -765,7 +744,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -791,7 +769,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
@ -811,8 +788,6 @@ public:
|
|||
: Expression(source_range)
|
||||
{
|
||||
}
|
||||
|
||||
Completion execute(Interpreter&) const override { return {}; }
|
||||
};
|
||||
|
||||
class YieldExpression final : public Expression {
|
||||
|
@ -827,7 +802,6 @@ public:
|
|||
Expression const* argument() const { return m_argument; }
|
||||
bool is_yield_from() const { return m_is_yield_from; }
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -844,7 +818,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -862,7 +835,6 @@ public:
|
|||
|
||||
Expression const* argument() const { return m_argument; }
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -884,7 +856,6 @@ public:
|
|||
Statement const& consequent() const { return *m_consequent; }
|
||||
Statement const* alternate() const { return m_alternate; }
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -906,8 +877,6 @@ public:
|
|||
Expression const& test() const { return *m_test; }
|
||||
Statement const& body() const { return *m_body; }
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual Completion loop_evaluation(Interpreter&, Vector<DeprecatedFlyString> const&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) const override;
|
||||
|
@ -929,8 +898,6 @@ public:
|
|||
Expression const& test() const { return *m_test; }
|
||||
Statement const& body() const { return *m_body; }
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual Completion loop_evaluation(Interpreter&, Vector<DeprecatedFlyString> const&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) const override;
|
||||
|
@ -952,7 +919,6 @@ public:
|
|||
Expression const& object() const { return *m_object; }
|
||||
Statement const& body() const { return *m_body; }
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -977,15 +943,11 @@ public:
|
|||
Expression const* update() const { return m_update; }
|
||||
Statement const& body() const { return *m_body; }
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual Completion loop_evaluation(Interpreter&, Vector<DeprecatedFlyString> const&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) const override;
|
||||
|
||||
private:
|
||||
Completion for_body_evaluation(Interpreter&, Vector<DeprecatedFlyString> const&, size_t per_iteration_bindings_size) const;
|
||||
|
||||
RefPtr<ASTNode const> m_init;
|
||||
RefPtr<Expression const> m_test;
|
||||
RefPtr<Expression const> m_update;
|
||||
|
@ -1006,10 +968,8 @@ public:
|
|||
Expression const& rhs() const { return *m_rhs; }
|
||||
Statement const& body() const { return *m_body; }
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) const override;
|
||||
virtual Completion loop_evaluation(Interpreter&, Vector<DeprecatedFlyString> const&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
|
||||
private:
|
||||
|
@ -1032,10 +992,8 @@ public:
|
|||
Expression const& rhs() const { return *m_rhs; }
|
||||
Statement const& body() const { return *m_body; }
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) const override;
|
||||
virtual Completion loop_evaluation(Interpreter&, Vector<DeprecatedFlyString> const&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
|
||||
private:
|
||||
|
@ -1054,10 +1012,8 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) const override;
|
||||
virtual Completion loop_evaluation(Interpreter&, Vector<DeprecatedFlyString> const&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
|
||||
private:
|
||||
|
@ -1101,7 +1057,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -1127,7 +1082,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -1156,7 +1110,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -1175,7 +1128,6 @@ public:
|
|||
}
|
||||
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
private:
|
||||
|
@ -1198,7 +1150,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -1214,7 +1165,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -1230,7 +1180,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -1246,7 +1195,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -1265,7 +1213,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
};
|
||||
|
@ -1282,7 +1229,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -1310,7 +1256,6 @@ public:
|
|||
|
||||
DeprecatedFlyString const& string() const { return m_string; }
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
|
||||
virtual bool is_private_identifier() const override { return true; }
|
||||
|
@ -1327,8 +1272,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
|
||||
enum class ElementKind {
|
||||
Method,
|
||||
Field,
|
||||
|
@ -1431,7 +1374,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -1455,7 +1397,6 @@ public:
|
|||
DeprecatedString const& source_text() const { return m_source_text; }
|
||||
RefPtr<FunctionExpression const> constructor() const { return m_constructor; }
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode_with_lhs_name(Bytecode::Generator&, Optional<Bytecode::IdentifierTableIndex> lhs_name) const;
|
||||
|
@ -1485,7 +1426,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -1514,7 +1454,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter& interpreter) const override;
|
||||
virtual void dump(int) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -1531,7 +1470,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -1545,7 +1483,6 @@ public:
|
|||
: Expression(source_range)
|
||||
{
|
||||
}
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
};
|
||||
|
@ -1576,7 +1513,6 @@ public:
|
|||
|
||||
static NonnullRefPtr<CallExpression> create(SourceRange, NonnullRefPtr<Expression const> callee, ReadonlySpan<Argument> arguments, InvocationStyleEnum invocation_style, InsideParenthesesEnum inside_parens);
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -1597,17 +1533,9 @@ protected:
|
|||
{
|
||||
}
|
||||
|
||||
private:
|
||||
struct ThisAndCallee {
|
||||
Value this_value;
|
||||
Value callee;
|
||||
};
|
||||
ThrowCompletionOr<ThisAndCallee> compute_this_and_callee(Interpreter&, Reference const&) const;
|
||||
|
||||
protected:
|
||||
virtual bool is_call_expression() const override { return true; }
|
||||
|
||||
Completion throw_type_error_for_callee(Interpreter&, Value callee_value, StringView call_type) const;
|
||||
Optional<DeprecatedString> expression_string() const;
|
||||
|
||||
NonnullRefPtr<Expression const> m_callee;
|
||||
|
@ -1619,8 +1547,6 @@ class NewExpression final : public CallExpression {
|
|||
public:
|
||||
static NonnullRefPtr<NewExpression> create(SourceRange, NonnullRefPtr<Expression const> callee, ReadonlySpan<Argument> arguments, InvocationStyleEnum invocation_style, InsideParenthesesEnum inside_parens);
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
|
||||
virtual bool is_new_expression() const override { return true; }
|
||||
|
||||
private:
|
||||
|
@ -1656,7 +1582,6 @@ public:
|
|||
VERIFY(is_part_of_synthetic_constructor == IsPartOfSyntheticConstructor::Yes);
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -1702,7 +1627,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -1727,7 +1651,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -1770,7 +1693,6 @@ public:
|
|||
auto& target() const { return m_target; }
|
||||
Expression const* init() const { return m_init; }
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
|
||||
private:
|
||||
|
@ -1789,7 +1711,6 @@ public:
|
|||
|
||||
DeclarationKind declaration_kind() const { return m_declaration_kind; }
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -1816,7 +1737,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
|
||||
ThrowCompletionOr<void> for_each_bound_identifier(ThrowCompletionOrVoidCallback<Identifier const&>&&) const override;
|
||||
|
@ -1861,7 +1781,6 @@ public:
|
|||
bool is_method() const { return m_is_method; }
|
||||
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
|
||||
private:
|
||||
Type m_property_type;
|
||||
|
@ -1878,7 +1797,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -1898,7 +1816,6 @@ public:
|
|||
|
||||
Vector<RefPtr<Expression const>> const& elements() const { return m_elements; }
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -1923,7 +1840,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -1944,12 +1860,9 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
ThrowCompletionOr<Value> get_template_object(Interpreter&) const;
|
||||
|
||||
private:
|
||||
NonnullRefPtr<Expression const> const m_tag;
|
||||
NonnullRefPtr<TemplateLiteral const> const m_template_literal;
|
||||
|
@ -1966,9 +1879,7 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual ThrowCompletionOr<Reference> to_reference(Interpreter&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
bool is_computed() const { return m_computed; }
|
||||
|
@ -2020,8 +1931,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual ThrowCompletionOr<JS::Reference> to_reference(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -2029,12 +1938,6 @@ public:
|
|||
Vector<Reference> const& references() const { return m_references; }
|
||||
|
||||
private:
|
||||
struct ReferenceAndValue {
|
||||
JS::Reference reference;
|
||||
Value value;
|
||||
};
|
||||
ThrowCompletionOr<ReferenceAndValue> to_reference_and_value(Interpreter&) const;
|
||||
|
||||
NonnullRefPtr<Expression const> m_base;
|
||||
Vector<Reference> m_references;
|
||||
};
|
||||
|
@ -2052,7 +1955,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -2070,7 +1972,6 @@ public:
|
|||
}
|
||||
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
private:
|
||||
|
@ -2091,7 +1992,6 @@ public:
|
|||
}
|
||||
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
private:
|
||||
|
@ -2120,7 +2020,6 @@ public:
|
|||
BlockStatement const& body() const { return m_body; }
|
||||
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
|
||||
private:
|
||||
Variant<DeprecatedFlyString, NonnullRefPtr<BindingPattern const>> m_parameter;
|
||||
|
@ -2142,7 +2041,6 @@ public:
|
|||
BlockStatement const* finalizer() const { return m_finalizer; }
|
||||
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
private:
|
||||
|
@ -2162,7 +2060,6 @@ public:
|
|||
Expression const& argument() const { return m_argument; }
|
||||
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
private:
|
||||
|
@ -2180,7 +2077,6 @@ public:
|
|||
Expression const* test() const { return m_test; }
|
||||
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
|
||||
private:
|
||||
RefPtr<Expression const> m_test;
|
||||
|
@ -2195,11 +2091,9 @@ public:
|
|||
}
|
||||
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) const;
|
||||
|
||||
Completion execute_impl(Interpreter&) const;
|
||||
void add_case(NonnullRefPtr<SwitchCase const> switch_case) { m_cases.append(move(switch_case)); }
|
||||
|
||||
private:
|
||||
|
@ -2215,8 +2109,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
|
||||
DeprecatedFlyString const& target_label() const { return m_target_label; }
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
|
@ -2232,7 +2124,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
|
||||
DeprecatedFlyString const& target_label() const { return m_target_label; }
|
||||
|
@ -2248,7 +2139,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override;
|
||||
virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override;
|
||||
};
|
||||
|
||||
|
@ -2261,9 +2151,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual Completion execute(Interpreter&) const override { return m_value; }
|
||||
virtual ThrowCompletionOr<Reference> to_reference(Interpreter&) const override { return m_reference; }
|
||||
|
||||
private:
|
||||
Reference m_reference;
|
||||
Value m_value;
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include <LibJS/Bytecode/Instruction.h>
|
||||
#include <LibJS/Bytecode/Interpreter.h>
|
||||
#include <LibJS/Bytecode/Op.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/GlobalEnvironment.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
#include <LibJS/Runtime/Realm.h>
|
||||
|
|
|
@ -24,7 +24,6 @@ set(SOURCES
|
|||
Heap/Heap.cpp
|
||||
Heap/HeapBlock.cpp
|
||||
Heap/MarkedVector.cpp
|
||||
Interpreter.cpp
|
||||
Lexer.cpp
|
||||
MarkupGenerator.cpp
|
||||
Module.cpp
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include <LibJS/Contrib/Test262/GlobalObject.h>
|
||||
#include <LibJS/Contrib/Test262/IsHTMLDDA.h>
|
||||
#include <LibJS/Heap/Cell.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/ArrayBuffer.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
|
@ -103,12 +102,7 @@ JS_DEFINE_NATIVE_FUNCTION($262Object::eval_script)
|
|||
}
|
||||
|
||||
// 5. Let status be ScriptEvaluation(s).
|
||||
auto status = [&] {
|
||||
if (auto* bytecode_interpreter = vm.bytecode_interpreter_if_exists())
|
||||
return bytecode_interpreter->run(script_or_error.value());
|
||||
else
|
||||
return vm.interpreter().run(script_or_error.value());
|
||||
}();
|
||||
auto status = vm.bytecode_interpreter().run(script_or_error.value());
|
||||
|
||||
// 6. Return Completion(status).
|
||||
return status;
|
||||
|
|
|
@ -183,7 +183,6 @@ class Heap;
|
|||
class HeapBlock;
|
||||
struct ImportEntry;
|
||||
class ImportStatement;
|
||||
class Interpreter;
|
||||
class Identifier;
|
||||
class Intrinsics;
|
||||
struct IteratorRecord;
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <LibJS/Heap/Handle.h>
|
||||
#include <LibJS/Heap/Heap.h>
|
||||
#include <LibJS/Heap/HeapBlock.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
#include <LibJS/Runtime/WeakContainer.h>
|
||||
#include <LibJS/SafeFunction.h>
|
||||
|
|
|
@ -1,156 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
|
||||
* Copyright (c) 2022, Luke Wilde <lukew@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/ScopeGuard.h>
|
||||
#include <LibJS/AST.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/ECMAScriptFunctionObject.h>
|
||||
#include <LibJS/Runtime/FunctionEnvironment.h>
|
||||
#include <LibJS/Runtime/GlobalEnvironment.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
#include <LibJS/Runtime/Reference.h>
|
||||
#include <LibJS/Runtime/Shape.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
NonnullOwnPtr<Interpreter> Interpreter::create_with_existing_realm(Realm& realm)
|
||||
{
|
||||
auto& vm = realm.vm();
|
||||
DeferGC defer_gc(vm.heap());
|
||||
auto interpreter = adopt_own(*new Interpreter(vm));
|
||||
interpreter->m_realm = make_handle(&realm);
|
||||
return interpreter;
|
||||
}
|
||||
|
||||
Interpreter::Interpreter(VM& vm)
|
||||
: m_vm(vm)
|
||||
{
|
||||
}
|
||||
|
||||
// 16.1.6 ScriptEvaluation ( scriptRecord ), https://tc39.es/ecma262/#sec-runtime-semantics-scriptevaluation
|
||||
ThrowCompletionOr<Value> Interpreter::run(Script& script_record, JS::GCPtr<Environment> lexical_environment_override)
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
|
||||
VM::InterpreterExecutionScope scope(*this);
|
||||
|
||||
// 1. Let globalEnv be scriptRecord.[[Realm]].[[GlobalEnv]].
|
||||
auto& global_environment = script_record.realm().global_environment();
|
||||
|
||||
// 2. Let scriptContext be a new ECMAScript code execution context.
|
||||
ExecutionContext script_context(vm.heap());
|
||||
|
||||
// 3. Set the Function of scriptContext to null.
|
||||
// NOTE: This was done during execution context construction.
|
||||
|
||||
// 4. Set the Realm of scriptContext to scriptRecord.[[Realm]].
|
||||
script_context.realm = &script_record.realm();
|
||||
|
||||
// 5. Set the ScriptOrModule of scriptContext to scriptRecord.
|
||||
script_context.script_or_module = NonnullGCPtr<Script>(script_record);
|
||||
|
||||
// 6. Set the VariableEnvironment of scriptContext to globalEnv.
|
||||
script_context.variable_environment = &global_environment;
|
||||
|
||||
// 7. Set the LexicalEnvironment of scriptContext to globalEnv.
|
||||
script_context.lexical_environment = &global_environment;
|
||||
|
||||
// Non-standard: Override the lexical environment if requested.
|
||||
if (lexical_environment_override)
|
||||
script_context.lexical_environment = lexical_environment_override;
|
||||
|
||||
// 8. Set the PrivateEnvironment of scriptContext to null.
|
||||
|
||||
// NOTE: This isn't in the spec, but we require it.
|
||||
script_context.is_strict_mode = script_record.parse_node().is_strict_mode();
|
||||
|
||||
// FIXME: 9. Suspend the currently running execution context.
|
||||
|
||||
// 10. Push scriptContext onto the execution context stack; scriptContext is now the running execution context.
|
||||
TRY(vm.push_execution_context(script_context, {}));
|
||||
|
||||
// 11. Let script be scriptRecord.[[ECMAScriptCode]].
|
||||
auto& script = script_record.parse_node();
|
||||
|
||||
// 12. Let result be Completion(GlobalDeclarationInstantiation(script, globalEnv)).
|
||||
auto instantiation_result = script.global_declaration_instantiation(vm, global_environment);
|
||||
Completion result = instantiation_result.is_throw_completion() ? instantiation_result.throw_completion() : normal_completion({});
|
||||
|
||||
// 13. If result.[[Type]] is normal, then
|
||||
if (result.type() == Completion::Type::Normal) {
|
||||
// a. Set result to the result of evaluating script.
|
||||
result = script.execute(*this);
|
||||
}
|
||||
|
||||
// 14. If result.[[Type]] is normal and result.[[Value]] is empty, then
|
||||
if (result.type() == Completion::Type::Normal && !result.value().has_value()) {
|
||||
// a. Set result to NormalCompletion(undefined).
|
||||
result = normal_completion(js_undefined());
|
||||
}
|
||||
|
||||
// FIXME: 15. Suspend scriptContext and remove it from the execution context stack.
|
||||
vm.pop_execution_context();
|
||||
|
||||
// 16. Assert: The execution context stack is not empty.
|
||||
VERIFY(!vm.execution_context_stack().is_empty());
|
||||
|
||||
// FIXME: 17. Resume the context that is now on the top of the execution context stack as the running execution context.
|
||||
|
||||
// At this point we may have already run any queued promise jobs via on_call_stack_emptied,
|
||||
// in which case this is a no-op.
|
||||
// FIXME: These three should be moved out of Interpreter::run and give the host an option to run these, as it's up to the host when these get run.
|
||||
// https://tc39.es/ecma262/#sec-jobs for jobs and https://tc39.es/ecma262/#_ref_3508 for ClearKeptObjects
|
||||
// finish_execution_generation is particularly an issue for LibWeb, as the HTML spec wants to run it specifically after performing a microtask checkpoint.
|
||||
// The promise and registry cleanup queues don't cause LibWeb an issue, as LibWeb overrides the hooks that push onto these queues.
|
||||
vm.run_queued_promise_jobs();
|
||||
|
||||
vm.run_queued_finalization_registry_cleanup_jobs();
|
||||
|
||||
vm.finish_execution_generation();
|
||||
|
||||
// 18. Return ? result.
|
||||
if (result.is_abrupt()) {
|
||||
VERIFY(result.type() == Completion::Type::Throw);
|
||||
return result.release_error();
|
||||
}
|
||||
|
||||
VERIFY(result.value().has_value());
|
||||
return *result.value();
|
||||
}
|
||||
|
||||
ThrowCompletionOr<Value> Interpreter::run(SourceTextModule& module)
|
||||
{
|
||||
// FIXME: This is not a entry point as defined in the spec, but is convenient.
|
||||
// To avoid work we use link_and_eval_module however that can already be
|
||||
// dangerous if the vm loaded other modules.
|
||||
auto& vm = this->vm();
|
||||
|
||||
VM::InterpreterExecutionScope scope(*this);
|
||||
|
||||
TRY(vm.link_and_eval_module(Badge<JS::Interpreter> {}, module));
|
||||
|
||||
vm.run_queued_promise_jobs();
|
||||
|
||||
vm.run_queued_finalization_registry_cleanup_jobs();
|
||||
|
||||
return js_undefined();
|
||||
}
|
||||
|
||||
Realm& Interpreter::realm()
|
||||
{
|
||||
return static_cast<Realm&>(*m_realm.cell());
|
||||
}
|
||||
|
||||
Realm const& Interpreter::realm() const
|
||||
{
|
||||
return static_cast<Realm const&>(*m_realm.cell());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2022, Luke Wilde <lukew@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/DeprecatedFlyString.h>
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/Weakable.h>
|
||||
#include <LibJS/Forward.h>
|
||||
#include <LibJS/Heap/DeferGC.h>
|
||||
#include <LibJS/Heap/Heap.h>
|
||||
#include <LibJS/Heap/MarkedVector.h>
|
||||
#include <LibJS/Runtime/Completion.h>
|
||||
#include <LibJS/Runtime/DeclarativeEnvironment.h>
|
||||
#include <LibJS/Runtime/ErrorTypes.h>
|
||||
#include <LibJS/Runtime/GlobalEnvironment.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
#include <LibJS/Runtime/Realm.h>
|
||||
#include <LibJS/Runtime/VM.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
#include <LibJS/Script.h>
|
||||
#include <LibJS/SourceTextModule.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
struct ExecutingASTNodeChain {
|
||||
ExecutingASTNodeChain* previous { nullptr };
|
||||
ASTNode const& node;
|
||||
};
|
||||
|
||||
class Interpreter : public Weakable<Interpreter> {
|
||||
public:
|
||||
template<typename GlobalObjectType, typename... Args>
|
||||
static NonnullOwnPtr<Interpreter> create(VM& vm, Args&&... args)
|
||||
requires(IsBaseOf<GlobalObject, GlobalObjectType>)
|
||||
{
|
||||
DeferGC defer_gc(vm.heap());
|
||||
auto interpreter = adopt_own(*new Interpreter(vm));
|
||||
VM::InterpreterExecutionScope scope(*interpreter);
|
||||
|
||||
Realm* realm { nullptr };
|
||||
|
||||
interpreter->m_global_execution_context = MUST(Realm::initialize_host_defined_realm(
|
||||
vm,
|
||||
[&](Realm& realm_) -> GlobalObject* {
|
||||
realm = &realm_;
|
||||
return interpreter->heap().allocate_without_realm<GlobalObjectType>(realm_, forward<Args>(args)...);
|
||||
},
|
||||
nullptr));
|
||||
|
||||
// NOTE: These are not in the spec.
|
||||
static DeprecatedFlyString global_execution_context_name = "(global execution context)";
|
||||
interpreter->m_global_execution_context->function_name = global_execution_context_name;
|
||||
|
||||
interpreter->m_realm = make_handle(realm);
|
||||
|
||||
return interpreter;
|
||||
}
|
||||
|
||||
static NonnullOwnPtr<Interpreter> create_with_existing_realm(Realm&);
|
||||
|
||||
~Interpreter() = default;
|
||||
|
||||
ThrowCompletionOr<Value> run(Script&, JS::GCPtr<Environment> lexical_environment_override = {});
|
||||
ThrowCompletionOr<Value> run(SourceTextModule&);
|
||||
|
||||
Realm& realm();
|
||||
Realm const& realm() const;
|
||||
|
||||
ALWAYS_INLINE VM& vm() { return *m_vm; }
|
||||
ALWAYS_INLINE const VM& vm() const { return *m_vm; }
|
||||
ALWAYS_INLINE Heap& heap() { return vm().heap(); }
|
||||
|
||||
Environment* lexical_environment() { return vm().lexical_environment(); }
|
||||
|
||||
void push_ast_node(ExecutingASTNodeChain& chain_node)
|
||||
{
|
||||
chain_node.previous = m_ast_node_chain;
|
||||
m_ast_node_chain = &chain_node;
|
||||
}
|
||||
|
||||
void pop_ast_node()
|
||||
{
|
||||
VERIFY(m_ast_node_chain);
|
||||
m_ast_node_chain = m_ast_node_chain->previous;
|
||||
}
|
||||
|
||||
ASTNode const* current_node() const { return m_ast_node_chain ? &m_ast_node_chain->node : nullptr; }
|
||||
|
||||
private:
|
||||
explicit Interpreter(VM&);
|
||||
|
||||
ExecutingASTNodeChain* m_ast_node_chain { nullptr };
|
||||
|
||||
NonnullRefPtr<VM> m_vm;
|
||||
Handle<Realm> m_realm;
|
||||
|
||||
// This is here to keep the global execution context alive for the entire lifespan of the Interpreter.
|
||||
OwnPtr<ExecutionContext> m_global_execution_context;
|
||||
};
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2020-2023, Linus Groh <linusg@serenityos.org>
|
||||
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2021-2023, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -11,7 +11,6 @@
|
|||
#include <AK/Optional.h>
|
||||
#include <AK/Utf16View.h>
|
||||
#include <LibJS/Bytecode/Interpreter.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Parser.h>
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/Accessor.h>
|
||||
|
@ -24,6 +23,7 @@
|
|||
#include <LibJS/Runtime/ErrorTypes.h>
|
||||
#include <LibJS/Runtime/FunctionEnvironment.h>
|
||||
#include <LibJS/Runtime/FunctionObject.h>
|
||||
#include <LibJS/Runtime/GlobalEnvironment.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
#include <LibJS/Runtime/ObjectEnvironment.h>
|
||||
|
@ -700,26 +700,21 @@ ThrowCompletionOr<Value> perform_eval(VM& vm, Value x, CallerMode strict_caller,
|
|||
|
||||
// 29. If result.[[Type]] is normal, then
|
||||
// a. Set result to the result of evaluating body.
|
||||
if (auto* bytecode_interpreter = vm.bytecode_interpreter_if_exists()) {
|
||||
auto executable_result = Bytecode::Generator::generate(program);
|
||||
if (executable_result.is_error())
|
||||
return vm.throw_completion<InternalError>(ErrorType::NotImplemented, TRY_OR_THROW_OOM(vm, executable_result.error().to_string()));
|
||||
auto executable_result = Bytecode::Generator::generate(program);
|
||||
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"sv;
|
||||
if (Bytecode::g_dump_bytecode)
|
||||
executable->dump();
|
||||
auto result_or_error = bytecode_interpreter->run_and_return_frame(eval_realm, *executable, nullptr);
|
||||
if (result_or_error.value.is_error())
|
||||
return result_or_error.value.release_error();
|
||||
auto executable = executable_result.release_value();
|
||||
executable->name = "eval"sv;
|
||||
if (Bytecode::g_dump_bytecode)
|
||||
executable->dump();
|
||||
auto result_or_error = vm.bytecode_interpreter().run_and_return_frame(eval_realm, *executable, nullptr);
|
||||
if (result_or_error.value.is_error())
|
||||
return result_or_error.value.release_error();
|
||||
|
||||
auto& result = result_or_error.frame->registers[0];
|
||||
if (!result.is_empty())
|
||||
eval_result = result;
|
||||
} else {
|
||||
auto& ast_interpreter = vm.interpreter();
|
||||
eval_result = TRY(program->execute(ast_interpreter));
|
||||
}
|
||||
auto& result = result_or_error.frame->registers[0];
|
||||
if (!result.is_empty())
|
||||
eval_result = result;
|
||||
|
||||
// 30. If result.[[Type]] is normal and result.[[Value]] is empty, then
|
||||
// a. Set result to NormalCompletion(undefined).
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/DeclarativeEnvironment.h>
|
||||
#include <LibJS/Runtime/Error.h>
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <LibJS/Bytecode/BasicBlock.h>
|
||||
#include <LibJS/Bytecode/Generator.h>
|
||||
#include <LibJS/Bytecode/Interpreter.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/Array.h>
|
||||
#include <LibJS/Runtime/AsyncFunctionDriverWrapper.h>
|
||||
|
@ -23,6 +22,7 @@
|
|||
#include <LibJS/Runtime/ExecutionContext.h>
|
||||
#include <LibJS/Runtime/FunctionEnvironment.h>
|
||||
#include <LibJS/Runtime/GeneratorObject.h>
|
||||
#include <LibJS/Runtime/GlobalEnvironment.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
#include <LibJS/Runtime/NativeFunction.h>
|
||||
#include <LibJS/Runtime/PromiseCapability.h>
|
||||
|
@ -152,8 +152,6 @@ ThrowCompletionOr<Value> ECMAScriptFunctionObject::internal_call(Value this_argu
|
|||
|
||||
// Non-standard
|
||||
callee_context.arguments.extend(move(arguments_list));
|
||||
if (auto* interpreter = vm.interpreter_if_exists(); interpreter && interpreter->current_node())
|
||||
callee_context.source_range = interpreter->current_node()->unrealized_source_range();
|
||||
|
||||
// 2. Let calleeContext be PrepareForOrdinaryCall(F, undefined).
|
||||
// NOTE: We throw if the end of the native stack is reached, so unlike in the spec this _does_ need an exception check.
|
||||
|
@ -223,8 +221,6 @@ ThrowCompletionOr<NonnullGCPtr<Object>> ECMAScriptFunctionObject::internal_const
|
|||
|
||||
// Non-standard
|
||||
callee_context.arguments.extend(move(arguments_list));
|
||||
if (auto* interpreter = vm.interpreter_if_exists(); interpreter && interpreter->current_node())
|
||||
callee_context.source_range = interpreter->current_node()->unrealized_source_range();
|
||||
|
||||
// 4. Let calleeContext be PrepareForOrdinaryCall(F, newTarget).
|
||||
// NOTE: We throw if the end of the native stack is reached, so unlike in the spec this _does_ need an exception check.
|
||||
|
@ -329,7 +325,7 @@ void ECMAScriptFunctionObject::make_method(Object& home_object)
|
|||
}
|
||||
|
||||
// 10.2.11 FunctionDeclarationInstantiation ( func, argumentsList ), https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
|
||||
ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantiation(Interpreter* interpreter)
|
||||
ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantiation()
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
auto& realm = *vm.current_realm();
|
||||
|
@ -560,18 +556,11 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
|
|||
} else if (i < execution_context_arguments.size() && !execution_context_arguments[i].is_undefined()) {
|
||||
argument_value = execution_context_arguments[i];
|
||||
} else if (parameter.default_value) {
|
||||
auto* bytecode_interpreter = vm.bytecode_interpreter_if_exists();
|
||||
if (static_cast<FunctionKind>(m_kind) == FunctionKind::Generator || static_cast<FunctionKind>(m_kind) == FunctionKind::AsyncGenerator)
|
||||
bytecode_interpreter = &vm.bytecode_interpreter();
|
||||
if (bytecode_interpreter) {
|
||||
auto value_and_frame = bytecode_interpreter->run_and_return_frame(realm, *m_default_parameter_bytecode_executables[default_parameter_index - 1], nullptr);
|
||||
if (value_and_frame.value.is_error())
|
||||
return value_and_frame.value.release_error();
|
||||
// Resulting value is in the accumulator.
|
||||
argument_value = value_and_frame.frame->registers.at(0);
|
||||
} else if (interpreter) {
|
||||
argument_value = TRY(parameter.default_value->execute(*interpreter)).release_value();
|
||||
}
|
||||
auto value_and_frame = vm.bytecode_interpreter().run_and_return_frame(realm, *m_default_parameter_bytecode_executables[default_parameter_index - 1], nullptr);
|
||||
if (value_and_frame.value.is_error())
|
||||
return value_and_frame.value.release_error();
|
||||
// Resulting value is in the accumulator.
|
||||
argument_value = value_and_frame.frame->registers.at(0);
|
||||
} else {
|
||||
argument_value = js_undefined();
|
||||
}
|
||||
|
@ -579,18 +568,15 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
|
|||
Environment* used_environment = has_duplicates ? nullptr : environment;
|
||||
|
||||
if constexpr (IsSame<NonnullRefPtr<Identifier const> const&, decltype(param)>) {
|
||||
if ((vm.bytecode_interpreter_if_exists() || kind() == FunctionKind::Generator || kind() == FunctionKind::AsyncGenerator) && param->is_local()) {
|
||||
// NOTE: Local variables are supported only in bytecode interpreter
|
||||
if (param->is_local()) {
|
||||
callee_context.local_variables[param->local_variable_index()] = argument_value;
|
||||
return {};
|
||||
} else {
|
||||
Reference reference = TRY(vm.resolve_binding(param->string(), used_environment));
|
||||
// Here the difference from hasDuplicates is important
|
||||
if (has_duplicates)
|
||||
return reference.put_value(vm, argument_value);
|
||||
else
|
||||
return reference.initialize_referenced_binding(vm, argument_value);
|
||||
}
|
||||
Reference reference = TRY(vm.resolve_binding(param->string(), used_environment));
|
||||
// Here the difference from hasDuplicates is important
|
||||
if (has_duplicates)
|
||||
return reference.put_value(vm, argument_value);
|
||||
return reference.initialize_referenced_binding(vm, argument_value);
|
||||
}
|
||||
if constexpr (IsSame<NonnullRefPtr<BindingPattern const> const&, decltype(param)>) {
|
||||
// Here the difference from hasDuplicates is important
|
||||
|
@ -957,16 +943,12 @@ void async_block_start(VM& vm, T const& async_body, PromiseCapability const& pro
|
|||
// a. If asyncBody is a Parse Node, then
|
||||
if constexpr (!IsCallableWithArguments<T, Completion>) {
|
||||
// a. Let result be the result of evaluating asyncBody.
|
||||
if (auto* bytecode_interpreter = vm.bytecode_interpreter_if_exists()) {
|
||||
// FIXME: Cache this executable somewhere.
|
||||
auto maybe_executable = Bytecode::compile(vm, async_body, FunctionKind::Async, "AsyncBlockStart"sv);
|
||||
if (maybe_executable.is_error())
|
||||
result = maybe_executable.release_error();
|
||||
else
|
||||
result = bytecode_interpreter->run_and_return_frame(realm, *maybe_executable.value(), nullptr).value;
|
||||
} else {
|
||||
result = async_body->execute(vm.interpreter());
|
||||
}
|
||||
// FIXME: Cache this executable somewhere.
|
||||
auto maybe_executable = Bytecode::compile(vm, async_body, FunctionKind::Async, "AsyncBlockStart"sv);
|
||||
if (maybe_executable.is_error())
|
||||
result = maybe_executable.release_error();
|
||||
else
|
||||
result = vm.bytecode_interpreter().run_and_return_frame(realm, *maybe_executable.value(), nullptr).value;
|
||||
}
|
||||
// b. Else,
|
||||
else {
|
||||
|
@ -1035,8 +1017,8 @@ void async_block_start(VM& vm, T const& async_body, PromiseCapability const& pro
|
|||
// 8. Return unused.
|
||||
}
|
||||
|
||||
template void async_block_start(VM&, NonnullGCPtr<Statement const> const& async_body, PromiseCapability const&, ExecutionContext&);
|
||||
template void async_function_start(VM&, PromiseCapability const&, NonnullGCPtr<Statement const> const& async_function_body);
|
||||
template void async_block_start(VM&, NonnullRefPtr<Statement const> const& async_body, PromiseCapability const&, ExecutionContext&);
|
||||
template void async_function_start(VM&, PromiseCapability const&, NonnullRefPtr<Statement const> const& async_function_body);
|
||||
|
||||
template void async_block_start(VM&, SafeFunction<Completion()> const& async_body, PromiseCapability const&, ExecutionContext&);
|
||||
template void async_function_start(VM&, PromiseCapability const&, SafeFunction<Completion()> const& async_function_body);
|
||||
|
@ -1048,136 +1030,68 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
|
|||
auto& vm = this->vm();
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
auto* bytecode_interpreter = vm.bytecode_interpreter_if_exists();
|
||||
// NOTE: There's a subtle ordering issue here:
|
||||
// - We have to compile the default parameter values before instantiating the function.
|
||||
// - We have to instantiate the function before compiling the function body.
|
||||
// This is why FunctionDeclarationInstantiation is invoked in the middle.
|
||||
// The issue is that FunctionDeclarationInstantiation may mark certain functions as hoisted
|
||||
// per Annex B. This affects code generation for FunctionDeclaration nodes.
|
||||
|
||||
// The bytecode interpreter can execute generator functions while the AST interpreter cannot.
|
||||
// This simply makes it create a new bytecode interpreter when one doesn't exist when executing a generator function.
|
||||
// Doing so makes it automatically switch to the bytecode interpreter to execute any future code until it exits the generator. See below.
|
||||
// This allows us to keep all of the existing functionality that works in AST while adding generator support on top of it.
|
||||
// However, this does cause an awkward situation with features not supported in bytecode, where features that work outside of generators with AST
|
||||
// suddenly stop working inside of generators.
|
||||
// This is a stop gap until bytecode mode becomes the default.
|
||||
if ((m_kind == FunctionKind::Generator || m_kind == FunctionKind::AsyncGenerator) && !bytecode_interpreter) {
|
||||
bytecode_interpreter = &vm.bytecode_interpreter();
|
||||
if (!m_bytecode_executable) {
|
||||
size_t default_parameter_index = 0;
|
||||
for (auto& parameter : m_formal_parameters) {
|
||||
if (!parameter.default_value)
|
||||
continue;
|
||||
auto executable = TRY(Bytecode::compile(vm, *parameter.default_value, FunctionKind::Normal, DeprecatedString::formatted("default parameter #{} for {}", default_parameter_index, m_name)));
|
||||
m_default_parameter_bytecode_executables.append(move(executable));
|
||||
}
|
||||
}
|
||||
|
||||
if (bytecode_interpreter) {
|
||||
// NOTE: There's a subtle ordering issue here:
|
||||
// - We have to compile the default parameter values before instantiating the function.
|
||||
// - We have to instantiate the function before compiling the function body.
|
||||
// This is why FunctionDeclarationInstantiation is invoked in the middle.
|
||||
// The issue is that FunctionDeclarationInstantiation may mark certain functions as hoisted
|
||||
// per Annex B. This affects code generation for FunctionDeclaration nodes.
|
||||
auto declaration_result = function_declaration_instantiation();
|
||||
|
||||
if (!m_bytecode_executable) {
|
||||
size_t default_parameter_index = 0;
|
||||
for (auto& parameter : m_formal_parameters) {
|
||||
if (!parameter.default_value)
|
||||
continue;
|
||||
auto executable = TRY(Bytecode::compile(vm, *parameter.default_value, FunctionKind::Normal, DeprecatedString::formatted("default parameter #{} for {}", default_parameter_index, m_name)));
|
||||
m_default_parameter_bytecode_executables.append(move(executable));
|
||||
}
|
||||
}
|
||||
if (m_kind == FunctionKind::Normal || m_kind == FunctionKind::Generator || m_kind == FunctionKind::AsyncGenerator) {
|
||||
if (declaration_result.is_error())
|
||||
return declaration_result.release_error();
|
||||
}
|
||||
|
||||
auto declaration_result = function_declaration_instantiation(nullptr);
|
||||
if (!m_bytecode_executable)
|
||||
m_bytecode_executable = TRY(Bytecode::compile(vm, *m_ecmascript_code, m_kind, m_name));
|
||||
|
||||
if (m_kind == FunctionKind::Normal || m_kind == FunctionKind::Generator || m_kind == FunctionKind::AsyncGenerator) {
|
||||
if (declaration_result.is_error())
|
||||
return declaration_result.release_error();
|
||||
}
|
||||
|
||||
if (!m_bytecode_executable)
|
||||
m_bytecode_executable = TRY(Bytecode::compile(vm, *m_ecmascript_code, m_kind, m_name));
|
||||
|
||||
if (m_kind == FunctionKind::Async) {
|
||||
if (declaration_result.is_throw_completion()) {
|
||||
auto promise_capability = MUST(new_promise_capability(vm, realm.intrinsics().promise_constructor()));
|
||||
MUST(call(vm, *promise_capability->reject(), js_undefined(), *declaration_result.throw_completion().value()));
|
||||
return Completion { Completion::Type::Return, promise_capability->promise(), {} };
|
||||
}
|
||||
}
|
||||
|
||||
auto result_and_frame = bytecode_interpreter->run_and_return_frame(realm, *m_bytecode_executable, nullptr);
|
||||
|
||||
VERIFY(result_and_frame.frame != nullptr);
|
||||
if (result_and_frame.value.is_error())
|
||||
return result_and_frame.value.release_error();
|
||||
|
||||
auto result = result_and_frame.value.release_value();
|
||||
|
||||
// NOTE: Running the bytecode should eventually return a completion.
|
||||
// Until it does, we assume "return" and include the undefined fallback from the call site.
|
||||
if (m_kind == FunctionKind::Normal)
|
||||
return { Completion::Type::Return, result.value_or(js_undefined()), {} };
|
||||
|
||||
if (m_kind == FunctionKind::AsyncGenerator) {
|
||||
auto async_generator_object = TRY(AsyncGenerator::create(realm, result, this, vm.running_execution_context().copy(), move(*result_and_frame.frame)));
|
||||
return { Completion::Type::Return, async_generator_object, {} };
|
||||
}
|
||||
|
||||
auto generator_object = TRY(GeneratorObject::create(realm, result, this, vm.running_execution_context().copy(), move(*result_and_frame.frame)));
|
||||
|
||||
// NOTE: Async functions are entirely transformed to generator functions, and wrapped in a custom driver that returns a promise
|
||||
// See AwaitExpression::generate_bytecode() for the transformation.
|
||||
if (m_kind == FunctionKind::Async)
|
||||
return { Completion::Type::Return, TRY(AsyncFunctionDriverWrapper::create(realm, generator_object)), {} };
|
||||
|
||||
VERIFY(m_kind == FunctionKind::Generator);
|
||||
return { Completion::Type::Return, generator_object, {} };
|
||||
} else {
|
||||
if (m_kind == FunctionKind::Generator)
|
||||
return vm.throw_completion<InternalError>(ErrorType::NotImplemented, "Generator function execution in AST interpreter");
|
||||
if (m_kind == FunctionKind::AsyncGenerator)
|
||||
return vm.throw_completion<InternalError>(ErrorType::NotImplemented, "Async generator function execution in AST interpreter");
|
||||
OwnPtr<Interpreter> local_interpreter;
|
||||
Interpreter* ast_interpreter = vm.interpreter_if_exists();
|
||||
|
||||
if (!ast_interpreter) {
|
||||
local_interpreter = Interpreter::create_with_existing_realm(realm);
|
||||
ast_interpreter = local_interpreter.ptr();
|
||||
}
|
||||
|
||||
VM::InterpreterExecutionScope scope(*ast_interpreter);
|
||||
|
||||
// FunctionBody : FunctionStatementList
|
||||
if (m_kind == FunctionKind::Normal) {
|
||||
// 1. Perform ? FunctionDeclarationInstantiation(functionObject, argumentsList).
|
||||
TRY(function_declaration_instantiation(ast_interpreter));
|
||||
|
||||
// 2. Let result be result of evaluating FunctionStatementList.
|
||||
auto result = m_ecmascript_code->execute(*ast_interpreter);
|
||||
|
||||
// 3. Let env be the running execution context's LexicalEnvironment.
|
||||
auto env = vm.running_execution_context().lexical_environment;
|
||||
VERIFY(is<DeclarativeEnvironment>(*env));
|
||||
|
||||
// 4. Return ? DisposeResources(env, result).
|
||||
return dispose_resources(vm, static_cast<DeclarativeEnvironment*>(env.ptr()), result);
|
||||
}
|
||||
// AsyncFunctionBody : FunctionBody
|
||||
else if (m_kind == FunctionKind::Async) {
|
||||
// 1. Let promiseCapability be ! NewPromiseCapability(%Promise%).
|
||||
if (m_kind == FunctionKind::Async) {
|
||||
if (declaration_result.is_throw_completion()) {
|
||||
auto promise_capability = MUST(new_promise_capability(vm, realm.intrinsics().promise_constructor()));
|
||||
|
||||
// 2. Let declResult be Completion(FunctionDeclarationInstantiation(functionObject, argumentsList)).
|
||||
auto declaration_result = function_declaration_instantiation(ast_interpreter);
|
||||
|
||||
// 3. If declResult is an abrupt completion, then
|
||||
if (declaration_result.is_throw_completion()) {
|
||||
// a. Perform ! Call(promiseCapability.[[Reject]], undefined, « declResult.[[Value]] »).
|
||||
MUST(call(vm, *promise_capability->reject(), js_undefined(), *declaration_result.throw_completion().value()));
|
||||
}
|
||||
// 4. Else,
|
||||
else {
|
||||
// a. Perform AsyncFunctionStart(promiseCapability, FunctionBody).
|
||||
async_function_start(vm, promise_capability, m_ecmascript_code);
|
||||
}
|
||||
|
||||
// 5. Return Completion Record { [[Type]]: return, [[Value]]: promiseCapability.[[Promise]], [[Target]]: empty }.
|
||||
MUST(call(vm, *promise_capability->reject(), js_undefined(), *declaration_result.throw_completion().value()));
|
||||
return Completion { Completion::Type::Return, promise_capability->promise(), {} };
|
||||
}
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
|
||||
auto result_and_frame = vm.bytecode_interpreter().run_and_return_frame(realm, *m_bytecode_executable, nullptr);
|
||||
|
||||
VERIFY(result_and_frame.frame != nullptr);
|
||||
if (result_and_frame.value.is_error())
|
||||
return result_and_frame.value.release_error();
|
||||
|
||||
auto result = result_and_frame.value.release_value();
|
||||
|
||||
// NOTE: Running the bytecode should eventually return a completion.
|
||||
// Until it does, we assume "return" and include the undefined fallback from the call site.
|
||||
if (m_kind == FunctionKind::Normal)
|
||||
return { Completion::Type::Return, result.value_or(js_undefined()), {} };
|
||||
|
||||
if (m_kind == FunctionKind::AsyncGenerator) {
|
||||
auto async_generator_object = TRY(AsyncGenerator::create(realm, result, this, vm.running_execution_context().copy(), move(*result_and_frame.frame)));
|
||||
return { Completion::Type::Return, async_generator_object, {} };
|
||||
}
|
||||
|
||||
auto generator_object = TRY(GeneratorObject::create(realm, result, this, vm.running_execution_context().copy(), move(*result_and_frame.frame)));
|
||||
|
||||
// NOTE: Async functions are entirely transformed to generator functions, and wrapped in a custom driver that returns a promise
|
||||
// See AwaitExpression::generate_bytecode() for the transformation.
|
||||
if (m_kind == FunctionKind::Async)
|
||||
return { Completion::Type::Return, TRY(AsyncFunctionDriverWrapper::create(realm, generator_object)), {} };
|
||||
|
||||
VERIFY(m_kind == FunctionKind::Generator);
|
||||
return { Completion::Type::Return, generator_object, {} };
|
||||
}
|
||||
|
||||
void ECMAScriptFunctionObject::set_name(DeprecatedFlyString const& name)
|
||||
|
@ -1187,5 +1101,4 @@ void ECMAScriptFunctionObject::set_name(DeprecatedFlyString const& name)
|
|||
m_name = name;
|
||||
MUST(define_property_or_throw(vm.names.name, { .value = PrimitiveString::create(vm, m_name), .writable = false, .enumerable = false, .configurable = true }));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ private:
|
|||
ThrowCompletionOr<void> prepare_for_ordinary_call(ExecutionContext& callee_context, Object* new_target);
|
||||
void ordinary_call_bind_this(ExecutionContext&, Value this_argument);
|
||||
|
||||
ThrowCompletionOr<void> function_declaration_instantiation(Interpreter*);
|
||||
ThrowCompletionOr<void> function_declaration_instantiation();
|
||||
|
||||
DeprecatedFlyString m_name;
|
||||
OwnPtr<Bytecode::Executable> m_bytecode_executable;
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/Completion.h>
|
||||
#include <LibJS/Runtime/ECMAScriptFunctionObject.h>
|
||||
#include <LibJS/Runtime/FunctionEnvironment.h>
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
*/
|
||||
|
||||
#include <AK/TypeCasts.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/Completion.h>
|
||||
#include <LibJS/Runtime/FunctionObject.h>
|
||||
#include <LibJS/Runtime/NativeFunction.h>
|
||||
#include <LibJS/Runtime/VM.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include <AK/StringBuilder.h>
|
||||
#include <AK/TypeCasts.h>
|
||||
#include <LibJS/Heap/MarkedVector.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/BoundFunction.h>
|
||||
#include <LibJS/Runtime/ECMAScriptFunctionObject.h>
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <AK/Utf16View.h>
|
||||
#include <AK/Utf8View.h>
|
||||
#include <LibJS/Heap/DeferGC.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/AggregateErrorConstructor.h>
|
||||
#include <LibJS/Runtime/ArrayBufferConstructor.h>
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
|
||||
#include <LibJS/AST.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/FunctionEnvironment.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
#include <LibJS/Runtime/NativeFunction.h>
|
||||
|
@ -142,9 +141,6 @@ ThrowCompletionOr<Value> NativeFunction::internal_call(Value this_argument, Mark
|
|||
// NOTE: This is a LibJS specific hack for NativeFunction to inherit the strictness of its caller.
|
||||
callee_context.is_strict_mode = vm.in_strict_mode();
|
||||
|
||||
if (auto* interpreter = vm.interpreter_if_exists(); interpreter && interpreter->current_node())
|
||||
callee_context.source_range = interpreter->current_node()->unrealized_source_range();
|
||||
|
||||
// </8.> --------------------------------------------------------------------------
|
||||
|
||||
// 9. Push calleeContext onto the execution context stack; calleeContext is now the running execution context.
|
||||
|
@ -205,9 +201,6 @@ ThrowCompletionOr<NonnullGCPtr<Object>> NativeFunction::internal_construct(Marke
|
|||
// NOTE: This is a LibJS specific hack for NativeFunction to inherit the strictness of its caller.
|
||||
callee_context.is_strict_mode = vm.in_strict_mode();
|
||||
|
||||
if (auto* interpreter = vm.interpreter_if_exists(); interpreter && interpreter->current_node())
|
||||
callee_context.source_range = interpreter->current_node()->unrealized_source_range();
|
||||
|
||||
// </8.> --------------------------------------------------------------------------
|
||||
|
||||
// 9. Push calleeContext onto the execution context stack; calleeContext is now the running execution context.
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
#include <AK/DeprecatedString.h>
|
||||
#include <AK/TypeCasts.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/Accessor.h>
|
||||
#include <LibJS/Runtime/Array.h>
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/AggregateError.h>
|
||||
#include <LibJS/Runtime/Array.h>
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/Error.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
#include <LibJS/Bytecode/Executable.h>
|
||||
#include <LibJS/Bytecode/Interpreter.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Lexer.h>
|
||||
#include <LibJS/Parser.h>
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
|
@ -173,26 +172,19 @@ ThrowCompletionOr<Value> perform_shadow_realm_eval(VM& vm, StringView source_tex
|
|||
// 17. If result.[[Type]] is normal, then
|
||||
if (!eval_result.is_throw_completion()) {
|
||||
// a. Set result to the result of evaluating body.
|
||||
if (auto* bytecode_interpreter = vm.bytecode_interpreter_if_exists()) {
|
||||
auto maybe_executable = Bytecode::compile(vm, program, FunctionKind::Normal, "ShadowRealmEval"sv);
|
||||
if (maybe_executable.is_error())
|
||||
result = maybe_executable.release_error();
|
||||
else {
|
||||
auto executable = maybe_executable.release_value();
|
||||
auto maybe_executable = Bytecode::compile(vm, program, FunctionKind::Normal, "ShadowRealmEval"sv);
|
||||
if (maybe_executable.is_error())
|
||||
result = maybe_executable.release_error();
|
||||
else {
|
||||
auto executable = maybe_executable.release_value();
|
||||
|
||||
auto value_and_frame = bytecode_interpreter->run_and_return_frame(eval_realm, *executable, nullptr);
|
||||
if (value_and_frame.value.is_error()) {
|
||||
result = value_and_frame.value.release_error();
|
||||
} else {
|
||||
// Resulting value is in the accumulator.
|
||||
result = value_and_frame.frame->registers.at(0).value_or(js_undefined());
|
||||
}
|
||||
auto value_and_frame = vm.bytecode_interpreter().run_and_return_frame(eval_realm, *executable, nullptr);
|
||||
if (value_and_frame.value.is_error()) {
|
||||
result = value_and_frame.value.release_error();
|
||||
} else {
|
||||
// Resulting value is in the accumulator.
|
||||
result = value_and_frame.frame->registers.at(0).value_or(js_undefined());
|
||||
}
|
||||
} else {
|
||||
// FIXME: Remove once everything uses the VM's current realm.
|
||||
auto eval_realm_interpreter = Interpreter::create_with_existing_realm(eval_realm);
|
||||
|
||||
result = program->execute(*eval_realm_interpreter);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <LibFileSystem/FileSystem.h>
|
||||
#include <LibJS/AST.h>
|
||||
#include <LibJS/Bytecode/Interpreter.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/Array.h>
|
||||
#include <LibJS/Runtime/BoundFunction.h>
|
||||
|
@ -188,19 +187,6 @@ void VM::enable_default_host_import_module_dynamically_hook()
|
|||
};
|
||||
}
|
||||
|
||||
Interpreter& VM::interpreter()
|
||||
{
|
||||
VERIFY(!m_interpreters.is_empty());
|
||||
return *m_interpreters.last();
|
||||
}
|
||||
|
||||
Interpreter* VM::interpreter_if_exists()
|
||||
{
|
||||
if (m_interpreters.is_empty())
|
||||
return nullptr;
|
||||
return m_interpreters.last();
|
||||
}
|
||||
|
||||
Bytecode::Interpreter& VM::bytecode_interpreter()
|
||||
{
|
||||
return *m_bytecode_interpreter;
|
||||
|
@ -211,29 +197,6 @@ Bytecode::Interpreter* VM::bytecode_interpreter_if_exists()
|
|||
return m_bytecode_interpreter;
|
||||
}
|
||||
|
||||
void VM::push_interpreter(Interpreter& interpreter)
|
||||
{
|
||||
m_interpreters.append(&interpreter);
|
||||
}
|
||||
|
||||
void VM::pop_interpreter(Interpreter& interpreter)
|
||||
{
|
||||
VERIFY(!m_interpreters.is_empty());
|
||||
auto* popped_interpreter = m_interpreters.take_last();
|
||||
VERIFY(popped_interpreter == &interpreter);
|
||||
}
|
||||
|
||||
VM::InterpreterExecutionScope::InterpreterExecutionScope(Interpreter& interpreter)
|
||||
: m_interpreter(interpreter)
|
||||
{
|
||||
m_interpreter.vm().push_interpreter(m_interpreter);
|
||||
}
|
||||
|
||||
VM::InterpreterExecutionScope::~InterpreterExecutionScope()
|
||||
{
|
||||
m_interpreter.vm().pop_interpreter(m_interpreter);
|
||||
}
|
||||
|
||||
void VM::gather_roots(HashTable<Cell*>& roots)
|
||||
{
|
||||
roots.set(m_empty_string);
|
||||
|
@ -356,15 +319,11 @@ ThrowCompletionOr<void> VM::binding_initialization(NonnullRefPtr<BindingPattern
|
|||
|
||||
ThrowCompletionOr<Value> VM::execute_ast_node(ASTNode const& node)
|
||||
{
|
||||
if (auto* bytecode_interpreter = bytecode_interpreter_if_exists()) {
|
||||
auto executable = TRY(Bytecode::compile(*this, node, FunctionKind::Normal, ""sv));
|
||||
auto result_or_error = bytecode_interpreter->run_and_return_frame(*current_realm(), *executable, nullptr);
|
||||
if (result_or_error.value.is_error())
|
||||
return result_or_error.value.release_error();
|
||||
return result_or_error.frame->registers[0];
|
||||
}
|
||||
|
||||
return TRY(node.execute(interpreter())).value();
|
||||
auto executable = TRY(Bytecode::compile(*this, node, FunctionKind::Normal, ""sv));
|
||||
auto result_or_error = bytecode_interpreter().run_and_return_frame(*current_realm(), *executable, nullptr);
|
||||
if (result_or_error.value.is_error())
|
||||
return result_or_error.value.release_error();
|
||||
return result_or_error.frame->registers[0];
|
||||
}
|
||||
|
||||
// 13.15.5.3 Runtime Semantics: PropertyDestructuringAssignmentEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-propertydestructuringassignmentevaluation
|
||||
|
@ -385,8 +344,6 @@ ThrowCompletionOr<void> VM::property_binding_initialization(BindingPattern const
|
|||
Reference assignment_target;
|
||||
if (auto identifier_ptr = property.name.get_pointer<NonnullRefPtr<Identifier const>>()) {
|
||||
assignment_target = TRY(resolve_binding((*identifier_ptr)->string(), environment));
|
||||
} else if (auto member_ptr = property.alias.get_pointer<NonnullRefPtr<MemberExpression const>>()) {
|
||||
assignment_target = TRY((*member_ptr)->to_reference(interpreter()));
|
||||
} else {
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
@ -436,8 +393,8 @@ ThrowCompletionOr<void> VM::property_binding_initialization(BindingPattern const
|
|||
return TRY(resolve_binding(identifier->string(), environment));
|
||||
},
|
||||
[&](NonnullRefPtr<BindingPattern const> const&) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; },
|
||||
[&](NonnullRefPtr<MemberExpression const> const& member_expression) -> ThrowCompletionOr<Optional<Reference>> {
|
||||
return TRY(member_expression->to_reference(interpreter()));
|
||||
[&](NonnullRefPtr<MemberExpression const> const&) -> ThrowCompletionOr<Optional<Reference>> {
|
||||
VERIFY_NOT_REACHED();
|
||||
}));
|
||||
|
||||
auto value_to_assign = TRY(object->get(name));
|
||||
|
@ -480,8 +437,8 @@ ThrowCompletionOr<void> VM::iterator_binding_initialization(BindingPattern const
|
|||
return TRY(resolve_binding(identifier->string(), environment));
|
||||
},
|
||||
[&](NonnullRefPtr<BindingPattern const> const&) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; },
|
||||
[&](NonnullRefPtr<MemberExpression const> const& member_expression) -> ThrowCompletionOr<Optional<Reference>> {
|
||||
return TRY(member_expression->to_reference(interpreter()));
|
||||
[&](NonnullRefPtr<MemberExpression const> const&) -> ThrowCompletionOr<Optional<Reference>> {
|
||||
VERIFY_NOT_REACHED();
|
||||
}));
|
||||
|
||||
// BindingRestElement : ... BindingIdentifier
|
||||
|
@ -861,11 +818,6 @@ VM::StoredModule* VM::get_stored_module(ScriptOrModule const&, DeprecatedString
|
|||
return &(*end_or_module);
|
||||
}
|
||||
|
||||
ThrowCompletionOr<void> VM::link_and_eval_module(Badge<Interpreter>, SourceTextModule& module)
|
||||
{
|
||||
return link_and_eval_module(module);
|
||||
}
|
||||
|
||||
ThrowCompletionOr<void> VM::link_and_eval_module(Badge<Bytecode::Interpreter>, SourceTextModule& module)
|
||||
{
|
||||
return link_and_eval_module(module);
|
||||
|
|
|
@ -46,25 +46,8 @@ public:
|
|||
Bytecode::Interpreter& bytecode_interpreter();
|
||||
Bytecode::Interpreter* bytecode_interpreter_if_exists();
|
||||
|
||||
Interpreter& interpreter();
|
||||
Interpreter* interpreter_if_exists();
|
||||
|
||||
void push_interpreter(Interpreter&);
|
||||
void pop_interpreter(Interpreter&);
|
||||
|
||||
void dump_backtrace() const;
|
||||
|
||||
class InterpreterExecutionScope {
|
||||
public:
|
||||
InterpreterExecutionScope(Interpreter&);
|
||||
~InterpreterExecutionScope();
|
||||
|
||||
Interpreter& interpreter() { return m_interpreter; }
|
||||
|
||||
private:
|
||||
Interpreter& m_interpreter;
|
||||
};
|
||||
|
||||
void gather_roots(HashTable<Cell*>&);
|
||||
|
||||
#define __JS_ENUMERATE(SymbolName, snake_name) \
|
||||
|
@ -249,7 +232,6 @@ public:
|
|||
void restore_execution_context_stack();
|
||||
|
||||
// Do not call this method unless you are sure this is the only and first module to be loaded in this vm.
|
||||
ThrowCompletionOr<void> link_and_eval_module(Badge<Interpreter>, SourceTextModule& module);
|
||||
ThrowCompletionOr<void> link_and_eval_module(Badge<Bytecode::Interpreter>, SourceTextModule& module);
|
||||
|
||||
ScriptOrModule get_active_script_or_module() const;
|
||||
|
@ -304,7 +286,6 @@ private:
|
|||
HashMap<DeprecatedString, GCPtr<PrimitiveString>> m_deprecated_string_cache;
|
||||
|
||||
Heap m_heap;
|
||||
Vector<Interpreter*> m_interpreters;
|
||||
|
||||
Vector<ExecutionContext*> m_execution_context_stack;
|
||||
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
#include <AK/Debug.h>
|
||||
#include <AK/QuickSort.h>
|
||||
#include <LibJS/Bytecode/Interpreter.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Parser.h>
|
||||
#include <LibJS/Runtime/ECMAScriptFunctionObject.h>
|
||||
#include <LibJS/Runtime/GlobalEnvironment.h>
|
||||
#include <LibJS/Runtime/ModuleEnvironment.h>
|
||||
#include <LibJS/SourceTextModule.h>
|
||||
|
||||
|
@ -695,23 +695,19 @@ ThrowCompletionOr<void> SourceTextModule::execute_module(VM& vm, GCPtr<PromiseCa
|
|||
// c. Let result be the result of evaluating module.[[ECMAScriptCode]].
|
||||
Completion result;
|
||||
|
||||
if (auto* bytecode_interpreter = vm.bytecode_interpreter_if_exists()) {
|
||||
auto maybe_executable = Bytecode::compile(vm, m_ecmascript_code, FunctionKind::Normal, "ShadowRealmEval"sv);
|
||||
if (maybe_executable.is_error())
|
||||
result = maybe_executable.release_error();
|
||||
else {
|
||||
auto executable = maybe_executable.release_value();
|
||||
auto maybe_executable = Bytecode::compile(vm, m_ecmascript_code, FunctionKind::Normal, "ShadowRealmEval"sv);
|
||||
if (maybe_executable.is_error())
|
||||
result = maybe_executable.release_error();
|
||||
else {
|
||||
auto executable = maybe_executable.release_value();
|
||||
|
||||
auto value_and_frame = bytecode_interpreter->run_and_return_frame(realm(), *executable, nullptr);
|
||||
if (value_and_frame.value.is_error()) {
|
||||
result = value_and_frame.value.release_error();
|
||||
} else {
|
||||
// Resulting value is in the accumulator.
|
||||
result = value_and_frame.frame->registers.at(0).value_or(js_undefined());
|
||||
}
|
||||
auto value_and_frame = vm.bytecode_interpreter().run_and_return_frame(realm(), *executable, nullptr);
|
||||
if (value_and_frame.value.is_error()) {
|
||||
result = value_and_frame.value.release_error();
|
||||
} else {
|
||||
// Resulting value is in the accumulator.
|
||||
result = value_and_frame.frame->registers.at(0).value_or(js_undefined());
|
||||
}
|
||||
} else {
|
||||
result = m_ecmascript_code->execute(vm.interpreter());
|
||||
}
|
||||
|
||||
// d. Let env be moduleContext's LexicalEnvironment.
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include <LibCore/DirIterator.h>
|
||||
#include <LibCore/File.h>
|
||||
#include <LibJS/Bytecode/Interpreter.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Lexer.h>
|
||||
#include <LibJS/Parser.h>
|
||||
#include <LibJS/Runtime/Array.h>
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <AK/StringBuilder.h>
|
||||
#include <AK/Utf8View.h>
|
||||
#include <LibCore/Timer.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/Array.h>
|
||||
#include <LibJS/Runtime/FunctionObject.h>
|
||||
#include <LibJS/Runtime/NativeFunction.h>
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <Kernel/API/KeyCode.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Parser.h>
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/ECMAScriptFunctionObject.h>
|
||||
#include <LibJS/Runtime/GlobalEnvironment.h>
|
||||
#include <LibJS/Runtime/NativeFunction.h>
|
||||
#include <LibJS/Runtime/ObjectEnvironment.h>
|
||||
#include <LibJS/Runtime/VM.h>
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibWeb/ARIA/Roles.h>
|
||||
#include <LibWeb/Bindings/ExceptionOrUtils.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include <AK/Debug.h>
|
||||
#include <LibCore/ElapsedTimer.h>
|
||||
#include <LibJS/Bytecode/Interpreter.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibWeb/Bindings/ExceptionOrUtils.h>
|
||||
#include <LibWeb/HTML/Scripting/ClassicScript.h>
|
||||
#include <LibWeb/HTML/Scripting/Environments.h>
|
||||
|
@ -95,12 +94,7 @@ JS::Completion ClassicScript::run(RethrowErrors rethrow_errors, JS::GCPtr<JS::En
|
|||
auto timer = Core::ElapsedTimer::start_new();
|
||||
|
||||
// 6. Otherwise, set evaluationStatus to ScriptEvaluation(script's record).
|
||||
if (auto* bytecode_interpreter = vm().bytecode_interpreter_if_exists()) {
|
||||
evaluation_status = bytecode_interpreter->run(*m_script_record, lexical_environment_override);
|
||||
} else {
|
||||
auto interpreter = JS::Interpreter::create_with_existing_realm(m_script_record->realm());
|
||||
evaluation_status = interpreter->run(*m_script_record, lexical_environment_override);
|
||||
}
|
||||
evaluation_status = vm().bytecode_interpreter().run(*m_script_record, lexical_environment_override);
|
||||
|
||||
// FIXME: If ScriptEvaluation does not complete because the user agent has aborted the running script, leave evaluationStatus as null.
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/ModuleRequest.h>
|
||||
#include <LibWeb/HTML/Scripting/Environments.h>
|
||||
#include <LibWeb/HTML/Scripting/Fetching.h>
|
||||
|
@ -136,9 +135,6 @@ JS::Promise* JavaScriptModuleScript::run(PreventErrorReporting)
|
|||
auto record = m_record;
|
||||
VERIFY(record);
|
||||
|
||||
auto interpreter = JS::Interpreter::create_with_existing_realm(settings.realm());
|
||||
JS::VM::InterpreterExecutionScope scope(*interpreter);
|
||||
|
||||
// 2. Set evaluationPromise to record.Evaluate().
|
||||
auto elevation_promise_or_error = record->evaluate(vm());
|
||||
|
||||
|
|
|
@ -23,8 +23,6 @@ Worker::Worker(String const& script_url, WorkerOptions const options, DOM::Docum
|
|||
, m_document(&document)
|
||||
, m_custom_data()
|
||||
, m_worker_vm(JS::VM::create(adopt_own(m_custom_data)).release_value_but_fixme_should_propagate_errors())
|
||||
, m_interpreter(JS::Interpreter::create<JS::GlobalObject>(m_worker_vm))
|
||||
, m_interpreter_scope(*m_interpreter)
|
||||
, m_implicit_port(MessagePort::create(document.realm()).release_value_but_fixme_should_propagate_errors())
|
||||
{
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include <AK/RefCounted.h>
|
||||
#include <AK/URLParser.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibWeb/Bindings/MainThreadVM.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
#include <LibWeb/HTML/MessageEvent.h>
|
||||
|
@ -79,9 +78,7 @@ private:
|
|||
Bindings::WebEngineCustomData m_custom_data;
|
||||
|
||||
NonnullRefPtr<JS::VM> m_worker_vm;
|
||||
NonnullOwnPtr<JS::Interpreter> m_interpreter;
|
||||
JS::GCPtr<WorkerEnvironmentSettingsObject> m_inner_settings;
|
||||
JS::VM::InterpreterExecutionScope m_interpreter_scope;
|
||||
RefPtr<WorkerDebugConsoleClient> m_console;
|
||||
|
||||
JS::NonnullGCPtr<MessagePort> m_implicit_port;
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
|
||||
#include "WebContentConsoleClient.h"
|
||||
#include <AK/TemporaryChange.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/MarkupGenerator.h>
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/GlobalEnvironment.h>
|
||||
#include <LibJS/Runtime/ObjectEnvironment.h>
|
||||
#include <LibJS/Runtime/Realm.h>
|
||||
#include <LibJS/Runtime/ThrowableStringBuilder.h>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2020-2023, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2020-2023, Linus Groh <linusg@serenityos.org>
|
||||
* Copyright (c) 2020-2022, Ali Mohammad Pur <mpfard@serenityos.org>
|
||||
*
|
||||
|
@ -16,10 +16,11 @@
|
|||
#include <LibJS/Bytecode/Interpreter.h>
|
||||
#include <LibJS/Console.h>
|
||||
#include <LibJS/Contrib/Test262/GlobalObject.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Parser.h>
|
||||
#include <LibJS/Print.h>
|
||||
#include <LibJS/Runtime/ConsoleObject.h>
|
||||
#include <LibJS/Runtime/DeclarativeEnvironment.h>
|
||||
#include <LibJS/Runtime/GlobalEnvironment.h>
|
||||
#include <LibJS/Runtime/JSONObject.h>
|
||||
#include <LibJS/Runtime/StringPrototype.h>
|
||||
#include <LibJS/Runtime/ThrowableStringBuilder.h>
|
||||
|
|
Loading…
Reference in a new issue