summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authordearblue <[email protected]>2020-03-31 23:24:53 +0900
committerdearblue <[email protected]>2020-03-31 23:24:53 +0900
commit15dec8383228e5b2762665ebb4422900d88e4e92 (patch)
treea4c766a52009905ecd6367c26e24b27eaa55b402
parent5acd802d2be19872b703d6c9876aa61a262c6c8c (diff)
downloadmruby-15dec8383228e5b2762665ebb4422900d88e4e92.tar.gz
mruby-15dec8383228e5b2762665ebb4422900d88e4e92.zip
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.
-rw-r--r--src/vm.c5
1 files changed, 2 insertions, 3 deletions
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;
}