summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLua Team <team@lua.org>2005-09-09 12:00:00 +0000
committerrepogen <>2005-09-09 12:00:00 +0000
commitbd80c4ee9b6d9464cf9f3ff4ee41890d8b3ca9e6 (patch)
treee1d7c1b341ccb9a3a1fb044ac6e67b5a5e0259b7 /src
parentbf6b5550cdfbc0c4a3a4577776ad76628d80718e (diff)
downloadlua-github-bd80c4ee9b6d9464cf9f3ff4ee41890d8b3ca9e6.tar.gz
Lua 5.1-alpha5.1-alpha
Diffstat (limited to 'src')
-rw-r--r--src/lapi.c27
-rw-r--r--src/lauxlib.c181
-rw-r--r--src/lauxlib.h57
-rw-r--r--src/lbaselib.c74
-rw-r--r--src/lcode.c85
-rw-r--r--src/lcode.h5
-rw-r--r--src/ldblib.c18
-rw-r--r--src/ldebug.c24
-rw-r--r--src/ldo.c164
-rw-r--r--src/ldo.h15
-rw-r--r--src/ldump.c79
-rw-r--r--src/lgc.c19
-rw-r--r--src/lgc.h17
-rw-r--r--src/linit.c8
-rw-r--r--src/liolib.c145
-rw-r--r--src/llex.h4
-rw-r--r--src/llimits.h21
-rw-r--r--src/lmathlib.c44
-rw-r--r--src/loadlib.c373
-rw-r--r--src/lobject.c24
-rw-r--r--src/lobject.h23
-rw-r--r--src/lopcodes.c10
-rw-r--r--src/lopcodes.h11
-rw-r--r--src/loslib.c11
-rw-r--r--src/lparser.c166
-rw-r--r--src/lstate.c5
-rw-r--r--src/lstate.h10
-rw-r--r--src/lstrlib.c117
-rw-r--r--src/ltable.c16
-rw-r--r--src/ltable.h4
-rw-r--r--src/ltablib.c14
-rw-r--r--src/ltm.c4
-rw-r--r--src/ltm.h6
-rw-r--r--src/lua.c56
-rw-r--r--src/lua.h17
-rw-r--r--src/luac.c8
-rw-r--r--src/luaconf.h307
-rw-r--r--src/lualib.h4
-rw-r--r--src/lundump.c242
-rw-r--r--src/lundump.h49
-rw-r--r--src/lvm.c143
-rw-r--r--src/lvm.h4
-rw-r--r--src/lzio.c22
-rw-r--r--src/print.c8
44 files changed, 1433 insertions, 1208 deletions
diff --git a/src/lapi.c b/src/lapi.c
index 1fe7916a..b85e1dc5 100644
--- a/src/lapi.c
+++ b/src/lapi.c
@@ -1,5 +1,5 @@
/*
-** $Id: lapi.c,v 2.41 2005/05/17 19:49:15 roberto Exp $
+** $Id: lapi.c,v 2.48 2005/09/01 17:42:22 roberto Exp $
** Lua API
** See Copyright Notice in lua.h
*/
@@ -113,11 +113,11 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
if (from == to) return;
lua_lock(to);
api_checknelems(from, n);
- api_check(L, G(from) == G(to));
+ api_check(from, G(from) == G(to));
+ api_check(from, to->ci->top - to->top >= n);
from->top -= n;
for (i = 0; i < n; i++) {
- setobj2s(to, to->top, from->top + i);
- api_incr_top(to);
+ setobj2s(to, to->top++, from->top + i);
}
lua_unlock(to);
}
@@ -153,7 +153,7 @@ LUA_API lua_State *lua_newthread (lua_State *L) {
LUA_API int lua_gettop (lua_State *L) {
- return (L->top - L->base);
+ return cast(int, L->top - L->base);
}
@@ -344,6 +344,7 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
return NULL;
}
luaC_checkGC(L);
+ o = index2adr(L, idx); /* previous call may reallocate the stack */
lua_unlock(L);
}
if (len != NULL) *len = tsvalue(o)->len;
@@ -351,7 +352,7 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
}
-LUA_API size_t lua_objsize (lua_State *L, int idx) {
+LUA_API size_t lua_objlen (lua_State *L, int idx) {
StkId o = index2adr(L, idx);
switch (ttype(o)) {
case LUA_TSTRING: return tsvalue(o)->len;
@@ -618,6 +619,9 @@ LUA_API void lua_getfenv (lua_State *L, int idx) {
case LUA_TUSERDATA:
sethvalue(L, L->top, uvalue(o)->env);
break;
+ case LUA_TTHREAD:
+ setobj2s(L, L->top, gt(thvalue(o)));
+ break;
default:
setnilvalue(L->top);
break;
@@ -736,6 +740,9 @@ LUA_API int lua_setfenv (lua_State *L, int idx) {
case LUA_TUSERDATA:
uvalue(o)->env = hvalue(L->top - 1);
break;
+ case LUA_TTHREAD:
+ sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1));
+ break;
default:
res = 0;
break;
@@ -868,7 +875,7 @@ LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
if (isLfunction(o))
status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0);
else
- status = 0;
+ status = 1;
lua_unlock(L);
return status;
}
@@ -969,10 +976,10 @@ LUA_API int lua_next (lua_State *L, int idx) {
LUA_API void lua_concat (lua_State *L, int n) {
lua_lock(L);
- luaC_checkGC(L);
api_checknelems(L, n);
if (n >= 2) {
- luaV_concat(L, n, L->top - L->base - 1);
+ luaC_checkGC(L);
+ luaV_concat(L, n, cast(int, L->top - L->base) - 1);
L->top -= (n-1);
}
else if (n == 0) { /* push empty string */
@@ -985,7 +992,7 @@ LUA_API void lua_concat (lua_State *L, int n) {
LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
- *ud = G(L)->ud;
+ if (ud) *ud = G(L)->ud;
return G(L)->frealloc;
}
diff --git a/src/lauxlib.c b/src/lauxlib.c
index 964f5eb0..b643d6c3 100644
--- a/src/lauxlib.c
+++ b/src/lauxlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.c,v 1.133 2005/05/17 19:49:15 roberto Exp $
+** $Id: lauxlib.c,v 1.152 2005/09/06 17:20:11 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -42,7 +42,8 @@
LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
lua_Debug ar;
- lua_getstack(L, 0, &ar);
+ if (!lua_getstack(L, 0, &ar)) /* no stack frame? */
+ return luaL_error(L, "bad argument #%d (%s)", narg, extramsg);
lua_getinfo(L, "n", &ar);
if (strcmp(ar.namewhat, "method") == 0) {
narg--; /* do not count `self' */
@@ -65,7 +66,7 @@ LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) {
static void tag_error (lua_State *L, int narg, int tag) {
- luaL_typerror(L, narg, lua_typename(L, tag));
+ luaL_typerror(L, narg, lua_typename(L, tag));
}
@@ -95,12 +96,16 @@ LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
/* }====================================================== */
-LUALIB_API int luaL_findstring (const char *name, const char *const list[]) {
+LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,
+ const char *const lst[]) {
+ const char *name = (def) ? luaL_optstring(L, narg, def) :
+ luaL_checkstring(L, narg);
int i;
- for (i=0; list[i]; i++)
- if (strcmp(list[i], name) == 0)
+ for (i=0; lst[i]; i++)
+ if (strcmp(lst[i], name) == 0)
return i;
- return -1; /* name not found */
+ return luaL_argerror(L, narg,
+ lua_pushfstring(L, "invalid option " LUA_QS, name));
}
@@ -112,31 +117,17 @@ LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
lua_newtable(L); /* create metatable */
lua_pushvalue(L, -1);
lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */
- lua_pushvalue(L, -1);
- lua_pushstring(L, tname);
- lua_rawset(L, LUA_REGISTRYINDEX); /* registry[metatable] = name */
return 1;
}
-LUALIB_API void luaL_getmetatable (lua_State *L, const char *tname) {
- lua_getfield(L, LUA_REGISTRYINDEX, tname);
-}
-
-
LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
- const char *tn;
- if (!lua_getmetatable(L, ud)) return NULL; /* no metatable? */
- lua_rawget(L, LUA_REGISTRYINDEX); /* get registry[metatable] */
- tn = lua_tostring(L, -1);
- if (tn && (strcmp(tn, tname) == 0)) {
- lua_pop(L, 1);
- return lua_touserdata(L, ud);
- }
- else {
- lua_pop(L, 1);
- return NULL;
- }
+ void *p = lua_touserdata(L, ud);
+ lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
+ if (p == NULL || !lua_getmetatable(L, ud) || !lua_rawequal(L, -1, -2))
+ luaL_typerror(L, ud, tname);
+ lua_pop(L, 2); /* remove both metatables */
+ return p;
}
@@ -230,26 +221,27 @@ LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
}
-LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
- const luaL_reg *l, int nup) {
+LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
+ const luaL_Reg *l) {
+ luaI_openlib(L, libname, l, 0);
+}
+
+
+LUALIB_API void luaI_openlib (lua_State *L, const char *libname,
+ const luaL_Reg *l, int nup) {
if (libname) {
/* check whether lib already exists */
- luaL_getfield(L, LUA_GLOBALSINDEX, libname);
- if (lua_isnil(L, -1)) { /* not found? */
+ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
+ lua_getfield(L, -1, libname); /* get _LOADED[libname] */
+ if (!lua_istable(L, -1)) { /* not found? */
lua_pop(L, 1); /* remove previous result */
- lua_newtable(L); /* create it */
- if (lua_getmetatable(L, LUA_GLOBALSINDEX))
- lua_setmetatable(L, -2); /* share metatable with global table */
- /* register it with given name */
+ /* try global variable (and create one if it does not exist) */
+ if (luaL_findtable(L, LUA_GLOBALSINDEX, libname) != NULL)
+ luaL_error(L, "name conflict for module " LUA_QS, libname);
lua_pushvalue(L, -1);
- luaL_setfield(L, LUA_GLOBALSINDEX, libname);
+ lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */
}
- else if (!lua_istable(L, -1))
- luaL_error(L, "name conflict for library " LUA_QS, libname);
- lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
- lua_pushvalue(L, -2);
- lua_setfield(L, -2, libname); /* _LOADED[modname] = new table */
- lua_pop(L, 1); /* remove _LOADED table */
+ lua_remove(L, -2); /* remove _LOADED table */
lua_insert(L, -(nup+1)); /* move library table to below upvalues */
}
for (; l->name; l++) {
@@ -270,7 +262,7 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
** =======================================================
*/
-#ifndef luaL_getn
+#if defined(LUA_COMPAT_GETN)
static int checkint (lua_State *L, int topop) {
int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1;
@@ -313,7 +305,7 @@ LUALIB_API int luaL_getn (lua_State *L, int t) {
if ((n = checkint(L, 2)) >= 0) return n;
lua_getfield(L, t, "n"); /* else try t.n */
if ((n = checkint(L, 1)) >= 0) return n;
- return lua_objsize(L, t);
+ return lua_objlen(L, t);
}
#endif
@@ -321,21 +313,11 @@ LUALIB_API int luaL_getn (lua_State *L, int t) {
/* }====================================================== */
-static const char *pushnexttemplate (lua_State *L, const char *path) {
- const char *l;
- if (*path == '\0') return NULL; /* no more templates */
- if (*path == LUA_PATHSEP) path++; /* skip separator */
- l = strchr(path, LUA_PATHSEP); /* find next separator */
- if (l == NULL) l = path+strlen(path);
- lua_pushlstring(L, path, l - path); /* template */
- return l;
-}
-
LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
const char *r) {
const char *wild;
- int l = strlen(p);
+ size_t l = strlen(p);
luaL_Buffer b;
luaL_buffinit(L, &b);
while ((wild = strstr(s, p)) != NULL) {
@@ -343,65 +325,19 @@ LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
luaL_addstring(&b, r); /* push replacement in place of pattern */
s = wild + l; /* continue after `p' */
}
- luaL_addstring(&b, s); /* push last suffix (`n' already includes this) */
+ luaL_addstring(&b, s); /* push last suffix */
luaL_pushresult(&b);
return lua_tostring(L, -1);
}
-static int readable (const char *fname) {
- int err;
- FILE *f = fopen(fname, "r"); /* try to open file */
- if (f == NULL) return 0; /* open failed */
- getc(f); /* try to read it */
- err = ferror(f);
- fclose(f);
- return (err == 0);
-}
-
-
-LUALIB_API const char *luaL_searchpath (lua_State *L, const char *name,
- const char *path) {
- const char *p = path;
- for (;;) {
- const char *fname;
- if ((p = pushnexttemplate(L, p)) == NULL) {
- lua_pushfstring(L, "no readable " LUA_QS " in path " LUA_QS "",
- name, path);
- return NULL;
- }
- fname = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name);
- lua_remove(L, -2); /* remove path template */
- if (readable(fname)) /* does file exist and is readable? */
- return fname; /* return that file name */
- lua_pop(L, 1); /* remove file name */
- }
-}
-
-
-LUALIB_API const char *luaL_getfield (lua_State *L, int idx,
- const char *fname) {
+LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
+ const char *fname) {
const char *e;
lua_pushvalue(L, idx);
- while ((e = strchr(fname, '.')) != NULL) {
- lua_pushlstring(L, fname, e - fname);
- lua_rawget(L, -2);
- lua_remove(L, -2); /* remove previous table */
- fname = e + 1;
- if (!lua_istable(L, -1)) return fname;
- }
- lua_pushstring(L, fname);
- lua_rawget(L, -2); /* get last field */
- lua_remove(L, -2); /* remove previous table */
- return NULL;
-}
-
-
-LUALIB_API const char *luaL_setfield (lua_State *L, int idx,
- const char *fname) {
- const char *e;
- lua_pushvalue(L, idx);
- while ((e = strchr(fname, '.')) != NULL) {
+ do {
+ e = strchr(fname, '.');
+ if (e == NULL) e = fname + strlen(fname);
lua_pushlstring(L, fname, e - fname);
lua_rawget(L, -2);
if (lua_isnil(L, -1)) { /* no such field? */
@@ -411,17 +347,13 @@ LUALIB_API const char *luaL_setfield (lua_State *L, int idx,
lua_pushvalue(L, -2);
lua_settable(L, -4); /* set new table into field */
}
- lua_remove(L, -2); /* remove previous table */
- fname = e + 1;
- if (!lua_istable(L, -1)) {
+ else if (!lua_istable(L, -1)) { /* field has a non-table value? */
lua_pop(L, 2); /* remove table and value */
- return fname;
+ return fname; /* return problematic part of the name */
}
- }
- lua_pushstring(L, fname);
- lua_pushvalue(L, -3); /* move value to the top */
- lua_rawset(L, -3); /* set last field */
- lua_pop(L, 2); /* remove value and table */
+ lua_remove(L, -2); /* remove previous table */
+ fname = e + 1;
+ } while (*e == '.');
return NULL;
}
@@ -480,7 +412,7 @@ LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) {
LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
while (l--)
- luaL_putchar(B, *s++);
+ luaL_addchar(B, *s++);
}
@@ -538,7 +470,7 @@ LUALIB_API int luaL_ref (lua_State *L, int t) {
lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */
}
else { /* no free elements */
- ref = lua_objsize(L, t);
+ ref = lua_objlen(L, t);
ref++; /* create new reference */
}
lua_rawseti(L, t, ref);
@@ -661,6 +593,12 @@ LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,
}
+LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) {
+ return luaL_loadbuffer(L, s, strlen(s), s);
+}
+
+
+
/* }====================================================== */
@@ -671,21 +609,22 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
free(ptr);
return NULL;
}
- else
+ else
return realloc(ptr, nsize);
}
static int panic (lua_State *L) {
(void)L; /* to avoid warnings */
- fprintf(stderr, "PANIC: unprotected error during Lua-API call\n");
+ fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n",
+ lua_tostring(L, -1));
return 0;
}
LUALIB_API lua_State *luaL_newstate (void) {
lua_State *L = lua_newstate(l_alloc, NULL);
- lua_atpanic(L, &panic);
+ if (L) lua_atpanic(L, &panic);
return L;
}
diff --git a/src/lauxlib.h b/src/lauxlib.h
index 83c807e9..aa07cb2b 100644
--- a/src/lauxlib.h
+++ b/src/lauxlib.h
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.h,v 1.75 2005/03/29 16:20:48 roberto Exp $
+** $Id: lauxlib.h,v 1.85 2005/09/06 17:19:51 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -15,24 +15,34 @@
#include "lua.h"
-#if !LUA_COMPAT_GETN
-#define luaL_getn(L,i) lua_objsize(L, i)
+#if defined(LUA_COMPAT_GETN)
+LUALIB_API int (luaL_getn) (lua_State *L, int t);
+LUALIB_API void (luaL_setn) (lua_State *L, int t, int n);
+#else
+#define luaL_getn(L,i) ((int)lua_objlen(L, i))
#define luaL_setn(L,i,j) ((void)0) /* no op! */
#endif
+#if defined(LUA_COMPAT_OPENLIB)
+#define luaI_openlib luaL_openlib
+#endif
+
/* extra error code for `luaL_load' */
#define LUA_ERRFILE (LUA_ERRERR+1)
-typedef struct luaL_reg {
+typedef struct luaL_Reg {
const char *name;
lua_CFunction func;
-} luaL_reg;
+} luaL_Reg;
+
-LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
- const luaL_reg *l, int nup);
+LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname,
+ const luaL_Reg *l, int nup);
+LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
+ const luaL_Reg *l);
LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname);
@@ -53,36 +63,31 @@ LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
-LUALIB_API void (luaL_getmetatable) (lua_State *L, const char *tname);
LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
LUALIB_API void (luaL_where) (lua_State *L, int lvl);
LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
-LUALIB_API int (luaL_findstring) (const char *st, const char *const lst[]);
-
-LUALIB_API const char *(luaL_searchpath) (lua_State *L, const char *name,
- const char *path);
+LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
+ const char *const lst[]);
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_getn) (lua_State *L, int t);
-LUALIB_API void (luaL_setn) (lua_State *L, int t, int n);
-
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_loadstring) (lua_State *L, const char *s);
LUALIB_API lua_State *(luaL_newstate) (void);
LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
const char *r);
-LUALIB_API const char *(luaL_getfield) (lua_State *L, int idx,
- const char *fname);
-LUALIB_API const char *(luaL_setfield) (lua_State *L, int idx,
- const char *fname);
+
+LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
+ const char *fname);
+
@@ -103,6 +108,13 @@ LUALIB_API const char *(luaL_setfield) (lua_State *L, int idx,
#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
+#define luaL_dofile(L, fn) (luaL_loadfile(L, fn) || lua_pcall(L, 0, 0, 0))
+
+#define luaL_dostring(L, s) (luaL_loadstring(L, s) || lua_pcall(L, 0, 0, 0))
+
+#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
+
+
/*
** {======================================================
** Generic Buffer manipulation
@@ -118,10 +130,13 @@ typedef struct luaL_Buffer {
char buffer[LUAL_BUFFERSIZE];
} luaL_Buffer;
-#define luaL_putchar(B,c) \
+#define luaL_addchar(B,c) \
((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
(*(B)->p++ = (char)(c)))
+/* compatibility only */
+#define luaL_putchar(B,c) luaL_addchar(B,c)
+
#define luaL_addsize(B,n) ((B)->p += (n))
LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
@@ -149,6 +164,8 @@ LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))
+#define luaL_reg luaL_Reg
+
#endif
diff --git a/src/lbaselib.c b/src/lbaselib.c
index d69d83ff..fb21da4b 100644
--- a/src/lbaselib.c
+++ b/src/lbaselib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbaselib.c,v 1.176 2005/05/17 19:49:15 roberto Exp $
+** $Id: lbaselib.c,v 1.182 2005/08/26 17:36:32 roberto Exp $
** Basic library
** See Copyright Notice in lua.h
*/
@@ -133,7 +133,7 @@ static void getfunc (lua_State *L) {
static int luaB_getfenv (lua_State *L) {
getfunc(L);
if (lua_iscfunction(L, -1)) /* is a C function? */
- lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the global env. */
+ lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */
else
lua_getfenv(L, -1);
return 1;
@@ -145,7 +145,10 @@ static int luaB_setfenv (lua_State *L) {
getfunc(L);
lua_pushvalue(L, 2);
if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
- lua_replace(L, LUA_GLOBALSINDEX);
+ /* change environment of current thread */
+ lua_pushthread(L);
+ lua_insert(L, -2);
+ lua_setfenv(L, -2);
return 0;
}
else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
@@ -192,9 +195,8 @@ static int luaB_collectgarbage (lua_State *L) {
"count", "step", "setpause", "setstepmul", NULL};
static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL};
- int o = luaL_findstring(luaL_optstring(L, 1, "collect"), opts);
+ int o = luaL_checkoption(L, 1, "collect", opts);
int ex = luaL_optinteger(L, 2, 0);
- luaL_argcheck(L, o >= 0, 1, "invalid option");
lua_pushinteger(L, lua_gc(L, optsnum[o], ex));
return 1;
}
@@ -268,15 +270,7 @@ static int luaB_loadstring (lua_State *L) {
static int luaB_loadfile (lua_State *L) {
const char *fname = luaL_optstring(L, 1, NULL);
- const char *path = luaL_optstring(L, 2, NULL);
- int status;
- if (path == NULL)
- status = luaL_loadfile(L, fname);
- else {
- fname = luaL_searchpath(L, fname, path);
- status = (fname) ? luaL_loadfile(L, fname) : 1;
- }
- return load_aux(L, status);
+ return load_aux(L, luaL_loadfile(L, fname));
}
@@ -331,13 +325,6 @@ static int luaB_assert (lua_State *L) {
}
-static int luaB_getn (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
- lua_pushinteger(L, lua_objsize(L, 1));
- return 1;
-}
-
-
static int luaB_unpack (lua_State *L) {
int i = luaL_optint(L, 2, 1);
int e = luaL_optint(L, 3, -1);
@@ -442,32 +429,31 @@ static int luaB_newproxy (lua_State *L) {
}
-static const luaL_reg base_funcs[] = {
+static const luaL_Reg base_funcs[] = {
+ {"assert", luaB_assert},
+ {"collectgarbage", luaB_collectgarbage},
+ {"dofile", luaB_dofile},
{"error", luaB_error},
- {"getmetatable", luaB_getmetatable},
- {"setmetatable", luaB_setmetatable},
+ {"gcinfo", luaB_gcinfo},
{"getfenv", luaB_getfenv},
- {"setfenv", luaB_setfenv},
+ {"getmetatable", luaB_getmetatable},
+ {"loadfile", luaB_loadfile},
+ {"load", luaB_load},
+ {"loadstring", luaB_loadstring},
{"next", luaB_next},
+ {"pcall", luaB_pcall},
{"print", luaB_print},
+ {"rawequal", luaB_rawequal},
+ {"rawget", luaB_rawget},
+ {"rawset", luaB_rawset},
+ {"select", luaB_select},
+ {"setfenv", luaB_setfenv},
+ {"setmetatable", luaB_setmetatable},
{"tonumber", luaB_tonumber},
{"tostring", luaB_tostring},
{"type", luaB_type},
- {"assert", luaB_assert},
- {"getn", luaB_getn},
{"unpack", luaB_unpack},
- {"select", luaB_select},
- {"rawequal", luaB_rawequal},
- {"rawget", luaB_rawget},
- {"rawset", luaB_rawset},
- {"pcall", luaB_pcall},
{"xpcall", luaB_xpcall},
- {"collectgarbage", luaB_collectgarbage},
- {"gcinfo", luaB_gcinfo},
- {"loadfile", luaB_loadfile},
- {"dofile", luaB_dofile},
- {"loadstring", luaB_loadstring},
- {"load", luaB_load},
{NULL, NULL}
};
@@ -593,13 +579,13 @@ static int luaB_corunning (lua_State *L) {
}
-static const luaL_reg co_funcs[] = {
+static const luaL_Reg co_funcs[] = {
{"create", luaB_cocreate},
- {"wrap", luaB_cowrap},
{"resume", luaB_coresume},
- {"yield", luaB_yield},
- {"status", luaB_costatus},
{"running", luaB_corunning},
+ {"status", luaB_costatus},
+ {"wrap", luaB_cowrap},
+ {"yield", luaB_yield},
{NULL, NULL}
};
@@ -616,7 +602,7 @@ static void auxopen (lua_State *L, const char *name,
static void base_open (lua_State *L) {
lua_pushvalue(L, LUA_GLOBALSINDEX);
- luaL_openlib(L, NULL, base_funcs, 0); /* open lib into global table */
+ luaL_register(L, NULL, base_funcs); /* open lib into global table */
lua_pushliteral(L, LUA_VERSION);
lua_setglobal(L, "_VERSION"); /* set global _VERSION */
/* `ipairs' and `pairs' need auxliliary functions as upvalues */
@@ -641,7 +627,7 @@ static void base_open (lua_State *L) {
LUALIB_API int luaopen_base (lua_State *L) {
base_open(L);
- luaL_openlib(L, LUA_COLIBNAME, co_funcs, 0);
+ luaL_register(L, LUA_COLIBNAME, co_funcs);
return 2;
}
diff --git a/src/lcode.c b/src/lcode.c
index 1e8d80fb..04838f33 100644
--- a/src/lcode.c
+++ b/src/lcode.c
@@ -1,5 +1,5 @@
/*
-** $Id: lcode.c,v 2.12 2005/03/16 16:59:21 roberto Exp $
+** $Id: lcode.c,v 2.16 2005/08/29 20:49:21 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -53,6 +53,11 @@ int luaK_jump (FuncState *fs) {
}
+void luaK_ret (FuncState *fs, int first, int nret) {
+ luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
+}
+
+
static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
luaK_codeABC(fs, op, A, B, C);
return luaK_jump(fs);
@@ -101,49 +106,50 @@ static Instruction *getjumpcontrol (FuncState *fs, int pc) {
** check whether list has any jump that do not produce a value
** (or produce an inverted value)
*/
-static int need_value (FuncState *fs, int list, int cond) {
+static int need_value (FuncState *fs, int list) {
for (; list != NO_JUMP; list = getjump(fs, list)) {
Instruction i = *getjumpcontrol(fs, list);
- if (GET_OPCODE(i) != OP_TEST || GETARG_C(i) != cond) return 1;
+ if (GET_OPCODE(i) != OP_TESTSET) return 1;
}
return 0; /* not found */
}
static void patchtestreg (Instruction *i, int reg) {
- if (reg == NO_REG) reg = GETARG_B(*i);
- SETARG_A(*i, reg);
+ if (reg != NO_REG)
+ SETARG_A(*i, reg);
+ else /* no register to put value; change TESTSET to TEST */
+ *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
}
-static void patchlistaux (FuncState *fs, int list,
- int ttarget, int treg, int ftarget, int freg, int dtarget) {
+static void removevalues (FuncState *fs, int list) {
+ for (; list != NO_JUMP; list = getjump(fs, list)) {
+ Instruction *i = getjumpcontrol(fs, list);
+ if (GET_OPCODE(*i) == OP_TESTSET)
+ patchtestreg(i, NO_REG);
+ }
+}
+
+
+static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
+ int dtarget) {
while (list != NO_JUMP) {
int next = getjump(fs, list);
Instruction *i = getjumpcontrol(fs, list);
- if (GET_OPCODE(*i) != OP_TEST) {
- lua_assert(dtarget != NO_JUMP);
- fixjump(fs, list, dtarget); /* jump to default target */
- }
- else {
- if (GETARG_C(*i)) {
- lua_assert(ttarget != NO_JUMP);
- patchtestreg(i, treg);
- fixjump(fs, list, ttarget);
- }
- else {
- lua_assert(ftarget != NO_JUMP);
- patchtestreg(i, freg);
- fixjump(fs, list, ftarget);
- }
+ if (GET_OPCODE(*i) == OP_TESTSET) {
+ patchtestreg(i, reg);
+ fixjump(fs, list, vtarget);
}
+ else
+ fixjump(fs, list, dtarget); /* jump to default target */
list = next;
}
}
static void dischargejpc (FuncState *fs) {
- patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc, NO_REG, fs->pc);
+ patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
fs->jpc = NO_JUMP;
}
@@ -153,7 +159,7 @@ void luaK_patchlist (FuncState *fs, int list, int target) {
luaK_patchtohere(fs, list);
else {
lua_assert(target < fs->pc);
- patchlistaux(fs, list, target, NO_REG, target, NO_REG, target);
+ patchlistaux(fs, list, target, NO_REG, target);
}
}
@@ -223,7 +229,7 @@ static int addk (FuncState *fs, TValue *k, TValue *v) {
MAXARG_Bx, "constant table overflow");
while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
setobj(L, &f->k[fs->nk], v);
- luaC_barriert(L, f, v);
+ luaC_barrier(L, f, v);
return fs->nk++;
}
}
@@ -373,7 +379,7 @@ static void exp2reg (FuncState *fs, expdesc *e, int reg) {
int final; /* position after whole expression */
int p_f = NO_JUMP; /* position of an eventual LOAD false */
int p_t = NO_JUMP; /* position of an eventual LOAD true */
- if (need_value(fs, e->t, 1) || need_value(fs, e->f, 0)) {
+ if (need_value(fs, e->t) || need_value(fs, e->f)) {
int fj = NO_JUMP; /* first jump (over LOAD ops.) */
if (e->k != VJMP)
fj = luaK_jump(fs);
@@ -382,8 +388,8 @@ static void exp2reg (FuncState *fs, expdesc *e, int reg) {
luaK_patchtohere(fs, fj);
}
final = luaK_getlabel(fs);
- patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f);
- patchlistaux(fs, e->t, final, reg, p_t, NO_REG, p_t);
+ patchlistaux(fs, e->f, final, reg, p_f);
+ patchlistaux(fs, e->t, final, reg, p_t);
}
e->f = e->t = NO_JUMP;
e->info = reg;
@@ -492,7 +498,8 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
static void invertjump (FuncState *fs, expdesc *e) {
Instruction *pc = getjumpcontrol(fs, e->info);
- lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TEST);
+ lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
+ GET_OPCODE(*pc) != OP_TEST);
SETARG_A(*pc, !(GETARG_A(*pc)));
}
@@ -502,13 +509,13 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) {
Instruction ie = getcode(fs, e);
if (GET_OPCODE(ie) == OP_NOT) {
fs->pc--; /* remove previous OP_NOT */
- return condjump(fs, OP_TEST, NO_REG, GETARG_B(ie), !cond);
+ return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
}
/* else go through */
}
discharge2anyreg(fs, e);
freeexp(fs, e);
- return condjump(fs, OP_TEST, NO_REG, e->info, cond);
+ return condjump(fs, OP_TESTSET, NO_REG, e->info, cond);
}
@@ -535,6 +542,8 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) {
}
}
luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
+ luaK_patchtohere(fs, e->t);
+ e->t = NO_JUMP;
}
@@ -560,6 +569,8 @@ void luaK_goiffalse (FuncState *fs, expdesc *e) {
}
}
luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
+ luaK_patchtohere(fs, e->f);
+ e->f = NO_JUMP;
}
@@ -593,6 +604,8 @@ static void codenot (FuncState *fs, expdesc *e) {
}
/* interchange true and false lists */
{ int temp = e->f; e->f = e->t; e->t = temp; }
+ removevalues(fs, e->f);
+ removevalues(fs, e->t);
}
@@ -607,7 +620,7 @@ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
case OPR_MINUS: {
luaK_exp2val(fs, e);
if (e->k == VK && ttisnumber(&fs->f->k[e->info]))
- e->info = luaK_numberK(fs, luai_numunm(nvalue(&fs->f->k[e->info])));
+ e->info = luaK_numberK(fs, luai_numunm(L, nvalue(&fs->f->k[e->info])));
else {
luaK_exp2anyreg(fs, e);
freeexp(fs, e);
@@ -620,10 +633,10 @@ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
codenot(fs, e);
break;
}
- case OPR_SIZE: {
+ case OPR_LEN: {
luaK_exp2anyreg(fs, e);
freeexp(fs, e);
- e->info = luaK_codeABC(fs, OP_SIZ, 0, e->info, 0);
+ e->info = luaK_codeABC(fs, OP_LEN, 0, e->info, 0);
e->k = VRELOCABLE;
break;
}
@@ -636,14 +649,10 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
switch (op) {
case OPR_AND: {
luaK_goiftrue(fs, v);
- luaK_patchtohere(fs, v->t);
- v->t = NO_JUMP;
break;
}
case OPR_OR: {
luaK_goiffalse(fs, v);
- luaK_patchtohere(fs, v->f);
- v->f = NO_JUMP;
break;
}
case OPR_CONCAT: {
diff --git a/src/lcode.h b/src/lcode.h
index 19a3284e..ed1a95bc 100644
--- a/src/lcode.h
+++ b/src/lcode.h
@@ -1,5 +1,5 @@
/*
-** $Id: lcode.h,v 1.43 2005/04/25 19:24:10 roberto Exp $
+** $Id: lcode.h,v 1.45 2005/08/29 20:49:21 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -34,7 +34,7 @@ typedef enum BinOpr {
#define binopistest(op) ((op) >= OPR_NE)
-typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_SIZE, OPR_NOUNOPR } UnOpr;
+typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
#define getcode(fs,e) ((fs)->f->code[(e)->info])
@@ -65,6 +65,7 @@ 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);
LUAI_FUNC int luaK_jump (FuncState *fs);
+LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
diff --git a/src/ldblib.c b/src/ldblib.c
index 6c1a1776..e7458634 100644
--- a/src/ldblib.c
+++ b/src/ldblib.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldblib.c,v 1.98 2005/05/17 19:49:15 roberto Exp $
+** $Id: ldblib.c,v 1.101 2005/08/26 17:36:32 roberto Exp $
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/
@@ -365,26 +365,26 @@ static int db_errorfb (lua_State *L) {
}
-static const luaL_reg dblib[] = {
- {"getmetatable", db_getmetatable},
- {"setmetatable", db_setmetatable},
+static const luaL_Reg dblib[] = {
+ {"debug", db_debug},
{"getfenv", db_getfenv},
- {"setfenv", db_setfenv},
- {"getlocal", db_getlocal},
- {"getinfo", db_getinfo},
{"gethook", db_gethook},
+ {"getinfo", db_getinfo},
+ {"getlocal", db_getlocal},
+ {"getmetatable", db_getmetatable},
{"getupvalue", db_getupvalue},
+ {"setfenv", db_setfenv},
{"sethook", db_sethook},
{"setlocal", db_setlocal},
+ {"setmetatable", db_setmetatable},
{"setupvalue", db_setupvalue},
- {"debug", db_debug},
{"traceback", db_errorfb},
{NULL, NULL}
};
LUALIB_API int luaopen_debug (lua_State *L) {
- luaL_openlib(L, LUA_DBLIBNAME, dblib, 0);
+ luaL_register(L, LUA_DBLIBNAME, dblib);
return 1;
}
diff --git a/src/ldebug.c b/src/ldebug.c
index 73a604ff..11166c0a 100644
--- a/src/ldebug.c
+++ b/src/ldebug.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldebug.c,v 2.20 2005/05/17 19:49:15 roberto Exp $
+** $Id: ldebug.c,v 2.26 2005/08/04 13:37:38 roberto Exp $
** Debug Interface
** See Copyright Notice in lua.h
*/
@@ -92,7 +92,7 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
}
if (level == 0 && ci > L->base_ci) { /* level found? */
status = 1;
- ar->i_ci = ci - L->base_ci;
+ ar->i_ci = cast(int, ci - L->base_ci);
}
else if (level < 0) { /* level is of a lost tail call? */
status = 1;
@@ -152,6 +152,7 @@ static void funcinfo (lua_Debug *ar, Closure *cl) {
if (cl->c.isC) {
ar->source = "=[C]";
ar->linedefined = -1;
+ ar->lastlinedefined = -1;
ar->what = "C";
}
else {
@@ -164,7 +165,7 @@ static void funcinfo (lua_Debug *ar, Closure *cl) {
}
-static void info_tailcall (lua_State *L, lua_Debug *ar) {
+static void info_tailcall (lua_Debug *ar) {
ar->name = ar->namewhat = "";
ar->what = "tail";
ar->lastlinedefined = ar->linedefined = ar->currentline = -1;
@@ -194,7 +195,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
Closure *f, CallInfo *ci) {
int status = 1;
if (f == NULL) {
- info_tailcall(L, ar);
+ info_tailcall(ar);
return status;
}
for (; *what; what++) {
@@ -275,8 +276,11 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
static int precheck (const Proto *pt) {
check(pt->maxstacksize <= MAXSTACK);
+ lua_assert(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize);
+ lua_assert(!(pt->is_vararg & VARARG_NEEDSARG) ||
+ (pt->is_vararg & VARARG_HASARG));
+ check(pt->sizeupvalues <= pt->nups);
check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0);
- lua_assert(pt->numparams+pt->is_vararg <= pt->maxstacksize);
check(GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN);
return 1;
}
@@ -389,8 +393,8 @@ static Instruction symbexec (const Proto *pt, int lastpc, int reg) {
}
case OP_TFORLOOP: {
check(c >= 1); /* at least one result (control variable) */
- checkreg(pt, a+3+c); /* space for results */
- if (reg >= a+3) last = pc; /* affect all regs above its call base */
+ checkreg(pt, a+2+c); /* space for results */
+ if (reg >= a+2) last = pc; /* affect all regs above its base */
break;
}
case OP_FORLOOP:
@@ -440,7 +444,8 @@ static Instruction symbexec (const Proto *pt, int lastpc, int reg) {
break;
}
case OP_VARARG: {
- check(pt->is_vararg & NEWSTYLEVARARG);
+ check((pt->is_vararg & VARARG_ISVARARG) &&
+ !(pt->is_vararg & VARARG_NEEDSARG));
b--;
if (b == LUA_MULTRET) check(checkopenop(pt, pc));
checkreg(pt, a+b-1);
@@ -546,7 +551,8 @@ void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
const char *name = NULL;
const char *t = luaT_typenames[ttype(o)];
const char *kind = (isinstack(L->ci, o)) ?
- getobjname(L, L->ci, o - L->base, &name) : NULL;
+ getobjname(L, L->ci, cast(int, o - L->base), &name) :
+ NULL;
if (kind)
luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
op, kind, name, t);
diff --git a/src/ldo.c b/src/ldo.c
index 09e0a44d..d7645835 100644
--- a/src/ldo.c
+++ b/src/ldo.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldo.c,v 2.23 2005/05/03 19:01:17 roberto Exp $
+** $Id: ldo.c,v 2.33 2005/09/09 18:16:28 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -48,7 +48,7 @@ struct lua_longjmp {
};
-static void seterrorobj (lua_State *L, int errcode, StkId oldtop) {
+void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) {
switch (errcode) {
case LUA_ERRMEM: {
setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG));
@@ -68,14 +68,41 @@ static void seterrorobj (lua_State *L, int errcode, StkId oldtop) {
}
+static void restore_stack_limit (lua_State *L) {
+ lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
+ if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */
+ int inuse = cast(int, L->ci - L->base_ci);
+ if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */
+ luaD_reallocCI(L, LUAI_MAXCALLS);
+ }
+}
+
+
+static void resetstack (lua_State *L, int status) {
+ L->ci = L->base_ci;
+ L->base = L->ci->base;
+ luaF_close(L, L->base); /* close eventual pending closures */
+ luaD_seterrorobj(L, status, L->base);
+ L->nCcalls = 0;
+ L->allowhook = 1;
+ restore_stack_limit(L);
+ L->errfunc = 0;
+ L->errorJmp = NULL;
+}
+
+
void luaD_throw (lua_State *L, int errcode) {
if (L->errorJmp) {
L->errorJmp->status = errcode;
LUAI_THROW(L, L->errorJmp);
}
else {
- L->status = errcode;
- if (G(L)->panic) G(L)->panic(L);
+ L->status = cast(lu_byte, errcode);
+ if (G(L)->panic) {
+ resetstack(L, errcode);
+ lua_unlock(L);
+ G(L)->panic(L);
+ }
exit(EXIT_FAILURE);
}
}
@@ -93,16 +120,6 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
return lj.status;
}
-
-static void restore_stack_limit (lua_State *L) {
- lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
- if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */
- int inuse = (L->ci - L->base_ci);
- if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */
- luaD_reallocCI(L, LUAI_MAXCALLS);
- }
-}
-
/* }====================================================== */
@@ -116,9 +133,8 @@ static void correctstack (lua_State *L, TValue *oldstack) {
ci->top = (ci->top - oldstack) + L->stack;
ci->base = (ci->base - oldstack) + L->stack;
ci->func = (ci->func - oldstack) + L->stack;
- lua_assert(lua_checkpc(L, ci));
}
- L->base = L->ci->base;
+ L->base = (L->base - oldstack) + L->stack;
}
@@ -173,7 +189,7 @@ void luaD_callhook (lua_State *L, int event, int line) {
if (event == LUA_HOOKTAILRET)
ar.i_ci = 0; /* tail call; no debug information about it */
else
- ar.i_ci = L->ci - L->base_ci;
+ ar.i_ci = cast(int, L->ci - L->base_ci);
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
L->ci->top = L->top + LUA_MINSTACK;
lua_assert(L->ci->top <= L->stack_last);
@@ -189,18 +205,17 @@ void luaD_callhook (lua_State *L, int event, int line) {
}
-static StkId adjust_varargs (lua_State *L, int nfixargs, int actual,
- int style) {
+static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
int i;
+ int nfixargs = p->numparams;
Table *htab = NULL;
StkId base, fixed;
- if (actual < nfixargs) {
- for (; actual < nfixargs; ++actual)
- setnilvalue(L->top++);
- }
-#if LUA_COMPAT_VARARG
- if (style != NEWSTYLEVARARG) { /* compatibility with old-style vararg */
+ for (; actual < nfixargs; ++actual)
+ setnilvalue(L->top++);
+#if defined(LUA_COMPAT_VARARG)
+ if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */
int nvar = actual - nfixargs; /* number of extra arguments */
+ lua_assert(p->is_vararg & VARARG_HASARG);
luaC_checkGC(L);
htab = luaH_new(L, nvar, 1); /* create `arg' table */
for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */
@@ -259,16 +274,14 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
CallInfo *ci;
StkId st, base;
Proto *p = cl->p;
- if (p->is_vararg) { /* varargs? */
- int nargs = L->top - restorestack(L, funcr) - 1;
- luaD_checkstack(L, p->maxstacksize + nargs);
- base = adjust_varargs(L, p->numparams, nargs, p->is_vararg);
- func = restorestack(L, funcr);
- }
- else {
- luaD_checkstack(L, p->maxstacksize);
- func = restorestack(L, funcr);
+ luaD_checkstack(L, p->maxstacksize);
+ func = restorestack(L, funcr);
+ if (!p->is_vararg) /* no varargs? */
base = func + 1;
+ else { /* vararg function */
+ int nargs = cast(int, L->top - func) - 1;
+ base = adjust_varargs(L, p, nargs);
+ func = restorestack(L, funcr); /* previous call may change the stack */
}
ci = inc_ci(L); /* now `enter' new function */
ci->func = func;
@@ -281,6 +294,11 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
for (st = L->top; st < ci->top; st++)
setnilvalue(st);
L->top = ci->top;
+ if (L->hookmask & LUA_MASKCALL) {
+ L->savedpc++; /* hooks assume 'pc' is already incremented */
+ luaD_callhook(L, LUA_HOOKCALL, -1);
+ L->savedpc--; /* correct 'pc' */
+ }
return PCRLUA;
}
else { /* if is a C function, call it */
@@ -292,13 +310,14 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
L->base = ci->base = ci->func + 1;
ci->top = L->top + LUA_MINSTACK;
lua_assert(ci->top <= L->stack_last);
+ ci->nresults = nresults;
if (L->hookmask & LUA_MASKCALL)
luaD_callhook(L, LUA_HOOKCALL, -1);
lua_unlock(L);
n = (*curr_func(L)->c.f)(L); /* do the actual call */
lua_lock(L);
if (n >= 0) { /* no yielding? */
- luaD_poscall(L, nresults, L->top - n);
+ luaD_poscall(L, L->top - n);
return PCRC;
}
else {
@@ -320,22 +339,24 @@ static StkId callrethooks (lua_State *L, StkId firstResult) {
}
-void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
+int luaD_poscall (lua_State *L, StkId firstResult) {
StkId res;
+ int wanted, i;
+ CallInfo *ci;
if (L->hookmask & LUA_MASKRET)
firstResult = callrethooks(L, firstResult);
- res = L->ci->func; /* res == final position of 1st result */
- L->ci--;
- L->base = L->ci->base; /* restore base */
- L->savedpc = L->ci->savedpc; /* restore savedpc */
+ ci = L->ci--;
+ res = ci->func; /* res == final position of 1st result */
+ wanted = ci->nresults;
+ L->base = (ci - 1)->base; /* restore base */
+ L->savedpc = (ci - 1)->savedpc; /* restore savedpc */
/* move results to correct place */
- while (wanted != 0 && firstResult < L->top) {
+ for (i = wanted; i != 0 && firstResult < L->top; i--)
setobjs2s(L, res++, firstResult++);
- wanted--;
- }
- while (wanted-- > 0)
+ while (i-- > 0)
setnilvalue(res++);
L->top = res;
+ return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */
}
@@ -352,38 +373,34 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
}
- if (luaD_precall(L, func, nResults) == PCRLUA) { /* is a Lua function? */
- StkId firstResult = luaV_execute(L, 1); /* call it */
- luaD_poscall(L, nResults, firstResult);
- }
+ if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */
+ luaV_execute(L, 1); /* call it */
L->nCcalls--;
luaC_checkGC(L);
}
static void resume (lua_State *L, void *ud) {
- StkId firstResult;
- int nargs = *cast(int *, ud);
+ StkId firstArg = cast(StkId, ud);
CallInfo *ci = L->ci;
- if (L->status != LUA_YIELD) {
- lua_assert(ci == L->base_ci && nargs < L->top - L->base);
- luaD_precall(L, L->top - (nargs + 1), LUA_MULTRET); /* start coroutine */
+ if (L->status != LUA_YIELD) { /* start coroutine */
+ lua_assert(ci == L->base_ci && firstArg > L->base);
+ if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA)
+ return;
}
else { /* resuming from previous yield */
if (!f_isLua(ci)) { /* `common' yield? */
/* finish interrupted execution of `OP_CALL' */
- int nresults = ci->nresults;
lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL);
- luaD_poscall(L, nresults, L->top - nargs); /* complete it */
- if (nresults >= 0) L->top = L->ci->top;
- } /* else yielded inside a hook: just continue its execution */
+ if (luaD_poscall(L, firstArg)) /* complete it... */
+ L->top = L->ci->top; /* and correct top if not multiple results */
+ }
+ else /* yielded inside a hook: just continue its execution */
+ L->base = L->ci->base;
}
L->status = 0;
- firstResult = luaV_execute(L, L->ci - L->base_ci);
- if (firstResult != NULL) { /* return? */
- luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */
- }
+ luaV_execute(L, cast(int, L->ci - L->base_ci));
}
@@ -399,17 +416,18 @@ static int resume_error (lua_State *L, const char *msg) {
LUA_API int lua_resume (lua_State *L, int nargs) {
int status;
lua_lock(L);
- lua_assert(L->errfunc == 0 && L->nCcalls == 0);
if (L->status != LUA_YIELD) {
if (L->status != 0)
return resume_error(L, "cannot resume dead coroutine");
else if (L->ci != L->base_ci)
return resume_error(L, "cannot resume non-suspended coroutine");
}
- status = luaD_rawrunprotected(L, resume, &nargs);
+ luai_userstateresume(L, nargs);
+ lua_assert(L->errfunc == 0 && L->nCcalls == 0);
+ status = luaD_rawrunprotected(L, resume, L->top - nargs);
if (status != 0) { /* error? */
- L->status = status; /* mark thread as `dead' */
- seterrorobj(L, status, L->top);
+ L->status = cast(lu_byte, status); /* mark thread as `dead' */
+ luaD_seterrorobj(L, status, L->top);
}
else
status = L->status;
@@ -419,19 +437,11 @@ LUA_API int lua_resume (lua_State *L, int nargs) {
LUA_API int lua_yield (lua_State *L, int nresults) {
- CallInfo *ci;
+ luai_userstateyield(L, nresults);
lua_lock(L);
- ci = L->ci;
if (L->nCcalls > 0)
luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
- if (!f_isLua(ci)) { /* usual yield */
- if (L->top - nresults > L->base) { /* is there garbage in the stack? */
- int i;
- for (i=0; i<nresults; i++) /* move down results */
- setobjs2s(L, L->base + i, L->top - nresults + i);
- L->top = L->base + nresults;
- }
- } /* else it's an yield inside a hook: nothing to do */
+ L->base = L->top - nresults; /* protect stack slots below */
L->status = LUA_YIELD;
lua_unlock(L);
return -1;
@@ -441,7 +451,7 @@ LUA_API int lua_yield (lua_State *L, int nresults) {
int luaD_pcall (lua_State *L, Pfunc func, void *u,
ptrdiff_t old_top, ptrdiff_t ef) {
int status;
- int oldnCcalls = L->nCcalls;
+ unsigned short oldnCcalls = L->nCcalls;
ptrdiff_t old_ci = saveci(L, L->ci);
lu_byte old_allowhooks = L->allowhook;
ptrdiff_t old_errfunc = L->errfunc;
@@ -450,7 +460,7 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u,
if (status != 0) { /* an error occurred? */
StkId oldtop = restorestack(L, old_top);
luaF_close(L, oldtop); /* close eventual pending closures */
- seterrorobj(L, status, oldtop);
+ luaD_seterrorobj(L, status, oldtop);
L->nCcalls = oldnCcalls;
L->ci = restoreci(L, old_ci);
L->base = L->ci->base;
diff --git a/src/ldo.h b/src/ldo.h
index b355b7e8..b2de92bb 100644
--- a/src/ldo.h
+++ b/src/ldo.h
@@ -1,5 +1,5 @@
/*
-** $Id: ldo.h,v 2.4 2005/04/25 19:24:10 roberto Exp $
+** $Id: ldo.h,v 2.7 2005/08/24 16:15:49 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -13,16 +13,6 @@
#include "lzio.h"
-/*
-** macro to control inclusion of some hard tests on stack reallocation
-*/
-#ifndef HARDSTACKTESTS
-#define condhardstacktests(x) ((void)0)
-#else
-#define condhardstacktests(x) x
-#endif
-
-
#define luaD_checkstack(L,n) \
if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \
luaD_growstack(L, n); \
@@ -53,7 +43,7 @@ LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
ptrdiff_t oldtop, ptrdiff_t ef);
-LUAI_FUNC void luaD_poscall (lua_State *L, int wanted, StkId firstResult);
+LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize);
LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
LUAI_FUNC void luaD_growstack (lua_State *L, int n);
@@ -61,6 +51,7 @@ LUAI_FUNC void luaD_growstack (lua_State *L, int n);
LUAI_FUNC void luaD_throw (lua_State *L, int errcode);
LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
+LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop);
#endif
diff --git a/src/ldump.c b/src/ldump.c
index 0c9f00d1..e580047b 100644
--- a/src/ldump.c
+++ b/src/ldump.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldump.c,v 1.10 2005/05/12 00:26:50 lhf Exp $
+** $Id: ldump.c,v 1.12 2005/06/08 14:40:44 lhf Exp $
** save pre-compiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -16,17 +16,20 @@
#include "lstate.h"
#include "lundump.h"
-#define DumpVector(b,n,size,D) DumpBlock(b,(n)*(size),D)
-#define DumpLiteral(s,D) DumpBlock("" s,(sizeof(s))-1,D)
-
typedef struct {
lua_State* L;
- lua_Chunkwriter writer;
+ lua_Writer writer;
void* data;
int strip;
int status;
} DumpState;
+#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D)
+#define DumpLines(f,D) DumpVector(f->lineinfo,f->sizelineinfo,sizeof(int),D)
+#define DumpLiteral(s,D) DumpBlock("" s,(sizeof(s))-1,D)
+#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D)
+#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D)
+
static void DumpBlock(const void* b, size_t size, DumpState* D)
{
if (D->status==0)
@@ -37,45 +40,43 @@ static void DumpBlock(const void* b, size_t size, DumpState* D)
}
}
-static void DumpByte(int y, DumpState* D)
+static void DumpChar(int y, DumpState* D)
{
char x=(char)y;
- DumpBlock(&x,sizeof(x),D);
+ DumpVar(x,D);
}
static void DumpInt(int x, DumpState* D)
{
- DumpBlock(&x,sizeof(x),D);
+ DumpVar(x,D);
}
-static void DumpSize(size_t x, DumpState* D)
+static void DumpNumber(lua_Number x, DumpState* D)
{
- DumpBlock(&x,sizeof(x),D);
+ DumpVar(x,D);
}
-static void DumpNumber(lua_Number x, DumpState* D)
+static void DumpVector(const void* b, int n, size_t size, DumpState* D)
{
- DumpBlock(&x,sizeof(x),D);
+ DumpInt(n,D);
+ DumpMem(b,n,size,D);
}
static void DumpString(const TString* s, DumpState* D)
{
if (s==NULL || getstr(s)==NULL)
- DumpSize(0,D);
+ {
+ size_t size=0;
+ DumpVar(size,D);
+ }
else
{
size_t size=s->tsv.len+1; /* include trailing '\0' */
- DumpSize(size,D);
+ DumpVar(size,D);
DumpBlock(getstr(s),size,D);
}
}
-static void DumpCode(const Proto* f, DumpState* D)
-{
- DumpInt(f->sizecode,D);
- DumpVector(f->code,f->sizecode,sizeof(*f->code),D);
-}
-
static void DumpLocals(const Proto* f, DumpState* D)
{
int i,n=f->sizelocvars;
@@ -88,12 +89,6 @@ static void DumpLocals(const Proto* f, DumpState* D)
}
}
-static void DumpLines(const Proto* f, DumpState* D)
-{
- DumpInt(f->sizelineinfo,D);
- DumpVector(f->lineinfo,f->sizelineinfo,sizeof(*f->lineinfo),D);
-}
-
static void DumpUpvalues(const Proto* f, DumpState* D)
{
int i,n=f->sizeupvalues;
@@ -105,18 +100,18 @@ static void DumpFunction(const Proto* f, const TString* p, DumpState* D);
static void DumpConstants(const Proto* f, DumpState* D)
{
- int i,n;
- DumpInt(n=f->sizek,D);
+ int i,n=f->sizek;
+ DumpInt(n,D);
for (i=0; i<n; i++)
{
const TValue* o=&f->k[i];
- DumpByte(ttype(o),D);
+ DumpChar(ttype(o),D);
switch (ttype(o))
{
case LUA_TNIL:
break;
case LUA_TBOOLEAN:
- DumpByte(bvalue(o),D);
+ DumpChar(bvalue(o),D);
break;
case LUA_TNUMBER:
DumpNumber(nvalue(o),D);
@@ -129,7 +124,8 @@ static void DumpConstants(const Proto* f, DumpState* D)
break;
}
}
- DumpInt(n=f->sizep,D);
+ n=f->sizep;
+ DumpInt(n,D);
for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
}
@@ -138,10 +134,10 @@ static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
DumpString((f->source==p) ? NULL : f->source,D);
DumpInt(f->linedefined,D);
DumpInt(f->lastlinedefined,D);
- DumpByte(f->nups,D);
- DumpByte(f->numparams,D);
- DumpByte(f->is_vararg,D);
- DumpByte(f->maxstacksize,D);
+ DumpChar(f->nups,D);
+ DumpChar(f->numparams,D);
+ DumpChar(f->is_vararg,D);
+ DumpChar(f->maxstacksize,D);
if (D->strip) DumpInt(0,D); else DumpLines(f,D);
if (D->strip) DumpInt(0,D); else DumpLocals(f,D);
if (D->strip) DumpInt(0,D); else DumpUpvalues(f,D);
@@ -151,20 +147,15 @@ static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
static void DumpHeader(DumpState* D)
{
- DumpLiteral(LUA_SIGNATURE,D);
- DumpByte(VERSION,D);
- DumpByte(luaU_endianness(),D);
- DumpByte(sizeof(int),D);
- DumpByte(sizeof(size_t),D);
- DumpByte(sizeof(Instruction),D);
- DumpByte(sizeof(lua_Number),D);
- DumpNumber(TEST_NUMBER,D);
+ char h[LUAC_HEADERSIZE];
+ luaU_header(h);
+ DumpBlock(h,LUAC_HEADERSIZE,D);
}
/*
** dump Lua function as precompiled chunk
*/
-int luaU_dump (lua_State* L, const Proto* f, lua_Chunkwriter w, void* data, int strip)
+int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)
{
DumpState D;
D.L=L;
diff --git a/src/lgc.c b/src/lgc.c
index 9257d2bc..0f30104f 100644
--- a/src/lgc.c
+++ b/src/lgc.c
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.c,v 2.32 2005/05/05 15:34:03 roberto Exp $
+** $Id: lgc.c,v 2.36 2005/08/24 17:06:36 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -240,8 +240,8 @@ static void traverseclosure (global_State *g, Closure *cl) {
static void checkstacksizes (lua_State *L, StkId max) {
- int ci_used = L->ci - L->base_ci; /* number of `ci' in use */
- int s_used = max - L->stack; /* part of stack in use */
+ int ci_used = cast(int, L->ci - L->base_ci); /* number of `ci' in use */
+ int s_used = cast(int, max - L->stack); /* part of stack in use */
if (L->size_ci > LUAI_MAXCALLS) /* handling overflow? */
return; /* do not touch the stacks */
if (4*ci_used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci)
@@ -287,7 +287,6 @@ static l_mem propagatemark (global_State *g) {
black2gray(o); /* keep it gray */
return sizeof(Table) + sizeof(TValue) * h->sizearray +
sizeof(Node) * sizenode(h);
- break;
}
case LUA_TFUNCTION: {
Closure *cl = gco2cl(o);
@@ -295,7 +294,6 @@ static l_mem propagatemark (global_State *g) {
traverseclosure(g, cl);
return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) :
sizeLclosure(cl->l.nupvalues);
- break;
}
case LUA_TTHREAD: {
lua_State *th = gco2th(o);
@@ -306,7 +304,6 @@ static l_mem propagatemark (global_State *g) {
traversestack(g, th);
return sizeof(lua_State) + sizeof(TValue) * th->stacksize +
sizeof(CallInfo) * th->size_ci;
- break;
}
case LUA_TPROTO: {
Proto *p = gco2p(o);
@@ -318,7 +315,6 @@ static l_mem propagatemark (global_State *g) {
sizeof(int) * p->sizelineinfo +
sizeof(LocVar) * p->sizelocvars +
sizeof(TString *) * p->sizeupvalues;
- break;
}
default: lua_assert(0); return 0;
}
@@ -528,10 +524,10 @@ static void remarkupvals (global_State *g) {
static void atomic (lua_State *L) {
global_State *g = G(L);
size_t udsize; /* total size of userdata to be finalized */
- /* remark objects cautch by write barrier */
- propagateall(g);
/* remark occasional upvalues of (maybe) dead threads */
remarkupvals(g);
+ /* traverse objects cautch by write barrier and by 'remarkupvals' */
+ propagateall(g);
/* remark weak tables */
g->gray = g->weak;
g->weak = NULL;
@@ -673,12 +669,13 @@ void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
}
-void luaC_barrierback (lua_State *L, GCObject *o) {
+void luaC_barrierback (lua_State *L, Table *t) {
global_State *g = G(L);
+ GCObject *o = obj2gco(t);
lua_assert(isblack(o) && !isdead(g, o));
lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
black2gray(o); /* make table gray (again) */
- gco2h(o)->gclist = g->grayagain;
+ t->gclist = g->grayagain;
g->grayagain = o;
}
diff --git a/src/lgc.h b/src/lgc.h
index 4fc4a81e..5f69acb1 100644
--- a/src/lgc.h
+++ b/src/lgc.h
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.h,v 2.13 2005/04/25 19:24:10 roberto Exp $
+** $Id: lgc.h,v 2.15 2005/08/24 16:15:49 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -77,23 +77,24 @@
#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
-#define luaC_checkGC(L) { if (G(L)->totalbytes >= G(L)->GCthreshold) \
+#define luaC_checkGC(L) { \
+ condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \
+ if (G(L)->totalbytes >= G(L)->GCthreshold) \
luaC_step(L); }
#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \
luaC_barrierf(L,obj2gco(p),gcvalue(v)); }
-#define luaC_barriert(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \
- luaC_barrierback(L,obj2gco(p)); }
+#define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \
+ luaC_barrierback(L,t); }
#define luaC_objbarrier(L,p,o) \
{ if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
luaC_barrierf(L,obj2gco(p),obj2gco(o)); }
-#define luaC_objbarriert(L,p,o) \
- { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
- luaC_barrierback(L,obj2gco(p)); }
+#define luaC_objbarriert(L,t,o) \
+ { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); }
LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all);
LUAI_FUNC void luaC_callGCTM (lua_State *L);
@@ -103,7 +104,7 @@ LUAI_FUNC void luaC_fullgc (lua_State *L);
LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv);
LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v);
-LUAI_FUNC void luaC_barrierback (lua_State *L, GCObject *o);
+LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t);
#endif
diff --git a/src/linit.c b/src/linit.c
index afcd338b..d30ff1e3 100644
--- a/src/linit.c
+++ b/src/linit.c
@@ -1,5 +1,5 @@
/*
-** $Id: linit.c,v 1.11 2005/04/13 17:24:20 roberto Exp $
+** $Id: linit.c,v 1.13 2005/08/26 17:36:32 roberto Exp $
** Initialization of libraries for lua.c
** See Copyright Notice in lua.h
*/
@@ -14,7 +14,7 @@
#include "lauxlib.h"
-static const luaL_reg lualibs[] = {
+static const luaL_Reg lualibs[] = {
{"", luaopen_base},
{LUA_TABLIBNAME, luaopen_table},
{LUA_IOLIBNAME, luaopen_io},
@@ -22,13 +22,13 @@ static const luaL_reg lualibs[] = {
{LUA_STRLIBNAME, luaopen_string},
{LUA_MATHLIBNAME, luaopen_math},
{LUA_DBLIBNAME, luaopen_debug},
- {LUA_LOADLIBNAME, luaopen_loadlib},
+ {LUA_LOADLIBNAME, luaopen_package},
{NULL, NULL}
};
LUALIB_API void luaL_openlibs (lua_State *L) {
- const luaL_reg *lib = lualibs;
+ const luaL_Reg *lib = lualibs;
for (; lib->func; lib++) {
lua_pushcfunction(L, lib->func);
lua_pushstring(L, lib->name);
diff --git a/src/liolib.c b/src/liolib.c
index 1dba7eff..a7f8743f 100644
--- a/src/liolib.c
+++ b/src/liolib.c
@@ -1,5 +1,5 @@
/*
-** $Id: liolib.c,v 2.60 2005/05/16 21:19:00 roberto Exp $
+** $Id: liolib.c,v 2.67 2005/08/26 17:36:32 roberto Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@@ -20,8 +20,8 @@
-#define IO_INPUT 1
-#define IO_OUTPUT 2
+#define IO_INPUT 1
+#define IO_OUTPUT 2
static const char *const fnames[] = {"input", "output"};
@@ -50,17 +50,17 @@ static void fileerror (lua_State *L, int arg, const char *filename) {
}
-static FILE **topfile (lua_State *L) {
- FILE **f = (FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE);
- if (f == NULL) luaL_argerror(L, 1, "bad file");
- return f;
-}
+#define topfile(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE))
static int io_type (lua_State *L) {
- FILE **f = (FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE);
- if (f == NULL) lua_pushnil(L);
- else if (*f == NULL)
+ void *ud;
+ luaL_checkany(L, 1);
+ ud = lua_touserdata(L, 1);
+ lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
+ if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1))
+ lua_pushnil(L); /* not a file */
+ else if (*((FILE **)ud) == NULL)
lua_pushliteral(L, "closed file");
else
lua_pushliteral(L, "file");
@@ -91,29 +91,45 @@ static FILE **newfile (lua_State *L) {
}
+/*
+** this function has a separated environment, which defines the
+** correct __close for 'popen' files
+*/
+static int io_pclose (lua_State *L) {
+ FILE **p = topfile(L);
+ int ok = lua_pclose(L, *p);
+ if (ok) *p = NULL;
+ return pushresult(L, ok, NULL);
+}
+
+
+static int io_fclose (lua_State *L) {
+ FILE **p = topfile(L);
+ int ok = (fclose(*p) == 0);
+ if (ok) *p = NULL;
+ return pushresult(L, ok, NULL);
+}
+
+
static int aux_close (lua_State *L) {
- FILE *f = tofile(L);
- if (f == stdin || f == stdout || f == stderr)
- return 0; /* file cannot be closed */
- else {
- int ok = (fclose(f) == 0);
- if (ok)
- *(FILE **)lua_touserdata(L, 1) = NULL; /* mark file as closed */
- return ok;
- }
+ lua_getfenv(L, 1);
+ lua_getfield(L, -1, "__close");
+ return (lua_tocfunction(L, -1))(L);
}
static int io_close (lua_State *L) {
if (lua_isnone(L, 1))
lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT);
- return pushresult(L, aux_close(L), NULL);
+ tofile(L); /* make sure argument is a file */
+ return aux_close(L);
}
static int io_gc (lua_State *L) {
- FILE **f = topfile(L);
- if (*f != NULL) /* ignore closed files */
+ FILE *f = *topfile(L);
+ /* ignore closed files and standard files */
+ if (f != NULL && f != stdin && f != stdout && f != stderr)
aux_close(L);
return 0;
}
@@ -138,6 +154,15 @@ static int io_open (lua_State *L) {
}
+static int io_popen (lua_State *L) {
+ const char *filename = luaL_checkstring(L, 1);
+ const char *mode = luaL_optstring(L, 2, "r");
+ FILE **pf = newfile(L);
+ *pf = lua_popen(L, filename, mode);
+ return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
+}
+
+
static int io_tmpfile (lua_State *L) {
FILE **pf = newfile(L);
*pf = tmpfile();
@@ -148,7 +173,6 @@ static int io_tmpfile (lua_State *L) {
static FILE *getiofile (lua_State *L, int findex) {
FILE *f;
lua_rawgeti(L, LUA_ENVIRONINDEX, findex);
- lua_assert(luaL_checkudata(L, -1, LUA_FILEHANDLE));
f = *(FILE **)lua_touserdata(L, -1);
if (f == NULL)
luaL_error(L, "standard %s file is closed", fnames[findex - 1]);
@@ -169,7 +193,6 @@ static int g_iofile (lua_State *L, int f, const char *mode) {
tofile(L); /* check that it's a valid file handle */
lua_pushvalue(L, 1);
}
- lua_assert(luaL_checkudata(L, -1, LUA_FILEHANDLE));
lua_rawseti(L, LUA_ENVIRONINDEX, f);
}
/* return current value */
@@ -352,7 +375,7 @@ static int io_readline (lua_State *L) {
luaL_error(L, "file is already closed");
sucess = read_line(L, f);
if (ferror(f))
- luaL_error(L, "%s", strerror(errno));
+ return luaL_error(L, "%s", strerror(errno));
if (sucess) return 1;
else { /* EOF */
if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */
@@ -400,9 +423,8 @@ static int f_seek (lua_State *L) {
static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
static const char *const modenames[] = {"set", "cur", "end", NULL};
FILE *f = tofile(L);
- int op = luaL_findstring(luaL_optstring(L, 2, "cur"), modenames);
+ int op = luaL_checkoption(L, 2, "cur", modenames);
lua_Integer offset = luaL_optinteger(L, 3, 0);
- luaL_argcheck(L, op != -1, 2, "invalid mode");
op = fseek(f, offset, mode[op]);
if (op)
return pushresult(L, 0, NULL); /* error */
@@ -417,9 +439,10 @@ static int f_setvbuf (lua_State *L) {
static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
static const char *const modenames[] = {"no", "full", "line", NULL};
FILE *f = tofile(L);
- int op = luaL_findstring(luaL_checkstring(L, 2), modenames);
- luaL_argcheck(L, op != -1, 2, "invalid mode");
- return pushresult(L, setvbuf(f, NULL, mode[op], 0) == 0, NULL);
+ int op = luaL_checkoption(L, 2, NULL, modenames);
+ lua_Integer sz = luaL_optinteger(L, 3, BUFSIZ);
+ int res = setvbuf(f, NULL, mode[op], sz);
+ return pushresult(L, res == 0, NULL);
}
@@ -434,13 +457,14 @@ static int f_flush (lua_State *L) {
}
-static const luaL_reg iolib[] = {
- {"input", io_input},
- {"output", io_output},
- {"lines", io_lines},
+static const luaL_Reg iolib[] = {
{"close", io_close},
{"flush", io_flush},
+ {"input", io_input},
+ {"lines", io_lines},
{"open", io_open},
+ {"output", io_output},
+ {"popen", io_popen},
{"read", io_read},
{"tmpfile", io_tmpfile},
{"type", io_type},
@@ -449,14 +473,14 @@ static const luaL_reg iolib[] = {
};
-static const luaL_reg flib[] = {
+static const luaL_Reg flib[] = {
+ {"close", io_close},
{"flush", f_flush},
- {"read", f_read},
{"lines", f_lines},
+ {"read", f_read},
{"seek", f_seek},
{"setvbuf", f_setvbuf},
{"write", f_write},
- {"close", io_close},
{"__gc", io_gc},
{"__tostring", io_tostring},
{NULL, NULL}
@@ -467,34 +491,41 @@ static void createmeta (lua_State *L) {
luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */
lua_pushvalue(L, -1); /* push metatable */
lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
- luaL_openlib(L, NULL, flib, 0); /* file methods */
+ luaL_register(L, NULL, flib); /* file methods */
}
-static void createupval (lua_State *L) {
- lua_newtable(L);
- /* create (and set) default files */
- *newfile(L) = stdin;
- lua_rawseti(L, -2, IO_INPUT);
- *newfile(L) = stdout;
- lua_rawseti(L, -2, IO_OUTPUT);
+static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
+ *newfile(L) = f;
+ if (k > 0) {
+ lua_pushvalue(L, -1);
+ lua_rawseti(L, LUA_ENVIRONINDEX, k);
+ }
+ lua_setfield(L, -2, fname);
}
-
LUALIB_API int luaopen_io (lua_State *L) {
createmeta(L);
- createupval(L);
- lua_pushvalue(L, -1);
+ /* create new (private) environment */
+ lua_newtable(L);
lua_replace(L, LUA_ENVIRONINDEX);
- luaL_openlib(L, LUA_IOLIBNAME, iolib, 0);
- /* put predefined file handles into `io' table */
- lua_rawgeti(L, -2, IO_INPUT); /* get current input from upval */
- lua_setfield(L, -2, "stdin"); /* io.stdin = upval[IO_INPUT] */
- lua_rawgeti(L, -2, IO_OUTPUT); /* get current output from upval */
- lua_setfield(L, -2, "stdout"); /* io.stdout = upval[IO_OUTPUT] */
- *newfile(L) = stderr;
- lua_setfield(L, -2, "stderr"); /* io.stderr = newfile(stderr) */
+ /* open library */
+ luaL_register(L, LUA_IOLIBNAME, iolib);
+ /* create (and set) default files */
+ createstdfile(L, stdin, IO_INPUT, "stdin");
+ createstdfile(L, stdout, IO_OUTPUT, "stdout");
+ createstdfile(L, stderr, 0, "stderr");
+ /* create environment for 'popen' */
+ lua_getfield(L, -1, "popen");
+ lua_newtable(L);
+ lua_pushcfunction(L, io_pclose);
+ lua_setfield(L, -2, "__close");
+ lua_setfenv(L, -2);
+ lua_pop(L, 1); /* pop 'popen' */
+ /* set default close function */
+ lua_pushcfunction(L, io_fclose);
+ lua_setfield(L, LUA_ENVIRONINDEX, "__close");
return 1;
}
diff --git a/src/llex.h b/src/llex.h
index 8bff8f43..08a0b254 100644
--- a/src/llex.h
+++ b/src/llex.h
@@ -1,5 +1,5 @@
/*
-** $Id: llex.h,v 1.54 2005/04/25 19:24:10 roberto Exp $
+** $Id: llex.h,v 1.55 2005/06/06 13:30:25 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -37,7 +37,7 @@ enum RESERVED {
/* array with token `names' */
-extern const char *const luaX_tokens [];
+LUAI_DATA const char *const luaX_tokens [];
typedef union {
diff --git a/src/llimits.h b/src/llimits.h
index 7a536a16..68c28c8c 100644
--- a/src/llimits.h
+++ b/src/llimits.h
@@ -1,5 +1,5 @@
/*
-** $Id: llimits.h,v 1.65 2005/03/09 16:28:07 roberto Exp $
+** $Id: llimits.h,v 1.67 2005/08/24 16:15:49 roberto Exp $
** Limits, basic types, and some other `installation-dependent' definitions
** See Copyright Notice in lua.h
*/
@@ -93,4 +93,23 @@ typedef lu_int32 Instruction;
#endif
+#ifndef lua_lock
+#define lua_lock(L) ((void) 0)
+#define lua_unlock(L) ((void) 0)
+#endif
+
+#ifndef luai_threadyield
+#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);}
+#endif
+
+
+/*
+** macro to control inclusion of some hard tests on stack reallocation
+*/
+#ifndef HARDSTACKTESTS
+#define condhardstacktests(x) ((void)0)
+#else
+#define condhardstacktests(x) x
+#endif
+
#endif
diff --git a/src/lmathlib.c b/src/lmathlib.c
index bba99b0d..d181a731 100644
--- a/src/lmathlib.c
+++ b/src/lmathlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lmathlib.c,v 1.63 2005/03/04 18:57:03 roberto Exp $
+** $Id: lmathlib.c,v 1.67 2005/08/26 17:36:32 roberto Exp $
** Standard mathematical library
** See Copyright Notice in lua.h
*/
@@ -88,7 +88,7 @@ static int math_floor (lua_State *L) {
return 1;
}
-static int math_mod (lua_State *L) {
+static int math_fmod (lua_State *L) {
lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
return 1;
}
@@ -212,35 +212,35 @@ static int math_randomseed (lua_State *L) {
}
-static const luaL_reg mathlib[] = {
+static const luaL_Reg mathlib[] = {
{"abs", math_abs},
- {"sin", math_sin},
- {"sinh", math_sinh},
- {"cos", math_cos},
- {"cosh", math_cosh},
- {"tan", math_tan},
- {"tanh", math_tanh},
- {"asin", math_asin},
{"acos", math_acos},
- {"atan", math_atan},
+ {"asin", math_asin},
{"atan2", math_atan2},
+ {"atan", math_atan},
{"ceil", math_ceil},
+ {"cosh", math_cosh},
+ {"cos", math_cos},
+ {"deg", math_deg},
+ {"exp", math_exp},
{"floor", math_floor},
- {"mod", math_mod},
- {"modf", math_modf},
+ {"fmod", math_fmod},
{"frexp", math_frexp},
{"ldexp", math_ldexp},
- {"sqrt", math_sqrt},
- {"min", math_min},
- {"max", math_max},
- {"log", math_log},
{"log10", math_log10},
- {"exp", math_exp},
- {"deg", math_deg},
+ {"log", math_log},
+ {"max", math_max},
+ {"min", math_min},
+ {"modf", math_modf},
{"pow", math_pow},
{"rad", math_rad},
{"random", math_random},
{"randomseed", math_randomseed},
+ {"sinh", math_sinh},
+ {"sin", math_sin},
+ {"sqrt", math_sqrt},
+ {"tanh", math_tanh},
+ {"tan", math_tan},
{NULL, NULL}
};
@@ -249,11 +249,15 @@ static const luaL_reg mathlib[] = {
** Open math library
*/
LUALIB_API int luaopen_math (lua_State *L) {
- luaL_openlib(L, LUA_MATHLIBNAME, mathlib, 0);
+ luaL_register(L, LUA_MATHLIBNAME, mathlib);
lua_pushnumber(L, PI);
lua_setfield(L, -2, "pi");
lua_pushnumber(L, HUGE_VAL);
lua_setfield(L, -2, "huge");
+#if defined(LUA_COMPAT_MOD)
+ lua_getfield(L, -1, "fmod");
+ lua_setfield(L, -2, "mod");
+#endif
return 1;
}
diff --git a/src/loadlib.c b/src/loadlib.c
index 1ae9ab57..767fdb8e 100644
--- a/src/loadlib.c
+++ b/src/loadlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: loadlib.c,v 1.28 2005/05/17 19:49:15 roberto Exp $
+** $Id: loadlib.c,v 1.44 2005/09/06 17:20:25 roberto Exp $
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
**
@@ -38,6 +38,13 @@
#define LIB_FAIL "open"
+/* error codes for ll_loadfunc */
+#define ERRLIB 1
+#define ERRFUNC 2
+
+#define setprogdir(L) ((void)0)
+
+
static void ll_unloadlib (void *lib);
static void *ll_load (lua_State *L, const char *path);
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
@@ -88,6 +95,21 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
#include <windows.h>
+#undef setprogdir
+
+void setprogdir (lua_State *L) {
+ char buff[MAX_PATH + 1];
+ char *lb;
+ DWORD nsize = sizeof(buff)/sizeof(char);
+ DWORD n = GetModuleFileName(NULL, buff, nsize);
+ if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
+ luaL_error(L, "unable to get ModuleFileName");
+ *lb = '\0';
+ luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff);
+ lua_remove(L, -2); /* remove original string */
+}
+
+
static void pusherror (lua_State *L) {
int error = GetLastError();
char buffer[128];
@@ -267,96 +289,148 @@ static void **ll_register (lua_State *L, const char *path) {
*/
static int gctm (lua_State *L) {
void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB");
- if (lib) {
- if (*lib) ll_unloadlib(*lib);
- *lib = NULL; /* mark library as closed */
- }
+ if (*lib) ll_unloadlib(*lib);
+ *lib = NULL; /* mark library as closed */
return 0;
}
static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
- const char *reason;
void **reg = ll_register(L, path);
if (*reg == NULL) *reg = ll_load(L, path);
if (*reg == NULL)
- reason = LIB_FAIL;
+ return ERRLIB; /* unable to load library */
else {
lua_CFunction f = ll_sym(L, *reg, sym);
- if (f) {
- lua_pushcfunction(L, f);
- return 1; /* return function */
- }
- reason = "init";
+ if (f == NULL)
+ return ERRFUNC; /* unable to find function */
+ lua_pushcfunction(L, f);
+ return 0; /* return function */
}
- lua_pushnil(L);
- lua_insert(L, -2);
- lua_pushstring(L, reason);
- return 3; /* return nil, ll_error, reason */
}
static int ll_loadlib (lua_State *L) {
const char *path = luaL_checkstring(L, 1);
const char *init = luaL_checkstring(L, 2);
- return ll_loadfunc(L, path, init);
+ int stat = ll_loadfunc(L, path, init);
+ if (stat == 0) /* no errors? */
+ return 1; /* return the loaded function */
+ else { /* error; error message is on stack top */
+ lua_pushnil(L);
+ lua_insert(L, -2);
+ lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
+ return 3; /* return nil, error message, and where */
+ }
}
/*
** {======================================================
-** `require' and `module' functions
+** 'require' function
** =======================================================
*/
-static int loader_Lua (lua_State *L) {
- const char *name = luaL_checkstring(L, 1);
- const char *fname = luaL_gsub(L, name, ".", LUA_DIRSEP);
- const char *path = NULL;
-#if LUA_COMPAT_PATH
- /* try first `LUA_PATH' for compatibility */
- lua_pushstring(L, "LUA_PATH");
- lua_rawget(L, LUA_GLOBALSINDEX);
+static int readable (const char *filename) {
+ FILE *f = fopen(filename, "r"); /* try to open file */
+ if (f == NULL) return 0; /* open failed */
+ fclose(f);
+ return 1;
+}
+
+
+static const char *pushnexttemplate (lua_State *L, const char *path) {
+ const char *l;
+ while (*path == *LUA_PATHSEP) path++; /* skip separators */
+ if (*path == '\0') return NULL; /* no more templates */
+ l = strchr(path, *LUA_PATHSEP); /* find next separator */
+ if (l == NULL) l = path + strlen(path);
+ lua_pushlstring(L, path, l - path); /* template */
+ return l;
+}
+
+
+static const char *findfile (lua_State *L, const char *name,
+ const char *pname) {
+ const char *path;
+ name = luaL_gsub(L, name, ".", LUA_DIRSEP);
+ lua_getfield(L, LUA_ENVIRONINDEX, pname);
path = lua_tostring(L, -1);
-#endif
- if (!path) {
- lua_pop(L, 1);
- lua_getfield(L, LUA_ENVIRONINDEX, "path");
- path = lua_tostring(L, -1);
- }
if (path == NULL)
- luaL_error(L, LUA_QL("package.path") " must be a string");
- fname = luaL_searchpath(L, fname, path);
- if (fname == NULL) return 0; /* library not found in this path */
- if (luaL_loadfile(L, fname) != 0)
- luaL_error(L, "error loading package " LUA_QS " (%s)",
- name, lua_tostring(L, -1));
+ luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
+ while ((path = pushnexttemplate(L, path)) != NULL) {
+ const char *filename;
+ filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name);
+ if (readable(filename)) /* does file exist and is readable? */
+ return filename; /* return that file name */
+ lua_pop(L, 2); /* remove path template and file name */
+ }
+ return NULL; /* not found */
+}
+
+
+static void loaderror (lua_State *L) {
+ luaL_error(L, "error loading module " LUA_QS " (%s)",
+ lua_tostring(L, 1), lua_tostring(L, -1));
+}
+
+
+static int loader_Lua (lua_State *L) {
+ const char *filename;
+ const char *name = luaL_checkstring(L, 1);
+ filename = findfile(L, name, "path");
+ if (filename == NULL) return 0; /* library not found in this path */
+ if (luaL_loadfile(L, filename) != 0)
+ loaderror(L);
return 1; /* library loaded successfully */
}
+static const char *mkfuncname (lua_State *L, const char *modname) {
+ const char *funcname;
+ const char *mark = strchr(modname, *LUA_IGMARK);
+ if (mark) modname = mark + 1;
+ funcname = luaL_gsub(L, modname, ".", LUA_OFSEP);
+ funcname = lua_pushfstring(L, POF"%s", funcname);
+ lua_remove(L, -2); /* remove 'gsub' result */
+ return funcname;
+}
+
+
static int loader_C (lua_State *L) {
- const char *name = luaL_checkstring(L, 1);
- const char *fname = luaL_gsub(L, name, ".", LUA_DIRSEP);
- const char *path;
const char *funcname;
- lua_getfield(L, LUA_ENVIRONINDEX, "cpath");
- path = lua_tostring(L, -1);
- if (path == NULL)
- luaL_error(L, LUA_QL("package.cpath") " must be a string");
- fname = luaL_searchpath(L, fname, path);
- if (fname == NULL) return 0; /* library not found in this path */
- funcname = luaL_gsub(L, name, ".", LUA_OFSEP);
- funcname = lua_pushfstring(L, "%s%s", POF, funcname);
- if (ll_loadfunc(L, fname, funcname) != 1)
- luaL_error(L, "error loading package " LUA_QS " (%s)",
- name, lua_tostring(L, -2));
+ const char *name = luaL_checkstring(L, 1);
+ const char *filename = findfile(L, name, "cpath");
+ if (filename == NULL) return 0; /* library not found in this path */
+ funcname = mkfuncname(L, name);
+ if (ll_loadfunc(L, filename, funcname) != 0)
+ loaderror(L);
return 1; /* library loaded successfully */
}
+static int loader_Croot (lua_State *L) {
+ const char *funcname;
+ const char *filename;
+ const char *name = luaL_checkstring(L, 1);
+ const char *p = strchr(name, '.');
+ int stat;
+ if (p == NULL) return 0; /* is root */
+ lua_pushlstring(L, name, p - name);
+ filename = findfile(L, lua_tostring(L, -1), "cpath");
+ if (filename == NULL) return 0; /* root not found */
+ funcname = mkfuncname(L, name);
+ if ((stat = ll_loadfunc(L, filename, funcname)) != 0) {
+ if (stat == ERRFUNC) return 0; /* function not found */
+ else
+ loaderror(L); /* real error */
+ }
+ return 1;
+}
+
+
static int loader_preload (lua_State *L) {
lua_getfield(L, LUA_ENVIRONINDEX, "preload");
if (!lua_istable(L, -1))
@@ -366,38 +440,58 @@ static int loader_preload (lua_State *L) {
}
+static const int sentinel = 0;
+
+
static int ll_require (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
int i;
- lua_settop(L, 1);
+ 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; return its result */
- /* else must load it; first mark it as loaded */
- lua_pushboolean(L, 1);
- lua_setfield(L, 2, name); /* _LOADED[name] = true */
- /* iterate over available loaders */
+ if (lua_toboolean(L, -1)) { /* is it there? */
+ if (lua_touserdata(L, -1) == &sentinel) /* check loops */
+ luaL_error(L, "loop or previous error loading module " LUA_QS, name);
+ return 1; /* package is already loaded */
+ }
+ /* else must load it; iterate over available loaders */
lua_getfield(L, LUA_ENVIRONINDEX, "loaders");
if (!lua_istable(L, -1))
luaL_error(L, LUA_QL("package.loaders") " must be a table");
- for (i=1;; i++) {
+ for (i=1; ; i++) {
lua_rawgeti(L, -1, i); /* get a loader */
if (lua_isnil(L, -1))
- return luaL_error(L, "package " LUA_QS " not found", name);
+ luaL_error(L, "module " LUA_QS " not found", name);
lua_pushstring(L, name);
lua_call(L, 1, 1); /* call it */
- if (lua_isnil(L, -1)) lua_pop(L, 1);
+ if (lua_isnil(L, -1)) lua_pop(L, 1); /* did not found module */
else break; /* module loaded successfully */
}
- lua_pushvalue(L, 1); /* pass name as argument to module */
+ lua_pushlightuserdata(L, (void *)&sentinel);
+ lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */
+ lua_pushstring(L, name); /* pass name as argument to module */
lua_call(L, 1, 1); /* run loaded module */
if (!lua_isnil(L, -1)) /* non-nil return? */
- lua_setfield(L, 2, name); /* update _LOADED[name] with returned value */
- lua_getfield(L, 2, name); /* return _LOADED[name] */
+ lua_setfield(L, 2, name); /* _LOADED[name] = returned value */
+ lua_getfield(L, 2, name);
+ if (lua_touserdata(L, -1) == &sentinel) { /* module did not set a value? */
+ lua_pushboolean(L, 1); /* use true as result */
+ lua_pushvalue(L, -1); /* extra copy to be returned */
+ lua_setfield(L, 2, name); /* _LOADED[name] = true */
+ }
return 1;
}
+/* }====================================================== */
+
+
+
+/*
+** {======================================================
+** 'module' function
+** =======================================================
+*/
+
static void setfenv (lua_State *L) {
lua_Debug ar;
@@ -405,49 +499,72 @@ static void setfenv (lua_State *L) {
lua_getinfo(L, "f", &ar);
lua_pushvalue(L, -2);
lua_setfenv(L, -2);
+ lua_pop(L, 1);
+}
+
+
+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);
+ }
+}
+
+
+static void modinit (lua_State *L, const char *modname) {
+ const char *dot;
+ lua_pushvalue(L, -1);
+ lua_setfield(L, -2, "_M"); /* module._M = module */
+ lua_pushstring(L, modname);
+ lua_setfield(L, -2, "_NAME");
+ dot = strrchr(modname, '.'); /* look for last dot in module name */
+ if (dot == NULL) dot = modname;
+ else dot++;
+ /* set _PACKAGE as package name (full module name minus last part) */
+ lua_pushlstring(L, modname, dot - modname);
+ lua_setfield(L, -2, "_PACKAGE");
}
static int ll_module (lua_State *L) {
const char *modname = luaL_checkstring(L, 1);
- const char *dot;
- lua_settop(L, 1);
+ int loaded = lua_gettop(L) + 1; /* index of _LOADED table */
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
- /* try to find given table */
- luaL_getfield(L, LUA_GLOBALSINDEX, modname);
- if (lua_isnil(L, -1)) { /* not found? */
+ lua_getfield(L, loaded, modname); /* get _LOADED[modname] */
+ if (!lua_istable(L, -1)) { /* not found? */
lua_pop(L, 1); /* remove previous result */
- lua_newtable(L); /* create it */
- /* register it with given name */
+ /* try global variable (and create one if it does not exist) */
+ if (luaL_findtable(L, LUA_GLOBALSINDEX, modname) != NULL)
+ return luaL_error(L, "name conflict for module " LUA_QS, modname);
lua_pushvalue(L, -1);
- luaL_setfield(L, LUA_GLOBALSINDEX, modname);
+ lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */
}
- else if (!lua_istable(L, -1))
- return luaL_error(L, "name conflict for module " LUA_QS, modname);
/* check whether table already has a _NAME field */
lua_getfield(L, -1, "_NAME");
if (!lua_isnil(L, -1)) /* is table an initialized module? */
lua_pop(L, 1);
else { /* no; initialize it */
lua_pop(L, 1);
- lua_newtable(L); /* create new metatable */
- lua_pushvalue(L, LUA_GLOBALSINDEX);
- lua_setfield(L, -2, "__index"); /* mt.__index = _G */
- lua_setmetatable(L, -2);
- lua_pushvalue(L, -1);
- lua_setfield(L, -2, "_M"); /* module._M = module */
- lua_pushstring(L, modname);
- lua_setfield(L, -2, "_NAME");
- dot = strrchr(modname, '.'); /* look for last dot in module name */
- if (dot == NULL) dot = modname;
- else dot++;
- /* set _PACKAGE as package name (full module name minus last part) */
- lua_pushlstring(L, modname, dot - modname);
- lua_setfield(L, -2, "_PACKAGE");
+ modinit(L, modname);
}
lua_pushvalue(L, -1);
- lua_setfield(L, 2, modname); /* _LOADED[modname] = new table */
setfenv(L);
+ dooptions(L, loaded - 1);
+ return 0;
+}
+
+
+static int ll_seeall (lua_State *L) {
+ luaL_checktype(L, 1, LUA_TTABLE);
+ if (!lua_getmetatable(L, 1)) {
+ lua_newtable(L); /* create new metatable */
+ lua_pushvalue(L, -1);
+ lua_setmetatable(L, 1);
+ }
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
+ lua_setfield(L, -2, "__index"); /* mt.__index = _G */
return 0;
}
@@ -455,28 +572,57 @@ static int ll_module (lua_State *L) {
/* }====================================================== */
-static const luaL_reg ll_funcs[] = {
- {"require", ll_require},
+
+/* auxiliary mark (for internal use) */
+#define AUXMARK "\1"
+
+static void setpath (lua_State *L, const char *fieldname, const char *envname,
+ const char *def) {
+ const char *path = getenv(envname);
+ if (path == NULL) /* no environment variable? */
+ lua_pushstring(L, def); /* use default */
+ else {
+ /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
+ path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP,
+ LUA_PATHSEP AUXMARK LUA_PATHSEP);
+ luaL_gsub(L, path, AUXMARK, def);
+ lua_remove(L, -2);
+ }
+ setprogdir(L);
+ lua_setfield(L, -2, fieldname);
+}
+
+
+static const luaL_Reg pk_funcs[] = {
+ {"loadlib", ll_loadlib},
+ {"seeall", ll_seeall},
+ {NULL, NULL}
+};
+
+
+static const luaL_Reg ll_funcs[] = {
{"module", ll_module},
+ {"require", ll_require},
{NULL, NULL}
};
static const lua_CFunction loaders[] =
- {loader_preload, loader_C, loader_Lua, NULL};
+ {loader_preload, loader_Lua, loader_C, loader_Croot, NULL};
-LUALIB_API int luaopen_loadlib (lua_State *L) {
- const char *path;
+LUALIB_API int luaopen_package (lua_State *L) {
int i;
/* create new type _LOADLIB */
luaL_newmetatable(L, "_LOADLIB");
lua_pushcfunction(L, gctm);
lua_setfield(L, -2, "__gc");
/* create `package' table */
- lua_newtable(L);
- lua_pushvalue(L, -1);
- lua_setglobal(L, LUA_LOADLIBNAME);
+ luaL_register(L, LUA_LOADLIBNAME, pk_funcs);
+#if defined(LUA_COMPAT_LOADLIB)
+ lua_getfield(L, -1, "loadlib");
+ lua_setfield(L, LUA_GLOBALSINDEX, "loadlib");
+#endif
lua_pushvalue(L, -1);
lua_setfield(L, LUA_REGISTRYINDEX, "_PACKAGE");
lua_pushvalue(L, -1);
@@ -488,33 +634,22 @@ LUALIB_API int luaopen_loadlib (lua_State *L) {
lua_pushcfunction(L, loaders[i]);
lua_rawseti(L, -2, i+1);
}
- /* put it in field `loaders' */
- lua_setfield(L, -2, "loaders");
- /* set field `path' */
- path = getenv(LUA_PATH);
- if (path == NULL) path = LUA_PATH_DEFAULT;
- lua_pushstring(L, path);
- lua_setfield(L, -2, "path");
- /* set field `cpath' */
- path = getenv(LUA_CPATH);
- if (path == NULL) path = LUA_CPATH_DEFAULT;
- lua_pushstring(L, path);
- lua_setfield(L, -2, "cpath");
+ lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */
+ setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */
+ setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */
+ /* store config information */
+ lua_pushstring(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n"
+ LUA_EXECDIR "\n" LUA_IGMARK);
+ lua_setfield(L, -2, "config");
/* set field `loaded' */
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
lua_setfield(L, -2, "loaded");
/* set field `preload' */
lua_newtable(L);
lua_setfield(L, -2, "preload");
- /* create `loadlib' function */
- lua_pushcfunction(L, ll_loadlib);
-#if LUA_COMPAT_LOADLIB
- lua_pushvalue(L, -1);
- lua_setfield(L, LUA_GLOBALSINDEX, "loadlib");
-#endif
- lua_setfield(L, -2, "loadlib");
lua_pushvalue(L, LUA_GLOBALSINDEX);
- luaL_openlib(L, NULL, ll_funcs, 0); /* open lib into global table */
- return 1;
+ luaL_register(L, NULL, ll_funcs); /* open lib into global table */
+ lua_pop(L, 1);
+ return 1; /* return 'package' table */
}
diff --git a/src/lobject.c b/src/lobject.c
index 98b08351..9aa9760f 100644
--- a/src/lobject.c
+++ b/src/lobject.c
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.c,v 2.13 2005/05/16 21:19:00 roberto Exp $
+** $Id: lobject.c,v 2.18 2005/08/01 04:22:23 roberto Exp $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
@@ -75,7 +75,7 @@ int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
case LUA_TNIL:
return 1;
case LUA_TNUMBER:
- return luai_numeq(nvalue(t1), nvalue(t2));
+ return luai_numeq(L, nvalue(t1), nvalue(t2));
case LUA_TBOOLEAN:
return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
case LUA_TLIGHTUSERDATA:
@@ -89,11 +89,11 @@ int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
int luaO_str2d (const char *s, lua_Number *result) {
char *endptr;
- lua_Number res = lua_str2number(s, &endptr);
- if (endptr == s) return 0; /* no conversion */
+ *result = lua_str2number(s, &endptr);
+ if (endptr == s) return 0; /* conversion failed */
+ if (*endptr == '\0') return 1; /* most common case */
while (isspace(cast(unsigned char, *endptr))) endptr++;
if (*endptr != '\0') return 0; /* invalid trailing characters? */
- *result = res;
return 1;
}
@@ -116,7 +116,9 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
incr_top(L);
switch (*(e+1)) {
case 's': {
- pushstr(L, va_arg(argp, char *));
+ const char *s = va_arg(argp, char *);
+ if (s == NULL) s = "(null)";
+ pushstr(L, s);
break;
}
case 'c': {
@@ -159,7 +161,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
fmt = e+2;
}
pushstr(L, fmt);
- luaV_concat(L, n+1, L->top - L->base - 1);
+ luaV_concat(L, n+1, cast(int, L->top - L->base) - 1);
L->top -= n;
return svalue(L->top - 1);
}
@@ -175,26 +177,26 @@ const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
}
-void luaO_chunkid (char *out, const char *source, int bufflen) {
+void luaO_chunkid (char *out, const char *source, size_t bufflen) {
if (*source == '=') {
strncpy(out, source+1, bufflen); /* remove first char */
out[bufflen-1] = '\0'; /* ensures null termination */
}
else { /* out = "source", or "...source" */
if (*source == '@') {
- int l;
+ size_t l;
source++; /* skip the `@' */
bufflen -= sizeof(" '...' ");
l = strlen(source);
strcpy(out, "");
- if (l>bufflen) {
+ if (l > bufflen) {
source += (l-bufflen); /* get last part of file name */
strcat(out, "...");
}
strcat(out, source);
}
else { /* out = [string "string"] */
- int len = strcspn(source, "\n\r"); /* stop at first newline */
+ size_t len = strcspn(source, "\n\r"); /* stop at first newline */
bufflen -= sizeof(" [string \"...\"] ");
if (len > bufflen) len = bufflen;
strcpy(out, "[string \"");
diff --git a/src/lobject.h b/src/lobject.h
index 4a77a539..1709fa3c 100644
--- a/src/lobject.h
+++ b/src/lobject.h
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.h,v 2.13 2005/05/05 20:47:02 roberto Exp $
+** $Id: lobject.h,v 2.17 2005/06/13 14:19:00 roberto Exp $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@@ -17,15 +17,17 @@
/* tags for values visible from Lua */
-#define NUM_TAGS LUA_TTHREAD
+#define LAST_TAG LUA_TTHREAD
+
+#define NUM_TAGS (LAST_TAG+1)
/*
** Extra tags for non-values
*/
-#define LUA_TPROTO (NUM_TAGS+1)
-#define LUA_TUPVAL (NUM_TAGS+2)
-#define LUA_TDEADKEY (NUM_TAGS+3)
+#define LUA_TPROTO (LAST_TAG+1)
+#define LUA_TUPVAL (LAST_TAG+2)
+#define LUA_TDEADKEY (LAST_TAG+3)
/*
@@ -254,8 +256,10 @@ typedef struct Proto {
} Proto;
-/* mask for new-style vararg */
-#define NEWSTYLEVARARG 2
+/* masks for new-style vararg */
+#define VARARG_HASARG 1
+#define VARARG_ISVARARG 2
+#define VARARG_NEEDSARG 4
typedef struct LocVar {
@@ -357,7 +361,7 @@ typedef struct Table {
-extern const TValue luaO_nilobject;
+LUAI_DATA const TValue luaO_nilobject;
#define ceillog2(x) (luaO_log2((x)-1) + 1)
@@ -369,7 +373,8 @@ LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result);
LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
va_list argp);
LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
-LUAI_FUNC void luaO_chunkid (char *out, const char *source, int len);
+LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);
#endif
+
diff --git a/src/lopcodes.c b/src/lopcodes.c
index 46b30ba9..5e3bc5f7 100644
--- a/src/lopcodes.c
+++ b/src/lopcodes.c
@@ -1,5 +1,5 @@
/*
-** $Id: lopcodes.c,v 1.33 2005/05/04 20:42:28 roberto Exp $
+** $Id: lopcodes.c,v 1.35 2005/08/29 20:49:21 roberto Exp $
** See Copyright Notice in lua.h
*/
@@ -36,13 +36,14 @@ const char *const luaP_opnames[NUM_OPCODES+1] = {
"POW",
"UNM",
"NOT",
- "SIZ",
+ "LEN",
"CONCAT",
"JMP",
"EQ",
"LT",
"LE",
"TEST",
+ "TESTSET",
"CALL",
"TAILCALL",
"RETURN",
@@ -81,13 +82,14 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = {
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
- ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_SIZ */
+ ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */
,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */
,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */
,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */
,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */
,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */
- ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */
+ ,opmode(1, 0, OpArgR, OpArgU, iABC) /* OP_TEST */
+ ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */
,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */
diff --git a/src/lopcodes.h b/src/lopcodes.h
index 77f60c00..b08b6798 100644
--- a/src/lopcodes.h
+++ b/src/lopcodes.h
@@ -1,5 +1,5 @@
/*
-** $Id: lopcodes.h,v 1.119 2005/05/04 20:42:28 roberto Exp $
+** $Id: lopcodes.h,v 1.122 2005/08/29 20:49:21 roberto Exp $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -176,7 +176,7 @@ OP_MOD,/* A B C R(A) := RK(B) % RK(C) */
OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
OP_UNM,/* A B R(A) := -R(B) */
OP_NOT,/* A B R(A) := not R(B) */
-OP_SIZ,/* A B R(A) := size of R(B) */
+OP_LEN,/* A B R(A) := length of R(B) */
OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
@@ -186,7 +186,8 @@ 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++ */
-OP_TEST,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
+OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
+OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
@@ -248,7 +249,7 @@ enum OpArgMask {
OpArgK /* argument is a constant or register/constant */
};
-extern const lu_byte luaP_opmodes[NUM_OPCODES];
+LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES];
#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
@@ -257,7 +258,7 @@ extern const lu_byte luaP_opmodes[NUM_OPCODES];
#define testTMode(m) (luaP_opmodes[m] & (1 << 7))
-extern const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */
+LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */
/* number of list items to accumulate before a SETLIST instruction */
diff --git a/src/loslib.c b/src/loslib.c
index 52532143..4cee7ba5 100644
--- a/src/loslib.c
+++ b/src/loslib.c
@@ -1,5 +1,5 @@
/*
-** $Id: loslib.c,v 1.9 2005/05/17 19:49:15 roberto Exp $
+** $Id: loslib.c,v 1.13 2005/09/09 18:22:46 roberto Exp $
** Standard Operating System library
** See Copyright Notice in lua.h
*/
@@ -93,6 +93,8 @@ static void setfield (lua_State *L, const char *key, int value) {
}
static void setboolfield (lua_State *L, const char *key, int value) {
+ if (value < 0) /* undefined? */
+ return; /* does not set field */
lua_pushboolean(L, value);
lua_setfield(L, -2, key);
}
@@ -197,9 +199,8 @@ static int io_setloc (lua_State *L) {
static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
"numeric", "time", NULL};
const char *l = lua_tostring(L, 1);
- int op = luaL_findstring(luaL_optstring(L, 2, "all"), catnames);
+ int op = luaL_checkoption(L, 2, "all", catnames);
luaL_argcheck(L, l || lua_isnoneornil(L, 1), 1, "string expected");
- luaL_argcheck(L, op != -1, 2, "invalid option");
lua_pushstring(L, setlocale(cat[op], l));
return 1;
}
@@ -210,7 +211,7 @@ static int io_exit (lua_State *L) {
return 0; /* to avoid warnings */
}
-static const luaL_reg syslib[] = {
+static const luaL_Reg syslib[] = {
{"clock", io_clock},
{"date", io_date},
{"difftime", io_difftime},
@@ -230,7 +231,7 @@ static const luaL_reg syslib[] = {
LUALIB_API int luaopen_os (lua_State *L) {
- luaL_openlib(L, LUA_OSLIBNAME, syslib, 0);
+ luaL_register(L, LUA_OSLIBNAME, syslib);
return 1;
}
diff --git a/src/lparser.c b/src/lparser.c
index 54facfc4..91dc4fff 100644
--- a/src/lparser.c
+++ b/src/lparser.c
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.c,v 2.27 2005/05/17 19:49:15 roberto Exp $
+** $Id: lparser.c,v 2.35 2005/08/29 20:49:21 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -239,35 +239,35 @@ static void markupval (FuncState *fs, int level) {
}
-static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
- if (fs == NULL) /* no more levels? */
+static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
+ if (fs == NULL) { /* no more levels? */
init_exp(var, VGLOBAL, NO_REG); /* default is global variable */
+ return VGLOBAL;
+ }
else {
int v = searchvar(fs, n); /* look up at current level */
if (v >= 0) {
init_exp(var, VLOCAL, v);
if (!base)
markupval(fs, v); /* local will be used as an upval */
+ return VLOCAL;
}
else { /* not found at current level; try upper one */
- singlevaraux(fs->prev, n, var, 0);
- if (var->k == VGLOBAL) {
- if (base)
- var->info = luaK_stringK(fs, n); /* info points to global name */
- }
- else { /* LOCAL or UPVAL */
- var->info = indexupvalue(fs, n, var);
- var->k = VUPVAL; /* upvalue in this level */
- }
+ if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL)
+ return VGLOBAL;
+ var->info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */
+ var->k = VUPVAL; /* upvalue in this level */
+ return VUPVAL;
}
}
}
-static TString *singlevar (LexState *ls, expdesc *var, int base) {
+static void singlevar (LexState *ls, expdesc *var) {
TString *varname = str_checkname(ls);
- singlevaraux(ls->fs, varname, var, base);
- return varname;
+ FuncState *fs = ls->fs;
+ if (singlevaraux(fs, varname, var, 1) == VGLOBAL)
+ var->info = luaK_stringK(fs, varname); /* info points to global name */
}
@@ -300,7 +300,7 @@ static void enterlevel (LexState *ls) {
#define leavelevel(ls) ((ls)->L->nCcalls--)
-static void enterblock (FuncState *fs, BlockCnt *bl, int isbreakable) {
+static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) {
bl->breaklist = NO_JUMP;
bl->isbreakable = isbreakable;
bl->nactvar = fs->nactvar;
@@ -317,6 +317,7 @@ static void leaveblock (FuncState *fs) {
removevars(fs->ls, bl->nactvar);
if (bl->upval)
luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
+ lua_assert(!bl->isbreakable || !bl->upval); /* loops have no body */
lua_assert(bl->nactvar == fs->nactvar);
fs->freereg = fs->nactvar; /* free registers */
luaK_patchtohere(fs, bl->breaklist);
@@ -374,7 +375,7 @@ static void close_func (LexState *ls) {
FuncState *fs = ls->fs;
Proto *f = fs->f;
removevars(ls, 0);
- luaK_codeABC(fs, OP_RETURN, 0, 1, 0); /* final return */
+ luaK_ret(fs, 0, 0); /* final return */
luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
f->sizecode = fs->pc;
luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
@@ -402,7 +403,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
lexstate.buff = buff;
luaX_setinput(L, &lexstate, z, luaS_new(L, name));
open_func(&lexstate, &funcstate);
- funcstate.f->is_vararg = NEWSTYLEVARARG;
+ funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */
next(&lexstate); /* read first token */
chunk(&lexstate);
check(&lexstate, TK_EOS);
@@ -525,7 +526,6 @@ static void constructor (LexState *ls, expdesc *t) {
checknext(ls, '{');
do {
lua_assert(cc.v.k == VVOID || cc.tostore > 0);
- testnext(ls, ';'); /* compatibility only */
if (ls->t.token == '}') break;
closelistfield(fs, &cc);
switch(ls->t.token) {
@@ -572,9 +572,12 @@ static void parlist (LexState *ls) {
}
case TK_DOTS: { /* param -> `...' */
next(ls);
+#if defined(LUA_COMPAT_VARARG)
/* use `arg' as default name */
new_localvarliteral(ls, "arg", nparams++);
- f->is_vararg = 1;
+ f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG;
+#endif
+ f->is_vararg |= VARARG_ISVARARG;
break;
}
default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected");
@@ -582,7 +585,7 @@ static void parlist (LexState *ls) {
} while (!f->is_vararg && testnext(ls, ','));
}
adjustlocalvars(ls, nparams);
- f->numparams = fs->nactvar - f->is_vararg;
+ f->numparams = fs->nactvar - (f->is_vararg & VARARG_HASARG);
luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */
}
@@ -690,7 +693,7 @@ static void prefixexp (LexState *ls, expdesc *v) {
return;
}
case TK_NAME: {
- singlevar(ls, v, 1);
+ singlevar(ls, v);
return;
}
default: {
@@ -766,7 +769,7 @@ static void simpleexp (LexState *ls, expdesc *v) {
FuncState *fs = ls->fs;
check_condition(ls, fs->f->is_vararg,
"cannot use " LUA_QL("...") " outside a vararg function");
- fs->f->is_vararg = NEWSTYLEVARARG;
+ fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */
init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
break;
}
@@ -792,7 +795,7 @@ static UnOpr getunopr (int op) {
switch (op) {
case TK_NOT: return OPR_NOT;
case '-': return OPR_MINUS;
- case '*': return OPR_SIZE;
+ case '#': return OPR_LEN;
default: return OPR_NOUNOPR;
}
}
@@ -979,78 +982,68 @@ static int cond (LexState *ls) {
expr(ls, &v); /* read condition */
if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */
luaK_goiftrue(ls->fs, &v);
- luaK_patchtohere(ls->fs, v.t);
return v.f;
}
-/*
-** The while statement optimizes its code by coding the condition
-** after its body (and thus avoiding one jump in the loop).
-*/
-
+static void breakstat (LexState *ls) {
+ FuncState *fs = ls->fs;
+ BlockCnt *bl = fs->bl;
+ int upval = 0;
+ while (bl && !bl->isbreakable) {
+ upval |= bl->upval;
+ bl = bl->previous;
+ }
+ if (!bl)
+ luaX_syntaxerror(ls, "no loop to break");
+ if (upval)
+ luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
+ luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
+}
-/*
-** the call `luaK_goiffalse' may grow the size of an expression by
-** at most this:
-*/
-#define EXTRAEXP 5
static void whilestat (LexState *ls, int line) {
/* whilestat -> WHILE cond DO block END */
- Instruction codeexp[LUAI_MAXEXPWHILE + EXTRAEXP];
- int lineexp;
- int i;
- int sizeexp;
FuncState *fs = ls->fs;
- int whileinit, blockinit, expinit;
- expdesc v;
+ int whileinit;
+ int condexit;
BlockCnt bl;
next(ls); /* skip WHILE */
- whileinit = luaK_jump(fs); /* jump to condition (which will be moved) */
- expinit = luaK_getlabel(fs);
- expr(ls, &v); /* parse condition */
- if (v.k == VK) v.k = VTRUE; /* `trues' are all equal here */
- lineexp = ls->linenumber;
- luaK_goiffalse(fs, &v);
- luaK_concat(fs, &v.f, fs->jpc);
- fs->jpc = NO_JUMP;
- sizeexp = fs->pc - expinit; /* size of expression code */
- if (sizeexp > LUAI_MAXEXPWHILE)
- luaX_syntaxerror(ls, LUA_QL("while") " condition too complex");
- for (i = 0; i < sizeexp; i++) /* save `exp' code */
- codeexp[i] = fs->f->code[expinit + i];
- fs->pc = expinit; /* remove `exp' code */
+ whileinit = luaK_getlabel(fs);
+ condexit = cond(ls);
enterblock(fs, &bl, 1);
checknext(ls, TK_DO);
- blockinit = luaK_getlabel(fs);
block(ls);
- luaK_patchtohere(fs, whileinit); /* initial jump jumps to here */
- /* move `exp' back to code */
- if (v.t != NO_JUMP) v.t += fs->pc - expinit;
- if (v.f != NO_JUMP) v.f += fs->pc - expinit;
- for (i=0; i<sizeexp; i++)
- luaK_code(fs, codeexp[i], lineexp);
+ luaK_patchlist(fs, luaK_jump(fs), whileinit);
check_match(ls, TK_END, TK_WHILE, line);
leaveblock(fs);
- luaK_patchlist(fs, v.t, blockinit); /* true conditions go back to loop */
- luaK_patchtohere(fs, v.f); /* false conditions finish the loop */
+ luaK_patchtohere(fs, condexit); /* false conditions finish the loop */
}
static void repeatstat (LexState *ls, int line) {
/* repeatstat -> REPEAT block UNTIL cond */
+ int condexit;
FuncState *fs = ls->fs;
int repeat_init = luaK_getlabel(fs);
- int flist;
- BlockCnt bl;
- enterblock(fs, &bl, 1);
- next(ls);
- block(ls);
+ BlockCnt bl1, bl2;
+ enterblock(fs, &bl1, 1); /* loop block */
+ enterblock(fs, &bl2, 0); /* scope block */
+ next(ls); /* skip REPEAT */
+ chunk(ls);
check_match(ls, TK_UNTIL, TK_REPEAT, line);
- flist = cond(ls);
- luaK_patchlist(fs, flist, repeat_init);
- leaveblock(fs);
+ condexit = cond(ls); /* read condition (inside scope block) */
+ if (!bl2.upval) { /* no upvalues? */
+ leaveblock(fs); /* finish scope */
+ luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */
+ }
+ else { /* complete semantics when there are upvalues */
+ breakstat(ls); /* if condition then break */
+ luaK_patchtohere(ls->fs, condexit); /* else... */
+ leaveblock(fs); /* finish scope... */
+ luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */
+ }
+ leaveblock(fs); /* finish loop */
}
@@ -1150,12 +1143,12 @@ static void forstat (LexState *ls, int line) {
static int test_then_block (LexState *ls) {
/* test_then_block -> [IF | ELSEIF] cond THEN block */
- int flist;
+ int condexit;
next(ls); /* skip IF or ELSEIF */
- flist = cond(ls);
+ condexit = cond(ls);
checknext(ls, TK_THEN);
block(ls); /* `then' part */
- return flist;
+ return condexit;
}
@@ -1219,7 +1212,7 @@ static void localstat (LexState *ls) {
static int funcname (LexState *ls, expdesc *v) {
/* funcname -> NAME {field} [`:' NAME] */
int needself = 0;
- singlevar(ls, v, 1);
+ singlevar(ls, v);
while (ls->t.token == '.')
field(ls, v);
if (ls->t.token == ':') {
@@ -1285,25 +1278,7 @@ static void retstat (LexState *ls) {
}
}
}
- luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
-}
-
-
-static void breakstat (LexState *ls) {
- /* stat -> BREAK */
- FuncState *fs = ls->fs;
- BlockCnt *bl = fs->bl;
- int upval = 0;
- next(ls); /* skip BREAK */
- while (bl && !bl->isbreakable) {
- upval |= bl->upval;
- bl = bl->previous;
- }
- if (!bl)
- luaX_syntaxerror(ls, "no loop to break");
- if (upval)
- luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
- luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
+ luaK_ret(fs, first, nret);
}
@@ -1349,6 +1324,7 @@ static int statement (LexState *ls) {
return 1; /* must be last statement */
}
case TK_BREAK: { /* stat -> breakstat */
+ next(ls); /* skip BREAK */
breakstat(ls);
return 1; /* must be last statement */
}
diff --git a/src/lstate.c b/src/lstate.c
index 41162dac..2a4ace12 100644
--- a/src/lstate.c
+++ b/src/lstate.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.c,v 2.31 2005/05/05 15:34:03 roberto Exp $
+** $Id: lstate.c,v 2.33 2005/08/25 15:39:16 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
@@ -72,7 +72,6 @@ static void f_luaopen (lua_State *L, void *ud) {
UNUSED(ud);
stack_init(L, L); /* init stack */
sethvalue(L, gt(L), luaH_new(L, 0, 20)); /* table of globals */
- hvalue(gt(L))->metatable = luaH_new(L, 0, 0); /* globals metatable */
sethvalue(L, registry(L), luaH_new(L, 6, 20)); /* registry */
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
luaT_init(L);
@@ -83,7 +82,7 @@ static void f_luaopen (lua_State *L, void *ud) {
static void preinit_state (lua_State *L, global_State *g) {
- L->l_G = g;
+ G(L) = g;
L->stack = NULL;
L->stacksize = 0;
L->errorJmp = NULL;
diff --git a/src/lstate.h b/src/lstate.h
index 7dafa4d5..e8bc15ab 100644
--- a/src/lstate.h
+++ b/src/lstate.h
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.h,v 2.21 2005/05/05 15:34:03 roberto Exp $
+** $Id: lstate.h,v 2.23 2005/07/09 13:22:34 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
@@ -19,10 +19,10 @@ struct lua_longjmp; /* defined in ldo.c */
/* table of globals */
-#define gt(L) (&L->_gt)
+#define gt(L) (&L->l_gt)
/* registry */
-#define registry(L) (&G(L)->_registry)
+#define registry(L) (&G(L)->l_registry)
/* extra stack space to handle TM calls and some other extras */
@@ -86,7 +86,7 @@ typedef struct global_State {
int gcpause; /* size of pause between successive GCs */
int gcstepmul; /* GC `granularity' */
lua_CFunction panic; /* to be called in unprotected errors */
- TValue _registry;
+ TValue l_registry;
struct lua_State *mainthread;
UpVal uvhead; /* head of double-linked list of all open upvalues */
struct Table *mt[NUM_TAGS]; /* metatables for basic types */
@@ -117,7 +117,7 @@ struct lua_State {
int basehookcount;
int hookcount;
lua_Hook hook;
- TValue _gt; /* table of globals */
+ TValue l_gt; /* table of globals */
TValue env; /* temporary place for environments */
GCObject *openupval; /* list of open upvalues in this stack */
GCObject *gclist;
diff --git a/src/lstrlib.c b/src/lstrlib.c
index 4929a27c..4cf5836a 100644
--- a/src/lstrlib.c
+++ b/src/lstrlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstrlib.c,v 1.115 2005/05/17 19:49:15 roberto Exp $
+** $Id: lstrlib.c,v 1.123 2005/08/26 17:36:32 roberto Exp $
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/
@@ -58,7 +58,7 @@ static int str_reverse (lua_State *L) {
luaL_Buffer b;
const char *s = luaL_checklstring(L, 1, &l);
luaL_buffinit(L, &b);
- while (l--) luaL_putchar(&b, s[l]);
+ while (l--) luaL_addchar(&b, s[l]);
luaL_pushresult(&b);
return 1;
}
@@ -71,7 +71,7 @@ static int str_lower (lua_State *L) {
const char *s = luaL_checklstring(L, 1, &l);
luaL_buffinit(L, &b);
for (i=0; i<l; i++)
- luaL_putchar(&b, tolower(uchar(s[i])));
+ luaL_addchar(&b, tolower(uchar(s[i])));
luaL_pushresult(&b);
return 1;
}
@@ -84,7 +84,7 @@ static int str_upper (lua_State *L) {
const char *s = luaL_checklstring(L, 1, &l);
luaL_buffinit(L, &b);
for (i=0; i<l; i++)
- luaL_putchar(&b, toupper(uchar(s[i])));
+ luaL_addchar(&b, toupper(uchar(s[i])));
luaL_pushresult(&b);
return 1;
}
@@ -127,7 +127,7 @@ static int str_char (lua_State *L) {
for (i=1; i<=n; i++) {
int c = luaL_checkint(L, i);
luaL_argcheck(L, uchar(c) == c, i, "invalid value");
- luaL_putchar(&b, uchar(c));
+ luaL_addchar(&b, uchar(c));
}
luaL_pushresult(&b);
return 1;
@@ -461,7 +461,7 @@ static const char *lmemfind (const char *s1, size_t l1,
static void push_onecapture (MatchState *ms, int i) {
- int l = ms->capture[i].len;
+ ptrdiff_t l = ms->capture[i].len;
if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
if (l == CAP_POSITION)
lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1);
@@ -485,15 +485,15 @@ static int push_captures (MatchState *ms, const char *s, const char *e) {
}
-static int str_find (lua_State *L) {
+static int str_find_aux (lua_State *L, int find) {
size_t l1, l2;
const char *s = luaL_checklstring(L, 1, &l1);
const char *p = luaL_checklstring(L, 2, &l2);
ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;
if (init < 0) init = 0;
else if ((size_t)(init) > l1) init = (ptrdiff_t)l1;
- if (lua_toboolean(L, 4) || /* explicit request? */
- strpbrk(p, SPECIALS) == NULL) { /* or no special characters? */
+ if (find && (lua_toboolean(L, 4) || /* explicit request? */
+ strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */
/* do a plain search */
const char *s2 = lmemfind(s+init, l1-init, p, l2);
if (s2) {
@@ -513,18 +513,37 @@ static int str_find (lua_State *L) {
const char *res;
ms.level = 0;
if ((res=match(&ms, s1, p)) != NULL) {
- lua_pushinteger(L, s1-s+1); /* start */
- lua_pushinteger(L, res-s); /* end */
- return push_captures(&ms, NULL, 0) + 2;
+ if (find) {
+ lua_pushinteger(L, s1-s+1); /* start */
+ lua_pushinteger(L, res-s); /* end */
+#if defined(LUA_COMPAT_FIND)
+ return push_captures(&ms, NULL, 0) + 2;
+#else
+ return 2;
+#endif
+
+ }
+ else
+ return push_captures(&ms, s1, res);
}
- } while (s1++<ms.src_end && !anchor);
+ } while (s1++ < ms.src_end && !anchor);
}
lua_pushnil(L); /* not found */
return 1;
}
-static int gfind_aux (lua_State *L) {
+static int str_find (lua_State *L) {
+ return str_find_aux(L, 1);
+}
+
+
+static int str_match (lua_State *L) {
+ return str_find_aux(L, 0);
+}
+
+
+static int gmatch_aux (lua_State *L) {
MatchState ms;
size_t ls;
const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls);
@@ -539,7 +558,7 @@ static int gfind_aux (lua_State *L) {
const char *e;
ms.level = 0;
if ((e = match(&ms, src, p)) != NULL) {
- int newstart = e-s;
+ lua_Integer newstart = e-s;
if (e == src) newstart++; /* empty match? go at least one position */
lua_pushinteger(L, newstart);
lua_replace(L, lua_upvalueindex(3));
@@ -550,16 +569,22 @@ static int gfind_aux (lua_State *L) {
}
-static int gfind (lua_State *L) {
+static int gmatch (lua_State *L) {
luaL_checkstring(L, 1);
luaL_checkstring(L, 2);
lua_settop(L, 2);
lua_pushinteger(L, 0);
- lua_pushcclosure(L, gfind_aux, 3);
+ lua_pushcclosure(L, gmatch_aux, 3);
return 1;
}
+static int gfind_nodef (lua_State *L) {
+ return luaL_error(L, LUA_QL("string.gfind") " was renamed to "
+ LUA_QL("string.gmatch"));
+}
+
+
static void add_s (MatchState *ms, luaL_Buffer *b,
const char *s, const char *e) {
lua_State *L = ms->L;
@@ -569,14 +594,18 @@ static void add_s (MatchState *ms, luaL_Buffer *b,
size_t i;
for (i=0; i<l; i++) {
if (news[i] != L_ESC)
- luaL_putchar(b, news[i]);
+ luaL_addchar(b, news[i]);
else {
i++; /* skip ESC */
if (!isdigit(uchar(news[i])))
- luaL_putchar(b, news[i]);
+ luaL_addchar(b, news[i]);
else {
- int level = check_capture(ms, news[i]);
- push_onecapture(ms, level);
+ if (news[i] == '0')
+ lua_pushlstring(L, s, e - s); /* add whole match */
+ else {
+ int level = check_capture(ms, news[i]);
+ push_onecapture(ms, level);
+ }
luaL_addvalue(b); /* add capture to accumulated result */
}
}
@@ -622,7 +651,7 @@ static int str_gsub (lua_State *L) {
if (e && e>src) /* non empty match? */
src = e; /* skip it */
else if (src < ms.src_end)
- luaL_putchar(&b, *src++);
+ luaL_addchar(&b, *src++);
else break;
if (anchor) break;
}
@@ -644,12 +673,12 @@ static int str_gsub (lua_State *L) {
static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
size_t l;
const char *s = luaL_checklstring(L, arg, &l);
- luaL_putchar(b, '"');
+ luaL_addchar(b, '"');
while (l--) {
switch (*s) {
case '"': case '\\': case '\n': {
- luaL_putchar(b, '\\');
- luaL_putchar(b, *s);
+ luaL_addchar(b, '\\');
+ luaL_addchar(b, *s);
break;
}
case '\0': {
@@ -657,13 +686,13 @@ static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
break;
}
default: {
- luaL_putchar(b, *s);
+ luaL_addchar(b, *s);
break;
}
}
s++;
}
- luaL_putchar(b, '"');
+ luaL_addchar(b, '"');
}
@@ -699,9 +728,9 @@ static int str_format (lua_State *L) {
luaL_buffinit(L, &b);
while (strfrmt < strfrmt_end) {
if (*strfrmt != L_ESC)
- luaL_putchar(&b, *strfrmt++);
+ luaL_addchar(&b, *strfrmt++);
else if (*++strfrmt == L_ESC)
- luaL_putchar(&b, *strfrmt++); /* %% */
+ luaL_addchar(&b, *strfrmt++); /* %% */
else { /* format item */
char form[MAX_FORMAT]; /* to store the format (`%...') */
char buff[MAX_ITEM]; /* to store the formatted item */
@@ -753,20 +782,22 @@ static int str_format (lua_State *L) {
}
-static const luaL_reg strlib[] = {
- {"len", str_len},
- {"sub", str_sub},
- {"reverse", str_reverse},
- {"lower", str_lower},
- {"upper", str_upper},
- {"char", str_char},
- {"rep", str_rep},
+static const luaL_Reg strlib[] = {
{"byte", str_byte},
- {"format", str_format},
+ {"char", str_char},
{"dump", str_dump},
{"find", str_find},
- {"gfind", gfind},
+ {"format", str_format},
+ {"gfind", gfind_nodef},
+ {"gmatch", gmatch},
{"gsub", str_gsub},
+ {"len", str_len},
+ {"lower", str_lower},
+ {"match", str_match},
+ {"rep", str_rep},
+ {"reverse", str_reverse},
+ {"sub", str_sub},
+ {"upper", str_upper},
{NULL, NULL}
};
@@ -779,8 +810,6 @@ static void createmetatable (lua_State *L) {
lua_pop(L, 1); /* pop dummy string */
lua_pushvalue(L, -2); /* string library... */
lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */
- lua_getfield(L, -2, "len");
- lua_setfield(L, -2, "__siz");
lua_pop(L, 1); /* pop metatable */
}
@@ -789,7 +818,11 @@ static void createmetatable (lua_State *L) {
** Open string library
*/
LUALIB_API int luaopen_string (lua_State *L) {
- luaL_openlib(L, LUA_STRLIBNAME, strlib, 0);
+ luaL_register(L, LUA_STRLIBNAME, strlib);
+#if defined(LUA_COMPAT_GFIND)
+ lua_getfield(L, -1, "gmatch");
+ lua_setfield(L, -2, "gfind");
+#endif
createmetatable(L);
return 1;
}
diff --git a/src/ltable.c b/src/ltable.c
index d0ba365b..979cc5ca 100644
--- a/src/ltable.c
+++ b/src/ltable.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.c,v 2.23 2005/05/17 19:49:15 roberto Exp $
+** $Id: ltable.c,v 2.26 2005/07/11 14:01:37 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -120,7 +120,7 @@ static int arrayindex (const TValue *key) {
lua_Number n = nvalue(key);
int k;
lua_number2int(k, n);
- if (luai_numeq(cast(lua_Number, k), nvalue(key)))
+ if (luai_numeq(L, cast(lua_Number, k), nvalue(key)))
return k;
}
return -1; /* `key' did not match some condition */
@@ -145,7 +145,7 @@ static int findindex (lua_State *L, Table *t, StkId key) {
if (luaO_rawequalObj(key2tval(n), key) ||
(ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) &&
gcvalue(gkey(n)) == gcvalue(key))) {
- i = n - gnode(t, 0); /* key index in hash table */
+ i = cast(int, n - gnode(t, 0)); /* key index in hash table */
/* hash elements are numbered after array ones */
return i + t->sizearray;
}
@@ -376,7 +376,7 @@ void luaH_free (lua_State *L, Table *t) {
}
-static Node *getfreepos (lua_State *L, Table *t) {
+static Node *getfreepos (Table *t) {
while (t->lastfree-- > t->node) {
if (ttisnil(gkey(t->lastfree)))
return t->lastfree;
@@ -397,7 +397,7 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
Node *mp = luaH_mainposition(t, key);
if (!ttisnil(gval(mp)) || mp == &luaH_dummynode) {
Node *othern;
- Node *n = getfreepos(L, t); /* get a free place */
+ 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 */
@@ -437,7 +437,7 @@ const TValue *luaH_getnum (Table *t, int key) {
lua_Number nk = cast(lua_Number, key);
Node *n = hashnum(t, nk);
do { /* check whether `key' is somewhere in the chain */
- if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk))
+ if (ttisnumber(gkey(n)) && luai_numeq(L, nvalue(gkey(n)), nk))
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
@@ -471,7 +471,7 @@ const TValue *luaH_get (Table *t, const TValue *key) {
int k;
lua_Number n = nvalue(key);
lua_number2int(k, n);
- if (luai_numeq(cast(lua_Number, k), nvalue(key))) /* index is integer? */
+ if (luai_numeq(L, cast(lua_Number, k), nvalue(key))) /* index is int? */
return luaH_getnum(t, k); /* use specialized version */
/* else go through */
}
@@ -495,7 +495,7 @@ TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
return cast(TValue *, p);
else {
if (ttisnil(key)) luaG_runerror(L, "table index is nil");
- else if (ttisnumber(key) && !luai_numeq(nvalue(key), nvalue(key)))
+ else if (ttisnumber(key) && !luai_numeq(L, nvalue(key), nvalue(key)))
luaG_runerror(L, "table index is NaN");
return newkey(L, t, key);
}
diff --git a/src/ltable.h b/src/ltable.h
index 1a798262..14a20448 100644
--- a/src/ltable.h
+++ b/src/ltable.h
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.h,v 2.7 2005/04/25 19:24:10 roberto Exp $
+** $Id: ltable.h,v 2.8 2005/06/06 13:30:25 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -18,7 +18,7 @@
#define key2tval(n) (cast(const TValue *, gkey(n)))
-extern const Node luaH_dummynode;
+LUAI_DATA const Node luaH_dummynode;
LUAI_FUNC const TValue *luaH_getnum (Table *t, int key);
LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key);
diff --git a/src/ltablib.c b/src/ltablib.c
index ab4d5db2..348b6ed5 100644
--- a/src/ltablib.c
+++ b/src/ltablib.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltablib.c,v 1.31 2005/05/17 19:49:15 roberto Exp $
+** $Id: ltablib.c,v 1.35 2005/08/26 17:36:32 roberto Exp $
** Library for Table Manipulation
** See Copyright Notice in lua.h
*/
@@ -109,7 +109,7 @@ static int tremove (lua_State *L) {
}
-static int str_concat (lua_State *L) {
+static int tconcat (lua_State *L) {
luaL_Buffer b;
size_t lsep;
const char *sep = luaL_optlstring(L, 2, "", &lsep);
@@ -236,21 +236,21 @@ static int sort (lua_State *L) {
/* }====================================================== */
-static const luaL_reg tab_funcs[] = {
- {"concat", str_concat},
+static const luaL_Reg tab_funcs[] = {
+ {"concat", tconcat},
{"foreach", foreach},
{"foreachi", foreachi},
{"getn", getn},
- {"setn", setn},
- {"sort", sort},
{"insert", tinsert},
{"remove", tremove},
+ {"setn", setn},
+ {"sort", sort},
{NULL, NULL}
};
LUALIB_API int luaopen_table (lua_State *L) {
- luaL_openlib(L, LUA_TABLIBNAME, tab_funcs, 0);
+ luaL_register(L, LUA_TABLIBNAME, tab_funcs);
return 1;
}
diff --git a/src/ltm.c b/src/ltm.c
index 6f2223a7..591134da 100644
--- a/src/ltm.c
+++ b/src/ltm.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltm.c,v 2.5 2005/05/05 15:34:03 roberto Exp $
+** $Id: ltm.c,v 2.6 2005/05/20 15:53:42 roberto Exp $
** Tag methods
** See Copyright Notice in lua.h
*/
@@ -32,7 +32,7 @@ void luaT_init (lua_State *L) {
"__index", "__newindex",
"__gc", "__mode", "__eq",
"__add", "__sub", "__mul", "__div", "__mod",
- "__pow", "__unm", "__siz", "__lt", "__le",
+ "__pow", "__unm", "__len", "__lt", "__le",
"__concat", "__call"
};
int i;
diff --git a/src/ltm.h b/src/ltm.h
index 1622b781..866c7966 100644
--- a/src/ltm.h
+++ b/src/ltm.h
@@ -1,5 +1,5 @@
/*
-** $Id: ltm.h,v 2.4 2005/05/05 15:34:03 roberto Exp $
+** $Id: ltm.h,v 2.6 2005/06/06 13:30:25 roberto Exp $
** Tag methods
** See Copyright Notice in lua.h
*/
@@ -28,7 +28,7 @@ typedef enum {
TM_MOD,
TM_POW,
TM_UNM,
- TM_SIZ,
+ TM_LEN,
TM_LT,
TM_LE,
TM_CONCAT,
@@ -43,7 +43,7 @@ typedef enum {
#define fasttm(l,et,e) gfasttm(G(l), et, e)
-extern const char *const luaT_typenames[];
+LUAI_DATA const char *const luaT_typenames[];
LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
diff --git a/src/lua.c b/src/lua.c
index a942c741..14c5e20d 100644
--- a/src/lua.c
+++ b/src/lua.c
@@ -1,5 +1,5 @@
/*
-** $Id: lua.c,v 1.144 2005/05/17 19:49:15 roberto Exp $
+** $Id: lua.c,v 1.150 2005/09/06 17:19:33 roberto Exp $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
@@ -48,15 +48,16 @@ static void print_usage (void) {
" -i enter interactive mode after executing " LUA_QL("script") "\n"
" -l name require library " LUA_QL("name") "\n"
" -v show version information\n"
- " -w trap access to undefined globals\n"
" -- stop handling options\n" ,
progname);
+ fflush(stderr);
}
static void l_message (const char *pname, const char *msg) {
if (pname) fprintf(stderr, "%s: ", pname);
fprintf(stderr, "%s\n", msg);
+ fflush(stderr);
}
@@ -72,14 +73,19 @@ static int report (lua_State *L, int status) {
static int traceback (lua_State *L) {
- luaL_getfield(L, LUA_GLOBALSINDEX, "debug.traceback");
- if (!lua_isfunction(L, -1))
+ lua_getfield(L, LUA_GLOBALSINDEX, "debug");
+ if (!lua_istable(L, -1)) {
lua_pop(L, 1);
- else {
- lua_pushvalue(L, 1); /* pass error message */
- lua_pushinteger(L, 2); /* skip this function and traceback */
- lua_call(L, 2, 1); /* call debug.traceback */
+ return 1;
+ }
+ lua_getfield(L, -1, "traceback");
+ if (!lua_isfunction(L, -1)) {
+ lua_pop(L, 2);
+ return 1;
}
+ lua_pushvalue(L, 1); /* pass error message */
+ lua_pushinteger(L, 2); /* skip this function and traceback */
+ lua_call(L, 2, 1); /* call debug.traceback */
return 1;
}
@@ -138,8 +144,7 @@ static int dolibrary (lua_State *L, const char *name) {
static const char *get_prompt (lua_State *L, int firstline) {
const char *p;
- lua_pushstring(L, firstline ? "_PROMPT" : "_PROMPT2");
- lua_rawget(L, LUA_GLOBALSINDEX);
+ lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2");
p = lua_tostring(L, -1);
if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2);
lua_pop(L, 1); /* remove global */
@@ -148,13 +153,16 @@ static const char *get_prompt (lua_State *L, int firstline) {
static int incomplete (lua_State *L, int status) {
- if (status == LUA_ERRSYNTAX &&
- strstr(lua_tostring(L, -1), "<eof>") != NULL) {
- lua_pop(L, 1);
- return 1;
+ if (status == LUA_ERRSYNTAX) {
+ size_t lmsg;
+ const char *msg = lua_tolstring(L, -1, &lmsg);
+ const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1);
+ if (strstr(msg, LUA_QL("<eof>")) == tp) {
+ lua_pop(L, 1);
+ return 1;
+ }
}
- else
- return 0;
+ return 0; /* else... */
}
@@ -216,18 +224,11 @@ static void dotty (lua_State *L) {
}
lua_settop(L, 0); /* clear stack */
fputs("\n", stdout);
+ fflush(stdout);
progname = oldprogname;
}
-static int checkvar (lua_State *L) {
- const char *name = lua_tostring(L, 2);
- if (name)
- luaL_error(L, "attempt to access undefined variable " LUA_QS, name);
- return 0;
-}
-
-
#define clearinteractive(i) (*i &= 2)
static int handle_argv (lua_State *L, int argc, char **argv, int *interactive) {
@@ -265,13 +266,6 @@ static int handle_argv (lua_State *L, int argc, char **argv, int *interactive) {
print_version();
break;
}
- case 'w': {
- if (lua_getmetatable(L, LUA_GLOBALSINDEX)) {
- lua_pushcfunction(L, checkvar);
- lua_setfield(L, -2, "__index");
- }
- break;
- }
case 'e': {
const char *chunk = argv[i] + 2;
clearinteractive(interactive);
diff --git a/src/lua.h b/src/lua.h
index 1028e5ea..339e076f 100644
--- a/src/lua.h
+++ b/src/lua.h
@@ -1,8 +1,7 @@
/*
-** $Id: lua.h,v 1.208 2005/05/17 19:49:15 roberto Exp $
+** $Id: lua.h,v 1.212 2005/08/25 20:02:08 roberto Exp $
** Lua - An Extensible Extension Language
-** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
-** http://www.lua.org
+** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
** See Copyright Notice at the end of this file
*/
@@ -17,9 +16,9 @@
#include "luaconf.h"
-#define LUA_VERSION "Lua 5.1 (work6)"
+#define LUA_VERSION "Lua 5.1 (alpha)"
#define LUA_VERSION_NUM 501
-#define LUA_COPYRIGHT "Copyright (C) 1994-2005 Tecgraf, PUC-Rio"
+#define LUA_COPYRIGHT "Copyright (C) 1994-2005 Lua.org, PUC-Rio"
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
@@ -39,7 +38,7 @@
#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
-/* return codes for `lua_pcall', `lua_resume', and `lua_status' */
+/* thread status; 0 is OK */
#define LUA_YIELD 1
#define LUA_ERRRUN 2
#define LUA_ERRSYNTAX 3
@@ -147,7 +146,7 @@ LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx);
LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx);
LUA_API int (lua_toboolean) (lua_State *L, int idx);
LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
-LUA_API size_t (lua_objsize) (lua_State *L, int idx);
+LUA_API size_t (lua_objlen) (lua_State *L, int idx);
LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
LUA_API void *(lua_touserdata) (lua_State *L, int idx);
LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
@@ -257,7 +256,7 @@ LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)
-#define lua_strlen(L,i) lua_objsize(L, (i))
+#define lua_strlen(L,i) lua_objlen(L, (i))
#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)
#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)
@@ -357,7 +356,7 @@ struct lua_Debug {
/******************************************************************************
-* Copyright (C) 1994-2005 Tecgraf, PUC-Rio. All rights reserved.
+* Copyright (C) 1994-2005 Lua.org, PUC-Rio. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
diff --git a/src/luac.c b/src/luac.c
index cfe00c7b..374ea3ac 100644
--- a/src/luac.c
+++ b/src/luac.c
@@ -1,5 +1,5 @@
/*
-** $Id: luac.c,v 1.50 2005/05/12 00:26:50 lhf Exp $
+** $Id: luac.c,v 1.51 2005/06/02 13:39:23 lhf Exp $
** Lua compiler (saves bytecodes to files; also list bytecodes)
** See Copyright Notice in lua.h
*/
@@ -53,7 +53,7 @@ static void cannot(const char* what)
static void usage(const char* message)
{
if (*message=='-')
- fprintf(stderr,"%s: unrecognized option `%s'\n",progname,message);
+ fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message);
else
fprintf(stderr,"%s: %s\n",progname,message);
fprintf(stderr,
@@ -61,7 +61,7 @@ static void usage(const char* message)
"Available options are:\n"
" - process stdin\n"
" -l list\n"
- " -o name output to file `name' (default is \"%s\")\n"
+ " -o name output to file " LUA_QL("name") " (default is \"%s\")\n"
" -p parse only\n"
" -s strip debug information\n"
" -v show version information\n"
@@ -92,7 +92,7 @@ static int doargs(int argc, char* argv[])
else if (IS("-o")) /* output file */
{
output=argv[++i];
- if (output==NULL || *output==0) usage("`-o' needs argument");
+ if (output==NULL || *output==0) usage(LUA_QL("-o") " needs argument");
if (IS("-")) output=NULL;
}
else if (IS("-p")) /* parse only */
diff --git a/src/luaconf.h b/src/luaconf.h
index bc211cd3..d6d4a2a7 100644
--- a/src/luaconf.h
+++ b/src/luaconf.h
@@ -1,5 +1,5 @@
/*
-** $Id: luaconf.h,v 1.49a 2005/05/17 19:49:15 roberto Exp $
+** $Id: luaconf.h,v 1.65 2005/09/09 18:24:42 roberto Exp $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
@@ -22,6 +22,16 @@
/*
+@@ 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(__STRICT_ANSI__)
+#define LUA_ANSI
+#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
@@ -31,22 +41,27 @@
** non-conventional directories.
*/
#if defined(_WIN32)
-#define LUA_ROOT "C:\\Program Files\\Lua51"
-#define LUA_LDIR LUA_ROOT "\\lua"
-#define LUA_CDIR LUA_ROOT "\\dll"
+/*
+** 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;" LUA_LDIR"\\?.lua;" LUA_LDIR"\\?\\init.lua"
-#define LUA_CPATH_DEFAULT \
- "?.dll;" "l?.dll;" LUA_CDIR"\\?.dll;" LUA_CDIR"\\l?.dll"
+ ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \
+ LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua"
+#define LUA_CPATH_DEFAULT \
+ ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
#else
-#define LUA_ROOT "/usr/local"
-#define LUA_LDIR LUA_ROOT "/share/lua/5.1"
-#define LUA_CDIR LUA_ROOT "/lib/lua/5.1"
+#define LUA_ROOT "/usr/local/"
+#define LUA_LDIR LUA_ROOT "share/lua/5.1/"
+#define LUA_CDIR LUA_ROOT "lib/lua/5.1/"
#define LUA_PATH_DEFAULT \
- "./?.lua;" LUA_LDIR"/?.lua;" LUA_LDIR"/?/init.lua"
-#define LUA_CPATH_DEFAULT \
- "./?.so;" "./l?.so;" LUA_CDIR"/?.so;" LUA_CDIR"/l?.so"
+ "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
+ LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua"
+#define LUA_CPATH_DEFAULT \
+ "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so"
#endif
@@ -64,21 +79,20 @@
/*
@@ LUA_PATHSEP is the character that separates templates in a path.
-** CHANGE it if for some reason your system cannot use a
-** semicolon. (E.g., if a semicolon is a common character in
-** file/directory names.) Probably you do not need to change this.
-*/
-#define LUA_PATHSEP ';'
-
-
-/*
@@ LUA_PATH_MARK is the string that marks the substitution points in a
@* template.
-** CHANGE it if for some reason your system cannot use an interrogation
-** mark. (E.g., if an interogation mark is a common character in
-** file/directory names.) Probably you do not need to change this.
-*/
+@@ LUA_EXECDIR in a Windows path is replaced by the executable's
+@* directory.
+@@ LUA_IGMARK is a mark to ignore all before it when bulding the
+@* luaopen_ function name.
+** CHANGE them if for some reason your system cannot use those
+** characters. (E.g., if one of those characters is a common character
+** in file/directory names.) Probably you do not need to change them.
+*/
+#define LUA_PATHSEP ";"
#define LUA_PATH_MARK "?"
+#define LUA_EXECDIR "!"
+#define LUA_IGMARK ":"
/*
@@ -100,9 +114,9 @@
#if defined(LUA_BUILD_AS_DLL)
#if defined(LUA_CORE) || defined(LUA_LIB)
-#define LUA_API __declspec(__dllexport)
+#define LUA_API __declspec(dllexport)
#else
-#define LUA_API __declspec(__dllimport)
+#define LUA_API __declspec(dllimport)
#endif
#else
@@ -118,19 +132,26 @@
/*
@@ LUAI_FUNC is a mark for all extern functions that are not to be
@* exported to outside modules.
-** CHANGE it if you need to mark them in some special way. Gcc (versions
-** 3.2 and later) mark them as "hidden" to optimize their call when Lua
-** is compiled as a shared library.
+@@ LUAI_DATA is a mark for all extern (const) variables that are not to
+@* be exported to outside modules.
+** 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.
*/
#if defined(luaall_c)
#define LUAI_FUNC static
-#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302)
-#define LUAI_FUNC __attribute__((visibility("hidden")))
+#define LUAI_DATA /* empty */
+#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
+ defined(__ELF__)
+#define LUAI_FUNC __attribute__((visibility("hidden"))) extern
+#define LUAI_DATA LUAI_FUNC
#else
#define LUAI_FUNC extern
+#define LUAI_DATA extern
#endif
+
/*
@@ lua_assert describes the internal assertions in Lua.
** CHANGE that only if you need to debug Lua.
@@ -149,7 +170,7 @@
/*
@@ LUA_IDSIZE gives the maximum size for the description of the source
@* of a function in debug information.
-** CHANGE it if you a different size.
+** CHANGE it if you want a different size.
*/
#define LUA_IDSIZE 60
@@ -168,10 +189,10 @@
** CHANGE it if you have a better definition for non-POSIX/non-Windows
** systems.
*/
-#if !defined(__STRICT_ANSI__) && defined(_POSIX_C_SOURCE)
+#if !defined(LUA_ANSI) && defined(_POSIX_C_SOURCE)
#include <unistd.h>
#define lua_stdin_is_tty() isatty(0)
-#elif !defined(__STRICT_ANSI__) && defined(_WIN32)
+#elif !defined(LUA_ANSI) && defined(_WIN32)
#include <io.h>
#include <stdio.h>
#define lua_stdin_is_tty() _isatty(_fileno(stdin))
@@ -214,7 +235,7 @@
** CHANGE them if you want to improve this functionality (e.g., by using
** GNU readline and history facilities).
*/
-#if !defined(__STRICT_ANSI__) && defined(LUA_USE_READLINE)
+#if defined(LUA_USE_READLINE)
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
@@ -239,49 +260,52 @@
/*
@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles
@* as a percentage.
-** CHANGE it if you want the GC to run faster or slower (higher
-** values mean larger pauses which mean slower collection.)
+** CHANGE it if you want the GC to run faster or slower (higher values
+** mean larger pauses which mean slower collection.) You can also change
+** this value dynamically.
*/
#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */
/*
-@@ LUAI_GCMUL defines the speed of garbage collection relative to
+@@ LUAI_GCMUL defines the default speed of garbage collection relative to
@* memory allocation as a percentage.
** CHANGE it if you want to change the granularity of the garbage
** collection. (Higher values mean coarser collections. 0 represents
-** infinity, where each step performs a full collection.)
+** infinity, where each step performs a full collection.) You can also
+** change this value dynamically.
*/
#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */
+
/*
@@ LUA_COMPAT_GETN controls compatibility with old getn behavior.
-** CHANGE it to 1 if you want exact compatibility with the behavior of
-** setn/getn in Lua 5.0.
+** CHANGE it (define it) if you want exact compatibility with the
+** behavior of setn/getn in Lua 5.0.
*/
-#define LUA_COMPAT_GETN 0
+#undef LUA_COMPAT_GETN
/*
-@@ LUA_COMPAT_PATH controls compatibility about LUA_PATH.
-** CHANGE it to 1 if you want 'require' to look for global LUA_PATH
-** before checking package.path.
+@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib.
+** CHANGE it to undefined as soon as you do not need a global 'loadlib'
+** function (the function is still available as 'package.loadlib').
*/
-#define LUA_COMPAT_PATH 0
+#undef LUA_COMPAT_LOADLIB
/*
-@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib.
-** CHANGE it to 1 if you want a global 'loadlib' function (otherwise
-** the function is only available as 'package.loadlib').
+@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature.
+** CHANGE it to undefined as soon as your programs use only '...' to
+** access vararg parameters (instead of the old 'arg' table).
*/
-#define LUA_COMPAT_LOADLIB 1
+#define LUA_COMPAT_VARARG
/*
-@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature.
-** CHANGE it to 1 if you want vararg functions that do not use '...'
-** to get an 'arg' table with their extra arguments.
+@@ LUA_COMPAT_MOD controls compatibility with old math.mod function.
+** CHANGE it to undefined as soon as your programs use 'math.fmod' or
+** the new '%' operator instead of 'math.mod'.
*/
-#define LUA_COMPAT_VARARG 1
+#define LUA_COMPAT_MOD
/*
@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting
@@ -292,6 +316,31 @@
#define LUA_COMPAT_LSTR 1
/*
+@@ LUA_COMPAT_FIND controls compatibility with old 'string.find' behavior.
+** CHANGE it to undefined as soon as your programs use 'string.find' only
+** to find patterns.
+*/
+#define LUA_COMPAT_FIND
+
+/*
+@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name.
+** CHANGE it to undefined as soon as you rename 'string.gfind' to
+** 'string.gmatch'.
+*/
+#define LUA_COMPAT_GFIND
+
+
+/*
+@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib'
+@* behavior.
+** CHANGE it to undefined as soon as you replace to 'luaL_registry'
+** your uses of 'luaL_openlib'
+*/
+#define LUA_COMPAT_OPENLIB
+
+
+
+/*
@@ luai_apicheck is the assert macro used by the Lua-C API.
** CHANGE luai_apicheck if you want Lua to perform some checks in the
** parameters it gets from API calls. This may slow down the interpreter
@@ -407,13 +456,6 @@
/*
-@@ LUAI_MAXEXPWHILE is the maximum size of code for expressions
-@* controling a 'while' loop.
-*/
-#define LUAI_MAXEXPWHILE 100
-
-
-/*
@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
*/
#define LUAL_BUFFERSIZE BUFSIZ
@@ -424,47 +466,25 @@
/*
@@ lua_number2int is a macro to convert lua_Number to int.
-** CHANGE that if you know a faster way to convert a lua_Number to
+@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
+** CHANGE them if you know a faster way to convert a lua_Number to
** int (with any rounding method and without throwing errors) in your
** system. In Pentium machines, a naive typecast from double to int
** in C is extremely slow, so any alternative is worth trying.
*/
-/* On a gcc/Pentium, resort to assembler */
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__i386)
-#define lua_number2int(i,d) __asm__ ("fistpl %0":"=m"(i):"t"(d):"st")
-
-/* On Windows/Pentium, resort to assembler */
-#elif !defined(__STRICT_ANSI__) && defined(_MSC_VER) && defined(_M_IX86)
-#define lua_number2int(i,d) \
- __asm fld d \
- __asm fistp i
-
-
-/* on Pentium machines compliant with C99, you can try lrint */
-#elif defined (__i386) && defined(__STDC_VERSION__) && \
- (__STDC_VERSION__ >= 199900L)
-#define lua_number2int(i,d) ((i)=lrint(d))
-
-/* this option always works, but may be slow */
-#else
-#define lua_number2int(i,d) ((i)=(int)(d))
-
-#endif
-
-
-/*
-@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
-** CHANGE (see lua_number2int).
-*/
-/* On a gcc or Windows/Pentium, resort to assembler */
-#if (defined(__GNUC__) && defined(__i386)) || \
- (defined(_MSC_VER) && defined(_M_IX86))
+/* On a Pentium, resort to a trick */
+#if !defined(LUA_ANSI) && !defined(__SSE2__) && \
+ (defined(__i386) || defined (_M_IX86))
+union luai_Cast { double l_d; long l_l; };
+#define lua_number2int(i,d) \
+ { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
#define lua_number2integer(i,n) lua_number2int(i, n)
/* this option always works, but may be slow */
#else
-#define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
+#define lua_number2int(i,d) ((i)=(int)(d))
+#define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
#endif
@@ -479,13 +499,13 @@
** ===================================================================
*/
+#define LUA_NUMBER double
/*
@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
@* over a number.
*/
-#define LUA_NUMBER double
-#define LUAI_UACNUMBER LUA_NUMBER
+#define LUAI_UACNUMBER double
/*
@@ -505,16 +525,16 @@
/*
@@ The luai_num* macros define the primitive operations over numbers.
*/
-#define luai_numadd(a,b) ((a)+(b))
-#define luai_numsub(a,b) ((a)-(b))
-#define luai_nummul(a,b) ((a)*(b))
-#define luai_numdiv(a,b) ((a)/(b))
-#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b))
-#define luai_numpow(a,b) pow(a,b)
-#define luai_numunm(a) (-(a))
-#define luai_numeq(a,b) ((a)==(b))
-#define luai_numlt(a,b) ((a)<(b))
-#define luai_numle(a,b) ((a)<=(b))
+#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_nummod(L,a,b) ((a) - floor((a)/(b))*(b))
+#define luai_numpow(L,a,b) pow(a,b)
+#define luai_numunm(L,a) (-(a))
+#define luai_numeq(L,a,b) ((a)==(b))
+#define luai_numlt(L,a,b) ((a)<(b))
+#define luai_numle(L,a,b) ((a)<=(b))
/* }================================================================== */
@@ -531,11 +551,11 @@
/*
@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling.
-** CHANGE them if you prefer to use longjmp/setjmp even with C++ or
-** if want/don't want to use _longjmp/_setjmp instead of regular
+** CHANGE them if you prefer to use longjmp/setjmp even with C++
+** or if want/don't to use _longjmp/_setjmp instead of regular
** longjmp/setjmp. By default, Lua handles errors with exceptions when
-** compiling as C++ code, with _longjmp/_setjmp when compiling as C code
-** in a Unix system, and with longjmp/setjmp otherwise.
+** compiling as C++ code, with _longjmp/_setjmp when asked to use them,
+** and with longjmp/setjmp otherwise.
*/
#if defined(__cplusplus)
/* C++ exceptions */
@@ -544,8 +564,7 @@
{ if ((c)->status == 0) (c)->status = -1; }
#define luai_jmpbuf int /* dummy variable */
-#elif !defined(__STRICT_ANSI__) && (defined(unix) || defined(__unix) || \
- defined(__unix__))
+#elif defined(LUA_USE_ULONGJMP)
/* in Unix, try _longjmp/_setjmp (more efficient) */
#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
@@ -578,7 +597,7 @@
*/
#if defined(loslib_c) || defined(luaall_c)
-#if !defined(__STRICT_ANSI__) && defined(_POSIX_C_SOURCE)
+#if !defined(LUA_ANSI) && defined(_POSIX_C_SOURCE)
#include <unistd.h>
#define LUA_TMPNAMBUFSIZE 32
#define lua_tmpnam(b,e) { \
@@ -593,6 +612,30 @@
#endif
+
+/*
+@@ lua_popen spawns a new process connected to the current one through
+@* the file streams.
+** CHANGE it if you have a way to implement it in your system.
+*/
+#if !defined(LUA_ANSI) && defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 2
+
+#define lua_popen(L,c,m) popen(c,m)
+#define lua_pclose(L,file) (pclose(file) != -1)
+
+#elif !defined(LUA_ANSI) && defined(_WIN32)
+
+#define lua_popen(L,c,m) _popen(c,m)
+#define lua_pclose(L,file) (_pclose(file) != -1)
+
+#else
+
+#define lua_popen(L,c,m) \
+ ((void)c, (void)m, luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0)
+#define lua_pclose(L,file) ((void)file, 0)
+
+#endif
+
/*
@@ LUA_DL_* define which dynamic-library system Lua should use.
** CHANGE here if Lua has problems choosing the appropriate
@@ -606,7 +649,7 @@
** If you do not want any kind of dynamic library, undefine all these
** options (or just remove these definitions).
*/
-#if !defined(__STRICT_ANSI__)
+#if !defined(LUA_ANSI)
#if defined(_WIN32)
#define LUA_DL_DLL
#elif defined(__APPLE__) && defined(__MACH__)
@@ -618,29 +661,6 @@
/*
-@@ lua_lock/lua_unlock are macros for thread synchronization inside the
-@* Lua core. This is an attempt to simplify the implementation of a
-@* multithreaded version of Lua.
-** CHANGE them only if you know what you are doing. All accesses to
-** the global state and to global objects are synchronized. Because
-** threads can read the stack of other threads (when running garbage
-** collection), a thread must also synchronize any write-access to its
-** own stack. Unsynchronized accesses are allowed only when reading its
-** own stack, or when reading immutable fields from global objects (such
-** as string values and udata values).
-*/
-#define lua_lock(L) ((void) 0)
-#define lua_unlock(L) ((void) 0)
-
-
-/*
-@@ lua_threadyield allows a thread switch in appropriate places in the core.
-** CHANGE it only if you know what you are doing. (See lua_lock.)
-*/
-#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);}
-
-
-/*
@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State
@* (the data goes just *before* the lua_State pointer).
** CHANGE (define) this if you really need that. This value must be
@@ -650,11 +670,15 @@
/*
-@@ luai_userstateopen allows user-specific initialization on new threads.
-** CHANGE it if you defined LUAI_EXTRASPACE and need to initialize that
-** data whenever a new lua_State is created.
+@@ luai_userstate* allow user-specific actions on threads.
+** CHANGE them if you defined LUAI_EXTRASPACE and need to do something
+** extra when a thread is created/deleted/resumed/yielded.
*/
-#define luai_userstateopen(L) ((void)0)
+#define luai_userstateopen(L) ((void)0)
+#define luai_userstatefree(L) ((void)0)
+#define luai_userstateresume(L,n) ((void)0)
+#define luai_userstateyield(L,n) ((void)0)
+
@@ -668,3 +692,4 @@
#endif
+
diff --git a/src/lualib.h b/src/lualib.h
index e1face32..f52bb888 100644
--- a/src/lualib.h
+++ b/src/lualib.h
@@ -1,5 +1,5 @@
/*
-** $Id: lualib.h,v 1.34 2005/04/13 17:24:20 roberto Exp $
+** $Id: lualib.h,v 1.35 2005/08/10 18:06:58 roberto Exp $
** Lua standard libraries
** See Copyright Notice in lua.h
*/
@@ -37,7 +37,7 @@ LUALIB_API int (luaopen_math) (lua_State *L);
LUALIB_API int (luaopen_debug) (lua_State *L);
#define LUA_LOADLIBNAME "package"
-LUALIB_API int (luaopen_loadlib) (lua_State *L);
+LUALIB_API int (luaopen_package) (lua_State *L);
/* open all previous libraries */
diff --git a/src/lundump.c b/src/lundump.c
index 8ceb571b..726d021d 100644
--- a/src/lundump.c
+++ b/src/lundump.c
@@ -1,11 +1,10 @@
/*
-** $Id: lundump.c,v 1.55 2005/05/12 00:26:50 lhf Exp $
+** $Id: lundump.c,v 1.58 2005/09/02 01:54:47 lhf Exp $
** load pre-compiled Lua chunks
** See Copyright Notice in lua.h
*/
-#include <stdarg.h>
-#include <stddef.h>
+#include <string.h>
#define lundump_c
#define LUA_CORE
@@ -21,113 +20,89 @@
#include "lundump.h"
#include "lzio.h"
-#define LoadByte (lu_byte) ezgetc
+#ifdef LUAC_TRUST_BINARIES
+#define IF(c,s)
+#else
+#define IF(c,s) if (c) error(S,s)
+#endif
typedef struct {
lua_State* L;
ZIO* Z;
Mbuffer* b;
- int swap;
const char* name;
+#ifdef LUAC_SWAP_ON_LOAD
+ int swap;
+#endif
} LoadState;
-static void error (LoadState* S, const char* fmt, ...)
-{
- const char *msg;
- va_list argp;
- va_start(argp,fmt);
- msg=luaO_pushvfstring(S->L,fmt,argp);
- va_end(argp);
- luaO_pushfstring(S->L,"%s: %s",S->name,msg);
- luaD_throw(S->L,LUA_ERRSYNTAX);
-}
+#ifdef LUAC_SWAP_ON_LOAD
+static void LoadMem (LoadState* S, void* b, int n, size_t size);
+#else
+#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size))
+#endif
-static int ezgetc (LoadState* S)
-{
- int c=zgetc(S->Z);
- if (c==EOZ) error(S,"unexpected end of file");
- return c;
-}
+#define LoadByte(S) (lu_byte)LoadChar(S)
+#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))
+#define LoadVector(S,b,n,size) LoadMem(S,b,n,size)
-static void ezread (LoadState* S, void* b, int n)
+static void error(LoadState* S, const char* why)
{
- int r=luaZ_read(S->Z,b,n);
- if (r!=0) error(S,"unexpected end of file");
+ luaO_pushfstring(S->L,"%s: %s",S->name,why);
+ luaD_throw(S->L,LUA_ERRSYNTAX);
}
-static void LoadBlock (LoadState* S, void* b, size_t size)
+static void LoadBlock(LoadState* S, void* b, size_t size)
{
- if (S->swap)
- {
- char* p=(char*) b+size-1;
- int n=size;
- while (n--) *p--=(char)ezgetc(S);
- }
- else
- ezread(S,b,size);
+ size_t r=luaZ_read(S->Z,b,size);
+ IF (r!=0, "unexpected end");
}
-static void LoadVector (LoadState* S, void* b, int m, size_t size)
+static int LoadChar(LoadState* S)
{
- if (S->swap)
- {
- char* q=(char*) b;
- while (m--)
- {
- char* p=q+size-1;
- int n=size;
- while (n--) *p--=(char)ezgetc(S);
- q+=size;
- }
- }
- else
- ezread(S,b,m*size);
-}
-
-static int LoadInt (LoadState* S)
-{
- int x;
- LoadBlock(S,&x,sizeof(x));
- if (x<0) error(S,"bad integer");
+ char x;
+ LoadVar(S,x);
return x;
}
-static size_t LoadSize (LoadState* S)
+static int LoadInt(LoadState* S)
{
- size_t x;
- LoadBlock(S,&x,sizeof(x));
+ int x;
+ LoadVar(S,x);
+ IF (x<0, "bad integer");
return x;
}
-static lua_Number LoadNumber (LoadState* S)
+static lua_Number LoadNumber(LoadState* S)
{
lua_Number x;
- LoadBlock(S,&x,sizeof(x));
+ LoadVar(S,x);
return x;
}
-static TString* LoadString (LoadState* S)
+static TString* LoadString(LoadState* S)
{
- size_t size=LoadSize(S);
+ size_t size;
+ LoadVar(S,size);
if (size==0)
return NULL;
else
{
char* s=luaZ_openspace(S->L,S->b,size);
- ezread(S,s,size);
+ LoadBlock(S,s,size);
return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
}
}
-static void LoadCode (LoadState* S, Proto* f)
+static void LoadCode(LoadState* S, Proto* f)
{
- int size=LoadInt(S);
- f->code=luaM_newvector(S->L,size,Instruction);
- f->sizecode=size;
- LoadVector(S,f->code,size,sizeof(Instruction));
+ int n=LoadInt(S);
+ f->code=luaM_newvector(S->L,n,Instruction);
+ f->sizecode=n;
+ LoadVector(S,f->code,n,sizeof(Instruction));
}
-static void LoadLocals (LoadState* S, Proto* f)
+static void LoadLocals(LoadState* S, Proto* f)
{
int i,n;
n=LoadInt(S);
@@ -142,29 +117,27 @@ static void LoadLocals (LoadState* S, Proto* f)
}
}
-static void LoadLines (LoadState* S, Proto* f)
+static void LoadLines(LoadState* S, Proto* f)
{
- int size=LoadInt(S);
- f->lineinfo=luaM_newvector(S->L,size,int);
- f->sizelineinfo=size;
- LoadVector(S,f->lineinfo,size,sizeof(int));
+ int n=LoadInt(S);
+ f->lineinfo=luaM_newvector(S->L,n,int);
+ f->sizelineinfo=n;
+ LoadVector(S,f->lineinfo,n,sizeof(int));
}
-static void LoadUpvalues (LoadState* S, Proto* f)
+static void LoadUpvalues(LoadState* S, Proto* f)
{
int i,n;
n=LoadInt(S);
- if (n!=0 && n!=f->nups)
- error(S,"bad nupvalues (read %d; expected %d)",n,f->nups);
f->upvalues=luaM_newvector(S->L,n,TString*);
f->sizeupvalues=n;
for (i=0; i<n; i++) f->upvalues[i]=NULL;
for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
}
-static Proto* LoadFunction (LoadState* S, TString* p);
+static Proto* LoadFunction(LoadState* S, TString* p);
-static void LoadConstants (LoadState* S, Proto* f)
+static void LoadConstants(LoadState* S, Proto* f)
{
int i,n;
n=LoadInt(S);
@@ -174,14 +147,14 @@ static void LoadConstants (LoadState* S, Proto* f)
for (i=0; i<n; i++)
{
TValue* o=&f->k[i];
- int t=LoadByte(S);
+ int t=LoadChar(S);
switch (t)
{
case LUA_TNIL:
setnilvalue(o);
break;
case LUA_TBOOLEAN:
- setbvalue(o,LoadByte(S));
+ setbvalue(o,LoadChar(S));
break;
case LUA_TNUMBER:
setnvalue(o,LoadNumber(S));
@@ -190,7 +163,7 @@ static void LoadConstants (LoadState* S, Proto* f)
setsvalue2n(S->L,o,LoadString(S));
break;
default:
- error(S,"bad constant type (%d)",t);
+ IF (1, "bad constant");
break;
}
}
@@ -201,7 +174,7 @@ static void LoadConstants (LoadState* S, Proto* f)
for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
}
-static Proto* LoadFunction (LoadState* S, TString* p)
+static Proto* LoadFunction(LoadState* S, TString* p)
{
Proto* f=luaF_newproto(S->L);
setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
@@ -217,46 +190,21 @@ static Proto* LoadFunction (LoadState* S, TString* p)
LoadUpvalues(S,f);
LoadConstants(S,f);
LoadCode(S,f);
-#ifndef TRUST_BINARIES
- if (!luaG_checkcode(f)) error(S,"bad code");
-#endif
+ IF (!luaG_checkcode(f), "bad code");
S->L->top--;
return f;
}
-static void LoadSignature (LoadState* S)
-{
- const char* s=LUA_SIGNATURE;
- while (*s!=0 && ezgetc(S)==*s)
- ++s;
- if (*s!=0) error(S,"bad signature");
-}
-
-static void TestSize (LoadState* S, int s, const char* what)
-{
- int r=LoadByte(S);
- if (r!=s)
- error(S,"bad size of %s (read %d; expected %d)",what,r,s);
-}
-
-#define V(v) v/16,v%16
-
-static void LoadHeader (LoadState* S)
+static void LoadHeader(LoadState* S)
{
- int version;
- lua_Number x,tx=TEST_NUMBER;
- LoadSignature(S);
- version=LoadByte(S);
- if (version!=VERSION)
- error(S,"bad version (read %d.%d; expected %d.%d)",V(version),V(VERSION));
- S->swap=(luaU_endianness()!=LoadByte(S)); /* need to swap bytes? */
- TestSize(S,sizeof(int),"int");
- TestSize(S,sizeof(size_t),"size_t");
- TestSize(S,sizeof(Instruction),"instruction");
- TestSize(S,sizeof(lua_Number),"number");
- x=LoadNumber(S);
- if (x!=tx)
- error(S,"unknown number format");
+ char h[LUAC_HEADERSIZE];
+ char s[LUAC_HEADERSIZE];
+ luaU_header(h);
+ LoadBlock(S,s,LUAC_HEADERSIZE);
+#ifdef LUAC_SWAP_ON_LOAD
+ S->swap=(s[6]!=h[6]); s[6]=h[6];
+#endif
+ IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header");
}
/*
@@ -279,10 +227,64 @@ Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
}
/*
-** find byte order
+* make header
*/
-int luaU_endianness (void)
+void luaU_header (char* h)
{
int x=1;
- return *(char*)&x;
+ memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);
+ h+=sizeof(LUA_SIGNATURE)-1;
+ *h++=(char)LUAC_VERSION;
+ *h++=(char)LUAC_FORMAT;
+ *h++=(char)*(char*)&x;
+ *h++=(char)sizeof(int);
+ *h++=(char)sizeof(size_t);
+ *h++=(char)sizeof(Instruction);
+ *h++=(char)sizeof(lua_Number);
+ *h++=(char)(((lua_Number)0.5)==0);
}
+
+#ifdef LUAC_SWAP_ON_LOAD
+static void LoadMem (LoadState* S, void* b, int n, size_t size)
+{
+ LoadBlock(S,b,n*size);
+ if (S->swap)
+ {
+ char* p=(char*) b;
+ char c;
+ switch (size)
+ {
+ case 1:
+ break;
+ case 2:
+ while (n--)
+ {
+ c=p[0]; p[0]=p[1]; p[1]=c;
+ p+=2;
+ }
+ break;
+ case 4:
+ while (n--)
+ {
+ c=p[0]; p[0]=p[3]; p[3]=c;
+ c=p[1]; p[1]=p[2]; p[2]=c;
+ p+=4;
+ }
+ break;
+ case 8:
+ while (n--)
+ {
+ c=p[0]; p[0]=p[7]; p[7]=c;
+ c=p[1]; p[1]=p[6]; p[6]=c;
+ c=p[2]; p[2]=p[5]; p[5]=c;
+ c=p[3]; p[3]=p[4]; p[4]=c;
+ p+=8;
+ }
+ break;
+ default:
+ IF(1, "bad size");
+ break;
+ }
+ }
+}
+#endif
diff --git a/src/lundump.h b/src/lundump.h
index 924cfb01..5de3c46e 100644
--- a/src/lundump.h
+++ b/src/lundump.h
@@ -1,5 +1,5 @@
/*
-** $Id: lundump.h,v 1.35 2005/05/12 00:26:50 lhf Exp $
+** $Id: lundump.h,v 1.38 2005/09/02 01:54:47 lhf Exp $
** load pre-compiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -10,22 +10,53 @@
#include "lobject.h"
#include "lzio.h"
+/* make it work with Lua 5.0 */
+#ifndef LUA_VERSION_NUM
+#define LUAI_FUNC
+#define lua_Writer lua_Chunkwriter
+#endif
+
/* load one chunk; from lundump.c */
-LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char *name);
+LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name);
-/* find byte order; from lundump.c */
-LUAI_FUNC int luaU_endianness (void);
+/* make header; from lundump.c */
+LUAI_FUNC void luaU_header (char* h);
/* dump one chunk; from ldump.c */
-LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Chunkwriter w, void* data, int strip);
+LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);
/* print one chunk; from print.c */
LUAI_FUNC void luaU_print (const Proto* f, int full);
/* for header of binary files -- this is Lua 5.1 */
-#define VERSION 0x51
-
-/* for testing native format of lua_Numbers */
-#define TEST_NUMBER ((lua_Number)31415926.0)
+#define LUAC_VERSION 0x51
+
+/* for header of binary files -- this is the official format */
+#define LUAC_FORMAT 0
+
+/* size of header of binary files */
+#define LUAC_HEADERSIZE 12
+
+/* make it work with Lua 5.0 */
+#ifndef LUA_VERSION_NUM
+#define LUA_SIGNATURE "\033Lua"
+#define TValue TObject
+#define rawtsvalue tsvalue
+#define linedefined lineDefined
+#define lastlinedefined lineDefined
+#define setptvalue2s(L,t,f)
+#undef setsvalue2n
+#define setsvalue2n(L,x,y) setsvalue(x,y)
+#define LUA_QL(x) "'" x "'"
+#define LUA_QS LUA_QL("%s")
+#undef LUAC_VERSION
+#define LUAC_VERSION 0x50
+#ifdef lapi_c
+#define luaU_dump(L,f,w,d) (luaU_dump)(L,f,w,d,0)
+#endif
+#ifdef ldo_c
+#define luaU_undump(L,z,b) (luaU_undump)(L,z,b,z->name)
+#endif
+#endif
#endif
diff --git a/src/lvm.c b/src/lvm.c
index f591a35f..92c853b2 100644
--- a/src/lvm.c
+++ b/src/lvm.c
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.c,v 2.44 2005/05/17 19:49:15 roberto Exp $
+** $Id: lvm.c,v 2.55 2005/09/09 18:23:35 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -226,7 +226,7 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
if (ttype(l) != ttype(r))
return luaG_ordererror(L, l, r);
else if (ttisnumber(l))
- return luai_numlt(nvalue(l), nvalue(r));
+ return luai_numlt(L, nvalue(l), nvalue(r));
else if (ttisstring(l))
return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
@@ -240,7 +240,7 @@ static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
if (ttype(l) != ttype(r))
return luaG_ordererror(L, l, r);
else if (ttisnumber(l))
- return luai_numle(nvalue(l), nvalue(r));
+ return luai_numle(L, nvalue(l), nvalue(r));
else if (ttisstring(l))
return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
@@ -256,7 +256,7 @@ int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
lua_assert(ttype(t1) == ttype(t2));
switch (ttype(t1)) {
case LUA_TNIL: return 1;
- case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
+ case LUA_TNUMBER: return luai_numeq(L, nvalue(t1), nvalue(t2));
case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
case LUA_TUSERDATA: {
@@ -311,26 +311,26 @@ void luaV_concat (lua_State *L, int total, int last) {
}
-static StkId Arith (lua_State *L, StkId ra, const TValue *rb,
- const TValue *rc, TMS op) {
+static void Arith (lua_State *L, StkId ra, const TValue *rb,
+ const TValue *rc, TMS op) {
TValue tempb, tempc;
const TValue *b, *c;
if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
(c = luaV_tonumber(rc, &tempc)) != NULL) {
lua_Number nb = nvalue(b), nc = nvalue(c);
switch (op) {
- case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
- case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
- case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
- case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break;
- case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break;
- case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
+ case TM_ADD: setnvalue(ra, luai_numadd(L, nb, nc)); break;
+ case TM_SUB: setnvalue(ra, luai_numsub(L, nb, nc)); break;
+ case TM_MUL: setnvalue(ra, luai_nummul(L, nb, nc)); break;
+ case TM_DIV: setnvalue(ra, luai_numdiv(L, nb, nc)); break;
+ case TM_MOD: setnvalue(ra, luai_nummod(L, nb, nc)); break;
+ case TM_POW: setnvalue(ra, luai_numpow(L, nb, nc)); break;
+ case TM_UNM: setnvalue(ra, luai_numunm(L, nb)); break;
default: lua_assert(0); break;
}
}
else if (!call_binTM(L, rb, rc, ra, op))
luaG_aritherror(L, rb, rc);
- return L->base;
}
@@ -358,15 +358,12 @@ static StkId Arith (lua_State *L, StkId ra, const TValue *rb,
#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; }
-StkId luaV_execute (lua_State *L, int nexeccalls) {
+void luaV_execute (lua_State *L, int nexeccalls) {
LClosure *cl;
StkId base;
TValue *k;
const Instruction *pc;
- callentry: /* entry point when calling new functions */
- if (L->hookmask & LUA_MASKCALL)
- luaD_callhook(L, LUA_HOOKCALL, -1);
- retentry: /* entry point when returning to old functions */
+ reentry: /* entry point */
pc = L->savedpc;
cl = &clvalue(L->ci->func)->l;
base = L->base;
@@ -380,7 +377,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
traceexec(L, pc);
if (L->status == LUA_YIELD) { /* did hook yield? */
L->savedpc = pc - 1;
- return NULL;
+ return;
}
base = L->base;
}
@@ -462,7 +459,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
TValue *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) {
lua_Number nb = nvalue(rb), nc = nvalue(rc);
- setnvalue(ra, luai_numadd(nb, nc));
+ setnvalue(ra, luai_numadd(L, nb, nc));
}
else
Protect(Arith(L, ra, rb, rc, TM_ADD));
@@ -473,7 +470,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
TValue *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) {
lua_Number nb = nvalue(rb), nc = nvalue(rc);
- setnvalue(ra, luai_numsub(nb, nc));
+ setnvalue(ra, luai_numsub(L, nb, nc));
}
else
Protect(Arith(L, ra, rb, rc, TM_SUB));
@@ -484,7 +481,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
TValue *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) {
lua_Number nb = nvalue(rb), nc = nvalue(rc);
- setnvalue(ra, luai_nummul(nb, nc));
+ setnvalue(ra, luai_nummul(L, nb, nc));
}
else
Protect(Arith(L, ra, rb, rc, TM_MUL));
@@ -495,7 +492,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
TValue *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) {
lua_Number nb = nvalue(rb), nc = nvalue(rc);
- setnvalue(ra, luai_numdiv(nb, nc));
+ setnvalue(ra, luai_numdiv(L, nb, nc));
}
else
Protect(Arith(L, ra, rb, rc, TM_DIV));
@@ -506,7 +503,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
TValue *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) {
lua_Number nb = nvalue(rb), nc = nvalue(rc);
- setnvalue(ra, luai_nummod(nb, nc));
+ setnvalue(ra, luai_nummod(L, nb, nc));
}
else
Protect(Arith(L, ra, rb, rc, TM_MOD));
@@ -517,25 +514,20 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
TValue *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) {
lua_Number nb = nvalue(rb), nc = nvalue(rc);
- setnvalue(ra, luai_numpow(nb, nc));
+ setnvalue(ra, luai_numpow(L, nb, nc));
}
else
Protect(Arith(L, ra, rb, rc, TM_POW));
continue;
}
case OP_UNM: {
- const TValue *rb = RB(i);
- TValue temp;
- if (tonumber(rb, &temp)) {
+ TValue *rb = RB(i);
+ if (ttisnumber(rb)) {
lua_Number nb = nvalue(rb);
- setnvalue(ra, luai_numunm(nb));
+ setnvalue(ra, luai_numunm(L, nb));
}
else {
- rb = RB(i); /* `tonumber' erased `rb' */
- Protect(
- if (!call_binTM(L, rb, &luaO_nilobject, ra, TM_UNM))
- luaG_aritherror(L, rb, &luaO_nilobject);
- )
+ Protect(Arith(L, ra, rb, rb, TM_UNM));
}
continue;
}
@@ -544,16 +536,23 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
setbvalue(ra, res);
continue;
}
- case OP_SIZ: {
+ case OP_LEN: {
const TValue *rb = RB(i);
- if (ttype(rb) == LUA_TTABLE) {
- setnvalue(ra, cast(lua_Number, luaH_getn(hvalue(rb))));
- }
- else { /* try metamethod */
- Protect(
- if (!call_binTM(L, rb, &luaO_nilobject, ra, TM_SIZ))
- luaG_typeerror(L, rb, "get size of");
- )
+ switch (ttype(rb)) {
+ case LUA_TTABLE: {
+ setnvalue(ra, cast(lua_Number, luaH_getn(hvalue(rb))));
+ break;
+ }
+ case LUA_TSTRING: {
+ setnvalue(ra, cast(lua_Number, tsvalue(rb)->len));
+ break;
+ }
+ default: { /* try metamethod */
+ Protect(
+ if (!call_binTM(L, rb, &luaO_nilobject, ra, TM_LEN))
+ luaG_typeerror(L, rb, "get length of");
+ )
+ }
}
continue;
}
@@ -569,8 +568,10 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
continue;
}
case OP_EQ: {
+ TValue *rb = RKB(i);
+ TValue *rc = RKC(i);
Protect(
- if (equalobj(L, RKB(i), RKC(i)) == GETARG_A(i))
+ if (equalobj(L, rb, rc) == GETARG_A(i))
dojump(L, pc, GETARG_sBx(*pc));
)
pc++;
@@ -593,6 +594,12 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
continue;
}
case OP_TEST: {
+ if (l_isfalse(ra) == GETARG_C(i)) pc++;
+ else
+ dojump(L, pc, GETARG_sBx(*pc) + 1);
+ continue;
+ }
+ case OP_TESTSET: {
TValue *rb = RB(i);
if (l_isfalse(rb) == GETARG_C(i)) pc++;
else {
@@ -609,7 +616,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
switch (luaD_precall(L, ra, nresults)) {
case PCRLUA: {
nexeccalls++;
- goto callentry; /* restart luaV_execute over new Lua function */
+ goto reentry; /* restart luaV_execute over new Lua function */
}
case PCRC: {
/* it was a C function (`precall' called it); adjust results */
@@ -618,7 +625,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
continue;
}
default: {
- return NULL;
+ return; /* yield */
}
}
}
@@ -643,15 +650,14 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
ci->savedpc = L->savedpc;
ci->tailcalls++; /* one more call lost */
L->ci--; /* remove new frame */
- goto callentry;
+ goto reentry;
}
- case PCRC: {
- /* it was a C function (`precall' called it) */
+ case PCRC: { /* it was a C function (`precall' called it) */
base = L->base;
continue;
}
default: {
- return NULL;
+ return; /* yield */
}
}
}
@@ -660,22 +666,21 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
if (b != 0) L->top = ra+b-1;
if (L->openupval) luaF_close(L, base);
L->savedpc = pc;
+ b = luaD_poscall(L, ra);
if (--nexeccalls == 0) /* was previous function running `here'? */
- return ra; /* no: return */
+ return; /* no: return */
else { /* yes: continue its execution */
- int nresults = L->ci->nresults;
- lua_assert(isLua(L->ci - 1));
- lua_assert(GET_OPCODE(*((L->ci - 1)->savedpc - 1)) == OP_CALL);
- luaD_poscall(L, nresults, ra);
- if (nresults >= 0) L->top = L->ci->top;
- goto retentry;
+ if (b) L->top = L->ci->top;
+ lua_assert(isLua(L->ci));
+ lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL);
+ goto reentry;
}
}
case OP_FORLOOP: {
lua_Number step = nvalue(ra+2);
- lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
+ lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */
lua_Number limit = nvalue(ra+1);
- if (step > 0 ? luai_numle(idx, limit) : luai_numle(limit, idx)) {
+ if (step > 0 ? luai_numle(L, idx, limit) : luai_numle(L, limit, idx)) {
dojump(L, pc, GETARG_sBx(i)); /* jump back */
setnvalue(ra, idx); /* update internal index... */
setnvalue(ra+3, idx); /* ...and external index */
@@ -693,7 +698,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
luaG_runerror(L, LUA_QL("for") " limit must be a number");
else if (!tonumber(pstep, ra+2))
luaG_runerror(L, LUA_QL("for") " step must be a number");
- setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
+ setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep)));
dojump(L, pc, GETARG_sBx(i));
continue;
}
@@ -720,7 +725,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
int last;
Table *h;
if (n == 0) {
- n = L->top - ra - 1;
+ n = cast(int, L->top - ra) - 1;
L->top = L->ci->top;
}
if (c == 0) c = cast(int, *pc++);
@@ -764,15 +769,21 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
int b = GETARG_B(i) - 1;
int j;
CallInfo *ci = L->ci;
- int n = ci->base - ci->func - cl->p->numparams - 1;
+ int n = cast(int, ci->base - ci->func) - cl->p->numparams - 1;
if (b == LUA_MULTRET) {
+ Protect(luaD_checkstack(L, n));
+ ra = RA(i); /* previous call may change the stack */
b = n;
L->top = ra + n;
}
- for (j=0; j<b && j<n; j++)
- setobjs2s(L, ra+j, ci->base - n + j);
- for (; j<b; j++)
- setnilvalue(ra+j);
+ for (j = 0; j < b; j++) {
+ if (j < n) {
+ setobjs2s(L, ra + j, ci->base - n + j);
+ }
+ else {
+ setnilvalue(ra + j);
+ }
+ }
continue;
}
}
diff --git a/src/lvm.h b/src/lvm.h
index b00cb8f2..788423f8 100644
--- a/src/lvm.h
+++ b/src/lvm.h
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.h,v 2.4 2005/04/25 19:24:10 roberto Exp $
+** $Id: lvm.h,v 2.5 2005/08/22 18:54:49 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -30,7 +30,7 @@ LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
StkId val);
LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
StkId val);
-LUAI_FUNC StkId luaV_execute (lua_State *L, int nexeccalls);
+LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls);
LUAI_FUNC void luaV_concat (lua_State *L, int total, int last);
#endif
diff --git a/src/lzio.c b/src/lzio.c
index abe086b4..5121ada8 100644
--- a/src/lzio.c
+++ b/src/lzio.c
@@ -1,5 +1,5 @@
/*
-** $Id: lzio.c,v 1.30 2005/05/17 19:49:15 roberto Exp $
+** $Id: lzio.c,v 1.31 2005/06/03 20:15:29 roberto Exp $
** a generic input stream interface
** See Copyright Notice in lua.h
*/
@@ -34,10 +34,12 @@ int luaZ_fill (ZIO *z) {
int luaZ_lookahead (ZIO *z) {
if (z->n == 0) {
- int c = luaZ_fill(z);
- if (c == EOZ) return c;
- z->n++;
- z->p--;
+ if (luaZ_fill(z) == EOZ)
+ return EOZ;
+ else {
+ z->n++; /* luaZ_fill removed first byte; put back it */
+ z->p--;
+ }
}
return char2int(*z->p);
}
@@ -56,14 +58,8 @@ void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
size_t luaZ_read (ZIO *z, void *b, size_t n) {
while (n) {
size_t m;
- if (z->n == 0) {
- if (luaZ_fill(z) == EOZ)
- return n; /* return number of missing bytes */
- else {
- ++z->n; /* filbuf removed first byte; put back it */
- --z->p;
- }
- }
+ if (luaZ_lookahead(z) == EOZ)
+ return n; /* return number of missing bytes */
m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
memcpy(b, z->p, m);
z->n -= m;
diff --git a/src/print.c b/src/print.c
index 85308705..8090a2d5 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1,5 +1,5 @@
/*
-** $Id: print.c,v 1.50 2005/05/12 00:26:50 lhf Exp $
+** $Id: print.c,v 1.52 2005/06/08 14:40:44 lhf Exp $
** print bytecodes
** See Copyright Notice in lua.h
*/
@@ -135,6 +135,10 @@ static void PrintCode(const Proto* f)
case OP_CLOSURE:
printf("\t; %p",VOID(f->p[bx]));
break;
+ case OP_SETLIST:
+ if (c==0) printf("\t; %d",(int)code[++pc]);
+ else printf("\t; %d",c);
+ break;
default:
break;
}
@@ -158,7 +162,7 @@ static void PrintHeader(const Proto* f)
(f->linedefined==0)?"main":"function",s,
f->linedefined,f->lastlinedefined,
S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f));
- printf("%d%s param%s, %d stack%s, %d upvalue%s, ",
+ printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
f->numparams,f->is_vararg?"+":"",SS(f->numparams),
S(f->maxstacksize),S(f->nups));
printf("%d local%s, %d constant%s, %d function%s\n",