From 15dec8383228e5b2762665ebb4422900d88e4e92 Mon Sep 17 00:00:00 2001 From: dearblue Date: Tue, 31 Mar 2020 23:24:53 +0900 Subject: Fix `mrb_funcall_with_block()` uses more GC arena If `mrb->jmp` is `NULL` and the function `mrb_funcall_with_block()` is called, GC Arena is returned from the function with over-used. - A normal (no global exodus) return will consume two GC Arena's. - In the event of an exception, five GC Arena are consumed. This patch reduces consumption in both cases to one. --- src/vm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/vm.c b/src/vm.c index 214907a19..d7826230e 100644 --- a/src/vm.c +++ b/src/vm.c @@ -430,6 +430,7 @@ MRB_API mrb_value mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, const mrb_value *argv, mrb_value blk) { mrb_value val; + int ai = mrb_gc_arena_save(mrb); if (!mrb->jmp) { struct mrb_jmpbuf c_jmp; @@ -518,19 +519,17 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc mrb->c->stack[argc+1] = blk; if (MRB_METHOD_CFUNC_P(m)) { - int ai = mrb_gc_arena_save(mrb); - ci->acc = CI_ACC_DIRECT; val = MRB_METHOD_CFUNC(m)(mrb, self); mrb->c->stack = mrb->c->ci->stackent; cipop(mrb); - mrb_gc_arena_restore(mrb, ai); } else { ci->acc = CI_ACC_SKIP; val = mrb_run(mrb, MRB_METHOD_PROC(m), self); } } + mrb_gc_arena_restore(mrb, ai); mrb_gc_protect(mrb, val); return val; } -- cgit v1.2.3