From 8981b2fb28dbaed76078aff6c84f19b90832aaaf Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 30 May 2022 01:19:10 +0900 Subject: [PATCH] vm.c (ary_new_from_regs): stack may be reallocated. Unlike `hash_new_from_regs`, `ary_new_from_regs` do not call `mrb_funcall` et al directly or indirectly. But since it may invoke the garbage collection, and hooks for GC may call `mrb_funcall` etc (although calling them is not encouraged), we care stack reallocation just for the safety. --- src/vm.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/vm.c b/src/vm.c index 09e557dc8..145bf524a 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1204,6 +1204,17 @@ hash_new_from_regs(mrb_state *mrb, mrb_int argc, mrb_int idx) } \ } while (0) +static mrb_value +ary_new_from_regs(mrb_state *mrb, mrb_int argc, mrb_int idx) +{ + mrb_value ary = mrb_ary_new_capa(mrb, argc); + while (argc--) { + mrb_ary_push(mrb, ary, regs[idx]); + idx++; + } + return ary; +} + MRB_API mrb_value mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) { @@ -1922,7 +1933,7 @@ RETRY_TRY_BLOCK: } else if (argc == 14) { /* pack arguments and kdict */ - regs[1] = mrb_ary_new_from_values(mrb, argc+1, ®s[1]); + regs[1] = ary_new_from_regs(mrb, argc+1, 1); argc = ci->n = 15; } else {/* argc == 15 */ @@ -2625,12 +2636,12 @@ RETRY_TRY_BLOCK: } CASE(OP_ARRAY, BB) { - regs[a] = mrb_ary_new_from_values(mrb, b, ®s[a]); + regs[a] = ary_new_from_regs(mrb, b, a); mrb_gc_arena_restore(mrb, ai); NEXT; } CASE(OP_ARRAY2, BBB) { - regs[a] = mrb_ary_new_from_values(mrb, c, ®s[b]); + regs[a] = ary_new_from_regs(mrb, c, b); mrb_gc_arena_restore(mrb, ai); NEXT; } @@ -2700,7 +2711,7 @@ RETRY_TRY_BLOCK: int len, idx; if (!mrb_array_p(v)) { - v = mrb_ary_new_from_values(mrb, 1, ®s[a]); + v = ary_new_from_regs(mrb, 1, a); } ary = mrb_ary_ptr(v); len = (int)ARY_LEN(ary);