mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 16:22:43 +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
					
				
					 41 changed files with 147 additions and 3734 deletions
				
			
		|  | @ -15,7 +15,6 @@ | ||||||
| #include <LibJS/Bytecode/Generator.h> | #include <LibJS/Bytecode/Generator.h> | ||||||
| #include <LibJS/Bytecode/Interpreter.h> | #include <LibJS/Bytecode/Interpreter.h> | ||||||
| #include <LibJS/Console.h> | #include <LibJS/Console.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Parser.h> | #include <LibJS/Parser.h> | ||||||
| #include <LibJS/Print.h> | #include <LibJS/Print.h> | ||||||
| #include <LibJS/Runtime/ConsoleObject.h> | #include <LibJS/Runtime/ConsoleObject.h> | ||||||
|  |  | ||||||
|  | @ -17,10 +17,10 @@ | ||||||
| #include <LibJS/Bytecode/Generator.h> | #include <LibJS/Bytecode/Generator.h> | ||||||
| #include <LibJS/Bytecode/Interpreter.h> | #include <LibJS/Bytecode/Interpreter.h> | ||||||
| #include <LibJS/Contrib/Test262/GlobalObject.h> | #include <LibJS/Contrib/Test262/GlobalObject.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Parser.h> | #include <LibJS/Parser.h> | ||||||
| #include <LibJS/Runtime/VM.h> | #include <LibJS/Runtime/VM.h> | ||||||
| #include <LibJS/Script.h> | #include <LibJS/Script.h> | ||||||
|  | #include <LibJS/SourceTextModule.h> | ||||||
| #include <fcntl.h> | #include <fcntl.h> | ||||||
| #include <signal.h> | #include <signal.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
|  | @ -206,27 +206,28 @@ static Result<void, TestError> run_test(StringView source, StringView filepath, | ||||||
| 
 | 
 | ||||||
|     auto vm = MUST(JS::VM::create()); |     auto vm = MUST(JS::VM::create()); | ||||||
|     vm->enable_default_host_import_module_dynamically_hook(); |     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()) |     if (program_or_error.is_error()) | ||||||
|         return program_or_error.release_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) { |     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()) |         if (harness_program_or_error.is_error()) | ||||||
|             return harness_program_or_error.release_error(); |             return harness_program_or_error.release_error(); | ||||||
|         ScriptOrModuleProgram harness_program { harness_program_or_error.release_value() }; |         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()) { |         if (result.is_error()) { | ||||||
|             return TestError { |             return TestError { | ||||||
|                 NegativePhase::Harness, |                 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) | static Result<TestMetadata, DeprecatedString> extract_metadata(StringView source) | ||||||
|  |  | ||||||
|  | @ -11,7 +11,6 @@ | ||||||
| #include <AK/URL.h> | #include <AK/URL.h> | ||||||
| #include <LibDesktop/AppFile.h> | #include <LibDesktop/AppFile.h> | ||||||
| #include <LibGUI/Desktop.h> | #include <LibGUI/Desktop.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Runtime/VM.h> | #include <LibJS/Runtime/VM.h> | ||||||
| #include <LibThreading/BackgroundAction.h> | #include <LibThreading/BackgroundAction.h> | ||||||
| #include <typeinfo> | #include <typeinfo> | ||||||
|  |  | ||||||
|  | @ -31,7 +31,6 @@ | ||||||
| #include <LibGUI/TabWidget.h> | #include <LibGUI/TabWidget.h> | ||||||
| #include <LibGUI/ToolbarContainer.h> | #include <LibGUI/ToolbarContainer.h> | ||||||
| #include <LibGUI/Widget.h> | #include <LibGUI/Widget.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibWeb/CSS/PreferredColorScheme.h> | #include <LibWeb/CSS/PreferredColorScheme.h> | ||||||
| #include <LibWeb/Dump.h> | #include <LibWeb/Dump.h> | ||||||
| #include <LibWeb/Layout/Viewport.h> | #include <LibWeb/Layout/Viewport.h> | ||||||
|  |  | ||||||
|  | @ -35,7 +35,6 @@ | ||||||
| #include <LibGUI/Toolbar.h> | #include <LibGUI/Toolbar.h> | ||||||
| #include <LibGUI/ToolbarContainer.h> | #include <LibGUI/ToolbarContainer.h> | ||||||
| #include <LibGUI/Window.h> | #include <LibGUI/Window.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibWeb/HTML/BrowsingContext.h> | #include <LibWeb/HTML/BrowsingContext.h> | ||||||
| #include <LibWeb/HTML/SyntaxHighlighter/SyntaxHighlighter.h> | #include <LibWeb/HTML/SyntaxHighlighter/SyntaxHighlighter.h> | ||||||
| #include <LibWeb/Layout/BlockContainer.h> | #include <LibWeb/Layout/BlockContainer.h> | ||||||
|  |  | ||||||
|  | @ -18,7 +18,6 @@ | ||||||
| #include <AK/WeakPtr.h> | #include <AK/WeakPtr.h> | ||||||
| #include <AK/Weakable.h> | #include <AK/Weakable.h> | ||||||
| #include <LibCore/EventReceiver.h> | #include <LibCore/EventReceiver.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| 
 | 
 | ||||||
| namespace Spreadsheet { | 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.
 |     // NOTE: This is here to stop ASAN complaining about mismatch between new/delete sizes in ASTNodeWithTailArray.
 | ||||||
|     void operator delete(void* ptr) { ::operator delete(ptr); } |     void operator delete(void* ptr) { ::operator delete(ptr); } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const = 0; |  | ||||||
|     virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const; |     virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const; | ||||||
|     virtual void dump(int indent) 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 void dump(int indent) const override; | ||||||
|     virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) 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; |     virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) const; | ||||||
|  | @ -197,7 +195,6 @@ class IterationStatement : public Statement { | ||||||
| public: | public: | ||||||
|     using Statement::Statement; |     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; |     virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) const; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  | @ -210,7 +207,6 @@ public: | ||||||
|         : Statement(source_range) |         : Statement(source_range) | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
|     Completion execute(Interpreter&) const override; |  | ||||||
|     virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; |     virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -220,7 +216,6 @@ public: | ||||||
|         : Statement(source_range) |         : Statement(source_range) | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
|     Completion execute(Interpreter&) const override { return {}; } |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class ExpressionStatement final : public Statement { | class ExpressionStatement final : public Statement { | ||||||
|  | @ -231,7 +226,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -298,8 +292,6 @@ public: | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|     Completion evaluate_statements(Interpreter&) const; |  | ||||||
| 
 |  | ||||||
|     void add_var_scoped_declaration(NonnullRefPtr<Declaration const> variables); |     void add_var_scoped_declaration(NonnullRefPtr<Declaration const> variables); | ||||||
|     void add_lexical_declaration(NonnullRefPtr<Declaration const> variables); |     void add_lexical_declaration(NonnullRefPtr<Declaration const> variables); | ||||||
|     void add_hoisted_function(NonnullRefPtr<FunctionDeclaration const> declaration); |     void add_hoisted_function(NonnullRefPtr<FunctionDeclaration const> declaration); | ||||||
|  | @ -384,8 +376,6 @@ public: | ||||||
|             entry.m_module_request = &m_module_request; |             entry.m_module_request = &m_module_request; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
| 
 |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
|  | @ -483,8 +473,6 @@ public: | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
| 
 |  | ||||||
|     virtual void dump(int indent) 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(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; } |     bool is_strict_mode() const { return m_is_strict_mode; } | ||||||
|     void set_strict_mode() { m_is_strict_mode = true; } |     void set_strict_mode() { m_is_strict_mode = true; } | ||||||
| 
 | 
 | ||||||
|  | @ -575,7 +561,6 @@ public: | ||||||
|         : ScopeNode(source_range) |         : ScopeNode(source_range) | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
|     Completion execute(Interpreter&) const override; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class FunctionBody final : public ScopeNode { | class FunctionBody final : public ScopeNode { | ||||||
|  | @ -589,8 +574,6 @@ public: | ||||||
| 
 | 
 | ||||||
|     bool in_strict_mode() const { return m_in_strict_mode; } |     bool in_strict_mode() const { return m_in_strict_mode; } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
| 
 |  | ||||||
| private: | private: | ||||||
|     bool m_in_strict_mode { false }; |     bool m_in_strict_mode { false }; | ||||||
| }; | }; | ||||||
|  | @ -601,7 +584,6 @@ public: | ||||||
|         : ASTNode(source_range) |         : ASTNode(source_range) | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
|     virtual ThrowCompletionOr<Reference> to_reference(Interpreter&) const; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class Declaration : public Statement { | class Declaration : public Statement { | ||||||
|  | @ -625,7 +607,6 @@ public: | ||||||
|         : Declaration(source_range) |         : Declaration(source_range) | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
|     Completion execute(Interpreter&) const override { return {}; } |  | ||||||
| 
 | 
 | ||||||
|     ThrowCompletionOr<void> for_each_bound_identifier(ThrowCompletionOrVoidCallback<Identifier const&>&&) const override |     ThrowCompletionOr<void> for_each_bound_identifier(ThrowCompletionOrVoidCallback<Identifier const&>&&) const override | ||||||
|     { |     { | ||||||
|  | @ -681,9 +662,7 @@ public: | ||||||
|     bool is_global() const { return m_is_global; } |     bool is_global() const { return m_is_global; } | ||||||
|     void set_is_global() { m_is_global = true; } |     void set_is_global() { m_is_global = true; } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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; |     virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  | @ -765,7 +744,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -791,7 +769,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
|  | @ -811,8 +788,6 @@ public: | ||||||
|         : Expression(source_range) |         : Expression(source_range) | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     Completion execute(Interpreter&) const override { return {}; } |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class YieldExpression final : public Expression { | class YieldExpression final : public Expression { | ||||||
|  | @ -827,7 +802,6 @@ public: | ||||||
|     Expression const* argument() const { return m_argument; } |     Expression const* argument() const { return m_argument; } | ||||||
|     bool is_yield_from() const { return m_is_yield_from; } |     bool is_yield_from() const { return m_is_yield_from; } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -844,7 +818,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -862,7 +835,6 @@ public: | ||||||
| 
 | 
 | ||||||
|     Expression const* argument() const { return m_argument; } |     Expression const* argument() const { return m_argument; } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -884,7 +856,6 @@ public: | ||||||
|     Statement const& consequent() const { return *m_consequent; } |     Statement const& consequent() const { return *m_consequent; } | ||||||
|     Statement const* alternate() const { return m_alternate; } |     Statement const* alternate() const { return m_alternate; } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -906,8 +877,6 @@ public: | ||||||
|     Expression const& test() const { return *m_test; } |     Expression const& test() const { return *m_test; } | ||||||
|     Statement const& body() const { return *m_body; } |     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 void dump(int indent) const override; | ||||||
|     virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) 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 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; } |     Expression const& test() const { return *m_test; } | ||||||
|     Statement const& body() const { return *m_body; } |     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 void dump(int indent) const override; | ||||||
|     virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) 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 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; } |     Expression const& object() const { return *m_object; } | ||||||
|     Statement const& body() const { return *m_body; } |     Statement const& body() const { return *m_body; } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -977,15 +943,11 @@ public: | ||||||
|     Expression const* update() const { return m_update; } |     Expression const* update() const { return m_update; } | ||||||
|     Statement const& body() const { return *m_body; } |     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 void dump(int indent) const override; | ||||||
|     virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) 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 Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) const override; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     Completion for_body_evaluation(Interpreter&, Vector<DeprecatedFlyString> const&, size_t per_iteration_bindings_size) const; |  | ||||||
| 
 |  | ||||||
|     RefPtr<ASTNode const> m_init; |     RefPtr<ASTNode const> m_init; | ||||||
|     RefPtr<Expression const> m_test; |     RefPtr<Expression const> m_test; | ||||||
|     RefPtr<Expression const> m_update; |     RefPtr<Expression const> m_update; | ||||||
|  | @ -1006,10 +968,8 @@ public: | ||||||
|     Expression const& rhs() const { return *m_rhs; } |     Expression const& rhs() const { return *m_rhs; } | ||||||
|     Statement const& body() const { return *m_body; } |     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_bytecode(Bytecode::Generator&) const override; | ||||||
|     virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) 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; |     virtual void dump(int indent) const override; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  | @ -1032,10 +992,8 @@ public: | ||||||
|     Expression const& rhs() const { return *m_rhs; } |     Expression const& rhs() const { return *m_rhs; } | ||||||
|     Statement const& body() const { return *m_body; } |     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_bytecode(Bytecode::Generator&) const override; | ||||||
|     virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) 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; |     virtual void dump(int indent) const override; | ||||||
| 
 | 
 | ||||||
| private: | 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_bytecode(Bytecode::Generator&) const override; | ||||||
|     virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) 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; |     virtual void dump(int indent) const override; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  | @ -1101,7 +1057,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -1127,7 +1082,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -1156,7 +1110,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -1175,7 +1128,6 @@ public: | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual void dump(int indent) const override; |     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_bytecode(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  | @ -1198,7 +1150,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -1214,7 +1165,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -1230,7 +1180,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -1246,7 +1195,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -1265,7 +1213,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| }; | }; | ||||||
|  | @ -1282,7 +1229,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -1310,7 +1256,6 @@ public: | ||||||
| 
 | 
 | ||||||
