1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 04:57:44 +00:00

LibJS: Move the current exception from Interpreter to VM

This will allow us to throw exceptions even when there is no active
interpreter in the VM.
This commit is contained in:
Andreas Kling 2020-09-21 15:28:09 +02:00
parent 675b482fe7
commit 4a8bfcdd1c
12 changed files with 26 additions and 23 deletions

View file

@ -1796,7 +1796,7 @@ Value TryStatement::execute(Interpreter& interpreter, GlobalObject& global_objec
interpreter.execute_statement(global_object, m_block, {}, ScopeType::Try);
if (auto* exception = interpreter.exception()) {
if (m_handler) {
interpreter.clear_exception();
interpreter.vm().clear_exception();
ArgumentVector arguments { { m_handler->parameter(), exception->value() } };
interpreter.execute_statement(global_object, m_handler->body(), move(arguments));
}
@ -1806,7 +1806,7 @@ Value TryStatement::execute(Interpreter& interpreter, GlobalObject& global_objec
// Keep, if any, and then clear the current exception so we can
// execute() the finalizer without an exception in our way.
auto* previous_exception = interpreter.exception();
interpreter.clear_exception();
interpreter.vm().clear_exception();
interpreter.stop_unwind();
m_finalizer->execute(interpreter, global_object);
// If we previously had an exception and the finalizer didn't

View file

@ -225,8 +225,6 @@ Symbol* Interpreter::get_global_symbol(const String& description)
void Interpreter::gather_roots(HashTable<Cell*>& roots)
{
roots.set(m_exception);
if (m_last_value.is_cell())
roots.set(m_last_value.as_cell());
@ -345,7 +343,7 @@ void Interpreter::throw_exception(Exception* exception)
}
}
#endif
m_exception = exception;
vm().set_exception({}, exception);
unwind(ScopeType::Try);
}

View file

@ -113,6 +113,7 @@ public:
VM& vm() { return *m_vm; }
Heap& heap() { return vm().heap(); }
Exception* exception() { return vm().exception(); }
void unwind(ScopeType type, FlyString label = {})
{
@ -195,12 +196,6 @@ public:
return m_call_stack.last().this_value;
}
Exception* exception()
{
return m_exception;
}
void clear_exception() { m_exception = nullptr; }
template<typename T, typename... Args>
void throw_exception(Args&&... args)
{
@ -252,8 +247,6 @@ private:
Handle<Object> m_global_object;
Exception* m_exception { nullptr };
ScopeType m_unwind_until { ScopeType::None };
FlyString m_unwind_until_label;

View file

@ -81,6 +81,8 @@ VM::InterpreterExecutionScope::~InterpreterExecutionScope()
void VM::gather_roots(HashTable<Cell*>& roots)
{
if (m_exception)
roots.set(m_exception);
for (auto* interpreter : m_interpreters)
interpreter->gather_roots(roots);
}

View file

@ -45,10 +45,18 @@ public:
void push_interpreter(Interpreter&);
void pop_interpreter(Interpreter&);
Exception* exception()
{
return m_exception;
}
void set_exception(Badge<Interpreter>, Exception* exception) { m_exception = exception; }
void clear_exception() { m_exception = nullptr; }
class InterpreterExecutionScope {
public:
InterpreterExecutionScope(Interpreter&);
~InterpreterExecutionScope();
private:
Interpreter& m_interpreter;
};
@ -58,6 +66,8 @@ public:
private:
VM();
Exception* m_exception { nullptr };
Heap m_heap;
Vector<Interpreter*> m_interpreters;
};