From 2823f4df89f76152f934dabbfa70eba04f085f49 Mon Sep 17 00:00:00 2001 From: Allanis Date: Sun, 15 Dec 2013 00:46:43 +0000 Subject: [PATCH] [Change] Updated Lua API. --- lib/lua/LICENSE | 7 ++ lib/lua/lapi.c | 25 +++-- lib/lua/lapi.h | 2 +- lib/lua/lauxlib.c | 13 ++- lib/lua/lauxlib.h | 2 +- lib/lua/lbaselib.c | 88 ++++++++++-------- lib/lua/lcode.c | 4 +- lib/lua/lcode.h | 2 +- lib/lua/ldblib.c | 30 +++--- lib/lua/ldebug.c | 38 +++++--- lib/lua/ldebug.h | 2 +- lib/lua/ldo.c | 24 ++--- lib/lua/ldo.h | 2 +- lib/lua/ldump.c | 2 +- lib/lua/lfunc.c | 2 +- lib/lua/lfunc.h | 2 +- lib/lua/lgc.c | 2 +- lib/lua/lgc.h | 2 +- lib/lua/linit.c | 2 +- lib/lua/liolib.c | 69 +++++++++----- lib/lua/llex.c | 2 +- lib/lua/llex.h | 2 +- lib/lua/llimits.h | 2 +- lib/lua/lmathlib.c | 2 +- lib/lua/lmem.c | 2 +- lib/lua/lmem.h | 2 +- lib/lua/loadlib.c | 8 +- lib/lua/lobject.c | 2 +- lib/lua/lobject.h | 4 +- lib/lua/lopcodes.c | 2 +- lib/lua/lopcodes.h | 2 +- lib/lua/loslib.c | 3 +- lib/lua/lparser.c | 4 +- lib/lua/lparser.h | 2 +- lib/lua/lstate.c | 6 +- lib/lua/lstate.h | 3 +- lib/lua/lstring.c | 2 +- lib/lua/lstring.h | 2 +- lib/lua/lstrlib.c | 13 +-- lib/lua/ltable.c | 6 +- lib/lua/ltable.h | 2 +- lib/lua/ltablib.c | 25 +++-- lib/lua/ltm.c | 2 +- lib/lua/ltm.h | 2 +- lib/lua/lua.c | 6 +- lib/lua/lua.h | 11 ++- lib/lua/luaconf.h | 9 +- lib/lua/lualib.h | 2 +- lib/lua/lundump.c | 12 ++- lib/lua/lundump.h | 2 +- lib/lua/lvm.c | 10 +- lib/lua/lvm.h | 2 +- lib/lua/lzio.c | 2 +- lib/lua/lzio.h | 2 +- lib/lua/print.c | 227 +++++++++++++++++++++++++++++++++++++++++++++ 55 files changed, 509 insertions(+), 198 deletions(-) create mode 100644 lib/lua/LICENSE create mode 100644 lib/lua/print.c diff --git a/lib/lua/LICENSE b/lib/lua/LICENSE new file mode 100644 index 0000000..3472ac6 --- /dev/null +++ b/lib/lua/LICENSE @@ -0,0 +1,7 @@ +Copyright © 1994-2007 Lua.org, PUC-Rio. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/lib/lua/lapi.c b/lib/lua/lapi.c index 7c532b8..5d5145d 100644 --- a/lib/lua/lapi.c +++ b/lib/lua/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 2.55 2006/06/07 12:37:17 roberto Exp $ +** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $ ** Lua API ** See Copyright Notice in lua.h */ @@ -93,15 +93,14 @@ void luaA_pushobject (lua_State *L, const TValue *o) { LUA_API int lua_checkstack (lua_State *L, int size) { - int res; + int res = 1; lua_lock(L); - if ((L->top - L->base + size) > LUAI_MAXCSTACK) + if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) res = 0; /* stack overflow */ - else { + else if (size > 0) { luaD_checkstack(L, size); if (L->ci->top < L->top + size) L->ci->top = L->top + size; - res = 1; } lua_unlock(L); return res; @@ -123,6 +122,11 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { } +LUA_API void lua_setlevel (lua_State *from, lua_State *to) { + to->nCcalls = from->nCcalls; +} + + LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { lua_CFunction old; lua_lock(L); @@ -749,7 +753,7 @@ LUA_API int lua_setfenv (lua_State *L, int idx) { res = 0; break; } - luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); + if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); L->top--; lua_unlock(L); return res; @@ -925,10 +929,13 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { g->GCthreshold = g->totalbytes - a; else g->GCthreshold = 0; - while (g->GCthreshold <= g->totalbytes) + while (g->GCthreshold <= g->totalbytes) { luaC_step(L); - if (g->gcstate == GCSpause) /* end of cycle? */ - res = 1; /* signal it */ + if (g->gcstate == GCSpause) { /* end of cycle? */ + res = 1; /* signal it */ + break; + } + } break; } case LUA_GCSETPAUSE: { diff --git a/lib/lua/lapi.h b/lib/lua/lapi.h index 9d1d435..2c3fab2 100644 --- a/lib/lua/lapi.h +++ b/lib/lua/lapi.h @@ -1,5 +1,5 @@ /* -** $Id: lapi.h,v 2.2 2005/04/25 19:24:10 roberto Exp $ +** $Id: lapi.h,v 2.2.1.1 2007/12/27 13:02:25 roberto Exp $ ** Auxiliary functions from Lua API ** See Copyright Notice in lua.h */ diff --git a/lib/lua/lauxlib.c b/lib/lua/lauxlib.c index 96a6b85..10f14e2 100644 --- a/lib/lua/lauxlib.c +++ b/lib/lua/lauxlib.c @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.c,v 1.159 2006/03/21 19:31:09 roberto Exp $ +** $Id: lauxlib.c,v 1.159.1.3 2008/01/21 13:20:51 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -244,7 +244,7 @@ LUALIB_API void luaI_openlib (lua_State *L, const char *libname, if (libname) { int size = libsize(l); /* check whether lib already exists */ - luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", size); + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); lua_getfield(L, -1, libname); /* get _LOADED[libname] */ if (!lua_istable(L, -1)) { /* not found? */ lua_pop(L, 1); /* remove previous result */ @@ -535,7 +535,7 @@ static const char *getF (lua_State *L, void *ud, size_t *size) { return "\n"; } if (feof(lf->f)) return NULL; - *size = fread(lf->buff, 1, LUAL_BUFFERSIZE, lf->f); + *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); return (*size > 0) ? lf->buff : NULL; } @@ -570,9 +570,8 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */ if (c == '\n') c = getc(lf.f); } - if (c == LUA_SIGNATURE[0] && lf.f != stdin) { /* binary file? */ - fclose(lf.f); - lf.f = fopen(filename, "rb"); /* reopen in binary mode */ + if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ + lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ if (lf.f == NULL) return errfile(L, "reopen", fnameindex); /* skip eventual `#!...' */ while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ; @@ -581,7 +580,7 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { ungetc(c, lf.f); status = lua_load(L, getF, &lf, lua_tostring(L, -1)); readstatus = ferror(lf.f); - if (lf.f != stdin) fclose(lf.f); /* close file (even in case of errors) */ + if (filename) fclose(lf.f); /* close file (even in case of errors) */ if (readstatus) { lua_settop(L, fnameindex); /* ignore results from `lua_load' */ return errfile(L, "read", fnameindex); diff --git a/lib/lua/lauxlib.h b/lib/lua/lauxlib.h index 1f34308..3425823 100644 --- a/lib/lua/lauxlib.h +++ b/lib/lua/lauxlib.h @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.h,v 1.88 2006/04/12 20:31:15 roberto Exp $ +** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ diff --git a/lib/lua/lbaselib.c b/lib/lua/lbaselib.c index 147a727..2a4c079 100644 --- a/lib/lua/lbaselib.c +++ b/lib/lua/lbaselib.c @@ -1,5 +1,5 @@ /* -** $Id: lbaselib.c,v 1.191a 2006/06/02 15:34:00 roberto Exp $ +** $Id: lbaselib.c,v 1.191.1.6 2008/02/14 16:46:22 roberto Exp $ ** Basic library ** See Copyright Notice in lua.h */ @@ -344,10 +344,12 @@ static int luaB_unpack (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); i = luaL_optint(L, 2, 1); e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1)); + if (i > e) return 0; /* empty range */ n = e - i + 1; /* number of elements */ - if (n <= 0) return 0; /* empty range */ - luaL_checkstack(L, n, "table too big to unpack"); - for (; i<=e; i++) /* push arg[i...e] */ + if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ + return luaL_error(L, "too many results to unpack"); + lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ + while (i++ < e) /* push arg[i + 1...e] */ lua_rawgeti(L, 1, i); return n; } @@ -477,19 +479,56 @@ static const luaL_Reg base_funcs[] = { ** ======================================================= */ +#define CO_RUN 0 /* running */ +#define CO_SUS 1 /* suspended */ +#define CO_NOR 2 /* 'normal' (it resumed another coroutine) */ +#define CO_DEAD 3 + +static const char *const statnames[] = + {"running", "suspended", "normal", "dead"}; + +static int costatus (lua_State *L, lua_State *co) { + if (L == co) return CO_RUN; + switch (lua_status(co)) { + case LUA_YIELD: + return CO_SUS; + case 0: { + lua_Debug ar; + if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ + return CO_NOR; /* it is running */ + else if (lua_gettop(co) == 0) + return CO_DEAD; + else + return CO_SUS; /* initial state */ + } + default: /* some error occured */ + return CO_DEAD; + } +} + + +static int luaB_costatus (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + luaL_argcheck(L, co, 1, "coroutine expected"); + lua_pushstring(L, statnames[costatus(L, co)]); + return 1; +} + + static int auxresume (lua_State *L, lua_State *co, int narg) { - int status; + int status = costatus(L, co); if (!lua_checkstack(co, narg)) luaL_error(L, "too many arguments to resume"); - if (lua_status(co) == 0 && lua_gettop(co) == 0) { - lua_pushliteral(L, "cannot resume dead coroutine"); + if (status != CO_SUS) { + lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]); return -1; /* error flag */ } lua_xmove(L, co, narg); + lua_setlevel(L, co); status = lua_resume(co, narg); if (status == 0 || status == LUA_YIELD) { int nres = lua_gettop(co); - if (!lua_checkstack(L, nres)) + if (!lua_checkstack(L, nres + 1)) luaL_error(L, "too many results to resume"); lua_xmove(co, L, nres); /* move yielded values */ return nres; @@ -556,39 +595,10 @@ static int luaB_yield (lua_State *L) { } -static int luaB_costatus (lua_State *L) { - lua_State *co = lua_tothread(L, 1); - luaL_argcheck(L, co, 1, "coroutine expected"); - if (L == co) lua_pushliteral(L, "running"); - else { - switch (lua_status(co)) { - case LUA_YIELD: - lua_pushliteral(L, "suspended"); - break; - case 0: { - lua_Debug ar; - if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ - lua_pushliteral(L, "normal"); /* it is running */ - else if (lua_gettop(co) == 0) - lua_pushliteral(L, "dead"); - else - lua_pushliteral(L, "suspended"); /* initial state */ - break; - } - default: /* some error occured */ - lua_pushliteral(L, "dead"); - break; - } - } - return 1; -} - - static int luaB_corunning (lua_State *L) { if (lua_pushthread(L)) - return 0; /* main thread is not a coroutine */ - else - return 1; + lua_pushnil(L); /* main thread is not a coroutine */ + return 1; } diff --git a/lib/lua/lcode.c b/lib/lua/lcode.c index 9ce515a..cff626b 100644 --- a/lib/lua/lcode.c +++ b/lib/lua/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 2.25a 2006/03/21 19:28:49 roberto Exp $ +** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -699,7 +699,7 @@ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; switch (op) { case OPR_MINUS: { - if (e->k == VK) + if (!isnumeral(e)) luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */ codearith(fs, OP_UNM, e, &e2); break; diff --git a/lib/lua/lcode.h b/lib/lua/lcode.h index c02cb2b..b941c60 100644 --- a/lib/lua/lcode.h +++ b/lib/lua/lcode.h @@ -1,5 +1,5 @@ /* -** $Id: lcode.h,v 1.48 2006/03/21 19:28:03 roberto Exp $ +** $Id: lcode.h,v 1.48.1.1 2007/12/27 13:02:25 roberto Exp $ ** Code generator for Lua ** See Copyright Notice in lua.h */ diff --git a/lib/lua/ldblib.c b/lib/lua/ldblib.c index 26a19b6..67de122 100644 --- a/lib/lua/ldblib.c +++ b/lib/lua/ldblib.c @@ -1,5 +1,5 @@ /* -** $Id: ldblib.c,v 1.104 2005/12/29 15:32:11 roberto Exp $ +** $Id: ldblib.c,v 1.104.1.3 2008/01/21 13:11:21 roberto Exp $ ** Interface from Lua to its debug API ** See Copyright Notice in lua.h */ @@ -255,24 +255,25 @@ static void gethooktable (lua_State *L) { static int db_sethook (lua_State *L) { - int arg; + int arg, mask, count; + lua_Hook func; lua_State *L1 = getthread(L, &arg); if (lua_isnoneornil(L, arg+1)) { lua_settop(L, arg+1); - lua_sethook(L1, NULL, 0, 0); /* turn off hooks */ + func = NULL; mask = 0; count = 0; /* turn off hooks */ } else { const char *smask = luaL_checkstring(L, arg+2); - int count = luaL_optint(L, arg+3, 0); luaL_checktype(L, arg+1, LUA_TFUNCTION); - lua_sethook(L1, hookf, makemask(smask, count), count); + count = luaL_optint(L, arg+3, 0); + func = hookf; mask = makemask(smask, count); } - gethooktable(L1); - lua_pushlightuserdata(L1, L1); + gethooktable(L); + lua_pushlightuserdata(L, L1); lua_pushvalue(L, arg+1); - lua_xmove(L, L1, 1); - lua_rawset(L1, -3); /* set new hook */ - lua_pop(L1, 1); /* remove hook table */ + lua_rawset(L, -3); /* set new hook */ + lua_pop(L, 1); /* remove hook table */ + lua_sethook(L1, func, mask, count); /* set hooks */ return 0; } @@ -286,11 +287,10 @@ static int db_gethook (lua_State *L) { if (hook != NULL && hook != hookf) /* external hook? */ lua_pushliteral(L, "external hook"); else { - gethooktable(L1); - lua_pushlightuserdata(L1, L1); - lua_rawget(L1, -2); /* get hook */ - lua_remove(L1, -2); /* remove hook table */ - lua_xmove(L1, L, 1); + gethooktable(L); + lua_pushlightuserdata(L, L1); + lua_rawget(L, -2); /* get hook */ + lua_remove(L, -2); /* remove hook table */ } lua_pushstring(L, unmakemask(mask, buff)); lua_pushinteger(L, lua_gethookcount(L1)); diff --git a/lib/lua/ldebug.c b/lib/lua/ldebug.c index 9c8bdf2..50ad3d3 100644 --- a/lib/lua/ldebug.c +++ b/lib/lua/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 2.29a 2005/12/22 16:19:56 roberto Exp $ +** $Id: ldebug.c,v 2.29.1.6 2008/05/08 16:56:26 roberto Exp $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -275,12 +275,12 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { static int precheck (const Proto *pt) { check(pt->maxstacksize <= MAXSTACK); - lua_assert(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize); - lua_assert(!(pt->is_vararg & VARARG_NEEDSARG) || + check(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize); + check(!(pt->is_vararg & VARARG_NEEDSARG) || (pt->is_vararg & VARARG_HASARG)); check(pt->sizeupvalues <= pt->nups); check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0); - check(GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); + check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); return 1; } @@ -346,9 +346,18 @@ static Instruction symbexec (const Proto *pt, int lastpc, int reg) { int dest = pc+1+b; check(0 <= dest && dest < pt->sizecode); if (dest > 0) { - /* cannot jump to a setlist count */ - Instruction d = pt->code[dest-1]; - check(!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)); + int j; + /* check that it does not jump to a setlist count; this + is tricky, because the count from a previous setlist may + have the same value of an invalid setlist; so, we must + go all the way back to the first of them (if any) */ + for (j = 0; j < dest; j++) { + Instruction d = pt->code[dest-1-j]; + if (!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)) break; + } + /* if 'j' is even, previous value is not a setlist (even if + it looks like one) */ + check((j&1) == 0); } } break; @@ -363,7 +372,11 @@ static Instruction symbexec (const Proto *pt, int lastpc, int reg) { } switch (op) { case OP_LOADBOOL: { - check(c == 0 || pc+2 < pt->sizecode); /* check its jump */ + if (c == 1) { /* does it jump? */ + check(pc+2 < pt->sizecode); /* check its jump */ + check(GET_OPCODE(pt->code[pc+1]) != OP_SETLIST || + GETARG_C(pt->code[pc+1]) != 0); + } break; } case OP_LOADNIL: { @@ -428,7 +441,10 @@ static Instruction symbexec (const Proto *pt, int lastpc, int reg) { } case OP_SETLIST: { if (b > 0) checkreg(pt, a + b); - if (c == 0) pc++; + if (c == 0) { + pc++; + check(pc < pt->sizecode - 1); + } break; } case OP_CLOSURE: { @@ -563,8 +579,8 @@ void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { void luaG_concaterror (lua_State *L, StkId p1, StkId p2) { - if (ttisstring(p1)) p1 = p2; - lua_assert(!ttisstring(p1)); + if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; + lua_assert(!ttisstring(p1) && !ttisnumber(p1)); luaG_typeerror(L, p1, "concatenate"); } diff --git a/lib/lua/ldebug.h b/lib/lua/ldebug.h index 9c76aa1..ba28a97 100644 --- a/lib/lua/ldebug.h +++ b/lib/lua/ldebug.h @@ -1,5 +1,5 @@ /* -** $Id: ldebug.h,v 2.3 2005/04/25 19:24:10 roberto Exp $ +** $Id: ldebug.h,v 2.3.1.1 2007/12/27 13:02:25 roberto Exp $ ** Auxiliary functions from Debug Interface module ** See Copyright Notice in lua.h */ diff --git a/lib/lua/ldo.c b/lib/lua/ldo.c index ab86fb7..8de05f7 100644 --- a/lib/lua/ldo.c +++ b/lib/lua/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 2.38 2006/06/05 19:36:14 roberto Exp $ +** $Id: ldo.c,v 2.38.1.3 2008/01/18 22:31:22 roberto Exp $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -83,7 +83,7 @@ static void resetstack (lua_State *L, int status) { L->base = L->ci->base; luaF_close(L, L->base); /* close eventual pending closures */ luaD_seterrorobj(L, status, L->base); - L->nCcalls = 0; + L->nCcalls = L->baseCcalls; L->allowhook = 1; restore_stack_limit(L); L->errfunc = 0; @@ -332,7 +332,7 @@ static StkId callrethooks (lua_State *L, StkId firstResult) { ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ luaD_callhook(L, LUA_HOOKRET, -1); if (f_isLua(L->ci)) { /* Lua function? */ - while (L->ci->tailcalls--) /* call hook for eventual tail calls */ + while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */ luaD_callhook(L, LUA_HOOKTAILRET, -1); } return restorestack(L, fr); @@ -417,22 +417,24 @@ static int resume_error (lua_State *L, const char *msg) { LUA_API int lua_resume (lua_State *L, int nargs) { int status; lua_lock(L); - if (L->status != LUA_YIELD) { - if (L->status != 0) - return resume_error(L, "cannot resume dead coroutine"); - else if (L->ci != L->base_ci) + if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci)) return resume_error(L, "cannot resume non-suspended coroutine"); - } + if (L->nCcalls >= LUAI_MAXCCALLS) + return resume_error(L, "C stack overflow"); luai_userstateresume(L, nargs); - lua_assert(L->errfunc == 0 && L->nCcalls == 0); + lua_assert(L->errfunc == 0); + L->baseCcalls = ++L->nCcalls; status = luaD_rawrunprotected(L, resume, L->top - nargs); if (status != 0) { /* error? */ L->status = cast_byte(status); /* mark thread as `dead' */ luaD_seterrorobj(L, status, L->top); L->ci->top = L->top; } - else + else { + lua_assert(L->nCcalls == L->baseCcalls); status = L->status; + } + --L->nCcalls; lua_unlock(L); return status; } @@ -441,7 +443,7 @@ LUA_API int lua_resume (lua_State *L, int nargs) { LUA_API int lua_yield (lua_State *L, int nresults) { luai_userstateyield(L, nresults); lua_lock(L); - if (L->nCcalls > 0) + if (L->nCcalls > L->baseCcalls) luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); L->base = L->top - nresults; /* protect stack slots below */ L->status = LUA_YIELD; diff --git a/lib/lua/ldo.h b/lib/lua/ldo.h index b2de92b..98fddac 100644 --- a/lib/lua/ldo.h +++ b/lib/lua/ldo.h @@ -1,5 +1,5 @@ /* -** $Id: ldo.h,v 2.7 2005/08/24 16:15:49 roberto Exp $ +** $Id: ldo.h,v 2.7.1.1 2007/12/27 13:02:25 roberto Exp $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ diff --git a/lib/lua/ldump.c b/lib/lua/ldump.c index f08277d..c9d3d48 100644 --- a/lib/lua/ldump.c +++ b/lib/lua/ldump.c @@ -1,5 +1,5 @@ /* -** $Id: ldump.c,v 1.15 2006/02/16 15:53:49 lhf Exp $ +** $Id: ldump.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ ** save precompiled Lua chunks ** See Copyright Notice in lua.h */ diff --git a/lib/lua/lfunc.c b/lib/lua/lfunc.c index 05bd5ff..813e88f 100644 --- a/lib/lua/lfunc.c +++ b/lib/lua/lfunc.c @@ -1,5 +1,5 @@ /* -** $Id: lfunc.c,v 2.12a 2005/12/22 16:19:56 roberto Exp $ +** $Id: lfunc.c,v 2.12.1.2 2007/12/28 14:58:43 roberto Exp $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ diff --git a/lib/lua/lfunc.h b/lib/lua/lfunc.h index 2e02419..a68cf51 100644 --- a/lib/lua/lfunc.h +++ b/lib/lua/lfunc.h @@ -1,5 +1,5 @@ /* -** $Id: lfunc.h,v 2.4 2005/04/25 19:24:10 roberto Exp $ +** $Id: lfunc.h,v 2.4.1.1 2007/12/27 13:02:25 roberto Exp $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ diff --git a/lib/lua/lgc.c b/lib/lua/lgc.c index 2d24a12..d9e0b78 100644 --- a/lib/lua/lgc.c +++ b/lib/lua/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.38 2006/05/24 14:34:06 roberto Exp $ +** $Id: lgc.c,v 2.38.1.1 2007/12/27 13:02:25 roberto Exp $ ** Garbage Collector ** See Copyright Notice in lua.h */ diff --git a/lib/lua/lgc.h b/lib/lua/lgc.h index 5f69acb..5a8dc60 100644 --- a/lib/lua/lgc.h +++ b/lib/lua/lgc.h @@ -1,5 +1,5 @@ /* -** $Id: lgc.h,v 2.15 2005/08/24 16:15:49 roberto Exp $ +** $Id: lgc.h,v 2.15.1.1 2007/12/27 13:02:25 roberto Exp $ ** Garbage Collector ** See Copyright Notice in lua.h */ diff --git a/lib/lua/linit.c b/lib/lua/linit.c index 483d9c8..c1f90df 100644 --- a/lib/lua/linit.c +++ b/lib/lua/linit.c @@ -1,5 +1,5 @@ /* -** $Id: linit.c,v 1.14 2005/12/29 15:32:11 roberto Exp $ +** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $ ** Initialization of libraries for lua.c ** See Copyright Notice in lua.h */ diff --git a/lib/lua/liolib.c b/lib/lua/liolib.c index be60972..e79ed1c 100644 --- a/lib/lua/liolib.c +++ b/lib/lua/liolib.c @@ -1,5 +1,5 @@ /* -** $Id: liolib.c,v 2.73 2006/05/08 20:14:16 roberto Exp $ +** $Id: liolib.c,v 2.73.1.3 2008/01/18 17:47:43 roberto Exp $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ @@ -51,7 +51,7 @@ static void fileerror (lua_State *L, int arg, const char *filename) { } -#define topfile(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE)) +#define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE)) static int io_type (lua_State *L) { @@ -70,7 +70,7 @@ static int io_type (lua_State *L) { static FILE *tofile (lua_State *L) { - FILE **f = topfile(L); + FILE **f = tofilep(L); if (*f == NULL) luaL_error(L, "attempt to use a closed file"); return *f; @@ -93,19 +93,31 @@ static FILE **newfile (lua_State *L) { /* -** this function has a separated environment, which defines the -** correct __close for 'popen' files +** function to (not) close the standard files stdin, stdout, and stderr +*/ +static int io_noclose (lua_State *L) { + lua_pushnil(L); + lua_pushliteral(L, "cannot close standard file"); + return 2; +} + + +/* +** function to close 'popen' files */ static int io_pclose (lua_State *L) { - FILE **p = topfile(L); + FILE **p = tofilep(L); int ok = lua_pclose(L, *p); *p = NULL; return pushresult(L, ok, NULL); } +/* +** function to close regular files +*/ static int io_fclose (lua_State *L) { - FILE **p = topfile(L); + FILE **p = tofilep(L); int ok = (fclose(*p) == 0); *p = NULL; return pushresult(L, ok, NULL); @@ -128,18 +140,18 @@ static int io_close (lua_State *L) { static int io_gc (lua_State *L) { - FILE *f = *topfile(L); - /* ignore closed files and standard files */ - if (f != NULL && f != stdin && f != stdout && f != stderr) + FILE *f = *tofilep(L); + /* ignore closed files */ + if (f != NULL) aux_close(L); return 0; } static int io_tostring (lua_State *L) { - FILE *f = *topfile(L); + FILE *f = *tofilep(L); if (f == NULL) - lua_pushstring(L, "file (closed)"); + lua_pushliteral(L, "file (closed)"); else lua_pushfstring(L, "file (%p)", f); return 1; @@ -155,6 +167,10 @@ static int io_open (lua_State *L) { } +/* +** this function has a separated environment, which defines the +** correct __close for 'popen' files +*/ static int io_popen (lua_State *L) { const char *filename = luaL_checkstring(L, 1); const char *mode = luaL_optstring(L, 2, "r"); @@ -280,7 +296,7 @@ static int read_line (lua_State *L, FILE *f) { char *p = luaL_prepbuffer(&b); if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ luaL_pushresult(&b); /* close buffer */ - return (lua_strlen(L, -1) > 0); /* check whether read something */ + return (lua_objlen(L, -1) > 0); /* check whether read something */ } l = strlen(p); if (l == 0 || p[l-1] != '\n') @@ -308,7 +324,7 @@ static int read_chars (lua_State *L, FILE *f, size_t n) { n -= nr; /* still have to read `n' chars */ } while (n > 0 && nr == rlen); /* until end of count or eof */ luaL_pushresult(&b); /* close buffer */ - return (n == 0 || lua_strlen(L, -1) > 0); + return (n == 0 || lua_objlen(L, -1) > 0); } @@ -502,31 +518,36 @@ static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) { lua_pushvalue(L, -1); lua_rawseti(L, LUA_ENVIRONINDEX, k); } - lua_setfield(L, -2, fname); + lua_pushvalue(L, -2); /* copy environment */ + lua_setfenv(L, -2); /* set it */ + lua_setfield(L, -3, fname); +} + + +static void newfenv (lua_State *L, lua_CFunction cls) { + lua_createtable(L, 0, 1); + lua_pushcfunction(L, cls); + lua_setfield(L, -2, "__close"); } LUALIB_API int luaopen_io (lua_State *L) { createmeta(L); /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */ - lua_createtable(L, 2, 1); + newfenv(L, io_fclose); lua_replace(L, LUA_ENVIRONINDEX); /* open library */ luaL_register(L, LUA_IOLIBNAME, iolib); /* create (and set) default files */ + newfenv(L, io_noclose); /* close function for default files */ createstdfile(L, stdin, IO_INPUT, "stdin"); createstdfile(L, stdout, IO_OUTPUT, "stdout"); createstdfile(L, stderr, 0, "stderr"); - /* create environment for 'popen' */ + lua_pop(L, 1); /* pop environment for default files */ lua_getfield(L, -1, "popen"); - lua_createtable(L, 0, 1); - lua_pushcfunction(L, io_pclose); - lua_setfield(L, -2, "__close"); - lua_setfenv(L, -2); + newfenv(L, io_pclose); /* create environment for 'popen' */ + lua_setfenv(L, -2); /* set fenv for 'popen' */ lua_pop(L, 1); /* pop 'popen' */ - /* set default close function */ - lua_pushcfunction(L, io_fclose); - lua_setfield(L, LUA_ENVIRONINDEX, "__close"); return 1; } diff --git a/lib/lua/llex.c b/lib/lua/llex.c index 1c07cad..6dc3193 100644 --- a/lib/lua/llex.c +++ b/lib/lua/llex.c @@ -1,5 +1,5 @@ /* -** $Id: llex.c,v 2.20 2006/03/09 18:14:31 roberto Exp $ +** $Id: llex.c,v 2.20.1.1 2007/12/27 13:02:25 roberto Exp $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ diff --git a/lib/lua/llex.h b/lib/lua/llex.h index ff07e83..a9201ce 100644 --- a/lib/lua/llex.h +++ b/lib/lua/llex.h @@ -1,5 +1,5 @@ /* -** $Id: llex.h,v 1.58 2006/03/23 18:23:32 roberto Exp $ +** $Id: llex.h,v 1.58.1.1 2007/12/27 13:02:25 roberto Exp $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ diff --git a/lib/lua/llimits.h b/lib/lua/llimits.h index b03221a..ca8dcb7 100644 --- a/lib/lua/llimits.h +++ b/lib/lua/llimits.h @@ -1,5 +1,5 @@ /* -** $Id: llimits.h,v 1.69 2005/12/27 17:12:00 roberto Exp $ +** $Id: llimits.h,v 1.69.1.1 2007/12/27 13:02:25 roberto Exp $ ** Limits, basic types, and some other `installation-dependent' definitions ** See Copyright Notice in lua.h */ diff --git a/lib/lua/lmathlib.c b/lib/lua/lmathlib.c index d181a73..441fbf7 100644 --- a/lib/lua/lmathlib.c +++ b/lib/lua/lmathlib.c @@ -1,5 +1,5 @@ /* -** $Id: lmathlib.c,v 1.67 2005/08/26 17:36:32 roberto Exp $ +** $Id: lmathlib.c,v 1.67.1.1 2007/12/27 13:02:25 roberto Exp $ ** Standard mathematical library ** See Copyright Notice in lua.h */ diff --git a/lib/lua/lmem.c b/lib/lua/lmem.c index cef2bc5..ae7d8c9 100644 --- a/lib/lua/lmem.c +++ b/lib/lua/lmem.c @@ -1,5 +1,5 @@ /* -** $Id: lmem.c,v 1.70 2005/12/26 13:35:47 roberto Exp $ +** $Id: lmem.c,v 1.70.1.1 2007/12/27 13:02:25 roberto Exp $ ** Interface to Memory Manager ** See Copyright Notice in lua.h */ diff --git a/lib/lua/lmem.h b/lib/lua/lmem.h index 19df1fb..7c2dcb3 100644 --- a/lib/lua/lmem.h +++ b/lib/lua/lmem.h @@ -1,5 +1,5 @@ /* -** $Id: lmem.h,v 1.31 2005/04/25 19:24:10 roberto Exp $ +** $Id: lmem.h,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ ** Interface to Memory Manager ** See Copyright Notice in lua.h */ diff --git a/lib/lua/loadlib.c b/lib/lua/loadlib.c index 808368b..0d401eb 100644 --- a/lib/lua/loadlib.c +++ b/lib/lua/loadlib.c @@ -1,5 +1,5 @@ /* -** $Id: loadlib.c,v 1.54a 2006/07/03 20:16:49 roberto Exp $ +** $Id: loadlib.c,v 1.52.1.3 2008/08/06 13:29:28 roberto Exp $ ** Dynamic library loader for Lua ** See Copyright Notice in lua.h ** @@ -506,8 +506,10 @@ static int ll_require (lua_State *L) { static void setfenv (lua_State *L) { lua_Debug ar; - lua_getstack(L, 1, &ar); - lua_getinfo(L, "f", &ar); + if (lua_getstack(L, 1, &ar) == 0 || + lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ + lua_iscfunction(L, -1)) + luaL_error(L, LUA_QL("module") " not called from a Lua function"); lua_pushvalue(L, -2); lua_setfenv(L, -2); lua_pop(L, 1); diff --git a/lib/lua/lobject.c b/lib/lua/lobject.c index acde82c..4ff5073 100644 --- a/lib/lua/lobject.c +++ b/lib/lua/lobject.c @@ -1,5 +1,5 @@ /* -** $Id: lobject.c,v 2.22 2006/02/10 17:43:52 roberto Exp $ +** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $ ** Some generic functions over Lua objects ** See Copyright Notice in lua.h */ diff --git a/lib/lua/lobject.h b/lib/lua/lobject.h index 8ce4405..f1e447e 100644 --- a/lib/lua/lobject.h +++ b/lib/lua/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 2.20 2006/01/18 11:37:34 roberto Exp $ +** $Id: lobject.h,v 2.20.1.2 2008/08/06 13:29:48 roberto Exp $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -208,7 +208,7 @@ typedef union TString { #define getstr(ts) cast(const char *, (ts) + 1) -#define svalue(o) getstr(tsvalue(o)) +#define svalue(o) getstr(rawtsvalue(o)) diff --git a/lib/lua/lopcodes.c b/lib/lua/lopcodes.c index bf9cd52..4cc7452 100644 --- a/lib/lua/lopcodes.c +++ b/lib/lua/lopcodes.c @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.c,v 1.37 2005/11/08 19:45:36 roberto Exp $ +** $Id: lopcodes.c,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ ** See Copyright Notice in lua.h */ diff --git a/lib/lua/lopcodes.h b/lib/lua/lopcodes.h index 48105f1..41224d6 100644 --- a/lib/lua/lopcodes.h +++ b/lib/lua/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.125 2006/03/14 19:04:44 roberto Exp $ +** $Id: lopcodes.h,v 1.125.1.1 2007/12/27 13:02:25 roberto Exp $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ diff --git a/lib/lua/loslib.c b/lib/lua/loslib.c index fdda474..da06a57 100644 --- a/lib/lua/loslib.c +++ b/lib/lua/loslib.c @@ -1,5 +1,5 @@ /* -** $Id: loslib.c,v 1.20 2006/09/19 13:57:08 roberto Exp $ +** $Id: loslib.c,v 1.19.1.3 2008/01/18 16:38:18 roberto Exp $ ** Standard Operating System library ** See Copyright Notice in lua.h */ @@ -215,7 +215,6 @@ static int os_setlocale (lua_State *L) { static int os_exit (lua_State *L) { exit(luaL_optint(L, 1, EXIT_SUCCESS)); - return 0; /* to avoid warnings */ } static const luaL_Reg syslib[] = { diff --git a/lib/lua/lparser.c b/lib/lua/lparser.c index 6c473c4..1e2a9a8 100644 --- a/lib/lua/lparser.c +++ b/lib/lua/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 2.42a 2006/06/05 15:57:59 roberto Exp $ +** $Id: lparser.c,v 2.42.1.3 2007/12/28 15:32:23 roberto Exp $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -938,6 +938,8 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { primaryexp(ls, &nv.v); if (nv.v.k == VLOCAL) check_conflict(ls, lh, &nv.v); + luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls, + "variables in assignment"); assignment(ls, &nv, nvars+1); } else { /* assignment -> `=' explist1 */ diff --git a/lib/lua/lparser.h b/lib/lua/lparser.h index e5b5b57..18836af 100644 --- a/lib/lua/lparser.h +++ b/lib/lua/lparser.h @@ -1,5 +1,5 @@ /* -** $Id: lparser.h,v 1.57 2006/03/09 18:14:31 roberto Exp $ +** $Id: lparser.h,v 1.57.1.1 2007/12/27 13:02:25 roberto Exp $ ** Lua Parser ** See Copyright Notice in lua.h */ diff --git a/lib/lua/lstate.c b/lib/lua/lstate.c index 4bcb759..4313b83 100644 --- a/lib/lua/lstate.c +++ b/lib/lua/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 2.36 2006/05/24 14:15:50 roberto Exp $ +** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $ ** Global State ** See Copyright Notice in lua.h */ @@ -93,7 +93,7 @@ static void preinit_state (lua_State *L, global_State *g) { resethookcount(L); L->openupval = NULL; L->size_ci = 0; - L->nCcalls = 0; + L->nCcalls = L->baseCcalls = 0; L->status = 0; L->base_ci = L->ci = NULL; L->savedpc = NULL; @@ -205,7 +205,7 @@ LUA_API void lua_close (lua_State *L) { do { /* repeat until no more errors */ L->ci = L->base_ci; L->base = L->top = L->ci->base; - L->nCcalls = 0; + L->nCcalls = L->baseCcalls = 0; } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0); lua_assert(G(L)->tmudata == NULL); luai_userstateclose(L); diff --git a/lib/lua/lstate.h b/lib/lua/lstate.h index d296a4c..3bc575b 100644 --- a/lib/lua/lstate.h +++ b/lib/lua/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 2.24 2006/02/06 18:27:59 roberto Exp $ +** $Id: lstate.h,v 2.24.1.2 2008/01/03 15:20:39 roberto Exp $ ** Global State ** See Copyright Notice in lua.h */ @@ -112,6 +112,7 @@ struct lua_State { int stacksize; int size_ci; /* size of array `base_ci' */ unsigned short nCcalls; /* number of nested C calls */ + unsigned short baseCcalls; /* nested C calls when resuming coroutine */ lu_byte hookmask; lu_byte allowhook; int basehookcount; diff --git a/lib/lua/lstring.c b/lib/lua/lstring.c index 4319930..4911315 100644 --- a/lib/lua/lstring.c +++ b/lib/lua/lstring.c @@ -1,5 +1,5 @@ /* -** $Id: lstring.c,v 2.8 2005/12/22 16:19:56 roberto Exp $ +** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ ** String table (keeps all strings handled by Lua) ** See Copyright Notice in lua.h */ diff --git a/lib/lua/lstring.h b/lib/lua/lstring.h index 1d2e91e..73a2ff8 100644 --- a/lib/lua/lstring.h +++ b/lib/lua/lstring.h @@ -1,5 +1,5 @@ /* -** $Id: lstring.h,v 1.43 2005/04/25 19:24:10 roberto Exp $ +** $Id: lstring.h,v 1.43.1.1 2007/12/27 13:02:25 roberto Exp $ ** String table (keep all strings handled by Lua) ** See Copyright Notice in lua.h */ diff --git a/lib/lua/lstrlib.c b/lib/lua/lstrlib.c index fc7ae48..1b4763d 100644 --- a/lib/lua/lstrlib.c +++ b/lib/lua/lstrlib.c @@ -1,5 +1,5 @@ /* -** $Id: lstrlib.c,v 1.132a 2006/04/26 20:41:19 roberto Exp $ +** $Id: lstrlib.c,v 1.132.1.4 2008/07/11 17:27:21 roberto Exp $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ @@ -35,7 +35,8 @@ static int str_len (lua_State *L) { static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) { /* relative string position: negative means back from end */ - return (pos>=0) ? pos : (ptrdiff_t)len+pos+1; + if (pos < 0) pos += (ptrdiff_t)len + 1; + return (pos >= 0) ? pos : 0; } @@ -629,10 +630,6 @@ static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, lua_gettable(L, 3); break; } - default: { - luaL_argerror(L, 3, "string/function/table expected"); - return; - } } if (!lua_toboolean(L, -1)) { /* nil or false? */ lua_pop(L, 1); @@ -648,11 +645,15 @@ static int str_gsub (lua_State *L) { size_t srcl; const char *src = luaL_checklstring(L, 1, &srcl); const char *p = luaL_checkstring(L, 2); + int tr = lua_type(L, 3); int max_s = luaL_optint(L, 4, srcl+1); int anchor = (*p == '^') ? (p++, 1) : 0; int n = 0; MatchState ms; luaL_Buffer b; + luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || + tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, + "string/function/table expected"); luaL_buffinit(L, &b); ms.L = L; ms.src_init = src; diff --git a/lib/lua/ltable.c b/lib/lua/ltable.c index bc91cac..ec84f4f 100644 --- a/lib/lua/ltable.c +++ b/lib/lua/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 2.32 2006/01/18 11:49:02 roberto Exp $ +** $Id: ltable.c,v 2.32.1.2 2007/12/28 15:32:23 roberto Exp $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -84,8 +84,8 @@ static const Node dummynode_ = { static Node *hashnum (const Table *t, lua_Number n) { unsigned int a[numints]; int i; - n += 1; /* normalize number (avoid -0) */ - lua_assert(sizeof(a) <= sizeof(n)); + if (luai_numeq(n, 0)) /* avoid problems with -0 */ + return gnode(t, 0); memcpy(a, &n, sizeof(a)); for (i = 1; i < numints; i++) a[0] += a[i]; return hashmod(t, a[0]); diff --git a/lib/lua/ltable.h b/lib/lua/ltable.h index 09193cd..f5b9d5e 100644 --- a/lib/lua/ltable.h +++ b/lib/lua/ltable.h @@ -1,5 +1,5 @@ /* -** $Id: ltable.h,v 2.10 2006/01/10 13:13:06 roberto Exp $ +** $Id: ltable.h,v 2.10.1.1 2007/12/27 13:02:25 roberto Exp $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ diff --git a/lib/lua/ltablib.c b/lib/lua/ltablib.c index 453b23b..b6d9cb4 100644 --- a/lib/lua/ltablib.c +++ b/lib/lua/ltablib.c @@ -1,5 +1,5 @@ /* -** $Id: ltablib.c,v 1.38 2005/10/23 17:38:15 roberto Exp $ +** $Id: ltablib.c,v 1.38.1.3 2008/02/14 16:46:58 roberto Exp $ ** Library for Table Manipulation ** See Copyright Notice in lua.h */ @@ -118,7 +118,8 @@ static int tinsert (lua_State *L) { static int tremove (lua_State *L) { int e = aux_getn(L, 1); int pos = luaL_optint(L, 2, e); - if (e == 0) return 0; /* table is `empty' */ + if (!(1 <= pos && pos <= e)) /* position is outside bounds? */ + return 0; /* nothing to remove */ luaL_setn(L, 1, e - 1); /* t.n = n-1 */ lua_rawgeti(L, 1, pos); /* result = t[pos] */ for ( ;posL,o,LoadString(S)); break; default: - IF (1, "bad constant"); + error(S,"bad constant"); break; } } @@ -159,7 +160,9 @@ static void LoadDebug(LoadState* S, Proto* f) static Proto* LoadFunction(LoadState* S, TString* p) { - Proto* f=luaF_newproto(S->L); + Proto* f; + if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep"); + f=luaF_newproto(S->L); setptvalue2s(S->L,S->L->top,f); incr_top(S->L); f->source=LoadString(S); if (f->source==NULL) f->source=p; f->linedefined=LoadInt(S); @@ -173,6 +176,7 @@ static Proto* LoadFunction(LoadState* S, TString* p) LoadDebug(S,f); IF (!luaG_checkcode(f), "bad code"); S->L->top--; + S->L->nCcalls--; return f; } diff --git a/lib/lua/lundump.h b/lib/lua/lundump.h index 58cca5d..c80189d 100644 --- a/lib/lua/lundump.h +++ b/lib/lua/lundump.h @@ -1,5 +1,5 @@ /* -** $Id: lundump.h,v 1.40 2005/11/11 14:03:13 lhf Exp $ +** $Id: lundump.h,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ ** load precompiled Lua chunks ** See Copyright Notice in lua.h */ diff --git a/lib/lua/lvm.c b/lib/lua/lvm.c index 08802f4..ee3256a 100644 --- a/lib/lua/lvm.c +++ b/lib/lua/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 2.63a 2006/06/05 15:58:59 roberto Exp $ +** $Id: lvm.c,v 2.63.1.3 2007/12/28 15:32:23 roberto Exp $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -61,11 +61,9 @@ static void traceexec (lua_State *L, const Instruction *pc) { lu_byte mask = L->hookmask; const Instruction *oldpc = L->savedpc; L->savedpc = pc; - if (mask > LUA_MASKLINE) { /* instruction-hook set? */ - if (L->hookcount == 0) { - resethookcount(L); - luaD_callhook(L, LUA_HOOKCOUNT, -1); - } + if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) { + resethookcount(L); + luaD_callhook(L, LUA_HOOKCOUNT, -1); } if (mask & LUA_MASKLINE) { Proto *p = ci_func(L->ci)->l.p; diff --git a/lib/lua/lvm.h b/lib/lua/lvm.h index 788423f..bfe4f56 100644 --- a/lib/lua/lvm.h +++ b/lib/lua/lvm.h @@ -1,5 +1,5 @@ /* -** $Id: lvm.h,v 2.5 2005/08/22 18:54:49 roberto Exp $ +** $Id: lvm.h,v 2.5.1.1 2007/12/27 13:02:25 roberto Exp $ ** Lua virtual machine ** See Copyright Notice in lua.h */ diff --git a/lib/lua/lzio.c b/lib/lua/lzio.c index 5121ada..293edd5 100644 --- a/lib/lua/lzio.c +++ b/lib/lua/lzio.c @@ -1,5 +1,5 @@ /* -** $Id: lzio.c,v 1.31 2005/06/03 20:15:29 roberto Exp $ +** $Id: lzio.c,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ ** a generic input stream interface ** See Copyright Notice in lua.h */ diff --git a/lib/lua/lzio.h b/lib/lua/lzio.h index 8f403b8..51d695d 100644 --- a/lib/lua/lzio.h +++ b/lib/lua/lzio.h @@ -1,5 +1,5 @@ /* -** $Id: lzio.h,v 1.21 2005/05/17 19:49:15 roberto Exp $ +** $Id: lzio.h,v 1.21.1.1 2007/12/27 13:02:25 roberto Exp $ ** Buffered streams ** See Copyright Notice in lua.h */ diff --git a/lib/lua/print.c b/lib/lua/print.c new file mode 100644 index 0000000..e240cfc --- /dev/null +++ b/lib/lua/print.c @@ -0,0 +1,227 @@ +/* +** $Id: print.c,v 1.55a 2006/05/31 13:30:05 lhf Exp $ +** print bytecodes +** See Copyright Notice in lua.h +*/ + +#include +#include + +#define luac_c +#define LUA_CORE + +#include "ldebug.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lundump.h" + +#define PrintFunction luaU_print + +#define Sizeof(x) ((int)sizeof(x)) +#define VOID(p) ((const void*)(p)) + +static void PrintString(const TString* ts) +{ + const char* s=getstr(ts); + size_t i,n=ts->tsv.len; + putchar('"'); + for (i=0; ik[i]; + switch (ttype(o)) + { + case LUA_TNIL: + printf("nil"); + break; + case LUA_TBOOLEAN: + printf(bvalue(o) ? "true" : "false"); + break; + case LUA_TNUMBER: + printf(LUA_NUMBER_FMT,nvalue(o)); + break; + case LUA_TSTRING: + PrintString(rawtsvalue(o)); + break; + default: /* cannot happen */ + printf("? type=%d",ttype(o)); + break; + } +} + +static void PrintCode(const Proto* f) +{ + const Instruction* code=f->code; + int pc,n=f->sizecode; + for (pc=0; pc0) printf("[%d]\t",line); else printf("[-]\t"); + printf("%-9s\t",luaP_opnames[o]); + switch (getOpMode(o)) + { + case iABC: + printf("%d",a); + if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b); + if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c); + break; + case iABx: + if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx); + break; + case iAsBx: + if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx); + break; + } + switch (o) + { + case OP_LOADK: + printf("\t; "); PrintConstant(f,bx); + break; + case OP_GETUPVAL: + case OP_SETUPVAL: + printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-"); + break; + case OP_GETGLOBAL: + case OP_SETGLOBAL: + printf("\t; %s",svalue(&f->k[bx])); + break; + case OP_GETTABLE: + case OP_SELF: + if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); } + break; + case OP_SETTABLE: + case OP_ADD: + case OP_SUB: + case OP_MUL: + case OP_DIV: + case OP_POW: + case OP_EQ: + case OP_LT: + case OP_LE: + if (ISK(b) || ISK(c)) + { + printf("\t; "); + if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-"); + printf(" "); + if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-"); + } + break; + case OP_JMP: + case OP_FORLOOP: + case OP_FORPREP: + printf("\t; to %d",sbx+pc+2); + break; + case OP_CLOSURE: + printf("\t; %p",VOID(f->p[bx])); + break; + case OP_SETLIST: + if (c==0) printf("\t; %d",(int)code[++pc]); + else printf("\t; %d",c); + break; + default: + break; + } + printf("\n"); + } +} + +#define SS(x) (x==1)?"":"s" +#define S(x) x,SS(x) + +static void PrintHeader(const Proto* f) +{ + const char* s=getstr(f->source); + if (*s=='@' || *s=='=') + s++; + else if (*s==LUA_SIGNATURE[0]) + s="(bstring)"; + else + s="(string)"; + printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n", + (f->linedefined==0)?"main":"function",s, + f->linedefined,f->lastlinedefined, + S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f)); + printf("%d%s param%s, %d slot%s, %d upvalue%s, ", + f->numparams,f->is_vararg?"+":"",SS(f->numparams), + S(f->maxstacksize),S(f->nups)); + printf("%d local%s, %d constant%s, %d function%s\n", + S(f->sizelocvars),S(f->sizek),S(f->sizep)); +} + +static void PrintConstants(const Proto* f) +{ + int i,n=f->sizek; + printf("constants (%d) for %p:\n",n,VOID(f)); + for (i=0; isizelocvars; + printf("locals (%d) for %p:\n",n,VOID(f)); + for (i=0; ilocvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1); + } +} + +static void PrintUpvalues(const Proto* f) +{ + int i,n=f->sizeupvalues; + printf("upvalues (%d) for %p:\n",n,VOID(f)); + if (f->upvalues==NULL) return; + for (i=0; iupvalues[i])); + } +} + +void PrintFunction(const Proto* f, int full) +{ + int i,n=f->sizep; + PrintHeader(f); + PrintCode(f); + if (full) + { + PrintConstants(f); + PrintLocals(f); + PrintUpvalues(f); + } + for (i=0; ip[i],full); +}