summaryrefslogtreecommitdiff
path: root/libs/liblua/src/lparser.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/liblua/src/lparser.c')
-rw-r--r--libs/liblua/src/lparser.c66
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 */