diff --git a/lcode.c b/lcode.c index 8786a721..c25226ab 100644 --- a/lcode.c +++ b/lcode.c @@ -208,8 +208,7 @@ void luaK_ret (FuncState *fs, int first, int nret) { case 1: op = OP_RETURN1; break; default: op = OP_RETURN; break; } - if (nret + 1 > MAXARG_B) - luaX_syntaxerror(fs->ls, "too many returns"); + luaY_checklimit(fs, nret + 1, MAXARG_B, "returns"); luaK_codeABC(fs, op, first, nret + 1, 0); } @@ -473,9 +472,7 @@ static int luaK_codek (FuncState *fs, int reg, int k) { void luaK_checkstack (FuncState *fs, int n) { int newstack = fs->freereg + n; if (newstack > fs->f->maxstacksize) { - if (newstack > MAX_FSTACK) - luaX_syntaxerror(fs->ls, - "function or expression needs too many registers"); + luaY_checklimit(fs, newstack, MAX_FSTACK, "registers"); fs->f->maxstacksize = cast_byte(newstack); } } @@ -727,8 +724,7 @@ static void const2exp (TValue *v, expdesc *e) { */ void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { Instruction *pc = &getinstruction(fs, e); - if (nresults + 1 > MAXARG_C) - luaX_syntaxerror(fs->ls, "too many multiple results"); + luaY_checklimit(fs, nresults + 1, MAXARG_C, "multiple results"); if (e->k == VCALL) /* expression is an open function call? */ SETARG_C(*pc, nresults + 1); else { diff --git a/lparser.c b/lparser.c index 452ab19e..b193b672 100644 --- a/lparser.c +++ b/lparser.c @@ -84,8 +84,8 @@ static l_noret errorlimit (FuncState *fs, int limit, const char *what) { } -static void checklimit (FuncState *fs, int v, int l, const char *what) { - if (v > l) errorlimit(fs, l, what); +void luaY_checklimit (FuncState *fs, int v, int l, const char *what) { + if (l_unlikely(v > l)) errorlimit(fs, l, what); } @@ -196,7 +196,7 @@ static int new_localvarkind (LexState *ls, TString *name, lu_byte kind) { FuncState *fs = ls->fs; Dyndata *dyd = ls->dyd; Vardesc *var; - checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, + luaY_checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, MAXVARS, "local variables"); luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1, dyd->actvar.size, Vardesc, USHRT_MAX, "local variables"); @@ -361,7 +361,7 @@ static int searchupvalue (FuncState *fs, TString *name) { static Upvaldesc *allocupvalue (FuncState *fs) { Proto *f = fs->f; int oldsize = f->sizeupvalues; - checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues"); + luaY_checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues"); luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues, Upvaldesc, MAXUPVAL, "upvalues"); while (oldsize < f->sizeupvalues) @@ -860,7 +860,7 @@ static void recfield (LexState *ls, ConsControl *cc) { lu_byte reg = ls->fs->freereg; expdesc tab, key, val; if (ls->t.token == TK_NAME) { - checklimit(fs, cc->nh, INT_MAX, "items in a constructor"); + luaY_checklimit(fs, cc->nh, INT_MAX / 2, "items in a constructor"); codename(ls, &key); } else /* ls->t.token == '[' */ diff --git a/lparser.h b/lparser.h index 535dc9da..8a87776d 100644 --- a/lparser.h +++ b/lparser.h @@ -164,6 +164,8 @@ typedef struct FuncState { LUAI_FUNC lu_byte luaY_nvarstack (FuncState *fs); +LUAI_FUNC void luaY_checklimit (FuncState *fs, int v, int l, + const char *what); LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, Dyndata *dyd, const char *name, int firstchar);