|     DeprecatedFlyString const& string() const { return m_string; } |     DeprecatedFlyString const& string() const { return m_string; } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) const override; |     virtual void dump(int indent) const override; | ||||||
| 
 | 
 | ||||||
|     virtual bool is_private_identifier() const override { return true; } |     virtual bool is_private_identifier() const override { return true; } | ||||||
|  | @ -1327,8 +1272,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
| 
 |  | ||||||
|     enum class ElementKind { |     enum class ElementKind { | ||||||
|         Method, |         Method, | ||||||
|         Field, |         Field, | ||||||
|  | @ -1431,7 +1374,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -1455,7 +1397,6 @@ public: | ||||||
|     DeprecatedString const& source_text() const { return m_source_text; } |     DeprecatedString const& source_text() const { return m_source_text; } | ||||||
|     RefPtr<FunctionExpression const> constructor() const { return m_constructor; } |     RefPtr<FunctionExpression const> constructor() const { return m_constructor; } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
|     virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode_with_lhs_name(Bytecode::Generator&, Optional<Bytecode::IdentifierTableIndex> lhs_name) const; |     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 void dump(int indent) const override; | ||||||
|     virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) 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 void dump(int) const override; | ||||||
|     virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) 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 void dump(int indent) const override; | ||||||
|     virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; |     virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -1545,7 +1483,6 @@ public: | ||||||
|         : Expression(source_range) |         : Expression(source_range) | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(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); |     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 void dump(int indent) const override; | ||||||
|     virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) 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: | protected: | ||||||
|     virtual bool is_call_expression() const override { return true; } |     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; |     Optional<DeprecatedString> expression_string() const; | ||||||
| 
 | 
 | ||||||
|     NonnullRefPtr<Expression const> m_callee; |     NonnullRefPtr<Expression const> m_callee; | ||||||
|  | @ -1619,8 +1547,6 @@ class NewExpression final : public CallExpression { | ||||||
| public: | public: | ||||||
|     static NonnullRefPtr<NewExpression> create(SourceRange, NonnullRefPtr<Expression const> callee, ReadonlySpan<Argument> arguments, InvocationStyleEnum invocation_style, InsideParenthesesEnum inside_parens); |     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; } |     virtual bool is_new_expression() const override { return true; } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  | @ -1656,7 +1582,6 @@ public: | ||||||
|         VERIFY(is_part_of_synthetic_constructor == IsPartOfSyntheticConstructor::Yes); |         VERIFY(is_part_of_synthetic_constructor == IsPartOfSyntheticConstructor::Yes); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -1702,7 +1627,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -1727,7 +1651,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -1770,7 +1693,6 @@ public: | ||||||
|     auto& target() const { return m_target; } |     auto& target() const { return m_target; } | ||||||
|     Expression const* init() const { return m_init; } |     Expression const* init() const { return m_init; } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) const override; |     virtual void dump(int indent) const override; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  | @ -1789,7 +1711,6 @@ public: | ||||||
| 
 | 
 | ||||||
|     DeclarationKind declaration_kind() const { return m_declaration_kind; } |     DeclarationKind declaration_kind() const { return m_declaration_kind; } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -1816,7 +1737,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) const override; |     virtual void dump(int indent) const override; | ||||||
| 
 | 
 | ||||||
|     ThrowCompletionOr<void> for_each_bound_identifier(ThrowCompletionOrVoidCallback<Identifier const&>&&) 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; } |     bool is_method() const { return m_is_method; } | ||||||
| 
 | 
 | ||||||
|     virtual void dump(int indent) const override; |     virtual void dump(int indent) const override; | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     Type m_property_type; |     Type m_property_type; | ||||||
|  | @ -1878,7 +1797,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -1898,7 +1816,6 @@ public: | ||||||
| 
 | 
 | ||||||
|     Vector<RefPtr<Expression const>> const& elements() const { return m_elements; } |     Vector<RefPtr<Expression const>> const& elements() const { return m_elements; } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -1923,7 +1840,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -1944,12 +1860,9 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|     ThrowCompletionOr<Value> get_template_object(Interpreter&) const; |  | ||||||
| 
 |  | ||||||
| private: | private: | ||||||
|     NonnullRefPtr<Expression const> const m_tag; |     NonnullRefPtr<Expression const> const m_tag; | ||||||
|     NonnullRefPtr<TemplateLiteral const> const m_template_literal; |     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 void dump(int indent) const override; | ||||||
|     virtual ThrowCompletionOr<Reference> to_reference(Interpreter&) const override; |  | ||||||
|     virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; |     virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|     bool is_computed() const { return m_computed; } |     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 void dump(int indent) const override; | ||||||
|     virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) 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; } |     Vector<Reference> const& references() const { return m_references; } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     struct ReferenceAndValue { |  | ||||||
|         JS::Reference reference; |  | ||||||
|         Value value; |  | ||||||
|     }; |  | ||||||
|     ThrowCompletionOr<ReferenceAndValue> to_reference_and_value(Interpreter&) const; |  | ||||||
| 
 |  | ||||||
