mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 13:38:11 +00:00
LibJS+LibWeb: Make JS::ExecutionContext protect its Web::HTML::ESO owner
We can't be nuking the ESO while its owned execution context is still on the VM's execution context stack, as that may lead to a use-after-free. This patch solves this by adding a `context_owner` field to each context and treating it as a GC root.
This commit is contained in:
parent
1fdce71483
commit
849499988e
3 changed files with 7 additions and 0 deletions
|
@ -58,6 +58,9 @@ public:
|
||||||
Environment* variable_environment { nullptr }; // [[VariableEnvironment]]
|
Environment* variable_environment { nullptr }; // [[VariableEnvironment]]
|
||||||
PrivateEnvironment* private_environment { nullptr }; // [[PrivateEnvironment]]
|
PrivateEnvironment* private_environment { nullptr }; // [[PrivateEnvironment]]
|
||||||
|
|
||||||
|
// Non-standard: This points at something that owns this ExecutionContext, in case it needs to be protected from GC.
|
||||||
|
Cell* context_owner { nullptr };
|
||||||
|
|
||||||
ASTNode const* current_node { nullptr };
|
ASTNode const* current_node { nullptr };
|
||||||
FlyString function_name;
|
FlyString function_name;
|
||||||
Value this_value;
|
Value this_value;
|
||||||
|
|
|
@ -204,6 +204,8 @@ void VM::gather_roots(HashTable<Cell*>& roots)
|
||||||
roots.set(execution_context->lexical_environment);
|
roots.set(execution_context->lexical_environment);
|
||||||
roots.set(execution_context->variable_environment);
|
roots.set(execution_context->variable_environment);
|
||||||
roots.set(execution_context->private_environment);
|
roots.set(execution_context->private_environment);
|
||||||
|
if (auto* context_owner = execution_context->context_owner)
|
||||||
|
roots.set(context_owner);
|
||||||
execution_context->script_or_module.visit(
|
execution_context->script_or_module.visit(
|
||||||
[](Empty) {},
|
[](Empty) {},
|
||||||
[&](auto& script_or_module) {
|
[&](auto& script_or_module) {
|
||||||
|
|
|
@ -22,6 +22,8 @@ namespace Web::HTML {
|
||||||
EnvironmentSettingsObject::EnvironmentSettingsObject(NonnullOwnPtr<JS::ExecutionContext> realm_execution_context)
|
EnvironmentSettingsObject::EnvironmentSettingsObject(NonnullOwnPtr<JS::ExecutionContext> realm_execution_context)
|
||||||
: m_realm_execution_context(move(realm_execution_context))
|
: m_realm_execution_context(move(realm_execution_context))
|
||||||
{
|
{
|
||||||
|
m_realm_execution_context->context_owner = this;
|
||||||
|
|
||||||
// Register with the responsible event loop so we can perform step 4 of "perform a microtask checkpoint".
|
// Register with the responsible event loop so we can perform step 4 of "perform a microtask checkpoint".
|
||||||
responsible_event_loop().register_environment_settings_object({}, *this);
|
responsible_event_loop().register_environment_settings_object({}, *this);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue