From 275dea9d98a147e891b95f054c74c8198478a223 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Mon, 22 Aug 2022 19:35:23 +0100 Subject: [PATCH] LibJS: Remove {Bytecode::,}Interpreter::global_object() The basic idea is that a global object cannot just come out of nowhere, it must be associated to a realm - so get it from there, if needed. This is to enforce the changes from all the previous commits by not handing out global objects unless you actually have an initialized realm (either stored somewhere, or the VM's current realm). --- Tests/LibJS/test-bytecode-js.cpp | 2 +- Userland/Applications/Spreadsheet/Spreadsheet.cpp | 2 +- Userland/Applications/Spreadsheet/Workbook.cpp | 4 ++-- Userland/Libraries/LibJS/Bytecode/Interpreter.cpp | 9 ++++----- Userland/Libraries/LibJS/Bytecode/Interpreter.h | 4 +--- Userland/Libraries/LibJS/Interpreter.cpp | 11 ----------- Userland/Libraries/LibJS/Interpreter.h | 10 +--------- Userland/Libraries/LibTest/JavaScriptTestRunner.h | 4 ++-- Userland/Services/WebContent/ConnectionFromClient.cpp | 4 ++-- Userland/Utilities/js.cpp | 2 +- 10 files changed, 15 insertions(+), 37 deletions(-) diff --git a/Tests/LibJS/test-bytecode-js.cpp b/Tests/LibJS/test-bytecode-js.cpp index 07f27b2808..90fe6acdf8 100644 --- a/Tests/LibJS/test-bytecode-js.cpp +++ b/Tests/LibJS/test-bytecode-js.cpp @@ -20,7 +20,7 @@ \ auto script = script_or_error.release_value(); \ auto const& program = script->parse_node(); \ - JS::Bytecode::Interpreter bytecode_interpreter(ast_interpreter->global_object(), ast_interpreter->realm()); + JS::Bytecode::Interpreter bytecode_interpreter(ast_interpreter->realm()); #define EXPECT_NO_EXCEPTION(executable) \ auto executable = MUST(JS::Bytecode::Generator::generate(program)); \ diff --git a/Userland/Applications/Spreadsheet/Spreadsheet.cpp b/Userland/Applications/Spreadsheet/Spreadsheet.cpp index e5da87ac9b..c8e3c4ab4a 100644 --- a/Userland/Applications/Spreadsheet/Spreadsheet.cpp +++ b/Userland/Applications/Spreadsheet/Spreadsheet.cpp @@ -43,7 +43,7 @@ Sheet::Sheet(Workbook& workbook) , m_interpreter(JS::Interpreter::create(m_workbook.vm(), *this)) { JS::DeferGC defer_gc(m_workbook.vm().heap()); - m_global_object = static_cast(&m_interpreter->global_object()); + m_global_object = static_cast(&m_interpreter->realm().global_object()); global_object().define_direct_property("workbook", m_workbook.workbook_object(), JS::default_attributes); global_object().define_direct_property("thisSheet", &global_object(), JS::default_attributes); // Self-reference is unfortunate, but required. diff --git a/Userland/Applications/Spreadsheet/Workbook.cpp b/Userland/Applications/Spreadsheet/Workbook.cpp index 3ebdd15c6d..30411b3521 100644 --- a/Userland/Applications/Spreadsheet/Workbook.cpp +++ b/Userland/Applications/Spreadsheet/Workbook.cpp @@ -30,10 +30,10 @@ Workbook::Workbook(NonnullRefPtrVector&& sheets, GUI::Window& parent_wind , m_parent_window(parent_window) { m_workbook_object = m_vm->heap().allocate(m_interpreter->realm(), m_interpreter->realm(), *this); - m_interpreter->global_object().define_direct_property("workbook", workbook_object(), JS::default_attributes); + m_interpreter->realm().global_object().define_direct_property("workbook", workbook_object(), JS::default_attributes); m_main_execution_context.current_node = nullptr; - m_main_execution_context.this_value = &m_interpreter->global_object(); + m_main_execution_context.this_value = &m_interpreter->realm().global_object(); m_main_execution_context.function_name = "(global execution context)"sv; m_main_execution_context.lexical_environment = &m_interpreter->realm().global_environment(); m_main_execution_context.variable_environment = &m_interpreter->realm().global_environment(); diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp index dceec8c5d3..8999675e8c 100644 --- a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp @@ -25,9 +25,8 @@ Interpreter* Interpreter::current() return s_current; } -Interpreter::Interpreter(GlobalObject& global_object, Realm& realm) - : m_vm(global_object.vm()) - , m_global_object(global_object) +Interpreter::Interpreter(Realm& realm) + : m_vm(realm.vm()) , m_realm(realm) { VERIFY(!s_current); @@ -51,7 +50,7 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable const& e ExecutionContext execution_context(vm().heap()); if (vm().execution_context_stack().is_empty() || !vm().running_execution_context().lexical_environment) { // The "normal" interpreter pushes an execution context without environment so in that case we also want to push one. - execution_context.this_value = &global_object(); + execution_context.this_value = &m_realm.global_object(); static FlyString global_execution_context_name = "(*BC* global execution context)"; execution_context.function_name = global_execution_context_name; execution_context.lexical_environment = &m_realm.global_environment(); @@ -69,7 +68,7 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable const& e m_register_windows.append(make(MarkedVector(vm().heap()), MarkedVector(vm().heap()), MarkedVector(vm().heap()))); registers().resize(executable.number_of_registers); - registers()[Register::global_object_index] = Value(&global_object()); + registers()[Register::global_object_index] = Value(&m_realm.global_object()); for (;;) { Bytecode::InstructionStreamIterator pc(block->instruction_stream()); diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.h b/Userland/Libraries/LibJS/Bytecode/Interpreter.h index 78904f0ebf..eafa76e6db 100644 --- a/Userland/Libraries/LibJS/Bytecode/Interpreter.h +++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.h @@ -26,13 +26,12 @@ struct RegisterWindow { class Interpreter { public: - Interpreter(GlobalObject&, Realm&); + explicit Interpreter(Realm&); ~Interpreter(); // FIXME: Remove this thing once we don't need it anymore! static Interpreter* current(); - GlobalObject& global_object() { return m_global_object; } Realm& realm() { return m_realm; } VM& vm() { return m_vm; } @@ -90,7 +89,6 @@ private: static AK::Array, static_cast>(Interpreter::OptimizationLevel::__Count)> s_optimization_pipelines; VM& m_vm; - GlobalObject& m_global_object; Realm& m_realm; Vector, RegisterWindow*>> m_register_windows; Optional m_pending_jump; diff --git a/Userland/Libraries/LibJS/Interpreter.cpp b/Userland/Libraries/LibJS/Interpreter.cpp index 9439662269..a708d87d2c 100644 --- a/Userland/Libraries/LibJS/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Interpreter.cpp @@ -25,7 +25,6 @@ NonnullOwnPtr 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_global_object = make_handle(&realm.global_object()); interpreter->m_realm = make_handle(&realm); return interpreter; } @@ -140,16 +139,6 @@ ThrowCompletionOr Interpreter::run(SourceTextModule& module) return js_undefined(); } -GlobalObject& Interpreter::global_object() -{ - return static_cast(*m_global_object.cell()); -} - -GlobalObject const& Interpreter::global_object() const -{ - return static_cast(*m_global_object.cell()); -} - Realm& Interpreter::realm() { return static_cast(*m_realm.cell()); diff --git a/Userland/Libraries/LibJS/Interpreter.h b/Userland/Libraries/LibJS/Interpreter.h index 0a8c1647fd..478ecbfa1a 100644 --- a/Userland/Libraries/LibJS/Interpreter.h +++ b/Userland/Libraries/LibJS/Interpreter.h @@ -43,15 +43,13 @@ public: auto interpreter = adopt_own(*new Interpreter(vm)); VM::InterpreterExecutionScope scope(*interpreter); - GlobalObject* global_object { nullptr }; Realm* realm { nullptr }; interpreter->m_global_execution_context = MUST(Realm::initialize_host_defined_realm( vm, [&](Realm& realm_) -> GlobalObject* { - global_object = interpreter->heap().allocate_without_realm(realm_, forward(args)...); realm = &realm_; - return global_object; + return interpreter->heap().allocate_without_realm(realm_, forward(args)...); }, nullptr)); @@ -59,7 +57,6 @@ public: static FlyString global_execution_context_name = "(global execution context)"; interpreter->m_global_execution_context->function_name = global_execution_context_name; - interpreter->m_global_object = make_handle(global_object); interpreter->m_realm = make_handle(realm); return interpreter; @@ -72,9 +69,6 @@ public: ThrowCompletionOr run(Script&); ThrowCompletionOr run(SourceTextModule&); - GlobalObject& global_object(); - GlobalObject const& global_object() const; - Realm& realm(); Realm const& realm() const; @@ -104,8 +98,6 @@ private: ExecutingASTNodeChain* m_ast_node_chain { nullptr }; NonnullRefPtr m_vm; - - Handle m_global_object; Handle m_realm; // This is here to keep the global execution context alive for the entire lifespan of the Interpreter. diff --git a/Userland/Libraries/LibTest/JavaScriptTestRunner.h b/Userland/Libraries/LibTest/JavaScriptTestRunner.h index be8719fb2d..eef825661d 100644 --- a/Userland/Libraries/LibTest/JavaScriptTestRunner.h +++ b/Userland/Libraries/LibTest/JavaScriptTestRunner.h @@ -365,7 +365,7 @@ inline JSFileResult TestRunner::run_file_test(String const& test_path) executable->name = test_path; if (JS::Bytecode::g_dump_bytecode) executable->dump(); - JS::Bytecode::Interpreter bytecode_interpreter(interpreter->global_object(), interpreter->realm()); + JS::Bytecode::Interpreter bytecode_interpreter(interpreter->realm()); MUST(bytecode_interpreter.run(*executable)); } else { g_vm->push_execution_context(global_execution_context); @@ -383,7 +383,7 @@ inline JSFileResult TestRunner::run_file_test(String const& test_path) executable->name = test_path; if (JS::Bytecode::g_dump_bytecode) executable->dump(); - JS::Bytecode::Interpreter bytecode_interpreter(interpreter->realm().global_object(), interpreter->realm()); + JS::Bytecode::Interpreter bytecode_interpreter(interpreter->realm()); (void)bytecode_interpreter.run(*executable); } } else { diff --git a/Userland/Services/WebContent/ConnectionFromClient.cpp b/Userland/Services/WebContent/ConnectionFromClient.cpp index f5148e7c4d..90bb582e09 100644 --- a/Userland/Services/WebContent/ConnectionFromClient.cpp +++ b/Userland/Services/WebContent/ConnectionFromClient.cpp @@ -390,8 +390,8 @@ void ConnectionFromClient::initialize_js_console(Badge) return; m_interpreter = interpreter; - m_console_client = make(interpreter->global_object().console(), interpreter, *this); - interpreter->global_object().console().set_client(*m_console_client.ptr()); + m_console_client = make(interpreter->realm().global_object().console(), interpreter, *this); + interpreter->realm().global_object().console().set_client(*m_console_client.ptr()); } void ConnectionFromClient::js_console_input(String const& js_source) diff --git a/Userland/Utilities/js.cpp b/Userland/Utilities/js.cpp index 84dffb5e12..b9f4c187e3 100644 --- a/Userland/Utilities/js.cpp +++ b/Userland/Utilities/js.cpp @@ -1170,7 +1170,7 @@ static bool parse_and_run(JS::Interpreter& interpreter, StringView source, Strin executable->dump(); if (s_run_bytecode) { - JS::Bytecode::Interpreter bytecode_interpreter(interpreter.realm().global_object(), interpreter.realm()); + JS::Bytecode::Interpreter bytecode_interpreter(interpreter.realm()); auto result_or_error = bytecode_interpreter.run_and_return_frame(*executable, nullptr); if (result_or_error.value.is_error()) result = result_or_error.value.release_error();