|     NonnullRefPtr<Expression const> m_base; |     NonnullRefPtr<Expression const> m_base; | ||||||
|     Vector<Reference> m_references; |     Vector<Reference> m_references; | ||||||
| }; | }; | ||||||
|  | @ -2052,7 +1955,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
|     virtual void dump(int indent) 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(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|  | @ -2070,7 +1972,6 @@ public: | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual void dump(int indent) const override; |     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_bytecode(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  | @ -2091,7 +1992,6 @@ public: | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual void dump(int indent) const override; |     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_bytecode(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  | @ -2120,7 +2020,6 @@ public: | ||||||
|     BlockStatement const& body() const { return m_body; } |     BlockStatement const& body() const { return m_body; } | ||||||
| 
 | 
 | ||||||
|     virtual void dump(int indent) const override; |     virtual void dump(int indent) const override; | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     Variant<DeprecatedFlyString, NonnullRefPtr<BindingPattern const>> m_parameter; |     Variant<DeprecatedFlyString, NonnullRefPtr<BindingPattern const>> m_parameter; | ||||||
|  | @ -2142,7 +2041,6 @@ public: | ||||||
|     BlockStatement const* finalizer() const { return m_finalizer; } |     BlockStatement const* finalizer() const { return m_finalizer; } | ||||||
| 
 | 
 | ||||||
|     virtual void dump(int indent) const override; |     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_bytecode(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  | @ -2162,7 +2060,6 @@ public: | ||||||
|     Expression const& argument() const { return m_argument; } |     Expression const& argument() const { return m_argument; } | ||||||
| 
 | 
 | ||||||
|     virtual void dump(int indent) const override; |     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_bytecode(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  | @ -2180,7 +2077,6 @@ public: | ||||||
|     Expression const* test() const { return m_test; } |     Expression const* test() const { return m_test; } | ||||||
| 
 | 
 | ||||||
|     virtual void dump(int indent) const override; |     virtual void dump(int indent) const override; | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     RefPtr<Expression const> m_test; |     RefPtr<Expression const> m_test; | ||||||
|  | @ -2195,11 +2091,9 @@ public: | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual void dump(int indent) const override; |     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_bytecode(Bytecode::Generator&) const override; | ||||||
|     virtual Bytecode::CodeGenerationErrorOr<void> generate_labelled_evaluation(Bytecode::Generator&, Vector<DeprecatedFlyString> const&) const; |     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)); } |     void add_case(NonnullRefPtr<SwitchCase const> switch_case) { m_cases.append(move(switch_case)); } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  | @ -2215,8 +2109,6 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual Completion execute(Interpreter&) const override; |  | ||||||
| 
 |  | ||||||
|     DeprecatedFlyString const& target_label() const { return m_target_label; } |     DeprecatedFlyString const& target_label() const { return m_target_label; } | ||||||
|     virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; |     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; |     virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; | ||||||
| 
 | 
 | ||||||
|     DeprecatedFlyString const& target_label() const { return m_target_label; } |     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; |     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: | private: | ||||||
|     Reference m_reference; |     Reference m_reference; | ||||||
|     Value m_value; |     Value m_value; | ||||||
|  |  | ||||||
|  | @ -12,7 +12,6 @@ | ||||||
| #include <LibJS/Bytecode/Instruction.h> | #include <LibJS/Bytecode/Instruction.h> | ||||||
| #include <LibJS/Bytecode/Interpreter.h> | #include <LibJS/Bytecode/Interpreter.h> | ||||||
| #include <LibJS/Bytecode/Op.h> | #include <LibJS/Bytecode/Op.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Runtime/GlobalEnvironment.h> | #include <LibJS/Runtime/GlobalEnvironment.h> | ||||||
| #include <LibJS/Runtime/GlobalObject.h> | #include <LibJS/Runtime/GlobalObject.h> | ||||||
| #include <LibJS/Runtime/Realm.h> | #include <LibJS/Runtime/Realm.h> | ||||||
|  |  | ||||||
|  | @ -24,7 +24,6 @@ set(SOURCES | ||||||
|     Heap/Heap.cpp |     Heap/Heap.cpp | ||||||
|     Heap/HeapBlock.cpp |     Heap/HeapBlock.cpp | ||||||
|     Heap/MarkedVector.cpp |     Heap/MarkedVector.cpp | ||||||
|     Interpreter.cpp |  | ||||||
|     Lexer.cpp |     Lexer.cpp | ||||||
|     MarkupGenerator.cpp |     MarkupGenerator.cpp | ||||||
|     Module.cpp |     Module.cpp | ||||||
|  |  | ||||||
|  | @ -14,7 +14,6 @@ | ||||||
| #include <LibJS/Contrib/Test262/GlobalObject.h> | #include <LibJS/Contrib/Test262/GlobalObject.h> | ||||||
| #include <LibJS/Contrib/Test262/IsHTMLDDA.h> | #include <LibJS/Contrib/Test262/IsHTMLDDA.h> | ||||||
| #include <LibJS/Heap/Cell.h> | #include <LibJS/Heap/Cell.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Runtime/ArrayBuffer.h> | #include <LibJS/Runtime/ArrayBuffer.h> | ||||||
| #include <LibJS/Runtime/GlobalObject.h> | #include <LibJS/Runtime/GlobalObject.h> | ||||||
| #include <LibJS/Runtime/Object.h> | #include <LibJS/Runtime/Object.h> | ||||||
|  | @ -103,12 +102,7 @@ JS_DEFINE_NATIVE_FUNCTION($262Object::eval_script) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // 5. Let status be ScriptEvaluation(s).
 |     // 5. Let status be ScriptEvaluation(s).
 | ||||||
|     auto status = [&] { |     auto status = vm.bytecode_interpreter().run(script_or_error.value()); | ||||||
|         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()); |  | ||||||
|     }(); |  | ||||||
| 
 | 
 | ||||||
|     // 6. Return Completion(status).
 |     // 6. Return Completion(status).
 | ||||||
|     return status; |     return status; | ||||||
|  |  | ||||||
|  | @ -183,7 +183,6 @@ class Heap; | ||||||
| class HeapBlock; | class HeapBlock; | ||||||
| struct ImportEntry; | struct ImportEntry; | ||||||
| class ImportStatement; | class ImportStatement; | ||||||
| class Interpreter; |  | ||||||
| class Identifier; | class Identifier; | ||||||
| class Intrinsics; | class Intrinsics; | ||||||
| struct IteratorRecord; | struct IteratorRecord; | ||||||
|  |  | ||||||
|  | @ -15,7 +15,6 @@ | ||||||
| #include <LibJS/Heap/Handle.h> | #include <LibJS/Heap/Handle.h> | ||||||
| #include <LibJS/Heap/Heap.h> | #include <LibJS/Heap/Heap.h> | ||||||
| #include <LibJS/Heap/HeapBlock.h> | #include <LibJS/Heap/HeapBlock.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Runtime/Object.h> | #include <LibJS/Runtime/Object.h> | ||||||
| #include <LibJS/Runtime/WeakContainer.h> | #include <LibJS/Runtime/WeakContainer.h> | ||||||
| #include <LibJS/SafeFunction.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) 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 |  * SPDX-License-Identifier: BSD-2-Clause | ||||||
|  */ |  */ | ||||||
|  | @ -11,7 +11,6 @@ | ||||||
| #include <AK/Optional.h> | #include <AK/Optional.h> | ||||||
| #include <AK/Utf16View.h> | #include <AK/Utf16View.h> | ||||||
| #include <LibJS/Bytecode/Interpreter.h> | #include <LibJS/Bytecode/Interpreter.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Parser.h> | #include <LibJS/Parser.h> | ||||||
| #include <LibJS/Runtime/AbstractOperations.h> | #include <LibJS/Runtime/AbstractOperations.h> | ||||||
| #include <LibJS/Runtime/Accessor.h> | #include <LibJS/Runtime/Accessor.h> | ||||||
|  | @ -24,6 +23,7 @@ | ||||||
| #include <LibJS/Runtime/ErrorTypes.h> | #include <LibJS/Runtime/ErrorTypes.h> | ||||||
| #include <LibJS/Runtime/FunctionEnvironment.h> | #include <LibJS/Runtime/FunctionEnvironment.h> | ||||||
| #include <LibJS/Runtime/FunctionObject.h> | #include <LibJS/Runtime/FunctionObject.h> | ||||||
|  | #include <LibJS/Runtime/GlobalEnvironment.h> | ||||||
| #include <LibJS/Runtime/GlobalObject.h> | #include <LibJS/Runtime/GlobalObject.h> | ||||||
| #include <LibJS/Runtime/Object.h> | #include <LibJS/Runtime/Object.h> | ||||||
| #include <LibJS/Runtime/ObjectEnvironment.h> | #include <LibJS/Runtime/ObjectEnvironment.h> | ||||||
|  | @ -700,7 +700,6 @@ ThrowCompletionOr<Value> perform_eval(VM& vm, Value x, CallerMode strict_caller, | ||||||
| 
 | 
 | ||||||
|     // 29. If result.[[Type]] is normal, then
 |     // 29. If result.[[Type]] is normal, then
 | ||||||
|     //     a. Set result to the result of evaluating body.
 |     //     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); |     auto executable_result = Bytecode::Generator::generate(program); | ||||||
|     if (executable_result.is_error()) |     if (executable_result.is_error()) | ||||||
|         return vm.throw_completion<InternalError>(ErrorType::NotImplemented, TRY_OR_THROW_OOM(vm, executable_result.error().to_string())); |         return vm.throw_completion<InternalError>(ErrorType::NotImplemented, TRY_OR_THROW_OOM(vm, executable_result.error().to_string())); | ||||||
|  | @ -709,17 +708,13 @@ ThrowCompletionOr<Value> perform_eval(VM& vm, Value x, CallerMode strict_caller, | ||||||
|     executable->name = "eval"sv; |     executable->name = "eval"sv; | ||||||
|     if (Bytecode::g_dump_bytecode) |     if (Bytecode::g_dump_bytecode) | ||||||
|         executable->dump(); |         executable->dump(); | ||||||
|         auto result_or_error = bytecode_interpreter->run_and_return_frame(eval_realm, *executable, nullptr); |     auto result_or_error = vm.bytecode_interpreter().run_and_return_frame(eval_realm, *executable, nullptr); | ||||||
|     if (result_or_error.value.is_error()) |     if (result_or_error.value.is_error()) | ||||||
|         return result_or_error.value.release_error(); |         return result_or_error.value.release_error(); | ||||||
| 
 | 
 | ||||||
|     auto& result = result_or_error.frame->registers[0]; |     auto& result = result_or_error.frame->registers[0]; | ||||||
|     if (!result.is_empty()) |     if (!result.is_empty()) | ||||||
|         eval_result = result; |         eval_result = result; | ||||||
|     } else { |  | ||||||
|         auto& ast_interpreter = vm.interpreter(); |  | ||||||
|         eval_result = TRY(program->execute(ast_interpreter)); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     // 30. If result.[[Type]] is normal and result.[[Value]] is empty, then
 |     // 30. If result.[[Type]] is normal and result.[[Value]] is empty, then
 | ||||||
|     //     a. Set result to NormalCompletion(undefined).
 |     //     a. Set result to NormalCompletion(undefined).
 | ||||||
|  |  | ||||||
|  | @ -4,7 +4,6 @@ | ||||||
|  * SPDX-License-Identifier: BSD-2-Clause |  * SPDX-License-Identifier: BSD-2-Clause | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Runtime/AbstractOperations.h> | #include <LibJS/Runtime/AbstractOperations.h> | ||||||
| #include <LibJS/Runtime/DeclarativeEnvironment.h> | #include <LibJS/Runtime/DeclarativeEnvironment.h> | ||||||
| #include <LibJS/Runtime/Error.h> | #include <LibJS/Runtime/Error.h> | ||||||
|  |  | ||||||
|  | @ -13,7 +13,6 @@ | ||||||
| #include <LibJS/Bytecode/BasicBlock.h> | #include <LibJS/Bytecode/BasicBlock.h> | ||||||
| #include <LibJS/Bytecode/Generator.h> | #include <LibJS/Bytecode/Generator.h> | ||||||
| #include <LibJS/Bytecode/Interpreter.h> | #include <LibJS/Bytecode/Interpreter.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Runtime/AbstractOperations.h> | #include <LibJS/Runtime/AbstractOperations.h> | ||||||
| #include <LibJS/Runtime/Array.h> | #include <LibJS/Runtime/Array.h> | ||||||
| #include <LibJS/Runtime/AsyncFunctionDriverWrapper.h> | #include <LibJS/Runtime/AsyncFunctionDriverWrapper.h> | ||||||
|  | @ -23,6 +22,7 @@ | ||||||
| #include <LibJS/Runtime/ExecutionContext.h> | #include <LibJS/Runtime/ExecutionContext.h> | ||||||
| #include <LibJS/Runtime/FunctionEnvironment.h> | #include <LibJS/Runtime/FunctionEnvironment.h> | ||||||
| #include <LibJS/Runtime/GeneratorObject.h> | #include <LibJS/Runtime/GeneratorObject.h> | ||||||
|  | #include <LibJS/Runtime/GlobalEnvironment.h> | ||||||
| #include <LibJS/Runtime/GlobalObject.h> | #include <LibJS/Runtime/GlobalObject.h> | ||||||
| #include <LibJS/Runtime/NativeFunction.h> | #include <LibJS/Runtime/NativeFunction.h> | ||||||
| #include <LibJS/Runtime/PromiseCapability.h> | #include <LibJS/Runtime/PromiseCapability.h> | ||||||
|  | @ -152,8 +152,6 @@ ThrowCompletionOr<Value> ECMAScriptFunctionObject::internal_call(Value this_argu | ||||||
| 
 | 
 | ||||||
|     // Non-standard
 |     // Non-standard
 | ||||||
|     callee_context.arguments.extend(move(arguments_list)); |     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).
 |     // 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.
 |     // 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
 |     // Non-standard
 | ||||||
|     callee_context.arguments.extend(move(arguments_list)); |     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).
 |     // 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.
 |     // 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
 | // 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& vm = this->vm(); | ||||||
|     auto& realm = *vm.current_realm(); |     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()) { |                 } else if (i < execution_context_arguments.size() && !execution_context_arguments[i].is_undefined()) { | ||||||
|                     argument_value = execution_context_arguments[i]; |                     argument_value = execution_context_arguments[i]; | ||||||
|                 } else if (parameter.default_value) { |                 } else if (parameter.default_value) { | ||||||
|                     auto* bytecode_interpreter = vm.bytecode_interpreter_if_exists(); |                     auto value_and_frame = vm.bytecode_interpreter().run_and_return_frame(realm, *m_default_parameter_bytecode_executables[default_parameter_index - 1], nullptr); | ||||||
|                     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()) |                     if (value_and_frame.value.is_error()) | ||||||
|                         return value_and_frame.value.release_error(); |                         return value_and_frame.value.release_error(); | ||||||
|                     // Resulting value is in the accumulator.
 |                     // Resulting value is in the accumulator.
 | ||||||
|                     argument_value = value_and_frame.frame->registers.at(0); |                     argument_value = value_and_frame.frame->registers.at(0); | ||||||
|                     } else if (interpreter) { |  | ||||||
|                         argument_value = TRY(parameter.default_value->execute(*interpreter)).release_value(); |  | ||||||
|                     } |  | ||||||
|                 } else { |                 } else { | ||||||
|                     argument_value = js_undefined(); |                     argument_value = js_undefined(); | ||||||
|                 } |                 } | ||||||
|  | @ -579,19 +568,16 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia | ||||||
|                 Environment* used_environment = has_duplicates ? nullptr : environment; |                 Environment* used_environment = has_duplicates ? nullptr : environment; | ||||||
| 
 | 
 | ||||||
