diff options
Diffstat (limited to 'libs/liblua/src/lparser.c')
-rw-r--r-- | libs/liblua/src/lparser.c | 66 |
1 files changed, 13 insertions, 53 deletions
diff --git a/libs/liblua/src/lparser.c b/libs/liblua/src/lparser.c index bc7d9a4f2d..77813a74e9 100644 --- a/libs/liblua/src/lparser.c +++ b/libs/liblua/src/lparser.c @@ -489,12 +489,10 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { } -/* -** Macros to limit the maximum recursion depth while parsing -*/ -#define enterlevel(ls) luaE_enterCcall((ls)->L) +#define enterlevel(ls) luaE_incCstack(ls->L) + -#define leavelevel(ls) luaE_exitCcall((ls)->L) +#define leavelevel(ls) ((ls)->L->nCcalls--) /* @@ -947,7 +945,7 @@ static void setvararg (FuncState *fs, int nparams) { static void parlist (LexState *ls) { - /* parlist -> [ param { ',' param } ] */ + /* parlist -> [ {NAME ','} (NAME | '...') ] */ FuncState *fs = ls->fs; Proto *f = fs->f; int nparams = 0; @@ -955,12 +953,12 @@ static void parlist (LexState *ls) { if (ls->t.token != ')') { /* is 'parlist' not empty? */ do { switch (ls->t.token) { - case TK_NAME: { /* param -> NAME */ + case TK_NAME: { new_localvar(ls, str_checkname(ls)); nparams++; break; } - case TK_DOTS: { /* param -> '...' */ + case TK_DOTS: { luaX_next(ls); isvararg = 1; break; @@ -1625,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); @@ -1686,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; @@ -1754,7 +1714,7 @@ static void checktoclose (LexState *ls, int level) { static void localstat (LexState *ls) { - /* stat -> LOCAL ATTRIB NAME {',' ATTRIB NAME} ['=' explist] */ + /* stat -> LOCAL NAME ATTRIB { ',' NAME ATTRIB } ['=' explist] */ FuncState *fs = ls->fs; int toclose = -1; /* index of to-be-closed variable (if any) */ Vardesc *var; /* last variable */ |