now retrieves number of arguments of blocks from OP_ENTER op code; close #2671

parent 358dd611
......@@ -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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment