summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-eval
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2014-12-19 19:45:20 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2014-12-19 19:45:20 +0900
commit10e9a1a167ea9a3359250c7040c2f61530946d68 (patch)
tree3484f83ca7bc2bc56eee2a36ab7f783a9a0a8ab5 /mrbgems/mruby-eval
parent358dd61107b64ca65cb6febb89f818388f62878e (diff)
downloadmruby-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.c22
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 */