From 7917743eb6ccdd35a87567170a9dd3a54acdc41e Mon Sep 17 00:00:00 2001 From: Jonathan Worthington Date: Tue, 2 Nov 2021 22:04:39 +0100 Subject: [PATCH] Don't lose exception handler results Invoking finalizers could end up replacing tc->last_handler_result, leading to missing or incorrect values being observed for that after finalizers had run. Don't run finalizers when there is such a risk. --- src/gc/finalize.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gc/finalize.c b/src/gc/finalize.c index 2274b7ff8a..2e3f826d1f 100644 --- a/src/gc/finalize.c +++ b/src/gc/finalize.c @@ -84,10 +84,13 @@ void MVM_finalize_walk_queues(MVMThreadContext *tc, MVMuint8 gen) { /* Try to run a finalization handler. Returns a true value if we do so */ MVMint32 MVM_gc_finalize_run_handler(MVMThreadContext *tc) { - /* Make sure there is a current frame and that there's a HLL handler - * to run. */ + /* Make sure there is a current frame, that we aren't hanging on to an + * exception handler result (which the finalizer could overwrite), and + * that there's a HLL handler to run. */ if (!tc->cur_frame) return 0; + if (tc->last_handler_result) + return 0; MVMCode *handler = MVM_hll_current(tc)->finalize_handler; if (handler) { /* Drain the finalizing queue to an array. */