diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2014-12-19 19:45:20 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2014-12-19 19:45:20 +0900 |
| commit | 10e9a1a167ea9a3359250c7040c2f61530946d68 (patch) | |
| tree | 3484f83ca7bc2bc56eee2a36ab7f783a9a0a8ab5 /mrbgems/mruby-eval | |
| parent | 358dd61107b64ca65cb6febb89f818388f62878e (diff) | |
| download | mruby-10e9a1a167ea9a3359250c7040c2f61530946d68.tar.gz mruby-10e9a1a167ea9a3359250c7040c2f61530946d68.zip | |
now retrieves number of arguments of blocks from OP_ENTER op code; close #2671
Diffstat (limited to 'mrbgems/mruby-eval')
| -rw-r--r-- | mrbgems/mruby-eval/src/eval.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c index bad084dd6..4a523018b 100644 --- a/mrbgems/mruby-eval/src/eval.c +++ b/mrbgems/mruby-eval/src/eval.c @@ -56,16 +56,11 @@ search_variable(mrb_state *mrb, mrb_sym vsym, int bnest) } static mrb_bool -potential_upvar_p(struct mrb_locals *lv, uint16_t v, uint16_t nlocals) +potential_upvar_p(struct mrb_locals *lv, uint16_t v, int argc, uint16_t nlocals) { - int i; - if (v >= nlocals) return FALSE; /* skip arguments */ - for (i=0; i<nlocals-1; i++) { - if (lv[i].name == 0) - return i < v; - } + if (v < argc+1) return FALSE; return TRUE; } @@ -74,10 +69,19 @@ patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest) { size_t i; mrb_code c; + int argc = 0; for (i = 0; i < irep->ilen; i++) { c = irep->iseq[i]; switch(GET_OPCODE(c)){ + case OP_ENTER: + { + mrb_aspec ax = GETARG_Ax(i); + /* extra 1 means a slot for block */ + argc = MRB_ASPEC_REQ(ax)+MRB_ASPEC_OPT(ax)+MRB_ASPEC_REST(ax)+MRB_ASPEC_POST(ax)+1; + } + break; + case OP_EPUSH: patch_irep(mrb, irep->reps[GETARG_Bx(c)], bnest + 1); break; @@ -106,7 +110,7 @@ patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest) case OP_MOVE: /* src part */ - if (potential_upvar_p(irep->lv, GETARG_B(c), irep->nlocals)) { + if (potential_upvar_p(irep->lv, GETARG_B(c), argc, irep->nlocals)) { mrb_code arg = search_variable(mrb, irep->lv[GETARG_B(c) - 1].name, bnest); if (arg != 0) { /* must replace */ @@ -114,7 +118,7 @@ patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest) } } /* dst part */ - if (potential_upvar_p(irep->lv, GETARG_A(c), irep->nlocals)) { + if (potential_upvar_p(irep->lv, GETARG_A(c), argc, irep->nlocals)) { mrb_code arg = search_variable(mrb, irep->lv[GETARG_A(c) - 1].name, bnest); if (arg != 0) { /* must replace */ |
