mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
now retrieves number of arguments of blocks from OP_ENTER op code; close #2671
This commit is contained in:
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user