From b12ea17d0b30f231dd969804838398c2e1459cf3 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 25 May 2024 10:48:16 +0900 Subject: [PATCH] Improvements to `mrb_protect_atexit()` - Initialize the GC arena each time `atexit` is called. - To reduce the overhead of `MRB_TRY()`, an internal loop is also performed. --- src/error.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/error.c b/src/error.c index c720b58b7..bfa0b0103 100644 --- a/src/error.c +++ b/src/error.c @@ -589,19 +589,24 @@ mrb_protect_atexit(mrb_state *mrb) if (mrb->atexit_stack_len > 0) { struct mrb_jmpbuf *prev_jmp = mrb->jmp; struct mrb_jmpbuf c_jmp; - for (int i = mrb->atexit_stack_len; i > 0; --i) { + int i = mrb->atexit_stack_len; + while (i > 0) { MRB_TRY(&c_jmp) { mrb->jmp = &c_jmp; - mrb->atexit_stack[i - 1](mrb); + do { + mrb->atexit_stack[--i](mrb); + mrb_gc_arena_restore(mrb, 0); + } while (i > 0); mrb->jmp = prev_jmp; } MRB_CATCH(&c_jmp) { + mrb->jmp = prev_jmp; /* ignore atexit errors */ + mrb_gc_arena_restore(mrb, 0); } MRB_END_EXC(&c_jmp); } #ifndef MRB_FIXED_STATE_ATEXIT_STACK mrb_free(mrb, mrb->atexit_stack); #endif - mrb->jmp = prev_jmp; } }