diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 14 | ||||
-rw-r--r-- | src/lapi.c | 50 | ||||
-rw-r--r-- | src/lauxlib.c | 75 | ||||
-rw-r--r-- | src/lauxlib.h | 5 | ||||
-rw-r--r-- | src/lbaselib.c | 18 | ||||
-rw-r--r-- | src/lbitlib.c | 82 | ||||
-rw-r--r-- | src/ldebug.c | 18 | ||||
-rw-r--r-- | src/ldo.c | 9 | ||||
-rw-r--r-- | src/ldump.c | 15 | ||||
-rw-r--r-- | src/lgc.c | 6 | ||||
-rw-r--r-- | src/linit.c | 4 | ||||
-rw-r--r-- | src/liolib.c | 4 | ||||
-rw-r--r-- | src/llex.c | 14 | ||||
-rw-r--r-- | src/lmathlib.c | 4 | ||||
-rw-r--r-- | src/loadlib.c | 10 | ||||
-rw-r--r-- | src/lobject.c | 19 | ||||
-rw-r--r-- | src/lopcodes.c | 6 | ||||
-rw-r--r-- | src/lopcodes.h | 9 | ||||
-rw-r--r-- | src/loslib.c | 8 | ||||
-rw-r--r-- | src/lparser.c | 27 | ||||
-rw-r--r-- | src/lstate.c | 7 | ||||
-rw-r--r-- | src/lstate.h | 7 | ||||
-rw-r--r-- | src/lstrlib.c | 8 | ||||
-rw-r--r-- | src/ltablib.c | 5 | ||||
-rw-r--r-- | src/lua.c | 13 | ||||
-rw-r--r-- | src/lua.h | 17 | ||||
-rw-r--r-- | src/luac.c | 312 | ||||
-rw-r--r-- | src/luaconf.h | 115 | ||||
-rw-r--r-- | src/lualib.h | 6 | ||||
-rw-r--r-- | src/lundump.c | 59 | ||||
-rw-r--r-- | src/lundump.h | 15 | ||||
-rw-r--r-- | src/lvm.c | 6 | ||||
-rw-r--r-- | src/print.c | 229 |
33 files changed, 683 insertions, 513 deletions
diff --git a/src/Makefile b/src/Makefile index 84a21035..61ad180e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -33,7 +33,7 @@ LUA_T= lua LUA_O= lua.o LUAC_T= luac -LUAC_O= luac.o print.o +LUAC_O= luac.o ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O) ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) @@ -62,7 +62,7 @@ clean: $(RM) $(ALL_T) $(ALL_O) depend: - @$(CC) $(CFLAGS) -MM l*.c print.c + @$(CC) $(CFLAGS) -MM l*.c echo: @echo "PLAT= $(PLAT)" @@ -94,8 +94,7 @@ bsd: freebsd: $(MAKE) $(ALL) MYCFLAGS="-DLUA_USE_LINUX" MYLIBS="-Wl,-E -lreadline" -generic: - $(MAKE) $(ALL) MYCFLAGS= +generic: $(ALL) linux: $(MAKE) $(ALL) MYCFLAGS="-DLUA_USE_LINUX" MYLIBS="-Wl,-E -ldl -lreadline -lncurses" @@ -170,16 +169,13 @@ ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ lmem.h lstring.h lgc.h ltable.h lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h -luac.o: luac.c lua.h luaconf.h lauxlib.h ldo.h lobject.h llimits.h \ - lstate.h ltm.h lzio.h lmem.h lfunc.h lopcodes.h lstring.h lgc.h \ - lundump.h +luac.o: luac.c lua.h luaconf.h lauxlib.h lobject.h llimits.h lstate.h \ + ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \ llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \ lzio.h -print.o: print.c ldebug.h lstate.h lua.h luaconf.h lobject.h llimits.h \ - ltm.h lzio.h lmem.h lopcodes.h lundump.h # (end of Makefile) @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 2.133 2010/07/25 15:18:19 roberto Exp $ +** $Id: lapi.c,v 2.139 2010/10/25 20:31:11 roberto Exp $ ** Lua API ** See Copyright Notice in lua.h */ @@ -85,7 +85,7 @@ LUA_API int lua_checkstack (lua_State *L, int size) { if (L->stack_last - L->top > size) /* stack large enough? */ res = 1; /* yes; check is OK */ else { /* no; need to grow stack */ - int inuse = L->top - L->stack + EXTRA_STACK; + int inuse = cast_int(L->top - L->stack) + EXTRA_STACK; if (inuse > LUAI_MAXSTACK - size) /* can grow without overflow? */ res = 0; /* no */ else /* try to grow stack */ @@ -347,6 +347,23 @@ LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) { } +LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *isnum) { + TValue n; + const TValue *o = index2addr(L, idx); + if (tonumber(o, &n)) { + lua_Unsigned res; + lua_Number num = nvalue(o); + lua_number2uint(res, num); + if (isnum) *isnum = 1; + return res; + } + else { + if (isnum) *isnum = 0; + return 0; + } +} + + LUA_API int lua_toboolean (lua_State *L, int idx) { const TValue *o = index2addr(L, idx); return !l_isfalse(o); @@ -452,6 +469,16 @@ LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { } +LUA_API void lua_pushunsigned (lua_State *L, lua_Unsigned u) { + lua_Number n; + lua_lock(L); + n = lua_uint2number(u); + setnvalue(L->top, n); + api_incr_top(L); + lua_unlock(L); +} + + LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) { TString *ts; lua_lock(L); @@ -799,6 +826,7 @@ LUA_API void lua_callk (lua_State *L, int nargs, int nresults, int ctx, api_check(L, k == NULL || !isLua(L->ci), "cannot use continuations inside hooks"); api_checknelems(L, nargs+1); + api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); checkresults(L, nargs, nresults); func = L->top - (nargs+1); if (k != NULL && L->nny == 0) { /* need to prepare continuation? */ @@ -839,6 +867,7 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, api_check(L, k == NULL || !isLua(L->ci), "cannot use continuations inside hooks"); api_checknelems(L, nargs+1); + api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); checkresults(L, nargs, nresults); if (errfunc == 0) func = 0; @@ -889,7 +918,7 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, /* get global table from registry */ Table *reg = hvalue(&G(L)->l_registry); const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS); - /* set global table as 1st upvalue of 'f' (may be _ENV) */ + /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ setobj(L, f->l.upvals[0]->v, gt); luaC_barrier(L, f->l.upvals[0], gt); } @@ -974,6 +1003,11 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { g->gcpause = data; break; } + case LUA_GCSETMAJORINC: { + res = g->gcmajorinc; + g->gcmajorinc = data; + break; + } case LUA_GCSETSTEPMUL: { res = g->gcstepmul; g->gcstepmul = data; @@ -1100,11 +1134,15 @@ static const char *aux_upvalue (StkId fi, int n, TValue **val, return ""; } else { + const char *name; Proto *p = f->l.p; if (!(1 <= n && n <= p->sizeupvalues)) return NULL; *val = f->l.upvals[n-1]->v; if (owner) *owner = obj2gco(f->l.upvals[n - 1]); - return getstr(p->upvalues[n-1].name); + name = getstr(p->upvalues[n-1].name); + if (name == NULL) /* no debug information? */ + name = ""; + return name; } } @@ -1144,13 +1182,11 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { static UpVal **getupvalref (lua_State *L, int fidx, int n, Closure **pf) { Closure *f; - Proto *p; StkId fi = index2addr(L, fidx); api_check(L, ttisclosure(fi), "Lua function expected"); f = clvalue(fi); api_check(L, !f->c.isC, "Lua function expected"); - p = f->l.p; - api_check(L, (1 <= n && n <= p->sizeupvalues), "invalid upvalue index"); + api_check(L, (1 <= n && n <= f->l.p->sizeupvalues), "invalid upvalue index"); if (pf) *pf = f; return &f->l.upvals[n - 1]; /* get its upvalue pointer */ } diff --git a/src/lauxlib.c b/src/lauxlib.c index 54f13da2..807c5522 100644 --- a/src/lauxlib.c +++ b/src/lauxlib.c @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.c,v 1.219 2010/07/28 15:51:59 roberto Exp $ +** $Id: lauxlib.c,v 1.224 2010/10/29 12:52:21 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -330,11 +330,26 @@ LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { } +LUALIB_API lua_Unsigned luaL_checkunsigned (lua_State *L, int narg) { + int isnum; + lua_Unsigned d = lua_tounsignedx(L, narg, &isnum); + if (!isnum) + tag_error(L, narg, LUA_TNUMBER); + return d; +} + + LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg, lua_Integer def) { return luaL_opt(L, luaL_checkinteger, narg, def); } + +LUALIB_API lua_Unsigned luaL_optunsigned (lua_State *L, int narg, + lua_Unsigned def) { + return luaL_opt(L, luaL_checkunsigned, narg, def); +} + /* }====================================================== */ @@ -434,7 +449,7 @@ LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) { */ /* index of free-list header */ -#define freelist "lua-freelist" +#define freelist 0 LUALIB_API int luaL_ref (lua_State *L, int t) { @@ -444,12 +459,12 @@ LUALIB_API int luaL_ref (lua_State *L, int t) { lua_pop(L, 1); /* remove from stack */ return LUA_REFNIL; /* `nil' has a unique fixed reference */ } - lua_getfield(L, t, freelist); /* get first free element */ - ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ + lua_rawgeti(L, t, freelist); /* get first free element */ + ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */ lua_pop(L, 1); /* remove it from stack */ if (ref != 0) { /* any free element? */ lua_rawgeti(L, t, ref); /* remove it from list */ - lua_setfield(L, t, freelist); /* (t[freelist] = t[ref]) */ + lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */ } else /* no free elements */ ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */ @@ -461,10 +476,10 @@ LUALIB_API int luaL_ref (lua_State *L, int t) { LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { if (ref >= 0) { t = lua_absindex(L, t); - lua_getfield(L, t, freelist); + lua_rawgeti(L, t, freelist); lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */ lua_pushinteger(L, ref); - lua_setfield(L, t, freelist); /* t[freelist] = ref */ + lua_rawseti(L, t, freelist); /* t[freelist] = ref */ } } @@ -511,17 +526,32 @@ static int errfile (lua_State *L, const char *what, int fnameindex) { } +static int skipBOM (LoadF *lf) { + const char *p = "\xEF\xBB\xBF"; /* Utf8 BOM mark */ + int c; + lf->n = 0; + do { + c = getc(lf->f); + if (c == EOF || c != *(unsigned char *)p++) return c; + lf->buff[lf->n++] = c; /* to be read by the parser */ + } while (*p != '\0'); + lf->n = 0; /* prefix matched; discard it */ + return getc(lf->f); /* return next character */ +} + + /* -** reads the first character of file 'f' and skips its first line -** if it starts with '#'. Returns true if it skipped the first line. -** In any case, '*cp' has the first "valid" character of the file -** (after the optional first-line comment). +** reads the first character of file 'f' and skips an optional BOM mark +** in its beginning plus its first line if it starts with '#'. Returns +** true if it skipped the first line. In any case, '*cp' has the +** first "valid" character of the file (after the optional BOM and +** a first-line comment). */ -static int skipcomment (FILE *f, int *cp) { - int c = *cp = getc(f); +static int skipcomment (LoadF *lf, int *cp) { + int c = *cp = skipBOM(lf); if (c == '#') { /* first line is a comment (Unix exec. file)? */ - while ((c = getc(f)) != EOF && c != '\n') ; /* skip first line */ - *cp = getc(f); /* skip end-of-line */ + while ((c = getc(lf->f)) != EOF && c != '\n') ; /* skip first line */ + *cp = getc(lf->f); /* skip end-of-line */ return 1; /* there was a comment */ } else return 0; /* no comment */ @@ -542,14 +572,12 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { lf.f = fopen(filename, "r"); if (lf.f == NULL) return errfile(L, "open", fnameindex); } - lf.n = 0; - if (skipcomment(lf.f, &c)) /* read initial portion */ + if (skipcomment(&lf, &c)) /* read initial portion */ lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */ 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); - lf.n = 0; - skipcomment(lf.f, &c); /* re-read initial portion */ + skipcomment(&lf, &c); /* re-read initial portion */ } if (c != EOF) lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */ @@ -628,7 +656,7 @@ LUALIB_API int luaL_len (lua_State *L, int idx) { int l; int isnum; lua_len(L, idx); - l = lua_tointegerx(L, -1, &isnum); + l = (int)lua_tointegerx(L, -1, &isnum); if (!isnum) luaL_error(L, "object length is not a number"); lua_pop(L, 1); /* remove object */ @@ -848,5 +876,12 @@ LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver) { else if (*v != ver) luaL_error(L, "version mismatch: app. needs %d, Lua core provides %f", ver, *v); + /* check conversions number -> integer types */ + lua_pushnumber(L, -(lua_Number)0x1234); + if (lua_tointeger(L, -1) != -0x1234 || + lua_tounsigned(L, -1) != (lua_Unsigned)-0x1234) + luaL_error(L, "bad conversion number->int;" + " must recompile Lua with proper settings"); + lua_pop(L, 1); } diff --git a/src/lauxlib.h b/src/lauxlib.h index b2034673..504fdf58 100644 --- a/src/lauxlib.h +++ b/src/lauxlib.h @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.h,v 1.108 2010/07/02 11:38:13 roberto Exp $ +** $Id: lauxlib.h,v 1.109 2010/10/25 20:31:11 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -44,6 +44,9 @@ LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, lua_Integer def); +LUALIB_API lua_Unsigned (luaL_checkunsigned) (lua_State *L, int numArg); +LUALIB_API lua_Unsigned (luaL_optunsigned) (lua_State *L, int numArg, + lua_Unsigned def); LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); diff --git a/src/lbaselib.c b/src/lbaselib.c index 1e13a183..1553c1d0 100644 --- a/src/lbaselib.c +++ b/src/lbaselib.c @@ -1,5 +1,5 @@ /* -** $Id: lbaselib.c,v 1.246 2010/07/02 11:38:13 roberto Exp $ +** $Id: lbaselib.c,v 1.251 2010/10/28 15:36:30 roberto Exp $ ** Basic library ** See Copyright Notice in lua.h */ @@ -56,12 +56,15 @@ static int luaB_tonumber (lua_State *L) { const char *s1 = luaL_checkstring(L, 1); char *s2; unsigned long n; + int neg = 0; luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); + while (isspace((unsigned char)(*s1))) s1++; /* skip initial spaces */ + if (*s1 == '-') { s1++; neg = 1; } n = strtoul(s1, &s2, base); if (s1 != s2) { /* at least one valid digit? */ while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */ if (*s2 == '\0') { /* no invalid trailing characters? */ - lua_pushnumber(L, (lua_Number)n); + lua_pushnumber(L, (neg) ? -(lua_Number)n : (lua_Number)n); return 1; } } @@ -142,11 +145,11 @@ static int luaB_rawset (lua_State *L) { static int luaB_collectgarbage (lua_State *L) { static const char *const opts[] = {"stop", "restart", "collect", - "count", "step", "setpause", "setstepmul", "isrunning", - "gen", "inc", NULL}; + "count", "step", "setpause", "setstepmul", + "setmajorinc", "isrunning", "gen", "inc", NULL}; static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, - LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC}; + LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC}; int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; int ex = luaL_optint(L, 2, 0); int res = lua_gc(L, o, ex); @@ -330,11 +333,12 @@ static int luaB_load (lua_State *L) { static int luaB_loadin (lua_State *L) { int n; - luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 1); n = luaB_load_aux(L, 2); if (n == 1) { /* success? */ lua_pushvalue(L, 1); /* environment for loaded function */ - lua_setupvalue(L, -2, 1); + if (lua_setupvalue(L, -2, 1) == NULL) + luaL_error(L, "loaded chunk does not have an upvalue"); } return n; } diff --git a/src/lbitlib.c b/src/lbitlib.c index 1b32653d..e93575e6 100644 --- a/src/lbitlib.c +++ b/src/lbitlib.c @@ -1,5 +1,5 @@ /* -** $Id: lbitlib.c,v 1.6 2010/07/02 12:01:53 roberto Exp $ +** $Id: lbitlib.c,v 1.10 2010/10/28 15:17:29 roberto Exp $ ** Standard library for bitwise operations ** See Copyright Notice in lua.h */ @@ -13,22 +13,19 @@ #include "lualib.h" -/* number of bits considered when shifting/rotating (must be a power of 2) */ +/* number of bits to consider in a number */ #define NBITS 32 +#define ALLONES (~(((~(lua_Unsigned)0) << (NBITS - 1)) << 1)) -typedef LUA_INT32 b_int; -typedef unsigned LUA_INT32 b_uint; +/* mask to trim extra bits */ +#define trim(x) ((x) & ALLONES) -static b_uint getuintarg (lua_State *L, int arg) { - b_uint r; - int isnum; - lua_Number x = lua_tonumberx(L, arg, &isnum); - if (!isnum) luaL_typeerror(L, arg, "number"); - lua_number2uint(r, x); - return r; -} +typedef lua_Unsigned b_uint; + + +#define getuintarg(L,arg) luaL_checkunsigned(L,arg) static b_uint andaux (lua_State *L) { @@ -36,13 +33,13 @@ static b_uint andaux (lua_State *L) { b_uint r = ~(b_uint)0; for (i = 1; i <= n; i++) r &= getuintarg(L, i); - return r; + return trim(r); } static int b_and (lua_State *L) { b_uint r = andaux(L); - lua_pushnumber(L, lua_uint2number(r)); + lua_pushunsigned(L, r); return 1; } @@ -59,7 +56,7 @@ static int b_or (lua_State *L) { b_uint r = 0; for (i = 1; i <= n; i++) r |= getuintarg(L, i); - lua_pushnumber(L, lua_uint2number(r)); + lua_pushunsigned(L, trim(r)); return 1; } @@ -69,49 +66,66 @@ static int b_xor (lua_State *L) { b_uint r = 0; for (i = 1; i <= n; i++) r ^= getuintarg(L, i); - lua_pushnumber(L, lua_uint2number(r)); + lua_pushunsigned(L, trim(r)); return 1; } static int b_not (lua_State *L) { b_uint r = ~getuintarg(L, 1); - lua_pushnumber(L, lua_uint2number(r)); + lua_pushunsigned(L, trim(r)); return 1; } -static int b_shift (lua_State *L, int i) { - b_uint r = getuintarg(L, 1); +static int b_shift (lua_State *L, b_uint r, int i) { if (i < 0) { /* shift right? */ i = -i; + r = trim(r); if (i >= NBITS) r = 0; else r >>= i; } else { /* shift left */ if (i >= NBITS) r = 0; else r <<= i; + r = trim(r); } - lua_pushnumber(L, lua_uint2number(r)); + lua_pushunsigned(L, r); return 1; } static int b_lshift (lua_State *L) { - return b_shift(L, luaL_checkint(L, 2)); + return b_shift(L, getuintarg(L, 1), luaL_checkint(L, 2)); } static int b_rshift (lua_State *L) { - return b_shift(L, -luaL_checkint(L, 2)); + return b_shift(L, getuintarg(L, 1), -luaL_checkint(L, 2)); +} + + +static int b_arshift (lua_State *L) { + b_uint r = getuintarg(L, 1); + int i = luaL_checkint(L, 2); + if (i < 0 || !(r & (1 << (NBITS - 1)))) + return b_shift(L, r, -i); + else { /* arithmetic shift for 'negative' number */ + if (i >= NBITS) r = ALLONES; + else + r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */ + lua_pushunsigned(L, r); + return 1; + } } static int b_rot (lua_State *L, int i) { b_uint r = getuintarg(L, 1); i &= (NBITS - 1); /* i = i % NBITS */ + r = trim(r); r = (r << i) | (r >> (NBITS - i)); - lua_pushnumber(L, lua_uint2number(r)); + lua_pushunsigned(L, trim(r)); return 1; } @@ -127,21 +141,23 @@ static int b_ror (lua_State *L) { static const luaL_Reg bitlib[] = { - {"band", b_and}, - {"btest", b_test}, - {"bor", b_or}, - {"bxor", b_xor}, - {"bnot", b_not}, - {"lshift", b_lshift}, - {"rshift", b_rshift}, - {"rol", b_rol}, - {"ror", b_ror}, + {"AND", b_and}, + {"TEST", b_test}, + {"OR", b_or}, + {"XOR", b_xor}, + {"NOT", b_not}, + {"SHL", b_lshift}, + {"SAR", b_arshift}, + {"SHR", b_rshift}, + {"ROL", b_rol}, + {"ROR", b_ror}, {NULL, NULL} }; -LUAMOD_API int luaopen_bit (lua_State *L) { +LUAMOD_API int luaopen_bit32 (lua_State *L) { luaL_newlib(L, bitlib); return 1; } + diff --git a/src/ldebug.c b/src/ldebug.c index 5a04d5a3..a112f4da 100644 --- a/src/ldebug.c +++ b/src/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 2.72 2010/06/21 16:30:12 roberto Exp $ +** $Id: ldebug.c,v 2.74 2010/10/11 20:24:42 roberto Exp $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -160,9 +160,10 @@ static void funcinfo (lua_Debug *ar, Closure *cl) { ar->what = "C"; } else { - ar->source = getstr(cl->l.p->source); - ar->linedefined = cl->l.p->linedefined; - ar->lastlinedefined = cl->l.p->lastlinedefined; + Proto *p = cl->l.p; + ar->source = p->source ? getstr(p->source) : "=?"; + ar->linedefined = p->linedefined; + ar->lastlinedefined = p->lastlinedefined; ar->what = (ar->linedefined == 0) ? "main" : "Lua"; } luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); @@ -315,7 +316,7 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg, ? luaF_getlocalname(p, t + 1, pc) : getstr(p->upvalues[t].name); kname(p, k, a, what, name); - what = (vn && strcmp(vn, "_ENV") == 0) ? "global" : "field"; + what = (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field"; } break; } @@ -496,7 +497,12 @@ static void addinfo (lua_State *L, const char *msg) { if (isLua(ci)) { /* is Lua code? */ char buff[LUA_IDSIZE]; /* add file:line information */ int line = currentline(ci); - luaO_chunkid(buff, getstr(ci_func(ci)->l.p->source), LUA_IDSIZE); + TString *src = ci_func(ci)->l.p->source; + if (src) + luaO_chunkid(buff, getstr(src), LUA_IDSIZE); + else { /* no source available; use "?" instead */ + buff[0] = '?'; buff[1] = '\0'; + } luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); } } @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 2.88 2010/06/04 13:06:15 roberto Exp $ +** $Id: ldo.c,v 2.90 2010/10/25 19:01:37 roberto Exp $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -177,7 +177,7 @@ void luaD_growstack (lua_State *L, int n) { if (size > LUAI_MAXSTACK) /* error after extra size? */ luaD_throw(L, LUA_ERRERR); else { - int needed = L->top - L->stack + n + EXTRA_STACK; + int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK; int newsize = 2 * size; if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK; if (newsize < needed) newsize = needed; @@ -299,7 +299,6 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { if (!ttisfunction(func)) /* `func' is not a function? */ func = tryfuncTM(L, func); /* check the `function' tag method */ funcr = savestack(L, func); - L->ci->nresults = nresults; if (ttislcf(func)) { /* light C function? */ f = fvalue(func); /* get it */ goto isCfunc; /* go to call it */ @@ -312,6 +311,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { isCfunc: /* call C function 'f' */ luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ ci = next_ci(L); /* now 'enter' new function */ + ci->nresults = nresults; ci->func = restorestack(L, funcr); ci->top = L->top + LUA_MINSTACK; lua_assert(ci->top <= L->stack_last); @@ -341,6 +341,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { else /* vararg function */ base = adjust_varargs(L, p, nargs); ci = next_ci(L); /* now 'enter' new function */ + ci->nresults = nresults; ci->func = func; ci->u.l.base = base; ci->top = base + p->maxstacksize; @@ -368,8 +369,8 @@ int luaD_poscall (lua_State *L, StkId firstResult) { L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */ } res = ci->func; /* res == final position of 1st result */ - L->ci = ci = ci->previous; /* back to caller */ wanted = ci->nresults; + L->ci = ci = ci->previous; /* back to caller */ /* move results to correct place */ for (i = wanted; i != 0 && firstResult < L->top; i--) setobjs2s(L, res++, firstResult++); diff --git a/src/ldump.c b/src/ldump.c index b2c1e709..54a7bb48 100644 --- a/src/ldump.c +++ b/src/ldump.c @@ -1,5 +1,5 @@ /* -** $Id: ldump.c,v 2.13 2010/03/12 19:14:06 roberto Exp $ +** $Id: ldump.c,v 1.17 2010/10/13 21:04:52 lhf Exp $ ** save precompiled Lua chunks ** See Copyright Notice in lua.h */ @@ -75,7 +75,7 @@ static void DumpString(const TString* s, DumpState* D) #define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) -static void DumpFunction(const Proto* f, const TString* p, DumpState* D); +static void DumpFunction(const Proto* f, DumpState* D); static void DumpConstants(const Proto* f, DumpState* D) { @@ -98,14 +98,11 @@ static void DumpConstants(const Proto* f, DumpState* D) case LUA_TSTRING: DumpString(rawtsvalue(o),D); break; - default: - lua_assert(0); /* cannot happen */ - break; } } n=f->sizep; DumpInt(n,D); - for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D); + for (i=0; i<n; i++) DumpFunction(f->p[i],D); } static void DumpUpvalues(const Proto* f, DumpState* D) @@ -122,6 +119,7 @@ static void DumpUpvalues(const Proto* f, DumpState* D) static void DumpDebug(const Proto* f, DumpState* D) { int i,n; + DumpString((D->strip) ? NULL : f->source,D); n= (D->strip) ? 0 : f->sizelineinfo; DumpVector(f->lineinfo,n,sizeof(int),D); n= (D->strip) ? 0 : f->sizelocvars; @@ -137,9 +135,8 @@ static void DumpDebug(const Proto* f, DumpState* D) for (i=0; i<n; i++) DumpString(f->upvalues[i].name,D); } -static void DumpFunction(const Proto* f, const TString* p, DumpState* D) +static void DumpFunction(const Proto* f, DumpState* D) { - DumpString((f->source==p || D->strip) ? NULL : f->source,D); DumpInt(f->linedefined,D); DumpInt(f->lastlinedefined,D); DumpChar(f->numparams,D); @@ -170,6 +167,6 @@ int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip D.strip=strip; D.status=0; DumpHeader(&D); - DumpFunction(f,NULL,&D); + DumpFunction(f,&D); return D.status; } @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.101 2010/06/30 14:11:17 roberto Exp $ +** $Id: lgc.c,v 2.103 2010/10/25 19:01:37 roberto Exp $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -449,7 +449,7 @@ static int traverseproto (global_State *g, Proto *f) { } -static l_mem traverseclosure (global_State *g, Closure *cl) { +static int traverseclosure (global_State *g, Closure *cl) { if (cl->c.isC) { int i; for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */ @@ -960,7 +960,7 @@ static void generationalcollection (lua_State *L) { else { luaC_runtilstate(L, ~bitmask(GCSpause)); /* run complete cycle */ luaC_runtilstate(L, bitmask(GCSpause)); - if (g->totalbytes > g->lastmajormem/100 * g->gcpause) + if (g->totalbytes > g->lastmajormem/100 * g->gcmajorinc) g->lastmajormem = 0; /* signal for a major collection */ } g->GCdebt = stddebt(g); diff --git a/src/linit.c b/src/linit.c index b8af9f39..ecde4915 100644 --- a/src/linit.c +++ b/src/linit.c @@ -1,5 +1,5 @@ /* -** $Id: linit.c,v 1.28 2010/07/02 11:38:13 roberto Exp $ +** $Id: linit.c,v 1.29 2010/10/25 14:32:36 roberto Exp $ ** Initialization of libraries for lua.c and other clients ** See Copyright Notice in lua.h */ @@ -34,7 +34,7 @@ static const luaL_Reg loadedlibs[] = { {LUA_IOLIBNAME, luaopen_io}, {LUA_OSLIBNAME, luaopen_os}, {LUA_STRLIBNAME, luaopen_string}, - {LUA_BITLIBNAME, luaopen_bit}, + {LUA_BITLIBNAME, luaopen_bit32}, {LUA_MATHLIBNAME, luaopen_math}, #if defined(LUA_COMPAT_DEBUGLIB) {LUA_DBLIBNAME, luaopen_debug}, diff --git a/src/liolib.c b/src/liolib.c index 3ecccb11..6574e8b6 100644 --- a/src/liolib.c +++ b/src/liolib.c @@ -1,5 +1,5 @@ /* -** $Id: liolib.c,v 2.91 2010/07/28 15:51:59 roberto Exp $ +** $Id: liolib.c,v 2.92 2010/10/25 19:01:37 roberto Exp $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ @@ -453,7 +453,7 @@ static int f_read (lua_State *L) { static int io_readline (lua_State *L) { FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1)); int i; - int n = lua_tointeger(L, lua_upvalueindex(2)); + int n = (int)lua_tointeger(L, lua_upvalueindex(2)); if (f == NULL) /* file is already closed? */ luaL_error(L, "file is already closed"); lua_settop(L , 1); @@ -1,5 +1,5 @@ /* -** $Id: llex.c,v 2.37 2010/04/16 12:31:07 roberto Exp $ +** $Id: llex.c,v 2.40 2010/10/25 12:24:36 roberto Exp $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ @@ -161,7 +161,7 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { ls->linenumber = 1; ls->lastline = 1; ls->source = source; - ls->envn = luaS_new(L, "_ENV"); /* create env name */ + ls->envn = luaS_new(L, LUA_ENV); /* create env name */ luaS_fix(ls->envn); /* never collect this name */ luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ next(ls); /* read first char */ @@ -221,11 +221,9 @@ static void read_numeral (LexState *ls, SemInfo *seminfo) { lua_assert(lisdigit(ls->current)); do { save_and_next(ls); - } while (lisdigit(ls->current) || ls->current == '.'); - if (check_next(ls, "Ee")) /* `E'? */ - check_next(ls, "+-"); /* optional exponent sign */ - while (lislalnum(ls->current)) - save_and_next(ls); + if (check_next(ls, "EePp")) /* exponent part? */ + check_next(ls, "+-"); /* optional exponent sign */ + } while (lislalnum(ls->current) || ls->current == '.'); save(ls, '\0'); buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */ @@ -234,7 +232,7 @@ static void read_numeral (LexState *ls, SemInfo *seminfo) { /* -** skip a sequence '[=*=[' or ']=*]' and return its number of '='s or +** skip a sequence '[=*[' or ']=*]' and return its number of '='s or ** -1 if sequence is malformed */ static int skip_sep (LexState *ls) { diff --git a/src/lmathlib.c b/src/lmathlib.c index 7ba6550c..13aebe9e 100644 --- a/src/lmathlib.c +++ b/src/lmathlib.c @@ -1,5 +1,5 @@ /* -** $Id: lmathlib.c,v 1.75 2010/07/02 11:38:13 roberto Exp $ +** $Id: lmathlib.c,v 1.76 2010/10/25 20:31:11 roberto Exp $ ** Standard mathematical library ** See Copyright Notice in lua.h */ @@ -220,7 +220,7 @@ static int math_random (lua_State *L) { static int math_randomseed (lua_State *L) { - srand(luaL_checkint(L, 1)); + srand(luaL_checkunsigned(L, 1)); (void)rand(); /* discard first value to avoid undesirable correlations */ return 0; } diff --git a/src/loadlib.c b/src/loadlib.c index 82c00b0d..42cfb869 100644 --- a/src/loadlib.c +++ b/src/loadlib.c @@ -1,5 +1,5 @@ /* -** $Id: loadlib.c,v 1.89 2010/07/28 15:51:59 roberto Exp $ +** $Id: loadlib.c,v 1.92 2010/10/29 14:35:09 roberto Exp $ ** Dynamic library loader for Lua ** See Copyright Notice in lua.h ** @@ -177,7 +177,7 @@ static void ll_unloadlib (void *lib) { static void *ll_load (lua_State *L, const char *path, int seeglb) { HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS); - (void)(seeglb); /* symbols are 'global' by default? */ + (void)(seeglb); /* symbols are 'global' by default */ if (lib == NULL) pusherror(L); return lib; } @@ -212,7 +212,7 @@ static void ll_unloadlib (void *lib) { static void *ll_load (lua_State *L, const char *path, int seeglb) { - (void)(path); /* to avoid warnings */ + (void)(path); (void)(seeglb); /* to avoid warnings */ lua_pushliteral(L, DLMSG); return NULL; } @@ -428,8 +428,6 @@ static int loader_Croot (lua_State *L) { static int loader_preload (lua_State *L) { const char *name = luaL_checkstring(L, 1); lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); - if (!lua_istable(L, -1)) - luaL_error(L, LUA_QL("package.preload") " must be a table"); lua_getfield(L, -1, name); if (lua_isnil(L, -1)) /* not found? */ lua_pushfstring(L, "\n\tno field package.preload['%s']", name); @@ -498,7 +496,7 @@ static int ll_require (lua_State *L) { #if defined(LUA_COMPAT_MODULE) /* -** changes the _ENV variable of calling function +** changes the environment variable of calling function */ static void set_env (lua_State *L) { lua_Debug ar; diff --git a/src/lobject.c b/src/lobject.c index d4fff394..f5fc09d7 100644 --- a/src/lobject.c +++ b/src/lobject.c @@ -1,5 +1,5 @@ /* -** $Id: lobject.c,v 2.40 2010/04/18 13:22:48 roberto Exp $ +** $Id: lobject.c,v 2.43 2010/10/29 15:54:55 roberto Exp $ ** Some generic functions over Lua objects ** See Copyright Notice in lua.h */ @@ -106,14 +106,19 @@ lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) { } +static int checkend (const char *s, const char *endptr) { + if (endptr == s) return 0; /* no characters converted */ + while (lisspace(cast(unsigned char, *endptr))) endptr++; + return (*endptr == '\0'); /* OK if no trailing characters */ +} + + int luaO_str2d (const char *s, lua_Number *result) { char *endptr; *result = lua_str2number(s, &endptr); - if (endptr == s) return 0; /* conversion failed */ - if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ - *result = cast_num(strtoul(s, &endptr, 16)); - while (lisspace(cast(unsigned char, *endptr))) endptr++; - return (*endptr == '\0'); /* OK if no trailing characters */ + if (checkend(s, endptr)) return 1; /* conversion OK? */ + *result = cast_num(strtoul(s, &endptr, 0)); /* try hexadecimal */ + return checkend(s, endptr); } @@ -221,7 +226,7 @@ void luaO_chunkid (char *out, const char *source, size_t bufflen) { else { /* string; format as [string "source"] */ const char *nl = strchr(source, '\n'); /* find first new line (if any) */ addstr(out, PRE, LL(PRE)); /* add prefix */ - bufflen -= LL(PRE RETS POS); /* save space for prefix+suffix */ + bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */ if (l < bufflen && nl == NULL) { /* small one-line source? */ addstr(out, source, l); /* keep it */ } diff --git a/src/lopcodes.c b/src/lopcodes.c index cc1acb13..af267224 100644 --- a/src/lopcodes.c +++ b/src/lopcodes.c @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.c,v 1.43 2010/03/12 19:14:06 roberto Exp $ +** $Id: lopcodes.c,v 1.44 2010/10/13 16:45:54 roberto Exp $ ** See Copyright Notice in lua.h */ @@ -48,11 +48,11 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { "FORLOOP", "FORPREP", "TFORCALL", + "TFORLOOP", "SETLIST", "CLOSE", "CLOSURE", "VARARG", - "TFORLOOP", "EXTRAARG", NULL }; @@ -96,11 +96,11 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */ ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ - ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */ ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */ }; diff --git a/src/lopcodes.h b/src/lopcodes.h index 4140db3a..af1dc9cd 100644 --- a/src/lopcodes.h +++ b/src/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.135 2010/03/12 19:14:06 roberto Exp $ +** $Id: lopcodes.h,v 1.137 2010/10/25 12:24:55 roberto Exp $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -17,6 +17,7 @@ `A' : 8 bits `B' : 9 bits `C' : 9 bits + 'Ax' : 26 bits ('A', 'B', and 'C' together) `Bx' : 18 bits (`B' and `C' together) `sBx' : signed Bx @@ -122,7 +123,7 @@ enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */ | (cast(Instruction, bc)<<POS_Bx)) #define CREATE_Ax(o,a) ((cast(Instruction, o)<<POS_OP) \ - | (cast(Instruction, a)<<POS_A)) + | (cast(Instruction, a)<<POS_Ax)) /* @@ -212,6 +213,8 @@ OP_FORLOOP,/* A sBx R(A)+=R(A+2); OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */ OP_TFORCALL,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */ +OP_TFORLOOP,/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/ + OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */ OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/ @@ -219,8 +222,6 @@ OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx]) */ OP_VARARG,/* A B R(A), R(A+1), ..., R(A+B-2) = vararg */ -OP_TFORLOOP,/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/ - OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ } OpCode; diff --git a/src/loslib.c b/src/loslib.c index 9b27ebce..0278eb51 100644 --- a/src/loslib.c +++ b/src/loslib.c @@ -1,5 +1,5 @@ /* -** $Id: loslib.c,v 1.31 2010/07/02 12:01:53 roberto Exp $ +** $Id: loslib.c,v 1.32 2010/10/05 12:18:03 roberto Exp $ ** Standard Operating System library ** See Copyright Notice in lua.h */ @@ -276,7 +276,11 @@ static int os_setlocale (lua_State *L) { static int os_exit (lua_State *L) { - int status = luaL_optint(L, 1, EXIT_SUCCESS); + int status; + if (lua_isboolean(L, 1)) + status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE); + else + status = luaL_optint(L, 1, EXIT_SUCCESS); if (lua_toboolean(L, 2)) lua_close(L); exit(status); diff --git a/src/lparser.c b/src/lparser.c index 16c05d9e..3524b9b2 100644 --- a/src/lparser.c +++ b/src/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 2.90 2010/07/07 16:27:29 roberto Exp $ +** $Id: lparser.c,v 2.92 2010/09/07 19:21:39 roberto Exp $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -289,7 +289,7 @@ static void singlevar (LexState *ls, expdesc *var) { FuncState *fs = ls->fs; if (singlevaraux(fs, varname, var, 1) == VVOID) { /* global name? */ expdesc key; - singlevaraux(fs, ls->envn, var, 1); /* get _ENV variable */ + singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ lua_assert(var->k == VLOCAL || var->k == VUPVAL); codestring(ls, &key, varname); /* key is variable name */ luaK_indexed(fs, var, &key); /* env[varname] */ @@ -352,15 +352,20 @@ static void leaveblock (FuncState *fs) { } -static void pushclosure (LexState *ls, Proto *clp, expdesc *v) { +/* +** adds prototype being created into its parent list of prototypes +** and codes instruction to create new closure +*/ +static void codeclosure (LexState *ls, Proto *clp, expdesc *v) { FuncState *fs = ls->fs->prev; Proto *f = fs->f; /* prototype of function creating new closure */ - int oldsize = f->sizep; - luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, - MAXARG_Bx, "functions"); - while (oldsize < f->sizep) f->p[oldsize++] = NULL; + if (fs->np >= f->sizep) { + int oldsize = f->sizep; + luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, + MAXARG_Bx, "functions"); + while (oldsize < f->sizep) f->p[oldsize++] = NULL; + } f->p[fs->np++] = clp; - /* initial environment for new function is current lexical environment */ luaC_objbarrier(ls->L, f, clp); init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); } @@ -428,14 +433,14 @@ static void close_func (LexState *ls) { /* ** opens the main function, which is a regular vararg function with an -** upvalue named '_ENV' +** upvalue named LUA_ENV */ static void open_mainfunc (LexState *ls, FuncState *fs) { expdesc v; open_func(ls, fs); fs->f->is_vararg = 1; /* main function is always vararg */ init_exp(&v, VLOCAL, 0); - newupvalue(fs, ls->envn, &v); /* create '_ENV' upvalue */ + newupvalue(fs, ls->envn, &v); /* create environment upvalue */ } @@ -653,7 +658,7 @@ static void body (LexState *ls, expdesc *e, int needself, int line) { chunk(ls); new_fs.f->lastlinedefined = ls->linenumber; check_match(ls, TK_END, TK_FUNCTION, line); - pushclosure(ls, new_fs.f, e); + codeclosure(ls, new_fs.f, e); close_func(ls); } diff --git a/src/lstate.c b/src/lstate.c index 6ea00b62..39a0ef4d 100644 --- a/src/lstate.c +++ b/src/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 2.85 2010/04/30 18:36:22 roberto Exp $ +** $Id: lstate.c,v 2.86 2010/09/03 14:14:01 roberto Exp $ ** Global State ** See Copyright Notice in lua.h */ @@ -29,6 +29,10 @@ #define LUAI_GCPAUSE 200 /* 200% */ #endif +#if !defined(LUAI_GCMAJOR) +#define LUAI_GCMAJOR 200 /* 200% */ +#endif + #if !defined(LUAI_GCMUL) #define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ #endif @@ -254,6 +258,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { g->weak = g->ephemeron = g->allweak = NULL; g->totalbytes = sizeof(LG); g->gcpause = LUAI_GCPAUSE; + g->gcmajorinc = LUAI_GCMAJOR; g->gcstepmul = LUAI_GCMUL; for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { diff --git a/src/lstate.h b/src/lstate.h index e829ed4a..bc64a4ae 100644 --- a/src/lstate.h +++ b/src/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 2.65 2010/05/03 17:39:48 roberto Exp $ +** $Id: lstate.h,v 2.68 2010/10/29 17:52:46 roberto Exp $ ** Global State ** See Copyright Notice in lua.h */ @@ -66,13 +66,13 @@ typedef struct stringtable { /* -** informations about a call +** information about a call */ typedef struct CallInfo { StkId func; /* function index in the stack */ StkId top; /* top for this function */ struct CallInfo *previous, *next; /* dynamic call link */ - short nresults; /* expected number of results from a call */ + short nresults; /* expected number of results from this function */ lu_byte callstatus; union { struct { /* only for Lua functions */ @@ -136,6 +136,7 @@ typedef struct global_State { UpVal uvhead; /* head of double-linked list of all open upvalues */ Mbuffer buff; /* temporary buffer for string concatenation */ int gcpause; /* size of pause between successive GCs */ + int gcmajorinc; /* how much to wait for a major GC (only in gen. mode) */ int gcstepmul; /* GC `granularity' */ lua_CFunction panic; /* to be called in unprotected errors */ struct lua_State *mainthread; diff --git a/src/lstrlib.c b/src/lstrlib.c index 558a748e..f2132005 100644 --- a/src/lstrlib.c +++ b/src/lstrlib.c @@ -1,5 +1,5 @@ /* -** $Id: lstrlib.c,v 1.154 2010/07/02 11:38:13 roberto Exp $ +** $Id: lstrlib.c,v 1.156 2010/10/29 17:52:46 roberto Exp $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ @@ -424,7 +424,7 @@ static const char *match (MatchState *ms, const char *s, const char *p) { default: goto dflt; } } - default: dflt: { /* pattern class plus optional sufix */ + default: dflt: { /* pattern class plus optional suffix */ const char *ep = classend(ms, p); /* points to what is next */ int m = s < ms->src_end && singlematch(uchar(*s), p, ep); switch (*ep) { @@ -758,9 +758,9 @@ static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { else if (*s == '\0' || iscntrl(uchar(*s))) { char buff[10]; if (!isdigit(uchar(*(s+1)))) - sprintf(buff, "\\%d", uchar(*s)); + sprintf(buff, "\\%d", (int)uchar(*s)); else - sprintf(buff, "\\%03d", uchar(*s)); + sprintf(buff, "\\%03d", (int)uchar(*s)); luaL_addstring(b, buff); } else diff --git a/src/ltablib.c b/src/ltablib.c index b094d2f8..17ea33bc 100644 --- a/src/ltablib.c +++ b/src/ltablib.c @@ -1,5 +1,5 @@ /* -** $Id: ltablib.c,v 1.56 2010/07/02 11:38:13 roberto Exp $ +** $Id: ltablib.c,v 1.57 2010/10/25 19:01:37 roberto Exp $ ** Library for Table Manipulation ** See Copyright Notice in lua.h */ @@ -16,7 +16,8 @@ #include "lualib.h" -#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), lua_rawlen(L, n)) +#define aux_getn(L,n) \ + (luaL_checktype(L, n, LUA_TTABLE), (int)lua_rawlen(L, n)) static int foreachi (lua_State *L) { @@ -1,5 +1,5 @@ /* -** $Id: lua.c,v 1.192 2010/07/25 15:03:37 roberto Exp $ +** $Id: lua.c,v 1.194 2010/10/25 19:01:37 roberto Exp $ ** Lua stand-alone interpreter ** See Copyright Notice in lua.h */ @@ -369,10 +369,11 @@ static int collectargs (char **argv, int *pi, int *pv, int *pe) { break; case 'e': *pe = 1; /* go through */ - case 'l': - if (argv[i][2] == '\0') { - i++; - if (argv[i] == NULL) return -(i - 1); + case 'l': /* both options need an argument */ + if (argv[i][2] == '\0') { /* no concatenated argument? */ + i++; /* try next 'argv' */ + if (argv[i] == NULL || argv[i][0] == '-') + return -(i - 1); /* no next argument or it is another option */ } break; default: /* invalid option; return its index... */ @@ -427,7 +428,7 @@ static int handle_luainit (lua_State *L) { static int pmain (lua_State *L) { - int argc = lua_tointeger(L, 1); + int argc = (int)lua_tointeger(L, 1); char **argv = (char **)lua_touserdata(L, 2); int script; int has_i = 0, has_v = 0, has_e = 0; @@ -1,5 +1,5 @@ /* -** $Id: lua.h,v 1.273 2010/07/25 15:18:19 roberto Exp $ +** $Id: lua.h,v 1.276 2010/10/26 19:32:19 roberto Exp $ ** Lua - A Scripting Language ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) ** See Copyright Notice at the end of this file @@ -18,7 +18,7 @@ #define LUA_VERSION_MAJOR "5" #define LUA_VERSION_MINOR "2" -#define LUA_VERSION_RELEASE "0" " (work4)" +#define LUA_VERSION_RELEASE "0" " (work5)" #define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR #define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE @@ -106,6 +106,9 @@ typedef LUA_NUMBER lua_Number; /* type for integer functions */ typedef LUA_INTEGER lua_Integer; +/* unsigned integer type */ +typedef LUA_UNSIGNED lua_Unsigned; + /* @@ -159,6 +162,7 @@ LUA_API const char *(lua_typename) (lua_State *L, int tp); LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum); LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum); +LUA_API lua_Unsigned (lua_tounsignedx) (lua_State *L, int idx, int *isnum); LUA_API int (lua_toboolean) (lua_State *L, int idx); LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); LUA_API size_t (lua_rawlen) (lua_State *L, int idx); @@ -196,6 +200,7 @@ LUA_API int (lua_compare) (lua_State *L, int idx1, int idx2, int op); LUA_API void (lua_pushnil) (lua_State *L); LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); +LUA_API void (lua_pushunsigned) (lua_State *L, lua_Unsigned n); LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t l); LUA_API const char *(lua_pushstring) (lua_State *L, const char *s); LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, @@ -271,9 +276,10 @@ LUA_API int (lua_status) (lua_State *L); #define LUA_GCSTEP 5 #define LUA_GCSETPAUSE 6 #define LUA_GCSETSTEPMUL 7 -#define LUA_GCISRUNNING 8 -#define LUA_GCGEN 9 -#define LUA_GCINC 10 +#define LUA_GCSETMAJORINC 8 +#define LUA_GCISRUNNING 9 +#define LUA_GCGEN 10 +#define LUA_GCINC 11 LUA_API int (lua_gc) (lua_State *L, int what, int data); @@ -302,6 +308,7 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); #define lua_tonumber(L,i) lua_tonumberx(L,i,NULL) #define lua_tointeger(L,i) lua_tointegerx(L,i,NULL) +#define lua_tounsigned(L,i) lua_tounsignedx(L,i,NULL) #define lua_pop(L,n) lua_settop(L, -(n)-1) @@ -1,5 +1,5 @@ /* -** $Id: luac.c,v 1.61 2010/05/14 11:40:22 lhf Exp $ +** $Id: luac.c,v 1.65 2010/10/26 09:07:52 lhf Exp $ ** Lua compiler (saves bytecodes to files; also list bytecodes) ** See Copyright Notice in lua.h */ @@ -15,14 +15,13 @@ #include "lua.h" #include "lauxlib.h" -#include "ldo.h" -#include "lfunc.h" -#include "lmem.h" #include "lobject.h" -#include "lopcodes.h" -#include "lstring.h" +#include "lstate.h" #include "lundump.h" +static void PrintFunction(const Proto* f, int full); +#define luaU_print PrintFunction + #define PROGNAME "luac" /* default program name */ #define OUTPUT PROGNAME ".out" /* default output file */ @@ -52,16 +51,16 @@ static void usage(const char* message) else fprintf(stderr,"%s: %s\n",progname,message); fprintf(stderr, - "usage: %s [options] [filenames]\n" - "Available options are:\n" - " -l list\n" - " -o name output to file " LUA_QL("name") " (default is \"%s\")\n" - " -p parse only\n" - " -s strip debug information\n" - " -v show version information\n" - " -- stop handling options\n" - " - stop handling options and process stdin\n" - ,progname,Output); + "usage: %s [options] [filenames]\n" + "Available options are:\n" + " -l list\n" + " -o name output to file " LUA_QL("name") " (default is \"%s\")\n" + " -p parse only\n" + " -s strip debug information\n" + " -v show version information\n" + " -- stop handling options\n" + " - stop handling options and process stdin\n" + ,progname,Output); exit(EXIT_FAILURE); } @@ -89,7 +88,8 @@ static int doargs(int argc, char* argv[]) else if (IS("-o")) /* output file */ { output=argv[++i]; - if (output==NULL || *output==0 || *output=='-') usage(LUA_QL("-o") " needs argument"); + if (output==NULL || *output==0 || (*output=='-' && output[1]!=0)) + usage(LUA_QL("-o") " needs argument"); if (IS("-")) output=NULL; } else if (IS("-p")) /* parse only */ @@ -114,7 +114,24 @@ static int doargs(int argc, char* argv[]) return i; } -#define toproto(L,i) (clvalue(L->top+(i))->l.p) +#define FUNCTION "(function()end)();" + +static const char* reader(lua_State *L, void *ud, size_t *size) +{ + UNUSED(L); + if ((*(int*)ud)--) + { + *size=sizeof(FUNCTION)-1; + return FUNCTION; + } + else + { + *size=0; + return NULL; + } +} + +#define toproto(L,i) getproto(L->top+(i)) static const Proto* combine(lua_State* L, int n) { @@ -122,24 +139,13 @@ static const Proto* combine(lua_State* L, int n) return toproto(L,-1); else { - int i,pc; - Proto* f=luaF_newproto(L); - setptvalue2s(L,L->top,f); incr_top(L); - f->source=luaS_newliteral(L,"=(" PROGNAME ")"); - f->maxstacksize=1; - pc=2*n+1; - f->code=luaM_newvector(L,pc,Instruction); - f->sizecode=pc; - f->p=luaM_newvector(L,n,Proto*); - f->sizep=n; - pc=0; - for (i=0; i<n; i++) - { - f->p[i]=toproto(L,i-n-1); - f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,i); - f->code[pc++]=CREATE_ABC(OP_CALL,0,1,1); - } - f->code[pc++]=CREATE_ABC(OP_RETURN,0,1,0); + Proto* f; + int i=n; + if (lua_load(L,reader,&i,"=(" PROGNAME ")")!=LUA_OK) fatal(lua_tostring(L,-1)); + f=toproto(L,-1); + for (i=0; i<n; i++) f->p[i]=toproto(L,i-n-1); + f->sizelineinfo=0; + f->sizeupvalues=0; return f; } } @@ -152,7 +158,7 @@ static int writer(lua_State* L, const void* p, size_t size, void* u) static int pmain(lua_State* L) { - int argc=lua_tointeger(L,1); + int argc=(int)lua_tointeger(L,1); char** argv=lua_touserdata(L,2); const Proto* f; int i; @@ -160,7 +166,7 @@ static int pmain(lua_State* L) for (i=0; i<argc; i++) { const char* filename=IS("-") ? NULL : argv[i]; - if (luaL_loadfile(L,filename)!=0) fatal(lua_tostring(L,-1)); + if (luaL_loadfile(L,filename)!=LUA_OK) fatal(lua_tostring(L,-1)); } f=combine(L,argc); if (listing) luaU_print(f,listing>1); @@ -188,7 +194,235 @@ int main(int argc, char* argv[]) lua_pushcfunction(L,&pmain); lua_pushinteger(L,argc); lua_pushlightuserdata(L,argv); - if (lua_pcall(L,2,0,0)!=0) fatal(lua_tostring(L,-1)); + if (lua_pcall(L,2,0,0)!=LUA_OK) fatal(lua_tostring(L,-1)); lua_close(L); return EXIT_SUCCESS; } + +/* +** $Id: print.c,v 1.66 2010/10/26 09:07:52 lhf Exp $ +** print bytecodes +** See Copyright Notice in lua.h +*/ + +#include <ctype.h> +#include <stdio.h> + +#define luac_c +#define LUA_CORE + +#include "ldebug.h" +#include "lobject.h" +#include "lopcodes.h" + +#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; + printf("%c",'"'); + for (i=0; i<n; i++) + { + int c=(int)(unsigned char)s[i]; + switch (c) + { + case '"': printf("\\\""); break; + case '\\': printf("\\\\"); break; + case '\a': printf("\\a"); break; + case '\b': printf("\\b"); break; + case '\f': printf("\\f"); break; + case '\n': printf("\\n"); break; + case '\r': printf("\\r"); break; + case '\t': printf("\\t"); break; + case '\v': printf("\\v"); break; + default: if (isprint(c)) + printf("%c",c); + else + printf("\\%03d",c); + } + } + printf("%c",'"'); +} + +static void PrintConstant(const Proto* f, int i) +{ + const TValue* o=&f->k[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; + } +} + +#define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-") + +static void PrintCode(const Proto* f) +{ + const Instruction* code=f->code; + int pc,n=f->sizecode; + for (pc=0; pc<n; pc++) + { + Instruction i=code[pc]; + OpCode o=GET_OPCODE(i); + int a=GETARG_A(i); + int b=GETARG_B(i); + int c=GETARG_C(i); + int ax=GETARG_Ax(i); + int bx=GETARG_Bx(i); + int sbx=GETARG_sBx(i); + int line=getfuncline(f,pc); + printf("\t%d\t",pc+1); + if (line>0) 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,-bx); else printf("%d %d",a,bx); + break; + case iAsBx: + if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx); + break; + case iAx: + printf("%d",-1-ax); + break; + } + switch (o) + { + case OP_LOADK: + if (bx>0) { printf("\t; "); PrintConstant(f,bx-1); } + break; + case OP_GETUPVAL: + case OP_SETUPVAL: + printf("\t; %s",UPVALNAME(b)); + break; + case OP_GETTABUP: + printf("\t; %s",UPVALNAME(b)); + if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); } + break; + case OP_SETTABUP: + printf("\t; %s",UPVALNAME(a)); + if (ISK(b)) { printf(" "); PrintConstant(f,INDEXK(b)); } + if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); } + 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: + case OP_TFORLOOP: + 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; + case OP_EXTRAARG: + printf("\t; "); PrintConstant(f,ax); + break; + default: + break; + } + printf("\n"); + } +} + +#define SS(x) ((x==1)?"":"s") +#define S(x) (int)(x),SS(x) + +static void PrintHeader(const Proto* f) +{ + const char* s=f->source ? 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 at %p)\n", + (f->linedefined==0)?"main":"function",s, + f->linedefined,f->lastlinedefined, + S(f->sizecode),VOID(f)); + printf("%d%s param%s, %d slot%s, %d upvalue%s, ", + (int)(f->numparams),f->is_vararg?"+":"",SS(f->numparams), + S(f->maxstacksize),S(f->sizeupvalues)); + printf("%d local%s, %d constant%s, %d function%s\n", + S(f->sizelocvars),S(f->sizek),S(f->sizep)); +} + +static void PrintDebug(const Proto* f) +{ + int i,n; + n=f->sizek; + printf("constants (%d) for %p:\n",n,VOID(f)); + for (i=0; i<n; i++) + { + printf("\t%d\t",i+1); + PrintConstant(f,i); + printf("\n"); + } + n=f->sizelocvars; + printf("locals (%d) for %p:\n",n,VOID(f)); + for (i=0; i<n; i++) + { + printf("\t%d\t%s\t%d\t%d\n", + i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1); + } + n=f->sizeupvalues; + printf("upvalues (%d) for %p:\n",n,VOID(f)); + for (i=0; i<n; i++) + { + printf("\t%d\t%s\t%d\t%d\n", + i,UPVALNAME(i),f->upvalues[i].instack,f->upvalues[i].idx); + } +} + +static void PrintFunction(const Proto* f, int full) +{ + int i,n=f->sizep; + PrintHeader(f); + PrintCode(f); + if (full) PrintDebug(f); + for (i=0; i<n; i++) PrintFunction(f->p[i],full); +} diff --git a/src/luaconf.h b/src/luaconf.h index 12ec5fc1..2345e00c 100644 --- a/src/luaconf.h +++ b/src/luaconf.h @@ -1,5 +1,5 @@ /* -** $Id: luaconf.h,v 1.142 2010/07/28 15:51:59 roberto Exp $ +** $Id: luaconf.h,v 1.148 2010/10/29 17:52:46 roberto Exp $ ** Configuration file for Lua ** See Copyright Notice in lua.h */ @@ -47,8 +47,8 @@ #if defined(LUA_USE_MACOSX) #define LUA_USE_POSIX -#define LUA_USE_DLOPEN -#define LUA_USE_READLINE /* needs some extra libraries */ +#define LUA_USE_DLOPEN /* does not need -ldl */ +#define LUA_USE_READLINE /* needs an extra library: -lreadline */ #endif @@ -116,6 +116,14 @@ /* +@@ LUA_ENV is the name of the variable that holds the current +@@ environment, used to access global names. +** CHANGE it if you do not like this name. +*/ +#define LUA_ENV "_ENV" + + +/* @@ LUA_API is a mark for all core API functions. @@ LUALIB_API is a mark for all auxiliary library functions. @@ LUAMOD_API is a mark for all standard library opening functions. @@ -430,26 +438,28 @@ */ #define LUA_INTEGER ptrdiff_t +/* +@@ LUA_UNSIGNED is the integral type used by lua_pushunsigned/lua_tounsigned. +** It must have at least 32 bits. +*/ +#define LUA_UNSIGNED unsigned LUA_INT32 + /* @@ lua_number2int is a macro to convert lua_Number to int. @@ lua_number2integer is a macro to convert lua_Number to LUA_INTEGER. -@@ lua_number2uint is a macro to convert a lua_Number to an unsigned -@* LUA_INT32. -@@ lua_uint2number is a macro to convert an unsigned LUA_INT32 -@* to a lua_Number. -** CHANGE them if you know a faster way to convert a lua_Number to -** int (with any rounding method and without throwing errors) in your -** system. In Pentium machines, a naive typecast from double to int -** in C is extremely slow, so any alternative is worth trying. +@@ lua_number2uint is a macro to convert a lua_Number to a LUA_UNSIGNED. +@@ lua_uint2number is a macro to convert a LUA_UNSIGNED to a lua_Number. */ -/* On a Pentium, resort to a trick */ -#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \ - (defined(__i386) || defined (_M_IX86) || defined(__i386__)) /* { */ +#if defined(LUA_CORE) /* { */ + +#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && \ + !defined(LUA_NOIEEE754TRICK) /* { */ -/* On a Microsoft compiler, use assembler */ -#if defined(_MSC_VER) /* { */ +/* On a Microsoft compiler on a Pentium, use assembler to avoid clashes + with a DirectX idiosyncrasy */ +#if defined(_MSC_VER) && defined(M_IX86) /* { */ #define lua_number2int(i,n) __asm {__asm fld n __asm fistp i} #define lua_number2integer(i,n) lua_number2int(i, n) @@ -457,31 +467,76 @@ {__int64 l; __asm {__asm fld n __asm fistp l} i = (unsigned int)l;} #else /* }{ */ -/* the next trick should work on any Pentium, but sometimes clashes - with a DirectX idiosyncrasy */ +/* the next trick should work on any machine using IEEE754 with + a 32-bit integer type */ -union luai_Cast { double l_d; long l_l; }; -#define lua_number2int(i,n) \ - { volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; (i) = u.l_l; } -#define lua_number2integer(i,n) lua_number2int(i, n) -#define lua_number2uint(i,n) lua_number2int(i, n) +union luai_Cast { double l_d; LUA_INT32 l_p[2]; }; + +/* +@@ LUA_IEEEENDIAN is the endianness of doubles in your machine +@@ (0 for little endian, 1 for big endian); if not defined, Lua will +@@ check it dynamically. +*/ +/* check for known architectures */ +#if defined(__i386__) || defined(__i386) || defined(i386) || \ + defined (__x86_64) +#define LUA_IEEEENDIAN 0 +#elif defined(__POWERPC__) || defined(__ppc__) +#define LUA_IEEEENDIAN 1 +#endif + +#if !defined(LUA_IEEEENDIAN) /* { */ +#define LUAI_EXTRAIEEE \ + static const union luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)}; +#define LUA_IEEEENDIAN (ieeeendian.l_p[1] == 33) +#else +#define LUAI_EXTRAIEEE /* empty */ +#endif /* } */ + +#define lua_number2int32(i,n,t) \ + { LUAI_EXTRAIEEE \ + volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; \ + (i) = (t)u.l_p[LUA_IEEEENDIAN]; } + +#define lua_number2int(i,n) lua_number2int32(i, n, int) +#define lua_number2integer(i,n) lua_number2int32(i, n, LUA_INTEGER) +#define lua_number2uint(i,n) lua_number2int32(i, n, LUA_UNSIGNED) #endif /* } */ -#else /* }{ */ -/* this option always works, but may be slow */ +#endif /* } */ + + +/* the following definitions always work, but may be slow */ + +#if !defined(lua_number2int) #define lua_number2int(i,n) ((i)=(int)(n)) -#define lua_number2integer(i,n) ((i)=(LUA_INTEGER)(n)) -#define lua_number2uint(i,n) ((i)=(unsigned LUA_INT32)(n)) +#endif -#endif /* } */ +#if !defined(lua_number2integer) +#define lua_number2integer(i,n) ((i)=(LUA_INTEGER)(n)) +#endif +#if !defined(lua_number2uint) && (defined(lapi_c) || defined(luaall_c)) /* { */ +/* the following definition assures proper modulo behavior */ +#if defined(LUA_NUMBER_DOUBLE) +#include <math.h> +#define lua_number2uint(i,n) \ + ((i)=(LUA_UNSIGNED)((n) - floor((n)/4294967296.0)*4294967296.0)) +#else +#define lua_number2uint(i,n) ((i)=(LUA_UNSIGNED)(n)) +#endif +#endif /* } */ -/* on several machines, coercion from unsigned to double is too slow, - so avoid that if possible */ +#if !defined(lua_uint2number) +/* on several machines, coercion from unsigned to double is slow, + so it may be worth to avoid */ #define lua_uint2number(u) \ ((LUA_INT32)(u) < 0 ? (lua_Number)(u) : (lua_Number)(LUA_INT32)(u)) +#endif + +#endif /* } */ /* diff --git a/src/lualib.h b/src/lualib.h index db2e200e..233a331e 100644 --- a/src/lualib.h +++ b/src/lualib.h @@ -1,5 +1,5 @@ /* -** $Id: lualib.h,v 1.40 2010/06/10 21:29:47 roberto Exp $ +** $Id: lualib.h,v 1.41 2010/10/25 14:32:36 roberto Exp $ ** Lua standard libraries ** See Copyright Notice in lua.h */ @@ -32,8 +32,8 @@ LUAMOD_API int (luaopen_os) (lua_State *L); #define LUA_STRLIBNAME "string" LUAMOD_API int (luaopen_string) (lua_State *L); -#define LUA_BITLIBNAME "bit" -LUAMOD_API int (luaopen_bit) (lua_State *L); +#define LUA_BITLIBNAME "bit32" +LUAMOD_API int (luaopen_bit32) (lua_State *L); #define LUA_MATHLIBNAME "math" LUAMOD_API int (luaopen_math) (lua_State *L); diff --git a/src/lundump.c b/src/lundump.c index e82e1951..c875d767 100644 --- a/src/lundump.c +++ b/src/lundump.c @@ -1,5 +1,5 @@ /* -** $Id: lundump.c,v 2.13 2010/03/12 19:14:06 roberto Exp $ +** $Id: lundump.c,v 1.68 2010/10/26 00:23:46 lhf Exp $ ** load precompiled Lua chunks ** See Copyright Notice in lua.h */ @@ -27,27 +27,20 @@ typedef struct { const char* name; } LoadState; -#ifdef LUAC_TRUST_BINARIES -#define IF(c,s) -#else -#define IF(c,s) if (c) error(S,s) - static void error(LoadState* S, const char* why) { - luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why); + luaO_pushfstring(S->L,"%s: %s precompiled chunk",S->name,why); luaD_throw(S->L,LUA_ERRSYNTAX); } -#endif #define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) -#define LoadByte(S) (lu_byte)LoadChar(S) +#define LoadByte(S) (lu_byte)LoadChar(S) #define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) #define LoadVector(S,b,n,size) LoadMem(S,b,n,size) static void LoadBlock(LoadState* S, void* b, size_t size) { - size_t r=luaZ_read(S->Z,b,size); - IF (r!=0, "unexpected end"); + if (luaZ_read(S->Z,b,size)!=0) error(S,"corrupted"); } static int LoadChar(LoadState* S) @@ -61,7 +54,6 @@ static int LoadInt(LoadState* S) { int x; LoadVar(S,x); - IF (x<0, "bad integer"); return x; } @@ -94,7 +86,7 @@ static void LoadCode(LoadState* S, Proto* f) LoadVector(S,f->code,n,sizeof(Instruction)); } -static Proto* LoadFunction(LoadState* S, TString* p); +static Proto* LoadFunction(LoadState* S); static void LoadConstants(LoadState* S, Proto* f) { @@ -113,7 +105,7 @@ static void LoadConstants(LoadState* S, Proto* f) setnilvalue(o); break; case LUA_TBOOLEAN: - setbvalue(o,LoadChar(S)!=0); + setbvalue(o,LoadChar(S)); break; case LUA_TNUMBER: setnvalue(o,LoadNumber(S)); @@ -121,16 +113,13 @@ static void LoadConstants(LoadState* S, Proto* f) case LUA_TSTRING: setsvalue2n(S->L,o,LoadString(S)); break; - default: - IF (1, "bad constant"); - break; } } n=LoadInt(S); f->p=luaM_newvector(S->L,n,Proto*); f->sizep=n; for (i=0; i<n; i++) f->p[i]=NULL; - for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source); + for (i=0; i<n; i++) f->p[i]=LoadFunction(S); } static void LoadUpvalues(LoadState* S, Proto* f) @@ -150,6 +139,7 @@ static void LoadUpvalues(LoadState* S, Proto* f) static void LoadDebug(LoadState* S, Proto* f) { int i,n; + f->source=LoadString(S); n=LoadInt(S); f->lineinfo=luaM_newvector(S->L,n,int); f->sizelineinfo=n; @@ -168,13 +158,10 @@ static void LoadDebug(LoadState* S, Proto* f) for (i=0; i<n; i++) f->upvalues[i].name=LoadString(S); } -static Proto* LoadFunction(LoadState* S, TString* p) +static Proto* LoadFunction(LoadState* S) { - Proto* f; - if (++G(S->L)->nCcalls > LUAI_MAXCCALLS) error(S, "function nest too deep"); - f=luaF_newproto(S->L); + Proto* 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); f->lastlinedefined=LoadInt(S); f->numparams=LoadByte(S); @@ -185,17 +172,25 @@ static Proto* LoadFunction(LoadState* S, TString* p) LoadUpvalues(S,f); LoadDebug(S,f); S->L->top--; - G(S->L)->nCcalls--; return f; } +/* the code below must be consistent with the code in luaU_header */ +#define N0 LUAC_HEADERSIZE +#define N1 (sizeof(LUA_SIGNATURE)-1) +#define N2 N1+2 +#define N3 N2+6 + static void LoadHeader(LoadState* S) { char h[LUAC_HEADERSIZE]; char s[LUAC_HEADERSIZE]; luaU_header(h); LoadBlock(S,s,LUAC_HEADERSIZE); - IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header"); + if (memcmp(h,s,N0)==0) return; + if (memcmp(h,s,N1)!=0) error(S,"not a"); + if (memcmp(h,s,N2)!=0) error(S,"version mismatch in"); + if (memcmp(h,s,N3)!=0) error(S,"incompatible"); else error(S,"corrupted"); } /* @@ -214,23 +209,29 @@ Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) S.Z=Z; S.b=buff; LoadHeader(&S); - return LoadFunction(&S,luaS_newliteral(L,"=?")); + return LoadFunction(&S); } +/* data to catch conversion errors */ +#define TAIL "\x19\x93\r\n\x1a\n" + /* -* make header +* make header for precompiled chunks +* if you make any changes in the code below or in LUA_SIGNATURE in lua.h, +* be sure to update LoadHeader above and LUAC_HEADERSIZE in lundump.h */ void luaU_header (char* h) { int x=1; memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1); h+=sizeof(LUA_SIGNATURE)-1; - *h++=(char)LUAC_VERSION; - *h++=(char)LUAC_FORMAT; + *h++=(char)0x52; /* Lua 5.2 */ + *h++=(char)0; /* the official format */ *h++=(char)*(char*)&x; /* endianness */ *h++=(char)sizeof(int); *h++=(char)sizeof(size_t); *h++=(char)sizeof(Instruction); *h++=(char)sizeof(lua_Number); *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */ + memcpy(h,TAIL,sizeof(TAIL)-1); } diff --git a/src/lundump.h b/src/lundump.h index 5b19104f..e55918cf 100644 --- a/src/lundump.h +++ b/src/lundump.h @@ -1,5 +1,5 @@ /* -** $Id: lundump.h,v 1.37 2005/11/16 11:55:07 roberto Exp $ +** $Id: lundump.h,v 1.43 2010/10/26 00:23:46 lhf Exp $ ** load precompiled Lua chunks ** See Copyright Notice in lua.h */ @@ -19,18 +19,7 @@ LUAI_FUNC void luaU_header (char* h); /* dump one chunk; from ldump.c */ LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); -#ifdef luac_c -/* print one chunk; from print.c */ -LUAI_FUNC void luaU_print (const Proto* f, int full); -#endif - -/* for header of binary files -- this is Lua 5.1 */ -#define LUAC_VERSION 0x51 - -/* for header of binary files -- this is the official format */ -#define LUAC_FORMAT 0 - /* size of header of binary files */ -#define LUAC_HEADERSIZE 12 +#define LUAC_HEADERSIZE 18 #endif @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 2.123 2010/06/30 14:11:17 roberto Exp $ +** $Id: lvm.c,v 2.125 2010/10/29 17:52:46 roberto Exp $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -301,7 +301,7 @@ void luaV_concat (lua_State *L, int total) { setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); } total -= n-1; /* got 'n' strings to create 1 new */ - L->top -= n-1; /* poped 'n' strings and pushed one */ + L->top -= n-1; /* popped 'n' strings and pushed one */ } while (total > 1); /* repeat until only 1 result left */ } @@ -421,7 +421,7 @@ void luaV_finishOp (lua_State *L) { case OP_CONCAT: { StkId top = L->top - 1; /* top when 'call_binTM' was called */ int b = GETARG_B(inst); /* first element to concatenate */ - int total = top - 1 - (base + b); /* elements yet to concatenate */ + int total = cast_int(top - 1 - (base + b)); /* yet to concatenate */ setobj2s(L, top - 2, top); /* put TM result in proper position */ if (total > 1) { /* are there elements to concat? */ L->top = top - 1; /* top is one after last element (at top-2) */ diff --git a/src/print.c b/src/print.c deleted file mode 100644 index 83a1cd68..00000000 --- a/src/print.c +++ /dev/null @@ -1,229 +0,0 @@ -/* -** $Id: print.c,v 1.61 2010/07/31 11:34:07 lhf Exp $ -** print bytecodes -** See Copyright Notice in lua.h -*/ - -#include <ctype.h> -#include <stdio.h> - -#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; i<n; i++) - { - int c=s[i]; - switch (c) - { - case '"': printf("\\\""); break; - case '\\': printf("\\\\"); break; - case '\a': printf("\\a"); break; - case '\b': printf("\\b"); break; - case '\f': printf("\\f"); break; - case '\n': printf("\\n"); break; - case '\r': printf("\\r"); break; - case '\t': printf("\\t"); break; - case '\v': printf("\\v"); break; - default: if (isprint((unsigned char)c)) - putchar(c); - else - printf("\\%03u",(unsigned char)c); - } - } - putchar('"'); -} - -static void PrintConstant(const Proto* f, int i) -{ - const TValue* o=&f->k[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; - } -} - -#define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-") - -static void PrintCode(const Proto* f) -{ - const Instruction* code=f->code; - int pc,n=f->sizecode; - for (pc=0; pc<n; pc++) - { - Instruction i=code[pc]; - OpCode o=GET_OPCODE(i); - int a=GETARG_A(i); - int b=GETARG_B(i); - int c=GETARG_C(i); - int ax=GETARG_Ax(i); - int bx=GETARG_Bx(i); - int sbx=GETARG_sBx(i); - int line=getfuncline(f,pc); -#ifdef LUAC_DUMP_INSTRUCTIONS - printf("%0*X",2*sizeof(i),i); -#endif - printf("\t%d\t",pc+1); - if (line>0) 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,-bx); else printf("%d %d",a,bx); - break; - case iAsBx: - if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx); - break; - case iAx: - printf("%d",ax); - break; - } - switch (o) - { - case OP_LOADK: - printf("\t; "); PrintConstant(f,bx-1); - break; - case OP_GETUPVAL: - case OP_SETUPVAL: - printf("\t; %s", UPVALNAME(b)); - break; - case OP_GETTABUP: - printf("\t; %s", UPVALNAME(b)); - if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); } - break; - case OP_SETTABUP: - printf("\t; %s", UPVALNAME(a)); - if (ISK(b)) { printf(" "); PrintConstant(f,INDEXK(b)); } - if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); } - 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->sizeupvalues)); - printf("%d local%s, %d constant%s, %d function%s\n", - S(f->sizelocvars),S(f->sizek),S(f->sizep)); -} - -static void PrintDebug(const Proto* f) -{ - int i,n; - n=f->sizek; - printf("constants (%d) for %p:\n",n,VOID(f)); - for (i=0; i<n; i++) - { - printf("\t%d\t",i+1); - PrintConstant(f,i); - printf("\n"); - } - n=f->sizelocvars; - printf("locals (%d) for %p:\n",n,VOID(f)); - for (i=0; i<n; i++) - { - printf("\t%d\t%s\t%d\t%d\n", - i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1); - } - n=f->sizeupvalues; - printf("upvalues (%d) for %p:\n",n,VOID(f)); - if (f->upvalues==NULL) return; - for (i=0; i<n; i++) - { - printf("\t%d\t%s\n",i,getstr(f->upvalues[i].name)); - } -} - -void PrintFunction(const Proto* f, int full) -{ - int i,n=f->sizep; - PrintHeader(f); - PrintCode(f); - if (full) PrintDebug(f); - for (i=0; i<n; i++) PrintFunction(f->p[i],full); -} |