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 07f27b28083..90fe6acdf82 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 e5da87ac9be..c8e3c4ab4ac 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 3ebdd15c6d5..30411b35219 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 dceec8c5d33..8999675e8cf 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 78904f0ebfb..eafa76e6dbe 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 9439662269f..a708d87d2cd 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 0a8c1647fde..478ecbfa1a4 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 be8719fb2df..eef825661df 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 f5148e7c4d1..90bb582e09e 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 84dffb5e12d..b9f4c187e31 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();