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

LibJS: Add a way to save/restore the entire execution context stack

This will be used by LibWeb to squirrel away the stack while performing
a microtask checkpoint in some cases. VM will simply consider saved
execution context stacks as GC roots as well.
This commit is contained in:
Andreas Kling 2021-10-03 14:52:53 +02:00
parent 17e56661db
commit 406d3199d0
2 changed files with 31 additions and 10 deletions

View file

@ -99,17 +99,23 @@ void VM::gather_roots(HashTable<Cell*>& roots)
if (m_last_value.is_cell()) if (m_last_value.is_cell())
roots.set(&m_last_value.as_cell()); roots.set(&m_last_value.as_cell());
for (auto& execution_context : m_execution_context_stack) { auto gather_roots_from_execution_context_stack = [&roots](Vector<ExecutionContext*> const& stack) {
if (execution_context->this_value.is_cell()) for (auto& execution_context : stack) {
roots.set(&execution_context->this_value.as_cell()); if (execution_context->this_value.is_cell())
roots.set(execution_context->arguments_object); roots.set(&execution_context->this_value.as_cell());
for (auto& argument : execution_context->arguments) { roots.set(execution_context->arguments_object);
if (argument.is_cell()) for (auto& argument : execution_context->arguments) {
roots.set(&argument.as_cell()); if (argument.is_cell())
roots.set(&argument.as_cell());
}
roots.set(execution_context->lexical_environment);
roots.set(execution_context->variable_environment);
} }
roots.set(execution_context->lexical_environment); };
roots.set(execution_context->variable_environment);
} gather_roots_from_execution_context_stack(m_execution_context_stack);
for (auto& saved_stack : m_saved_execution_context_stacks)
gather_roots_from_execution_context_stack(saved_stack);
#define __JS_ENUMERATE(SymbolName, snake_name) \ #define __JS_ENUMERATE(SymbolName, snake_name) \
roots.set(well_known_symbol_##snake_name()); roots.set(well_known_symbol_##snake_name());
@ -828,4 +834,14 @@ VM::CustomData::~CustomData()
{ {
} }
void VM::save_execution_context_stack()
{
m_saved_execution_context_stacks.append(move(m_execution_context_stack));
}
void VM::restore_execution_context_stack()
{
m_execution_context_stack = m_saved_execution_context_stacks.take_last();
}
} }

View file

@ -280,6 +280,9 @@ public:
ThrowCompletionOr<Value> named_evaluation_if_anonymous_function(GlobalObject& global_object, ASTNode const& expression, FlyString const& name); ThrowCompletionOr<Value> named_evaluation_if_anonymous_function(GlobalObject& global_object, ASTNode const& expression, FlyString const& name);
void save_execution_context_stack();
void restore_execution_context_stack();
private: private:
explicit VM(OwnPtr<CustomData>); explicit VM(OwnPtr<CustomData>);
@ -302,6 +305,8 @@ private:
Vector<ExecutionContext*> m_execution_context_stack; Vector<ExecutionContext*> m_execution_context_stack;
Vector<Vector<ExecutionContext*>> m_saved_execution_context_stacks;
Value m_last_value; Value m_last_value;
ScopeType m_unwind_until { ScopeType::None }; ScopeType m_unwind_until { ScopeType::None };
FlyString m_unwind_until_label; FlyString m_unwind_until_label;