ladybird/Libraries/LibJS/Runtime/WeakRef.cpp
Andreas Kling 4c10f44e3e LibJS: Remove bogus VERIFY_NOT_REACHED() in WeakRef::remove_dead_cells()
It's harmless if the WeakRef is asked to remove dead cells when it has
no dead cells to remove. This can happen if the WeakRef lives longer
due to someone referencing it. Caught by test-js with different GC
frequency.
2026-01-07 07:52:03 -05:00

57 lines
1.5 KiB
C++

/*
* Copyright (c) 2021-2022, Idan Horowitz <idan.horowitz@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Runtime/WeakRef.h>
namespace JS {
GC_DEFINE_ALLOCATOR(WeakRef);
GC::Ref<WeakRef> WeakRef::create(Realm& realm, Object& value)
{
return realm.create<WeakRef>(value, realm.intrinsics().weak_ref_prototype());
}
GC::Ref<WeakRef> WeakRef::create(Realm& realm, Symbol& value)
{
return realm.create<WeakRef>(value, realm.intrinsics().weak_ref_prototype());
}
WeakRef::WeakRef(Object& value, Object& prototype)
: Object(ConstructWithPrototypeTag::Tag, prototype)
, WeakContainer(heap())
, m_value(&value)
, m_last_execution_generation(vm().execution_generation())
{
}
WeakRef::WeakRef(Symbol& value, Object& prototype)
: Object(ConstructWithPrototypeTag::Tag, prototype)
, WeakContainer(heap())
, m_value(&value)
, m_last_execution_generation(vm().execution_generation())
{
}
void WeakRef::remove_dead_cells(Badge<GC::Heap>)
{
if (m_value.visit([](Cell* cell) -> bool { return cell->state() == Cell::State::Live; }, [](Empty) -> bool { return true; }))
return;
m_value = Empty {};
}
void WeakRef::visit_edges(Visitor& visitor)
{
Base::visit_edges(visitor);
if (vm().execution_generation() == m_last_execution_generation) {
auto* cell = m_value.visit([](Cell* cell) -> Cell* { return cell; }, [](Empty) -> Cell* { return nullptr; });
visitor.visit(cell);
}
}
}