summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Drahoš <drahosp@gmail.com>2011-12-17 00:10:30 +0100
committerPeter Drahoš <drahosp@gmail.com>2011-12-17 00:10:30 +0100
commit0713c5ca0b7b60ab525019ee77200d19f7c4be03 (patch)
tree503047beba08224e011f877dc0d23ca455e6b2cf
parent9358cd648bc92ccdd4b3492375a53f2c8ca18bbc (diff)
downloadlua-0713c5ca0b7b60ab525019ee77200d19f7c4be03.tar.gz
Lua 5.2 release.
-rw-r--r--[-rwxr-xr-x]Makefile4
-rw-r--r--[-rwxr-xr-x]README2
-rw-r--r--dist.info2
-rwxr-xr-xdoc/alert.pngbin1411 -> 0 bytes
-rw-r--r--[-rwxr-xr-x]src/Makefile1
-rw-r--r--[-rwxr-xr-x]src/lapi.c129
-rw-r--r--[-rwxr-xr-x]src/lapi.h0
-rw-r--r--[-rwxr-xr-x]src/lauxlib.c35
-rw-r--r--[-rwxr-xr-x]src/lauxlib.h39
-rw-r--r--[-rwxr-xr-x]src/lbaselib.c114
-rw-r--r--[-rwxr-xr-x]src/lbitlib.c0
-rw-r--r--[-rwxr-xr-x]src/lcode.c22
-rw-r--r--[-rwxr-xr-x]src/lcode.h3
-rw-r--r--[-rwxr-xr-x]src/lcorolib.c4
-rw-r--r--[-rwxr-xr-x]src/lctype.c5
-rw-r--r--[-rwxr-xr-x]src/lctype.h4
-rw-r--r--[-rwxr-xr-x]src/ldblib.c11
-rw-r--r--[-rwxr-xr-x]src/ldebug.c204
-rw-r--r--[-rwxr-xr-x]src/ldebug.h20
-rw-r--r--[-rwxr-xr-x]src/ldo.c61
-rw-r--r--[-rwxr-xr-x]src/ldo.h7
-rw-r--r--[-rwxr-xr-x]src/ldump.c6
-rw-r--r--[-rwxr-xr-x]src/lfunc.c0
-rw-r--r--[-rwxr-xr-x]src/lfunc.h0
-rw-r--r--[-rwxr-xr-x]src/lgc.c162
-rw-r--r--[-rwxr-xr-x]src/lgc.h6
-rw-r--r--[-rwxr-xr-x]src/linit.c0
-rw-r--r--[-rwxr-xr-x]src/liolib.c106
-rw-r--r--[-rwxr-xr-x]src/llex.c93
-rw-r--r--[-rwxr-xr-x]src/llex.h4
-rw-r--r--[-rwxr-xr-x]src/llimits.h24
-rw-r--r--[-rwxr-xr-x]src/lmathlib.c0
-rw-r--r--[-rwxr-xr-x]src/lmem.c7
-rw-r--r--[-rwxr-xr-x]src/lmem.h10
-rw-r--r--[-rwxr-xr-x]src/loadlib.c129
-rw-r--r--src/loadlib_rel.c131
-rw-r--r--[-rwxr-xr-x]src/lobject.c13
-rw-r--r--[-rwxr-xr-x]src/lobject.h68
-rw-r--r--[-rwxr-xr-x]src/lopcodes.c0
-rw-r--r--[-rwxr-xr-x]src/lopcodes.h4
-rw-r--r--[-rwxr-xr-x]src/loslib.c28
-rw-r--r--[-rwxr-xr-x]src/lparser.c172
-rw-r--r--[-rwxr-xr-x]src/lparser.h13
-rw-r--r--[-rwxr-xr-x]src/lstate.c13
-rw-r--r--[-rwxr-xr-x]src/lstate.h6
-rw-r--r--[-rwxr-xr-x]src/lstring.c0
-rw-r--r--[-rwxr-xr-x]src/lstring.h0
-rw-r--r--[-rwxr-xr-x]src/lstrlib.c24
-rw-r--r--[-rwxr-xr-x]src/ltable.c73
-rw-r--r--[-rwxr-xr-x]src/ltable.h8
-rw-r--r--[-rwxr-xr-x]src/ltablib.c7
-rw-r--r--[-rwxr-xr-x]src/ltm.c0
-rw-r--r--[-rwxr-xr-x]src/ltm.h0
-rw-r--r--[-rwxr-xr-x]src/lua.c42
-rw-r--r--[-rwxr-xr-x]src/lua.h20
-rw-r--r--[-rwxr-xr-x]src/lua.hpp0
-rw-r--r--[-rwxr-xr-x]src/luac.c9
-rw-r--r--src/luaconf.h.in38
-rwxr-xr-xsrc/luaconf.h.orig528
-rw-r--r--[-rwxr-xr-x]src/lualib.h5
-rw-r--r--[-rwxr-xr-x]src/lundump.c6
-rw-r--r--[-rwxr-xr-x]src/lundump.h0
-rw-r--r--[-rwxr-xr-x]src/lvm.c58
-rw-r--r--[-rwxr-xr-x]src/lvm.h0
-rw-r--r--[-rwxr-xr-x]src/lzio.c4
-rw-r--r--[-rwxr-xr-x]src/lzio.h8
66 files changed, 1165 insertions, 1327 deletions
diff --git a/Makefile b/Makefile
index da62ab9..ec53e1a 100755..100644
--- a/Makefile
+++ b/Makefile
@@ -62,13 +62,13 @@ install: dummy
cd src && $(INSTALL_EXEC) $(TO_BIN) $(INSTALL_BIN)
cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC)
cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB)
- #cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN)
+ cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN)
uninstall:
cd src && cd $(INSTALL_BIN) && $(RM) $(TO_BIN)
cd src && cd $(INSTALL_INC) && $(RM) $(TO_INC)
cd src && cd $(INSTALL_LIB) && $(RM) $(TO_LIB)
- #cd doc && cd $(INSTALL_MAN) && $(RM) $(TO_MAN)
+ cd doc && cd $(INSTALL_MAN) && $(RM) $(TO_MAN)
local:
$(MAKE) install INSTALL_TOP=../install
diff --git a/README b/README
index f00e8e7..9c38467 100755..100644
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
-This is Lua 5.2 (beta), released on 05 Jul 2011.
+This is Lua 5.2, released on 12 Dec 2011.
For installation instructions, license details, and
further information about Lua, see doc/readme.html.
diff --git a/dist.info b/dist.info
index 2d9961d..95e41d4 100644
--- a/dist.info
+++ b/dist.info
@@ -1,7 +1,7 @@
--- This file is part of LuaDist project
name = "lua"
-version = "5.2-beta"
+version = "5.2"
desc = "Lua is a powerful, fast, light-weight, embeddable scripting language."
author = "Roberto Ierusalimschy, Waldemar Celes, Luiz Henrique de Figueiredo"
diff --git a/doc/alert.png b/doc/alert.png
deleted file mode 100755
index 4938074..0000000
--- a/doc/alert.png
+++ /dev/null
Binary files differ
diff --git a/src/Makefile b/src/Makefile
index a77f35d..bba1693 100755..100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -112,6 +112,7 @@ mingw:
$(MAKE) "LUA_A=lua52.dll" "LUA_T=lua.exe" \
"AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \
"SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe
+ $(MAKE) "LUAC_T=luac.exe" luac.exe
posix:
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX"
diff --git a/src/lapi.c b/src/lapi.c
index 7761419..e96ceb9 100755..100644
--- a/src/lapi.c
+++ b/src/lapi.c
@@ -1,5 +1,5 @@
/*
-** $Id: lapi.c,v 2.149 2011/06/13 14:13:06 roberto Exp $
+** $Id: lapi.c,v 2.159 2011/11/30 12:32:05 roberto Exp $
** Lua API
** See Copyright Notice in lua.h
*/
@@ -34,9 +34,13 @@ const char lua_ident[] =
"$LuaAuthors: " LUA_AUTHORS " $";
+/* value at a non-valid index */
+#define NONVALIDVALUE cast(TValue *, luaO_nilobject)
-#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject, \
- "invalid index")
+/* corresponding test */
+#define isvalid(o) ((o) != luaO_nilobject)
+
+#define api_checkvalidindex(L, i) api_check(L, isvalid(i), "invalid index")
static TValue *index2addr (lua_State *L, int idx) {
@@ -44,7 +48,7 @@ static TValue *index2addr (lua_State *L, int idx) {
if (idx > 0) {
TValue *o = ci->func + idx;
api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
- if (o >= L->top) return cast(TValue *, luaO_nilobject);
+ if (o >= L->top) return NONVALIDVALUE;
else return o;
}
else if (idx > LUA_REGISTRYINDEX) {
@@ -57,12 +61,10 @@ static TValue *index2addr (lua_State *L, int idx) {
idx = LUA_REGISTRYINDEX - idx;
api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
if (ttislcf(ci->func)) /* light C function? */
- return cast(TValue *, luaO_nilobject); /* it has no upvalues */
+ return NONVALIDVALUE; /* it has no upvalues */
else {
CClosure *func = clCvalue(ci->func);
- return (idx <= func->nupvalues)
- ? &func->upvalue[idx-1]
- : cast(TValue *, luaO_nilobject);
+ return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE;
}
}
}
@@ -237,7 +239,7 @@ LUA_API void lua_pushvalue (lua_State *L, int idx) {
LUA_API int lua_type (lua_State *L, int idx) {
StkId o = index2addr(L, idx);
- return (o == luaO_nilobject) ? LUA_TNONE : ttypenv(o);
+ return (isvalid(o) ? ttypenv(o) : LUA_TNONE);
}
@@ -275,8 +277,7 @@ LUA_API int lua_isuserdata (lua_State *L, int idx) {
LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
StkId o1 = index2addr(L, index1);
StkId o2 = index2addr(L, index2);
- return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
- : luaV_rawequalobj(o1, o2);
+ return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0;
}
@@ -305,17 +306,17 @@ LUA_API void lua_arith (lua_State *L, int op) {
LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
StkId o1, o2;
- int i;
+ int i = 0;
lua_lock(L); /* may call tag method */
o1 = index2addr(L, index1);
o2 = index2addr(L, index2);
- if (o1 == luaO_nilobject || o2 == luaO_nilobject)
- i = 0;
- else switch (op) {
- case LUA_OPEQ: i = equalobj(L, o1, o2); break;
- case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
- case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
- default: api_check(L, 0, "invalid option"); i = 0;
+ if (isvalid(o1) && isvalid(o2)) {
+ switch (op) {
+ case LUA_OPEQ: i = equalobj(L, o1, o2); break;
+ case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
+ case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
+ default: api_check(L, 0, "invalid option");
+ }
}
lua_unlock(L);
return i;
@@ -595,6 +596,17 @@ LUA_API int lua_pushthread (lua_State *L) {
*/
+LUA_API void lua_getglobal (lua_State *L, const char *var) {
+ Table *reg = hvalue(&G(L)->l_registry);
+ const TValue *gt; /* global table */
+ lua_lock(L);
+ gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
+ setsvalue2s(L, L->top++, luaS_new(L, var));
+ luaV_gettable(L, gt, L->top - 1, L->top - 1);
+ lua_unlock(L);
+}
+
+
LUA_API void lua_gettable (lua_State *L, int idx) {
StkId t;
lua_lock(L);
@@ -628,11 +640,24 @@ LUA_API void lua_rawget (lua_State *L, int idx) {
LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
- StkId o;
+ StkId t;
lua_lock(L);
- o = index2addr(L, idx);
- api_check(L, ttistable(o), "table expected");
- setobj2s(L, L->top, luaH_getint(hvalue(o), n));
+ t = index2addr(L, idx);
+ api_check(L, ttistable(t), "table expected");
+ setobj2s(L, L->top, luaH_getint(hvalue(t), n));
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_rawgetp (lua_State *L, int idx, const void *p) {
+ StkId t;
+ TValue k;
+ lua_lock(L);
+ t = index2addr(L, idx);
+ api_check(L, ttistable(t), "table expected");
+ setpvalue(&k, cast(void *, p));
+ setobj2s(L, L->top, luaH_get(hvalue(t), &k));
api_incr_top(L);
lua_unlock(L);
}
@@ -700,6 +725,19 @@ LUA_API void lua_getuservalue (lua_State *L, int idx) {
*/
+LUA_API void lua_setglobal (lua_State *L, const char *var) {
+ Table *reg = hvalue(&G(L)->l_registry);
+ const TValue *gt; /* global table */
+ lua_lock(L);
+ api_checknelems(L, 1);
+ gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
+ setsvalue2s(L, L->top++, luaS_new(L, var));
+ luaV_settable(L, gt, L->top - 1, L->top - 2);
+ L->top -= 2; /* pop value and key */
+ lua_unlock(L);
+}
+
+
LUA_API void lua_settable (lua_State *L, int idx) {
StkId t;
lua_lock(L);
@@ -732,6 +770,7 @@ LUA_API void lua_rawset (lua_State *L, int idx) {
t = index2addr(L, idx);
api_check(L, ttistable(t), "table expected");
setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
+ invalidateTMcache(hvalue(t));
luaC_barrierback(L, gcvalue(t), L->top-1);
L->top -= 2;
lua_unlock(L);
@@ -739,13 +778,28 @@ LUA_API void lua_rawset (lua_State *L, int idx) {
LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
- StkId o;
+ StkId t;
lua_lock(L);
api_checknelems(L, 1);
- o = index2addr(L, idx);
- api_check(L, ttistable(o), "table expected");
- setobj2t(L, luaH_setint(L, hvalue(o), n), L->top-1);
- luaC_barrierback(L, gcvalue(o), L->top-1);
+ t = index2addr(L, idx);
+ api_check(L, ttistable(t), "table expected");
+ luaH_setint(L, hvalue(t), n, L->top - 1);
+ luaC_barrierback(L, gcvalue(t), L->top-1);
+ L->top--;
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
+ StkId t;
+ TValue k;
+ lua_lock(L);
+ api_checknelems(L, 1);
+ t = index2addr(L, idx);
+ api_check(L, ttistable(t), "table expected");
+ setpvalue(&k, cast(void *, p));
+ setobj2t(L, luaH_set(L, hvalue(t), &k), L->top - 1);
+ luaC_barrierback(L, gcvalue(t), L->top - 1);
L->top--;
lua_unlock(L);
}
@@ -914,13 +968,13 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
- const char *chunkname) {
+ const char *chunkname, const char *mode) {
ZIO z;
int status;
lua_lock(L);
if (!chunkname) chunkname = "?";
luaZ_init(L, &z, reader, data);
- status = luaD_protectedparser(L, &z, chunkname);
+ status = luaD_protectedparser(L, &z, chunkname, mode);
if (status == LUA_OK) { /* no errors? */
LClosure *f = clLvalue(L->top - 1); /* get newly created function */
if (f->nupvalues == 1) { /* does it have one upvalue? */
@@ -1128,7 +1182,6 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
-
static const char *aux_upvalue (StkId fi, int n, TValue **val,
GCObject **owner) {
switch (ttype(fi)) {
@@ -1141,15 +1194,13 @@ static const char *aux_upvalue (StkId fi, int n, TValue **val,
}
case LUA_TLCL: { /* Lua closure */
LClosure *f = clLvalue(fi);
- const char *name;
+ TString *name;
Proto *p = f->p;
if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
*val = f->upvals[n-1]->v;
if (owner) *owner = obj2gco(f->upvals[n - 1]);
- name = getstr(p->upvalues[n-1].name);
- if (name == NULL) /* no debug information? */
- name = "";
- return name;
+ name = p->upvalues[n-1].name;
+ return (name == NULL) ? "" : getstr(name);
}
default: return NULL; /* not a closure */
}
@@ -1158,7 +1209,7 @@ static const char *aux_upvalue (StkId fi, int n, TValue **val,
LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
const char *name;
- TValue *val;
+ TValue *val = NULL; /* to avoid warnings */
lua_lock(L);
name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL);
if (name) {
@@ -1172,8 +1223,8 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
const char *name;
- TValue *val;
- GCObject *owner;
+ TValue *val = NULL; /* to avoid warnings */
+ GCObject *owner = NULL; /* to avoid warnings */
StkId fi;
lua_lock(L);
fi = index2addr(L, funcindex);
diff --git a/src/lapi.h b/src/lapi.h
index 0909a39..0909a39 100755..100644
--- a/src/lapi.h
+++ b/src/lapi.h
diff --git a/src/lauxlib.c b/src/lauxlib.c
index b765cfd..0aa80fd 100755..100644
--- a/src/lauxlib.c
+++ b/src/lauxlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.c,v 1.233 2011/06/16 14:11:04 roberto Exp $
+** $Id: lauxlib.c,v 1.240 2011/12/06 16:33:55 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -41,11 +41,10 @@
** return 1 + string at top if find a good name.
*/
static int findfield (lua_State *L, int objidx, int level) {
- int found = 0;
if (level == 0 || !lua_istable(L, -1))
return 0; /* not found */
lua_pushnil(L); /* start 'next' loop */
- while (!found && lua_next(L, -2)) { /* for each pair in table */
+ while (lua_next(L, -2)) { /* for each pair in table */
if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */
if (lua_rawequal(L, objidx, -1)) { /* found object? */
lua_pop(L, 1); /* remove value (but keep name) */
@@ -86,7 +85,7 @@ static void pushfuncname (lua_State *L, lua_Debug *ar) {
lua_pushfstring(L, "function " LUA_QS, ar->name);
else if (*ar->what == 'm') /* main? */
lua_pushfstring(L, "main chunk");
- else if (*ar->what == 'C' || *ar->what == 't') {
+ else if (*ar->what == 'C') {
if (pushglobalfuncname(L, ar)) {
lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1));
lua_remove(L, -2); /* remove name */
@@ -270,7 +269,7 @@ LUALIB_API int luaL_execresult (lua_State *L, int stat) {
*/
LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
- lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */
+ luaL_getmetatable(L, tname); /* try to get metatable */
if (!lua_isnil(L, -1)) /* name already in use? */
return 0; /* leave previous value on top, but return 0 */
lua_pop(L, 1);
@@ -291,7 +290,7 @@ LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) {
void *p = lua_touserdata(L, ud);
if (p != NULL) { /* value is a userdata? */
if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
- lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
+ luaL_getmetatable(L, tname); /* get correct metatable */
if (!lua_rawequal(L, -1, -2)) /* not the same? */
p = NULL; /* value is a userdata with wrong metatable */
lua_pop(L, 2); /* remove both metatables */
@@ -331,7 +330,9 @@ LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,
LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) {
- if (!lua_checkstack(L, space)) {
+ /* keep some extra space to run error routines, if needed */
+ const int extra = LUA_MINSTACK;
+ if (!lua_checkstack(L, space + extra)) {
if (msg)
luaL_error(L, "stack overflow (%s)", msg);
else
@@ -566,7 +567,7 @@ typedef struct LoadF {
static const char *getF (lua_State *L, void *ud, size_t *size) {
LoadF *lf = (LoadF *)ud;
- (void)L;
+ (void)L; /* not used */
if (lf->n > 0) { /* are there pre-read characters to be read? */
*size = lf->n; /* return them (chars already in buffer) */
lf->n = 0; /* no more pre-read characters */
@@ -623,7 +624,8 @@ static int skipcomment (LoadF *lf, int *cp) {
}
-LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
+LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
+ const char *mode) {
LoadF lf;
int status, readstatus;
int c;
@@ -646,7 +648,7 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
}
if (c != EOF)
lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */
- status = lua_load(L, getF, &lf, lua_tostring(L, -1));
+ status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode);
readstatus = ferror(lf.f);
if (filename) fclose(lf.f); /* close file (even in case of errors) */
if (readstatus) {
@@ -666,7 +668,7 @@ typedef struct LoadS {
static const char *getS (lua_State *L, void *ud, size_t *size) {
LoadS *ls = (LoadS *)ud;
- (void)L;
+ (void)L; /* not used */
if (ls->size == 0) return NULL;
*size = ls->size;
ls->size = 0;
@@ -674,12 +676,12 @@ static const char *getS (lua_State *L, void *ud, size_t *size) {
}
-LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,
- const char *name) {
+LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size,
+ const char *name, const char *mode) {
LoadS ls;
ls.s = buff;
ls.size = size;
- return lua_load(L, getS, &ls, name);
+ return lua_load(L, getS, &ls, name, mode);
}
@@ -913,8 +915,7 @@ LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
- (void)ud;
- (void)osize;
+ (void)ud; (void)osize; /* not used */
if (nsize == 0) {
free(ptr);
return NULL;
@@ -943,7 +944,7 @@ LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver) {
if (v != lua_version(NULL))
luaL_error(L, "multiple Lua VMs detected");
else if (*v != ver)
- luaL_error(L, "version mismatch: app. needs %d, Lua core provides %f",
+ luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f",
ver, *v);
/* check conversions number -> integer types */
lua_pushnumber(L, -(lua_Number)0x1234);
diff --git a/src/lauxlib.h b/src/lauxlib.h
index a7aa0d7..ac4d15f 100755..100644
--- a/src/lauxlib.h
+++ b/src/lauxlib.h
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.h,v 1.117 2011/06/16 14:10:12 roberto Exp $
+** $Id: lauxlib.h,v 1.120 2011/11/29 15:55:08 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -72,9 +72,13 @@ LUALIB_API int (luaL_execresult) (lua_State *L, int stat);
LUALIB_API int (luaL_ref) (lua_State *L, int t);
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
-LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
-LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
- const char *name);
+LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
+ const char *mode);
+
+#define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL)
+
+LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
+ const char *name, const char *mode);
LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
LUALIB_API lua_State *(luaL_newstate) (void);
@@ -127,6 +131,8 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
+#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL)
+
/*
** {======================================================
@@ -163,6 +169,31 @@ LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz);
/* }====================================================== */
+
+/*
+** {======================================================
+** File handles for IO library
+** =======================================================
+*/
+
+/*
+** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and
+** initial structure 'luaL_Stream' (it may contain other fields
+** after that initial structure).
+*/
+
+#define LUA_FILEHANDLE "FILE*"
+
+
+typedef struct luaL_Stream {
+ FILE *f; /* stream (NULL for incompletely created streams) */
+ lua_CFunction closef; /* to close stream (NULL for closed streams) */
+} luaL_Stream;
+
+/* }====================================================== */
+
+
+
/* compatibility with old module system */
#if defined(LUA_COMPAT_MODULE)
diff --git a/src/lbaselib.c b/src/lbaselib.c
index e4daf5d..1dfae30 100755..100644
--- a/src/lbaselib.c
+++ b/src/lbaselib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbaselib.c,v 1.264 2011/07/05 12:49:35 roberto Exp $
+** $Id: lbaselib.c,v 1.273 2011/11/30 13:03:24 roberto Exp $
** Basic library
** See Copyright Notice in lua.h
*/
@@ -46,20 +46,22 @@ static int luaB_print (lua_State *L) {
#define SPACECHARS " \f\n\r\t\v"
static int luaB_tonumber (lua_State *L) {
- int base = luaL_optint(L, 2, 10);
- luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
- if (base == 10) { /* standard conversion */
- luaL_checkany(L, 1);
- if (lua_isnumber(L, 1)) {
- lua_pushnumber(L, lua_tonumber(L, 1));
+ if (lua_isnoneornil(L, 2)) { /* standard conversion */
+ int isnum;
+ lua_Number n = lua_tonumberx(L, 1, &isnum);
+ if (isnum) {
+ lua_pushnumber(L, n);
return 1;
- } /* else not a number */
+ } /* else not a number; must be something */
+ luaL_checkany(L, 1);
}
else {
size_t l;
const char *s = luaL_checklstring(L, 1, &l);
const char *e = s + l; /* end point for 's' */
+ int base = luaL_checkint(L, 2);
int neg = 0;
+ luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
s += strspn(s, SPACECHARS); /* skip initial spaces */
if (*s == '-') { s++; neg = 1; } /* handle signal */
else if (*s == '+') s++;
@@ -158,7 +160,7 @@ 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",
- "setmajorinc", "isrunning", "gen", "inc", NULL};
+ "setmajorinc", "isrunning", "generational", "incremental", NULL};
static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC};
@@ -253,7 +255,14 @@ static int load_aux (lua_State *L, int status) {
static int luaB_loadfile (lua_State *L) {
const char *fname = luaL_optstring(L, 1, NULL);
- return load_aux(L, luaL_loadfile(L, fname));
+ const char *mode = luaL_optstring(L, 2, NULL);
+ int env = !lua_isnone(L, 3); /* 'env' parameter? */
+ int status = luaL_loadfilex(L, fname, mode);
+ if (status == LUA_OK && env) { /* 'env' parameter? */
+ lua_pushvalue(L, 3);
+ lua_setupvalue(L, -2, 1); /* set it as 1st upvalue of loaded chunk */
+ }
+ return load_aux(L, status);
}
@@ -264,26 +273,6 @@ static int luaB_loadfile (lua_State *L) {
*/
-typedef struct {
-char c;
- const char *mode;
-} loaddata;
-
-
-/*
-** check whether a chunk (prefix in 's') satisfies given 'mode'
-** ('t' for text, 'b' for binary). Returns error message (also
-** pushed on the stack) in case of errors.
-*/
-static const char *checkrights (lua_State *L, const char *mode, const char *s) {
- if (strchr(mode, 'b') == NULL && *s == LUA_SIGNATURE[0])
- return lua_pushstring(L, "attempt to load a binary chunk");
- if (strchr(mode, 't') == NULL && *s != LUA_SIGNATURE[0])
- return lua_pushstring(L, "attempt to load a text chunk");
- return NULL; /* chunk in allowed format */
-}
-
-
/*
** reserved slot, above all arguments, to hold a copy of the returned
** string to avoid it being collected while parsed. 'load' has four
@@ -299,8 +288,7 @@ static const char *checkrights (lua_State *L, const char *mode, const char *s) {
** reserved slot inside the stack.
*/
static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
- const char *s;
- loaddata *ld = (loaddata *)ud;
+ (void)(ud); /* not used */
luaL_checkstack(L, 2, "too many nested functions");
lua_pushvalue(L, 1); /* get function */
lua_call(L, 0, 1); /* call it */
@@ -308,19 +296,10 @@ static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
*size = 0;
return NULL;
}
- else if ((s = lua_tostring(L, -1)) != NULL) {
- if (ld->mode != NULL) { /* first time? */
- s = checkrights(L, ld->mode, s); /* check mode */
- ld->mode = NULL; /* to avoid further checks */
- if (s) luaL_error(L, s);
- }
- lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */
- return lua_tolstring(L, RESERVEDSLOT, size);
- }
- else {
+ else if (!lua_isstring(L, -1))
luaL_error(L, "reader function must return a string");
- return NULL; /* to avoid warnings */
- }
+ lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */
+ return lua_tolstring(L, RESERVEDSLOT, size);
}
@@ -332,16 +311,13 @@ static int luaB_load (lua_State *L) {
const char *mode = luaL_optstring(L, 3, "bt");
if (s != NULL) { /* loading a string? */
const char *chunkname = luaL_optstring(L, 2, s);
- status = (checkrights(L, mode, s) != NULL)
- || luaL_loadbuffer(L, s, l, chunkname);
+ status = luaL_loadbufferx(L, s, l, chunkname, mode);
}
else { /* loading from a reader function */
const char *chunkname = luaL_optstring(L, 2, "=(load)");
- loaddata ld;
- ld.mode = mode;
luaL_checktype(L, 1, LUA_TFUNCTION);
lua_settop(L, RESERVEDSLOT); /* create reserved slot */
- status = lua_load(L, generic_reader, &ld, chunkname);
+ status = lua_load(L, generic_reader, NULL, chunkname, mode);
}
if (status == LUA_OK && top >= 4) { /* is there an 'env' argument */
lua_pushvalue(L, 4); /* environment for loaded function */
@@ -390,27 +366,32 @@ static int luaB_select (lua_State *L) {
}
-static int pcallcont (lua_State *L) {
- int errfunc = 0; /* =0 to avoid warnings */
- int status = lua_getctx(L, &errfunc);
- lua_assert(status != LUA_OK);
- lua_pushboolean(L, (status == LUA_YIELD)); /* first result (status) */
- if (errfunc) /* came from xpcall? */
- lua_replace(L, 1); /* put first result in place of error function */
- else /* came from pcall */
- lua_insert(L, 1); /* open space for first result */
+static int finishpcall (lua_State *L, int status) {
+ if (!lua_checkstack(L, 1)) { /* no space for extra boolean? */
+ lua_settop(L, 0); /* create space for return values */
+ lua_pushboolean(L, 0);
+ lua_pushstring(L, "stack overflow");
+ return 2; /* return false, msg */
+ }
+ lua_pushboolean(L, status); /* first result (status) */
+ lua_replace(L, 1); /* put first result in first slot */
return lua_gettop(L);
}
+static int pcallcont (lua_State *L) {
+ int status = lua_getctx(L, NULL);
+ return finishpcall(L, (status == LUA_YIELD));
+}
+
+
static int luaB_pcall (lua_State *L) {
int status;
luaL_checkany(L, 1);
- status = lua_pcallk(L, lua_gettop(L) - 1, LUA_MULTRET, 0, 0, pcallcont);
- luaL_checkstack(L, 1, NULL);
- lua_pushboolean(L, (status == LUA_OK));
- lua_insert(L, 1);
- return lua_gettop(L); /* return status + all results */
+ lua_pushnil(L);
+ lua_insert(L, 1); /* create space for status result */
+ status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, pcallcont);
+ return finishpcall(L, (status == LUA_OK));
}
@@ -421,11 +402,8 @@ static int luaB_xpcall (lua_State *L) {
lua_pushvalue(L, 1); /* exchange function... */
lua_copy(L, 2, 1); /* ...and error handler */
lua_replace(L, 2);
- status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 1, pcallcont);
- luaL_checkstack(L, 1, NULL);
- lua_pushboolean(L, (status == LUA_OK));
- lua_replace(L, 1);
- return lua_gettop(L); /* return status + all results */
+ status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 0, pcallcont);
+ return finishpcall(L, (status == LUA_OK));
}
diff --git a/src/lbitlib.c b/src/lbitlib.c
index 7533b85..7533b85 100755..100644
--- a/src/lbitlib.c
+++ b/src/lbitlib.c
diff --git a/src/lcode.c b/src/lcode.c
index 00966a1..614e452 100755..100644
--- a/src/lcode.c
+++ b/src/lcode.c
@@ -1,5 +1,5 @@
/*
-** $Id: lcode.c,v 2.56 2011/05/31 18:27:56 roberto Exp $
+** $Id: lcode.c,v 2.60 2011/08/30 16:26:41 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -44,8 +44,8 @@ void luaK_nil (FuncState *fs, int from, int n) {
int pl = pfrom + GETARG_B(*previous);
if ((pfrom <= from && from <= pl + 1) ||
(from <= pfrom && pfrom <= l + 1)) { /* can connect both? */
- if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */
- if (pl > l) l = pl; /* l = max(l, pl) */
+ if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */
+ if (pl > l) l = pl; /* l = max(l, pl) */
SETARG_A(*previous, from);
SETARG_B(*previous, l - from);
return;
@@ -213,11 +213,11 @@ static int luaK_code (FuncState *fs, Instruction i) {
Proto *f = fs->f;
dischargejpc(fs); /* `pc' will change */
/* put new instruction in code array */
- luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
+ luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
MAX_INT, "opcodes");
f->code[fs->pc] = i;
/* save corresponding line information */
- luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
+ luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
MAX_INT, "opcodes");
f->lineinfo[fs->pc] = fs->ls->lastline;
return fs->pc++;
@@ -289,7 +289,7 @@ static void freeexp (FuncState *fs, expdesc *e) {
static int addk (FuncState *fs, TValue *key, TValue *v) {
- lua_State *L = fs->L;
+ lua_State *L = fs->ls->L;
TValue *idx = luaH_set(L, fs->h, key);
Proto *f = fs->f;
int k, oldsize;
@@ -304,6 +304,8 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
/* constant not found; create a new entry */
oldsize = f->sizek;
k = fs->nk;
+ /* numerical value does not need GC barrier;
+ table has no metatable, so it does not need to invalidate cache */
setnvalue(idx, cast_num(k));
luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
@@ -316,14 +318,14 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
int luaK_stringK (FuncState *fs, TString *s) {
TValue o;
- setsvalue(fs->L, &o, s);
+ setsvalue(fs->ls->L, &o, s);
return addk(fs, &o, &o);
}
int luaK_numberK (FuncState *fs, lua_Number r) {
int n;
- lua_State *L = fs->L;
+ lua_State *L = fs->ls->L;
TValue o;
setnvalue(&o, r);
if (r == 0 || luai_numisnan(NULL, r)) { /* handle -0 and NaN */
@@ -350,7 +352,7 @@ static int nilK (FuncState *fs) {
TValue k, v;
setnilvalue(&v);
/* cannot use nil as key; instead use table itself to represent nil */
- sethvalue(fs->L, &k, fs->h);
+ sethvalue(fs->ls->L, &k, fs->h);
return addk(fs, &k, &v);
}
@@ -641,7 +643,7 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) {
}
-static void luaK_goiffalse (FuncState *fs, expdesc *e) {
+void luaK_goiffalse (FuncState *fs, expdesc *e) {
int pc; /* pc of last jump */
luaK_dischargevars(fs, e);
switch (e->k) {
diff --git a/src/lcode.h b/src/lcode.h
index 26a5daa..5a1fa9f 100755..100644
--- a/src/lcode.h
+++ b/src/lcode.h
@@ -1,5 +1,5 @@
/*
-** $Id: lcode.h,v 1.57 2011/04/07 18:14:12 roberto Exp $
+** $Id: lcode.h,v 1.58 2011/08/30 16:26:41 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -62,6 +62,7 @@ LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
+LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
diff --git a/src/lcorolib.c b/src/lcorolib.c
index 981ca38..0edde26 100755..100644
--- a/src/lcorolib.c
+++ b/src/lcorolib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lcorolib.c,v 1.2 2010/07/02 11:38:13 roberto Exp $
+** $Id: lcorolib.c,v 1.3 2011/08/23 17:24:34 roberto Exp $
** Coroutine Library
** See Copyright Notice in lua.h
*/
@@ -28,7 +28,7 @@ static int auxresume (lua_State *L, lua_State *co, int narg) {
return -1; /* error flag */
}
lua_xmove(L, co, narg);
- status = lua_resume(co, narg);
+ status = lua_resume(co, L, narg);
if (status == LUA_OK || status == LUA_YIELD) {
int nres = lua_gettop(co);
if (!lua_checkstack(L, nres + 1)) {
diff --git a/src/lctype.c b/src/lctype.c
index 387c93a..55e433a 100755..100644
--- a/src/lctype.c
+++ b/src/lctype.c
@@ -1,9 +1,12 @@
/*
-** $Id: lctype.c,v 1.10 2011/06/24 12:25:33 roberto Exp $
+** $Id: lctype.c,v 1.11 2011/10/03 16:19:23 roberto Exp $
** 'ctype' functions for Lua
** See Copyright Notice in lua.h
*/
+#define lctype_c
+#define LUA_CORE
+
#include "lctype.h"
#if !LUA_USE_CTYPE /* { */
diff --git a/src/lctype.h b/src/lctype.h
index b24d925..99c7d12 100755..100644
--- a/src/lctype.h
+++ b/src/lctype.h
@@ -1,5 +1,5 @@
/*
-** $Id: lctype.h,v 1.11 2011/06/27 18:22:46 roberto Exp $
+** $Id: lctype.h,v 1.12 2011/07/15 12:50:29 roberto Exp $
** 'ctype' functions for Lua
** See Copyright Notice in lua.h
*/
@@ -11,7 +11,7 @@
/*
-** WARNING: the functions defined here do not necessarily correspond
+** WARNING: the functions defined here do not necessarily correspond
** to the similar functions in the standard C ctype.h. They are
** optimized for the specific needs of Lua
*/
diff --git a/src/ldblib.c b/src/ldblib.c
index 78f6cc0..3c2f159 100755..100644
--- a/src/ldblib.c
+++ b/src/ldblib.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldblib.c,v 1.130 2011/04/08 19:17:36 roberto Exp $
+** $Id: ldblib.c,v 1.131 2011/10/24 14:54:05 roberto Exp $
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/
@@ -260,8 +260,7 @@ static void hookf (lua_State *L, lua_Debug *ar) {
static const char *const hooknames[] =
{"call", "return", "line", "count", "tail call"};
gethooktable(L);
- lua_pushlightuserdata(L, L);
- lua_rawget(L, -2);
+ lua_rawgetp(L, -1, L);
if (lua_isfunction(L, -1)) {
lua_pushstring(L, hooknames[(int)ar->event]);
if (ar->currentline >= 0)
@@ -308,9 +307,8 @@ static int db_sethook (lua_State *L) {
func = hookf; mask = makemask(smask, count);
}
gethooktable(L);
- lua_pushlightuserdata(L, L1);
lua_pushvalue(L, arg+1);
- lua_rawset(L, -3); /* set new hook */
+ lua_rawsetp(L, -2, L1); /* set new hook */
lua_pop(L, 1); /* remove hook table */
lua_sethook(L1, func, mask, count); /* set hooks */
return 0;
@@ -327,8 +325,7 @@ static int db_gethook (lua_State *L) {
lua_pushliteral(L, "external hook");
else {
gethooktable(L);
- lua_pushlightuserdata(L, L1);
- lua_rawget(L, -2); /* get hook */
+ lua_rawgetp(L, -1, L1); /* get hook */
lua_remove(L, -2); /* remove hook table */
}
lua_pushstring(L, unmakemask(mask, buff));
diff --git a/src/ldebug.c b/src/ldebug.c
index a2565cf..31b7ae4 100755..100644
--- a/src/ldebug.c
+++ b/src/ldebug.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldebug.c,v 2.82 2011/06/02 19:31:40 roberto Exp $
+** $Id: ldebug.c,v 2.88 2011/11/30 12:43:51 roberto Exp $
** Debug Interface
** See Copyright Notice in lua.h
*/
@@ -94,6 +94,13 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
}
+static const char *upvalname (Proto *p, int uv) {
+ TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name);
+ if (s == NULL) return "?";
+ else return getstr(s);
+}
+
+
static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
int nparams = clLvalue(ci->func)->p->numparams;
if (n >= ci->u.l.base - ci->func - nparams)
@@ -190,12 +197,14 @@ static void collectvalidlines (lua_State *L, Closure *f) {
}
else {
int i;
+ TValue v;
int *lineinfo = f->l.p->lineinfo;
- Table *t = luaH_new(L);
- sethvalue(L, L->top, t);
+ Table *t = luaH_new(L); /* new table to store active lines */
+ sethvalue(L, L->top, t); /* push it on stack */
incr_top(L);
- for (i=0; i<f->l.p->sizelineinfo; i++)
- setbvalue(luaH_setint(L, t, lineinfo[i]), 1);
+ setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */
+ for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */
+ luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */
}
}
@@ -230,7 +239,11 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
break;
}
case 'n': {
- ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL;
+ /* calling function is a known Lua function? */
+ if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
+ ar->namewhat = getfuncname(L, ci->previous, &ar->name);
+ else
+ ar->namewhat = NULL;
if (ar->namewhat == NULL) {
ar->namewhat = ""; /* not found */
ar->name = NULL;
@@ -284,17 +297,16 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
** =======================================================
*/
-static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
+static const char *getobjname (Proto *p, int lastpc, int reg,
const char **name);
/*
** find a "name" for the RK value 'c'
*/
-static void kname (lua_State *L, CallInfo *ci, int c, int oreg,
- const char *what, const char **name) {
+static void kname (Proto *p, int pc, int c, const char **name) {
if (ISK(c)) { /* is 'c' a constant? */
- TValue *kvalue = &ci_func(ci)->p->k[INDEXK(c)];
+ TValue *kvalue = &p->k[INDEXK(c)];
if (ttisstring(kvalue)) { /* literal constant? */
*name = svalue(kvalue); /* it is its own name */
return;
@@ -302,8 +314,7 @@ static void kname (lua_State *L, CallInfo *ci, int c, int oreg,
/* else no reasonable name found */
}
else { /* 'c' is a register */
- if (c != oreg) /* not the original register? */
- what = getobjname(L, ci, c, name); /* search for 'c' */
+ const char *what = getobjname(p, pc, c, name); /* search for 'c' */
if (what && *what == 'c') { /* found a constant name? */
return; /* 'name' already filled */
}
@@ -313,85 +324,30 @@ static void kname (lua_State *L, CallInfo *ci, int c, int oreg,
}
-static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
- const char **name) {
- Proto *p = ci_func(ci)->p;
- const char *what = NULL;
- int lastpc = currentpc(ci);
+/*
+** try to find last instruction before 'lastpc' that modified register 'reg'
+*/
+static int findsetreg (Proto *p, int lastpc, int reg) {
int pc;
- *name = luaF_getlocalname(p, reg + 1, lastpc);
- if (*name) /* is a local? */
- return "local";
- /* else try symbolic execution */
+ int setreg = -1; /* keep last instruction that changed 'reg' */
for (pc = 0; pc < lastpc; pc++) {
Instruction i = p->code[pc];
OpCode op = GET_OPCODE(i);
int a = GETARG_A(i);
switch (op) {
- case OP_MOVE: {
- if (reg == a) {
- int b = GETARG_B(i); /* move from 'b' to 'a' */
- if (b < a)
- what = getobjname(L, ci, b, name); /* get name for 'b' */
- else what = NULL;
- }
- break;
- }
- case OP_GETTABUP:
- case OP_GETTABLE: {
- if (reg == a) {
- int k = GETARG_C(i); /* key index */
- int t = GETARG_B(i);
- const char *vn = (op == OP_GETTABLE) /* name of indexed variable */
- ? luaF_getlocalname(p, t + 1, pc)
- : getstr(p->upvalues[t].name);
- kname(L, ci, k, a, what, name);
- what = (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
- }
- break;
- }
- case OP_GETUPVAL: {
- if (reg == a) {
- int u = GETARG_B(i); /* upvalue index */
- TString *tn = p->upvalues[u].name;
- *name = tn ? getstr(tn) : "?";
- what = "upvalue";
- }
- break;
- }
- case OP_LOADK:
- case OP_LOADKX: {
- if (reg == a) {
- int b = (op == OP_LOADK) ? GETARG_Bx(i)
- : GETARG_Ax(p->code[pc + 1]);
- if (ttisstring(&p->k[b])) {
- what = "constant";
- *name = svalue(&p->k[b]);
- }
- }
- break;
- }
case OP_LOADNIL: {
int b = GETARG_B(i);
if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */
- what = NULL;
- break;
- }
- case OP_SELF: {
- if (reg == a) {
- int k = GETARG_C(i); /* key index */
- kname(L, ci, k, a, what, name);
- what = "method";
- }
+ setreg = pc;
break;
}
case OP_TFORCALL: {
- if (reg >= a + 2) what = NULL; /* affect all regs above its base */
+ if (reg >= a + 2) setreg = pc; /* affect all regs above its base */
break;
}
case OP_CALL:
case OP_TAILCALL: {
- if (reg >= a) what = NULL; /* affect all registers above base */
+ if (reg >= a) setreg = pc; /* affect all registers above base */
break;
}
case OP_JMP: {
@@ -403,35 +359,87 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
break;
}
case OP_TEST: {
- if (reg == a) what = NULL; /* jumped code can change 'a' */
+ if (reg == a) setreg = pc; /* jumped code can change 'a' */
break;
}
default:
- if (testAMode(op) && reg == a) what = NULL;
+ if (testAMode(op) && reg == a) /* any instruction that set A */
+ setreg = pc;
break;
}
}
- return what;
+ return setreg;
+}
+
+
+static const char *getobjname (Proto *p, int lastpc, int reg,
+ const char **name) {
+ int pc;
+ *name = luaF_getlocalname(p, reg + 1, lastpc);
+ if (*name) /* is a local? */
+ return "local";
+ /* else try symbolic execution */
+ pc = findsetreg(p, lastpc, reg);
+ if (pc != -1) { /* could find instruction? */
+ Instruction i = p->code[pc];
+ OpCode op = GET_OPCODE(i);
+ switch (op) {
+ case OP_MOVE: {
+ int b = GETARG_B(i); /* move from 'b' to 'a' */
+ if (b < GETARG_A(i))
+ return getobjname(p, pc, b, name); /* get name for 'b' */
+ break;
+ }
+ case OP_GETTABUP:
+ case OP_GETTABLE: {
+ int k = GETARG_C(i); /* key index */
+ int t = GETARG_B(i); /* table index */
+ const char *vn = (op == OP_GETTABLE) /* name of indexed variable */
+ ? luaF_getlocalname(p, t + 1, pc)
+ : upvalname(p, t);
+ kname(p, pc, k, name);
+ return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
+ }
+ case OP_GETUPVAL: {
+ *name = upvalname(p, GETARG_B(i));
+ return "upvalue";
+ }
+ case OP_LOADK:
+ case OP_LOADKX: {
+ int b = (op == OP_LOADK) ? GETARG_Bx(i)
+ : GETARG_Ax(p->code[pc + 1]);
+ if (ttisstring(&p->k[b])) {
+ *name = svalue(&p->k[b]);
+ return "constant";
+ }
+ break;
+ }
+ case OP_SELF: {
+ int k = GETARG_C(i); /* key index */
+ kname(p, pc, k, name);
+ return "method";
+ }
+ default: break; /* go through to return NULL */
+ }
+ }
+ return NULL; /* could not find reasonable name */
}
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
TMS tm;
- Instruction i;
- if ((ci->callstatus & CIST_TAIL) || !isLua(ci->previous))
- return NULL; /* calling function is not Lua (or is unknown) */
- ci = ci->previous; /* calling function */
- i = ci_func(ci)->p->code[currentpc(ci)];
- if (GET_OPCODE(i) == OP_EXTRAARG) /* extra argument? */
- i = ci_func(ci)->p->code[currentpc(ci) - 1]; /* get 'real' instruction */
+ Proto *p = ci_func(ci)->p; /* calling function */
+ int pc = currentpc(ci); /* calling instruction index */
+ Instruction i = p->code[pc]; /* calling instruction */
switch (GET_OPCODE(i)) {
case OP_CALL:
- case OP_TAILCALL:
- return getobjname(L, ci, GETARG_A(i), name);
- case OP_TFORCALL: {
+ case OP_TAILCALL: /* get function name */
+ return getobjname(p, pc, GETARG_A(i), name);
+ case OP_TFORCALL: { /* for iterator */
*name = "for iterator";
return "for iterator";
}
+ /* all other instructions can call only through metamethods */
case OP_SELF:
case OP_GETTABUP:
case OP_GETTABLE: tm = TM_INDEX; break;
@@ -473,12 +481,12 @@ static int isinstack (CallInfo *ci, const TValue *o) {
static const char *getupvalname (CallInfo *ci, const TValue *o,
- const char **name) {
+ const char **name) {
LClosure *c = ci_func(ci);
int i;
for (i = 0; i < c->nupvalues; i++) {
if (c->upvals[i]->v == o) {
- *name = getstr(c->p->upvalues[i].name);
+ *name = upvalname(c->p, i);
return "upvalue";
}
}
@@ -486,7 +494,7 @@ static const char *getupvalname (CallInfo *ci, const TValue *o,
}
-void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
+l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
CallInfo *ci = L->ci;
const char *name = NULL;
const char *t = objtypename(o);
@@ -494,7 +502,8 @@ void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
if (isLua(ci)) {
kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */
if (!kind && isinstack(ci, o)) /* no? try a register */
- kind = getobjname(L, ci, cast_int(o - ci->u.l.base), &name);
+ kind = getobjname(ci_func(ci)->p, currentpc(ci),
+ cast_int(o - ci->u.l.base), &name);
}
if (kind)
luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
@@ -504,14 +513,14 @@ void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
}
-void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
+l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
lua_assert(!ttisstring(p1) && !ttisnumber(p2));
luaG_typeerror(L, p1, "concatenate");
}
-void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
+l_noret luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
TValue temp;
if (luaV_tonumber(p1, &temp) == NULL)
p2 = p1; /* first operand is wrong */
@@ -519,14 +528,13 @@ void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
}
-int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
+l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
const char *t1 = objtypename(p1);
const char *t2 = objtypename(p2);
if (t1 == t2)
luaG_runerror(L, "attempt to compare two %s values", t1);
else
luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
- return 0;
}
@@ -546,7 +554,7 @@ static void addinfo (lua_State *L, const char *msg) {
}
-void luaG_errormsg (lua_State *L) {
+l_noret luaG_errormsg (lua_State *L) {
if (L->errfunc != 0) { /* is there an error handling function? */
StkId errfunc = restorestack(L, L->errfunc);
if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
@@ -559,7 +567,7 @@ void luaG_errormsg (lua_State *L) {
}
-void luaG_runerror (lua_State *L, const char *fmt, ...) {
+l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
va_list argp;
va_start(argp, fmt);
addinfo(L, luaO_pushvfstring(L, fmt, argp));
diff --git a/src/ldebug.h b/src/ldebug.h
index 6590c56..fe39556 100755..100644
--- a/src/ldebug.h
+++ b/src/ldebug.h
@@ -1,5 +1,5 @@
/*
-** $Id: ldebug.h,v 2.6 2011/06/02 19:31:40 roberto Exp $
+** $Id: ldebug.h,v 2.7 2011/10/07 20:45:19 roberto Exp $
** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h
*/
@@ -21,14 +21,14 @@
#define ci_func(ci) (clLvalue((ci)->func))
-LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o,
- const char *opname);
-LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
-LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1,
- const TValue *p2);
-LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1,
- const TValue *p2);
-LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...);
-LUAI_FUNC void luaG_errormsg (lua_State *L);
+LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
+ const char *opname);
+LUAI_FUNC l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2);
+LUAI_FUNC l_noret luaG_aritherror (lua_State *L, const TValue *p1,
+ const TValue *p2);
+LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1,
+ const TValue *p2);
+LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...);
+LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
#endif
diff --git a/src/ldo.c b/src/ldo.c
index a34b0d0..26f9a67 100755..100644
--- a/src/ldo.c
+++ b/src/ldo.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldo.c,v 2.98 2011/06/28 15:42:04 roberto Exp $
+** $Id: ldo.c,v 2.102 2011/11/29 15:55:08 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -100,7 +100,7 @@ static void seterrorobj (lua_State *L, int errcode, StkId oldtop) {
}
-void luaD_throw (lua_State *L, int errcode) {
+l_noret luaD_throw (lua_State *L, int errcode) {
if (L->errorJmp) { /* thread has an error handler? */
L->errorJmp->status = errcode; /* set status */
LUAI_THROW(L, L->errorJmp); /* jump to it */
@@ -123,7 +123,7 @@ void luaD_throw (lua_State *L, int errcode) {
int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
- unsigned short oldnCcalls = G(L)->nCcalls;
+ unsigned short oldnCcalls = L->nCcalls;
struct lua_longjmp lj;
lj.status = LUA_OK;
lj.previous = L->errorJmp; /* chain new error handler */
@@ -132,7 +132,7 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
(*f)(L, ud);
);
L->errorJmp = lj.previous; /* restore old error handler */
- G(L)->nCcalls = oldnCcalls;
+ L->nCcalls = oldnCcalls;
return lj.status;
}
@@ -344,7 +344,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
}
default: { /* not a function */
func = tryfuncTM(L, func); /* retry with 'function' tag method */
- return luaD_precall(L, func, nresults);
+ return luaD_precall(L, func, nresults); /* now it must be a function */
}
}
}
@@ -382,18 +382,17 @@ int luaD_poscall (lua_State *L, StkId firstResult) {
** function position.
*/
void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) {
- global_State *g = G(L);
- if (++g->nCcalls >= LUAI_MAXCCALLS) {
- if (g->nCcalls == LUAI_MAXCCALLS)
+ if (++L->nCcalls >= LUAI_MAXCCALLS) {
+ if (L->nCcalls == LUAI_MAXCCALLS)
luaG_runerror(L, "C stack overflow");
- else if (g->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
+ else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
}
if (!allowyield) L->nny++;
if (!luaD_precall(L, func, nResults)) /* is a Lua function? */
luaV_execute(L); /* call it */
if (!allowyield) L->nny--;
- g->nCcalls--;
+ L->nCcalls--;
luaC_checkGC(L);
}
@@ -404,7 +403,7 @@ static void finishCcall (lua_State *L) {
lua_assert(ci->u.c.k != NULL); /* must have a continuation */
lua_assert(L->nny == 0);
/* finish 'luaD_call' */
- G(L)->nCcalls--;
+ L->nCcalls--;
/* finish 'lua_callk' */
adjustresults(L, ci->nresults);
/* call continuation function */
@@ -473,7 +472,7 @@ static int recover (lua_State *L, int status) {
** coroutine itself. (Such errors should not be handled by any coroutine
** error handler and should not kill the coroutine.)
*/
-static void resume_error (lua_State *L, const char *msg, StkId firstArg) {
+static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) {
L->top = firstArg; /* remove args from the stack */
setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */
incr_top(L);
@@ -487,7 +486,7 @@ static void resume_error (lua_State *L, const char *msg, StkId firstArg) {
static void resume (lua_State *L, void *ud) {
StkId firstArg = cast(StkId, ud);
CallInfo *ci = L->ci;
- if (G(L)->nCcalls >= LUAI_MAXCCALLS)
+ if (L->nCcalls >= LUAI_MAXCCALLS)
resume_error(L, "C stack overflow", firstArg);
if (L->status == LUA_OK) { /* may be starting a coroutine */
if (ci != &L->base_ci) /* not in base level? */
@@ -514,7 +513,7 @@ static void resume (lua_State *L, void *ud) {
api_checknelems(L, n);
firstArg = L->top - n; /* yield results come from continuation */
}
- G(L)->nCcalls--; /* finish 'luaD_call' */
+ L->nCcalls--; /* finish 'luaD_call' */
luaD_poscall(L, firstArg); /* finish 'luaD_precall' */
}
unroll(L, NULL);
@@ -522,11 +521,11 @@ static void resume (lua_State *L, void *ud) {
}
-LUA_API int lua_resume (lua_State *L, int nargs) {
+LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {
int status;
lua_lock(L);
luai_userstateresume(L, nargs);
- ++G(L)->nCcalls; /* count resume */
+ L->nCcalls = (from) ? from->nCcalls + 1 : 1;
L->nny = 0; /* allow yields */
api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
status = luaD_rawrunprotected(L, resume, L->top - nargs);
@@ -546,7 +545,8 @@ LUA_API int lua_resume (lua_State *L, int nargs) {
lua_assert(status == L->status);
}
L->nny = 1; /* do not allow yields */
- --G(L)->nCcalls;
+ L->nCcalls--;
+ lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0));
lua_unlock(L);
return status;
}
@@ -611,18 +611,34 @@ struct SParser { /* data to `f_parser' */
ZIO *z;
Mbuffer buff; /* dynamic structure used by the scanner */
Dyndata dyd; /* dynamic structures used by the parser */
+ const char *mode;
const char *name;
};
+
+static void checkmode (lua_State *L, const char *mode, const char *x) {
+ if (mode && strchr(mode, x[0]) == NULL) {
+ luaO_pushfstring(L,
+ "attempt to load a %s chunk (mode is " LUA_QS ")", x, mode);
+ luaD_throw(L, LUA_ERRSYNTAX);
+ }
+}
+
+
static void f_parser (lua_State *L, void *ud) {
int i;
Proto *tf;
Closure *cl;
struct SParser *p = cast(struct SParser *, ud);
int c = zgetc(p->z); /* read first character */
- tf = (c == LUA_SIGNATURE[0])
- ? luaU_undump(L, p->z, &p->buff, p->name)
- : luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
+ if (c == LUA_SIGNATURE[0]) {
+ checkmode(L, p->mode, "binary");
+ tf = luaU_undump(L, p->z, &p->buff, p->name);
+ }
+ else {
+ checkmode(L, p->mode, "text");
+ tf = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
+ }
setptvalue2s(L, L->top, tf);
incr_top(L);
cl = luaF_newLclosure(L, tf);
@@ -632,11 +648,12 @@ static void f_parser (lua_State *L, void *ud) {
}
-int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) {
+int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
+ const char *mode) {
struct SParser p;
int status;
L->nny++; /* cannot yield during parsing */
- p.z = z; p.name = name;
+ p.z = z; p.name = name; p.mode = mode;
p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0;
p.dyd.gt.arr = NULL; p.dyd.gt.size = 0;
p.dyd.label.arr = NULL; p.dyd.label.size = 0;
diff --git a/src/ldo.h b/src/ldo.h
index 88962d9..27b837d 100755..100644
--- a/src/ldo.h
+++ b/src/ldo.h
@@ -1,5 +1,5 @@
/*
-** $Id: ldo.h,v 2.18 2009/12/17 12:28:57 roberto Exp $
+** $Id: ldo.h,v 2.20 2011/11/29 15:55:08 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -26,7 +26,8 @@
/* type of protected functions, to be ran by `runprotected' */
typedef void (*Pfunc) (lua_State *L, void *ud);
-LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name);
+LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
+ const char *mode);
LUAI_FUNC void luaD_hook (lua_State *L, int event, int line);
LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults,
@@ -38,7 +39,7 @@ LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
LUAI_FUNC void luaD_growstack (lua_State *L, int n);
LUAI_FUNC void luaD_shrinkstack (lua_State *L);
-LUAI_FUNC void luaD_throw (lua_State *L, int errcode);
+LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode);
LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
#endif
diff --git a/src/ldump.c b/src/ldump.c
index 77b578d..699e1dc 100755..100644
--- a/src/ldump.c
+++ b/src/ldump.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldump.c,v 1.18 2011/05/06 13:35:17 lhf Exp $
+** $Id: ldump.c,v 1.19 2011/11/23 17:48:18 lhf Exp $
** save precompiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -111,8 +111,8 @@ static void DumpUpvalues(const Proto* f, DumpState* D)
DumpInt(n,D);
for (i=0; i<n; i++)
{
- DumpChar(f->upvalues[i].instack, D);
- DumpChar(f->upvalues[i].idx, D);
+ DumpChar(f->upvalues[i].instack,D);
+ DumpChar(f->upvalues[i].idx,D);
}
}
diff --git a/src/lfunc.c b/src/lfunc.c
index 1a1a8bb..1a1a8bb 100755..100644
--- a/src/lfunc.c
+++ b/src/lfunc.c
diff --git a/src/lfunc.h b/src/lfunc.h
index da18923..da18923 100755..100644
--- a/src/lfunc.h
+++ b/src/lfunc.h
diff --git a/src/lgc.c b/src/lgc.c
index 598cc71..cdd92e5 100755..100644
--- a/src/lgc.c
+++ b/src/lgc.c
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.c,v 2.109 2011/05/05 19:42:25 roberto Exp $
+** $Id: lgc.c,v 2.116 2011/12/02 13:18:41 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -94,18 +94,25 @@ static void reallymarkobject (global_State *g, GCObject *o);
/*
+** one after last element in a hash array
+*/
+#define gnodelast(h) gnode(h, cast(size_t, sizenode(h)))
+
+
+/*
** link table 'h' into list pointed by 'p'
*/
#define linktable(h,p) ((h)->gclist = *(p), *(p) = obj2gco(h))
/*
-** mark a table entry as dead (therefore removing it from the table)
+** if key is not marked, mark its entry as dead (therefore removing it
+** from the table)
*/
static void removeentry (Node *n) {
lua_assert(ttisnil(gval(n)));
- if (iscollectable(gkey(n)))
- setdeadvalue(gkey(n)); /* dead key; remove it */
+ if (valiswhite(gkey(n)))
+ setdeadvalue(gkey(n)); /* unused and unmarked key; remove it */
}
@@ -116,13 +123,13 @@ static void removeentry (Node *n) {
** other objects: if really collected, cannot keep them; for objects
** being finalized, keep them in keys, but not in values
*/
-static int iscleared (const TValue *o, int iskey) {
+static int iscleared (const TValue *o) {
if (!iscollectable(o)) return 0;
else if (ttisstring(o)) {
stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */
return 0;
}
- else return iswhite(gcvalue(o)) || (!iskey && isfinalized(gcvalue(o)));
+ else return iswhite(gcvalue(o));
}
@@ -152,7 +159,7 @@ void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) {
*/
void luaC_barrierback_ (lua_State *L, GCObject *o) {
global_State *g = G(L);
- lua_assert(isblack(o) && !isdead(g, o));
+ lua_assert(isblack(o) && !isdead(g, o) && gch(o)->tt == LUA_TTABLE);
black2gray(o); /* make object gray (again) */
gco2t(o)->gclist = g->grayagain;
g->grayagain = o;
@@ -284,7 +291,7 @@ static void reallymarkobject (global_State *g, GCObject *o) {
/*
-** mark tag methods for basic types
+** mark metamethods for basic types
*/
static void markmt (global_State *g) {
int i;
@@ -341,7 +348,10 @@ static void markroot (global_State *g) {
*/
static void traverseweakvalue (global_State *g, Table *h) {
- Node *n, *limit = gnode(h, sizenode(h));
+ Node *n, *limit = gnodelast(h);
+ /* if there is array part, assume it may have white values (do not
+ traverse it just to check) */
+ int hasclears = (h->sizearray > 0);
for (n = gnode(h, 0); n < limit; n++) {
checkdeadkey(n);
if (ttisnil(gval(n))) /* entry is empty? */
@@ -349,16 +359,22 @@ static void traverseweakvalue (global_State *g, Table *h) {
else {
lua_assert(!ttisnil(gkey(n)));
markvalue(g, gkey(n)); /* mark key */
+ if (!hasclears && iscleared(gval(n))) /* is there a white value? */
+ hasclears = 1; /* table will have to be cleared */
}
}
- linktable(h, &g->weak); /* link into appropriate list */
+ if (hasclears)
+ linktable(h, &g->weak); /* has to be cleared later */
+ else /* no white values */
+ linktable(h, &g->grayagain); /* no need to clean */
}
static int traverseephemeron (global_State *g, Table *h) {
int marked = 0; /* true if an object is marked in this traversal */
- int hasclears = 0; /* true if table has unmarked pairs */
- Node *n, *limit = gnode(h, sizenode(h));
+ int hasclears = 0; /* true if table has white keys */
+ int prop = 0; /* true if table has entry "white-key -> white-value" */
+ Node *n, *limit = gnodelast(h);
int i;
/* traverse array part (numeric keys are 'strong') */
for (i = 0; i < h->sizearray; i++) {
@@ -372,25 +388,28 @@ static int traverseephemeron (global_State *g, Table *h) {
checkdeadkey(n);
if (ttisnil(gval(n))) /* entry is empty? */
removeentry(n); /* remove it */
+ else if (iscleared(gkey(n))) { /* key is not marked (yet)? */
+ hasclears = 1; /* table must be cleared */
+ if (valiswhite(gval(n))) /* value not marked yet? */
+ prop = 1; /* must propagate again */
+ }
else if (valiswhite(gval(n))) { /* value not marked yet? */
- if (iscleared(gkey(n), 1)) /* key is not marked (yet)? */
- hasclears = 1; /* may have to propagate mark from key to value */
- else { /* key is marked, so mark value */
- marked = 1; /* value was not marked */
- reallymarkobject(g, gcvalue(gval(n)));
- }
+ marked = 1;
+ reallymarkobject(g, gcvalue(gval(n))); /* mark it now */
}
}
- if (hasclears) /* does table have unmarked pairs? */
- linktable(h, &g->ephemeron); /* will have to propagate again */
- else /* nothing to propagate */
- linktable(h, &g->weak); /* avoid convergence phase */
+ if (prop)
+ linktable(h, &g->ephemeron); /* have to propagate again */
+ else if (hasclears) /* does table have white keys? */
+ linktable(h, &g->allweak); /* may have to clean white keys */
+ else /* no white keys */
+ linktable(h, &g->grayagain); /* no need to clean */
return marked;
}
static void traversestrongtable (global_State *g, Table *h) {
- Node *n, *limit = gnode(h, sizenode(h));
+ Node *n, *limit = gnodelast(h);
int i;
for (i = 0; i < h->sizearray; i++) /* traverse array part */
markvalue(g, &h->array[i]);
@@ -526,11 +545,26 @@ static void propagateall (global_State *g) {
}
-static void traverselistofgrays (global_State *g, GCObject **l) {
+static void propagatelist (global_State *g, GCObject *l) {
lua_assert(g->gray == NULL); /* no grays left */
- g->gray = *l; /* now 'l' is new gray list */
- *l = NULL;
- propagateall(g);
+ g->gray = l;
+ propagateall(g); /* traverse all elements from 'l' */
+}
+
+/*
+** retraverse all gray lists. Because tables may be reinserted in other
+** lists when traversed, traverse the original lists to avoid traversing
+** twice the same table (which is not wrong, but inefficient)
+*/
+static void retraversegrays (global_State *g) {
+ GCObject *weak = g->weak; /* save original lists */
+ GCObject *grayagain = g->grayagain;
+ GCObject *ephemeron = g->ephemeron;
+ g->weak = g->grayagain = g->ephemeron = NULL;
+ propagateall(g); /* traverse main gray list */
+ propagatelist(g, grayagain);
+ propagatelist(g, weak);
+ propagatelist(g, ephemeron);
}
@@ -562,21 +596,39 @@ static void convergeephemerons (global_State *g) {
/*
-** clear collected entries from all weaktables in list 'l'
+** clear entries with unmarked keys from all weaktables in list 'l' up
+** to element 'f'
*/
-static void cleartable (GCObject *l) {
- for (; l != NULL; l = gco2t(l)->gclist) {
+static void clearkeys (GCObject *l, GCObject *f) {
+ for (; l != f; l = gco2t(l)->gclist) {
Table *h = gco2t(l);
- Node *n, *limit = gnode(h, sizenode(h));
+ Node *n, *limit = gnodelast(h);
+ for (n = gnode(h, 0); n < limit; n++) {
+ if (!ttisnil(gval(n)) && (iscleared(gkey(n)))) {
+ setnilvalue(gval(n)); /* remove value ... */
+ removeentry(n); /* and remove entry from table */
+ }
+ }
+ }
+}
+
+
+/*
+** clear entries with unmarked values from all weaktables in list 'l' up
+** to element 'f'
+*/
+static void clearvalues (GCObject *l, GCObject *f) {
+ for (; l != f; l = gco2t(l)->gclist) {
+ Table *h = gco2t(l);
+ Node *n, *limit = gnodelast(h);
int i;
for (i = 0; i < h->sizearray; i++) {
TValue *o = &h->array[i];
- if (iscleared(o, 0)) /* value was collected? */
+ if (iscleared(o)) /* value was collected? */
setnilvalue(o); /* remove value */
}
for (n = gnode(h, 0); n < limit; n++) {
- if (!ttisnil(gval(n)) && /* non-empty entry? */
- (iscleared(gkey(n), 1) || iscleared(gval(n), 0))) {
+ if (!ttisnil(gval(n)) && iscleared(gval(n))) {
setnilvalue(gval(n)); /* remove value ... */
removeentry(n); /* and remove entry from table */
}
@@ -722,7 +774,7 @@ static void GCTM (lua_State *L, int propagateerrors) {
int status;
lu_byte oldah = L->allowhook;
int running = g->gcrunning;
- L->allowhook = 0; /* stop debug hooks during GC tag method */
+ L->allowhook = 0; /* stop debug hooks during GC metamethod */
g->gcrunning = 0; /* avoid GC steps */
setobj2s(L, L->top, tm); /* push finalizer... */
setobj2s(L, L->top + 1, &v); /* ... and its argument */
@@ -732,7 +784,7 @@ static void GCTM (lua_State *L, int propagateerrors) {
g->gcrunning = running; /* restore state */
if (status != LUA_OK && propagateerrors) { /* error while running __gc? */
if (status == LUA_ERRRUN) { /* is there an error msg.? */
- luaO_pushfstring(L, "error in __gc tag method (%s)",
+ luaO_pushfstring(L, "error in __gc metamethod (%s)",
lua_tostring(L, -1));
status = LUA_ERRGCMM; /* error in __gc metamethod */
}
@@ -743,10 +795,10 @@ static void GCTM (lua_State *L, int propagateerrors) {
/*
-** move all unreachable objects that need finalization from list 'finobj'
-** to list 'tobefnz'
+** move all unreachable objects (or 'all' objects) that need
+** finalization from list 'finobj' to list 'tobefnz' (to be finalized)
*/
-void luaC_separateudata (lua_State *L, int all) {
+static void separatetobefnz (lua_State *L, int all) {
global_State *g = G(L);
GCObject **p = &g->finobj;
GCObject *curr;
@@ -842,14 +894,13 @@ static void callallpendingfinalizers (lua_State *L, int propagateerrors) {
void luaC_freeallobjects (lua_State *L) {
global_State *g = G(L);
int i;
+ separatetobefnz(L, 1); /* separate all objects with finalizers */
+ lua_assert(g->finobj == NULL);
callallpendingfinalizers(L, 0);
- /* following "white" makes all objects look dead */
- g->currentwhite = WHITEBITS;
+ g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */
g->gckind = KGC_NORMAL;
- sweepwholelist(L, &g->finobj);
- lua_assert(g->finobj == NULL);
+ sweepwholelist(L, &g->finobj); /* finalizers can create objs. in 'finobj' */
sweepwholelist(L, &g->allgc);
- lua_assert(g->allgc == NULL);
for (i = 0; i < g->strt.size; i++) /* free all string lists */
sweepwholelist(L, &g->strt.hash[i]);
lua_assert(g->strt.nuse == 0);
@@ -858,6 +909,7 @@ void luaC_freeallobjects (lua_State *L) {
static void atomic (lua_State *L) {
global_State *g = G(L);
+ GCObject *origweak, *origall;
lua_assert(!iswhite(obj2gco(g->mainthread)));
markobject(g, L); /* mark running thread */
/* registry and global metatables may be changed by API */
@@ -866,20 +918,24 @@ static void atomic (lua_State *L) {
/* remark occasional upvalues of (maybe) dead threads */
remarkupvals(g);
/* traverse objects caught by write barrier and by 'remarkupvals' */
- propagateall(g);
- traverselistofgrays(g, &g->weak); /* remark weak tables */
- traverselistofgrays(g, &g->ephemeron); /* remark ephemeron tables */
- traverselistofgrays(g, &g->grayagain); /* remark gray again */
+ retraversegrays(g);
convergeephemerons(g);
/* at this point, all strongly accessible objects are marked. */
- luaC_separateudata(L, 0); /* separate userdata to be finalized */
+ /* clear values from weak tables, before checking finalizers */
+ clearvalues(g->weak, NULL);
+ clearvalues(g->allweak, NULL);
+ origweak = g->weak; origall = g->allweak;
+ separatetobefnz(L, 0); /* separate objects to be finalized */
markbeingfnz(g); /* mark userdata that will be finalized */
propagateall(g); /* remark, to propagate `preserveness' */
convergeephemerons(g);
- /* remove collected objects from weak tables */
- cleartable(g->weak);
- cleartable(g->ephemeron);
- cleartable(g->allweak);
+ /* at this point, all resurrected objects are marked. */
+ /* remove dead objects from weak tables */
+ clearkeys(g->ephemeron, NULL); /* clear keys from all ephemeron tables */
+ clearkeys(g->allweak, NULL); /* clear keys from all allweak tables */
+ /* clear values from resurrected weak tables */
+ clearvalues(g->weak, origweak);
+ clearvalues(g->allweak, origall);
g->sweepstrgc = 0; /* prepare to sweep strings */
g->gcstate = GCSsweepstring;
g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */
diff --git a/src/lgc.h b/src/lgc.h
index 0fae4dd..aa5dfce 100755..100644
--- a/src/lgc.h
+++ b/src/lgc.h
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.h,v 2.50 2011/01/26 16:30:02 roberto Exp $
+** $Id: lgc.h,v 2.52 2011/10/03 17:54:25 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -63,9 +63,6 @@
#define l_setbit(x,b) setbits(x, bitmask(b))
#define resetbit(x,b) resetbits(x, bitmask(b))
#define testbit(x,b) testbits(x, bitmask(b))
-#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2)))
-#define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2)))
-
/* Layout for bit use in `marked' field: */
@@ -125,7 +122,6 @@
#define luaC_barrierproto(L,p,c) \
{ if (isblack(obj2gco(p))) luaC_barrierproto_(L,p,c); }
-LUAI_FUNC void luaC_separateudata (lua_State *L, int all);
LUAI_FUNC void luaC_freeallobjects (lua_State *L);
LUAI_FUNC void luaC_step (lua_State *L);
LUAI_FUNC void luaC_forcestep (lua_State *L);
diff --git a/src/linit.c b/src/linit.c
index 8d3aa65..8d3aa65 100755..100644
--- a/src/linit.c
+++ b/src/linit.c
diff --git a/src/liolib.c b/src/liolib.c
index 41e7ec5..4814aa2 100755..100644
--- a/src/liolib.c
+++ b/src/liolib.c
@@ -1,10 +1,20 @@
/*
-** $Id: liolib.c,v 2.101 2011/06/27 19:42:31 roberto Exp $
+** $Id: liolib.c,v 2.108 2011/11/25 12:50:03 roberto Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
+/*
+** POSIX idiosyncrasy!
+** This definition must come before the inclusion of 'stdio.h'; it
+** should not affect non-POSIX systems
+*/
+#if !defined(_FILE_OFFSET_BITS)
+#define _FILE_OFFSET_BITS 64
+#endif
+
+
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -21,9 +31,12 @@
/*
-** lua_popen spawns a new process connected to the current one through
-** the file streams.
+** {======================================================
+** lua_popen spawns a new process connected to the current
+** one through the file streams.
+** =======================================================
*/
+
#if !defined(lua_popen) /* { */
#if defined(LUA_USE_POPEN) /* { */
@@ -48,22 +61,50 @@
#endif /* } */
+/* }====================================================== */
+
+
+/*
+** {======================================================
+** lua_fseek/lua_ftell: configuration for longer offsets
+** =======================================================
+*/
+
+#if !defined(lua_fseek) /* { */
+
+#if defined(LUA_USE_POSIX)
+
+#define l_fseek(f,o,w) fseeko(f,o,w)
+#define l_ftell(f) ftello(f)
+#define l_seeknum off_t
+
+#elif defined(LUA_WIN) && !defined(_CRTIMP_TYPEINFO) \
+ && defined(_MSC_VER) && (_MSC_VER >= 1400)
+/* Windows (but not DDK) and Visual C++ 2005 or higher */
+
+#define l_fseek(f,o,w) _fseeki64(f,o,w)
+#define l_ftell(f) _ftelli64(f)
+#define l_seeknum __int64
+
+#else
+
+#define l_fseek(f,o,w) fseek(f,o,w)
+#define l_ftell(f) ftell(f)
+#define l_seeknum long
+
+#endif
+
+#endif /* } */
+
+/* }====================================================== */
+
#define IO_PREFIX "_IO_"
#define IO_INPUT (IO_PREFIX "input")
#define IO_OUTPUT (IO_PREFIX "output")
-typedef struct LStream {
- FILE *f; /* stream */
- lua_CFunction closef; /* to close stream (NULL for closed streams) */
-} LStream;
-
-
-static void fileerror (lua_State *L, int arg, const char *filename) {
- lua_pushfstring(L, "%s: %s", filename, strerror(errno));
- luaL_argerror(L, arg, lua_tostring(L, -1));
-}
+typedef luaL_Stream LStream;
#define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE))
@@ -159,6 +200,14 @@ static LStream *newfile (lua_State *L) {
}
+static void opencheck (lua_State *L, const char *fname, const char *mode) {
+ LStream *p = newfile(L);
+ p->f = fopen(fname, mode);
+ if (p->f == NULL)
+ luaL_error(L, "cannot open file " LUA_QS " (%s)", fname, strerror(errno));
+}
+
+
static int io_open (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
@@ -169,7 +218,7 @@ static int io_open (lua_State *L) {
(mode[i] != '+' || ++i) && /* skip if char is '+' */
(mode[i] != 'b' || ++i) && /* skip if char is 'b' */
(mode[i] == '\0')))
- return luaL_error(L, "invalid mode " LUA_QL("%s")
+ return luaL_error(L, "invalid mode " LUA_QS
" (should match " LUA_QL("[rwa]%%+?b?") ")", mode);
p->f = fopen(filename, mode);
return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
@@ -215,12 +264,8 @@ static FILE *getiofile (lua_State *L, const char *findex) {
static int g_iofile (lua_State *L, const char *f, const char *mode) {
if (!lua_isnoneornil(L, 1)) {
const char *filename = lua_tostring(L, 1);
- if (filename) {
- LStream *p = newfile(L);
- p->f = fopen(filename, mode);
- if (p->f == NULL)
- fileerror(L, 1, filename);
- }
+ if (filename)
+ opencheck(L, filename, mode);
else {
tofile(L); /* check that it's a valid file handle */
lua_pushvalue(L, 1);
@@ -277,10 +322,7 @@ static int io_lines (lua_State *L) {
}
else { /* open a new file */
const char *filename = luaL_checkstring(L, 1);
- LStream *p = newfile(L);
- p->f = fopen(filename, "r");
- if (p->f == NULL)
- fileerror(L, 1, filename);
+ opencheck(L, filename, "r");
lua_replace(L, 1); /* put file at index 1 */
toclose = 1; /* close it after iteration */
}
@@ -444,9 +486,10 @@ static int io_readline (lua_State *L) {
if (!lua_isnil(L, -n)) /* read at least one value? */
return n; /* return them */
else { /* first result is nil: EOF or error */
- if (!lua_isnil(L, -1)) /* is there error information? */
- return luaL_error(L, "%s", lua_tostring(L, -1)); /* error */
- /* else EOF */
+ if (n > 1) { /* is there error information? */
+ /* 2nd result is error message */
+ return luaL_error(L, "%s", lua_tostring(L, -n + 1));
+ }
if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */
lua_settop(L, 0);
lua_pushvalue(L, lua_upvalueindex(1));
@@ -496,12 +539,15 @@ static int f_seek (lua_State *L) {
static const char *const modenames[] = {"set", "cur", "end", NULL};
FILE *f = tofile(L);
int op = luaL_checkoption(L, 2, "cur", modenames);
- long offset = luaL_optlong(L, 3, 0);
- op = fseek(f, offset, mode[op]);
+ lua_Number p3 = luaL_optnumber(L, 3, 0);
+ l_seeknum offset = (l_seeknum)p3;
+ luaL_argcheck(L, (lua_Number)offset == p3, 3,
+ "not an integer in proper range");
+ op = l_fseek(f, offset, mode[op]);
if (op)
return luaL_fileresult(L, 0, NULL); /* error */
else {
- lua_pushinteger(L, ftell(f));
+ lua_pushnumber(L, (lua_Number)l_ftell(f));
return 1;
}
}
diff --git a/src/llex.c b/src/llex.c
index 289abfd..74deebb 100755..100644
--- a/src/llex.c
+++ b/src/llex.c
@@ -1,5 +1,5 @@
/*
-** $Id: llex.c,v 2.53 2011/07/08 20:01:38 roberto Exp $
+** $Id: llex.c,v 2.59 2011/11/30 12:43:51 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -46,7 +46,7 @@ static const char *const luaX_tokens [] = {
#define save_and_next(ls) (save(ls, ls->current), next(ls))
-static void lexerror (LexState *ls, const char *msg, int token);
+static l_noret lexerror (LexState *ls, const char *msg, int token);
static void save (LexState *ls, int c) {
@@ -101,7 +101,7 @@ static const char *txtToken (LexState *ls, int token) {
}
-static void lexerror (LexState *ls, const char *msg, int token) {
+static l_noret lexerror (LexState *ls, const char *msg, int token) {
char buff[LUA_IDSIZE];
luaO_chunkid(buff, getstr(ls->source), LUA_IDSIZE);
msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg);
@@ -111,7 +111,7 @@ static void lexerror (LexState *ls, const char *msg, int token) {
}
-void luaX_syntaxerror (LexState *ls, const char *msg) {
+l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
lexerror(ls, msg, ls->t.token);
}
@@ -126,8 +126,10 @@ TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
TValue *o; /* entry for `str' */
TString *ts = luaS_newlstr(L, str, l); /* create new string */
setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */
- o = luaH_setstr(L, ls->fs->h, ts);
- if (ttisnil(o)) {
+ o = luaH_set(L, ls->fs->h, L->top - 1);
+ if (ttisnil(o)) { /* not in use yet? (see 'addK') */
+ /* boolean value does not need GC barrier;
+ table has no metatable, so it does not need to invalidate cache */
setbvalue(o, 1); /* t[string] = true */
luaC_checkGC(L);
}
@@ -297,39 +299,29 @@ static void escerror (LexState *ls, int *c, int n, const char *msg) {
static int readhexaesc (LexState *ls) {
- int c[3]; /* keep input for error message */
- int i = 2; /* at least 'x?' will go to error message */
- c[0] = 'x';
- c[1] = next(ls); /* first hexa digit */
- if (lisxdigit(c[1])) {
- c[i++] = next(ls); /* second hexa digit */
- if (lisxdigit(c[2]))
- return (luaO_hexavalue(c[1]) << 4) + luaO_hexavalue(c[2]);
- /* else go through to error */
+ int c[3], i; /* keep input for error message */
+ int r = 0; /* result accumulator */
+ c[0] = 'x'; /* for error message */
+ for (i = 1; i < 3; i++) { /* read two hexa digits */
+ c[i] = next(ls);
+ if (!lisxdigit(c[i]))
+ escerror(ls, c, i + 1, "hexadecimal digit expected");
+ r = (r << 4) + luaO_hexavalue(c[i]);
}
- escerror(ls, c, i, "hexadecimal digit expected");
- return 0; /* to avoid warnings */
+ return r;
}
static int readdecesc (LexState *ls) {
- int c[3], r;
- int i = 2; /* at least two chars will be read */
- c[0] = ls->current; /* first char must be a digit */
- c[1] = next(ls); /* read second char */
- r = c[0] - '0'; /* partial result */
- if (lisdigit(c[1])) {
- c[i++] = next(ls); /* read third char */
- r = 10*r + c[1] - '0'; /* update result */
- if (lisdigit(c[2])) {
- r = 10*r + c[2] - '0'; /* update result */
- if (r > UCHAR_MAX)
- escerror(ls, c, i, "decimal escape too large");
- return r;
- }
+ int c[3], i;
+ int r = 0; /* result accumulator */
+ for (i = 0; i < 3 && lisdigit(ls->current); i++) { /* read up to 3 digits */
+ c[i] = ls->current;
+ r = 10*r + c[i] - '0';
+ next(ls);
}
- /* else, has read one character that was not a digit */
- zungetc(ls->z); /* return it to input stream */
+ if (r > UCHAR_MAX)
+ escerror(ls, c, i, "decimal escape too large");
return r;
}
@@ -349,37 +341,38 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) {
int c; /* final character to be saved */
next(ls); /* do not save the `\' */
switch (ls->current) {
- case 'a': c = '\a'; break;
- case 'b': c = '\b'; break;
- case 'f': c = '\f'; break;
- case 'n': c = '\n'; break;
- case 'r': c = '\r'; break;
- case 't': c = '\t'; break;
- case 'v': c = '\v'; break;
- case 'x': c = readhexaesc(ls); break;
- case '\n':
- case '\r': save(ls, '\n'); inclinenumber(ls); continue;
- case '\\': case '\"': case '\'': c = ls->current; break;
- case EOZ: continue; /* will raise an error next loop */
+ case 'a': c = '\a'; goto read_save;
+ case 'b': c = '\b'; goto read_save;
+ case 'f': c = '\f'; goto read_save;
+ case 'n': c = '\n'; goto read_save;
+ case 'r': c = '\r'; goto read_save;
+ case 't': c = '\t'; goto read_save;
+ case 'v': c = '\v'; goto read_save;
+ case 'x': c = readhexaesc(ls); goto read_save;
+ case '\n': case '\r':
+ inclinenumber(ls); c = '\n'; goto only_save;
+ case '\\': case '\"': case '\'':
+ c = ls->current; goto read_save;
+ case EOZ: goto no_save; /* will raise an error next loop */
case 'z': { /* zap following span of spaces */
next(ls); /* skip the 'z' */
while (lisspace(ls->current)) {
if (currIsNewline(ls)) inclinenumber(ls);
else next(ls);
}
- continue; /* do not save 'c' */
+ goto no_save;
}
default: {
if (!lisdigit(ls->current))
escerror(ls, &ls->current, 1, "invalid escape sequence");
/* digital escape \ddd */
c = readdecesc(ls);
- break;
+ goto only_save;
}
}
- next(ls);
- save(ls, c);
- break;
+ read_save: next(ls); /* read next character */
+ only_save: save(ls, c); /* save 'c' */
+ no_save: break;
}
default:
save_and_next(ls);
diff --git a/src/llex.h b/src/llex.h
index ce0bad4..9ca8a29 100755..100644
--- a/src/llex.h
+++ b/src/llex.h
@@ -1,5 +1,5 @@
/*
-** $Id: llex.h,v 1.71 2011/06/20 16:52:48 roberto Exp $
+** $Id: llex.h,v 1.72 2011/11/30 12:43:51 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -71,7 +71,7 @@ LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z,
LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l);
LUAI_FUNC void luaX_next (LexState *ls);
LUAI_FUNC int luaX_lookahead (LexState *ls);
-LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s);
+LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s);
LUAI_FUNC const char *luaX_token2str (LexState *ls, int token);
diff --git a/src/llimits.h b/src/llimits.h
index b64c7b7..48dc81f 100755..100644
--- a/src/llimits.h
+++ b/src/llimits.h
@@ -1,5 +1,5 @@
/*
-** $Id: llimits.h,v 1.90 2011/07/02 15:57:25 roberto Exp $
+** $Id: llimits.h,v 1.95 2011/12/06 16:58:36 roberto Exp $
** Limits, basic types, and some other `installation-dependent' definitions
** See Copyright Notice in lua.h
*/
@@ -30,7 +30,6 @@ typedef unsigned char lu_byte;
#define MAX_SIZET ((size_t)(~(size_t)0)-2)
#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2)
-#define MIN_LMEM ((l_mem)~((~(lu_mem)0)>>1))
#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
@@ -62,9 +61,9 @@ typedef LUAI_UACNUMBER l_uacNumber;
/* to avoid problems with conditions too long */
#define lua_longassert(c) { if (!(c)) lua_assert(0); }
#else
-#define lua_assert(c) /* empty */
+#define lua_assert(c) ((void)0)
#define check_exp(c,e) (e)
-#define lua_longassert(c) /* empty */
+#define lua_longassert(c) ((void)0)
#endif
/*
@@ -98,6 +97,19 @@ typedef LUAI_UACNUMBER l_uacNumber;
/*
+** non-return type
+*/
+#if defined(__GNUC__)
+#define l_noret void __attribute__((noreturn))
+#elif defined(_MSC_VER)
+#define l_noret void __declspec(noreturn)
+#else
+#define l_noret void
+#endif
+
+
+
+/*
** maximum depth for nested C calls and syntactical nested non-terminals
** in a program. (Value must fit in an unsigned short int.)
*/
@@ -216,7 +228,7 @@ union luai_Cast { double l_d; LUA_INT32 l_p[2]; };
#define luai_hashnum(i,n) \
{ volatile union luai_Cast u; u.l_d = (n) + 1.0; /* avoid -0 */ \
- (i) = u.l_p[0] + u.l_p[1]; } /* add double bits for his hash */
+ (i) = u.l_p[0]; (i) += u.l_p[1]; } /* add double bits for his hash */
#define lua_number2int(i,n) lua_number2int32(i, n, int)
#define lua_number2integer(i,n) lua_number2int32(i, n, lua_Integer)
@@ -257,7 +269,7 @@ union luai_Cast { double l_d; LUA_INT32 l_p[2]; };
-#if (defined(ltable_c) || defined(luaall_c)) && !defined(luai_hashnum)
+#if defined(ltable_c) && !defined(luai_hashnum)
#include <float.h>
#include <math.h>
diff --git a/src/lmathlib.c b/src/lmathlib.c
index b17237f..b17237f 100755..100644
--- a/src/lmathlib.c
+++ b/src/lmathlib.c
diff --git a/src/lmem.c b/src/lmem.c
index c3775df..792deb3 100755..100644
--- a/src/lmem.c
+++ b/src/lmem.c
@@ -1,5 +1,5 @@
/*
-** $Id: lmem.c,v 1.81 2010/12/20 19:40:07 roberto Exp $
+** $Id: lmem.c,v 1.83 2011/11/30 12:42:49 roberto Exp $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
@@ -63,9 +63,8 @@ void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
}
-void *luaM_toobig (lua_State *L) {
+l_noret luaM_toobig (lua_State *L) {
luaG_runerror(L, "memory allocation error: block too big");
- return NULL; /* to avoid warnings */
}
@@ -106,7 +105,7 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
if ((total % 200) == 0) {
if (f == NULL) f = fopen(TRACEMEM, "w");
fprintf(f, "%lu %u %d %d\n", total,
- g->totalbytes, g->GCdebt, g->gcstate * 1000);
+ gettotalbytes(g), g->GCdebt, g->gcstate * 10000);
}
}
#endif
diff --git a/src/lmem.h b/src/lmem.h
index ff324f8..535dfe0 100755..100644
--- a/src/lmem.h
+++ b/src/lmem.h
@@ -1,5 +1,5 @@
/*
-** $Id: lmem.h,v 1.36 2010/04/08 17:16:46 roberto Exp $
+** $Id: lmem.h,v 1.38 2011/12/02 13:26:54 roberto Exp $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
@@ -15,9 +15,9 @@
#define luaM_reallocv(L,b,on,n,e) \
- ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \
- luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \
- luaM_toobig(L))
+ ((cast(size_t, (n)+1) > MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \
+ (luaM_toobig(L), (void *)0) : \
+ luaM_realloc_(L, (b), (on)*(e), (n)*(e)))
#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0)
#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0)
@@ -37,7 +37,7 @@
#define luaM_reallocvector(L, v,oldn,n,t) \
((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
-LUAI_FUNC void *luaM_toobig (lua_State *L);
+LUAI_FUNC l_noret luaM_toobig (lua_State *L);
/* not to be called directly */
LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
diff --git a/src/loadlib.c b/src/loadlib.c
index 0313d8e..783bc12 100755..100644
--- a/src/loadlib.c
+++ b/src/loadlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: loadlib.c,v 1.100 2011/07/05 12:49:35 roberto Exp $
+** $Id: loadlib.c,v 1.108 2011/12/12 16:34:03 roberto Exp $
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
**
@@ -9,6 +9,14 @@
*/
+/*
+** if needed, includes windows header before everything else
+*/
+#if defined(_WIN32)
+#include <windows.h>
+#endif
+
+
#include <stdlib.h>
#include <string.h>
@@ -62,6 +70,20 @@
#endif
+/*
+** LUA_CSUBSEP is the character that replaces dots in submodule names
+** when searching for a C loader.
+** LUA_LSUBSEP is the character that replaces dots in submodule names
+** when searching for a Lua loader.
+*/
+#if !defined(LUA_CSUBSEP)
+#define LUA_CSUBSEP LUA_DIRSEP
+#endif
+
+#if !defined(LUA_LSUBSEP)
+#define LUA_LSUBSEP LUA_DIRSEP
+#endif
+
/* prefix for open functions in C libraries */
#define LUA_POF "luaopen_"
@@ -110,7 +132,7 @@ static void ll_unloadlib (void *lib) {
static void *ll_load (lua_State *L, const char *path, int seeglb) {
- void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : 0));
+ void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL));
if (lib == NULL) lua_pushstring(L, dlerror());
return lib;
}
@@ -133,8 +155,6 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
** =======================================================================
*/
-#include <windows.h>
-
#undef setprogdir
/*
@@ -177,7 +197,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); /* not used: symbols are 'global' by default */
if (lib == NULL) pusherror(L);
return lib;
}
@@ -207,19 +227,19 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
static void ll_unloadlib (void *lib) {
- (void)(lib); /* to avoid warnings */
+ (void)(lib); /* not used */
}
static void *ll_load (lua_State *L, const char *path, int seeglb) {
- (void)(path); (void)(seeglb); /* to avoid warnings */
+ (void)(path); (void)(seeglb); /* not used */
lua_pushliteral(L, DLMSG);
return NULL;
}
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
- (void)(lib); (void)(sym); /* to avoid warnings */
+ (void)(lib); (void)(sym); /* not used */
lua_pushliteral(L, DLMSG);
return NULL;
}
@@ -322,10 +342,12 @@ static const char *pushnexttemplate (lua_State *L, const char *path) {
static const char *searchpath (lua_State *L, const char *name,
const char *path,
- const char *sep) {
+ const char *sep,
+ const char *dirsep) {
+ luaL_Buffer msg; /* to build error message */
+ luaL_buffinit(L, &msg);
if (*sep != '\0') /* non-empty separator? */
- name = luaL_gsub(L, name, sep, LUA_DIRSEP); /* replace it by proper one */
- lua_pushliteral(L, ""); /* error accumulator */
+ name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */
while ((path = pushnexttemplate(L, path)) != NULL) {
const char *filename = luaL_gsub(L, lua_tostring(L, -1),
LUA_PATH_MARK, name);
@@ -334,8 +356,9 @@ static const char *searchpath (lua_State *L, const char *name,
return filename; /* return that file name */
lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
lua_remove(L, -2); /* remove file name */
- lua_concat(L, 2); /* add entry to possible error message */
+ luaL_addvalue(&msg); /* concatenate error msg. entry */
}
+ luaL_pushresult(&msg); /* create error message */
return NULL; /* not found */
}
@@ -343,7 +366,8 @@ static const char *searchpath (lua_State *L, const char *name,
static int ll_searchpath (lua_State *L) {
const char *f = searchpath(L, luaL_checkstring(L, 1),
luaL_checkstring(L, 2),
- luaL_optstring(L, 3, "."));
+ luaL_optstring(L, 3, "."),
+ luaL_optstring(L, 4, LUA_DIRSEP));
if (f != NULL) return 1;
else { /* error message is on top of the stack */
lua_pushnil(L);
@@ -354,13 +378,14 @@ static int ll_searchpath (lua_State *L) {
static const char *findfile (lua_State *L, const char *name,
- const char *pname) {
+ const char *pname,
+ const char *dirsep) {
const char *path;
lua_getfield(L, lua_upvalueindex(1), pname);
path = lua_tostring(L, -1);
if (path == NULL)
luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
- return searchpath(L, name, path, ".");
+ return searchpath(L, name, path, ".", dirsep);
}
@@ -379,7 +404,7 @@ static int checkload (lua_State *L, int stat, const char *filename) {
static int searcher_Lua (lua_State *L) {
const char *filename;
const char *name = luaL_checkstring(L, 1);
- filename = findfile(L, name, "path");
+ filename = findfile(L, name, "path", LUA_LSUBSEP);
if (filename == NULL) return 1; /* module not found in this path */
return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename);
}
@@ -405,7 +430,7 @@ static int loadfunc (lua_State *L, const char *filename, const char *modname) {
static int searcher_C (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
- const char *filename = findfile(L, name, "cpath");
+ const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP);
if (filename == NULL) return 1; /* module not found in this path */
return checkload(L, (loadfunc(L, filename, name) == 0), filename);
}
@@ -418,7 +443,7 @@ static int searcher_Croot (lua_State *L) {
int stat;
if (p == NULL) return 0; /* is root */
lua_pushlstring(L, name, p - name);
- filename = findfile(L, lua_tostring(L, -1), "cpath");
+ filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP);
if (filename == NULL) return 1; /* root not found */
if ((stat = loadfunc(L, filename, name)) != 0) {
if (stat != ERRFUNC)
@@ -444,35 +469,46 @@ static int searcher_preload (lua_State *L) {
}
-static int ll_require (lua_State *L) {
- const char *name = luaL_checkstring(L, 1);
+static void findloader (lua_State *L, const char *name) {
int i;
- lua_settop(L, 1); /* _LOADED table will be at index 2 */
- lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
- lua_getfield(L, 2, name);
- if (lua_toboolean(L, -1)) /* is it there? */
- return 1; /* package is already loaded */
- /* else must load it; iterate over available seachers to find a loader */
- lua_getfield(L, lua_upvalueindex(1), "searchers");
- if (!lua_istable(L, -1))
+ luaL_Buffer msg; /* to build error message */
+ luaL_buffinit(L, &msg);
+ lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */
+ if (!lua_istable(L, 3))
luaL_error(L, LUA_QL("package.searchers") " must be a table");
- lua_pushliteral(L, ""); /* error message accumulator */
- for (i=1; ; i++) {
- lua_rawgeti(L, -2, i); /* get a seacher */
- if (lua_isnil(L, -1)) /* no more searchers? */
+ /* iterate over available seachers to find a loader */
+ for (i = 1; ; i++) {
+ lua_rawgeti(L, 3, i); /* get a seacher */
+ if (lua_isnil(L, -1)) { /* no more searchers? */
+ lua_pop(L, 1); /* remove nil */
+ luaL_pushresult(&msg); /* create error message */
luaL_error(L, "module " LUA_QS " not found:%s",
- name, lua_tostring(L, -2));
+ name, lua_tostring(L, -1));
+ }
lua_pushstring(L, name);
lua_call(L, 1, 2); /* call it */
if (lua_isfunction(L, -2)) /* did it find a loader? */
- break; /* module loader found */
+ return; /* module loader found */
else if (lua_isstring(L, -2)) { /* searcher returned error message? */
lua_pop(L, 1); /* remove extra return */
- lua_concat(L, 2); /* accumulate error message */
+ luaL_addvalue(&msg); /* concatenate error message */
}
else
lua_pop(L, 2); /* remove both returns */
}
+}
+
+
+static int ll_require (lua_State *L) {
+ const char *name = luaL_checkstring(L, 1);
+ lua_settop(L, 1); /* _LOADED table will be at index 2 */
+ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
+ lua_getfield(L, 2, name); /* _LOADED[name] */
+ if (lua_toboolean(L, -1)) /* is it there? */
+ return 1; /* package is already loaded */
+ /* else must load package */
+ lua_pop(L, 1); /* remove 'getfield' result */
+ findloader(L, name);
lua_pushstring(L, name); /* pass name as argument to module loader */
lua_insert(L, -2); /* name is 1st argument (before search data) */
lua_call(L, 2, 1); /* run loader to load module */
@@ -516,9 +552,11 @@ static void set_env (lua_State *L) {
static void dooptions (lua_State *L, int n) {
int i;
for (i = 2; i <= n; i++) {
- lua_pushvalue(L, i); /* get option (a function) */
- lua_pushvalue(L, -2); /* module */
- lua_call(L, 1, 0);
+ if (lua_isfunction(L, i)) { /* avoid 'calling' extra info. */
+ lua_pushvalue(L, i); /* get option (a function) */
+ lua_pushvalue(L, -2); /* module */
+ lua_call(L, 1, 0);
+ }
}
}
@@ -577,12 +615,25 @@ static int ll_seeall (lua_State *L) {
/* auxiliary mark (for internal use) */
#define AUXMARK "\1"
+
+/*
+** return registry.LUA_NOENV as a boolean
+*/
+static int noenv (lua_State *L) {
+ int b;
+ lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
+ b = lua_toboolean(L, -1);
+ lua_pop(L, 1); /* remove value */
+ return b;
+}
+
+
static void setpath (lua_State *L, const char *fieldname, const char *envname1,
const char *envname2, const char *def) {
const char *path = getenv(envname1);
if (path == NULL) /* no environment variable? */
path = getenv(envname2); /* try alternative name */
- if (path == NULL) /* no environment variable? */
+ if (path == NULL || noenv(L)) /* no environment variable? */
lua_pushstring(L, def); /* use default */
else {
/* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
diff --git a/src/loadlib_rel.c b/src/loadlib_rel.c
index 9ebd8cc..13fce89 100644
--- a/src/loadlib_rel.c
+++ b/src/loadlib_rel.c
@@ -1,5 +1,5 @@
/*
-** $Id: loadlib.c,v 1.100 2011/07/05 12:49:35 roberto Exp $
+** $Id: loadlib.c,v 1.108 2011/12/12 16:34:03 roberto Exp $
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
**
@@ -9,6 +9,14 @@
*/
+/*
+** if needed, includes windows header before everything else
+*/
+#if defined(_WIN32)
+#include <windows.h>
+#endif
+
+
#include <stdlib.h>
#include <string.h>
@@ -62,6 +70,20 @@
#endif
+/*
+** LUA_CSUBSEP is the character that replaces dots in submodule names
+** when searching for a C loader.
+** LUA_LSUBSEP is the character that replaces dots in submodule names
+** when searching for a Lua loader.
+*/
+#if !defined(LUA_CSUBSEP)
+#define LUA_CSUBSEP LUA_DIRSEP
+#endif
+
+#if !defined(LUA_LSUBSEP)
+#define LUA_LSUBSEP LUA_DIRSEP
+#endif
+
/* prefix for open functions in C libraries */
#define LUA_POF "luaopen_"
@@ -91,6 +113,7 @@ static void setprogdir (lua_State *L);
/*
** {=========================================================================
** This determines the location of the executable for relative module loading
+** Modified by the LuaDist project for UNIX platforms
** ==========================================================================
*/
#if defined(_WIN32) || defined(__CYGWIN__)
@@ -161,7 +184,6 @@ static void setprogdir (lua_State *L) {
}
}
-
#if defined(LUA_USE_DLOPEN)
/*
** {========================================================================
@@ -180,7 +202,7 @@ static void ll_unloadlib (void *lib) {
static void *ll_load (lua_State *L, const char *path, int seeglb) {
- void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : 0));
+ void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL));
if (lib == NULL) lua_pushstring(L, dlerror());
return lib;
}
@@ -203,8 +225,6 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
** =======================================================================
*/
-#include <windows.h>
-
/*
** optional flags for LoadLibraryEx
*/
@@ -229,7 +249,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); /* not used: symbols are 'global' by default */
if (lib == NULL) pusherror(L);
return lib;
}
@@ -259,19 +279,19 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
static void ll_unloadlib (void *lib) {
- (void)(lib); /* to avoid warnings */
+ (void)(lib); /* not used */
}
static void *ll_load (lua_State *L, const char *path, int seeglb) {
- (void)(path); (void)(seeglb); /* to avoid warnings */
+ (void)(path); (void)(seeglb); /* not used */
lua_pushliteral(L, DLMSG);
return NULL;
}
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
- (void)(lib); (void)(sym); /* to avoid warnings */
+ (void)(lib); (void)(sym); /* not used */
lua_pushliteral(L, DLMSG);
return NULL;
}
@@ -374,10 +394,12 @@ static const char *pushnexttemplate (lua_State *L, const char *path) {
static const char *searchpath (lua_State *L, const char *name,
const char *path,
- const char *sep) {
+ const char *sep,
+ const char *dirsep) {
+ luaL_Buffer msg; /* to build error message */
+ luaL_buffinit(L, &msg);
if (*sep != '\0') /* non-empty separator? */
- name = luaL_gsub(L, name, sep, LUA_DIRSEP); /* replace it by proper one */
- lua_pushliteral(L, ""); /* error accumulator */
+ name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */
while ((path = pushnexttemplate(L, path)) != NULL) {
const char *filename = luaL_gsub(L, lua_tostring(L, -1),
LUA_PATH_MARK, name);
@@ -386,8 +408,9 @@ static const char *searchpath (lua_State *L, const char *name,
return filename; /* return that file name */
lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
lua_remove(L, -2); /* remove file name */
- lua_concat(L, 2); /* add entry to possible error message */
+ luaL_addvalue(&msg); /* concatenate error msg. entry */
}
+ luaL_pushresult(&msg); /* create error message */
return NULL; /* not found */
}
@@ -395,7 +418,8 @@ static const char *searchpath (lua_State *L, const char *name,
static int ll_searchpath (lua_State *L) {
const char *f = searchpath(L, luaL_checkstring(L, 1),
luaL_checkstring(L, 2),
- luaL_optstring(L, 3, "."));
+ luaL_optstring(L, 3, "."),
+ luaL_optstring(L, 4, LUA_DIRSEP));
if (f != NULL) return 1;
else { /* error message is on top of the stack */
lua_pushnil(L);
@@ -406,13 +430,14 @@ static int ll_searchpath (lua_State *L) {
static const char *findfile (lua_State *L, const char *name,
- const char *pname) {
+ const char *pname,
+ const char *dirsep) {
const char *path;
lua_getfield(L, lua_upvalueindex(1), pname);
path = lua_tostring(L, -1);
if (path == NULL)
luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
- return searchpath(L, name, path, ".");
+ return searchpath(L, name, path, ".", dirsep);
}
@@ -431,7 +456,7 @@ static int checkload (lua_State *L, int stat, const char *filename) {
static int searcher_Lua (lua_State *L) {
const char *filename;
const char *name = luaL_checkstring(L, 1);
- filename = findfile(L, name, "path");
+ filename = findfile(L, name, "path", LUA_LSUBSEP);
if (filename == NULL) return 1; /* module not found in this path */
return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename);
}
@@ -457,7 +482,7 @@ static int loadfunc (lua_State *L, const char *filename, const char *modname) {
static int searcher_C (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
- const char *filename = findfile(L, name, "cpath");
+ const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP);
if (filename == NULL) return 1; /* module not found in this path */
return checkload(L, (loadfunc(L, filename, name) == 0), filename);
}
@@ -470,7 +495,7 @@ static int searcher_Croot (lua_State *L) {
int stat;
if (p == NULL) return 0; /* is root */
lua_pushlstring(L, name, p - name);
- filename = findfile(L, lua_tostring(L, -1), "cpath");
+ filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP);
if (filename == NULL) return 1; /* root not found */
if ((stat = loadfunc(L, filename, name)) != 0) {
if (stat != ERRFUNC)
@@ -496,35 +521,46 @@ static int searcher_preload (lua_State *L) {
}
-static int ll_require (lua_State *L) {
- const char *name = luaL_checkstring(L, 1);
+static void findloader (lua_State *L, const char *name) {
int i;
- lua_settop(L, 1); /* _LOADED table will be at index 2 */
- lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
- lua_getfield(L, 2, name);
- if (lua_toboolean(L, -1)) /* is it there? */
- return 1; /* package is already loaded */
- /* else must load it; iterate over available seachers to find a loader */
- lua_getfield(L, lua_upvalueindex(1), "searchers");
- if (!lua_istable(L, -1))
+ luaL_Buffer msg; /* to build error message */
+ luaL_buffinit(L, &msg);
+ lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */
+ if (!lua_istable(L, 3))
luaL_error(L, LUA_QL("package.searchers") " must be a table");
- lua_pushliteral(L, ""); /* error message accumulator */
- for (i=1; ; i++) {
- lua_rawgeti(L, -2, i); /* get a seacher */
- if (lua_isnil(L, -1)) /* no more searchers? */
+ /* iterate over available seachers to find a loader */
+ for (i = 1; ; i++) {
+ lua_rawgeti(L, 3, i); /* get a seacher */
+ if (lua_isnil(L, -1)) { /* no more searchers? */
+ lua_pop(L, 1); /* remove nil */
+ luaL_pushresult(&msg); /* create error message */
luaL_error(L, "module " LUA_QS " not found:%s",
- name, lua_tostring(L, -2));
+ name, lua_tostring(L, -1));
+ }
lua_pushstring(L, name);
lua_call(L, 1, 2); /* call it */
if (lua_isfunction(L, -2)) /* did it find a loader? */
- break; /* module loader found */
+ return; /* module loader found */
else if (lua_isstring(L, -2)) { /* searcher returned error message? */
lua_pop(L, 1); /* remove extra return */
- lua_concat(L, 2); /* accumulate error message */
+ luaL_addvalue(&msg); /* concatenate error message */
}
else
lua_pop(L, 2); /* remove both returns */
}
+}
+
+
+static int ll_require (lua_State *L) {
+ const char *name = luaL_checkstring(L, 1);
+ lua_settop(L, 1); /* _LOADED table will be at index 2 */
+ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
+ lua_getfield(L, 2, name); /* _LOADED[name] */
+ if (lua_toboolean(L, -1)) /* is it there? */
+ return 1; /* package is already loaded */
+ /* else must load package */
+ lua_pop(L, 1); /* remove 'getfield' result */
+ findloader(L, name);
lua_pushstring(L, name); /* pass name as argument to module loader */
lua_insert(L, -2); /* name is 1st argument (before search data) */
lua_call(L, 2, 1); /* run loader to load module */
@@ -568,9 +604,11 @@ static void set_env (lua_State *L) {
static void dooptions (lua_State *L, int n) {
int i;
for (i = 2; i <= n; i++) {
- lua_pushvalue(L, i); /* get option (a function) */
- lua_pushvalue(L, -2); /* module */
- lua_call(L, 1, 0);
+ if (lua_isfunction(L, i)) { /* avoid 'calling' extra info. */
+ lua_pushvalue(L, i); /* get option (a function) */
+ lua_pushvalue(L, -2); /* module */
+ lua_call(L, 1, 0);
+ }
}
}
@@ -629,12 +667,25 @@ static int ll_seeall (lua_State *L) {
/* auxiliary mark (for internal use) */
#define AUXMARK "\1"
+
+/*
+** return registry.LUA_NOENV as a boolean
+*/
+static int noenv (lua_State *L) {
+ int b;
+ lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
+ b = lua_toboolean(L, -1);
+ lua_pop(L, 1); /* remove value */
+ return b;
+}
+
+
static void setpath (lua_State *L, const char *fieldname, const char *envname1,
const char *envname2, const char *def) {
const char *path = getenv(envname1);
if (path == NULL) /* no environment variable? */
path = getenv(envname2); /* try alternative name */
- if (path == NULL) /* no environment variable? */
+ if (path == NULL || noenv(L)) /* no environment variable? */
lua_pushstring(L, def); /* use default */
else {
/* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
diff --git a/src/lobject.c b/src/lobject.c
index d8cc3ce..cf0f754 100755..100644
--- a/src/lobject.c
+++ b/src/lobject.c
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.c,v 2.52 2011/06/24 12:25:02 roberto Exp $
+** $Id: lobject.c,v 2.55 2011/11/30 19:30:16 roberto Exp $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
@@ -33,7 +33,7 @@ LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT};
** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
** eeeee != 0 and (xxx) otherwise.
*/
-int luaO_int2fb (lu_int32 x) {
+int luaO_int2fb (unsigned int x) {
int e = 0; /* exponent */
if (x < 8) return x;
while (x >= 0x10) {
@@ -103,8 +103,8 @@ static int isneg (const char **s) {
static lua_Number readhexa (const char **s, lua_Number r, int *count) {
- while (lisxdigit(cast_uchar(**s))) { /* read integer part */
- r = (r * 16.0) + cast_num(luaO_hexavalue(cast_uchar(*(*s)++)));
+ for (; lisxdigit(cast_uchar(**s)); (*s)++) { /* read integer part */
+ r = (r * 16.0) + cast_num(luaO_hexavalue(cast_uchar(**s)));
(*count)++;
}
return r;
@@ -157,7 +157,9 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
int luaO_str2d (const char *s, size_t len, lua_Number *result) {
char *endptr;
- if (strpbrk(s, "xX")) /* hexa? */
+ if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */
+ return 0;
+ else if (strpbrk(s, "xX")) /* hexa? */
*result = lua_strx2number(s, &endptr);
else
*result = lua_str2number(s, &endptr);
@@ -219,7 +221,6 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
luaG_runerror(L,
"invalid option " LUA_QL("%%%c") " to " LUA_QL("lua_pushfstring"),
*(e + 1));
- break;
}
}
n += 2;
diff --git a/src/lobject.h b/src/lobject.h
index d69d615..06246bf 100755..100644
--- a/src/lobject.h
+++ b/src/lobject.h
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.h,v 2.61 2011/07/04 20:29:02 roberto Exp $
+** $Id: lobject.h,v 2.64 2011/10/31 17:48:22 roberto Exp $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@@ -132,7 +132,7 @@ typedef struct lua_TValue TValue;
#define ttislcf(o) checktag((o), LUA_TLCF)
#define ttisuserdata(o) checktag((o), ctb(LUA_TUSERDATA))
#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD))
-#define ttisdeadkey(o) checktag((o), ctb(LUA_TDEADKEY))
+#define ttisdeadkey(o) checktag((o), LUA_TDEADKEY)
#define ttisequal(o1,o2) (rttype(o1) == rttype(o2))
@@ -151,6 +151,8 @@ typedef struct lua_TValue TValue;
#define hvalue(o) check_exp(ttistable(o), &val_(o).gc->h)
#define bvalue(o) check_exp(ttisboolean(o), val_(o).b)
#define thvalue(o) check_exp(ttisthread(o), &val_(o).gc->th)
+/* a dead value may get the 'gc' field, but cannot access its contents */
+#define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc))
#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
@@ -224,7 +226,7 @@ typedef struct lua_TValue TValue;
val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TPROTO)); \
checkliveness(G(L),io); }
-#define setdeadvalue(obj) settt_(obj, ctb(LUA_TDEADKEY))
+#define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY)
@@ -262,51 +264,73 @@ typedef struct lua_TValue TValue;
** =======================================================
*/
-#if defined(LUA_NANTRICKLE) || defined(LUA_NANTRICKBE)
+#if defined(LUA_NANTRICK) \
+ || defined(LUA_NANTRICK_LE) \
+ || defined(LUA_NANTRICK_BE)
/*
** numbers are represented in the 'd_' field. All other values have the
-** value (NNMARK | tag) in 'tt_'. A number with such pattern would be
+** value (NNMARK | tag) in 'tt__'. A number with such pattern would be
** a "signaled NaN", which is never generated by regular operations by
** the CPU (nor by 'strtod')
*/
#if !defined(NNMARK)
#define NNMARK 0x7FF7A500
+#define NNMASK 0x7FFFFF00
#endif
#undef TValuefields
#undef NILCONSTANT
-#if defined(LUA_NANTRICKLE)
+
+#if defined(LUA_NANTRICK_LE)
+
/* little endian */
#define TValuefields \
- union { struct { Value v_; int tt_; } i; double d_; } u
+ union { struct { Value v__; int tt__; } i; double d__; } u
#define NILCONSTANT {{{NULL}, tag2tt(LUA_TNIL)}}
-#else
+/* field-access macros */
+#define v_(o) ((o)->u.i.v__)
+#define d_(o) ((o)->u.d__)
+#define tt_(o) ((o)->u.i.tt__)
+
+#elif defined(LUA_NANTRICK_BE)
+
/* big endian */
#define TValuefields \
- union { struct { int tt_; Value v_; } i; double d_; } u
+ union { struct { int tt__; Value v__; } i; double d__; } u
#define NILCONSTANT {{tag2tt(LUA_TNIL), {NULL}}}
+/* field-access macros */
+#define v_(o) ((o)->u.i.v__)
+#define d_(o) ((o)->u.d__)
+#define tt_(o) ((o)->u.i.tt__)
+
+#elif !defined(TValuefields)
+#error option 'LUA_NANTRICK' needs declaration for 'TValuefields'
+
#endif
+
+/* correspondence with standard representation */
+#undef val_
+#define val_(o) v_(o)
+#undef num_
+#define num_(o) d_(o)
+
+
#undef numfield
#define numfield /* no such field; numbers are the entire struct */
/* basic check to distinguish numbers from non-numbers */
#undef ttisnumber
-#define ttisnumber(o) (((o)->u.i.tt_ & 0x7fffff00) != NNMARK)
+#define ttisnumber(o) ((tt_(o) & NNMASK) != NNMARK)
#define tag2tt(t) (NNMARK | (t))
-#undef val_
-#define val_(o) ((o)->u.i.v_)
-#undef num_
-#define num_(o) ((o)->u.d_)
-
#undef rttype
-#define rttype(o) (ttisnumber(o) ? LUA_TNUMBER : (o)->u.i.tt_ & 0xff)
+#define rttype(o) (ttisnumber(o) ? LUA_TNUMBER : tt_(o) & 0xff)
#undef settt_
-#define settt_(o,t) ((o)->u.i.tt_=tag2tt(t))
+#define settt_(o,t) (tt_(o) = tag2tt(t))
#undef setnvalue
#define setnvalue(obj,x) \
@@ -324,11 +348,11 @@ typedef struct lua_TValue TValue;
*/
#undef checktag
-#define checktag(o,t) ((o)->u.i.tt_ == tag2tt(t))
+#define checktag(o,t) (tt_(o) == tag2tt(t))
#undef ttisequal
#define ttisequal(o1,o2) \
- (ttisnumber(o1) ? ttisnumber(o2) : ((o1)->u.i.tt_ == (o2)->u.i.tt_))
+ (ttisnumber(o1) ? ttisnumber(o2) : (tt_(o1) == tt_(o2)))
@@ -435,11 +459,11 @@ typedef struct Proto {
TValue *k; /* constants used by the function */
Instruction *code;
struct Proto **p; /* functions defined inside the function */
- int *lineinfo; /* map from opcodes to source lines */
- LocVar *locvars; /* information about local variables */
+ int *lineinfo; /* map from opcodes to source lines (debug information) */
+ LocVar *locvars; /* information about local variables (debug information) */
Upvaldesc *upvalues; /* upvalue information */
union Closure *cache; /* last created closure with this prototype */
- TString *source;
+ TString *source; /* used for debug information */
int sizeupvalues; /* size of 'upvalues' */
int sizek; /* size of `k' */
int sizecode;
diff --git a/src/lopcodes.c b/src/lopcodes.c
index 2e34676..2e34676 100755..100644
--- a/src/lopcodes.c
+++ b/src/lopcodes.c
diff --git a/src/lopcodes.h b/src/lopcodes.h
index 01c69bd..07d2b3f 100755..100644
--- a/src/lopcodes.h
+++ b/src/lopcodes.h
@@ -1,5 +1,5 @@
/*
-** $Id: lopcodes.h,v 1.141 2011/04/19 16:22:13 roberto Exp $
+** $Id: lopcodes.h,v 1.142 2011/07/15 12:50:29 roberto Exp $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -196,7 +196,7 @@ OP_LEN,/* A B R(A) := length of R(B) */
OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
-OP_JMP,/* A sBx pc+=sBx; if (A) close all upvalues >= R(A) + 1 */
+OP_JMP,/* A sBx pc+=sBx; if (A) close all upvalues >= R(A) + 1 */
OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
diff --git a/src/loslib.c b/src/loslib.c
index 585ba78..881667d 100755..100644
--- a/src/loslib.c
+++ b/src/loslib.c
@@ -1,5 +1,5 @@
/*
-** $Id: loslib.c,v 1.35 2011/06/20 16:50:59 roberto Exp $
+** $Id: loslib.c,v 1.38 2011/11/30 12:35:05 roberto Exp $
** Standard Operating System library
** See Copyright Notice in lua.h
*/
@@ -58,6 +58,23 @@
#endif
+/*
+** By default, Lua uses gmtime/localtime, except when POSIX is available,
+** where it uses gmtime_r/localtime_r
+*/
+#if defined(LUA_USE_GMTIME_R)
+
+#define l_gmtime(t,r) gmtime_r(t,r)
+#define l_localtime(t,r) localtime_r(t,r)
+
+#elif !defined(l_gmtime)
+
+#define l_gmtime(t,r) ((void)r, gmtime(t))
+#define l_localtime(t,r) ((void)r, localtime(t))
+
+#endif
+
+
static int os_execute (lua_State *L) {
const char *cmd = luaL_optstring(L, 1, NULL);
@@ -177,13 +194,13 @@ static const char *checkoption (lua_State *L, const char *conv, char *buff) {
static int os_date (lua_State *L) {
const char *s = luaL_optstring(L, 1, "%c");
time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
- struct tm *stm;
+ struct tm tmr, *stm;
if (*s == '!') { /* UTC? */
- stm = gmtime(&t);
+ stm = l_gmtime(&t, &tmr);
s++; /* skip `!' */
}
else
- stm = localtime(&t);
+ stm = l_localtime(&t, &tmr);
if (stm == NULL) /* invalid date? */
lua_pushnil(L);
else if (strcmp(s, "*t") == 0) {
@@ -274,7 +291,8 @@ static int os_exit (lua_State *L) {
status = luaL_optint(L, 1, EXIT_SUCCESS);
if (lua_toboolean(L, 2))
lua_close(L);
- exit(status);
+ if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */
+ return 0;
}
diff --git a/src/lparser.c b/src/lparser.c
index d9c4173..4d68936 100755..100644
--- a/src/lparser.c
+++ b/src/lparser.c
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.c,v 2.113 2011/07/02 15:58:14 roberto Exp $
+** $Id: lparser.c,v 2.124 2011/12/02 13:23:56 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -41,8 +41,8 @@
*/
typedef struct BlockCnt {
struct BlockCnt *previous; /* chain */
- int firstlabel; /* index of first label in this block */
- int firstgoto; /* index of first pending goto in this block */
+ short firstlabel; /* index of first label in this block */
+ short firstgoto; /* index of first pending goto in this block */
lu_byte nactvar; /* # active locals outside the block */
lu_byte upval; /* true if some variable in the block is an upvalue */
lu_byte isloop; /* true if `block' is a loop */
@@ -68,26 +68,27 @@ static void anchor_token (LexState *ls) {
/* semantic error */
-static void semerror (LexState *ls, const char *msg) {
+static l_noret semerror (LexState *ls, const char *msg) {
ls->t.token = 0; /* remove 'near to' from final message */
luaX_syntaxerror(ls, msg);
}
-static void error_expected (LexState *ls, int token) {
+static l_noret error_expected (LexState *ls, int token) {
luaX_syntaxerror(ls,
luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token)));
}
-static void errorlimit (FuncState *fs, int limit, const char *what) {
+static l_noret errorlimit (FuncState *fs, int limit, const char *what) {
+ lua_State *L = fs->ls->L;
const char *msg;
int line = fs->f->linedefined;
const char *where = (line == 0)
? "main function"
- : luaO_pushfstring(fs->L, "function at line %d", line);
- msg = luaO_pushfstring(fs->L, "too many %s (limit is %d) in %s",
- what, limit, where);
+ : luaO_pushfstring(L, "function at line %d", line);
+ msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s",
+ what, limit, where);
luaX_syntaxerror(fs->ls, msg);
}
@@ -182,7 +183,7 @@ static void new_localvar (LexState *ls, TString *name) {
MAXVARS, "local variables");
luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1,
dyd->actvar.size, Vardesc, MAX_INT, "local variables");
- dyd->actvar.arr[dyd->actvar.n++].idx = cast(unsigned short, reg);
+ dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg);
}
@@ -231,13 +232,13 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
Proto *f = fs->f;
int oldsize = f->sizeupvalues;
checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");
- luaM_growvector(fs->L, f->upvalues, fs->nups, f->sizeupvalues,
+ luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues,
Upvaldesc, MAXUPVAL, "upvalues");
while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL;
f->upvalues[fs->nups].instack = (v->k == VLOCAL);
f->upvalues[fs->nups].idx = cast_byte(v->u.info);
f->upvalues[fs->nups].name = name;
- luaC_objbarrier(fs->L, f, name);
+ luaC_objbarrier(fs->ls->L, f, name);
return fs->nups++;
}
@@ -327,13 +328,13 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
static void enterlevel (LexState *ls) {
- global_State *g = G(ls->L);
- ++g->nCcalls;
- checklimit(ls->fs, g->nCcalls, LUAI_MAXCCALLS, "syntax levels");
+ lua_State *L = ls->L;
+ ++L->nCcalls;
+ checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "C levels");
}
-#define leavelevel(ls) (G((ls)->L)->nCcalls--)
+#define leavelevel(ls) ((ls)->L->nCcalls--)
static void closegoto (LexState *ls, int g, Labeldesc *label) {
@@ -343,9 +344,10 @@ static void closegoto (LexState *ls, int g, Labeldesc *label) {
Labeldesc *gt = &gl->arr[g];
lua_assert(eqstr(gt->name, label->name));
if (gt->nactvar < label->nactvar) {
+ TString *vname = getlocvar(fs, gt->nactvar)->varname;
const char *msg = luaO_pushfstring(ls->L,
"<goto %s> at line %d jumps into the scope of local " LUA_QS,
- getstr(gt->name), gt->line, getstr(getlocvar(fs, gt->nactvar)->varname));
+ getstr(gt->name), gt->line, getstr(vname));
semerror(ls, msg);
}
luaK_patchlist(fs, gt->pc, label->pc);
@@ -382,7 +384,8 @@ static int findlabel (LexState *ls, int g) {
static int newlabelentry (LexState *ls, Labellist *l, TString *name,
int line, int pc) {
int n = l->n;
- luaM_growvector(ls->L, l->arr, n, l->size, Labeldesc, MAX_INT, "labels");
+ luaM_growvector(ls->L, l->arr, n, l->size,
+ Labeldesc, SHRT_MAX, "labels/gotos");
l->arr[n].name = name;
l->arr[n].line = line;
l->arr[n].nactvar = ls->fs->nactvar;
@@ -418,7 +421,7 @@ static void movegotosout (FuncState *fs, BlockCnt *bl) {
int i = bl->firstgoto;
Labellist *gl = &fs->ls->dyd->gt;
/* correct pending gotos to current block and try to close it
- with visible labels */
+ with visible labels */
while (i < gl->n) {
Labeldesc *gt = &gl->arr[i];
if (gt->nactvar > bl->nactvar) {
@@ -457,7 +460,7 @@ static void breaklabel (LexState *ls) {
** generates an error for an undefined 'goto'; choose appropriate
** message when label name is a reserved word (which can only be 'break')
*/
-static void undefgoto (LexState *ls, Labeldesc *gt) {
+static l_noret undefgoto (LexState *ls, Labeldesc *gt) {
const char *msg = (gt->name->tsv.reserved > 0)
? "<%s> at line %d not inside a loop"
: "no visible label " LUA_QS " for <goto> at line %d";
@@ -514,7 +517,6 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
Proto *f;
fs->prev = ls->fs; /* linked list of funcstates */
fs->ls = ls;
- fs->L = L;
ls->fs = fs;
fs->pc = 0;
fs->lasttarget = 0;
@@ -850,7 +852,6 @@ static void funcargs (LexState *ls, expdesc *f, int line) {
}
default: {
luaX_syntaxerror(ls, "function arguments expected");
- return;
}
}
lua_assert(f->k == VNONRELOC);
@@ -895,7 +896,6 @@ static void prefixexp (LexState *ls, expdesc *v) {
}
default: {
luaX_syntaxerror(ls, "unexpected symbol");
- return;
}
}
}
@@ -1039,7 +1039,7 @@ static const struct {
** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
** where `binop' is any binary operator with a priority higher than `limit'
*/
-static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) {
+static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
BinOpr op;
UnOpr uop;
enterlevel(ls);
@@ -1105,31 +1105,34 @@ struct LHS_assign {
/*
-** check whether, in an assignment to a local variable, the local variable
-** is needed in a previous assignment (to a table). If so, save original
-** local value in a safe place and use this safe copy in the previous
-** assignment.
+** check whether, in an assignment to an upvalue/local variable, the
+** upvalue/local variable is begin used in a previous assignment to a
+** table. If so, save original upvalue/local value in a safe place and
+** use this safe copy in the previous assignment.
*/
static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
FuncState *fs = ls->fs;
int extra = fs->freereg; /* eventual position to save local variable */
int conflict = 0;
- for (; lh; lh = lh->prev) {
- /* conflict in table 't'? */
- if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) {
- conflict = 1;
- lh->v.u.ind.vt = VLOCAL;
- lh->v.u.ind.t = extra; /* previous assignment will use safe copy */
- }
- /* conflict in index 'idx'? */
- if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) {
- conflict = 1;
- lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */
+ for (; lh; lh = lh->prev) { /* check all previous assignments */
+ if (lh->v.k == VINDEXED) { /* assigning to a table? */
+ /* table is the upvalue/local being assigned now? */
+ if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) {
+ conflict = 1;
+ lh->v.u.ind.vt = VLOCAL;
+ lh->v.u.ind.t = extra; /* previous assignment will use safe copy */
+ }
+ /* index is the local being assigned? (index cannot be upvalue) */
+ if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) {
+ conflict = 1;
+ lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */
+ }
}
}
if (conflict) {
+ /* copy upvalue/local value to a temporary (in position 'extra') */
OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
- luaK_codeABC(fs, op, fs->freereg, v->u.info, 0); /* make copy */
+ luaK_codeABC(fs, op, extra, v->u.info, 0);
luaK_reserveregs(fs, 1);
}
}
@@ -1144,8 +1147,8 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
primaryexp(ls, &nv.v);
if (nv.v.k != VINDEXED)
check_conflict(ls, lh, &nv.v);
- checklimit(ls->fs, nvars, LUAI_MAXCCALLS - G(ls->L)->nCcalls,
- "variable names");
+ checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS,
+ "C levels");
assignment(ls, &nv, nvars+1);
}
else { /* assignment -> `=' explist */
@@ -1178,10 +1181,18 @@ static int cond (LexState *ls) {
}
-static void gotostat (LexState *ls, TString *label, int line) {
- /* create new entry for this goto */
- int g = newlabelentry(ls, &ls->dyd->gt, label, line, luaK_jump(ls->fs));
- findlabel(ls, g);
+static void gotostat (LexState *ls, int pc) {
+ int line = ls->linenumber;
+ TString *label;
+ int g;
+ if (testnext(ls, TK_GOTO))
+ label = str_checkname(ls);
+ else {
+ luaX_next(ls); /* skip break */
+ label = luaS_new(ls->L, "break");
+ }
+ g = newlabelentry(ls, &ls->dyd->gt, label, line, pc);
+ findlabel(ls, g); /* close it if label already defined */
}
@@ -1190,7 +1201,7 @@ static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) {
int i;
for (i = fs->bl->firstlabel; i < ll->n; i++) {
if (eqstr(label, ll->arr[i].name)) {
- const char *msg = luaO_pushfstring(fs->ls->L,
+ const char *msg = luaO_pushfstring(fs->ls->L,
"label " LUA_QS " already defined on line %d",
getstr(label), ll->arr[i].line);
semerror(fs->ls, msg);
@@ -1360,38 +1371,51 @@ static void forstat (LexState *ls, int line) {
}
-static int test_then_block (LexState *ls) {
+static void test_then_block (LexState *ls, int *escapelist) {
/* test_then_block -> [IF | ELSEIF] cond THEN block */
- int condexit;
+ BlockCnt bl;
+ FuncState *fs = ls->fs;
+ expdesc v;
+ int jf; /* instruction to skip 'then' code (if condition is false) */
luaX_next(ls); /* skip IF or ELSEIF */
- condexit = cond(ls);
+ expr(ls, &v); /* read condition */
checknext(ls, TK_THEN);
- block(ls); /* `then' part */
- return condexit;
+ if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) {
+ luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */
+ enterblock(fs, &bl, 0); /* must enter block before 'goto' */
+ gotostat(ls, v.t); /* handle goto/break */
+ if (block_follow(ls, 0)) { /* 'goto' is the entire block? */
+ leaveblock(fs);
+ return; /* and that is it */
+ }
+ else /* must skip over 'then' part if condition is false */
+ jf = luaK_jump(fs);
+ }
+ else { /* regular case (not goto/break) */
+ luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */
+ enterblock(fs, &bl, 0);
+ jf = v.f;
+ }
+ statlist(ls); /* `then' part */
+ leaveblock(fs);
+ if (ls->t.token == TK_ELSE ||
+ ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */
+ luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */
+ luaK_patchtohere(fs, jf);
}
static void ifstat (LexState *ls, int line) {
/* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
FuncState *fs = ls->fs;
- int flist;
- int escapelist = NO_JUMP;
- flist = test_then_block(ls); /* IF cond THEN block */
- while (ls->t.token == TK_ELSEIF) {
- luaK_concat(fs, &escapelist, luaK_jump(fs));
- luaK_patchtohere(fs, flist);
- flist = test_then_block(ls); /* ELSEIF cond THEN block */
- }
- if (ls->t.token == TK_ELSE) {
- luaK_concat(fs, &escapelist, luaK_jump(fs));
- luaK_patchtohere(fs, flist);
- luaX_next(ls); /* skip ELSE (after patch, for correct line info) */
+ int escapelist = NO_JUMP; /* exit list for finished parts */
+ test_then_block(ls, &escapelist); /* IF cond THEN block */
+ while (ls->t.token == TK_ELSEIF)
+ test_then_block(ls, &escapelist); /* ELSEIF cond THEN block */
+ if (testnext(ls, TK_ELSE))
block(ls); /* `else' part */
- }
- else
- luaK_concat(fs, &escapelist, flist);
- luaK_patchtohere(fs, escapelist);
check_match(ls, TK_END, TK_IF, line);
+ luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */
}
@@ -1551,15 +1575,9 @@ static void statement (LexState *ls) {
retstat(ls);
break;
}
- case TK_BREAK: { /* stat -> breakstat */
- luaX_next(ls); /* skip BREAK */
- /* code it as "goto 'break'" */
- gotostat(ls, luaS_new(ls->L, "break"), line);
- break;
- }
+ case TK_BREAK: /* stat -> breakstat */
case TK_GOTO: { /* stat -> 'goto' NAME */
- luaX_next(ls); /* skip GOTO */
- gotostat(ls, str_checkname(ls), line);
+ gotostat(ls, luaK_jump(ls->fs));
break;
}
default: { /* stat -> func | assignment */
@@ -1595,8 +1613,8 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
close_func(&lexstate);
L->top--; /* pop name */
lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
- return funcstate.f;
/* all scopes should be correctly finished */
lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);
+ return funcstate.f;
}
diff --git a/src/lparser.h b/src/lparser.h
index 4e7e06f..caabf46 100755..100644
--- a/src/lparser.h
+++ b/src/lparser.h
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.h,v 1.68 2011/02/23 13:13:10 roberto Exp $
+** $Id: lparser.h,v 1.69 2011/07/27 18:09:01 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -55,7 +55,7 @@ typedef struct expdesc {
/* description of active local variable */
typedef struct Vardesc {
- unsigned short idx; /* variable index in stack */
+ short idx; /* variable index in stack */
} Vardesc;
@@ -98,18 +98,17 @@ typedef struct FuncState {
Table *h; /* table to find (and reuse) elements in `k' */
struct FuncState *prev; /* enclosing function */
struct LexState *ls; /* lexical state */
- struct lua_State *L; /* copy of the Lua state */
struct BlockCnt *bl; /* chain of current blocks */
int pc; /* next position to code (equivalent to `ncode') */
- int lasttarget; /* `pc' of last `jump target' */
+ int lasttarget; /* 'label' of last 'jump label' */
int jpc; /* list of pending jumps to `pc' */
- int freereg; /* first free register */
int nk; /* number of elements in `k' */
int np; /* number of elements in `p' */
- int firstlocal; /* index of first local var of this function */
- short nlocvars; /* number of elements in `locvars' */
+ int firstlocal; /* index of first local var (in Dyndata array) */
+ short nlocvars; /* number of elements in 'f->locvars' */
lu_byte nactvar; /* number of active local variables */
lu_byte nups; /* number of upvalues */
+ lu_byte freereg; /* first free register */
} FuncState;
diff --git a/src/lstate.c b/src/lstate.c
index 45dac3c..6e2801c 100755..100644
--- a/src/lstate.c
+++ b/src/lstate.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.c,v 2.89 2010/12/20 19:40:07 roberto Exp $
+** $Id: lstate.c,v 2.92 2011/10/03 17:54:25 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
@@ -136,10 +136,10 @@ static void init_registry (lua_State *L, global_State *g) {
luaH_resize(L, registry, LUA_RIDX_LAST, 0);
/* registry[LUA_RIDX_MAINTHREAD] = L */
setthvalue(L, &mt, L);
- setobj2t(L, luaH_setint(L, registry, LUA_RIDX_MAINTHREAD), &mt);
+ luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt);
/* registry[LUA_RIDX_GLOBALS] = table of globals */
sethvalue(L, &mt, luaH_new(L));
- setobj2t(L, luaH_setint(L, registry, LUA_RIDX_GLOBALS), &mt);
+ luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt);
}
@@ -171,6 +171,7 @@ static void preinit_state (lua_State *L, global_State *g) {
L->ci = NULL;
L->stacksize = 0;
L->errorJmp = NULL;
+ L->nCcalls = 0;
L->hook = NULL;
L->hookmask = 0;
L->basehookcount = 0;
@@ -191,7 +192,7 @@ static void close_state (lua_State *L) {
luaZ_freebuffer(L, &g->buff);
freestack(L);
lua_assert(gettotalbytes(g) == sizeof(LG));
- (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0);
+ (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */
}
@@ -237,7 +238,6 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
L->marked = luaC_white(g);
g->gckind = KGC_NORMAL;
- g->nCcalls = 0;
preinit_state(L, g);
g->frealloc = f;
g->ud = ud;
@@ -279,9 +279,6 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
LUA_API void lua_close (lua_State *L) {
L = G(L)->mainthread; /* only the main thread can be closed */
lua_lock(L);
- luaF_close(L, L->stack); /* close all upvalues for this thread */
- luaC_separateudata(L, 1); /* separate all udata with GC metamethods */
- lua_assert(L->next == NULL);
luai_userstateclose(L);
close_state(L);
}
diff --git a/src/lstate.h b/src/lstate.h
index 9d21e7e..4743d74 100755..100644
--- a/src/lstate.h
+++ b/src/lstate.h
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.h,v 2.72 2011/06/02 19:31:40 roberto Exp $
+** $Id: lstate.h,v 2.74 2011/09/30 12:45:07 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
@@ -47,8 +47,6 @@ struct lua_longjmp; /* defined in ldo.c */
#define EXTRA_STACK 5
-#define BASIC_CI_SIZE 8
-
#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
@@ -118,7 +116,6 @@ typedef struct global_State {
lu_mem lastmajormem; /* memory in use after last major collection */
stringtable strt; /* hash table for strings */
TValue l_registry;
- unsigned short nCcalls; /* number of nested C calls */
lu_byte currentwhite;
lu_byte gcstate; /* state of garbage collector */
lu_byte gckind; /* kind of GC running */
@@ -161,6 +158,7 @@ struct lua_State {
StkId stack; /* stack base */
int stacksize;
unsigned short nny; /* number of non-yieldable calls in stack */
+ unsigned short nCcalls; /* number of nested C calls */
lu_byte hookmask;
lu_byte allowhook;
int basehookcount;
diff --git a/src/lstring.c b/src/lstring.c
index adec415..adec415 100755..100644
--- a/src/lstring.c
+++ b/src/lstring.c
diff --git a/src/lstring.h b/src/lstring.h
index d708a1b..d708a1b 100755..100644
--- a/src/lstring.h
+++ b/src/lstring.h
diff --git a/src/lstrlib.c b/src/lstrlib.c
index 5e200f1..f5d61fd 100755..100644
--- a/src/lstrlib.c
+++ b/src/lstrlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstrlib.c,v 1.170 2011/06/28 17:13:52 roberto Exp $
+** $Id: lstrlib.c,v 1.173 2011/11/30 18:24:56 roberto Exp $
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/
@@ -138,7 +138,7 @@ static int str_byte (lua_State *L) {
if (pose > l) pose = l;
if (posi > pose) return 0; /* empty interval; return no values */
n = (int)(pose - posi + 1);
- if (posi + n <= pose) /* overflow? */
+ if (posi + n <= pose) /* (size_t -> int) overflow? */
return luaL_error(L, "string slice too long");
luaL_checkstack(L, n, "string slice too long");
for (i=0; i<n; i++)
@@ -154,7 +154,7 @@ static int str_char (lua_State *L) {
char *p = luaL_buffinitsize(L, &b, n);
for (i=1; i<=n; i++) {
int c = luaL_checkint(L, i);
- luaL_argcheck(L, uchar(c) == c, i, "invalid value");
+ luaL_argcheck(L, uchar(c) == c, i, "value out of range");
p[i - 1] = uchar(c);
}
luaL_pushresultsize(&b, n);
@@ -756,6 +756,9 @@ static int str_gsub (lua_State *L) {
#endif
#endif /* } */
+#define MAX_UINTFRM ((lua_Number)(~(unsigned LUA_INTFRM_T)0))
+#define MAX_INTFRM ((lua_Number)((~(unsigned LUA_INTFRM_T)0)/2))
+#define MIN_INTFRM (-(lua_Number)((~(unsigned LUA_INTFRM_T)0)/2) - 1)
/*
** LUA_FLTFRMLEN is the length modifier for float conversions in
@@ -865,13 +868,20 @@ static int str_format (lua_State *L) {
nb = sprintf(buff, form, luaL_checkint(L, arg));
break;
}
- case 'd': case 'i':
+ case 'd': case 'i': {
+ lua_Number n = luaL_checknumber(L, arg);
+ luaL_argcheck(L, (MIN_INTFRM - 1) < n && n < (MAX_INTFRM + 1), arg,
+ "not a number in proper range");
+ addlenmod(form, LUA_INTFRMLEN);
+ nb = sprintf(buff, form, (LUA_INTFRM_T)n);
+ break;
+ }
case 'o': case 'u': case 'x': case 'X': {
lua_Number n = luaL_checknumber(L, arg);
- LUA_INTFRM_T r = (n < 0) ? (LUA_INTFRM_T)n :
- (LUA_INTFRM_T)(unsigned LUA_INTFRM_T)n;
+ luaL_argcheck(L, 0 <= n && n < (MAX_UINTFRM + 1), arg,
+ "not a non-negative number in proper range");
addlenmod(form, LUA_INTFRMLEN);
- nb = sprintf(buff, form, r);
+ nb = sprintf(buff, form, (unsigned LUA_INTFRM_T)n);
break;
}
case 'e': case 'E': case 'f':
diff --git a/src/ltable.c b/src/ltable.c
index a937959..9581add 100755..100644
--- a/src/ltable.c
+++ b/src/ltable.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.c,v 2.60 2011/06/16 14:14:31 roberto Exp $
+** $Id: ltable.c,v 2.67 2011/11/30 12:41:45 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -64,13 +64,6 @@
#define hashpointer(t,p) hashmod(t, IntPoint(p))
-/*
-** number of ints inside a lua_Number
-*/
-#define numints cast_int(sizeof(lua_Number)/sizeof(int))
-
-
-
#define dummynode (&dummynode_)
#define isdummy(n) ((n) == dummynode)
@@ -148,19 +141,19 @@ static int findindex (lua_State *L, Table *t, StkId key) {
return i-1; /* yes; that's the index (corrected to C) */
else {
Node *n = mainposition(t, key);
- do { /* check whether `key' is somewhere in the chain */
+ for (;;) { /* check whether `key' is somewhere in the chain */
/* key may be dead already, but it is ok to use it in `next' */
if (luaV_rawequalobj(gkey(n), key) ||
(ttisdeadkey(gkey(n)) && iscollectable(key) &&
- gcvalue(gkey(n)) == gcvalue(key))) {
+ deadvalue(gkey(n)) == gcvalue(key))) {
i = cast_int(n - gnode(t, 0)); /* key index in hash table */
/* hash elements are numbered after array ones */
return i + t->sizearray;
}
else n = gnext(n);
- } while (n);
- luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */
- return 0; /* to avoid warnings */
+ if (n == NULL)
+ luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */
+ }
}
}
@@ -314,7 +307,7 @@ void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) {
/* re-insert elements from vanishing slice */
for (i=nasize; i<oldasize; i++) {
if (!ttisnil(&t->array[i]))
- setobjt2t(L, luaH_setint(L, t, i+1), &t->array[i]);
+ luaH_setint(L, t, i + 1, &t->array[i]);
}
/* shrink array */
luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
@@ -322,11 +315,14 @@ void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) {
/* re-insert elements from hash part */
for (i = twoto(oldhsize) - 1; i >= 0; i--) {
Node *old = nold+i;
- if (!ttisnil(gval(old)))
+ if (!ttisnil(gval(old))) {
+ /* doesn't need barrier/invalidate cache, as entry was
+ already present in the table */
setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old));
+ }
}
if (!isdummy(nold))
- luaM_freearray(L, nold, twoto(oldhsize)); /* free old array */
+ luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old array */
}
@@ -374,7 +370,7 @@ Table *luaH_new (lua_State *L) {
void luaH_free (lua_State *L, Table *t) {
if (!isdummy(t->node))
- luaM_freearray(L, t->node, sizenode(t));
+ luaM_freearray(L, t->node, cast(size_t, sizenode(t)));
luaM_freearray(L, t->array, t->sizearray);
luaM_free(L, t);
}
@@ -398,14 +394,19 @@ static Node *getfreepos (Table *t) {
** put new key in its main position; otherwise (colliding node is in its main
** position), new key goes to an empty position.
*/
-static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
- Node *mp = mainposition(t, key);
+TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
+ Node *mp;
+ if (ttisnil(key)) luaG_runerror(L, "table index is nil");
+ else if (ttisnumber(key) && luai_numisnan(L, nvalue(key)))
+ luaG_runerror(L, "table index is NaN");
+ mp = mainposition(t, key);
if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */
Node *othern;
Node *n = getfreepos(t); /* get a free place */
if (n == NULL) { /* cannot find a free place? */
rehash(L, t, key); /* grow table */
- return luaH_set(L, t, key); /* re-insert key into grown table */
+ /* whatever called 'newkey' take care of TM cache and GC barrier */
+ return luaH_set(L, t, key); /* insert key into grown table */
}
lua_assert(!isdummy(n));
othern = mainposition(t, gkey(mp));
@@ -493,41 +494,29 @@ const TValue *luaH_get (Table *t, const TValue *key) {
}
+/*
+** beware: when using this function you probably need to check a GC
+** barrier and invalidate the TM cache.
+*/
TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
const TValue *p = luaH_get(t, key);
- t->flags = 0;
if (p != luaO_nilobject)
return cast(TValue *, p);
- else {
- if (ttisnil(key)) luaG_runerror(L, "table index is nil");
- else if (ttisnumber(key) && luai_numisnan(L, nvalue(key)))
- luaG_runerror(L, "table index is NaN");
- return newkey(L, t, key);
- }
+ else return luaH_newkey(L, t, key);
}
-TValue *luaH_setint (lua_State *L, Table *t, int key) {
+void luaH_setint (lua_State *L, Table *t, int key, TValue *value) {
const TValue *p = luaH_getint(t, key);
+ TValue *cell;
if (p != luaO_nilobject)
- return cast(TValue *, p);
+ cell = cast(TValue *, p);
else {
TValue k;
setnvalue(&k, cast_num(key));
- return newkey(L, t, &k);
- }
-}
-
-
-TValue *luaH_setstr (lua_State *L, Table *t, TString *key) {
- const TValue *p = luaH_getstr(t, key);
- if (p != luaO_nilobject)
- return cast(TValue *, p);
- else {
- TValue k;
- setsvalue(L, &k, key);
- return newkey(L, t, &k);
+ cell = luaH_newkey(L, t, &k);
}
+ setobj2t(L, cell, value);
}
diff --git a/src/ltable.h b/src/ltable.h
index c14b028..2f6f5c2 100755..100644
--- a/src/ltable.h
+++ b/src/ltable.h
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.h,v 2.14 2010/06/25 12:18:10 roberto Exp $
+** $Id: ltable.h,v 2.16 2011/08/17 20:26:47 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -15,12 +15,14 @@
#define gval(n) (&(n)->i_val)
#define gnext(n) ((n)->i_key.nk.next)
+#define invalidateTMcache(t) ((t)->flags = 0)
+
LUAI_FUNC const TValue *luaH_getint (Table *t, int key);
-LUAI_FUNC TValue *luaH_setint (lua_State *L, Table *t, int key);
+LUAI_FUNC void luaH_setint (lua_State *L, Table *t, int key, TValue *value);
LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
-LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
+LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key);
LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
LUAI_FUNC Table *luaH_new (lua_State *L);
LUAI_FUNC void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize);
diff --git a/src/ltablib.c b/src/ltablib.c
index 06353c7..a52add0 100755..100644
--- a/src/ltablib.c
+++ b/src/ltablib.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltablib.c,v 1.61 2011/07/05 12:49:35 roberto Exp $
+** $Id: ltablib.c,v 1.63 2011/11/28 17:26:30 roberto Exp $
** Library for Table Manipulation
** See Copyright Notice in lua.h
*/
@@ -86,7 +86,7 @@ static void addfield (lua_State *L, luaL_Buffer *b, int i) {
if (!lua_isstring(L, -1))
luaL_error(L, "invalid value (%s) at index %d in table for "
LUA_QL("concat"), luaL_typename(L, -1), i);
- luaL_addvalue(b);
+ luaL_addvalue(b);
}
@@ -129,8 +129,7 @@ static int pack (lua_State *L) {
for (i = n; i >= 2; i--) /* assign other elements */
lua_rawseti(L, 1, i);
}
- lua_pushinteger(L, n);
- return 2; /* return table and number of elements */
+ return 1; /* return table */
}
diff --git a/src/ltm.c b/src/ltm.c
index e70006d..e70006d 100755..100644
--- a/src/ltm.c
+++ b/src/ltm.c
diff --git a/src/ltm.h b/src/ltm.h
index 89bdc19..89bdc19 100755..100644
--- a/src/ltm.h
+++ b/src/ltm.h
diff --git a/src/lua.c b/src/lua.c
index 8b317c6..e20ab86 100755..100644
--- a/src/lua.c
+++ b/src/lua.c
@@ -1,5 +1,5 @@
/*
-** $Id: lua.c,v 1.200 2011/06/16 14:30:58 roberto Exp $
+** $Id: lua.c,v 1.203 2011/12/12 16:34:03 roberto Exp $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
@@ -118,6 +118,7 @@ static void print_usage (const char *badoption) {
" -i enter interactive mode after executing " LUA_QL("script") "\n"
" -l name require library " LUA_QL("name") "\n"
" -v show version information\n"
+ " -E ignore environment variables\n"
" -- stop handling options\n"
" - stop handling options and execute stdin\n"
,
@@ -348,7 +349,16 @@ static int handle_script (lua_State *L, char **argv, int n) {
#define noextrachars(x) {if ((x)[2] != '\0') return -1;}
-static int collectargs (char **argv, int *pi, int *pv, int *pe) {
+/* indices of various argument indicators in array args */
+#define has_i 0 /* -i */
+#define has_v 1 /* -v */
+#define has_e 2 /* -e */
+#define has_E 3 /* -E */
+
+#define num_has 4 /* number of 'has_*' */
+
+
+static int collectargs (char **argv, int *args) {
int i;
for (i = 1; argv[i] != NULL; i++) {
if (argv[i][0] != '-') /* not an option? */
@@ -359,15 +369,18 @@ static int collectargs (char **argv, int *pi, int *pv, int *pe) {
return (argv[i+1] != NULL ? i+1 : 0);
case '\0':
return i;
+ case 'E':
+ args[has_E] = 1;
+ break;
case 'i':
noextrachars(argv[i]);
- *pi = 1; /* go through */
+ args[has_i] = 1; /* go through */
case 'v':
noextrachars(argv[i]);
- *pv = 1;
+ args[has_v] = 1;
break;
case 'e':
- *pe = 1; /* go through */
+ args[has_e] = 1; /* go through */
case 'l': /* both options need an argument */
if (argv[i][2] == '\0') { /* no concatenated argument? */
i++; /* try next 'argv' */
@@ -430,28 +443,33 @@ static int pmain (lua_State *L) {
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;
+ int args[num_has];
+ args[has_i] = args[has_v] = args[has_e] = args[has_E] = 0;
if (argv[0] && argv[0][0]) progname = argv[0];
- script = collectargs(argv, &has_i, &has_v, &has_e);
+ script = collectargs(argv, args);
if (script < 0) { /* invalid arg? */
print_usage(argv[-script]);
return 0;
}
- if (has_v) print_version();
+ if (args[has_v]) print_version();
+ if (args[has_E]) { /* option '-E'? */
+ lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */
+ lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
+ }
/* open standard libraries */
luaL_checkversion(L);
lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */
luaL_openlibs(L); /* open libraries */
lua_gc(L, LUA_GCRESTART, 0);
- /* run LUA_INIT */
- if (handle_luainit(L) != LUA_OK) return 0;
+ if (!args[has_E] && handle_luainit(L) != LUA_OK)
+ return 0; /* error running LUA_INIT */
/* execute arguments -e and -l */
if (!runargs(L, argv, (script > 0) ? script : argc)) return 0;
/* execute main script (if there is one) */
if (script && handle_script(L, argv, script) != LUA_OK) return 0;
- if (has_i) /* -i option? */
+ if (args[has_i]) /* -i option? */
dotty(L);
- else if (script == 0 && !has_e && !has_v) { /* no arguments? */
+ else if (script == 0 && !args[has_e] && !args[has_v]) { /* no arguments? */
if (lua_stdin_is_tty()) {
print_version();
dotty(L);
diff --git a/src/lua.h b/src/lua.h
index 518d44c..1fafa45 100755..100644
--- a/src/lua.h
+++ b/src/lua.h
@@ -1,5 +1,5 @@
/*
-** $Id: lua.h,v 1.278 2011/07/02 16:00:15 roberto Exp $
+** $Id: lua.h,v 1.282 2011/11/29 15:55:08 roberto Exp $
** Lua - A Scripting Language
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
** See Copyright Notice at the end of this file
@@ -19,7 +19,7 @@
#define LUA_VERSION_MAJOR "5"
#define LUA_VERSION_MINOR "2"
#define LUA_VERSION_NUM 502
-#define LUA_VERSION_RELEASE "0" " (beta)"
+#define LUA_VERSION_RELEASE "0"
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
@@ -215,10 +215,12 @@ LUA_API int (lua_pushthread) (lua_State *L);
/*
** get functions (Lua -> stack)
*/
+LUA_API void (lua_getglobal) (lua_State *L, const char *var);
LUA_API void (lua_gettable) (lua_State *L, int idx);
LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k);
LUA_API void (lua_rawget) (lua_State *L, int idx);
LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n);
+LUA_API void (lua_rawgetp) (lua_State *L, int idx, const void *p);
LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
@@ -228,10 +230,12 @@ LUA_API void (lua_getuservalue) (lua_State *L, int idx);
/*
** set functions (stack -> Lua)
*/
+LUA_API void (lua_setglobal) (lua_State *L, const char *var);
LUA_API void (lua_settable) (lua_State *L, int idx);
LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
LUA_API void (lua_rawset) (lua_State *L, int idx);
LUA_API void (lua_rawseti) (lua_State *L, int idx, int n);
+LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p);
LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
LUA_API void (lua_setuservalue) (lua_State *L, int idx);
@@ -250,7 +254,8 @@ LUA_API int (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL)
LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
- const char *chunkname);
+ const char *chunkname,
+ const char *mode);
LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
@@ -261,7 +266,7 @@ LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
LUA_API int (lua_yieldk) (lua_State *L, int nresults, int ctx,
lua_CFunction k);
#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL)
-LUA_API int (lua_resume) (lua_State *L, int narg);
+LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg);
LUA_API int (lua_status) (lua_State *L);
/*
@@ -314,13 +319,6 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
#define lua_newtable(L) lua_createtable(L, 0, 0)
-#define lua_setglobal(L,s) \
- (lua_pushglobaltable(L), lua_pushvalue(L, -2), \
- lua_setfield(L, -2, (s)), lua_pop(L, 2))
-
-#define lua_getglobal(L,s) \
- (lua_pushglobaltable(L), lua_getfield(L, -1, (s)), lua_remove(L, -2))
-
#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)
diff --git a/src/lua.hpp b/src/lua.hpp
index ec417f5..ec417f5 100755..100644
--- a/src/lua.hpp
+++ b/src/lua.hpp
diff --git a/src/luac.c b/src/luac.c
index 62ff9cc..5081836 100755..100644
--- a/src/luac.c
+++ b/src/luac.c
@@ -1,5 +1,5 @@
/*
-** $Id: luac.c,v 1.67 2011/06/21 12:29:00 lhf Exp $
+** $Id: luac.c,v 1.69 2011/11/29 17:46:33 lhf Exp $
** Lua compiler (saves bytecodes to files; also list bytecodes)
** See Copyright Notice in lua.h
*/
@@ -53,7 +53,7 @@ static void usage(const char* message)
fprintf(stderr,
"usage: %s [options] [filenames]\n"
"Available options are:\n"
- " -l list\n"
+ " -l list (use -l -l for full listing)\n"
" -o name output to file " LUA_QL("name") " (default is \"%s\")\n"
" -p parse only\n"
" -s strip debug information\n"
@@ -141,7 +141,7 @@ static const Proto* combine(lua_State* L, int n)
{
Proto* f;
int i=n;
- if (lua_load(L,reader,&i,"=(" PROGNAME ")")!=LUA_OK) fatal(lua_tostring(L,-1));
+ if (lua_load(L,reader,&i,"=(" PROGNAME ")",NULL)!=LUA_OK) fatal(lua_tostring(L,-1));
f=toproto(L,-1);
for (i=0; i<n; i++)
{
@@ -203,7 +203,7 @@ int main(int argc, char* argv[])
}
/*
-** $Id: print.c,v 1.67 2011/05/06 13:37:15 lhf Exp $
+** $Id: print.c,v 1.68 2011/09/30 10:21:20 lhf Exp $
** print bytecodes
** See Copyright Notice in lua.h
*/
@@ -218,7 +218,6 @@ int main(int argc, char* argv[])
#include "lobject.h"
#include "lopcodes.h"
-#define Sizeof(x) ((int)sizeof(x))
#define VOID(p) ((const void*)(p))
static void PrintString(const TString* ts)
diff --git a/src/luaconf.h.in b/src/luaconf.h.in
index e4916f0..2bae837 100644
--- a/src/luaconf.h.in
+++ b/src/luaconf.h.in
@@ -1,5 +1,5 @@
/*
-** $Id: luaconf.h,v 1.161 2011/07/08 20:07:11 roberto Exp $
+** $Id: luaconf.h,v 1.170 2011/12/06 16:58:36 roberto Exp $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
@@ -28,7 +28,6 @@
#cmakedefine LUA_WIN
#if defined(LUA_WIN)
-#undef LUA_ANSI
#define LUA_DL_DLL
#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */
#endif
@@ -44,6 +43,7 @@
#cmakedefine LUA_USE_POPEN
#cmakedefine LUA_USE_ULONGJMP
+
/*
@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
@* Lua libraries.
@@ -52,8 +52,6 @@
** CHANGE them if your machine has a non-conventional directory
** hierarchy or if you want to install your libraries in
** non-conventional directories.
-** Any exclamation mark ('!') in the path is replaced by the
-** path of the directory of the executable file of the current process.
*/
#cmakedefine LUA_MODULE_SUFFIX "@LUA_MODULE_SUFFIX@"
#cmakedefine LUA_DIR "@LUA_DIR@"
@@ -121,13 +119,8 @@
** give a warning about it. To avoid these warnings, change to the
** default definition.
*/
-#if defined(luaall_c) /* { */
-#define LUAI_FUNC static
-#define LUAI_DDEC static
-#define LUAI_DDEF static
-
-#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
- defined(__ELF__)
+#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
+ defined(__ELF__) /* { */
#define LUAI_FUNC __attribute__((visibility("hidden"))) extern
#define LUAI_DDEC LUAI_FUNC
#define LUAI_DDEF /* empty */
@@ -158,10 +151,14 @@
/*
@@ luai_writestring/luai_writeline define how 'print' prints its results.
+** They are only used in libraries and the stand-alone program. (The #if
+** avoids including 'stdio.h' everywhere.)
*/
+#if defined(LUA_LIB) || defined(lua_c)
#include <stdio.h>
#define luai_writestring(s,l) fwrite((s), sizeof(char), (l), stdout)
#define luai_writeline() (luai_writestring("\n", 1), fflush(stdout))
+#endif
/*
@@ luai_writestringerror defines how to print error messages.
@@ -367,7 +364,7 @@
*/
/* the following operations need the math library */
-#if defined(lobject_c) || defined(lvm_c) || defined(luaall_c)
+#if defined(lobject_c) || defined(lvm_c)
#include <math.h>
#define luai_nummod(L,a,b) ((a) - floor((a)/(b))*(b))
#define luai_numpow(L,a,b) (pow(a,b))
@@ -408,7 +405,7 @@
/* On a Microsoft compiler on a Pentium, use assembler to avoid clashes
with a DirectX idiosyncrasy */
-#if defined(_MSC_VER) && defined(M_IX86) /* { */
+#if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86) /* { */
#define MS_ASMTRICK
@@ -441,12 +438,13 @@
/*
-@@ LUA_NANTRICKLE/LUA_NANTRICKBE controls the use of a trick to pack all
-** types into a single double value, using NaN values to represent
-** non-number values. The trick only works on 32-bit machines (ints and
-** pointers are 32-bit values) with numbers represented as IEEE 754-2008
-** doubles with conventional endianess (12345678 or 87654321), in CPUs
-** that do not produce signaling NaN values (all NaNs are quiet).
+@@ LUA_NANTRICK_LE/LUA_NANTRICK_BE controls the use of a trick to
+** pack all types into a single double value, using NaN values to
+** represent non-number values. The trick only works on 32-bit machines
+** (ints and pointers are 32-bit values) with numbers represented as
+** IEEE 754-2008 doubles with conventional endianess (12345678 or
+** 87654321), in CPUs that do not produce signaling NaN values (all NaNs
+** are quiet).
*/
#if defined(LUA_CORE) && \
defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */
@@ -455,7 +453,7 @@
#if defined(__i386__) || defined(__i386) || defined(__X86__) || \
defined(_M_IX86)
-#define LUA_NANTRICKLE
+#define LUA_NANTRICK_LE
#endif
diff --git a/src/luaconf.h.orig b/src/luaconf.h.orig
deleted file mode 100755
index 1135e50..0000000
--- a/src/luaconf.h.orig
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
-** $Id: luaconf.h,v 1.161 2011/07/08 20:07:11 roberto Exp $
-** Configuration file for Lua
-** See Copyright Notice in lua.h
-*/
-
-
-#ifndef lconfig_h
-#define lconfig_h
-
-#include <limits.h>
-#include <stddef.h>
-
-
-/*
-** ==================================================================
-** Search for "@@" to find all configurable definitions.
-** ===================================================================
-*/
-
-
-/*
-@@ LUA_ANSI controls the use of non-ansi features.
-** CHANGE it (define it) if you want Lua to avoid the use of any
-** non-ansi feature or library.
-*/
-#if !defined(LUA_ANSI) && defined(__STRICT_ANSI__)
-#define LUA_ANSI
-#endif
-
-
-#if !defined(LUA_ANSI) && defined(_WIN32)
-#define LUA_WIN
-#endif
-
-#if defined(LUA_WIN)
-#define LUA_DL_DLL
-#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */
-#endif
-
-
-
-#if defined(LUA_USE_LINUX)
-#define LUA_USE_POSIX
-#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
-#define LUA_USE_READLINE /* needs some extra libraries */
-#define LUA_USE_STRTODHEX /* assume 'strtod' handles hexa formats */
-#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */
-#define LUA_USE_LONGLONG /* assume support for long long */
-#endif
-
-#if defined(LUA_USE_MACOSX)
-#define LUA_USE_POSIX
-#define LUA_USE_DLOPEN /* does not need -ldl */
-#define LUA_USE_READLINE /* needs an extra library: -lreadline */
-#define LUA_USE_STRTODHEX /* assume 'strtod' handles hexa formats */
-#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */
-#define LUA_USE_LONGLONG /* assume support for long long */
-#endif
-
-
-
-/*
-@@ LUA_USE_POSIX includes all functionality listed as X/Open System
-@* Interfaces Extension (XSI).
-** CHANGE it (define it) if your system is XSI compatible.
-*/
-#if defined(LUA_USE_POSIX)
-#define LUA_USE_MKSTEMP
-#define LUA_USE_ISATTY
-#define LUA_USE_POPEN
-#define LUA_USE_ULONGJMP
-#endif
-
-
-
-/*
-@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
-@* Lua libraries.
-@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
-@* C libraries.
-** CHANGE them if your machine has a non-conventional directory
-** hierarchy or if you want to install your libraries in
-** non-conventional directories.
-*/
-#if defined(_WIN32) /* { */
-/*
-** In Windows, any exclamation mark ('!') in the path is replaced by the
-** path of the directory of the executable file of the current process.
-*/
-#define LUA_LDIR "!\\lua\\"
-#define LUA_CDIR "!\\"
-#define LUA_PATH_DEFAULT \
- LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \
- LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" ".\\?.lua"
-#define LUA_CPATH_DEFAULT \
- LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" ".\\?.dll"
-
-#else /* }{ */
-
-#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR "/"
-#define LUA_ROOT "/usr/local/"
-#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR
-#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR
-#define LUA_PATH_DEFAULT \
- LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
- LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" "./?.lua"
-#define LUA_CPATH_DEFAULT \
- LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so"
-#endif /* } */
-
-
-/*
-@@ LUA_DIRSEP is the directory separator (for submodules).
-** CHANGE it if your machine does not use "/" as the directory separator
-** and is not Windows. (On Windows Lua automatically uses "\".)
-*/
-#if defined(_WIN32)
-#define LUA_DIRSEP "\\"
-#else
-#define LUA_DIRSEP "/"
-#endif
-
-
-/*
-@@ 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.
-** CHANGE them if you need to define those functions in some special way.
-** For instance, if you want to create one Windows DLL with the core and
-** the libraries, you may want to use the following definition (define
-** LUA_BUILD_AS_DLL to get it).
-*/
-#if defined(LUA_BUILD_AS_DLL) /* { */
-
-#if defined(LUA_CORE) || defined(LUA_LIB) /* { */
-#define LUA_API __declspec(dllexport)
-#else /* }{ */
-#define LUA_API __declspec(dllimport)
-#endif /* } */
-
-#else /* }{ */
-
-#define LUA_API extern
-
-#endif /* } */
-
-
-/* more often than not the libs go together with the core */
-#define LUALIB_API LUA_API
-#define LUAMOD_API LUALIB_API
-
-
-/*
-@@ LUAI_FUNC is a mark for all extern functions that are not to be
-@* exported to outside modules.
-@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables
-@* that are not to be exported to outside modules (LUAI_DDEF for
-@* definitions and LUAI_DDEC for declarations).
-** CHANGE them if you need to mark them in some special way. Elf/gcc
-** (versions 3.2 and later) mark them as "hidden" to optimize access
-** when Lua is compiled as a shared library. Not all elf targets support
-** this attribute. Unfortunately, gcc does not offer a way to check
-** whether the target offers that support, and those without support
-** give a warning about it. To avoid these warnings, change to the
-** default definition.
-*/
-#if defined(luaall_c) /* { */
-#define LUAI_FUNC static
-#define LUAI_DDEC static
-#define LUAI_DDEF static
-
-#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
- defined(__ELF__)
-#define LUAI_FUNC __attribute__((visibility("hidden"))) extern
-#define LUAI_DDEC LUAI_FUNC
-#define LUAI_DDEF /* empty */
-
-#else /* }{ */
-#define LUAI_FUNC extern
-#define LUAI_DDEC extern
-#define LUAI_DDEF /* empty */
-#endif /* } */
-
-
-
-/*
-@@ LUA_QL describes how error messages quote program elements.
-** CHANGE it if you want a different appearance.
-*/
-#define LUA_QL(x) "'" x "'"
-#define LUA_QS LUA_QL("%s")
-
-
-/*
-@@ LUA_IDSIZE gives the maximum size for the description of the source
-@* of a function in debug information.
-** CHANGE it if you want a different size.
-*/
-#define LUA_IDSIZE 60
-
-
-/*
-@@ luai_writestring/luai_writeline define how 'print' prints its results.
-*/
-#include <stdio.h>
-#define luai_writestring(s,l) fwrite((s), sizeof(char), (l), stdout)
-#define luai_writeline() (luai_writestring("\n", 1), fflush(stdout))
-
-/*
-@@ luai_writestringerror defines how to print error messages.
-** (A format string with one argument is enough for Lua...)
-*/
-#define luai_writestringerror(s,p) \
- (fprintf(stderr, (s), (p)), fflush(stderr))
-
-
-
-
-
-/*
-** {==================================================================
-** Compatibility with previous versions
-** ===================================================================
-*/
-
-/*
-@@ LUA_COMPAT_ALL controls all compatibility options.
-** You can define it to get all options, or change specific options
-** to fit your specific needs.
-*/
-#if defined(LUA_COMPAT_ALL) /* { */
-
-/*
-@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'.
-** You can replace it with 'table.unpack'.
-*/
-#define LUA_COMPAT_UNPACK
-
-/*
-@@ LUA_COMPAT_LOADERS controls the presence of table 'package.loaders'.
-** You can replace it with 'package.searchers'.
-*/
-#define LUA_COMPAT_LOADERS
-
-/*
-@@ macro 'lua_cpcall' emulates deprecated function lua_cpcall.
-** You can call your C function directly (with light C functions).
-*/
-#define lua_cpcall(L,f,u) \
- (lua_pushcfunction(L, (f)), \
- lua_pushlightuserdata(L,(u)), \
- lua_pcall(L,1,0,0))
-
-
-/*
-@@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library.
-** You can rewrite 'log10(x)' as 'log(x, 10)'.
-*/
-#define LUA_COMPAT_LOG10
-
-/*
-@@ LUA_COMPAT_LOADSTRING defines the function 'loadstring' in the base
-** library. You can rewrite 'loadstring(s)' as 'load(s)'.
-*/
-#define LUA_COMPAT_LOADSTRING
-
-/*
-@@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library.
-*/
-#define LUA_COMPAT_MAXN
-
-/*
-@@ The following macros supply trivial compatibility for some
-** changes in the API. The macros themselves document how to
-** change your code to avoid using them.
-*/
-#define lua_strlen(L,i) lua_rawlen(L, (i))
-
-#define lua_objlen(L,i) lua_rawlen(L, (i))
-
-#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ)
-#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT)
-
-/*
-@@ LUA_COMPAT_MODULE controls compatibility with previous
-** module functions 'module' (Lua) and 'luaL_register' (C).
-*/
-#define LUA_COMPAT_MODULE
-
-#endif /* } */
-
-/* }================================================================== */
-
-
-
-/*
-@@ LUAI_BITSINT defines the number of bits in an int.
-** CHANGE here if Lua cannot automatically detect the number of bits of
-** your machine. Probably you do not need to change this.
-*/
-/* avoid overflows in comparison */
-#if INT_MAX-20 < 32760 /* { */
-#define LUAI_BITSINT 16
-#elif INT_MAX > 2147483640L /* }{ */
-/* int has at least 32 bits */
-#define LUAI_BITSINT 32
-#else /* }{ */
-#error "you must define LUA_BITSINT with number of bits in an integer"
-#endif /* } */
-
-
-/*
-@@ LUA_INT32 is an signed integer with exactly 32 bits.
-@@ LUAI_UMEM is an unsigned integer big enough to count the total
-@* memory used by Lua.
-@@ LUAI_MEM is a signed integer big enough to count the total memory
-@* used by Lua.
-** CHANGE here if for some weird reason the default definitions are not
-** good enough for your machine. Probably you do not need to change
-** this.
-*/
-#if LUAI_BITSINT >= 32 /* { */
-#define LUA_INT32 int
-#define LUAI_UMEM size_t
-#define LUAI_MEM ptrdiff_t
-#else /* }{ */
-/* 16-bit ints */
-#define LUA_INT32 long
-#define LUAI_UMEM unsigned long
-#define LUAI_MEM long
-#endif /* } */
-
-
-/*
-@@ LUAI_MAXSTACK limits the size of the Lua stack.
-** CHANGE it if you need a different limit. This limit is arbitrary;
-** its only purpose is to stop Lua to consume unlimited stack
-** space (and to reserve some numbers for pseudo-indices).
-*/
-#if LUAI_BITSINT >= 32
-#define LUAI_MAXSTACK 1000000
-#else
-#define LUAI_MAXSTACK 15000
-#endif
-
-/* reserve some space for error handling */
-#define LUAI_FIRSTPSEUDOIDX (-LUAI_MAXSTACK - 1000)
-
-
-
-
-/*
-@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
-** CHANGE it if it uses too much C-stack space.
-*/
-#define LUAL_BUFFERSIZE BUFSIZ
-
-
-
-
-/*
-** {==================================================================
-@@ LUA_NUMBER is the type of numbers in Lua.
-** CHANGE the following definitions only if you want to build Lua
-** with a number type different from double. You may also need to
-** change lua_number2int & lua_number2integer.
-** ===================================================================
-*/
-
-#define LUA_NUMBER_DOUBLE
-#define LUA_NUMBER double
-
-/*
-@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
-@* over a number.
-*/
-#define LUAI_UACNUMBER double
-
-
-/*
-@@ LUA_NUMBER_SCAN is the format for reading numbers.
-@@ LUA_NUMBER_FMT is the format for writing numbers.
-@@ lua_number2str converts a number to a string.
-@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
-*/
-#define LUA_NUMBER_SCAN "%lf"
-#define LUA_NUMBER_FMT "%.14g"
-#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
-#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
-
-
-/*
-@@ lua_str2number converts a decimal numeric string to a number.
-@@ lua_strx2number converts an hexadecimal numeric string to a number.
-** In C99, 'strtod' do both conversions. C89, however, has no function
-** to convert floating hexadecimal strings to numbers. For these
-** systems, you can leave 'lua_strx2number' undefined and Lua will
-** provide its own implementation.
-*/
-#define lua_str2number(s,p) strtod((s), (p))
-
-#if defined(LUA_USE_STRTODHEX)
-#define lua_strx2number(s,p) strtod((s), (p))
-#endif
-
-
-/*
-@@ The luai_num* macros define the primitive operations over numbers.
-*/
-
-/* the following operations need the math library */
-#if defined(lobject_c) || defined(lvm_c) || defined(luaall_c)
-#include <math.h>
-#define luai_nummod(L,a,b) ((a) - floor((a)/(b))*(b))
-#define luai_numpow(L,a,b) (pow(a,b))
-#endif
-
-/* these are quite standard operations */
-#if defined(LUA_CORE)
-#define luai_numadd(L,a,b) ((a)+(b))
-#define luai_numsub(L,a,b) ((a)-(b))
-#define luai_nummul(L,a,b) ((a)*(b))
-#define luai_numdiv(L,a,b) ((a)/(b))
-#define luai_numunm(L,a) (-(a))
-#define luai_numeq(a,b) ((a)==(b))
-#define luai_numlt(L,a,b) ((a)<(b))
-#define luai_numle(L,a,b) ((a)<=(b))
-#define luai_numisnan(L,a) (!luai_numeq((a), (a)))
-#endif
-
-
-
-/*
-@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
-** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
-** machines, ptrdiff_t gives a good choice between int or long.)
-*/
-#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
-
-
-#if defined(LUA_CORE) /* { */
-
-#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */
-
-/* On a Microsoft compiler on a Pentium, use assembler to avoid clashes
- with a DirectX idiosyncrasy */
-#if defined(_MSC_VER) && defined(M_IX86) /* { */
-
-#define MS_ASMTRICK
-
-#else /* }{ */
-/* the next definition uses a trick that should work on any machine
- using IEEE754 with a 32-bit integer type */
-
-#define LUA_IEEE754TRICK
-
-/*
-@@ 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(__X86__) || \
- defined (__x86_64)
-#define LUA_IEEEENDIAN 0
-#elif defined(__POWERPC__) || defined(__ppc__)
-#define LUA_IEEEENDIAN 1
-#endif
-
-#endif /* } */
-
-#endif /* } */
-
-#endif /* } */
-
-/* }================================================================== */
-
-
-/*
-@@ LUA_NANTRICKLE/LUA_NANTRICKBE controls the use of a trick to pack all
-** types into a single double value, using NaN values to represent
-** non-number values. The trick only works on 32-bit machines (ints and
-** pointers are 32-bit values) with numbers represented as IEEE 754-2008
-** doubles with conventional endianess (12345678 or 87654321), in CPUs
-** that do not produce signaling NaN values (all NaNs are quiet).
-*/
-#if defined(LUA_CORE) && \
- defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */
-
-/* little-endian architectures that satisfy those conditions */
-#if defined(__i386__) || defined(__i386) || defined(__X86__) || \
- defined(_M_IX86)
-
-#define LUA_NANTRICKLE
-
-#endif
-
-#endif /* } */
-
-
-
-
-/* =================================================================== */
-
-/*
-** Local configuration. You can use this space to add your redefinitions
-** without modifying the main part of the file.
-*/
-
-
-
-#endif
-
diff --git a/src/lualib.h b/src/lualib.h
index 8132da6..9fd126b 100755..100644
--- a/src/lualib.h
+++ b/src/lualib.h
@@ -1,5 +1,5 @@
/*
-** $Id: lualib.h,v 1.42 2011/05/25 14:12:28 roberto Exp $
+** $Id: lualib.h,v 1.43 2011/12/08 12:11:37 roberto Exp $
** Lua standard libraries
** See Copyright Notice in lua.h
*/
@@ -11,9 +11,6 @@
#include "lua.h"
-/* Key to file-handle type */
-#define LUA_FILEHANDLE "FILE*"
-
LUAMOD_API int (luaopen_base) (lua_State *L);
diff --git a/src/lundump.c b/src/lundump.c
index d7b0ab3..80c7aa3 100755..100644
--- a/src/lundump.c
+++ b/src/lundump.c
@@ -1,5 +1,5 @@
/*
-** $Id: lundump.c,v 1.70 2011/06/21 12:29:00 lhf Exp $
+** $Id: lundump.c,v 1.71 2011/12/07 10:39:12 lhf Exp $
** load precompiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -136,8 +136,8 @@ static void LoadUpvalues(LoadState* S, Proto* f)
for (i=0; i<n; i++) f->upvalues[i].name=NULL;
for (i=0; i<n; i++)
{
- f->upvalues[i].instack=LoadChar(S);
- f->upvalues[i].idx=LoadChar(S);
+ f->upvalues[i].instack=LoadByte(S);
+ f->upvalues[i].idx=LoadByte(S);
}
}
diff --git a/src/lundump.h b/src/lundump.h
index b63993f..b63993f 100755..100644
--- a/src/lundump.h
+++ b/src/lundump.h
diff --git a/src/lvm.c b/src/lvm.c
index e4f90af..694971b 100755..100644
--- a/src/lvm.c
+++ b/src/lvm.c
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.c,v 2.141 2011/06/09 18:24:22 roberto Exp $
+** $Id: lvm.c,v 2.147 2011/12/07 14:43:55 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -127,29 +127,38 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
int loop;
- TValue temp;
for (loop = 0; loop < MAXTAGLOOP; loop++) {
const TValue *tm;
if (ttistable(t)) { /* `t' is a table? */
Table *h = hvalue(t);
- TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
- if (!ttisnil(oldval) || /* result is not nil? */
- (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
- setobj2t(L, oldval, val);
+ TValue *oldval = cast(TValue *, luaH_get(h, key));
+ /* if previous value is not nil, there must be a previous entry
+ in the table; moreover, a metamethod has no relevance */
+ if (!ttisnil(oldval) ||
+ /* previous value is nil; must check the metamethod */
+ ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL &&
+ /* no metamethod; is there a previous entry in the table? */
+ (oldval != luaO_nilobject ||
+ /* no previous entry; must create one. (The next test is
+ always true; we only need the assignment.) */
+ (oldval = luaH_newkey(L, h, key), 1)))) {
+ /* no metamethod and (now) there is an entry with given key */
+ setobj2t(L, oldval, val); /* assign new value to that entry */
+ invalidateTMcache(h);
luaC_barrierback(L, obj2gco(h), val);
return;
}
- /* else will try the tag method */
+ /* else will try the metamethod */
}
- else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
- luaG_typeerror(L, t, "index");
+ else /* not a table; check metamethod */
+ if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
+ luaG_typeerror(L, t, "index");
+ /* there is a metamethod */
if (ttisfunction(tm)) {
callTM(L, tm, t, key, val, 0);
return;
}
- /* else repeat with 'tm' */
- setobj(L, &temp, tm); /* avoid pointing inside table (may rehash) */
- t = &temp;
+ t = tm; /* else repeat with 'tm' */
}
luaG_runerror(L, "loop in settable");
}
@@ -217,9 +226,9 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
return luai_numlt(L, nvalue(l), nvalue(r));
else if (ttisstring(l) && ttisstring(r))
return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
- else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
- return res;
- return luaG_ordererror(L, l, r);
+ else if ((res = call_orderTM(L, l, r, TM_LT)) < 0)
+ luaG_ordererror(L, l, r);
+ return res;
}
@@ -229,11 +238,11 @@ int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
return luai_numle(L, nvalue(l), nvalue(r));
else if (ttisstring(l) && ttisstring(r))
return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
- else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
+ else if ((res = call_orderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */
return res;
- else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */
- return !res;
- return luaG_ordererror(L, l, r);
+ else if ((res = call_orderTM(L, r, l, TM_LT)) < 0) /* else try `lt' */
+ luaG_ordererror(L, l, r);
+ return !res;
}
@@ -506,6 +515,7 @@ void luaV_finishOp (lua_State *L) {
#define vmdispatch(o) switch(o)
#define vmcase(l,b) case l: {b} break;
+#define vmcasenb(l,b) case l: {b} /* nb = no break */
void luaV_execute (lua_State *L) {
CallInfo *ci = L->ci;
@@ -525,7 +535,7 @@ void luaV_execute (lua_State *L) {
(--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
Protect(traceexec(L));
}
- /* warning!! several calls may realloc the stack and invalidate `ra' */
+ /* WARNING: several calls may realloc the stack and invalidate `ra' */
ra = RA(i);
lua_assert(base == ci->u.l.base);
lua_assert(base <= L->top && L->top < L->stack + L->stacksize);
@@ -652,7 +662,7 @@ void luaV_execute (lua_State *L) {
TValue *rb = RKB(i);
TValue *rc = RKC(i);
Protect(
- if (equalobj(L, rb, rc) != GETARG_A(i))
+ if (cast_int(equalobj(L, rb, rc)) != GETARG_A(i))
ci->u.l.savedpc++;
else
donextjump(ci);
@@ -732,7 +742,7 @@ void luaV_execute (lua_State *L) {
goto newframe; /* restart luaV_execute over new Lua function */
}
)
- vmcase(OP_RETURN,
+ vmcasenb(OP_RETURN,
int b = GETARG_B(i);
if (b != 0) L->top = ra+b-1;
if (cl->p->sizep > 0) luaF_close(L, base);
@@ -771,7 +781,7 @@ void luaV_execute (lua_State *L) {
setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep)));
ci->u.l.savedpc += GETARG_sBx(i);
)
- vmcase(OP_TFORCALL,
+ vmcasenb(OP_TFORCALL,
StkId cb = ra + 3; /* call base */
setobjs2s(L, cb+2, ra+2);
setobjs2s(L, cb+1, ra+1);
@@ -808,7 +818,7 @@ void luaV_execute (lua_State *L) {
luaH_resizearray(L, h, last); /* pre-allocate it at once */
for (; n > 0; n--) {
TValue *val = ra+n;
- setobj2t(L, luaH_setint(L, h, last--), val);
+ luaH_setint(L, h, last--, val);
luaC_barrierback(L, obj2gco(h), val);
}
L->top = ci->top; /* correct top (in case of previous open call) */
diff --git a/src/lvm.h b/src/lvm.h
index ec35822..ec35822 100755..100644
--- a/src/lvm.h
+++ b/src/lvm.h
diff --git a/src/lzio.c b/src/lzio.c
index 7d2677b..354f94e 100755..100644
--- a/src/lzio.c
+++ b/src/lzio.c
@@ -1,5 +1,5 @@
/*
-** $Id: lzio.c,v 1.33 2011/02/23 13:13:10 roberto Exp $
+** $Id: lzio.c,v 1.34 2011/07/15 12:35:32 roberto Exp $
** a generic input stream interface
** See Copyright Notice in lua.h
*/
@@ -29,7 +29,7 @@ int luaZ_fill (ZIO *z) {
return EOZ;
z->n = size - 1; /* discount char being returned */
z->p = buff;
- return char2int(*(z->p++));
+ return cast_uchar(*(z->p++));
}
diff --git a/src/lzio.h b/src/lzio.h
index 4174986..0868230 100755..100644
--- a/src/lzio.h
+++ b/src/lzio.h
@@ -1,5 +1,5 @@
/*
-** $Id: lzio.h,v 1.24 2011/02/23 13:13:10 roberto Exp $
+** $Id: lzio.h,v 1.26 2011/07/15 12:48:03 roberto Exp $
** Buffered streams
** See Copyright Notice in lua.h
*/
@@ -17,11 +17,7 @@
typedef struct Zio ZIO;
-#define char2int(c) cast(int, cast(unsigned char, (c)))
-
-#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z))
-
-#define zungetc(z) ((z)->n++, (z)->p--)
+#define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z))
typedef struct Mbuffer {