|
@@ -1623,59 +1623,21 @@ static void forstat (LexState *ls, int line) {
|
|
|
}
|
|
|
|
|
|
|
|
|
-/*
|
|
|
-** Check whether next instruction is a single jump (a 'break', a 'goto'
|
|
|
-** to a forward label, or a 'goto' to a backward label with no variable
|
|
|
-** to close). If so, set the name of the 'label' it is jumping to
|
|
|
-** ("break" for a 'break') or to where it is jumping to ('target') and
|
|
|
-** return true. If not a single jump, leave input unchanged, to be
|
|
|
-** handled as a regular statement.
|
|
|
-*/
|
|
|
-static int issinglejump (LexState *ls, TString **label, int *target) {
|
|
|
- if (testnext(ls, TK_BREAK)) { /* a break? */
|
|
|
- *label = luaS_newliteral(ls->L, "break");
|
|
|
- return 1;
|
|
|
- }
|
|
|
- else if (ls->t.token != TK_GOTO || luaX_lookahead(ls) != TK_NAME)
|
|
|
- return 0; /* not a valid goto */
|
|
|
- else {
|
|
|
- TString *lname = ls->lookahead.seminfo.ts; /* label's id */
|
|
|
- Labeldesc *lb = findlabel(ls, lname);
|
|
|
- if (lb) { /* a backward jump? */
|
|
|
- /* does it need to close variables? */
|
|
|
- if (luaY_nvarstack(ls->fs) > stacklevel(ls->fs, lb->nactvar))
|
|
|
- return 0; /* not a single jump; cannot optimize */
|
|
|
- *target = lb->pc;
|
|
|
- }
|
|
|
- else /* jump forward */
|
|
|
- *label = lname;
|
|
|
- luaX_next(ls); /* skip goto */
|
|
|
- luaX_next(ls); /* skip name */
|
|
|
- return 1;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
static void test_then_block (LexState *ls, int *escapelist) {
|
|
|
/* test_then_block -> [IF | ELSEIF] cond THEN block */
|
|
|
BlockCnt bl;
|
|
|
- int line;
|
|
|
FuncState *fs = ls->fs;
|
|
|
- TString *jlb = NULL;
|
|
|
- int target = NO_JUMP;
|
|
|
expdesc v;
|
|
|
int jf; /* instruction to skip 'then' code (if condition is false) */
|
|
|
luaX_next(ls); /* skip IF or ELSEIF */
|
|
|
expr(ls, &v); /* read condition */
|
|
|
checknext(ls, TK_THEN);
|
|
|
- line = ls->linenumber;
|
|
|
- if (issinglejump(ls, &jlb, &target)) { /* 'if x then goto' ? */
|
|
|
- luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */
|
|
|
+ if (ls->t.token == TK_BREAK) { /* 'if x then break' ? */
|
|
|
+ int line = ls->linenumber;
|
|
|
+ luaK_goiffalse(ls->fs, &v); /* will jump if condition is true */
|
|
|
+ luaX_next(ls); /* skip 'break' */
|
|
|
enterblock(fs, &bl, 0); /* must enter block before 'goto' */
|
|
|
- if (jlb != NULL) /* forward jump? */
|
|
|
- newgotoentry(ls, jlb, line, v.t); /* will be resolved later */
|
|
|
- else /* backward jump */
|
|
|
- luaK_patchlist(fs, v.t, target); /* jump directly to 'target' */
|
|
|
+ newgotoentry(ls, luaS_newliteral(ls->L, "break"), line, v.t);
|
|
|
while (testnext(ls, ';')) {} /* skip semicolons */
|
|
|
if (block_follow(ls, 0)) { /* jump is the entire block? */
|
|
|
leaveblock(fs);
|
|
@@ -1684,7 +1646,7 @@ static void test_then_block (LexState *ls, int *escapelist) {
|
|
|
else /* must skip over 'then' part if condition is false */
|
|
|
jf = luaK_jump(fs);
|
|
|
}
|
|
|
- else { /* regular case (not a jump) */
|
|
|
+ else { /* regular case (not a break) */
|
|
|
luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */
|
|
|
enterblock(fs, &bl, 0);
|
|
|
jf = v.f;
|