Spreadsheet: Replace hacky JS VM configuration with a more correct one

Now we give each sheet its own interpreter and realm, and only make them
share the VM.
This is to prepare for the next commit, which will be refactoring a
bunch of things to propagate exceptions via ThrowCompletionOr<T>.
This commit is contained in:
Ali Mohammad Pur 2021-11-21 05:04:55 +03:30 committed by Ali Mohammad Pur
parent 82dde46a30
commit 235eb0b1ad
Notes: sideshowbarker 2024-07-17 22:53:55 +09:00
5 changed files with 27 additions and 26 deletions

View File

@ -356,7 +356,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::get_column_bound)
}
WorkbookObject::WorkbookObject(Workbook& workbook)
: JS::Object(*JS::Object::create(workbook.global_object(), workbook.global_object().object_prototype()))
: JS::Object(*JS::Object::create(workbook.vm().interpreter().global_object(), workbook.vm().interpreter().global_object().object_prototype()))
, m_workbook(workbook)
{
}

View File

@ -17,6 +17,7 @@
#include <AK/TemporaryChange.h>
#include <AK/URL.h>
#include <LibCore/File.h>
#include <LibJS/Interpreter.h>
#include <LibJS/Parser.h>
#include <LibJS/Runtime/FunctionObject.h>
#include <ctype.h>
@ -38,16 +39,13 @@ Sheet::Sheet(StringView name, Workbook& workbook)
Sheet::Sheet(Workbook& workbook)
: m_workbook(workbook)
, m_interpreter(JS::Interpreter::create<SheetGlobalObject>(m_workbook.vm(), *this))
{
JS::DeferGC defer_gc(m_workbook.interpreter().heap());
m_global_object = m_workbook.interpreter().heap().allocate_without_global_object<SheetGlobalObject>(*this);
global_object().initialize_global_object();
JS::DeferGC defer_gc(m_workbook.vm().heap());
m_global_object = static_cast<SheetGlobalObject*>(&m_interpreter->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.
// Note: We have to set the global object here otherwise the functions in runtime.js are not registered correctly.
interpreter().realm().set_global_object(global_object(), &global_object());
// Sadly, these have to be evaluated once per sheet.
auto file_or_error = Core::File::open("/res/js/Spreadsheet/runtime.js", Core::OpenMode::ReadOnly);
if (!file_or_error.is_error()) {
@ -77,7 +75,7 @@ Sheet::~Sheet()
JS::Interpreter& Sheet::interpreter() const
{
return m_workbook.interpreter();
return const_cast<JS::Interpreter&>(*m_interpreter);
}
size_t Sheet::add_row()

View File

@ -147,6 +147,8 @@ private:
Workbook& m_workbook;
mutable SheetGlobalObject* m_global_object;
NonnullOwnPtr<JS::Interpreter> m_interpreter;
Cell* m_current_cell_being_evaluated { nullptr };
HashTable<Cell*> m_visited_cells_in_update;

View File

@ -17,21 +17,24 @@
namespace Spreadsheet {
static JS::VM& global_vm()
{
static RefPtr<JS::VM> vm;
if (!vm)
vm = JS::VM::create();
return *vm;
}
Workbook::Workbook(NonnullRefPtrVector<Sheet>&& sheets)
: m_sheets(move(sheets))
, m_interpreter(JS::Interpreter::create<JS::GlobalObject>(global_vm()))
, m_interpreter_scope(JS::VM::InterpreterExecutionScope(interpreter()))
, m_vm(JS::VM::create())
, m_interpreter(JS::Interpreter::create<JS::GlobalObject>(m_vm))
, m_interpreter_scope(*m_interpreter)
, m_main_execution_context(m_vm->heap())
{
m_workbook_object = interpreter().heap().allocate<WorkbookObject>(global_object(), *this);
global_object().define_direct_property("workbook", workbook_object(), JS::default_attributes);
m_workbook_object = m_vm->heap().allocate<WorkbookObject>(m_interpreter->global_object(), *this);
m_interpreter->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.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();
m_main_execution_context.realm = &m_interpreter->realm();
m_main_execution_context.is_strict_mode = true;
MUST(m_vm->push_execution_context(m_main_execution_context, m_interpreter->global_object()));
}
bool Workbook::set_filename(const String& filename)

View File

@ -37,19 +37,17 @@ public:
return *sheet;
}
JS::Interpreter& interpreter() { return *m_interpreter; }
const JS::Interpreter& interpreter() const { return *m_interpreter; }
JS::GlobalObject& global_object() { return m_interpreter->global_object(); }
const JS::GlobalObject& global_object() const { return m_interpreter->global_object(); }
WorkbookObject* workbook_object() { return m_workbook_object; }
JS::VM& vm() { return *m_vm; }
JS::VM const& vm() const { return *m_vm; }
private:
NonnullRefPtrVector<Sheet> m_sheets;
NonnullRefPtr<JS::VM> m_vm;
NonnullOwnPtr<JS::Interpreter> m_interpreter;
JS::VM::InterpreterExecutionScope m_interpreter_scope;
WorkbookObject* m_workbook_object { nullptr };
JS::ExecutionContext m_main_execution_context;
String m_current_filename;
bool m_dirty { false };