summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2020-07-21 12:47:35 +0900
committerHiroshi Mimaki <[email protected]>2020-07-29 09:09:37 +0900
commit63956036e116ef6a33a91e16348c4d1a09f6f72c (patch)
tree7ab7fc05cbd3ace10366426015cf0af6e60209ba
parentcdf45438f03379292e71f5c16e7b2fe221b8b272 (diff)
downloadmruby-63956036e116ef6a33a91e16348c4d1a09f6f72c.tar.gz
mruby-63956036e116ef6a33a91e16348c4d1a09f6f72c.zip
Fix the VM stack handling bug in 'mrb_yield_with_class()`; fix #5042
-rw-r--r--src/vm.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/src/vm.c b/src/vm.c
index 136ea2fcf..f74be7edd 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -754,16 +754,25 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value
ci = cipush(mrb);
ci->mid = mid;
ci->proc = p;
- ci->stackent = mrb->c->stack;
- ci->argc = (int)argc;
ci->target_class = c;
ci->acc = CI_ACC_SKIP;
- n = MRB_PROC_CFUNC_P(p) ? (int)(argc+2) : p->body.irep->nregs;
- mrb->c->stack = mrb->c->stack + n;
+ ci->stackent = mrb->c->stack;
+ mrb->c->stack += n;
+ if (argc >= CALL_MAXARGS) {
+ ci->argc = -1;
+ n = 3;
+ }
+ else {
+ ci->argc = (int)argc;
+ n = argc + 2;
+ }
mrb_stack_extend(mrb, n);
-
mrb->c->stack[0] = self;
- if (argc > 0) {
+ if (ci->argc < 0) {
+ mrb->c->stack[1] = mrb_ary_new_from_values(mrb, argc, argv);
+ argc = 1;
+ }
+ else if (argc > 0) {
stack_copy(mrb->c->stack+1, argv, argc);
}
mrb->c->stack[argc+1] = mrb_nil_value();