Beispiel #1
0
static void forbody (LexState *ls, int base, int line, int nvars, int isnum)
{
    /* forbody -> DO block */
    BlockCnt bl;
    FuncState *fs = GetCurrentFuncState( ls );

    adjustlocalvars(ls, 3);  /* control variables */

    checknext(ls, TK_DO);

    int prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs);

    enterblock(fs, &bl, 0);  /* scope for declared variables */

    adjustlocalvars(ls, nvars);
    luaK_reserveregs(fs, nvars);
    block(ls);

    leaveblock(fs);  /* end of scope for declared variables */

    luaK_patchtohere(fs, prep);

    int 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);
}
Beispiel #2
0
/*
** Create a jump instruction and return its position, so its destination
** can be fixed later (with 'fixjump'). If there are jumps to
** this position (kept in 'jpc'), link them all together so that
** 'patchlistaux' will fix all them directly to the final destination.
*/
int luaK_jump (FuncState *fs) {
  int jpc = fs->jpc;  /* save list of jumps to here */
  int j;
  fs->jpc = NO_JUMP;  /* no more jumps to here */
  j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
  luaK_concat(fs, &j, jpc);  /* keep them on hold */
  return j;
}
Beispiel #3
0
int FuncState::luaK_jump (/*FuncState *fs*/) {
	int jpc = this->jpc;  /* save list of jumps to here */
	int j;
	this->jpc = NO_JUMP;
	j = luaK_codeAsBx(OP_JMP, 0, NO_JUMP);
	luaK_concat(&j, jpc);  /* keep them on hold */
	return j;
}
Beispiel #4
0
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, 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);
}
Beispiel #5
0
static void forlist (LexState *ls, TString *indexname) {
  /* forlist -> NAME {,NAME} IN explist1 DO body */
  FuncState *fs = ls->fs;
  expdesc e;
  int nvars = 0;
  int line;
  int base = fs->freereg;
  new_localvarstr(ls, "(for generator)", nvars++);
  new_localvarstr(ls, "(for state)", nvars++);
  new_localvar(ls, indexname, nvars++);
  while (testnext(ls, ','))
    new_localvar(ls, str_checkname(ls), nvars++);
  check(ls, TK_IN);
  line = ls->linenumber;
  adjust_assign(ls, nvars, explist1(ls, &e), &e);
  luaK_checkstack(fs, 3);  /* extra space to call generator */
  luaK_codeAsBx(fs, OP_TFORPREP, base, NO_JUMP);
  forbody(ls, base, line, nvars, 0);
}
Beispiel #6
0
static void trystat (LexState *ls, int line) {
  /* trystat -> TRY block CATCH err DO block END */
  FuncState *fs = ls->fs;
  BlockCnt bl;
  int base, pc, escapelist = NO_JUMP;

  luaX_next(ls);

  enterblock(fs, &bl, 2);   /* try block */
  base = fs->freereg;
  new_localvarliteral(ls, "(error obj)", 0);
  adjustlocalvars(ls, 1);  /* error object */
  luaK_reserveregs(fs, 1);

  pc = luaK_codeAsBx(fs, OP_TRY, base, NO_JUMP);
  chunk(ls);

  if (ls->t.token == TK_CATCH) {
    TString *varname;
    int errobj;

    luaK_codeABC(fs, OP_EXITTRY, 0, 0, 0);
    luaK_concat(fs, &escapelist, luaK_jump(fs));
    SET_OPCODE(fs->f->code[pc], OP_TRYCATCH);   /* change it to TRYCATCH */
    luaK_patchtohere(fs, pc);
    bl.isbreakable = 0;

    // local err
    luaX_next(ls);  /* skip `catch' */
    varname = str_checkname(ls);  /* first variable name */

    // do
    checknext(ls, TK_DO);
    errobj = fs->freereg;
    new_localvar(ls, varname, 0);
    adjustlocalvars(ls, 1);
    luaK_reserveregs(fs, 1);
    luaK_codeABC(fs, OP_MOVE, errobj, base, 0);

    block(ls);

  } else if (ls->t.token == TK_FINALLY) {
    luaK_codeABC(fs, OP_EXITTRY, 0, 0, 0);
    luaK_concat(fs, &escapelist, luaK_jump(fs));
    SET_OPCODE(fs->f->code[pc], OP_TRYFIN);   /* change it to TRYFIN */
    luaK_patchtohere(fs, pc);
    bl.isbreakable = 3;

    luaX_next(ls);  /* skip 'finally' */

    block(ls);

    luaK_codeABC(fs, OP_RETFIN, base, 0, 0);  /* OP_ENDFIN jump to the return point */

  } else {
    luaK_codeABC(fs, OP_EXITTRY, 0, 0, 0);
    luaK_concat(fs, &escapelist, pc);
  }

  leaveblock(fs);

  luaK_patchtohere(fs, escapelist);
  check_match(ls, TK_END, TK_TRY, line);
}