diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-04-10 21:12:41 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-04-10 21:12:41 +0900 |
| commit | 0048dd118a0d57ff87265593819f9e93e05fafed (patch) | |
| tree | 5115618de51eb7dba2713ce94e58dbf0b03db2df /src | |
| parent | a55b237d89e1397da8dc879b24c1a34e80ad4e91 (diff) | |
| download | mruby-0048dd118a0d57ff87265593819f9e93e05fafed.tar.gz mruby-0048dd118a0d57ff87265593819f9e93e05fafed.zip | |
Protect arguments from GC; fix #3597
GC may be called with OP_ENTER (especially when GC_STRESS is set).
Diffstat (limited to 'src')
| -rw-r--r-- | src/gc.c | 8 | ||||
| -rw-r--r-- | src/vm.c | 2 |
2 files changed, 8 insertions, 2 deletions
@@ -545,10 +545,16 @@ mark_context_stack(mrb_state *mrb, struct mrb_context *c) size_t i; size_t e; mrb_value nil; + int nregs; if (c->stack == NULL) return; e = c->stack - c->stbase; - if (c->ci) e += c->ci->nregs; + if (c->ci) { + nregs = c->ci->argc + 2; + if (c->ci->nregs > nregs) + nregs = c->ci->nregs; + e += nregs; + } if (c->stbase + e > c->stend) e = c->stend - c->stbase; for (i=0; i<e; i++) { mrb_value v = c->stbase[i]; @@ -1589,7 +1589,6 @@ RETRY_TRY_BLOCK: argc = mrb_ary_ptr(argv[0])->len; argv = mrb_ary_ptr(argv[0])->ptr; } - mrb->c->ci->argc = len; if (argc < len) { int mlen = m2; if (argc < m1+m2) { @@ -1639,6 +1638,7 @@ RETRY_TRY_BLOCK: } pc += o + 1; } + mrb->c->ci->argc = len; /* clear local (but non-argument) variables */ if (irep->nlocals-len-2 > 0) { stack_clear(®s[len+2], irep->nlocals-len-2); |