|                 if constexpr (IsSame<NonnullRefPtr<Identifier const> const&, decltype(param)>) { |                 if constexpr (IsSame<NonnullRefPtr<Identifier const> const&, decltype(param)>) { | ||||||
|                     if ((vm.bytecode_interpreter_if_exists() || kind() == FunctionKind::Generator || kind() == FunctionKind::AsyncGenerator) && param->is_local()) { |                     if (param->is_local()) { | ||||||
|                         // NOTE: Local variables are supported only in bytecode interpreter
 |  | ||||||
|                         callee_context.local_variables[param->local_variable_index()] = argument_value; |                         callee_context.local_variables[param->local_variable_index()] = argument_value; | ||||||
|                         return {}; |                         return {}; | ||||||
|                     } else { |                     } | ||||||
|                     Reference reference = TRY(vm.resolve_binding(param->string(), used_environment)); |                     Reference reference = TRY(vm.resolve_binding(param->string(), used_environment)); | ||||||
|                     // Here the difference from hasDuplicates is important
 |                     // Here the difference from hasDuplicates is important
 | ||||||
|                     if (has_duplicates) |                     if (has_duplicates) | ||||||
|                         return reference.put_value(vm, argument_value); |                         return reference.put_value(vm, argument_value); | ||||||
|                         else |  | ||||||
|                     return reference.initialize_referenced_binding(vm, argument_value); |                     return reference.initialize_referenced_binding(vm, argument_value); | ||||||
|                 } |                 } | ||||||
|                 } |  | ||||||
|                 if constexpr (IsSame<NonnullRefPtr<BindingPattern const> const&, decltype(param)>) { |                 if constexpr (IsSame<NonnullRefPtr<BindingPattern const> const&, decltype(param)>) { | ||||||
|                     // Here the difference from hasDuplicates is important
 |                     // Here the difference from hasDuplicates is important
 | ||||||
|                     return vm.binding_initialization(param, argument_value, used_environment); |                     return vm.binding_initialization(param, argument_value, used_environment); | ||||||
|  | @ -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
 |         // a. If asyncBody is a Parse Node, then
 | ||||||
|         if constexpr (!IsCallableWithArguments<T, Completion>) { |         if constexpr (!IsCallableWithArguments<T, Completion>) { | ||||||
|             // a. Let result be the result of evaluating asyncBody.
 |             // a. Let result be the result of evaluating asyncBody.
 | ||||||
|             if (auto* bytecode_interpreter = vm.bytecode_interpreter_if_exists()) { |  | ||||||
|             // FIXME: Cache this executable somewhere.
 |             // FIXME: Cache this executable somewhere.
 | ||||||
|             auto maybe_executable = Bytecode::compile(vm, async_body, FunctionKind::Async, "AsyncBlockStart"sv); |             auto maybe_executable = Bytecode::compile(vm, async_body, FunctionKind::Async, "AsyncBlockStart"sv); | ||||||
|             if (maybe_executable.is_error()) |             if (maybe_executable.is_error()) | ||||||
|                 result = maybe_executable.release_error(); |                 result = maybe_executable.release_error(); | ||||||
|             else |             else | ||||||
|                     result = bytecode_interpreter->run_and_return_frame(realm, *maybe_executable.value(), nullptr).value; |                 result = vm.bytecode_interpreter().run_and_return_frame(realm, *maybe_executable.value(), nullptr).value; | ||||||
|             } else { |  | ||||||
|                 result = async_body->execute(vm.interpreter()); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|         // b. Else,
 |         // b. Else,
 | ||||||
|         else { |         else { | ||||||
|  | @ -1035,8 +1017,8 @@ void async_block_start(VM& vm, T const& async_body, PromiseCapability const& pro | ||||||
|     // 8. Return unused.
 |     // 8. Return unused.
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template void async_block_start(VM&, NonnullGCPtr<Statement const> const& async_body, PromiseCapability const&, ExecutionContext&); | template void async_block_start(VM&, NonnullRefPtr<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_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_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); | template void async_function_start(VM&, PromiseCapability const&, SafeFunction<Completion()> const& async_function_body); | ||||||
|  | @ -1048,20 +1030,6 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body() | ||||||
|     auto& vm = this->vm(); |     auto& vm = this->vm(); | ||||||
|     auto& realm = *vm.current_realm(); |     auto& realm = *vm.current_realm(); | ||||||
| 
 | 
 | ||||||
|     auto* bytecode_interpreter = vm.bytecode_interpreter_if_exists(); |  | ||||||
| 
 |  | ||||||
|     // 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 (bytecode_interpreter) { |  | ||||||
|     // NOTE: There's a subtle ordering issue here:
 |     // NOTE: There's a subtle ordering issue here:
 | ||||||
|     //       - We have to compile the default parameter values before instantiating the function.
 |     //       - We have to compile the default parameter values before instantiating the function.
 | ||||||
|     //       - We have to instantiate the function before compiling the function body.
 |     //       - We have to instantiate the function before compiling the function body.
 | ||||||
|  | @ -1079,7 +1047,7 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body() | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|         auto declaration_result = function_declaration_instantiation(nullptr); |     auto declaration_result = function_declaration_instantiation(); | ||||||
| 
 | 
 | ||||||
|     if (m_kind == FunctionKind::Normal || m_kind == FunctionKind::Generator || m_kind == FunctionKind::AsyncGenerator) { |     if (m_kind == FunctionKind::Normal || m_kind == FunctionKind::Generator || m_kind == FunctionKind::AsyncGenerator) { | ||||||
|         if (declaration_result.is_error()) |         if (declaration_result.is_error()) | ||||||
|  | @ -1097,7 +1065,7 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body() | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|         auto result_and_frame = bytecode_interpreter->run_and_return_frame(realm, *m_bytecode_executable, nullptr); |     auto result_and_frame = vm.bytecode_interpreter().run_and_return_frame(realm, *m_bytecode_executable, nullptr); | ||||||
| 
 | 
 | ||||||
|     VERIFY(result_and_frame.frame != nullptr); |     VERIFY(result_and_frame.frame != nullptr); | ||||||
|     if (result_and_frame.value.is_error()) |     if (result_and_frame.value.is_error()) | ||||||
|  | @ -1124,60 +1092,6 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body() | ||||||
| 
 | 
 | ||||||
|     VERIFY(m_kind == FunctionKind::Generator); |     VERIFY(m_kind == FunctionKind::Generator); | ||||||
|     return { Completion::Type::Return, generator_object, {} }; |     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%).
 |  | ||||||
|             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 }.
 |  | ||||||
|             return Completion { Completion::Type::Return, promise_capability->promise(), {} }; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     VERIFY_NOT_REACHED(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ECMAScriptFunctionObject::set_name(DeprecatedFlyString const& name) | void ECMAScriptFunctionObject::set_name(DeprecatedFlyString const& name) | ||||||
|  | @ -1187,5 +1101,4 @@ void ECMAScriptFunctionObject::set_name(DeprecatedFlyString const& name) | ||||||
|     m_name = name; |     m_name = name; | ||||||
|     MUST(define_property_or_throw(vm.names.name, { .value = PrimitiveString::create(vm, m_name), .writable = false, .enumerable = false, .configurable = true })); |     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); |     ThrowCompletionOr<void> prepare_for_ordinary_call(ExecutionContext& callee_context, Object* new_target); | ||||||
|     void ordinary_call_bind_this(ExecutionContext&, Value this_argument); |     void ordinary_call_bind_this(ExecutionContext&, Value this_argument); | ||||||
| 
 | 
 | ||||||
|     ThrowCompletionOr<void> function_declaration_instantiation(Interpreter*); |     ThrowCompletionOr<void> function_declaration_instantiation(); | ||||||
| 
 | 
 | ||||||
|     DeprecatedFlyString m_name; |     DeprecatedFlyString m_name; | ||||||
|     OwnPtr<Bytecode::Executable> m_bytecode_executable; |     OwnPtr<Bytecode::Executable> m_bytecode_executable; | ||||||
|  |  | ||||||
|  | @ -4,7 +4,6 @@ | ||||||
|  * SPDX-License-Identifier: BSD-2-Clause |  * SPDX-License-Identifier: BSD-2-Clause | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Runtime/Completion.h> | #include <LibJS/Runtime/Completion.h> | ||||||
| #include <LibJS/Runtime/ECMAScriptFunctionObject.h> | #include <LibJS/Runtime/ECMAScriptFunctionObject.h> | ||||||
| #include <LibJS/Runtime/FunctionEnvironment.h> | #include <LibJS/Runtime/FunctionEnvironment.h> | ||||||
|  |  | ||||||
|  | @ -6,10 +6,10 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include <AK/TypeCasts.h> | #include <AK/TypeCasts.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Runtime/Completion.h> | #include <LibJS/Runtime/Completion.h> | ||||||
| #include <LibJS/Runtime/FunctionObject.h> | #include <LibJS/Runtime/FunctionObject.h> | ||||||
| #include <LibJS/Runtime/NativeFunction.h> | #include <LibJS/Runtime/NativeFunction.h> | ||||||
|  | #include <LibJS/Runtime/VM.h> | ||||||
| 
 | 
 | ||||||
| namespace JS { | namespace JS { | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -8,7 +8,6 @@ | ||||||
| #include <AK/StringBuilder.h> | #include <AK/StringBuilder.h> | ||||||
| #include <AK/TypeCasts.h> | #include <AK/TypeCasts.h> | ||||||
| #include <LibJS/Heap/MarkedVector.h> | #include <LibJS/Heap/MarkedVector.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Runtime/AbstractOperations.h> | #include <LibJS/Runtime/AbstractOperations.h> | ||||||
| #include <LibJS/Runtime/BoundFunction.h> | #include <LibJS/Runtime/BoundFunction.h> | ||||||
| #include <LibJS/Runtime/ECMAScriptFunctionObject.h> | #include <LibJS/Runtime/ECMAScriptFunctionObject.h> | ||||||
|  |  | ||||||
|  | @ -13,7 +13,6 @@ | ||||||
| #include <AK/Utf16View.h> | #include <AK/Utf16View.h> | ||||||
| #include <AK/Utf8View.h> | #include <AK/Utf8View.h> | ||||||
| #include <LibJS/Heap/DeferGC.h> | #include <LibJS/Heap/DeferGC.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Runtime/AbstractOperations.h> | #include <LibJS/Runtime/AbstractOperations.h> | ||||||
| #include <LibJS/Runtime/AggregateErrorConstructor.h> | #include <LibJS/Runtime/AggregateErrorConstructor.h> | ||||||
| #include <LibJS/Runtime/ArrayBufferConstructor.h> | #include <LibJS/Runtime/ArrayBufferConstructor.h> | ||||||
|  |  | ||||||
|  | @ -6,7 +6,6 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include <LibJS/AST.h> | #include <LibJS/AST.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Runtime/FunctionEnvironment.h> | #include <LibJS/Runtime/FunctionEnvironment.h> | ||||||
| #include <LibJS/Runtime/GlobalObject.h> | #include <LibJS/Runtime/GlobalObject.h> | ||||||
| #include <LibJS/Runtime/NativeFunction.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.
 |     // 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(); |     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.> --------------------------------------------------------------------------
 |     // </8.> --------------------------------------------------------------------------
 | ||||||
| 
 | 
 | ||||||
|     // 9. Push calleeContext onto the execution context stack; calleeContext is now the running execution context.
 |     // 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.
 |     // 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(); |     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.> --------------------------------------------------------------------------
 |     // </8.> --------------------------------------------------------------------------
 | ||||||
| 
 | 
 | ||||||
|     // 9. Push calleeContext onto the execution context stack; calleeContext is now the running execution context.
 |     // 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/DeprecatedString.h> | ||||||
| #include <AK/TypeCasts.h> | #include <AK/TypeCasts.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Runtime/AbstractOperations.h> | #include <LibJS/Runtime/AbstractOperations.h> | ||||||
| #include <LibJS/Runtime/Accessor.h> | #include <LibJS/Runtime/Accessor.h> | ||||||
| #include <LibJS/Runtime/Array.h> | #include <LibJS/Runtime/Array.h> | ||||||
|  |  | ||||||
|  | @ -5,7 +5,6 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include <AK/Function.h> | #include <AK/Function.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Runtime/AbstractOperations.h> | #include <LibJS/Runtime/AbstractOperations.h> | ||||||
| #include <LibJS/Runtime/AggregateError.h> | #include <LibJS/Runtime/AggregateError.h> | ||||||
| #include <LibJS/Runtime/Array.h> | #include <LibJS/Runtime/Array.h> | ||||||
|  |  | ||||||
|  | @ -5,7 +5,6 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include <AK/Function.h> | #include <AK/Function.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Runtime/AbstractOperations.h> | #include <LibJS/Runtime/AbstractOperations.h> | ||||||
| #include <LibJS/Runtime/Error.h> | #include <LibJS/Runtime/Error.h> | ||||||
| #include <LibJS/Runtime/GlobalObject.h> | #include <LibJS/Runtime/GlobalObject.h> | ||||||
|  |  | ||||||
|  | @ -6,7 +6,6 @@ | ||||||
| 
 | 
 | ||||||
| #include <LibJS/Bytecode/Executable.h> | #include <LibJS/Bytecode/Executable.h> | ||||||
| #include <LibJS/Bytecode/Interpreter.h> | #include <LibJS/Bytecode/Interpreter.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Lexer.h> | #include <LibJS/Lexer.h> | ||||||
| #include <LibJS/Parser.h> | #include <LibJS/Parser.h> | ||||||
| #include <LibJS/Runtime/AbstractOperations.h> | #include <LibJS/Runtime/AbstractOperations.h> | ||||||
|  | @ -173,14 +172,13 @@ ThrowCompletionOr<Value> perform_shadow_realm_eval(VM& vm, StringView source_tex | ||||||
|     // 17. If result.[[Type]] is normal, then
 |     // 17. If result.[[Type]] is normal, then
 | ||||||
|     if (!eval_result.is_throw_completion()) { |     if (!eval_result.is_throw_completion()) { | ||||||
|         // a. Set result to the result of evaluating body.
 |         // 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); |         auto maybe_executable = Bytecode::compile(vm, program, FunctionKind::Normal, "ShadowRealmEval"sv); | ||||||
|         if (maybe_executable.is_error()) |         if (maybe_executable.is_error()) | ||||||
|             result = maybe_executable.release_error(); |             result = maybe_executable.release_error(); | ||||||
|         else { |         else { | ||||||
|             auto executable = maybe_executable.release_value(); |             auto executable = maybe_executable.release_value(); | ||||||
| 
 | 
 | ||||||
|                 auto value_and_frame = bytecode_interpreter->run_and_return_frame(eval_realm, *executable, nullptr); |             auto value_and_frame = vm.bytecode_interpreter().run_and_return_frame(eval_realm, *executable, nullptr); | ||||||
|             if (value_and_frame.value.is_error()) { |             if (value_and_frame.value.is_error()) { | ||||||
|                 result = value_and_frame.value.release_error(); |                 result = value_and_frame.value.release_error(); | ||||||
|             } else { |             } else { | ||||||
|  | @ -188,12 +186,6 @@ ThrowCompletionOr<Value> perform_shadow_realm_eval(VM& vm, StringView source_tex | ||||||
|                 result = value_and_frame.frame->registers.at(0).value_or(js_undefined()); |                 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); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // 18. If result.[[Type]] is normal and result.[[Value]] is empty, then
 |     // 18. If result.[[Type]] is normal and result.[[Value]] is empty, then
 | ||||||
|  |  | ||||||
|  | @ -15,7 +15,6 @@ | ||||||
| #include <LibFileSystem/FileSystem.h> | #include <LibFileSystem/FileSystem.h> | ||||||
| #include <LibJS/AST.h> | #include <LibJS/AST.h> | ||||||
| #include <LibJS/Bytecode/Interpreter.h> | #include <LibJS/Bytecode/Interpreter.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Runtime/AbstractOperations.h> | #include <LibJS/Runtime/AbstractOperations.h> | ||||||
| #include <LibJS/Runtime/Array.h> | #include <LibJS/Runtime/Array.h> | ||||||
| #include <LibJS/Runtime/BoundFunction.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() | Bytecode::Interpreter& VM::bytecode_interpreter() | ||||||
| { | { | ||||||
|     return *m_bytecode_interpreter; |     return *m_bytecode_interpreter; | ||||||
|  | @ -211,29 +197,6 @@ Bytecode::Interpreter* VM::bytecode_interpreter_if_exists() | ||||||
|     return m_bytecode_interpreter; |     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) | void VM::gather_roots(HashTable<Cell*>& roots) | ||||||
| { | { | ||||||
|     roots.set(m_empty_string); |     roots.set(m_empty_string); | ||||||
|  | @ -356,17 +319,13 @@ ThrowCompletionOr<void> VM::binding_initialization(NonnullRefPtr<BindingPattern | ||||||
| 
 | 
 | ||||||
| ThrowCompletionOr<Value> VM::execute_ast_node(ASTNode const& node) | 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 executable = TRY(Bytecode::compile(*this, node, FunctionKind::Normal, ""sv)); | ||||||
|         auto result_or_error = bytecode_interpreter->run_and_return_frame(*current_realm(), *executable, nullptr); |     auto result_or_error = bytecode_interpreter().run_and_return_frame(*current_realm(), *executable, nullptr); | ||||||
|     if (result_or_error.value.is_error()) |     if (result_or_error.value.is_error()) | ||||||
|         return result_or_error.value.release_error(); |         return result_or_error.value.release_error(); | ||||||
|     return result_or_error.frame->registers[0]; |     return result_or_error.frame->registers[0]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|     return TRY(node.execute(interpreter())).value(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // 13.15.5.3 Runtime Semantics: PropertyDestructuringAssignmentEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-propertydestructuringassignmentevaluation
 | // 13.15.5.3 Runtime Semantics: PropertyDestructuringAssignmentEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-propertydestructuringassignmentevaluation
 | ||||||
| // 14.3.3.1 Runtime Semantics: PropertyBindingInitialization, https://tc39.es/ecma262/#sec-destructuring-binding-patterns-runtime-semantics-propertybindinginitialization
 | // 14.3.3.1 Runtime Semantics: PropertyBindingInitialization, https://tc39.es/ecma262/#sec-destructuring-binding-patterns-runtime-semantics-propertybindinginitialization
 | ||||||
| ThrowCompletionOr<void> VM::property_binding_initialization(BindingPattern const& binding, Value value, Environment* environment) | ThrowCompletionOr<void> VM::property_binding_initialization(BindingPattern const& binding, Value value, Environment* environment) | ||||||
|  | @ -385,8 +344,6 @@ ThrowCompletionOr<void> VM::property_binding_initialization(BindingPattern const | ||||||
|             Reference assignment_target; |             Reference assignment_target; | ||||||
|             if (auto identifier_ptr = property.name.get_pointer<NonnullRefPtr<Identifier const>>()) { |             if (auto identifier_ptr = property.name.get_pointer<NonnullRefPtr<Identifier const>>()) { | ||||||
|                 assignment_target = TRY(resolve_binding((*identifier_ptr)->string(), environment)); |                 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 { |             } else { | ||||||
|                 VERIFY_NOT_REACHED(); |                 VERIFY_NOT_REACHED(); | ||||||
|             } |             } | ||||||
|  | @ -436,8 +393,8 @@ ThrowCompletionOr<void> VM::property_binding_initialization(BindingPattern const | ||||||
|                 return TRY(resolve_binding(identifier->string(), environment)); |                 return TRY(resolve_binding(identifier->string(), environment)); | ||||||
|             }, |             }, | ||||||
|             [&](NonnullRefPtr<BindingPattern const> const&) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; }, |             [&](NonnullRefPtr<BindingPattern const> const&) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; }, | ||||||
|             [&](NonnullRefPtr<MemberExpression const> const& member_expression) -> ThrowCompletionOr<Optional<Reference>> { |             [&](NonnullRefPtr<MemberExpression const> const&) -> ThrowCompletionOr<Optional<Reference>> { | ||||||
|                 return TRY(member_expression->to_reference(interpreter())); |                 VERIFY_NOT_REACHED(); | ||||||
|             })); |             })); | ||||||
| 
 | 
 | ||||||
|         auto value_to_assign = TRY(object->get(name)); |         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)); |                 return TRY(resolve_binding(identifier->string(), environment)); | ||||||
|             }, |             }, | ||||||
|             [&](NonnullRefPtr<BindingPattern const> const&) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; }, |             [&](NonnullRefPtr<BindingPattern const> const&) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; }, | ||||||
|             [&](NonnullRefPtr<MemberExpression const> const& member_expression) -> ThrowCompletionOr<Optional<Reference>> { |             [&](NonnullRefPtr<MemberExpression const> const&) -> ThrowCompletionOr<Optional<Reference>> { | ||||||
|                 return TRY(member_expression->to_reference(interpreter())); |                 VERIFY_NOT_REACHED(); | ||||||
|             })); |             })); | ||||||
| 
 | 
 | ||||||
|         // BindingRestElement : ... BindingIdentifier
 |         // BindingRestElement : ... BindingIdentifier
 | ||||||
|  | @ -861,11 +818,6 @@ VM::StoredModule* VM::get_stored_module(ScriptOrModule const&, DeprecatedString | ||||||
|     return &(*end_or_module); |     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) | ThrowCompletionOr<void> VM::link_and_eval_module(Badge<Bytecode::Interpreter>, SourceTextModule& module) | ||||||
| { | { | ||||||
|     return link_and_eval_module(module); |     return link_and_eval_module(module); | ||||||
|  |  | ||||||
|  | @ -46,25 +46,8 @@ public: | ||||||
|     Bytecode::Interpreter& bytecode_interpreter(); |     Bytecode::Interpreter& bytecode_interpreter(); | ||||||
|     Bytecode::Interpreter* bytecode_interpreter_if_exists(); |     Bytecode::Interpreter* bytecode_interpreter_if_exists(); | ||||||
| 
 | 
 | ||||||
|     Interpreter& interpreter(); |  | ||||||
|     Interpreter* interpreter_if_exists(); |  | ||||||
| 
 |  | ||||||
|     void push_interpreter(Interpreter&); |  | ||||||
|     void pop_interpreter(Interpreter&); |  | ||||||
| 
 |  | ||||||
|     void dump_backtrace() const; |     void dump_backtrace() const; | ||||||
| 
 | 
 | ||||||
|     class InterpreterExecutionScope { |  | ||||||
|     public: |  | ||||||
|         InterpreterExecutionScope(Interpreter&); |  | ||||||
|         ~InterpreterExecutionScope(); |  | ||||||
| 
 |  | ||||||
|         Interpreter& interpreter() { return m_interpreter; } |  | ||||||
| 
 |  | ||||||
|     private: |  | ||||||
|         Interpreter& m_interpreter; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     void gather_roots(HashTable<Cell*>&); |     void gather_roots(HashTable<Cell*>&); | ||||||
| 
 | 
 | ||||||
| #define __JS_ENUMERATE(SymbolName, snake_name)                  \ | #define __JS_ENUMERATE(SymbolName, snake_name)                  \ | ||||||
|  | @ -249,7 +232,6 @@ public: | ||||||
|     void restore_execution_context_stack(); |     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.
 |     // 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); |     ThrowCompletionOr<void> link_and_eval_module(Badge<Bytecode::Interpreter>, SourceTextModule& module); | ||||||
| 
 | 
 | ||||||
|     ScriptOrModule get_active_script_or_module() const; |     ScriptOrModule get_active_script_or_module() const; | ||||||
|  | @ -304,7 +286,6 @@ private: | ||||||
|     HashMap<DeprecatedString, GCPtr<PrimitiveString>> m_deprecated_string_cache; |     HashMap<DeprecatedString, GCPtr<PrimitiveString>> m_deprecated_string_cache; | ||||||
| 
 | 
 | ||||||
|     Heap m_heap; |     Heap m_heap; | ||||||
|     Vector<Interpreter*> m_interpreters; |  | ||||||
| 
 | 
 | ||||||
|     Vector<ExecutionContext*> m_execution_context_stack; |     Vector<ExecutionContext*> m_execution_context_stack; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -8,9 +8,9 @@ | ||||||
| #include <AK/Debug.h> | #include <AK/Debug.h> | ||||||
| #include <AK/QuickSort.h> | #include <AK/QuickSort.h> | ||||||
| #include <LibJS/Bytecode/Interpreter.h> | #include <LibJS/Bytecode/Interpreter.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Parser.h> | #include <LibJS/Parser.h> | ||||||
| #include <LibJS/Runtime/ECMAScriptFunctionObject.h> | #include <LibJS/Runtime/ECMAScriptFunctionObject.h> | ||||||
|  | #include <LibJS/Runtime/GlobalEnvironment.h> | ||||||
| #include <LibJS/Runtime/ModuleEnvironment.h> | #include <LibJS/Runtime/ModuleEnvironment.h> | ||||||
| #include <LibJS/SourceTextModule.h> | #include <LibJS/SourceTextModule.h> | ||||||
| 
 | 
 | ||||||
|  | @ -695,14 +695,13 @@ ThrowCompletionOr<void> SourceTextModule::execute_module(VM& vm, GCPtr<PromiseCa | ||||||
|         // c. Let result be the result of evaluating module.[[ECMAScriptCode]].
 |         // c. Let result be the result of evaluating module.[[ECMAScriptCode]].
 | ||||||
|         Completion result; |         Completion result; | ||||||
| 
 | 
 | ||||||
|         if (auto* bytecode_interpreter = vm.bytecode_interpreter_if_exists()) { |  | ||||||
|         auto maybe_executable = Bytecode::compile(vm, m_ecmascript_code, FunctionKind::Normal, "ShadowRealmEval"sv); |         auto maybe_executable = Bytecode::compile(vm, m_ecmascript_code, FunctionKind::Normal, "ShadowRealmEval"sv); | ||||||
|         if (maybe_executable.is_error()) |         if (maybe_executable.is_error()) | ||||||
|             result = maybe_executable.release_error(); |             result = maybe_executable.release_error(); | ||||||
|         else { |         else { | ||||||
|             auto executable = maybe_executable.release_value(); |             auto executable = maybe_executable.release_value(); | ||||||
| 
 | 
 | ||||||
|                 auto value_and_frame = bytecode_interpreter->run_and_return_frame(realm(), *executable, nullptr); |             auto value_and_frame = vm.bytecode_interpreter().run_and_return_frame(realm(), *executable, nullptr); | ||||||
|             if (value_and_frame.value.is_error()) { |             if (value_and_frame.value.is_error()) { | ||||||
|                 result = value_and_frame.value.release_error(); |                 result = value_and_frame.value.release_error(); | ||||||
|             } else { |             } else { | ||||||
|  | @ -710,9 +709,6 @@ ThrowCompletionOr<void> SourceTextModule::execute_module(VM& vm, GCPtr<PromiseCa | ||||||
|                 result = value_and_frame.frame->registers.at(0).value_or(js_undefined()); |                 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.
 |         // d. Let env be moduleContext's LexicalEnvironment.
 | ||||||
|         auto env = module_context.lexical_environment; |         auto env = module_context.lexical_environment; | ||||||
|  |  | ||||||
|  | @ -20,7 +20,6 @@ | ||||||
| #include <LibCore/DirIterator.h> | #include <LibCore/DirIterator.h> | ||||||
| #include <LibCore/File.h> | #include <LibCore/File.h> | ||||||
| #include <LibJS/Bytecode/Interpreter.h> | #include <LibJS/Bytecode/Interpreter.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Lexer.h> | #include <LibJS/Lexer.h> | ||||||
| #include <LibJS/Parser.h> | #include <LibJS/Parser.h> | ||||||
| #include <LibJS/Runtime/Array.h> | #include <LibJS/Runtime/Array.h> | ||||||
|  |  | ||||||
|  | @ -13,7 +13,6 @@ | ||||||
| #include <AK/StringBuilder.h> | #include <AK/StringBuilder.h> | ||||||
| #include <AK/Utf8View.h> | #include <AK/Utf8View.h> | ||||||
| #include <LibCore/Timer.h> | #include <LibCore/Timer.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Runtime/Array.h> | #include <LibJS/Runtime/Array.h> | ||||||
| #include <LibJS/Runtime/FunctionObject.h> | #include <LibJS/Runtime/FunctionObject.h> | ||||||
| #include <LibJS/Runtime/NativeFunction.h> | #include <LibJS/Runtime/NativeFunction.h> | ||||||
|  |  | ||||||
|  | @ -7,10 +7,10 @@ | ||||||
| 
 | 
 | ||||||
| #include <AK/StringBuilder.h> | #include <AK/StringBuilder.h> | ||||||
| #include <Kernel/API/KeyCode.h> | #include <Kernel/API/KeyCode.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Parser.h> | #include <LibJS/Parser.h> | ||||||
| #include <LibJS/Runtime/AbstractOperations.h> | #include <LibJS/Runtime/AbstractOperations.h> | ||||||
| #include <LibJS/Runtime/ECMAScriptFunctionObject.h> | #include <LibJS/Runtime/ECMAScriptFunctionObject.h> | ||||||
|  | #include <LibJS/Runtime/GlobalEnvironment.h> | ||||||
| #include <LibJS/Runtime/NativeFunction.h> | #include <LibJS/Runtime/NativeFunction.h> | ||||||
| #include <LibJS/Runtime/ObjectEnvironment.h> | #include <LibJS/Runtime/ObjectEnvironment.h> | ||||||
| #include <LibJS/Runtime/VM.h> | #include <LibJS/Runtime/VM.h> | ||||||
|  |  | ||||||
|  | @ -5,7 +5,6 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include <AK/StringBuilder.h> | #include <AK/StringBuilder.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibWeb/ARIA/Roles.h> | #include <LibWeb/ARIA/Roles.h> | ||||||
| #include <LibWeb/Bindings/ExceptionOrUtils.h> | #include <LibWeb/Bindings/ExceptionOrUtils.h> | ||||||
| #include <LibWeb/DOM/Document.h> | #include <LibWeb/DOM/Document.h> | ||||||
|  |  | ||||||
|  | @ -7,7 +7,6 @@ | ||||||
| #include <AK/Debug.h> | #include <AK/Debug.h> | ||||||
| #include <LibCore/ElapsedTimer.h> | #include <LibCore/ElapsedTimer.h> | ||||||
| #include <LibJS/Bytecode/Interpreter.h> | #include <LibJS/Bytecode/Interpreter.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibWeb/Bindings/ExceptionOrUtils.h> | #include <LibWeb/Bindings/ExceptionOrUtils.h> | ||||||
| #include <LibWeb/HTML/Scripting/ClassicScript.h> | #include <LibWeb/HTML/Scripting/ClassicScript.h> | ||||||
| #include <LibWeb/HTML/Scripting/Environments.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(); |         auto timer = Core::ElapsedTimer::start_new(); | ||||||
| 
 | 
 | ||||||
|         // 6. Otherwise, set evaluationStatus to ScriptEvaluation(script's record).
 |         // 6. Otherwise, set evaluationStatus to ScriptEvaluation(script's record).
 | ||||||
|         if (auto* bytecode_interpreter = vm().bytecode_interpreter_if_exists()) { |         evaluation_status = vm().bytecode_interpreter().run(*m_script_record, lexical_environment_override); | ||||||
|             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); |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         // FIXME: If ScriptEvaluation does not complete because the user agent has aborted the running script, leave evaluationStatus as null.
 |         // 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 |  * SPDX-License-Identifier: BSD-2-Clause | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Runtime/ModuleRequest.h> | #include <LibJS/Runtime/ModuleRequest.h> | ||||||
| #include <LibWeb/HTML/Scripting/Environments.h> | #include <LibWeb/HTML/Scripting/Environments.h> | ||||||
| #include <LibWeb/HTML/Scripting/Fetching.h> | #include <LibWeb/HTML/Scripting/Fetching.h> | ||||||
|  | @ -136,9 +135,6 @@ JS::Promise* JavaScriptModuleScript::run(PreventErrorReporting) | ||||||
|         auto record = m_record; |         auto record = m_record; | ||||||
|         VERIFY(record); |         VERIFY(record); | ||||||
| 
 | 
 | ||||||
|         auto interpreter = JS::Interpreter::create_with_existing_realm(settings.realm()); |  | ||||||
|         JS::VM::InterpreterExecutionScope scope(*interpreter); |  | ||||||
| 
 |  | ||||||
|         // 2. Set evaluationPromise to record.Evaluate().
 |         // 2. Set evaluationPromise to record.Evaluate().
 | ||||||
|         auto elevation_promise_or_error = record->evaluate(vm()); |         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_document(&document) | ||||||
|     , m_custom_data() |     , m_custom_data() | ||||||
|     , m_worker_vm(JS::VM::create(adopt_own(m_custom_data)).release_value_but_fixme_should_propagate_errors()) |     , 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()) |     , m_implicit_port(MessagePort::create(document.realm()).release_value_but_fixme_should_propagate_errors()) | ||||||
| { | { | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -8,7 +8,6 @@ | ||||||
| 
 | 
 | ||||||
| #include <AK/RefCounted.h> | #include <AK/RefCounted.h> | ||||||
| #include <AK/URLParser.h> | #include <AK/URLParser.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibWeb/Bindings/MainThreadVM.h> | #include <LibWeb/Bindings/MainThreadVM.h> | ||||||
| #include <LibWeb/Forward.h> | #include <LibWeb/Forward.h> | ||||||
| #include <LibWeb/HTML/MessageEvent.h> | #include <LibWeb/HTML/MessageEvent.h> | ||||||
|  | @ -79,9 +78,7 @@ private: | ||||||
|     Bindings::WebEngineCustomData m_custom_data; |     Bindings::WebEngineCustomData m_custom_data; | ||||||
| 
 | 
 | ||||||
|     NonnullRefPtr<JS::VM> m_worker_vm; |     NonnullRefPtr<JS::VM> m_worker_vm; | ||||||
|     NonnullOwnPtr<JS::Interpreter> m_interpreter; |  | ||||||
|     JS::GCPtr<WorkerEnvironmentSettingsObject> m_inner_settings; |     JS::GCPtr<WorkerEnvironmentSettingsObject> m_inner_settings; | ||||||
|     JS::VM::InterpreterExecutionScope m_interpreter_scope; |  | ||||||
|     RefPtr<WorkerDebugConsoleClient> m_console; |     RefPtr<WorkerDebugConsoleClient> m_console; | ||||||
| 
 | 
 | ||||||
|     JS::NonnullGCPtr<MessagePort> m_implicit_port; |     JS::NonnullGCPtr<MessagePort> m_implicit_port; | ||||||
|  |  | ||||||
|  | @ -8,9 +8,9 @@ | ||||||
| 
 | 
 | ||||||
| #include "WebContentConsoleClient.h" | #include "WebContentConsoleClient.h" | ||||||
| #include <AK/TemporaryChange.h> | #include <AK/TemporaryChange.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/MarkupGenerator.h> | #include <LibJS/MarkupGenerator.h> | ||||||
| #include <LibJS/Runtime/AbstractOperations.h> | #include <LibJS/Runtime/AbstractOperations.h> | ||||||
|  | #include <LibJS/Runtime/GlobalEnvironment.h> | ||||||
| #include <LibJS/Runtime/ObjectEnvironment.h> | #include <LibJS/Runtime/ObjectEnvironment.h> | ||||||
| #include <LibJS/Runtime/Realm.h> | #include <LibJS/Runtime/Realm.h> | ||||||
| #include <LibJS/Runtime/ThrowableStringBuilder.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-2023, Linus Groh <linusg@serenityos.org> | ||||||
|  * Copyright (c) 2020-2022, Ali Mohammad Pur <mpfard@serenityos.org> |  * Copyright (c) 2020-2022, Ali Mohammad Pur <mpfard@serenityos.org> | ||||||
|  * |  * | ||||||
|  | @ -16,10 +16,11 @@ | ||||||
| #include <LibJS/Bytecode/Interpreter.h> | #include <LibJS/Bytecode/Interpreter.h> | ||||||
| #include <LibJS/Console.h> | #include <LibJS/Console.h> | ||||||
| #include <LibJS/Contrib/Test262/GlobalObject.h> | #include <LibJS/Contrib/Test262/GlobalObject.h> | ||||||
| #include <LibJS/Interpreter.h> |  | ||||||
| #include <LibJS/Parser.h> | #include <LibJS/Parser.h> | ||||||
| #include <LibJS/Print.h> | #include <LibJS/Print.h> | ||||||
| #include <LibJS/Runtime/ConsoleObject.h> | #include <LibJS/Runtime/ConsoleObject.h> | ||||||
|  | #include <LibJS/Runtime/DeclarativeEnvironment.h> | ||||||
|  | #include <LibJS/Runtime/GlobalEnvironment.h> | ||||||
| #include <LibJS/Runtime/JSONObject.h> | #include <LibJS/Runtime/JSONObject.h> | ||||||
| #include <LibJS/Runtime/StringPrototype.h> | #include <LibJS/Runtime/StringPrototype.h> | ||||||
| #include <LibJS/Runtime/ThrowableStringBuilder.h> | #include <LibJS/Runtime/ThrowableStringBuilder.h> | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling