lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]



This works on 5.1w4, but.. could some Lua Guru :) please check. I'm not sure that the stabbing is in the right place. Thanks.


static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
  /* forbody -> DO block */
  BlockCnt bl;
  FuncState *fs = ls->fs;
  int prep, endfor;
  adjustlocalvars(ls, 3);  /* control variables */
  checknext(ls, TK_DO);
prep = luaK_codeAsBx(fs, (isnum ? OP_FORPREP : OP_TFORPREP), base, NO_JUMP);
  enterblock(fs, &bl, 0);  /* scope for declared variables */
  adjustlocalvars(ls, nvars);
  luaK_reserveregs(fs, nvars);
  block(ls);
#ifdef CONTINUE_PATCH
// TBD: NOT SURE IF THIS IS QUITE RIGHT (someone Lua Guru should check?)
  //      Lua code for for loops has changed since the original patch..
  //
//fprintf( stderr, "forbody() patchtohere %p %d %p %d\n",
// &bl, bl.continuelist, &bl, bl.previous, bl.previous->continuelist );
  luaK_patchtohere(fs, bl.previous->continuelist);  // this works
#endif
  leaveblock(fs);  /* end of scope for declared variables */
  luaK_patchtohere(fs, prep);
  endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
                     luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars);
  luaK_fixline(fs, line);  /* pretend that `OP_FOR' starts the loop */
  luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1);
}

As a second issue with the original patch, 'continuestat' does not take into account upvalue cleaning. Is it rightfully so, or should it now do that?



9.4.2005 kello 21:52, Asko Kauppi kirjoitti:


The old "continue patch" is for Lua 5.0 code. It covers three files, llex.h, llex.c, and lparser.c (where most of the fun is).

The change of for counter scope in >5.0 Lua makes me unaware, where exactly to place the patched line. Let's see:


This is the original Lua 5.0.2 portion (with patch addition marked):

static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
  BlockCnt bl;
  FuncState *fs = ls->fs;
  int prep, endfor;
  adjustlocalvars(ls, nvars);  /* scope for all variables */
  check(ls, TK_DO);
  enterblock(fs, &bl, 1);  /* loop block */
  prep = luaK_getlabel(fs);
  block(ls);
>>> luaK_patchtohere(fs, bl.continuelist);
  luaK_patchtohere(fs, prep-1);
  endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
                     luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars - 3);
  luaK_fixline(fs, line);  /* pretend that `OP_FOR' starts the loop */
  luaK_patchlist(fs, (isnum) ? endfor : luaK_jump(fs), prep);
  leaveblock(fs);
}


This is 5.1w4 'modern' portion with both A and B tried (but neither worked):

static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
  /* forbody -> DO block */
  BlockCnt bl;
  FuncState *fs = ls->fs;
  int prep, endfor;
  adjustlocalvars(ls, 3);  /* control variables */
  checknext(ls, TK_DO);
prep = luaK_codeAsBx(fs, (isnum ? OP_FORPREP : OP_TFORPREP), base, NO_JUMP);
  enterblock(fs, &bl, 0);  /* scope for declared variables */
  adjustlocalvars(ls, nvars);
  luaK_reserveregs(fs, nvars);
  block(ls);
>>> A: luaK_patchtohere(fs, bl.continuelist);
  leaveblock(fs);  /* end of scope for declared variables */
>>> B: luaK_patchtohere(fs, bl.continuelist);
  luaK_patchtohere(fs, prep);
  endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
                     luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars);
  luaK_fixline(fs, line);  /* pretend that `OP_FOR' starts the loop */
  luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1);
}

When 'continue' within a for loop is met, the execution goes into eternal loop (or so it seems..)

-ak