diff options
author | Lua Team <team@lua.org> | 2005-05-20 12:00:00 +0000 |
---|---|---|
committer | repogen <> | 2005-05-20 12:00:00 +0000 |
commit | bf6b5550cdfbc0c4a3a4577776ad76628d80718e (patch) | |
tree | d714ef8ac5581536c0f8bb2c8e90e2b8207799b1 /src | |
parent | e6ddfd3b09c0a3727afc773029c323a3defe50fa (diff) | |
download | lua-github-bf6b5550cdfbc0c4a3a4577776ad76628d80718e.tar.gz |
Lua 5.1-work65.1-work6
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 34 | ||||
-rw-r--r-- | src/lapi.c | 85 | ||||
-rw-r--r-- | src/lapi.h | 4 | ||||
-rw-r--r-- | src/lauxlib.c | 67 | ||||
-rw-r--r-- | src/lauxlib.h | 8 | ||||
-rw-r--r-- | src/lbaselib.c | 33 | ||||
-rw-r--r-- | src/lcode.c | 31 | ||||
-rw-r--r-- | src/lcode.h | 66 | ||||
-rw-r--r-- | src/ldblib.c | 114 | ||||
-rw-r--r-- | src/ldebug.c | 115 | ||||
-rw-r--r-- | src/ldebug.h | 21 | ||||
-rw-r--r-- | src/ldo.c | 40 | ||||
-rw-r--r-- | src/ldo.h | 28 | ||||
-rw-r--r-- | src/ldump.c | 5 | ||||
-rw-r--r-- | src/lfunc.c | 9 | ||||
-rw-r--r-- | src/lfunc.h | 24 | ||||
-rw-r--r-- | src/lgc.c | 17 | ||||
-rw-r--r-- | src/lgc.h | 20 | ||||
-rw-r--r-- | src/linit.c | 14 | ||||
-rw-r--r-- | src/liolib.c | 8 | ||||
-rw-r--r-- | src/llex.c | 35 | ||||
-rw-r--r-- | src/llex.h | 18 | ||||
-rw-r--r-- | src/llimits.h | 14 | ||||
-rw-r--r-- | src/lmathlib.c | 31 | ||||
-rw-r--r-- | src/lmem.h | 23 | ||||
-rw-r--r-- | src/loadlib.c | 74 | ||||
-rw-r--r-- | src/lobject.c | 10 | ||||
-rw-r--r-- | src/lobject.h | 24 | ||||
-rw-r--r-- | src/lopcodes.c | 8 | ||||
-rw-r--r-- | src/lopcodes.h | 10 | ||||
-rw-r--r-- | src/loslib.c | 19 | ||||
-rw-r--r-- | src/lparser.c | 64 | ||||
-rw-r--r-- | src/lparser.h | 11 | ||||
-rw-r--r-- | src/lstate.c | 39 | ||||
-rw-r--r-- | src/lstate.h | 12 | ||||
-rw-r--r-- | src/lstring.h | 8 | ||||
-rw-r--r-- | src/lstrlib.c | 62 | ||||
-rw-r--r-- | src/ltable.c | 67 | ||||
-rw-r--r-- | src/ltable.h | 25 | ||||
-rw-r--r-- | src/ltablib.c | 39 | ||||
-rw-r--r-- | src/ltm.c | 10 | ||||
-rw-r--r-- | src/ltm.h | 13 | ||||
-rw-r--r-- | src/lua.c | 137 | ||||
-rw-r--r-- | src/lua.h | 56 | ||||
-rw-r--r-- | src/luac.c | 4 | ||||
-rw-r--r-- | src/luaconf.h | 697 | ||||
-rw-r--r-- | src/lualib.h | 6 | ||||
-rw-r--r-- | src/lundump.c | 5 | ||||
-rw-r--r-- | src/lundump.h | 10 | ||||
-rw-r--r-- | src/lvm.c | 358 | ||||
-rw-r--r-- | src/lvm.h | 22 | ||||
-rw-r--r-- | src/lzio.c | 4 | ||||
-rw-r--r-- | src/lzio.h | 23 | ||||
-rw-r--r-- | src/print.c | 33 |
54 files changed, 1574 insertions, 1140 deletions
diff --git a/src/Makefile b/src/Makefile index 9ec6d349..60fd14c8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -9,20 +9,21 @@ CFLAGS= -O2 -Wall $(MYCFLAGS) AR= ar rcu RANLIB= ranlib RM= rm -f +LIBS= -lm $(MYLIBS) MYCFLAGS= MYLDFLAGS= -MYLIBS= -lm -DL= -ldl -Wl,-E # enable dynamic loading in Linux +MYLIBS= +# enable dynamic loading and line editing in Linux +# MYCFLAGS= -DLUA_USE_DLOPEN -DLUA_USE_READLINE +# MYLIBS= -Wl,-E -ldl -lreadline -lhistory -lncurses # == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE ========= -CORE_T= liblua.a +LUA_A= liblua.a CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \ lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \ lundump.o lvm.o lzio.o - -LIB_T= liblualib.a LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \ lstrlib.o loadlib.o linit.o @@ -30,11 +31,11 @@ LUA_T= lua LUA_O= lua.o LUAC_T= luac -LUAC_O= luac.o print.o lauxlib.o +LUAC_O= luac.o print.o -ALL_T= $(CORE_T) $(LIB_T) $(LUA_T) $(LUAC_T) ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O) -ALL_A= $(CORE_T) $(LIB_T) +ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) +ALL_A= $(LUA_A) all: $(ALL_T) @@ -42,25 +43,21 @@ o: $(ALL_O) a: $(ALL_A) -$(CORE_T): $(CORE_O) - $(AR) $@ $? - $(RANLIB) $@ - -$(LIB_T): $(LIB_O) +$(LUA_A): $(CORE_O) $(LIB_O) $(AR) $@ $? $(RANLIB) $@ -$(LUA_T): $(LUA_O) $(CORE_T) $(LIB_T) - $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) -L. -llua -llualib $(MYLIBS) $(DL) +$(LUA_T): $(LUA_O) $(LUA_A) + $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) -$(LUAC_T): $(LUAC_O) $(CORE_T) - $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) -L. -llua $(MYLIBS) +$(LUAC_T): $(LUAC_O) $(LUA_A) + $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) clean: $(RM) $(ALL_T) $(ALL_O) depend: - @$(CC) $(CFLAGS) -MM *.c + @$(CC) $(CFLAGS) -MM l*.c print.c echo: @echo "CC = $(CC)" @@ -71,7 +68,6 @@ echo: @echo "MYCFLAGS = $(MYCFLAGS)" @echo "MYLDFLAGS = $(MYLDFLAGS)" @echo "MYLIBS = $(MYLIBS)" - @echo "DL = $(DL)" # DO NOT DELETE @@ -1,11 +1,12 @@ /* -** $Id: lapi.c,v 2.28 2005/02/23 17:30:22 roberto Exp $ +** $Id: lapi.c,v 2.41 2005/05/17 19:49:15 roberto Exp $ ** Lua API ** See Copyright Notice in lua.h */ #include <assert.h> +#include <math.h> #include <stdarg.h> #include <string.h> @@ -87,14 +88,14 @@ static Table *getcurrenv (lua_State *L) { void luaA_pushobject (lua_State *L, const TValue *o) { setobj2s(L, L->top, o); - incr_top(L); + api_incr_top(L); } LUA_API int lua_checkstack (lua_State *L, int size) { int res; lua_lock(L); - if ((L->top - L->base + size) > MAXCSTACK) + if ((L->top - L->base + size) > LUAI_MAXCSTACK) res = 0; /* stack overflow */ else { luaD_checkstack(L, size); @@ -140,7 +141,7 @@ LUA_API lua_State *lua_newthread (lua_State *L) { setthvalue(L, L->top, L1); api_incr_top(L); lua_unlock(L); - lua_userstateopen(L1); + luai_userstateopen(L1); return L1; } @@ -318,7 +319,8 @@ LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) { const TValue *o = index2adr(L, idx); if (tonumber(o, &n)) { lua_Integer res; - lua_number2integer(res, nvalue(o)); + lua_Number num = nvalue(o); + lua_number2integer(res, num); return res; } else @@ -332,33 +334,37 @@ LUA_API int lua_toboolean (lua_State *L, int idx) { } -LUA_API const char *lua_tostring (lua_State *L, int idx) { +LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { StkId o = index2adr(L, idx); - if (ttisstring(o)) - return svalue(o); - else { - const char *s; + if (!ttisstring(o)) { lua_lock(L); /* `luaV_tostring' may create a new string */ - s = (luaV_tostring(L, o) ? svalue(o) : NULL); + if (!luaV_tostring(L, o)) { /* conversion failed? */ + if (len != NULL) *len = 0; + lua_unlock(L); + return NULL; + } luaC_checkGC(L); lua_unlock(L); - return s; } + if (len != NULL) *len = tsvalue(o)->len; + return svalue(o); } LUA_API size_t lua_objsize (lua_State *L, int idx) { StkId o = index2adr(L, idx); - if (ttisstring(o)) - return tsvalue(o)->len; - else if (ttisuserdata(o)) - return uvalue(o)->len; - else { - size_t l; - lua_lock(L); /* `luaV_tostring' may create a new string */ - l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0); - lua_unlock(L); - return l; + switch (ttype(o)) { + case LUA_TSTRING: return tsvalue(o)->len; + case LUA_TUSERDATA: return uvalue(o)->len; + case LUA_TTABLE: return luaH_getn(hvalue(o)); + case LUA_TNUMBER: { + size_t l; + lua_lock(L); /* `luaV_tostring' may create a new string */ + l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0); + lua_unlock(L); + return l; + } + default: return 0; } } @@ -523,7 +529,7 @@ LUA_API void lua_gettable (lua_State *L, int idx) { lua_lock(L); t = index2adr(L, idx); api_checkvalidindex(L, t); - luaV_gettable(L, t, L->top - 1, L->top - 1, NULL); + luaV_gettable(L, t, L->top - 1, L->top - 1); lua_unlock(L); } @@ -535,7 +541,7 @@ LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { t = index2adr(L, idx); api_checkvalidindex(L, t); setsvalue(L, &key, luaS_new(L, k)); - luaV_gettable(L, t, &key, L->top, NULL); + luaV_gettable(L, t, &key, L->top); api_incr_top(L); lua_unlock(L); } @@ -584,6 +590,9 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) { case LUA_TUSERDATA: mt = uvalue(obj)->metatable; break; + default: + mt = G(L)->mt[ttype(obj)]; + break; } if (mt == NULL) res = 0; @@ -629,7 +638,7 @@ LUA_API void lua_settable (lua_State *L, int idx) { api_checknelems(L, 2); t = index2adr(L, idx); api_checkvalidindex(L, t); - luaV_settable(L, t, L->top - 2, L->top - 1, NULL); + luaV_settable(L, t, L->top - 2, L->top - 1); L->top -= 2; /* pop index and value */ lua_unlock(L); } @@ -643,7 +652,7 @@ LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { t = index2adr(L, idx); api_checkvalidindex(L, t); setsvalue(L, &key, luaS_new(L, k)); - luaV_settable(L, t, &key, L->top - 1, NULL); + luaV_settable(L, t, &key, L->top - 1); L->top--; /* pop value */ lua_unlock(L); } @@ -678,7 +687,6 @@ LUA_API void lua_rawseti (lua_State *L, int idx, int n) { LUA_API int lua_setmetatable (lua_State *L, int objindex) { TValue *obj; Table *mt; - int res = 1; lua_lock(L); api_checknelems(L, 1); obj = index2adr(L, objindex); @@ -703,13 +711,13 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { break; } default: { - res = 0; /* cannot set */ + G(L)->mt[ttype(obj)] = mt; break; } } L->top--; lua_unlock(L); - return res; + return 1; } @@ -819,9 +827,9 @@ static void f_Ccall (lua_State *L, void *ud) { cl = luaF_newCclosure(L, 0, getcurrenv(L)); cl->c.f = c->func; setclvalue(L, L->top, cl); /* push function */ - incr_top(L); + api_incr_top(L); setpvalue(L->top, c->ud); /* push only argument */ - incr_top(L); + api_incr_top(L); luaD_call(L, L->top - 2, 0); } @@ -838,7 +846,7 @@ LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) { } -LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data, +LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, const char *chunkname) { ZIO z; int status; @@ -851,7 +859,7 @@ LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data, } -LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data) { +LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { int status; TValue *o; lua_lock(L); @@ -904,12 +912,15 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { g->GCthreshold = g->totalbytes - a; else g->GCthreshold = 0; - luaC_step(L); + while (g->GCthreshold <= g->totalbytes) + luaC_step(L); + if (g->gcstate == GCSpause) /* end of cycle? */ + res = 1; /* signal it */ break; } - case LUA_GCSETPACE: { - res = g->gcpace; - g->gcpace = data; + case LUA_GCSETPAUSE: { + res = g->gcpause; + g->gcpause = data; break; } case LUA_GCSETSTEPMUL: { @@ -1,5 +1,5 @@ /* -** $Id: lapi.h,v 2.1 2003/12/10 12:13:36 roberto Exp $ +** $Id: lapi.h,v 2.2 2005/04/25 19:24:10 roberto Exp $ ** Auxiliary functions from Lua API ** See Copyright Notice in lua.h */ @@ -11,6 +11,6 @@ #include "lobject.h" -void luaA_pushobject (lua_State *L, const TValue *o); +LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o); #endif diff --git a/src/lauxlib.c b/src/lauxlib.c index ac53db39..964f5eb0 100644 --- a/src/lauxlib.c +++ b/src/lauxlib.c @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.c,v 1.129 2005/02/23 17:30:22 roberto Exp $ +** $Id: lauxlib.c,v 1.133 2005/05/17 19:49:15 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -25,12 +25,7 @@ #include "lauxlib.h" -/* number of prereserved references (for internal use) */ -#define RESERVED_REFS 2 - -/* reserved references */ -#define FREELIST_REF 1 /* free list of references */ -#define ARRAYSIZE_REF 2 /* array sizes */ +#define FREELIST_REF 0 /* free list of references */ /* convert a stack index to positive */ @@ -52,11 +47,12 @@ LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { if (strcmp(ar.namewhat, "method") == 0) { narg--; /* do not count `self' */ if (narg == 0) /* error is in the self argument itself? */ - return luaL_error(L, "calling `%s' on bad self (%s)", ar.name, extramsg); + return luaL_error(L, "calling " LUA_QS " on bad self (%s)", + ar.name, extramsg); } if (ar.name == NULL) ar.name = "?"; - return luaL_error(L, "bad argument #%d to `%s' (%s)", + return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", narg, ar.name, extramsg); } @@ -163,9 +159,8 @@ LUALIB_API void luaL_checkany (lua_State *L, int narg) { LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) { - const char *s = lua_tostring(L, narg); + const char *s = lua_tolstring(L, narg, len); if (!s) tag_error(L, narg, LUA_TSTRING); - if (len) *len = lua_strlen(L, narg); return s; } @@ -250,7 +245,7 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname, luaL_setfield(L, LUA_GLOBALSINDEX, libname); } else if (!lua_istable(L, -1)) - luaL_error(L, "name conflict for library `%s'", libname); + 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 */ @@ -275,6 +270,8 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname, ** ======================================================= */ +#ifndef luaL_getn + static int checkint (lua_State *L, int topop) { int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1; lua_pop(L, topop); @@ -283,7 +280,7 @@ static int checkint (lua_State *L, int topop) { static void getsizes (lua_State *L) { - lua_rawgeti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); + lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); if (lua_isnil(L, -1)) { /* no `size' table? */ lua_pop(L, 1); /* remove nil */ lua_newtable(L); /* create it */ @@ -292,7 +289,7 @@ static void getsizes (lua_State *L) { lua_pushliteral(L, "kv"); lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */ lua_pushvalue(L, -1); - lua_rawseti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); /* store in register */ + lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */ } } @@ -307,31 +304,6 @@ LUALIB_API void luaL_setn (lua_State *L, int t, int n) { } -/* find an `n' such that t[n] ~= nil and t[n+1] == nil */ -static int countn (lua_State *L, int t) { - int i = LUA_FIRSTINDEX - 1; - int j = 2; - /* find `i' such that i <= n < i*2 (= j) */ - for (;;) { - lua_rawgeti(L, t, j); - if (lua_isnil(L, -1)) break; - lua_pop(L, 1); - i = j; - j = i*2; - } - lua_pop(L, 1); - /* i <= n < j; do a binary search */ - while (i < j-1) { - int m = (i+j)/2; - lua_rawgeti(L, t, m); - if (lua_isnil(L, -1)) j = m; - else i = m; - lua_pop(L, 1); - } - return i - LUA_FIRSTINDEX + 1; -} - - LUALIB_API int luaL_getn (lua_State *L, int t) { int n; t = abs_index(L, t); @@ -341,9 +313,11 @@ 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 countn(L, t); + return lua_objsize(L, t); } +#endif + /* }====================================================== */ @@ -392,7 +366,8 @@ LUALIB_API const char *luaL_searchpath (lua_State *L, const char *name, for (;;) { const char *fname; if ((p = pushnexttemplate(L, p)) == NULL) { - lua_pushfstring(L, "no readable `%s' in path `%s'", name, path); + 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); @@ -523,9 +498,10 @@ LUALIB_API void luaL_pushresult (luaL_Buffer *B) { LUALIB_API void luaL_addvalue (luaL_Buffer *B) { lua_State *L = B->L; - size_t vl = lua_strlen(L, -1); + size_t vl; + const char *s = lua_tolstring(L, -1, &vl); if (vl <= bufffree(B)) { /* fit into buffer? */ - memcpy(B->p, lua_tostring(L, -1), vl); /* put it there */ + memcpy(B->p, s, vl); /* put it there */ B->p += vl; lua_pop(L, 1); /* remove from stack */ } @@ -562,11 +538,8 @@ 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 = luaL_getn(L, t); - if (ref < RESERVED_REFS) - ref = RESERVED_REFS; /* skip reserved references */ + ref = lua_objsize(L, t); ref++; /* create new reference */ - luaL_setn(L, t, ref); } lua_rawseti(L, t, ref); return ref; diff --git a/src/lauxlib.h b/src/lauxlib.h index 82585cf4..83c807e9 100644 --- a/src/lauxlib.h +++ b/src/lauxlib.h @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.h,v 1.74 2005/01/10 17:31:50 roberto Exp $ +** $Id: lauxlib.h,v 1.75 2005/03/29 16:20:48 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -15,6 +15,12 @@ #include "lua.h" +#if !LUA_COMPAT_GETN +#define luaL_getn(L,i) lua_objsize(L, i) +#define luaL_setn(L,i,j) ((void)0) /* no op! */ +#endif + + /* extra error code for `luaL_load' */ #define LUA_ERRFILE (LUA_ERRERR+1) diff --git a/src/lbaselib.c b/src/lbaselib.c index 9e1573cb..d69d83ff 100644 --- a/src/lbaselib.c +++ b/src/lbaselib.c @@ -1,5 +1,5 @@ /* -** $Id: lbaselib.c,v 1.169 2005/02/28 17:24:41 roberto Exp $ +** $Id: lbaselib.c,v 1.176 2005/05/17 19:49:15 roberto Exp $ ** Basic library ** See Copyright Notice in lua.h */ @@ -39,7 +39,8 @@ static int luaB_print (lua_State *L) { lua_call(L, 1, 1); s = lua_tostring(L, -1); /* get result */ if (s == NULL) - return luaL_error(L, "`tostring' must return a string to `print'"); + return luaL_error(L, LUA_QL("tostring") " must return a string to " + LUA_QL("print")); if (i>1) fputs("\t", stdout); fputs(s, stdout); lua_pop(L, 1); /* pop result */ @@ -148,7 +149,8 @@ static int luaB_setfenv (lua_State *L) { return 0; } else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0) - luaL_error(L, "`setfenv' cannot change environment of given object"); + luaL_error(L, + LUA_QL("setfenv") " cannot change environment of given object"); return 1; } @@ -164,6 +166,7 @@ static int luaB_rawequal (lua_State *L) { static int luaB_rawget (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); luaL_checkany(L, 2); + lua_settop(L, 2); lua_rawget(L, 1); return 1; } @@ -172,6 +175,7 @@ static int luaB_rawset (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); luaL_checkany(L, 2); luaL_checkany(L, 3); + lua_settop(L, 3); lua_rawset(L, 1); return 1; } @@ -185,9 +189,9 @@ static int luaB_gcinfo (lua_State *L) { static int luaB_collectgarbage (lua_State *L) { static const char *const opts[] = {"stop", "restart", "collect", - "count", "step", "setpace", "setstepmul", NULL}; + "count", "step", "setpause", "setstepmul", NULL}; static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, - LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPACE, LUA_GCSETSTEPMUL}; + LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL}; int o = luaL_findstring(luaL_optstring(L, 1, "collect"), opts); int ex = luaL_optinteger(L, 2, 0); luaL_argcheck(L, o >= 0, 1, "invalid option"); @@ -238,7 +242,7 @@ static int luaB_ipairs (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ lua_pushvalue(L, 1); /* state, */ - lua_pushinteger(L, LUA_FIRSTINDEX - 1); /* and initial value */ + lua_pushinteger(L, 0); /* and initial value */ return 3; } @@ -292,11 +296,8 @@ static const char *generic_reader (lua_State *L, void *ud, size_t *size) { return NULL; } else if (lua_isstring(L, -1)) { - const char *res; lua_replace(L, 3); /* save string in a reserved stack slot */ - res = lua_tostring(L, 3); - *size = lua_strlen(L, 3); - return res; + return lua_tolstring(L, 3, size); } else luaL_error(L, "reader function must return a string"); return NULL; /* to avoid warnings */ @@ -330,13 +331,20 @@ 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, LUA_FIRSTINDEX); + int i = luaL_optint(L, 2, 1); int e = luaL_optint(L, 3, -1); int n; luaL_checktype(L, 1, LUA_TTABLE); if (e == -1) - e = luaL_getn(L, 1) + LUA_FIRSTINDEX - 1; + e = luaL_getn(L, 1); n = e - i + 1; /* number of elements */ if (n <= 0) return 0; /* empty range */ luaL_checkstack(L, n, "table too big to unpack"); @@ -446,6 +454,7 @@ static const luaL_reg base_funcs[] = { {"tostring", luaB_tostring}, {"type", luaB_type}, {"assert", luaB_assert}, + {"getn", luaB_getn}, {"unpack", luaB_unpack}, {"select", luaB_select}, {"rawequal", luaB_rawequal}, diff --git a/src/lcode.c b/src/lcode.c index b40bc5a1..1e8d80fb 100644 --- a/src/lcode.c +++ b/src/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 2.9 2005/01/10 18:17:39 roberto Exp $ +** $Id: lcode.c,v 2.12 2005/03/16 16:59:21 roberto Exp $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -603,19 +603,32 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { - if (op == OPR_MINUS) { - luaK_exp2val(fs, e); - if (e->k == VK && ttisnumber(&fs->f->k[e->info])) - e->info = luaK_numberK(fs, num_unm(nvalue(&fs->f->k[e->info]))); - else { + switch (op) { + 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]))); + else { + luaK_exp2anyreg(fs, e); + freeexp(fs, e); + e->info = luaK_codeABC(fs, OP_UNM, 0, e->info, 0); + e->k = VRELOCABLE; + } + break; + } + case OPR_NOT: { + codenot(fs, e); + break; + } + case OPR_SIZE: { luaK_exp2anyreg(fs, e); freeexp(fs, e); - e->info = luaK_codeABC(fs, OP_UNM, 0, e->info, 0); + e->info = luaK_codeABC(fs, OP_SIZ, 0, e->info, 0); e->k = VRELOCABLE; + break; } + default: lua_assert(0); } - else /* op == NOT */ - codenot(fs, e); } diff --git a/src/lcode.h b/src/lcode.h index 532b3478..19a3284e 100644 --- a/src/lcode.h +++ b/src/lcode.h @@ -1,5 +1,5 @@ /* -** $Id: lcode.h,v 1.40 2004/10/04 19:01:53 roberto Exp $ +** $Id: lcode.h,v 1.43 2005/04/25 19:24:10 roberto Exp $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -24,7 +24,7 @@ ** grep "ORDER OPR" if you change these enums */ typedef enum BinOpr { - OPR_ADD, OPR_SUB, OPR_MULT, OPR_DIV, OPR_POW, + OPR_ADD, OPR_SUB, OPR_MULT, OPR_DIV, OPR_MOD, OPR_POW, OPR_CONCAT, OPR_NE, OPR_EQ, OPR_LT, OPR_LE, OPR_GT, OPR_GE, @@ -34,7 +34,7 @@ typedef enum BinOpr { #define binopistest(op) ((op) >= OPR_NE) -typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_NOUNOPR } UnOpr; +typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_SIZE, OPR_NOUNOPR } UnOpr; #define getcode(fs,e) ((fs)->f->code[(e)->info]) @@ -43,36 +43,36 @@ typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_NOUNOPR } UnOpr; #define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) -int luaK_code (FuncState *fs, Instruction i, int line); -int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); -int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); -void luaK_fixline (FuncState *fs, int line); -void luaK_nil (FuncState *fs, int from, int n); -void luaK_reserveregs (FuncState *fs, int n); -void luaK_checkstack (FuncState *fs, int n); -int luaK_stringK (FuncState *fs, TString *s); -int luaK_numberK (FuncState *fs, lua_Number r); -void luaK_dischargevars (FuncState *fs, expdesc *e); -int luaK_exp2anyreg (FuncState *fs, expdesc *e); -void luaK_exp2nextreg (FuncState *fs, expdesc *e); -void luaK_exp2val (FuncState *fs, expdesc *e); -int luaK_exp2RK (FuncState *fs, expdesc *e); -void luaK_self (FuncState *fs, expdesc *e, expdesc *key); -void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); -void luaK_goiftrue (FuncState *fs, expdesc *e); -void luaK_goiffalse (FuncState *fs, expdesc *e); -void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); -void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); -void luaK_setoneret (FuncState *fs, expdesc *e); -int luaK_jump (FuncState *fs); -void luaK_patchlist (FuncState *fs, int list, int target); -void luaK_patchtohere (FuncState *fs, int list); -void luaK_concat (FuncState *fs, int *l1, int l2); -int luaK_getlabel (FuncState *fs); -void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v); -void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); -void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2); -void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); +LUAI_FUNC int luaK_code (FuncState *fs, Instruction i, int line); +LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); +LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); +LUAI_FUNC void luaK_fixline (FuncState *fs, int line); +LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); +LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); +LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); +LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); +LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); +LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); +LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); +LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); +LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); +LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_jump (FuncState *fs); +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); +LUAI_FUNC int luaK_getlabel (FuncState *fs); +LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v); +LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); +LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2); +LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); #endif diff --git a/src/ldblib.c b/src/ldblib.c index 7f8bde1f..6c1a1776 100644 --- a/src/ldblib.c +++ b/src/ldblib.c @@ -1,5 +1,5 @@ /* -** $Id: ldblib.c,v 1.93 2005/02/18 12:40:02 roberto Exp $ +** $Id: ldblib.c,v 1.98 2005/05/17 19:49:15 roberto Exp $ ** Interface from Lua to its debug API ** See Copyright Notice in lua.h */ @@ -19,7 +19,7 @@ -static int getmetatable (lua_State *L) { +static int db_getmetatable (lua_State *L) { luaL_checkany(L, 1); if (!lua_getmetatable(L, 1)) { lua_pushnil(L); /* no metatable */ @@ -28,7 +28,7 @@ static int getmetatable (lua_State *L) { } -static int setmetatable (lua_State *L) { +static int db_setmetatable (lua_State *L) { int t = lua_type(L, 2); luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table expected"); @@ -38,17 +38,18 @@ static int setmetatable (lua_State *L) { } -static int getfenv (lua_State *L) { +static int db_getfenv (lua_State *L) { lua_getfenv(L, 1); return 1; } -static int setfenv (lua_State *L) { +static int db_setfenv (lua_State *L) { luaL_checktype(L, 2, LUA_TTABLE); lua_settop(L, 2); if (lua_setfenv(L, 1) == 0) - luaL_error(L, "`setfenv' cannot change environment of given object"); + luaL_error(L, LUA_QL("setfenv") + " cannot change environment of given object"); return 1; } @@ -77,7 +78,18 @@ static lua_State *getthread (lua_State *L, int *arg) { } -static int getinfo (lua_State *L) { +static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) { + if (L == L1) { + lua_pushvalue(L, -2); + lua_remove(L, -3); + } + else + lua_xmove(L1, L, 1); + lua_setfield(L, -2, fname); +} + + +static int db_getinfo (lua_State *L) { lua_Debug ar; int arg; lua_State *L1 = getthread(L, &arg); @@ -99,38 +111,30 @@ static int getinfo (lua_State *L) { if (!lua_getinfo(L1, options, &ar)) return luaL_argerror(L, arg+2, "invalid option"); lua_newtable(L); - for (; *options; options++) { - switch (*options) { - case 'S': - settabss(L, "source", ar.source); - settabss(L, "short_src", ar.short_src); - settabsi(L, "linedefined", ar.linedefined); - settabss(L, "what", ar.what); - break; - case 'l': - settabsi(L, "currentline", ar.currentline); - break; - case 'u': - settabsi(L, "nups", ar.nups); - break; - case 'n': - settabss(L, "name", ar.name); - settabss(L, "namewhat", ar.namewhat); - break; - case 'f': - if (L == L1) - lua_pushvalue(L, -2); - else - lua_xmove(L1, L, 1); - lua_setfield(L, -2, "func"); - break; - } + if (strchr(options, 'S')) { + settabss(L, "source", ar.source); + settabss(L, "short_src", ar.short_src); + settabsi(L, "linedefined", ar.linedefined); + settabsi(L, "lastlinedefined", ar.lastlinedefined); + settabss(L, "what", ar.what); + } + if (strchr(options, 'l')) + settabsi(L, "currentline", ar.currentline); + if (strchr(options, 'u')) + settabsi(L, "nups", ar.nups); + if (strchr(options, 'n')) { + settabss(L, "name", ar.name); + settabss(L, "namewhat", ar.namewhat); } + if (strchr(options, 'L')) + treatstackoption(L, L1, "activelines"); + if (strchr(options, 'f')) + treatstackoption(L, L1, "func"); return 1; /* return table */ } -static int getlocal (lua_State *L) { +static int db_getlocal (lua_State *L) { int arg; lua_State *L1 = getthread(L, &arg); lua_Debug ar; @@ -151,7 +155,7 @@ static int getlocal (lua_State *L) { } -static int setlocal (lua_State *L) { +static int db_setlocal (lua_State *L) { int arg; lua_State *L1 = getthread(L, &arg); lua_Debug ar; @@ -178,12 +182,12 @@ static int auxupvalue (lua_State *L, int get) { } -static int getupvalue (lua_State *L) { +static int db_getupvalue (lua_State *L) { return auxupvalue(L, 1); } -static int setupvalue (lua_State *L) { +static int db_setupvalue (lua_State *L) { luaL_checkany(L, 3); return auxupvalue(L, 0); } @@ -244,7 +248,7 @@ static void gethooktable (lua_State *L) { } -static int sethook (lua_State *L) { +static int db_sethook (lua_State *L) { int arg; lua_State *L1 = getthread(L, &arg); if (lua_isnoneornil(L, arg+1)) { @@ -267,7 +271,7 @@ static int sethook (lua_State *L) { } -static int gethook (lua_State *L) { +static int db_gethook (lua_State *L) { int arg; lua_State *L1 = getthread(L, &arg); char buff[5]; @@ -288,7 +292,7 @@ static int gethook (lua_State *L) { } -static int debug (lua_State *L) { +static int db_debug (lua_State *L) { for (;;) { char buffer[250]; fputs("lua_debug> ", stderr); @@ -308,7 +312,7 @@ static int debug (lua_State *L) { #define LEVELS1 12 /* size of the first part of the stack */ #define LEVELS2 10 /* size of the second part of the stack */ -static int errorfb (lua_State *L) { +static int db_errorfb (lua_State *L) { int level; int firstpart = 1; /* still before eventual `...' */ int arg; @@ -344,7 +348,7 @@ static int errorfb (lua_State *L) { if (ar.currentline > 0) lua_pushfstring(L, "%d:", ar.currentline); if (*ar.namewhat != '\0') /* is there a name? */ - lua_pushfstring(L, " in function `%s'", ar.name); + lua_pushfstring(L, " in function " LUA_QS, ar.name); else { if (*ar.what == 'm') /* main? */ lua_pushfstring(L, " in main chunk"); @@ -362,19 +366,19 @@ static int errorfb (lua_State *L) { static const luaL_reg dblib[] = { - {"getmetatable", getmetatable}, - {"setmetatable", setmetatable}, - {"getfenv", getfenv}, - {"setfenv", setfenv}, - {"getlocal", getlocal}, - {"getinfo", getinfo}, - {"gethook", gethook}, - {"getupvalue", getupvalue}, - {"sethook", sethook}, - {"setlocal", setlocal}, - {"setupvalue", setupvalue}, - {"debug", debug}, - {"traceback", errorfb}, + {"getmetatable", db_getmetatable}, + {"setmetatable", db_setmetatable}, + {"getfenv", db_getfenv}, + {"setfenv", db_setfenv}, + {"getlocal", db_getlocal}, + {"getinfo", db_getinfo}, + {"gethook", db_gethook}, + {"getupvalue", db_getupvalue}, + {"sethook", db_sethook}, + {"setlocal", db_setlocal}, + {"setupvalue", db_setupvalue}, + {"debug", db_debug}, + {"traceback", db_errorfb}, {NULL, NULL} }; diff --git a/src/ldebug.c b/src/ldebug.c index 0456669f..73a604ff 100644 --- a/src/ldebug.c +++ b/src/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 2.12 2004/12/20 15:50:00 roberto Exp $ +** $Id: ldebug.c,v 2.20 2005/05/17 19:49:15 roberto Exp $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -30,17 +30,19 @@ -static const char *getfuncname (CallInfo *ci, const char **name); +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); -static int currentpc (CallInfo *ci) { +static int currentpc (lua_State *L, CallInfo *ci) { if (!isLua(ci)) return -1; /* function is not a Lua function? */ + if (ci == L->ci) + ci->savedpc = L->savedpc; return pcRel(ci->savedpc, ci_func(ci)->l.p); } -static int currentline (CallInfo *ci) { - int pc = currentpc(ci); +static int currentline (lua_State *L, CallInfo *ci) { + int pc = currentpc(L, ci); if (pc < 0) return -1; /* only active lua functions have current-line information */ else @@ -88,15 +90,15 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { if (f_isLua(ci)) /* Lua function? */ level -= ci->tailcalls; /* skip lost tail calls */ } - if (level > 0 || ci == L->base_ci) status = 0; /* there is no such level */ - else if (level < 0) { /* level is of a lost tail call */ + if (level == 0 && ci > L->base_ci) { /* level found? */ status = 1; - ar->i_ci = 0; + ar->i_ci = ci - L->base_ci; } - else { + else if (level < 0) { /* level is of a lost tail call? */ status = 1; - ar->i_ci = ci - L->base_ci; + ar->i_ci = 0; } + else status = 0; /* no such level */ lua_unlock(L); return status; } @@ -116,7 +118,7 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { ci = L->base_ci + ar->i_ci; fp = getluaproto(ci); if (fp) { /* is a Lua function? */ - name = luaF_getlocalname(fp, n, currentpc(ci)); + name = luaF_getlocalname(fp, n, currentpc(L, ci)); if (name) luaA_pushobject(L, ci->base+(n-1)); /* push value */ } @@ -135,7 +137,7 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { fp = getluaproto(ci); L->top--; /* pop new value */ if (fp) { /* is a Lua function? */ - name = luaF_getlocalname(fp, n, currentpc(ci)); + name = luaF_getlocalname(fp, n, currentpc(L, ci)); if (!name || name[0] == '(') /* `(' starts private locals */ name = NULL; else @@ -146,8 +148,7 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { } -static void funcinfo (lua_Debug *ar, StkId func) { - Closure *cl = clvalue(func); +static void funcinfo (lua_Debug *ar, Closure *cl) { if (cl->c.isC) { ar->source = "=[C]"; ar->linedefined = -1; @@ -155,7 +156,8 @@ static void funcinfo (lua_Debug *ar, StkId func) { } else { ar->source = getstr(cl->l.p->source); - ar->linedefined = cl->l.p->lineDefined; + ar->linedefined = cl->l.p->linedefined; + ar->lastlinedefined = cl->l.p->lastlinedefined; ar->what = (ar->linedefined == 0) ? "main" : "Lua"; } luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); @@ -165,17 +167,36 @@ static void funcinfo (lua_Debug *ar, StkId func) { static void info_tailcall (lua_State *L, lua_Debug *ar) { ar->name = ar->namewhat = ""; ar->what = "tail"; - ar->linedefined = ar->currentline = -1; + ar->lastlinedefined = ar->linedefined = ar->currentline = -1; ar->source = "=(tail call)"; luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); ar->nups = 0; - setnilvalue(L->top); +} + + +static void collectvalidlines (lua_State *L, Closure *f) { + if (f == NULL || f->c.isC) { + setnilvalue(L->top); + } + else { + Table *t = luaH_new(L, 0, 0); + int *lineinfo = f->l.p->lineinfo; + int i; + for (i=0; i<f->l.p->sizelineinfo; i++) + setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); + sethvalue(L, L->top, t); + } + incr_top(L); } static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, - StkId f, CallInfo *ci) { + Closure *f, CallInfo *ci) { int status = 1; + if (f == NULL) { + info_tailcall(L, ar); + return status; + } for (; *what; what++) { switch (*what) { case 'S': { @@ -183,25 +204,24 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, break; } case 'l': { - ar->currentline = (ci) ? currentline(ci) : -1; + ar->currentline = (ci) ? currentline(L, ci) : -1; break; } case 'u': { - ar->nups = clvalue(f)->c.nupvalues; + ar->nups = f->c.nupvalues; break; } case 'n': { - ar->namewhat = (ci) ? getfuncname(ci, &ar->name) : NULL; + ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL; if (ar->namewhat == NULL) { ar->namewhat = ""; /* not found */ ar->name = NULL; } break; } - case 'f': { - setobj2s(L, L->top, f); + case 'L': + case 'f': /* handled by lua_getinfo */ break; - } default: status = 0; /* invalid option */ } } @@ -210,23 +230,30 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { - int status = 1; + int status; + Closure *f = NULL; + CallInfo *ci = NULL; lua_lock(L); if (*what == '>') { - StkId f = L->top - 1; - if (!ttisfunction(f)) - luaG_runerror(L, "value for `lua_getinfo' is not a function"); - status = auxgetinfo(L, what + 1, ar, f, NULL); + StkId func = L->top - 1; + luai_apicheck(L, ttisfunction(func)); + what++; /* skip the '>' */ + f = clvalue(func); L->top--; /* pop function */ } else if (ar->i_ci != 0) { /* no tail call? */ - CallInfo *ci = L->base_ci + ar->i_ci; + ci = L->base_ci + ar->i_ci; lua_assert(ttisfunction(ci->func)); - status = auxgetinfo(L, what, ar, ci->func, ci); + f = clvalue(ci->func); } - else - info_tailcall(L, ar); - if (strchr(what, 'f')) incr_top(L); + status = auxgetinfo(L, what, ar, f, ci); + if (strchr(what, 'f')) { + if (f == NULL) setnilvalue(L->top); + else setclvalue(L, L->top, f); + incr_top(L); + } + if (strchr(what, 'L')) + collectvalidlines(L, f); lua_unlock(L); return status; } @@ -366,7 +393,6 @@ static Instruction symbexec (const Proto *pt, int lastpc, int reg) { if (reg >= a+3) last = pc; /* affect all regs above its call base */ break; } - case OP_TFORPREP: case OP_FORLOOP: case OP_FORPREP: checkreg(pt, a+3); @@ -446,10 +472,11 @@ static const char *kname (Proto *p, int c) { } -static const char *getobjname (CallInfo *ci, int stackpos, const char **name) { +static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos, + const char **name) { if (isLua(ci)) { /* a Lua function? */ Proto *p = ci_func(ci)->l.p; - int pc = currentpc(ci); + int pc = currentpc(L, ci); Instruction i; *name = luaF_getlocalname(p, stackpos+1, pc); if (*name) /* is a local? */ @@ -467,7 +494,7 @@ static const char *getobjname (CallInfo *ci, int stackpos, const char **name) { int a = GETARG_A(i); int b = GETARG_B(i); /* move from `b' to `a' */ if (b < a) - return getobjname(ci, b, name); /* get name for `b' */ + return getobjname(L, ci, b, name); /* get name for `b' */ break; } case OP_GETTABLE: { @@ -492,15 +519,15 @@ static const char *getobjname (CallInfo *ci, int stackpos, const char **name) { } -static const char *getfuncname (CallInfo *ci, const char **name) { +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { Instruction i; if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1)) return NULL; /* calling function is not Lua (or is unknown) */ ci--; /* calling function */ - i = ci_func(ci)->l.p->code[currentpc(ci)]; + i = ci_func(ci)->l.p->code[currentpc(L, ci)]; if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL || GET_OPCODE(i) == OP_TFORLOOP) - return getobjname(ci, GETARG_A(i), name); + return getobjname(L, ci, GETARG_A(i), name); else return NULL; /* no useful name can be found */ } @@ -519,9 +546,9 @@ 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->ci, o - L->base, &name) : NULL; + getobjname(L, L->ci, o - L->base, &name) : NULL; if (kind) - luaG_runerror(L, "attempt to %s %s `%s' (a %s value)", + luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", op, kind, name, t); else luaG_runerror(L, "attempt to %s a %s value", op, t); @@ -558,7 +585,7 @@ static void addinfo (lua_State *L, const char *msg) { CallInfo *ci = L->ci; if (isLua(ci)) { /* is Lua code? */ char buff[LUA_IDSIZE]; /* add file:line information */ - int line = currentline(ci); + int line = currentline(L, ci); luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE); luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); } diff --git a/src/ldebug.h b/src/ldebug.h index 5d8d2c2e..9c76aa10 100644 --- a/src/ldebug.h +++ b/src/ldebug.h @@ -1,5 +1,5 @@ /* -** $Id: ldebug.h,v 2.2 2004/06/02 19:07:55 roberto Exp $ +** $Id: ldebug.h,v 2.3 2005/04/25 19:24:10 roberto Exp $ ** Auxiliary functions from Debug Interface module ** See Copyright Notice in lua.h */ @@ -18,13 +18,16 @@ #define resethookcount(L) (L->hookcount = L->basehookcount) -void luaG_typeerror (lua_State *L, const TValue *o, const char *opname); -void luaG_concaterror (lua_State *L, StkId p1, StkId p2); -void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2); -int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2); -void luaG_runerror (lua_State *L, const char *fmt, ...); -void luaG_errormsg (lua_State *L); -int luaG_checkcode (const Proto *pt); -int luaG_checkopenop (Instruction i); +LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o, + const char *opname); +LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2); +LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...); +LUAI_FUNC void luaG_errormsg (lua_State *L); +LUAI_FUNC int luaG_checkcode (const Proto *pt); +LUAI_FUNC int luaG_checkopenop (Instruction i); #endif @@ -1,10 +1,11 @@ /* -** $Id: ldo.c,v 2.14 2005/02/18 12:40:02 roberto Exp $ +** $Id: ldo.c,v 2.23 2005/05/03 19:01:17 roberto Exp $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ +#include <setjmp.h> #include <stdlib.h> #include <string.h> @@ -42,7 +43,7 @@ /* chain list of long jump buffers */ struct lua_longjmp { struct lua_longjmp *previous; - l_jmpbuf b; + luai_jmpbuf b; volatile int status; /* error code */ }; @@ -70,9 +71,10 @@ static void seterrorobj (lua_State *L, int errcode, StkId oldtop) { void luaD_throw (lua_State *L, int errcode) { if (L->errorJmp) { L->errorJmp->status = errcode; - L_THROW(L, L->errorJmp); + LUAI_THROW(L, L->errorJmp); } else { + L->status = errcode; if (G(L)->panic) G(L)->panic(L); exit(EXIT_FAILURE); } @@ -84,7 +86,7 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { lj.status = 0; lj.previous = L->errorJmp; /* chain new error handler */ L->errorJmp = &lj; - L_TRY(L, &lj, + LUAI_TRY(L, &lj, (*f)(L, ud); ); L->errorJmp = lj.previous; /* restore old error handler */ @@ -94,10 +96,10 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { static void restore_stack_limit (lua_State *L) { lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); - if (L->size_ci > LUA_MAXCALLS) { /* there was an overflow? */ + if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */ int inuse = (L->ci - L->base_ci); - if (inuse + 1 < LUA_MAXCALLS) /* can `undo' overflow? */ - luaD_reallocCI(L, LUA_MAXCALLS); + if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */ + luaD_reallocCI(L, LUAI_MAXCALLS); } } @@ -114,6 +116,7 @@ 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; } @@ -133,7 +136,7 @@ void luaD_reallocstack (lua_State *L, int newsize) { void luaD_reallocCI (lua_State *L, int newsize) { CallInfo *oldci = L->base_ci; luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); - L->size_ci = cast(unsigned short, newsize); + L->size_ci = newsize; L->ci = (L->ci - oldci) + L->base_ci; L->end_ci = L->base_ci + L->size_ci - 1; } @@ -148,11 +151,11 @@ void luaD_growstack (lua_State *L, int n) { static CallInfo *growCI (lua_State *L) { - if (L->size_ci > LUA_MAXCALLS) /* overflow while handling overflow? */ + if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */ luaD_throw(L, LUA_ERRERR); else { luaD_reallocCI(L, 2*L->size_ci); - if (L->size_ci > LUA_MAXCALLS) + if (L->size_ci > LUAI_MAXCALLS) luaG_runerror(L, "stack overflow"); } return ++L->ci; @@ -195,16 +198,18 @@ static StkId adjust_varargs (lua_State *L, int nfixargs, int actual, for (; actual < nfixargs; ++actual) setnilvalue(L->top++); } +#if LUA_COMPAT_VARARG if (style != NEWSTYLEVARARG) { /* compatibility with old-style vararg */ int nvar = actual - nfixargs; /* number of extra arguments */ luaC_checkGC(L); htab = luaH_new(L, nvar, 1); /* create `arg' table */ for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */ - setobj2n(L, luaH_setnum(L, htab, i+LUA_FIRSTINDEX), L->top - nvar + i); + setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i); /* store counter in field `n' */ setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast(lua_Number, nvar)); } +#endif /* move fixed parameters to final position */ fixed = L->top - actual; /* first fixed argument */ base = L->top; /* final position of first argument */ @@ -249,6 +254,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { func = tryfuncTM(L, func); /* check the `function' tag method */ funcr = savestack(L, func); cl = &clvalue(func)->l; + L->ci->savedpc = L->savedpc; if (!cl->isC) { /* Lua function? prepare its call */ CallInfo *ci; StkId st, base; @@ -269,7 +275,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { L->base = ci->base = base; ci->top = L->base + p->maxstacksize; lua_assert(ci->top <= L->stack_last); - ci->savedpc = p->code; /* starting point */ + L->savedpc = p->code; /* starting point */ ci->tailcalls = 0; ci->nresults = nresults; for (st = L->top; st < ci->top; st++) @@ -321,6 +327,7 @@ void luaD_poscall (lua_State *L, int wanted, StkId 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 */ /* move results to correct place */ while (wanted != 0 && firstResult < L->top) { setobjs2s(L, res++, firstResult++); @@ -339,10 +346,10 @@ void luaD_poscall (lua_State *L, int wanted, StkId firstResult) { ** function position. */ void luaD_call (lua_State *L, StkId func, int nResults) { - if (++L->nCcalls >= LUA_MAXCCALLS) { - if (L->nCcalls == LUA_MAXCCALLS) + if (++L->nCcalls >= LUAI_MAXCCALLS) { + if (L->nCcalls == LUAI_MAXCCALLS) luaG_runerror(L, "C stack overflow"); - else if (L->nCcalls >= (LUA_MAXCCALLS + (LUA_MAXCCALLS>>3))) + 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? */ @@ -434,7 +441,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; - unsigned short oldnCcalls = L->nCcalls; + int oldnCcalls = L->nCcalls; ptrdiff_t old_ci = saveci(L, L->ci); lu_byte old_allowhooks = L->allowhook; ptrdiff_t old_errfunc = L->errfunc; @@ -447,6 +454,7 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u, L->nCcalls = oldnCcalls; L->ci = restoreci(L, old_ci); L->base = L->ci->base; + L->savedpc = L->ci->savedpc; L->allowhook = old_allowhooks; restore_stack_limit(L); } @@ -1,5 +1,5 @@ /* -** $Id: ldo.h,v 2.3 2004/09/08 14:23:09 roberto Exp $ +** $Id: ldo.h,v 2.4 2005/04/25 19:24:10 roberto Exp $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -47,20 +47,20 @@ /* type of protected functions, to be ran by `runprotected' */ typedef void (*Pfunc) (lua_State *L, void *ud); -void luaD_resetprotection (lua_State *L); -int luaD_protectedparser (lua_State *L, ZIO *z, const char *name); -void luaD_callhook (lua_State *L, int event, int line); -int luaD_precall (lua_State *L, StkId func, int nresults); -void luaD_call (lua_State *L, StkId func, int nResults); -int luaD_pcall (lua_State *L, Pfunc func, void *u, - ptrdiff_t oldtop, ptrdiff_t ef); -void luaD_poscall (lua_State *L, int wanted, StkId firstResult); -void luaD_reallocCI (lua_State *L, int newsize); -void luaD_reallocstack (lua_State *L, int newsize); -void luaD_growstack (lua_State *L, int n); +LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name); +LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line); +LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); +LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); +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 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); -void luaD_throw (lua_State *L, int errcode); -int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); +LUAI_FUNC void luaD_throw (lua_State *L, int errcode); +LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); #endif + diff --git a/src/ldump.c b/src/ldump.c index 967596a1..0c9f00d1 100644 --- a/src/ldump.c +++ b/src/ldump.c @@ -1,5 +1,5 @@ /* -** $Id: ldump.c,v 1.9 2004/11/25 09:31:41 lhf Exp $ +** $Id: ldump.c,v 1.10 2005/05/12 00:26:50 lhf Exp $ ** save pre-compiled Lua chunks ** See Copyright Notice in lua.h */ @@ -136,7 +136,8 @@ static void DumpConstants(const Proto* f, DumpState* D) 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->linedefined,D); + DumpInt(f->lastlinedefined,D); DumpByte(f->nups,D); DumpByte(f->numparams,D); DumpByte(f->is_vararg,D); diff --git a/src/lfunc.c b/src/lfunc.c index 1c95e781..c9286d91 100644 --- a/src/lfunc.c +++ b/src/lfunc.c @@ -1,5 +1,5 @@ /* -** $Id: lfunc.c,v 2.9 2005/02/18 12:40:02 roberto Exp $ +** $Id: lfunc.c,v 2.11 2005/05/05 20:47:02 roberto Exp $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ @@ -105,10 +105,6 @@ void luaF_close (lua_State *L, StkId level) { else { unlinkupval(uv); setobj(L, &uv->u.value, uv->v); - if (isgray(o)) { - gray2black(o); /* closed upvalues are never gray */ - luaC_barrier(L, uv, &uv->u.value); - } uv->v = &uv->u.value; /* now current value lives here */ luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ } @@ -135,7 +131,8 @@ Proto *luaF_newproto (lua_State *L) { f->lineinfo = NULL; f->sizelocvars = 0; f->locvars = NULL; - f->lineDefined = 0; + f->linedefined = 0; + f->lastlinedefined = 0; f->source = NULL; return f; } diff --git a/src/lfunc.h b/src/lfunc.h index 93f7b888..2e02419b 100644 --- a/src/lfunc.h +++ b/src/lfunc.h @@ -1,5 +1,5 @@ /* -** $Id: lfunc.h,v 2.3 2005/02/18 12:40:02 roberto Exp $ +** $Id: lfunc.h,v 2.4 2005/04/25 19:24:10 roberto Exp $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ @@ -18,17 +18,17 @@ cast(int, sizeof(TValue *)*((n)-1))) -Proto *luaF_newproto (lua_State *L); -Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e); -Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e); -UpVal *luaF_newupval (lua_State *L); -UpVal *luaF_findupval (lua_State *L, StkId level); -void luaF_close (lua_State *L, StkId level); -void luaF_freeproto (lua_State *L, Proto *f); -void luaF_freeclosure (lua_State *L, Closure *c); -void luaF_freeupval (lua_State *L, UpVal *uv); - -const char *luaF_getlocalname (const Proto *func, int local_number, int pc); +LUAI_FUNC Proto *luaF_newproto (lua_State *L); +LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e); +LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e); +LUAI_FUNC UpVal *luaF_newupval (lua_State *L); +LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); +LUAI_FUNC void luaF_close (lua_State *L, StkId level); +LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); +LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c); +LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv); +LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, + int pc); #endif @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.27 2005/02/23 17:30:22 roberto Exp $ +** $Id: lgc.c,v 2.32 2005/05/05 15:34:03 roberto Exp $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -57,7 +57,7 @@ reallymarkobject(g, obj2gco(t)); } -#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpace) +#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause) static void removeentry (Node *n) { @@ -242,7 +242,7 @@ 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 */ - if (L->size_ci > LUA_MAXCALLS) /* handling overflow? */ + 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) luaD_reallocCI(L, L->size_ci/2); /* still big enough... */ @@ -493,6 +493,13 @@ void luaC_freeall (lua_State *L) { } +static void markmt (global_State *g) { + int i; + for (i=0; i<NUM_TAGS; i++) + if (g->mt[i]) markobject(g, g->mt[i]); +} + + /* mark root set */ static void markroot (lua_State *L) { global_State *g = G(L); @@ -503,6 +510,7 @@ static void markroot (lua_State *L) { /* make global table be traversed before main stack */ markvalue(g, gt(g->mainthread)); markvalue(g, registry(L)); + markmt(g); g->gcstate = GCSpropagate; } @@ -529,6 +537,7 @@ static void atomic (lua_State *L) { g->weak = NULL; lua_assert(!iswhite(obj2gco(g->mainthread))); markobject(g, L); /* mark running thread */ + markmt(g); /* mark basic metatables (again) */ propagateall(g); /* remark gray again */ g->gray = g->grayagain; @@ -539,7 +548,7 @@ static void atomic (lua_State *L) { propagateall(g); /* remark, to propagate `preserveness' */ cleartable(g->weak); /* remove collected objects from weak tables */ /* flip current white */ - g->currentwhite = otherwhite(g); + g->currentwhite = cast(lu_byte, otherwhite(g)); g->sweepstrgc = 0; g->sweepgc = &g->rootgc; g->gcstate = GCSsweepstring; @@ -1,5 +1,5 @@ /* -** $Id: lgc.h,v 2.12 2005/02/23 17:30:22 roberto Exp $ +** $Id: lgc.h,v 2.13 2005/04/25 19:24:10 roberto Exp $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -95,15 +95,15 @@ { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ luaC_barrierback(L,obj2gco(p)); } -size_t luaC_separateudata (lua_State *L, int all); -void luaC_callGCTM (lua_State *L); -void luaC_freeall (lua_State *L); -void luaC_step (lua_State *L); -void luaC_fullgc (lua_State *L); -void luaC_link (lua_State *L, GCObject *o, lu_byte tt); -void luaC_linkupval (lua_State *L, UpVal *uv); -void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); -void luaC_barrierback (lua_State *L, GCObject *o); +LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all); +LUAI_FUNC void luaC_callGCTM (lua_State *L); +LUAI_FUNC void luaC_freeall (lua_State *L); +LUAI_FUNC void luaC_step (lua_State *L); +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); #endif diff --git a/src/linit.c b/src/linit.c index 24f70edb..afcd338b 100644 --- a/src/linit.c +++ b/src/linit.c @@ -1,5 +1,5 @@ /* -** $Id: linit.c,v 1.9 2005/02/18 12:40:02 roberto Exp $ +** $Id: linit.c,v 1.11 2005/04/13 17:24:20 roberto Exp $ ** Initialization of libraries for lua.c ** See Copyright Notice in lua.h */ @@ -22,19 +22,17 @@ static const luaL_reg lualibs[] = { {LUA_STRLIBNAME, luaopen_string}, {LUA_MATHLIBNAME, luaopen_math}, {LUA_DBLIBNAME, luaopen_debug}, - {"", luaopen_loadlib}, + {LUA_LOADLIBNAME, luaopen_loadlib}, {NULL, NULL} }; -LUALIB_API int luaopen_stdlibs (lua_State *L) { +LUALIB_API void luaL_openlibs (lua_State *L) { const luaL_reg *lib = lualibs; for (; lib->func; lib++) { - lib->func(L); /* open library */ - lua_settop(L, 0); /* discard any results */ - lua_pushvalue(L, LUA_GLOBALSINDEX); - lua_replace(L, LUA_ENVIRONINDEX); /* restore environment */ + lua_pushcfunction(L, lib->func); + lua_pushstring(L, lib->name); + lua_call(L, 1, 0); } - return 0; } diff --git a/src/liolib.c b/src/liolib.c index 854ba3ba..1dba7eff 100644 --- a/src/liolib.c +++ b/src/liolib.c @@ -1,5 +1,5 @@ /* -** $Id: liolib.c,v 2.58 2005/02/18 12:40:02 roberto Exp $ +** $Id: liolib.c,v 2.60 2005/05/16 21:19:00 roberto Exp $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ @@ -191,9 +191,9 @@ static int io_output (lua_State *L) { static int io_readline (lua_State *L); -static void aux_lines (lua_State *L, int idx, int close) { +static void aux_lines (lua_State *L, int idx, int toclose) { lua_pushvalue(L, idx); - lua_pushboolean(L, close); /* close/not close file when finished */ + lua_pushboolean(L, toclose); /* close/not close file when finished */ lua_pushcclosure(L, io_readline, 2); } @@ -319,8 +319,6 @@ static int g_read (lua_State *L, FILE *f, int first) { read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ success = 1; /* always success */ break; - case 'w': /* word */ - return luaL_error(L, "obsolete option `*w' to `read'"); default: return luaL_argerror(L, n, "invalid format"); } @@ -1,5 +1,5 @@ /* -** $Id: llex.c,v 2.9 2004/12/03 20:54:12 roberto Exp $ +** $Id: llex.c,v 2.12 2005/05/17 19:49:15 roberto Exp $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ @@ -102,7 +102,7 @@ void luaX_lexerror (LexState *ls, const char *msg, int token) { luaO_chunkid(buff, getstr(ls->source), MAXSRC); msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg); if (token) - luaO_pushfstring(ls->L, "%s near `%s'", msg, txtToken(ls, token)); + luaO_pushfstring(ls->L, "%s near " LUA_QS, msg, txtToken(ls, token)); luaD_throw(ls->L, LUA_ERRSYNTAX); } @@ -202,6 +202,7 @@ static int skip_sep (LexState *ls) { static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { int cont = 0; + (void)(cont); /* avoid warnings when `cont' is not used */ save_and_next(ls); /* skip 2nd `[' */ if (currIsNewline(ls)) /* string starts with a newline? */ inclinenumber(ls); /* skip it */ @@ -211,27 +212,41 @@ static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { luaX_lexerror(ls, (seminfo) ? "unfinished long string" : "unfinished long comment", TK_EOS); break; /* to avoid warnings */ - case '[': +#if defined(LUA_COMPAT_LSTR) + case '[': { if (skip_sep(ls) == sep) { save_and_next(ls); /* skip 2nd `[' */ cont++; +#if LUA_COMPAT_LSTR == 1 + if (sep == 0) + luaX_lexerror(ls, "nesting of [[...]] is deprecated", '['); +#endif } - continue; - case ']': + break; + } +#endif + case ']': { if (skip_sep(ls) == sep) { save_and_next(ls); /* skip 2nd `]' */ - if (cont-- == 0) goto endloop; +#if defined(LUA_COMPAT_LSTR) && LUA_COMPAT_LSTR == 2 + cont--; + if (sep == 0 && cont >= 0) break; +#endif + goto endloop; } - continue; + break; + } case '\n': - case '\r': + case '\r': { save(ls, '\n'); inclinenumber(ls); if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ - continue; - default: + break; + } + default: { if (seminfo) save_and_next(ls); else next(ls); + } } } endloop: if (seminfo) @@ -1,5 +1,5 @@ /* -** $Id: llex.h,v 1.52 2004/12/03 20:54:12 roberto Exp $ +** $Id: llex.h,v 1.54 2005/04/25 19:24:10 roberto Exp $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ @@ -63,17 +63,17 @@ typedef struct LexState { ZIO *z; /* input stream */ Mbuffer *buff; /* buffer for tokens */ TString *source; /* current source name */ - int nestlevel; /* level of nested non-terminals */ } LexState; -void luaX_init (lua_State *L); -void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source); -TString *luaX_newstring (LexState *LS, const char *str, size_t l); -int luaX_lex (LexState *LS, SemInfo *seminfo); -void luaX_lexerror (LexState *ls, const char *msg, int token); -void luaX_syntaxerror (LexState *ls, const char *s); -const char *luaX_token2str (LexState *ls, int token); +LUAI_FUNC void luaX_init (lua_State *L); +LUAI_FUNC void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, + TString *source); +LUAI_FUNC TString *luaX_newstring (LexState *LS, const char *str, size_t l); +LUAI_FUNC int luaX_lex (LexState *LS, SemInfo *seminfo); +LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token); +LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s); +LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); #endif diff --git a/src/llimits.h b/src/llimits.h index 5b11e820..7a536a16 100644 --- a/src/llimits.h +++ b/src/llimits.h @@ -1,5 +1,5 @@ /* -** $Id: llimits.h,v 1.63 2005/01/14 14:19:42 roberto Exp $ +** $Id: llimits.h,v 1.65 2005/03/09 16:28:07 roberto Exp $ ** Limits, basic types, and some other `installation-dependent' definitions ** See Copyright Notice in lua.h */ @@ -15,12 +15,14 @@ #include "lua.h" +#define api_check luai_apicheck -typedef LUA_UINT32 lu_int32; -typedef LU_MEM lu_mem; +typedef LUAI_UINT32 lu_int32; -typedef L_MEM l_mem; +typedef LUAI_UMEM lu_mem; + +typedef LUAI_MEM l_mem; @@ -45,11 +47,11 @@ typedef unsigned char lu_byte; /* type to ensure maximum alignment */ -typedef LUSER_ALIGNMENT_T L_Umaxalign; +typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; /* result of a `usual argument conversion' over lua_Number */ -typedef LUA_UACNUMBER l_uacNumber; +typedef LUAI_UACNUMBER l_uacNumber; #define check_exp(c,e) (lua_assert(c), (e)) diff --git a/src/lmathlib.c b/src/lmathlib.c index add88970..bba99b0d 100644 --- a/src/lmathlib.c +++ b/src/lmathlib.c @@ -1,5 +1,5 @@ /* -** $Id: lmathlib.c,v 1.62 2005/01/07 20:00:33 roberto Exp $ +** $Id: lmathlib.c,v 1.63 2005/03/04 18:57:03 roberto Exp $ ** Standard mathematical library ** See Copyright Notice in lua.h */ @@ -33,16 +33,31 @@ static int math_sin (lua_State *L) { return 1; } +static int math_sinh (lua_State *L) { + lua_pushnumber(L, sinh(luaL_checknumber(L, 1))); + return 1; +} + static int math_cos (lua_State *L) { lua_pushnumber(L, cos(luaL_checknumber(L, 1))); return 1; } +static int math_cosh (lua_State *L) { + lua_pushnumber(L, cosh(luaL_checknumber(L, 1))); + return 1; +} + static int math_tan (lua_State *L) { lua_pushnumber(L, tan(luaL_checknumber(L, 1))); return 1; } +static int math_tanh (lua_State *L) { + lua_pushnumber(L, tanh(luaL_checknumber(L, 1))); + return 1; +} + static int math_asin (lua_State *L) { lua_pushnumber(L, asin(luaL_checknumber(L, 1))); return 1; @@ -78,6 +93,14 @@ static int math_mod (lua_State *L) { return 1; } +static int math_modf (lua_State *L) { + double ip; + double fp = modf(luaL_checknumber(L, 1), &ip); + lua_pushnumber(L, ip); + lua_pushnumber(L, fp); + return 2; +} + static int math_sqrt (lua_State *L) { lua_pushnumber(L, sqrt(luaL_checknumber(L, 1))); return 1; @@ -192,8 +215,11 @@ static int math_randomseed (lua_State *L) { 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}, @@ -201,6 +227,7 @@ static const luaL_reg mathlib[] = { {"ceil", math_ceil}, {"floor", math_floor}, {"mod", math_mod}, + {"modf", math_modf}, {"frexp", math_frexp}, {"ldexp", math_ldexp}, {"sqrt", math_sqrt}, @@ -225,6 +252,8 @@ LUALIB_API int luaopen_math (lua_State *L) { luaL_openlib(L, LUA_MATHLIBNAME, mathlib, 0); lua_pushnumber(L, PI); lua_setfield(L, -2, "pi"); + lua_pushnumber(L, HUGE_VAL); + lua_setfield(L, -2, "huge"); return 1; } @@ -1,5 +1,5 @@ /* -** $Id: lmem.h,v 1.29 2004/12/01 15:46:18 roberto Exp $ +** $Id: lmem.h,v 1.31 2005/04/25 19:24:10 roberto Exp $ ** Interface to Memory Manager ** See Copyright Notice in lua.h */ @@ -16,18 +16,10 @@ #define MEMERRMSG "not enough memory" -void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, size_t size); - -void *luaM_toobig (lua_State *L); - #define luaM_reallocv(L,b,on,n,e) \ - ((cast(unsigned int, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \ - luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \ - luaM_toobig(L)) - - -void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elem, - int limit, const char *errormsg); + ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \ + luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \ + luaM_toobig(L)) #define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) #define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) @@ -46,5 +38,12 @@ void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elem, ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) +LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, + size_t size); +LUAI_FUNC void *luaM_toobig (lua_State *L); +LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, + size_t size_elem, int limit, + const char *errormsg); + #endif diff --git a/src/loadlib.c b/src/loadlib.c index 957310b6..1ae9ab57 100644 --- a/src/loadlib.c +++ b/src/loadlib.c @@ -1,11 +1,11 @@ /* -** $Id: loadlib.c,v 1.18 2005/02/28 15:58:48 roberto Exp $ +** $Id: loadlib.c,v 1.28 2005/05/17 19:49:15 roberto Exp $ ** Dynamic library loader for Lua ** See Copyright Notice in lua.h -* -* This module contains an implementation of loadlib for Unix systems -* that have dlfcn, an implementation for Darwin (Mac OS X), an -* implementation for Windows, and a stub for other systems. +** +** This module contains an implementation of loadlib for Unix systems +** that have dlfcn, an implementation for Darwin (Mac OS X), an +** implementation for Windows, and a stub for other systems. */ @@ -21,6 +21,17 @@ #include "lualib.h" +/* environment variables that hold the search path for packages */ +#define LUA_PATH "LUA_PATH" +#define LUA_CPATH "LUA_CPATH" + +/* prefix for open functions in C libraries */ +#define LUA_POF "luaopen_" + +/* separator for open functions in C libraries */ +#define LUA_OFSEP "_" + + #define LIBPREFIX "LOADLIB: " #define POF LUA_POF @@ -33,7 +44,7 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym); -#if defined(USE_DLOPEN) +#if defined(LUA_DL_DLOPEN) /* ** {======================================================================== ** This is an implementation of loadlib based on the dlfcn interface. @@ -67,7 +78,7 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { -#elif defined(USE_DLL) +#elif defined(LUA_DL_DLL) /* ** {====================================================================== ** This is an implementation of loadlib for Windows using native functions. @@ -82,7 +93,7 @@ static void pusherror (lua_State *L) { char buffer[128]; if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, buffer, sizeof(buffer), NULL)) - lua_pushstring(L,buffer); + lua_pushstring(L, buffer); else lua_pushfstring(L, "system error %d\n", error); } @@ -109,7 +120,7 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { -#elif defined(USE_DYLD) +#elif defined(LUA_DL_DYLD) /* ** {====================================================================== ** Native Mac OS X / Darwin Implementation @@ -119,6 +130,7 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { #include <mach-o/dyld.h> +/* Mac appends a `_' before C function names */ #undef POF #define POF "_" LUA_POF @@ -179,7 +191,7 @@ static void *ll_load (lua_State *L, const char *path) { static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym); if (nss == NULL) { - lua_pushfstring(L, "symbol `%s' not found", sym); + lua_pushfstring(L, "symbol " LUA_QS " not found", sym); return NULL; } return (lua_CFunction)NSAddressOfSymbol(nss); @@ -200,6 +212,12 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { #define LIB_FAIL "absent" +#if defined(__ELF__) || defined(__sun) || defined(sgi) || defined(__hpux) +#define DLMSG LUA_QL("loadlib") " not enabled; check your Lua installation" +#else +#define DLMSG LUA_QL("loadlib") " not supported" +#endif + static void ll_unloadlib (void *lib) { (void)lib; /* to avoid warnings */ } @@ -207,14 +225,14 @@ static void ll_unloadlib (void *lib) { static void *ll_load (lua_State *L, const char *path) { (void)path; /* to avoid warnings */ - lua_pushliteral(L,"`loadlib' not supported"); + lua_pushliteral(L, DLMSG); return NULL; } static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { (void)lib; (void)sym; /* to avoid warnings */ - lua_pushliteral(L,"`loadlib' not supported"); + lua_pushliteral(L, DLMSG); return NULL; } @@ -296,22 +314,25 @@ static int ll_loadlib (lua_State *L) { 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; + const char *path = NULL; +#if LUA_COMPAT_PATH /* try first `LUA_PATH' for compatibility */ lua_pushstring(L, "LUA_PATH"); lua_rawget(L, LUA_GLOBALSINDEX); 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, "`package.path' must be a string"); + 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 `%s' (%s)", name, lua_tostring(L, -1)); + luaL_error(L, "error loading package " LUA_QS " (%s)", + name, lua_tostring(L, -1)); return 1; /* library loaded successfully */ } @@ -324,13 +345,14 @@ static int loader_C (lua_State *L) { lua_getfield(L, LUA_ENVIRONINDEX, "cpath"); path = lua_tostring(L, -1); if (path == NULL) - luaL_error(L, "`package.cpath' must be a string"); + 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 `%s' (%s)", name, lua_tostring(L, -2)); + luaL_error(L, "error loading package " LUA_QS " (%s)", + name, lua_tostring(L, -2)); return 1; /* library loaded successfully */ } @@ -338,7 +360,7 @@ static int loader_C (lua_State *L) { static int loader_preload (lua_State *L) { lua_getfield(L, LUA_ENVIRONINDEX, "preload"); if (!lua_istable(L, -1)) - luaL_error(L, "`package.preload' must be a table"); + luaL_error(L, LUA_QL("package.preload") " must be a table"); lua_getfield(L, -1, luaL_checkstring(L, 1)); return 1; } @@ -358,11 +380,11 @@ static int ll_require (lua_State *L) { /* iterate over available loaders */ lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); if (!lua_istable(L, -1)) - luaL_error(L, "`package.loaders' must be a table"); + luaL_error(L, LUA_QL("package.loaders") " must be a table"); for (i=1;; i++) { lua_rawgeti(L, -1, i); /* get a loader */ if (lua_isnil(L, -1)) - return luaL_error(L, "package `%s' not found", name); + return luaL_error(L, "package " 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); @@ -401,7 +423,7 @@ static int ll_module (lua_State *L) { luaL_setfield(L, LUA_GLOBALSINDEX, modname); } else if (!lua_istable(L, -1)) - return luaL_error(L, "name conflict for module `%s'", modname); + 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? */ @@ -434,7 +456,6 @@ static int ll_module (lua_State *L) { static const luaL_reg ll_funcs[] = { - {"loadlib", ll_loadlib}, {"require", ll_require}, {"module", ll_module}, {NULL, NULL} @@ -455,7 +476,7 @@ LUALIB_API int luaopen_loadlib (lua_State *L) { /* create `package' table */ lua_newtable(L); lua_pushvalue(L, -1); - lua_setglobal(L, "package"); + lua_setglobal(L, LUA_LOADLIBNAME); lua_pushvalue(L, -1); lua_setfield(L, LUA_REGISTRYINDEX, "_PACKAGE"); lua_pushvalue(L, -1); @@ -485,6 +506,13 @@ LUALIB_API int luaopen_loadlib (lua_State *L) { /* 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; diff --git a/src/lobject.c b/src/lobject.c index f4464474..98b08351 100644 --- a/src/lobject.c +++ b/src/lobject.c @@ -1,11 +1,12 @@ /* -** $Id: lobject.c,v 2.8 2005/01/10 18:17:39 roberto Exp $ +** $Id: lobject.c,v 2.13 2005/05/16 21:19:00 roberto Exp $ ** Some generic functions over Lua objects ** See Copyright Notice in lua.h */ #include <ctype.h> #include <stdarg.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> @@ -28,7 +29,8 @@ const TValue luaO_nilobject = {{NULL}, LUA_TNIL}; /* ** converts an integer to a "floating point byte", represented as -** (mmmmmxxx), where the real value is (xxx) * 2^(mmmmm) +** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if +** eeeee != 0 and (xxx) otherwise. */ int luaO_int2fb (unsigned int x) { int e = 0; /* expoent */ @@ -73,7 +75,7 @@ int luaO_rawequalObj (const TValue *t1, const TValue *t2) { case LUA_TNIL: return 1; case LUA_TNUMBER: - return num_eq(nvalue(t1), nvalue(t2)); + return luai_numeq(nvalue(t1), nvalue(t2)); case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ case LUA_TLIGHTUSERDATA: @@ -182,7 +184,7 @@ void luaO_chunkid (char *out, const char *source, int bufflen) { if (*source == '@') { int l; source++; /* skip the `@' */ - bufflen -= sizeof(" `...' "); + bufflen -= sizeof(" '...' "); l = strlen(source); strcpy(out, ""); if (l>bufflen) { diff --git a/src/lobject.h b/src/lobject.h index 967b46c7..4a77a539 100644 --- a/src/lobject.h +++ b/src/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 2.11 2005/02/18 12:40:02 roberto Exp $ +** $Id: lobject.h,v 2.13 2005/05/05 20:47:02 roberto Exp $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -244,7 +244,8 @@ typedef struct Proto { int sizelineinfo; int sizep; /* size of `p' */ int sizelocvars; - int lineDefined; + int linedefined; + int lastlinedefined; GCObject *gclist; lu_byte nups; /* number of upvalues */ lu_byte numparams; @@ -360,16 +361,15 @@ extern const TValue luaO_nilobject; #define ceillog2(x) (luaO_log2((x)-1) + 1) -int luaO_log2 (unsigned int x); -int luaO_int2fb (unsigned int x); -int luaO_fb2int (int x); - -int luaO_rawequalObj (const TValue *t1, const TValue *t2); -int luaO_str2d (const char *s, lua_Number *result); - -const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp); -const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); -void luaO_chunkid (char *out, const char *source, int len); +LUAI_FUNC int luaO_log2 (unsigned int x); +LUAI_FUNC int luaO_int2fb (unsigned int x); +LUAI_FUNC int luaO_fb2int (int x); +LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2); +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); #endif diff --git a/src/lopcodes.c b/src/lopcodes.c index 24cd31d5..46b30ba9 100644 --- a/src/lopcodes.c +++ b/src/lopcodes.c @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.c,v 1.30 2004/12/02 12:59:10 roberto Exp $ +** $Id: lopcodes.c,v 1.33 2005/05/04 20:42:28 roberto Exp $ ** See Copyright Notice in lua.h */ @@ -32,9 +32,11 @@ const char *const luaP_opnames[NUM_OPCODES+1] = { "SUB", "MUL", "DIV", + "MOD", "POW", "UNM", "NOT", + "SIZ", "CONCAT", "JMP", "EQ", @@ -47,7 +49,6 @@ const char *const luaP_opnames[NUM_OPCODES+1] = { "FORLOOP", "FORPREP", "TFORLOOP", - "TFORPREP", "SETLIST", "CLOSE", "CLOSURE", @@ -76,9 +77,11 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = { ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ ,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, OpArgR, iABC) /* OP_CONCAT */ ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ @@ -91,7 +94,6 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = { ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */ - ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_TFORPREP */ ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ diff --git a/src/lopcodes.h b/src/lopcodes.h index dfbcaffe..77f60c00 100644 --- a/src/lopcodes.h +++ b/src/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.114 2004/12/02 12:59:10 roberto Exp $ +** $Id: lopcodes.h,v 1.119 2005/05/04 20:42:28 roberto Exp $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -51,9 +51,9 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ /* ** limits for opcode arguments. ** we use (signed) int to manipulate most arguments, -** so they must fit in LUA_BITSINT-1 bits (-1 for sign) +** so they must fit in LUAI_BITSINT-1 bits (-1 for sign) */ -#if SIZE_Bx < LUA_BITSINT-1 +#if SIZE_Bx < LUAI_BITSINT-1 #define MAXARG_Bx ((1<<SIZE_Bx)-1) #define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */ #else @@ -172,9 +172,11 @@ OP_ADD,/* A B C R(A) := RK(B) + RK(C) */ OP_SUB,/* A B C R(A) := RK(B) - RK(C) */ OP_MUL,/* A B C R(A) := RK(B) * RK(C) */ OP_DIV,/* A B C R(A) := RK(B) / RK(C) */ +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_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */ @@ -195,8 +197,6 @@ OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */ OP_TFORLOOP,/* A C R(A+2), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); if R(A+2) ~= nil then pc++ */ -OP_TFORPREP,/* A sBx if type(R(A)) == table then R(A+1):=R(A), R(A):=next; - pc+=sBx */ OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */ diff --git a/src/loslib.c b/src/loslib.c index dad959e2..52532143 100644 --- a/src/loslib.c +++ b/src/loslib.c @@ -1,5 +1,5 @@ /* -** $Id: loslib.c,v 1.4 2005/01/10 19:16:29 roberto Exp $ +** $Id: loslib.c,v 1.9 2005/05/17 19:49:15 roberto Exp $ ** Standard Operating System library ** See Copyright Notice in lua.h */ @@ -57,16 +57,13 @@ static int io_rename (lua_State *L) { static int io_tmpname (lua_State *L) { -#if !USE_TMPNAME - luaL_error(L, "`tmpname' not supported"); - return 0; -#else - char buff[L_tmpnam]; - if (tmpnam(buff) != buff) - return luaL_error(L, "unable to generate a unique filename in `tmpname'"); + char buff[LUA_TMPNAMBUFSIZE]; + int err; + lua_tmpnam(buff, err); + if (err) + return luaL_error(L, "unable to generate a unique filename"); lua_pushstring(L, buff); return 1; -#endif } @@ -116,7 +113,7 @@ static int getfield (lua_State *L, const char *key, int d) { res = (int)lua_tointeger(L, -1); else { if (d < 0) - return luaL_error(L, "field `%s' missing in date table", key); + return luaL_error(L, "field " LUA_QS " missing in date table", key); res = d; } lua_pop(L, 1); @@ -154,7 +151,7 @@ static int io_date (lua_State *L) { if (strftime(b, sizeof(b), s, stm)) lua_pushstring(L, b); else - return luaL_error(L, "`date' format too long"); + return luaL_error(L, LUA_QL("date") " format too long"); } return 1; } diff --git a/src/lparser.c b/src/lparser.c index 19e048ce..54facfc4 100644 --- a/src/lparser.c +++ b/src/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 2.13 2005/01/05 18:20:51 roberto Exp $ +** $Id: lparser.c,v 2.27 2005/05/17 19:49:15 roberto Exp $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -33,10 +33,6 @@ #define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m) -#define enterlevel(ls) if (++(ls)->nestlevel > LUA_MAXPARSERLEVEL) \ - luaX_lexerror(ls, "chunk has too many syntax levels", 0) -#define leavelevel(ls) ((ls)->nestlevel--) - /* ** nodes for block list (list of active blocks) @@ -86,15 +82,15 @@ static void anchor_token (LexState *ls) { static void error_expected (LexState *ls, int token) { luaX_syntaxerror(ls, - luaO_pushfstring(ls->L, "`%s' expected", luaX_token2str(ls, token))); + luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token))); } static void errorlimit (FuncState *fs, int limit, const char *what) { - const char *msg = (fs->f->lineDefined == 0) ? + const char *msg = (fs->f->linedefined == 0) ? luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) : luaO_pushfstring(fs->L, "function at line %d has more than %d %s", - fs->f->lineDefined, limit, what); + fs->f->linedefined, limit, what); luaX_lexerror(fs->ls, msg, 0); } @@ -129,7 +125,7 @@ static void check_match (LexState *ls, int what, int who, int where) { error_expected(ls, what); else { luaX_syntaxerror(ls, luaO_pushfstring(ls->L, - "`%s' expected (to close `%s' at line %d)", + LUA_QS " expected (to close " LUA_QS " at line %d)", luaX_token2str(ls, what), luaX_token2str(ls, who), where)); } } @@ -167,7 +163,7 @@ static int registerlocalvar (LexState *ls, TString *varname) { Proto *f = fs->f; int oldsize = f->sizelocvars; luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, - LocVar, USHRT_MAX, "too many local variables"); + LocVar, SHRT_MAX, "too many local variables"); while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; f->locvars[fs->nlocvars].varname = varname; luaC_objbarrier(ls->L, f, varname); @@ -181,7 +177,7 @@ static int registerlocalvar (LexState *ls, TString *varname) { static void new_localvar (LexState *ls, TString *name, int n) { FuncState *fs = ls->fs; - luaY_checklimit(fs, fs->nactvar+n+1, MAXVARS, "local variables"); + luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables"); fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name)); } @@ -213,7 +209,7 @@ static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { } } /* new one */ - luaY_checklimit(fs, f->nups + 1, MAXUPVALUES, "upvalues"); + luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues"); luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues, TString *, MAX_INT, ""); while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL; @@ -295,6 +291,15 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { } +static void enterlevel (LexState *ls) { + if (++ls->L->nCcalls > LUAI_MAXCCALLS) + luaX_lexerror(ls, "chunk has too many syntax levels", 0); +} + + +#define leavelevel(ls) ((ls)->L->nCcalls--) + + static void enterblock (FuncState *fs, BlockCnt *bl, int isbreakable) { bl->breaklist = NO_JUMP; bl->isbreakable = isbreakable; @@ -395,7 +400,6 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { struct LexState lexstate; struct FuncState funcstate; lexstate.buff = buff; - lexstate.nestlevel = 0; luaX_setinput(L, &lexstate, z, luaS_new(L, name)); open_func(&lexstate, &funcstate); funcstate.f->is_vararg = NEWSTYLEVARARG; @@ -405,7 +409,6 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { close_func(&lexstate); lua_assert(funcstate.prev == NULL); lua_assert(funcstate.f->nups == 0); - lua_assert(lexstate.nestlevel == 0); lua_assert(lexstate.fs == NULL); return funcstate.f; } @@ -460,11 +463,11 @@ static void recfield (LexState *ls, struct ConsControl *cc) { expdesc key, val; if (ls->t.token == TK_NAME) { luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); - cc->nh++; checkname(ls, &key); } else /* ls->t.token == '[' */ yindex(ls, &key); + cc->nh++; checknext(ls, '='); luaK_exp2RK(fs, &key); expr(ls, &val); @@ -574,7 +577,7 @@ static void parlist (LexState *ls) { f->is_vararg = 1; break; } - default: luaX_syntaxerror(ls, "<name> or `...' expected"); + default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected"); } } while (!f->is_vararg && testnext(ls, ',')); } @@ -588,7 +591,7 @@ static void body (LexState *ls, expdesc *e, int needself, int line) { /* body -> `(' parlist `)' chunk END */ FuncState new_fs; open_func(ls, &new_fs); - new_fs.f->lineDefined = line; + new_fs.f->linedefined = line; checknext(ls, '('); if (needself) { new_localvarliteral(ls, "self", 0); @@ -597,6 +600,7 @@ static void body (LexState *ls, expdesc *e, int needself, int line) { parlist(ls); checknext(ls, ')'); chunk(ls); + new_fs.f->lastlinedefined = ls->linenumber; check_match(ls, TK_END, TK_FUNCTION, line); close_func(ls); pushclosure(ls, &new_fs, e); @@ -735,8 +739,8 @@ static void primaryexp (LexState *ls, expdesc *v) { static void simpleexp (LexState *ls, expdesc *v) { - /* simpleexp -> NUMBER | STRING | NIL | constructor | FUNCTION body - | primaryexp */ + /* simpleexp -> NUMBER | STRING | NIL | true | false | ... | + constructor | FUNCTION body | primaryexp */ switch (ls->t.token) { case TK_NUMBER: { init_exp(v, VK, luaK_numberK(ls->fs, ls->t.seminfo.r)); @@ -761,7 +765,7 @@ static void simpleexp (LexState *ls, expdesc *v) { case TK_DOTS: { /* vararg */ FuncState *fs = ls->fs; check_condition(ls, fs->f->is_vararg, - "cannot use `...' outside a vararg function"); + "cannot use " LUA_QL("...") " outside a vararg function"); fs->f->is_vararg = NEWSTYLEVARARG; init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); break; @@ -788,6 +792,7 @@ static UnOpr getunopr (int op) { switch (op) { case TK_NOT: return OPR_NOT; case '-': return OPR_MINUS; + case '*': return OPR_SIZE; default: return OPR_NOUNOPR; } } @@ -799,6 +804,7 @@ static BinOpr getbinopr (int op) { case '-': return OPR_SUB; case '*': return OPR_MULT; case '/': return OPR_DIV; + case '%': return OPR_MOD; case '^': return OPR_POW; case TK_CONCAT: return OPR_CONCAT; case TK_NE: return OPR_NE; @@ -818,9 +824,9 @@ static const struct { lu_byte left; /* left priority for each binary operator */ lu_byte right; /* right priority */ } priority[] = { /* ORDER OPR */ - {6, 6}, {6, 6}, {7, 7}, {7, 7}, /* arithmetic */ + {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */ {10, 9}, {5, 4}, /* power and concat (right associative) */ - {3, 3}, {3, 3}, /* equality */ + {3, 3}, {3, 3}, /* equality and inequality */ {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */ {2, 2}, {1, 1} /* logical (and/or) */ }; @@ -829,7 +835,7 @@ static const struct { /* -** subexpr -> (simplexep | unop subexpr) { binop subexpr } +** subexpr -> (simpleexp | unop subexpr) { binop subexpr } ** where `binop' is any binary operator with a priority higher than `limit' */ static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) { @@ -992,7 +998,7 @@ static int cond (LexState *ls) { static void whilestat (LexState *ls, int line) { /* whilestat -> WHILE cond DO block END */ - Instruction codeexp[MAXEXPWHILE + EXTRAEXP]; + Instruction codeexp[LUAI_MAXEXPWHILE + EXTRAEXP]; int lineexp; int i; int sizeexp; @@ -1010,8 +1016,8 @@ static void whilestat (LexState *ls, int line) { luaK_concat(fs, &v.f, fs->jpc); fs->jpc = NO_JUMP; sizeexp = fs->pc - expinit; /* size of expression code */ - if (sizeexp > MAXEXPWHILE) - luaX_syntaxerror(ls, "`while' condition too complex"); + 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 */ @@ -1065,7 +1071,7 @@ static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { int prep, endfor; adjustlocalvars(ls, 3); /* control variables */ checknext(ls, TK_DO); - prep = luaK_codeAsBx(fs, (isnum ? OP_FORPREP : OP_TFORPREP), base, NO_JUMP); + prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); enterblock(fs, &bl, 0); /* scope for declared variables */ adjustlocalvars(ls, nvars); luaK_reserveregs(fs, nvars); @@ -1135,7 +1141,7 @@ static void forstat (LexState *ls, int line) { switch (ls->t.token) { case '=': fornum(ls, varname, line); break; case ',': case TK_IN: forlist(ls, varname); break; - default: luaX_syntaxerror(ls, "`=' or `in' expected"); + default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected"); } check_match(ls, TK_END, TK_FOR, line); leaveblock(fs); /* loop scope (`break' jumps to this point) */ @@ -1284,7 +1290,7 @@ static void retstat (LexState *ls) { static void breakstat (LexState *ls) { - /* stat -> BREAK [NAME] */ + /* stat -> BREAK */ FuncState *fs = ls->fs; BlockCnt *bl = fs->bl; int upval = 0; diff --git a/src/lparser.h b/src/lparser.h index 582b4878..d8542f9c 100644 --- a/src/lparser.h +++ b/src/lparser.h @@ -1,5 +1,5 @@ /* -** $Id: lparser.h,v 1.51 2004/05/31 18:51:50 roberto Exp $ +** $Id: lparser.h,v 1.55 2005/04/25 19:24:10 roberto Exp $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -65,14 +65,15 @@ typedef struct FuncState { int freereg; /* first free register */ int nk; /* number of elements in `k' */ int np; /* number of elements in `p' */ - int nlocvars; /* number of elements in `locvars' */ + short nlocvars; /* number of elements in `locvars' */ lu_byte nactvar; /* number of active local variables */ - upvaldesc upvalues[MAXUPVALUES]; /* upvalues */ - unsigned short actvar[MAXVARS]; /* declared-variable stack */ + upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */ + unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */ } FuncState; -Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name); +LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, + const char *name); #endif diff --git a/src/lstate.c b/src/lstate.c index 18dd4f95..41162dac 100644 --- a/src/lstate.c +++ b/src/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 2.25 2005/02/23 17:30:22 roberto Exp $ +** $Id: lstate.c,v 2.31 2005/05/05 15:34:03 roberto Exp $ ** Global State ** See Copyright Notice in lua.h */ @@ -24,20 +24,9 @@ #include "ltm.h" -/* -** macro to allow the inclusion of user information in Lua state -*/ -#ifndef LUA_USERSTATE -#define EXTRASPACE 0 -#else -union UEXTRASPACE {L_Umaxalign a; LUA_USERSTATE b;}; -#define EXTRASPACE (sizeof(union UEXTRASPACE)) -#endif - - -#define state_size(x) (sizeof(x) + EXTRASPACE) -#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + EXTRASPACE)) -#define fromstate(l) (cast(lu_byte *, (l)) - EXTRASPACE) +#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE) +#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE) +#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE)) /* @@ -51,18 +40,21 @@ typedef struct LG { static void stack_init (lua_State *L1, lua_State *L) { + /* initialize CallInfo array */ + L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); + L1->ci = L1->base_ci; + L1->size_ci = BASIC_CI_SIZE; + L1->end_ci = L1->base_ci + L1->size_ci - 1; + /* initialize stack array */ L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue); L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; L1->top = L1->stack; L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; - L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); - L1->ci = L1->base_ci; + /* initialize first ci */ L1->ci->func = L1->top; setnilvalue(L1->top++); /* `function' entry for this `ci' */ L1->base = L1->ci->base = L1->top; L1->ci->top = L1->top + LUA_MINSTACK; - L1->size_ci = BASIC_CI_SIZE; - L1->end_ci = L1->base_ci + L1->size_ci - 1; } @@ -105,6 +97,7 @@ static void preinit_state (lua_State *L, global_State *g) { L->nCcalls = 0; L->status = 0; L->base_ci = L->ci = NULL; + L->savedpc = NULL; L->errfunc = 0; setnilvalue(gt(L)); } @@ -148,6 +141,7 @@ void luaE_freethread (lua_State *L, lua_State *L1) { LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { + int i; lua_State *L; global_State *g; void *l = (*f)(ud, NULL, 0, state_size(LG)); @@ -181,16 +175,17 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { g->weak = NULL; g->tmudata = NULL; g->totalbytes = sizeof(LG); - g->gcpace = 200; /* 200% (wait memory to double before next collection) */ - g->gcstepmul = 200; /* GC runs `twice the speed' of memory allocation */ + g->gcpause = LUAI_GCPAUSE; + g->gcstepmul = LUAI_GCMUL; g->gcdept = 0; + for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL; if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { /* memory allocation error: free partial state */ close_state(L); L = NULL; } else - lua_userstateopen(L); + luai_userstateopen(L); return L; } diff --git a/src/lstate.h b/src/lstate.h index 54469172..7dafa4d5 100644 --- a/src/lstate.h +++ b/src/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 2.16 2005/02/23 17:30:22 roberto Exp $ +** $Id: lstate.h,v 2.21 2005/05/05 15:34:03 roberto Exp $ ** Global State ** See Copyright Notice in lua.h */ @@ -83,12 +83,13 @@ typedef struct global_State { lu_mem totalbytes; /* number of bytes currently allocated */ lu_mem estimate; /* an estimate of number of bytes actually in use */ lu_mem gcdept; /* how much GC is `behind schedule' */ - int gcpace; /* size of pause between successive GCs */ + int gcpause; /* size of pause between successive GCs */ int gcstepmul; /* GC `granularity' */ lua_CFunction panic; /* to be called in unprotected errors */ TValue _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 */ TString *tmname[TM_N]; /* array with tag-method names */ } global_State; @@ -102,12 +103,13 @@ struct lua_State { StkId base; /* base of current function */ global_State *l_G; CallInfo *ci; /* call info for current function */ + const Instruction *savedpc; /* `savedpc' of current function */ StkId stack_last; /* last free slot in the stack */ StkId stack; /* stack base */ int stacksize; CallInfo *end_ci; /* points after end of ci array*/ CallInfo *base_ci; /* array of CallInfo's */ - unsigned short size_ci; /* size of array `base_ci' */ + int size_ci; /* size of array `base_ci' */ unsigned short nCcalls; /* number of nested C calls */ lu_byte hookmask; lu_byte allowhook; @@ -159,8 +161,8 @@ union GCObject { #define obj2gco(v) (cast(GCObject *, (v))) -lua_State *luaE_newthread (lua_State *L); -void luaE_freethread (lua_State *L, lua_State *L1); +LUAI_FUNC lua_State *luaE_newthread (lua_State *L); +LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); #endif diff --git a/src/lstring.h b/src/lstring.h index 88f6da80..1d2e91ea 100644 --- a/src/lstring.h +++ b/src/lstring.h @@ -1,5 +1,5 @@ /* -** $Id: lstring.h,v 1.42 2005/02/23 17:30:22 roberto Exp $ +** $Id: lstring.h,v 1.43 2005/04/25 19:24:10 roberto Exp $ ** String table (keep all strings handled by Lua) ** See Copyright Notice in lua.h */ @@ -23,9 +23,9 @@ #define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) -void luaS_resize (lua_State *L, int newsize); -Udata *luaS_newudata (lua_State *L, size_t s, Table *e); -TString *luaS_newlstr (lua_State *L, const char *str, size_t l); +LUAI_FUNC void luaS_resize (lua_State *L, int newsize); +LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); +LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); #endif diff --git a/src/lstrlib.c b/src/lstrlib.c index a9c002fb..4929a27c 100644 --- a/src/lstrlib.c +++ b/src/lstrlib.c @@ -1,5 +1,5 @@ /* -** $Id: lstrlib.c,v 1.109 2004/12/01 15:46:06 roberto Exp $ +** $Id: lstrlib.c,v 1.115 2005/05/17 19:49:15 roberto Exp $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ @@ -172,11 +172,11 @@ typedef struct MatchState { struct { const char *init; ptrdiff_t len; - } capture[MAX_CAPTURES]; + } capture[LUA_MAXCAPTURES]; } MatchState; -#define ESC '%' +#define L_ESC '%' #define SPECIALS "^$*+?.([%-" @@ -198,17 +198,17 @@ static int capture_to_close (MatchState *ms) { static const char *classend (MatchState *ms, const char *p) { switch (*p++) { - case ESC: { + case L_ESC: { if (*p == '\0') - luaL_error(ms->L, "malformed pattern (ends with `%%')"); + luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")"); return p+1; } case '[': { if (*p == '^') p++; do { /* look for a `]' */ if (*p == '\0') - luaL_error(ms->L, "malformed pattern (missing `]')"); - if (*(p++) == ESC && *p != '\0') + luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")"); + if (*(p++) == L_ESC && *p != '\0') p++; /* skip escapes (e.g. `%]') */ } while (*p != ']'); return p+1; @@ -246,7 +246,7 @@ static int matchbracketclass (int c, const char *p, const char *ec) { p++; /* skip the `^' */ } while (++p < ec) { - if (*p == ESC) { + if (*p == L_ESC) { p++; if (match_class(c, uchar(*p))) return sig; @@ -265,7 +265,7 @@ static int matchbracketclass (int c, const char *p, const char *ec) { static int singlematch (int c, const char *p, const char *ep) { switch (*p) { case '.': return 1; /* matches any char */ - case ESC: return match_class(c, uchar(*(p+1))); + case L_ESC: return match_class(c, uchar(*(p+1))); case '[': return matchbracketclass(c, p, ep-1); default: return (uchar(*p) == c); } @@ -327,7 +327,7 @@ static const char *start_capture (MatchState *ms, const char *s, const char *p, int what) { const char *res; int level = ms->level; - if (level >= MAX_CAPTURES) luaL_error(ms->L, "too many captures"); + if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures"); ms->capture[level].init = s; ms->capture[level].len = what; ms->level = level+1; @@ -371,7 +371,7 @@ static const char *match (MatchState *ms, const char *s, const char *p) { case ')': { /* end capture */ return end_capture(ms, s, p+1); } - case ESC: { + case L_ESC: { switch (*(p+1)) { case 'b': { /* balanced string? */ s = matchbalance(ms, s, p+2); @@ -382,7 +382,8 @@ static const char *match (MatchState *ms, const char *s, const char *p) { const char *ep; char previous; p += 2; if (*p != '[') - luaL_error(ms->L, "missing `[' after `%%f' in pattern"); + luaL_error(ms->L, "missing " LUA_QL("[") " after " + LUA_QL("%%f") " in pattern"); ep = classend(ms, p); /* points to what is next */ previous = (s == ms->src_init) ? '\0' : *(s-1); if (matchbracketclass(uchar(previous), p, ep-1) || @@ -525,8 +526,8 @@ static int str_find (lua_State *L) { static int gfind_aux (lua_State *L) { MatchState ms; - const char *s = lua_tostring(L, lua_upvalueindex(1)); - size_t ls = lua_strlen(L, lua_upvalueindex(1)); + size_t ls; + const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); const char *p = lua_tostring(L, lua_upvalueindex(2)); const char *src; ms.L = L; @@ -563,11 +564,11 @@ static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, const char *e) { lua_State *L = ms->L; if (lua_isstring(L, 3)) { - const char *news = lua_tostring(L, 3); - size_t l = lua_strlen(L, 3); + size_t l; + const char *news = lua_tolstring(L, 3, &l); size_t i; for (i=0; i<l; i++) { - if (news[i] != ESC) + if (news[i] != L_ESC) luaL_putchar(b, news[i]); else { i++; /* skip ESC */ @@ -682,7 +683,7 @@ static const char *scanformat (lua_State *L, const char *strfrmt, luaL_error(L, "invalid format (width or precision too long)"); if (p-strfrmt+2 > MAX_FORMAT) /* +2 to include `%' and the specifier */ luaL_error(L, "invalid format (too long)"); - form[0] = ESC; + form[0] = L_ESC; strncpy(form+1, strfrmt, p-strfrmt+1); form[p-strfrmt+2] = 0; return p; @@ -697,16 +698,14 @@ static int str_format (lua_State *L) { luaL_Buffer b; luaL_buffinit(L, &b); while (strfrmt < strfrmt_end) { - if (*strfrmt != ESC) + if (*strfrmt != L_ESC) luaL_putchar(&b, *strfrmt++); - else if (*++strfrmt == ESC) + else if (*++strfrmt == L_ESC) luaL_putchar(&b, *strfrmt++); /* %% */ else { /* format item */ char form[MAX_FORMAT]; /* to store the format (`%...') */ char buff[MAX_ITEM]; /* to store the formatted item */ int hasprecision = 0; - if (isdigit(uchar(*strfrmt)) && *(strfrmt+1) == '$') - return luaL_error(L, "obsolete option (d$) to `format'"); arg++; strfrmt = scanformat(L, strfrmt, form, &hasprecision); switch (*strfrmt++) { @@ -725,7 +724,7 @@ static int str_format (lua_State *L) { } case 'q': { addquoted(L, &b, arg); - continue; /* skip the `addsize' at the end */ + continue; /* skip the 'addsize' at the end */ } case 's': { size_t l; @@ -743,7 +742,7 @@ static int str_format (lua_State *L) { } } default: { /* also treat cases `pnLlh' */ - return luaL_error(L, "invalid option to `format'"); + return luaL_error(L, "invalid option to " LUA_QL("format")); } } luaL_addlstring(&b, buff, strlen(buff)); @@ -772,11 +771,26 @@ static const luaL_reg strlib[] = { }; +static void createmetatable (lua_State *L) { + lua_newtable(L); /* create metatable for strings */ + lua_pushliteral(L, ""); /* dummy string */ + lua_pushvalue(L, -2); + lua_setmetatable(L, -2); /* set string metatable */ + 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 */ +} + + /* ** Open string library */ LUALIB_API int luaopen_string (lua_State *L) { luaL_openlib(L, LUA_STRLIBNAME, strlib, 0); + createmetatable(L); return 1; } diff --git a/src/ltable.c b/src/ltable.c index d4070dd5..d0ba365b 100644 --- a/src/ltable.c +++ b/src/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 2.15 2005/01/10 18:17:39 roberto Exp $ +** $Id: ltable.c,v 2.23 2005/05/17 19:49:15 roberto Exp $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -18,6 +18,7 @@ ** Hence even when the load factor reaches 100%, performance remains good. */ +#include <math.h> #include <string.h> #define ltable_c @@ -37,10 +38,10 @@ /* ** max size of array part is 2^MAXBITS */ -#if LUA_BITSINT > 26 +#if LUAI_BITSINT > 26 #define MAXBITS 26 #else -#define MAXBITS (LUA_BITSINT-2) +#define MAXBITS (LUAI_BITSINT-2) #endif #define MAXASIZE (1 << MAXBITS) @@ -119,7 +120,7 @@ static int arrayindex (const TValue *key) { lua_Number n = nvalue(key); int k; lua_number2int(k, n); - if (num_eq(cast(lua_Number, k), nvalue(key))) + if (luai_numeq(cast(lua_Number, k), nvalue(key))) return k; } return -1; /* `key' did not match some condition */ @@ -150,7 +151,7 @@ static int findindex (lua_State *L, Table *t, StkId key) { } else n = gnext(n); } while (n); - luaG_runerror(L, "invalid key for `next'"); /* key not found */ + luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ return 0; /* to avoid warnings */ } } @@ -436,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)) && num_eq(nvalue(gkey(n)), nk)) + if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) return gval(n); /* that's it */ else n = gnext(n); } while (n); @@ -468,8 +469,9 @@ const TValue *luaH_get (Table *t, const TValue *key) { case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key)); case LUA_TNUMBER: { int k; - lua_number2int(k, (nvalue(key))); - if (num_eq(cast(lua_Number, k), nvalue(key))) /* is an integer index? */ + lua_Number n = nvalue(key); + lua_number2int(k, n); + if (luai_numeq(cast(lua_Number, k), nvalue(key))) /* index is integer? */ return luaH_getnum(t, k); /* use specialized version */ /* else go through */ } @@ -493,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) && !num_eq(nvalue(key), nvalue(key))) + else if (ttisnumber(key) && !luai_numeq(nvalue(key), nvalue(key))) luaG_runerror(L, "table index is NaN"); return newkey(L, t, key); } @@ -523,3 +525,50 @@ TValue *luaH_setstr (lua_State *L, Table *t, TString *key) { } } + +static int unbound_search (Table *t, unsigned int j) { + unsigned int i = j; /* i is zero or a present index */ + j = j+1; + /* find `i' and `j' such that i is present and j is not */ + while (!ttisnil(luaH_getnum(t, j))) { + i = j; + j = i*2; + if (j > cast(unsigned int, MAX_INT)) { /* overflow? */ + /* table was built with bad purposes: resort to linear search */ + i = 1; + while (!ttisnil(luaH_getnum(t, i))) i++; + return i - 1; + } + } + /* now do a binary search between them */ + while (i < j-1) { + unsigned int m = (i+j)/2; + if (ttisnil(luaH_getnum(t, m))) j = m; + else i = m; + } + return i; +} + + +/* +** Try to find a boundary in table `t'. A `boundary' is an integer index +** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). +*/ +int luaH_getn (Table *t) { + unsigned int j = t->sizearray; + if (j > 0 && ttisnil(&t->array[j - 1])) { + /* there is a boundary in the array part: (binary) search for it */ + unsigned int i = 0; + while (j - i > 1) { + unsigned int m = (i+j)/2; + if (ttisnil(&t->array[m - 1])) j = m; + else i = m; + } + return i; + } + /* else must find a boundary in hash part */ + else if (t->node == &luaH_dummynode) /* hash part is empty? */ + return j; /* that is easy... */ + else return unbound_search(t, j); +} + diff --git a/src/ltable.h b/src/ltable.h index 9700062e..1a798262 100644 --- a/src/ltable.h +++ b/src/ltable.h @@ -1,5 +1,5 @@ /* -** $Id: ltable.h,v 2.5 2005/01/05 18:20:51 roberto Exp $ +** $Id: ltable.h,v 2.7 2005/04/25 19:24:10 roberto Exp $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -20,19 +20,20 @@ extern const Node luaH_dummynode; -const TValue *luaH_getnum (Table *t, int key); -TValue *luaH_setnum (lua_State *L, Table *t, int key); -const TValue *luaH_getstr (Table *t, TString *key); -TValue *luaH_setstr (lua_State *L, Table *t, TString *key); -const TValue *luaH_get (Table *t, const TValue *key); -TValue *luaH_set (lua_State *L, Table *t, const TValue *key); -Table *luaH_new (lua_State *L, int narray, int lnhash); -void luaH_resizearray (lua_State *L, Table *t, int nasize); -void luaH_free (lua_State *L, Table *t); -int luaH_next (lua_State *L, Table *t, StkId key); +LUAI_FUNC const TValue *luaH_getnum (Table *t, int key); +LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key); +LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); +LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key); +LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); +LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); +LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash); +LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize); +LUAI_FUNC void luaH_free (lua_State *L, Table *t); +LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); +LUAI_FUNC int luaH_getn (Table *t); /* exported only for debugging */ -Node *luaH_mainposition (const Table *t, const TValue *key); +LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); #endif diff --git a/src/ltablib.c b/src/ltablib.c index 792bf313..ab4d5db2 100644 --- a/src/ltablib.c +++ b/src/ltablib.c @@ -1,5 +1,5 @@ /* -** $Id: ltablib.c,v 1.27 2004/12/07 18:28:47 roberto Exp $ +** $Id: ltablib.c,v 1.31 2005/05/17 19:49:15 roberto Exp $ ** Library for Table Manipulation ** See Copyright Notice in lua.h */ @@ -23,7 +23,7 @@ static int foreachi (lua_State *L) { int i; int n = aux_getn(L, 1); luaL_checktype(L, 2, LUA_TFUNCTION); - for (i=LUA_FIRSTINDEX; i < n+LUA_FIRSTINDEX; i++) { + for (i=1; i <= n; i++) { lua_pushvalue(L, 2); /* function */ lua_pushinteger(L, i); /* 1st argument */ lua_rawgeti(L, 1, i); /* 2nd argument */ @@ -62,39 +62,42 @@ static int getn (lua_State *L) { static int setn (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); +#ifndef luaL_setn luaL_setn(L, 1, luaL_checkint(L, 2)); +#else + luaL_error(L, LUA_QL("setn") " is obsolete"); +#endif lua_pushvalue(L, 1); return 1; } static int tinsert (lua_State *L) { - int v = lua_gettop(L); /* number of arguments */ - int e = aux_getn(L, 1) + LUA_FIRSTINDEX; /* first empty element */ + int e = aux_getn(L, 1) + 1; /* first empty element */ int pos; /* where to insert new element */ - if (v == 2) /* called with only 2 arguments */ + if (lua_isnone(L, 3)) /* called with only 2 arguments */ pos = e; /* insert new element at the end */ else { + int i; pos = luaL_checkint(L, 2); /* 2nd argument is the position */ if (pos > e) e = pos; /* `grow' array if necessary */ - v = 3; /* function may be called with more than 3 args */ - } - luaL_setn(L, 1, e - LUA_FIRSTINDEX + 1); /* new size */ - while (--e >= pos) { /* move up elements */ - lua_rawgeti(L, 1, e); - lua_rawseti(L, 1, e+1); /* t[e+1] = t[e] */ + lua_settop(L, 3); /* function may be called with more than 3 args */ + for (i = e; i > pos; i--) { /* move up elements */ + lua_rawgeti(L, 1, i-1); + lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ + } } - lua_pushvalue(L, v); + luaL_setn(L, 1, e); /* new size */ lua_rawseti(L, 1, pos); /* t[pos] = v */ return 0; } static int tremove (lua_State *L) { - int e = aux_getn(L, 1) + LUA_FIRSTINDEX - 1; + int e = aux_getn(L, 1); int pos = luaL_optint(L, 2, e); - if (e < LUA_FIRSTINDEX) return 0; /* table is `empty' */ - luaL_setn(L, 1, e - LUA_FIRSTINDEX); /* t.n = n-1 */ + if (e == 0) return 0; /* table is `empty' */ + luaL_setn(L, 1, e - 1); /* t.n = n-1 */ lua_rawgeti(L, 1, pos); /* result = t[pos] */ for ( ;pos<e; pos++) { lua_rawgeti(L, 1, pos+1); @@ -110,11 +113,11 @@ static int str_concat (lua_State *L) { luaL_Buffer b; size_t lsep; const char *sep = luaL_optlstring(L, 2, "", &lsep); - int i = luaL_optint(L, 3, LUA_FIRSTINDEX); + int i = luaL_optint(L, 3, 1); int last = luaL_optint(L, 4, -2); luaL_checktype(L, 1, LUA_TTABLE); if (last == -2) - last = luaL_getn(L, 1) + LUA_FIRSTINDEX - 1; + last = luaL_getn(L, 1); luaL_buffinit(L, &b); for (; i <= last; i++) { lua_rawgeti(L, 1, i); @@ -226,7 +229,7 @@ static int sort (lua_State *L) { if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ luaL_checktype(L, 2, LUA_TFUNCTION); lua_settop(L, 2); /* make sure there is two arguments */ - auxsort(L, LUA_FIRSTINDEX, n + LUA_FIRSTINDEX - 1); + auxsort(L, 1, n); return 0; } @@ -1,5 +1,5 @@ /* -** $Id: ltm.c,v 2.3 2004/04/30 20:13:38 roberto Exp $ +** $Id: ltm.c,v 2.5 2005/05/05 15:34:03 roberto Exp $ ** Tag methods ** See Copyright Notice in lua.h */ @@ -31,8 +31,8 @@ void luaT_init (lua_State *L) { static const char *const luaT_eventname[] = { /* ORDER TM */ "__index", "__newindex", "__gc", "__mode", "__eq", - "__add", "__sub", "__mul", "__div", - "__pow", "__unm", "__lt", "__le", + "__add", "__sub", "__mul", "__div", "__mod", + "__pow", "__unm", "__siz", "__lt", "__le", "__concat", "__call" }; int i; @@ -68,8 +68,8 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) { mt = uvalue(o)->metatable; break; default: - mt = NULL; + mt = G(L)->mt[ttype(o)]; } - return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : &luaO_nilobject); + return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : &luaO_nilobject); } @@ -1,5 +1,5 @@ /* -** $Id: ltm.h,v 2.1 2003/12/10 12:13:36 roberto Exp $ +** $Id: ltm.h,v 2.4 2005/05/05 15:34:03 roberto Exp $ ** Tag methods ** See Copyright Notice in lua.h */ @@ -25,8 +25,10 @@ typedef enum { TM_SUB, TM_MUL, TM_DIV, + TM_MOD, TM_POW, TM_UNM, + TM_SIZ, TM_LT, TM_LE, TM_CONCAT, @@ -41,11 +43,12 @@ typedef enum { #define fasttm(l,et,e) gfasttm(G(l), et, e) +extern const char *const luaT_typenames[]; -const TValue *luaT_gettm (Table *events, TMS event, TString *ename); -const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event); -void luaT_init (lua_State *L); -extern const char *const luaT_typenames[]; +LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); +LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, + TMS event); +LUAI_FUNC void luaT_init (lua_State *L); #endif @@ -1,5 +1,5 @@ /* -** $Id: lua.c,v 1.135 2005/01/10 17:21:10 roberto Exp $ +** $Id: lua.c,v 1.144 2005/05/17 19:49:15 roberto Exp $ ** Lua stand-alone interpreter ** See Copyright Notice in lua.h */ @@ -18,19 +18,10 @@ #include "lualib.h" -/* -** generic extra include file -*/ -#ifdef LUA_USERCONFIG -#include LUA_USERCONFIG -#endif - - - static lua_State *globalL = NULL; -static const char *progname = PROGNAME; +static const char *progname = LUA_PROGNAME; @@ -53,10 +44,11 @@ static void print_usage (void) { "usage: %s [options] [script [args]].\n" "Available options are:\n" " - execute stdin as a file\n" - " -e stat execute string `stat'\n" - " -i enter interactive mode after executing `script'\n" - " -l name load and run library `name'\n" + " -e stat execute string " LUA_QL("stat") "\n" + " -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); } @@ -110,15 +102,14 @@ static void print_version (void) { } -static int getargs (lua_State *L, char *argv[], int n) { - int i, narg; - for (i=n+1; argv[i]; i++) { - luaL_checkstack(L, 1, "too many arguments to script"); +static int getargs (lua_State *L, int argc, char **argv, int n) { + int narg = argc - (n + 1); /* number of arguments to the script */ + int i; + luaL_checkstack(L, narg + 3, "too many arguments to script"); + for (i=n+1; i < argc; i++) lua_pushstring(L, argv[i]); - } - narg = i-(n+1); /* number of arguments to the script (not to `lua.c') */ lua_newtable(L); - for (i=0; argv[i]; i++) { + for (i=0; i < argc; i++) { lua_pushstring(L, argv[i]); lua_rawseti(L, -2, i - n); } @@ -139,54 +130,18 @@ static int dostring (lua_State *L, const char *s, const char *name) { static int dolibrary (lua_State *L, const char *name) { - luaL_getfield(L, LUA_GLOBALSINDEX, "package.path"); - if (!lua_isstring(L, -1)) { - l_message(progname, "`package.path' must be a string"); - return 1; - } - name = luaL_searchpath(L, name, lua_tostring(L, -1)); - if (name == NULL) return report(L, 1); - else return dofile(L, name); -} - - - -/* -** this macro defines a function to show the prompt and reads the -** next line for manual input -*/ -#ifndef lua_readline -#define lua_readline(L,prompt) readline(L,prompt) - -/* maximum length of an input line */ -#ifndef MAXINPUT -#define MAXINPUT 512 -#endif - - -static int readline (lua_State *L, const char *prompt) { - static char buffer[MAXINPUT]; - if (prompt) { - fputs(prompt, stdout); - fflush(stdout); - } - if (fgets(buffer, sizeof(buffer), stdin) == NULL) - return 0; /* read fails */ - else { - lua_pushstring(L, buffer); - return 1; - } + lua_getglobal(L, "require"); + lua_pushstring(L, name); + return report(L, lua_pcall(L, 1, 0, 0)); } -#endif - static const char *get_prompt (lua_State *L, int firstline) { - const char *p = NULL; + const char *p; lua_pushstring(L, firstline ? "_PROMPT" : "_PROMPT2"); lua_rawget(L, LUA_GLOBALSINDEX); p = lua_tostring(L, -1); - if (p == NULL) p = (firstline ? PROMPT : PROMPT2); + if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2); lua_pop(L, 1); /* remove global */ return p; } @@ -194,7 +149,7 @@ 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), "near `<eof>'") != NULL) { + strstr(lua_tostring(L, -1), "<eof>") != NULL) { lua_pop(L, 1); return 1; } @@ -203,23 +158,40 @@ static int incomplete (lua_State *L, int status) { } +static int pushline (lua_State *L, int firstline) { + char buffer[LUA_MAXINPUT]; + char *b = buffer; + size_t l; + const char *prmt = get_prompt(L, firstline); + if (lua_readline(L, b, prmt) == 0) + return 0; /* no input */ + l = strlen(b); + if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ + b[l-1] = '\0'; /* remove it */ + if (firstline && b[0] == '=') /* first line starts with `=' ? */ + lua_pushfstring(L, "return %s", b+1); /* change it to `return' */ + else + lua_pushstring(L, b); + lua_freeline(L, b); + return 1; +} + + static int loadline (lua_State *L) { int status; lua_settop(L, 0); - if (lua_readline(L, get_prompt(L, 1)) == 0) /* no input? */ - return -1; - if (lua_tostring(L, -1)[0] == '=') { /* line starts with `=' ? */ - lua_pushfstring(L, "return %s", lua_tostring(L, -1)+1);/* `=' -> `return' */ - lua_remove(L, -2); /* remove original line */ - } + if (!pushline(L, 1)) + return -1; /* no input */ for (;;) { /* repeat until gets a complete line */ status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); if (!incomplete(L, status)) break; /* cannot try to add lines? */ - if (lua_readline(L, get_prompt(L, 0)) == 0) /* no more input? */ + if (!pushline(L, 0)) /* no more input? */ return -1; - lua_concat(L, lua_gettop(L)); /* join lines */ + lua_pushliteral(L, "\n"); /* add a new line... */ + lua_insert(L, -2); /* ...between the two lines */ + lua_concat(L, 3); /* join them */ } - lua_saveline(L, lua_tostring(L, 1)); + lua_saveline(L, 1); lua_remove(L, 1); /* remove line */ return status; } @@ -237,8 +209,9 @@ static void dotty (lua_State *L) { lua_getglobal(L, "print"); lua_insert(L, 1); if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) - l_message(progname, lua_pushfstring(L, "error calling `print' (%s)", - lua_tostring(L, -1))); + l_message(progname, lua_pushfstring(L, + "error calling " LUA_QL("print") " (%s)", + lua_tostring(L, -1))); } } lua_settop(L, 0); /* clear stack */ @@ -250,17 +223,17 @@ static void dotty (lua_State *L) { static int checkvar (lua_State *L) { const char *name = lua_tostring(L, 2); if (name) - luaL_error(L, "attempt to access undefined variable `%s'", 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, char *argv[], int *interactive) { +static int handle_argv (lua_State *L, int argc, char **argv, int *interactive) { if (argv[1] == NULL) { /* no arguments? */ *interactive = 0; - if (stdin_is_tty()) + if (lua_stdin_is_tty()) dotty(L); else dofile(L, NULL); /* executes stdin as a file */ @@ -330,9 +303,9 @@ static int handle_argv (lua_State *L, char *argv[], int *interactive) { } } endloop: if (argv[i] != NULL) { - const char *filename = argv[i]; - int narg = getargs(L, argv, i); /* collect arguments */ int status; + const char *filename = argv[i]; + int narg = getargs(L, argc, argv, i); /* collect arguments */ lua_setglobal(L, "arg"); clearinteractive(interactive); status = luaL_loadfile(L, filename); @@ -371,10 +344,10 @@ static int pmain (lua_State *L) { int interactive = 1; if (s->argv[0] && s->argv[0][0]) progname = s->argv[0]; globalL = L; - luaopen_stdlibs(L); /* open libraries */ + luaL_openlibs(L); /* open libraries */ status = handle_luainit(L); if (status == 0) { - status = handle_argv(L, s->argv, &interactive); + status = handle_argv(L, s->argc, s->argv, &interactive); if (status == 0 && interactive) dotty(L); } s->status = status; @@ -382,7 +355,7 @@ static int pmain (lua_State *L) { } -int main (int argc, char *argv[]) { +int main (int argc, char **argv) { int status; struct Smain s; lua_State *L = lua_open(); /* create state */ @@ -1,8 +1,8 @@ /* -** $Id: lua.h,v 1.202 2005/02/18 12:40:02 roberto Exp $ +** $Id: lua.h,v 1.208 2005/05/17 19:49:15 roberto Exp $ ** Lua - An Extensible Extension Language ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil -** http://www.lua.org mailto:info@lua.org +** http://www.lua.org ** See Copyright Notice at the end of this file */ @@ -17,7 +17,7 @@ #include "luaconf.h" -#define LUA_VERSION "Lua 5.1 (work5)" +#define LUA_VERSION "Lua 5.1 (work6)" #define LUA_VERSION_NUM 501 #define LUA_COPYRIGHT "Copyright (C) 1994-2005 Tecgraf, PUC-Rio" #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" @@ -55,10 +55,9 @@ typedef int (*lua_CFunction) (lua_State *L); /* ** functions that read/write blocks when loading/dumping Lua chunks */ -typedef const char * (*lua_Chunkreader) (lua_State *L, void *ud, size_t *sz); +typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); -typedef int (*lua_Chunkwriter) (lua_State *L, const void* p, - size_t sz, void* ud); +typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); /* @@ -70,22 +69,19 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); /* ** basic types */ -#define LUA_TNONE (-1) +#define LUA_TNONE (-1) -#define LUA_TNIL 0 -#define LUA_TBOOLEAN 1 +#define LUA_TNIL 0 +#define LUA_TBOOLEAN 1 #define LUA_TLIGHTUSERDATA 2 -#define LUA_TNUMBER 3 -#define LUA_TSTRING 4 -#define LUA_TTABLE 5 -#define LUA_TFUNCTION 6 -#define LUA_TUSERDATA 7 -#define LUA_TTHREAD 8 +#define LUA_TNUMBER 3 +#define LUA_TSTRING 4 +#define LUA_TTABLE 5 +#define LUA_TFUNCTION 6 +#define LUA_TUSERDATA 7 +#define LUA_TTHREAD 8 -/* first index for arrays */ -#define LUA_FIRSTINDEX 1 - /* minimum Lua stack available to a C function */ #define LUA_MINSTACK 20 @@ -94,7 +90,7 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); /* ** generic extra include file */ -#ifdef LUA_USER_H +#if defined(LUA_USER_H) #include LUA_USER_H #endif @@ -150,7 +146,7 @@ LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2); 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_tostring) (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 lua_CFunction (lua_tocfunction) (lua_State *L, int idx); LUA_API void *(lua_touserdata) (lua_State *L, int idx); @@ -204,11 +200,11 @@ LUA_API int (lua_setfenv) (lua_State *L, int idx); */ LUA_API void (lua_call) (lua_State *L, int nargs, int nresults); LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc); -LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); -LUA_API int (lua_load) (lua_State *L, lua_Chunkreader reader, void *dt, +LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); +LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, const char *chunkname); -LUA_API int (lua_dump) (lua_State *L, lua_Chunkwriter writer, void *data); +LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); /* @@ -227,7 +223,7 @@ LUA_API int (lua_status) (lua_State *L); #define LUA_GCCOLLECT 2 #define LUA_GCCOUNT 3 #define LUA_GCSTEP 4 -#define LUA_GCSETPACE 5 +#define LUA_GCSETPAUSE 5 #define LUA_GCSETSTEPMUL 6 LUA_API int (lua_gc) (lua_State *L, int what, int data); @@ -278,6 +274,8 @@ LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); #define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) #define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) +#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) + /* @@ -290,7 +288,8 @@ LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); #define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0) - +#define lua_Chunkreader lua_Reader +#define lua_Chunkwriter lua_Writer @@ -321,6 +320,8 @@ LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); typedef struct lua_Debug lua_Debug; /* activation record */ + +/* Functions to be called by the debuger in specific events */ typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); @@ -337,8 +338,6 @@ LUA_API int lua_gethookmask (lua_State *L); LUA_API int lua_gethookcount (lua_State *L); -#define LUA_IDSIZE 60 - struct lua_Debug { int event; const char *name; /* (n) */ @@ -348,6 +347,7 @@ struct lua_Debug { int currentline; /* (l) */ int nups; /* (u) number of upvalues */ int linedefined; /* (S) */ + int lastlinedefined; /* (S) */ char short_src[LUA_IDSIZE]; /* (S) */ /* private part */ int i_ci; /* active function */ @@ -357,7 +357,7 @@ struct lua_Debug { /****************************************************************************** -* Copyright (C) 1994-2004 Tecgraf, PUC-Rio. All rights reserved. +* Copyright (C) 1994-2005 Tecgraf, 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 @@ -1,5 +1,5 @@ /* -** $Id: luac.c,v 1.49 2004/09/01 21:22:34 lhf Exp $ +** $Id: luac.c,v 1.50 2005/05/12 00:26:50 lhf Exp $ ** Lua compiler (saves bytecodes to files; also list bytecodes) ** See Copyright Notice in lua.h */ @@ -151,8 +151,6 @@ static int writer(lua_State* L, const void* p, size_t size, void* u) return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0); } -void unprint(lua_State* L, const char* name); - struct Smain { int argc; char **argv; diff --git a/src/luaconf.h b/src/luaconf.h index 04b8e990..bc211cd3 100644 --- a/src/luaconf.h +++ b/src/luaconf.h @@ -1,5 +1,5 @@ /* -** $Id: luaconf.h,v 1.30 2005/02/28 15:59:11 roberto Exp $ +** $Id: luaconf.h,v 1.49a 2005/05/17 19:49:15 roberto Exp $ ** Configuration file for Lua ** See Copyright Notice in lua.h */ @@ -13,387 +13,658 @@ /* -** {====================================================== -** Index (search for keyword to find corresponding entry) -** ======================================================= +** ================================================================== +** Search for "@@" to find all configurable definitions. +** =================================================================== */ -/* }====================================================== */ - - /* -** {====================================================== -** Generic configuration -** ======================================================= +@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for +@* Lua libraries. +@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for +@* C libraries. +** CHANGE them if your machine has a non-conventional directory +** hierarchy or if you want to install your libraries in +** non-conventional directories. */ - -/* default path */ #if defined(_WIN32) #define LUA_ROOT "C:\\Program Files\\Lua51" #define LUA_LDIR LUA_ROOT "\\lua" #define LUA_CDIR LUA_ROOT "\\dll" #define LUA_PATH_DEFAULT \ - "?.lua;" LUA_LDIR "\\?.lua;" LUA_LDIR "\\?\\init.lua" -#define LUA_CPATH_DEFAULT "?.dll;" LUA_CDIR "\\?.dll" + "?.lua;" LUA_LDIR"\\?.lua;" LUA_LDIR"\\?\\init.lua" +#define LUA_CPATH_DEFAULT \ + "?.dll;" "l?.dll;" LUA_CDIR"\\?.dll;" LUA_CDIR"\\l?.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_PATH_DEFAULT \ - "./?.lua;" LUA_LDIR "/?.lua;" LUA_LDIR "/?/init.lua" -#define LUA_CPATH_DEFAULT "./?.so;" LUA_CDIR "/?.so" + "./?.lua;" LUA_LDIR"/?.lua;" LUA_LDIR"/?/init.lua" +#define LUA_CPATH_DEFAULT \ + "./?.so;" "./l?.so;" LUA_CDIR"/?.so;" LUA_CDIR"/l?.so" #endif +/* +@@ LUA_DIRSEP is the directory separator (for submodules). +** CHANGE it if your machine does not use "/" as the directory separator +** and is not Windows. (On Windows Lua automatically uses "\".) +*/ +#if defined(_WIN32) +#define LUA_DIRSEP "\\" +#else +#define LUA_DIRSEP "/" +#endif -/* type of numbers in Lua */ -#define LUA_NUMBER double -/* formats for Lua numbers */ -#define LUA_NUMBER_SCAN "%lf" -#define LUA_NUMBER_FMT "%.14g" +/* +@@ 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 ';' /* -** type for integer functions -** on most machines, `ptrdiff_t' gives a reasonable size for integers +@@ 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. +*/ +#define LUA_PATH_MARK "?" + + +/* +@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. +** CHANGE that if ptrdiff_t is not adequate on your machine. (On most +** machines, ptrdiff_t gives a good choice between int or long.) */ #define LUA_INTEGER ptrdiff_t -/* mark for all API functions */ +/* +@@ LUA_API is a mark for all core API functions. +@@ LUALIB_API is a mark for all standard library functions. +** CHANGE them if you need to define those functions in some special way. +** For instance, if you want to create one Windows DLL with the core and +** the libraries, you may want to use the following definition (define +** LUA_BUILD_AS_DLL to get it). +*/ +#if defined(LUA_BUILD_AS_DLL) + +#if defined(LUA_CORE) || defined(LUA_LIB) +#define LUA_API __declspec(__dllexport) +#else +#define LUA_API __declspec(__dllimport) +#endif + +#else + #define LUA_API extern -/* mark for auxlib functions */ -#define LUALIB_API extern +#endif -/* buffer size used by lauxlib buffer system */ -#define LUAL_BUFFERSIZE BUFSIZ +/* more often than not the libs go together with the core */ +#define LUALIB_API LUA_API -/* assertions in Lua (mainly for internal debugging) */ +/* +@@ 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. +*/ +#if defined(luaall_c) +#define LUAI_FUNC static +#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) +#define LUAI_FUNC __attribute__((visibility("hidden"))) +#else +#define LUAI_FUNC extern +#endif + + +/* +@@ lua_assert describes the internal assertions in Lua. +** CHANGE that only if you need to debug Lua. +*/ #define lua_assert(c) ((void)0) -/* }====================================================== */ +/* +@@ LUA_QL describes how error messages quote program elements. +** CHANGE it if you want a different appearance. +*/ +#define LUA_QL(x) "'" x "'" +#define LUA_QS LUA_QL("%s") /* -** {====================================================== +@@ LUA_IDSIZE gives the maximum size for the description of the source +@* of a function in debug information. +** CHANGE it if you a different size. +*/ +#define LUA_IDSIZE 60 + + +/* +** {================================================================== ** Stand-alone configuration -** ======================================================= +** =================================================================== */ -#ifdef lua_c +#if defined(lua_c) || defined(luaall_c) -/* definition of `isatty' */ -#ifdef _POSIX_C_SOURCE +/* +@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that +@* is, whether we're running lua interactively). +** CHANGE it if you have a better definition for non-POSIX/non-Windows +** systems. +*/ +#if !defined(__STRICT_ANSI__) && defined(_POSIX_C_SOURCE) #include <unistd.h> -#define stdin_is_tty() isatty(0) -#elif defined(_WIN32) +#define lua_stdin_is_tty() isatty(0) +#elif !defined(__STRICT_ANSI__) && defined(_WIN32) #include <io.h> #include <stdio.h> -#define stdin_is_tty() _isatty(_fileno(stdin)) +#define lua_stdin_is_tty() _isatty(_fileno(stdin)) #else -#define stdin_is_tty() 1 /* assume stdin is a tty */ +#define lua_stdin_is_tty() 1 /* assume stdin is a tty */ #endif -#define PROMPT "> " -#define PROMPT2 ">> " -#define PROGNAME "lua" +/* +@@ LUA_PROMPT is the default prompt used by stand-alone Lua. +@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua. +** CHANGE them if you want different prompts. (You can also change the +** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.) +*/ +#define LUA_PROMPT "> " +#define LUA_PROMPT2 ">> " +/* +@@ LUA_PROGNAME is the default name for the stand-alone Lua program. +** CHANGE it if your stand-alone interpreter has a different name and +** your system is not able to detect that name automatically. +*/ +#define LUA_PROGNAME "lua" /* -** this macro can be used by some `history' system to save lines -** read in manual input +@@ LUA_MAXINPUT is the maximum length for an input line in the +@* stand-alone interpreter. +** CHANGE it if you need longer lines. */ -#define lua_saveline(L,line) /* empty */ +#define LUA_MAXINPUT 512 +/* +@@ lua_readline defines how to show a prompt and then read a line from +@* the standard input. +@@ lua_saveline defines how to "save" a read line in a "history". +@@ lua_freeline defines how to free a line read by lua_readline. +** 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) +#include <stdio.h> +#include <readline/readline.h> +#include <readline/history.h> +#define lua_readline(L,b,p) (((b)=readline(p)) != NULL) +#define lua_saveline(L,idx) \ + if (lua_strlen(L,idx) > 0) /* non-empty line? */ \ + add_history(lua_tostring(L, idx)); /* add it to history */ +#define lua_freeline(L,b) free(b) +#else +#define lua_readline(L,b,p) \ + (fputs(p, stdout), fflush(stdout), /* show prompt */ \ + fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ +#define lua_saveline(L,idx) ((void)0) +#define lua_freeline(L,b) ((void)0) +#endif #endif -/* }====================================================== */ +/* }================================================================== */ + + +/* +@@ 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.) +*/ +#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */ + + +/* +@@ LUAI_GCMUL defines the 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.) +*/ +#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. +*/ +#define LUA_COMPAT_GETN 0 +/* +@@ 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. +*/ +#define LUA_COMPAT_PATH 0 /* -** {====================================================== -** Core configuration -** ======================================================= +@@ 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'). */ +#define LUA_COMPAT_LOADLIB 1 -#ifdef LUA_CORE +/* +@@ 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. +*/ +#define LUA_COMPAT_VARARG 1 -/* LUA-C API assertions */ -#define api_check(L,o) lua_assert(o) +/* +@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting +@* facility. +** CHANGE it to 2 if you want the old behaviour, or undefine it to turn +** off the advisory error when nesting [[...]]. +*/ +#define LUA_COMPAT_LSTR 1 + +/* +@@ 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 +** a bit, but may be quite useful when debugging C code that interfaces +** with Lua. A useful redefinition is to use assert.h. +*/ +#if defined(LUA_USE_APICHECK) +#include <assert.h> +#define luai_apicheck(L,o) assert(o) +#else +/* (By default lua_assert is empty, so luai_apicheck is also empty.) */ +#define luai_apicheck(L,o) lua_assert(o) +#endif -/* number of bits in an `int' */ +/* +@@ LUAI_BITSINT defines the number of bits in an int. +** CHANGE here if Lua cannot automatically detect the number of bits of +** your machine. Probably you do not need to change this. +*/ /* avoid overflows in comparison */ #if INT_MAX-20 < 32760 -#define LUA_BITSINT 16 +#define LUAI_BITSINT 16 #elif INT_MAX > 2147483640L -/* `int' has at least 32 bits */ -#define LUA_BITSINT 32 +/* int has at least 32 bits */ +#define LUAI_BITSINT 32 #else #error "you must define LUA_BITSINT with number of bits in an integer" #endif /* -** L_UINT32: unsigned integer with at least 32 bits -** L_INT32: signed integer with at least 32 bits -** LU_MEM: an unsigned integer big enough to count the total memory used by Lua -** L_MEM: a signed integer big enough to count the total memory used by Lua +@@ LUAI_UINT32 is an unsigned integer with at least 32 bits. +@@ LUAI_INT32 is an signed integer with at least 32 bits. +@@ LUAI_UMEM is an unsigned integer big enough to count the total +@* memory used by Lua. +@@ LUAI_MEM is a signed integer big enough to count the total memory +@* used by Lua. +** CHANGE here if for some weird reason the default definitions are not +** good enough for your machine. (The definitions in the 'else' +** part always works, but may waste space on machines with 64-bit +** longs.) Probably you do not need to change this. */ -#if LUA_BITSINT >= 32 -#define LUA_UINT32 unsigned int -#define LUA_INT32 int -#define LUA_MAXINT32 INT_MAX -#define LU_MEM size_t -#define L_MEM ptrdiff_t +#if LUAI_BITSINT >= 32 +#define LUAI_UINT32 unsigned int +#define LUAI_INT32 int +#define LUAI_MAXINT32 INT_MAX +#define LUAI_UMEM size_t +#define LUAI_MEM ptrdiff_t #else /* 16-bit ints */ -#define LUA_UINT32 unsigned long -#define LUA_INT32 long -#define LUA_MAXINT32 LONG_MAX -#define LU_MEM LUA_UINT32 -#define L_MEM ptrdiff_t +#define LUAI_UINT32 unsigned long +#define LUAI_INT32 long +#define LUAI_MAXINT32 LONG_MAX +#define LUAI_UMEM unsigned long +#define LUAI_MEM long #endif -/* maximum depth for calls (unsigned short) */ -#define LUA_MAXCALLS 10000 - /* -** maximum depth for C calls (unsigned short): Not too big, or may -** overflow the C stack... +@@ LUAI_MAXCALLS limits the number of nested calls. +** CHANGE it if you need really deep recursive calls. This limit is +** arbitrary; its only purpose is to stop infinite recursion before +** exhausting memory. */ -#define LUA_MAXCCALLS 200 - - -/* maximum size for the virtual stack of a C function */ -#define MAXCSTACK 2048 +#define LUAI_MAXCALLS 20000 /* -** maximum number of syntactical nested non-terminals: Not too big, -** or may overflow the C stack... +@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function +@* can use. +** CHANGE it if you need lots of (Lua) stack space for your C +** functions. This limit is arbitrary; its only purpose is to stop C +** functions to consume unlimited stack space. */ -#define LUA_MAXPARSERLEVEL 200 +#define LUAI_MAXCSTACK 2048 -/* maximum number of variables declared in a function */ -#define MAXVARS 200 /* <MAXSTACK */ - -/* maximum number of upvalues per function */ -#define MAXUPVALUES 60 /* <MAXSTACK */ +/* +** {================================================================== +** CHANGE (to smaller values) the following definitions if your system +** has a small C stack. (Or you may want to change them to larger +** values if your system has a large C stack and these limits are +** too rigid for you.) Some of these constants control the size of +** stack-allocated arrays used by the compiler or the interpreter, while +** others limit the maximum number of recursive calls that the compiler +** or the interpreter can perform. Values too large may cause a C stack +** overflow for some forms of deep constructs. +** =================================================================== +*/ -/* maximum size of expressions for optimizing `while' code */ -#define MAXEXPWHILE 100 +/* +@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and +@* syntactical nested non-terminals in a program. +*/ +#define LUAI_MAXCCALLS 200 -/* function to convert a lua_Number to int (with any rounding method) */ -#if defined(__GNUC__) && defined(__i386) -#define lua_number2int(i,d) __asm__ ("fistpl %0":"=m"(i):"t"(d):"st") +/* +@@ LUAI_MAXVARS is the maximum number of local variables per function +@* (must be smaller than 250). +*/ +#define LUAI_MAXVARS 200 -#elif defined(_MSC_VER) && defined(_M_IX86) -#pragma warning(disable: 4514) -__inline int l_lrint (double flt) -{ int i; - _asm { - fld flt - fistp i - }; - return i; -} -#define lua_number2int(i,d) ((i)=l_lrint((d))) - -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199900L) -/* on machines compliant with C99, you can try `lrint' */ -#include <math.h> -#define lua_number2int(i,d) ((i)=lrint(d)) -#else -#define lua_number2int(i,d) ((i)=(int)(d)) +/* +@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function +@* (must be smaller than 250). +*/ +#define LUAI_MAXUPVALUES 60 -#endif +/* +@@ LUAI_MAXEXPWHILE is the maximum size of code for expressions +@* controling a 'while' loop. +*/ +#define LUAI_MAXEXPWHILE 100 -/* function to convert a lua_Number to lua_Integer (with any rounding method) */ -#define lua_number2integer(i,n) lua_number2int((i), (n)) +/* +@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. +*/ +#define LUAL_BUFFERSIZE BUFSIZ -/* function to convert a lua_Number to a string */ -#include <stdio.h> -#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) -/* maximum size of previous conversion */ -#define MAX_NUMBER2STR 32 /* 16 digits, sign, point and \0 (+ some extra) */ +/* }================================================================== */ -/* function to convert a string to a lua_Number */ -#define lua_str2number(s,p) strtod((s), (p)) +/* +@@ 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 +** 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. +*/ -/* result of a `usual argument conversion' over lua_Number */ -#define LUA_UACNUMBER double +/* 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 -/* primitive operators for numbers */ -#define num_add(a,b) ((a)+(b)) -#define num_sub(a,b) ((a)-(b)) -#define num_mul(a,b) ((a)*(b)) -#define num_div(a,b) ((a)/(b)) -#define num_unm(a) (-(a)) -#define num_eq(a,b) ((a)==(b)) -#define num_lt(a,b) ((a)<(b)) -#define num_le(a,b) ((a)<=(b)) -#include <math.h> -#define num_pow(a,b) pow(a,b) +/* 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)) -/* type to ensure maximum alignment */ -#define LUSER_ALIGNMENT_T union { double u; void *s; long l; } +#endif /* -** exception handling: by default, Lua handles errors with longjmp/setjmp -** when compiling as C code and with exceptions when compiling as C++ code. -** Change that if you prefer to use longjmp/setjmp even with C++. +@@ lua_number2integer is a macro to convert lua_Number to lua_Integer. +** CHANGE (see lua_number2int). */ -#ifndef __cplusplus -/* default handling with long jumps */ -#include <setjmp.h> -#define L_THROW(L,c) longjmp((c)->b, 1) -#define L_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } -#define l_jmpbuf jmp_buf +/* On a gcc or Windows/Pentium, resort to assembler */ +#if (defined(__GNUC__) && defined(__i386)) || \ + (defined(_MSC_VER) && defined(_M_IX86)) +#define lua_number2integer(i,n) lua_number2int(i, n) +/* this option always works, but may be slow */ #else -/* C++ exceptions */ -#define L_THROW(L,c) throw(c) -#define L_TRY(L,c,a) try { a } catch(...) \ - { if ((c)->status == 0) (c)->status = -1; } -#define l_jmpbuf int /* dummy variable */ +#define lua_number2integer(i,d) ((i)=(lua_Integer)(d)) + #endif /* -** macros for thread synchronization inside Lua core machine: This is -** an attempt to simplify the implementation of a multithreaded version -** of Lua. Do not change that unless 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). +** {================================================================== +@@ LUA_NUMBER is the type of numbers in Lua. +** CHANGE the following definitions only if you want to build Lua +** with a number type different from double. You may also need to +** change lua_number2int & lua_number2integer. +** =================================================================== */ -#define lua_lock(L) ((void) 0) -#define lua_unlock(L) ((void) 0) /* -** this macro allows a thread switch in appropriate places in the Lua -** core +@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' +@* over a number. */ -#define lua_threadyield(L) {lua_unlock(L); lua_lock(L);} +#define LUA_NUMBER double +#define LUAI_UACNUMBER LUA_NUMBER +/* +@@ LUA_NUMBER_SCAN is the format for reading numbers. +@@ LUA_NUMBER_FMT is the format for writing numbers. +@@ lua_number2str converts a number to a string. +@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. +@@ lua_str2number converts a string to a number. +*/ +#define LUA_NUMBER_SCAN "%lf" +#define LUA_NUMBER_FMT "%.14g" +#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) +#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ +#define lua_str2number(s,p) strtod((s), (p)) -/* allows user-specific initialization on new threads */ -#define lua_userstateopen(L) ((void)0) +/* +@@ 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)) -#endif +/* }================================================================== */ -/* }====================================================== */ +/* +@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment. +** CHANGE it if your system requires alignments larger than double. (For +** instance, if your system supports long doubles and they must be +** aligned in 16-byte boundaries, then you should add long double in the +** union.) Probably you do not need to change this. +*/ +#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } /* -** {====================================================== -** Library configuration -** ======================================================= +@@ 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 +** 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. */ +#if defined(__cplusplus) +/* C++ exceptions */ +#define LUAI_THROW(L,c) throw(c) +#define LUAI_TRY(L,c,a) try { a } catch(...) \ + { if ((c)->status == 0) (c)->status = -1; } +#define luai_jmpbuf int /* dummy variable */ -#ifdef LUA_LIB +#elif !defined(__STRICT_ANSI__) && (defined(unix) || defined(__unix) || \ + defined(__unix__)) +/* 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 } +#define luai_jmpbuf jmp_buf +#else +/* default handling with long jumps */ +#define LUAI_THROW(L,c) longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf -/* environment variables that hold the search path for packages */ -#define LUA_PATH "LUA_PATH" -#define LUA_CPATH "LUA_CPATH" +#endif -/* prefix for open functions in C libraries */ -#define LUA_POF "luaopen_" -/* separator for open functions in C libraries */ -#define LUA_OFSEP "_" +/* +@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern +@* can do during pattern-matching. +** CHANGE it if you need more captures. This limit is arbitrary. +*/ +#define LUA_MAXCAPTURES 32 -/* directory separator (for submodules) */ -#if defined(_WIN32) -#define LUA_DIRSEP "\\" + +/* +@@ lua_tmpnam is the function that the OS library uses to create a +@* temporary name. +@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam. +** CHANGE them if you have an alternative to tmpnam (which is considered +** insecure) or if you want the original tmpnam anyway. By default, Lua +** uses tmpnam except when POSIX is available, where it uses mkstemp. +*/ +#if defined(loslib_c) || defined(luaall_c) + +#if !defined(__STRICT_ANSI__) && defined(_POSIX_C_SOURCE) +#include <unistd.h> +#define LUA_TMPNAMBUFSIZE 32 +#define lua_tmpnam(b,e) { \ + strcpy(b, "/tmp/lua_XXXXXX"); \ + e = mkstemp(b); \ + if (e != -1) close(e); \ + e = (e == -1); } #else -#define LUA_DIRSEP "/" +#define LUA_TMPNAMBUFSIZE L_tmpnam +#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } #endif -/* separator of templates in a path */ -#define LUA_PATHSEP ';' +#endif -/* wild char in each template */ -#define LUA_PATH_MARK "?" +/* +@@ LUA_DL_* define which dynamic-library system Lua should use. +** CHANGE here if Lua has problems choosing the appropriate +** dynamic-library system for your platform (either Windows' DLL, Mac's +** dyld, or Unix's dlopen). If your system is some kind of Unix, there +** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for +** it. To use dlopen you also need to adapt the src/Makefile (probably +** adding -ldl to the linker options), so Lua does not select it +** automatically. (When you change the makefile to add -ldl, you must +** also add -DLUA_USE_DLOPEN.) +** 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(_WIN32) +#define LUA_DL_DLL +#elif defined(__APPLE__) && defined(__MACH__) +#define LUA_DL_DYLD +#elif defined(LUA_USE_DLOPEN) +#define LUA_DL_DLOPEN +#endif +#endif -/* maximum number of captures in pattern-matching (arbitrary limit) */ -#define MAX_CAPTURES 32 +/* +@@ 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) /* -** by default, gcc does not get `os.tmpname', because it generates a warning -** when using `tmpname'. Change that if you really want (or do not want) -** `os.tmpname' available. +@@ 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.) */ -#ifdef __GNUC__ -#define USE_TMPNAME 0 -#else -#define USE_TMPNAME 1 -#endif +#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} /* -** Configuration for loadlib: Lua tries to guess the dynamic-library -** system that your platform uses (either Windows' DLL, Mac's dyld, or -** dlopen). If your system is some kind of Unix, there is a good chance -** that USE_DLOPEN will work for it. You may need to adapt also the -** makefile. +@@ 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 +** a multiple of the maximum alignment required for your machine. */ -#if defined(_WIN32) -#define USE_DLL -#elif defined(__APPLE__) && defined(__MACH__) -#define USE_DYLD -#elif defined(__linux) || defined(sun) || defined(sgi) || defined(BSD) -#define USE_DLOPEN -#endif +#define LUAI_EXTRASPACE 0 -#endif +/* +@@ 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. +*/ +#define luai_userstateopen(L) ((void)0) + -/* }====================================================== */ +/* =================================================================== */ +/* +** Local configuration. You can use this space to add your redefinitions +** without modifying the main part of the file. +*/ -/* Local configuration */ #endif diff --git a/src/lualib.h b/src/lualib.h index a5dde236..e1face32 100644 --- a/src/lualib.h +++ b/src/lualib.h @@ -1,5 +1,5 @@ /* -** $Id: lualib.h,v 1.33 2005/01/10 16:31:30 roberto Exp $ +** $Id: lualib.h,v 1.34 2005/04/13 17:24:20 roberto Exp $ ** Lua standard libraries ** See Copyright Notice in lua.h */ @@ -36,12 +36,12 @@ LUALIB_API int (luaopen_math) (lua_State *L); #define LUA_DBLIBNAME "debug" LUALIB_API int (luaopen_debug) (lua_State *L); - +#define LUA_LOADLIBNAME "package" LUALIB_API int (luaopen_loadlib) (lua_State *L); /* open all previous libraries */ -LUALIB_API int (luaopen_stdlibs) (lua_State *L); +LUALIB_API void (luaL_openlibs) (lua_State *L); #endif diff --git a/src/lundump.c b/src/lundump.c index e13a4e48..8ceb571b 100644 --- a/src/lundump.c +++ b/src/lundump.c @@ -1,5 +1,5 @@ /* -** $Id: lundump.c,v 1.54 2004/11/25 09:31:41 lhf Exp $ +** $Id: lundump.c,v 1.55 2005/05/12 00:26:50 lhf Exp $ ** load pre-compiled Lua chunks ** See Copyright Notice in lua.h */ @@ -206,7 +206,8 @@ static Proto* LoadFunction (LoadState* S, TString* p) Proto* f=luaF_newproto(S->L); setptvalue2s(S->L,S->L->top,f); incr_top(S->L); f->source=LoadString(S); if (f->source==NULL) f->source=p; - f->lineDefined=LoadInt(S); + f->linedefined=LoadInt(S); + f->lastlinedefined=LoadInt(S); f->nups=LoadByte(S); f->numparams=LoadByte(S); f->is_vararg=LoadByte(S); diff --git a/src/lundump.h b/src/lundump.h index 1a7b897b..924cfb01 100644 --- a/src/lundump.h +++ b/src/lundump.h @@ -1,5 +1,5 @@ /* -** $Id: lundump.h,v 1.34 2004/11/25 09:31:41 lhf Exp $ +** $Id: lundump.h,v 1.35 2005/05/12 00:26:50 lhf Exp $ ** load pre-compiled Lua chunks ** See Copyright Notice in lua.h */ @@ -11,16 +11,16 @@ #include "lzio.h" /* load one chunk; from lundump.c */ -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 */ -int luaU_endianness (void); +LUAI_FUNC int luaU_endianness (void); /* dump one chunk; from ldump.c */ -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_Chunkwriter w, void* data, int strip); /* print one chunk; from print.c */ -void luaU_print (const Proto* f, int full); +LUAI_FUNC void luaU_print (const Proto* f, int full); /* for header of binary files -- this is Lua 5.1 */ #define VERSION 0x51 @@ -1,10 +1,12 @@ /* -** $Id: lvm.c,v 2.26 2005/02/23 17:30:22 roberto Exp $ +** $Id: lvm.c,v 2.44 2005/05/17 19:49:15 roberto Exp $ ** Lua virtual machine ** See Copyright Notice in lua.h */ +#include <math.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> @@ -47,8 +49,9 @@ int luaV_tostring (lua_State *L, StkId obj) { if (!ttisnumber(obj)) return 0; else { - char s[MAX_NUMBER2STR]; - lua_number2str(s, nvalue(obj)); + char s[LUAI_MAXNUMBER2STR]; + lua_Number n = nvalue(obj); + lua_number2str(s, n); setsvalue2s(L, obj, luaS_new(L, s)); return 1; } @@ -57,9 +60,8 @@ int luaV_tostring (lua_State *L, StkId obj) { static void traceexec (lua_State *L, const Instruction *pc) { lu_byte mask = L->hookmask; - CallInfo *ci = L->ci; - const Instruction *oldpc = ci->savedpc; - ci->savedpc = pc; + const Instruction *oldpc = L->savedpc; + L->savedpc = pc; if (mask > LUA_MASKLINE) { /* instruction-hook set? */ if (L->hookcount == 0) { resethookcount(L); @@ -68,7 +70,7 @@ static void traceexec (lua_State *L, const Instruction *pc) { } } if (mask & LUA_MASKLINE) { - Proto *p = ci_func(ci)->l.p; + Proto *p = ci_func(L->ci)->l.p; int npc = pcRel(pc, p); int newline = getline(p, npc); /* call linehook when enter a new function, when jump back (loop), @@ -79,16 +81,12 @@ static void traceexec (lua_State *L, const Instruction *pc) { } -static void prepTMcall (lua_State *L, const TValue *f, +static void callTMres (lua_State *L, StkId res, const TValue *f, const TValue *p1, const TValue *p2) { + ptrdiff_t result = savestack(L, res); setobj2s(L, L->top, f); /* push function */ setobj2s(L, L->top+1, p1); /* 1st argument */ setobj2s(L, L->top+2, p2); /* 2nd argument */ -} - - -static void callTMres (lua_State *L, StkId res) { - ptrdiff_t result = savestack(L, res); luaD_checkstack(L, 3); L->top += 3; luaD_call(L, L->top - 3, 1); @@ -99,15 +97,18 @@ static void callTMres (lua_State *L, StkId res) { -static void callTM (lua_State *L) { +static void callTM (lua_State *L, const TValue *f, const TValue *p1, const TValue *p2, const TValue *p3) { + setobj2s(L, L->top, f); /* push function */ + setobj2s(L, L->top+1, p1); /* 1st argument */ + setobj2s(L, L->top+2, p2); /* 2nd argument */ + setobj2s(L, L->top+3, p3); /* 3th argument */ luaD_checkstack(L, 4); L->top += 4; luaD_call(L, L->top - 4, 0); } -StkId luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val, - const Instruction *pc) { +void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { int loop; for (loop = 0; loop < MAXTAGLOOP; loop++) { const TValue *tm; @@ -117,30 +118,23 @@ StkId luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val, if (!ttisnil(res) || /* result is no nil? */ (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ setobj2s(L, val, res); - return L->base; + return; } /* else will try the tag method */ } - else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) { - L->ci->savedpc = pc; + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) luaG_typeerror(L, t, "index"); - } if (ttisfunction(tm)) { - L->ci->savedpc = pc; - prepTMcall(L, tm, t, key); - callTMres(L, val); - return L->base; + callTMres(L, val, tm, t, key); + return; } t = tm; /* else repeat with `tm' */ } - L->ci->savedpc = pc; luaG_runerror(L, "loop in gettable"); - return NULL; /* to avoid warnings */ } -StkId luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val, - const Instruction *pc) { +void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { int loop; for (loop = 0; loop < MAXTAGLOOP; loop++) { const TValue *tm; @@ -151,26 +145,19 @@ StkId luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val, (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ setobj2t(L, oldval, val); luaC_barriert(L, h, val); - return L->base; + return; } /* else will try the tag method */ } - else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) { - L->ci->savedpc = pc; + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) luaG_typeerror(L, t, "index"); - } if (ttisfunction(tm)) { - L->ci->savedpc = pc; - prepTMcall(L, tm, t, key); - setobj2s(L, L->top+3, val); /* 3th argument */ - callTM(L); - return L->base; + callTM(L, tm, t, key, val); + return; } t = tm; /* else repeat with `tm' */ } - L->ci->savedpc = pc; luaG_runerror(L, "loop in settable"); - return NULL; /* to avoid warnings */ } @@ -180,8 +167,7 @@ static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, if (ttisnil(tm)) tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ if (!ttisfunction(tm)) return 0; - prepTMcall(L, tm, p1, p2); - callTMres(L, res); + callTMres(L, res, tm, p1, p2); return 1; } @@ -208,8 +194,7 @@ static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, tm2 = luaT_gettmbyobj(L, p2, event); if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */ return -1; - prepTMcall(L, tm1, p1, p2); - callTMres(L, L->top); + callTMres(L, L->top, tm1, p1, p2); return !l_isfalse(L->top); } @@ -241,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 num_lt(nvalue(l), nvalue(r)); + return luai_numlt(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) @@ -255,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 num_le(nvalue(l), nvalue(r)); + return luai_numle(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' */ @@ -271,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 num_eq(nvalue(t1), nvalue(t2)); + case LUA_TNUMBER: return luai_numeq(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: { @@ -288,8 +273,7 @@ int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { default: return gcvalue(t1) == gcvalue(t2); } if (tm == NULL) return 0; /* no TM? */ - prepTMcall(L, tm, t1, t2); - callTMres(L, L->top); /* call TM */ + callTMres(L, L->top, tm, t1, t2); /* call TM */ return !l_isfalse(L->top); } @@ -328,18 +312,19 @@ 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, const Instruction *pc) { + const TValue *rc, TMS op) { TValue tempb, tempc; const TValue *b, *c; - L->ci->savedpc = pc; 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, num_add(nvalue(b), nvalue(c))); break; - case TM_SUB: setnvalue(ra, num_sub(nvalue(b), nvalue(c))); break; - case TM_MUL: setnvalue(ra, num_mul(nvalue(b), nvalue(c))); break; - case TM_DIV: setnvalue(ra, num_div(nvalue(b), nvalue(c))); break; - case TM_POW: setnvalue(ra, num_pow(nvalue(b), nvalue(c))); break; + 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; default: lua_assert(0); break; } } @@ -354,7 +339,7 @@ static StkId Arith (lua_State *L, StkId ra, const TValue *rb, ** some macros for common tasks in `luaV_execute' */ -#define runtime_check(L, c) { if (!(c)) return 0; } +#define runtime_check(L, c) { if (!(c)) break; } #define RA(i) (base+GETARG_A(i)) /* to be used after possible stack reallocation */ @@ -367,19 +352,22 @@ static StkId Arith (lua_State *L, StkId ra, const TValue *rb, #define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) -#define dojump(L,pc,i) {(pc) += (i); lua_threadyield(L);} +#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);} + + +#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; } StkId luaV_execute (lua_State *L, int nexeccalls) { LClosure *cl; - TValue *k; 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 */ - pc = L->ci->savedpc; + pc = L->savedpc; cl = &clvalue(L->ci->func)->l; base = L->base; k = cl->p->k; @@ -389,16 +377,16 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { StkId ra; if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { - traceexec(L, pc); /***/ + traceexec(L, pc); if (L->status == LUA_YIELD) { /* did hook yield? */ - L->ci->savedpc = pc - 1; + L->savedpc = pc - 1; return NULL; } base = L->base; } /* warning!! several calls may realloc the stack and invalidate `ra' */ ra = RA(i); - lua_assert(base == L->ci->base && base == L->base); + lua_assert(base == L->base && L->base == L->ci->base); lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); lua_assert(L->top == L->ci->top || luaG_checkopenop(i)); switch (GET_OPCODE(i)) { @@ -432,18 +420,18 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { TValue *rb = KBx(i); sethvalue(L, &g, cl->env); lua_assert(ttisstring(rb)); - base = luaV_gettable(L, &g, rb, ra, pc); /***/ + Protect(luaV_gettable(L, &g, rb, ra)); continue; } case OP_GETTABLE: { - base = luaV_gettable(L, RB(i), RKC(i), ra, pc); /***/ + Protect(luaV_gettable(L, RB(i), RKC(i), ra)); continue; } case OP_SETGLOBAL: { TValue g; sethvalue(L, &g, cl->env); lua_assert(ttisstring(KBx(i))); - base = luaV_settable(L, &g, KBx(i), ra, pc); /***/ + Protect(luaV_settable(L, &g, KBx(i), ra)); continue; } case OP_SETUPVAL: { @@ -453,86 +441,101 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { continue; } case OP_SETTABLE: { - base = luaV_settable(L, ra, RKB(i), RKC(i), pc); /***/ + Protect(luaV_settable(L, ra, RKB(i), RKC(i))); continue; } case OP_NEWTABLE: { int b = GETARG_B(i); int c = GETARG_C(i); sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c))); - L->ci->savedpc = pc; - luaC_checkGC(L); /***/ - base = L->base; + Protect(luaC_checkGC(L)); continue; } case OP_SELF: { StkId rb = RB(i); setobjs2s(L, ra+1, rb); - base = luaV_gettable(L, rb, RKC(i), ra, pc); /***/ + Protect(luaV_gettable(L, rb, RKC(i), ra)); continue; } case OP_ADD: { TValue *rb = RKB(i); TValue *rc = RKC(i); if (ttisnumber(rb) && ttisnumber(rc)) { - setnvalue(ra, num_add(nvalue(rb), nvalue(rc))); + lua_Number nb = nvalue(rb), nc = nvalue(rc); + setnvalue(ra, luai_numadd(nb, nc)); } else - base = Arith(L, ra, rb, rc, TM_ADD, pc); /***/ + Protect(Arith(L, ra, rb, rc, TM_ADD)); continue; } case OP_SUB: { TValue *rb = RKB(i); TValue *rc = RKC(i); if (ttisnumber(rb) && ttisnumber(rc)) { - setnvalue(ra, num_sub(nvalue(rb), nvalue(rc))); + lua_Number nb = nvalue(rb), nc = nvalue(rc); + setnvalue(ra, luai_numsub(nb, nc)); } else - base = Arith(L, ra, rb, rc, TM_SUB, pc); /***/ + Protect(Arith(L, ra, rb, rc, TM_SUB)); continue; } case OP_MUL: { TValue *rb = RKB(i); TValue *rc = RKC(i); if (ttisnumber(rb) && ttisnumber(rc)) { - setnvalue(ra, num_mul(nvalue(rb), nvalue(rc))); + lua_Number nb = nvalue(rb), nc = nvalue(rc); + setnvalue(ra, luai_nummul(nb, nc)); } else - base = Arith(L, ra, rb, rc, TM_MUL, pc); /***/ + Protect(Arith(L, ra, rb, rc, TM_MUL)); continue; } case OP_DIV: { TValue *rb = RKB(i); TValue *rc = RKC(i); if (ttisnumber(rb) && ttisnumber(rc)) { - setnvalue(ra, num_div(nvalue(rb), nvalue(rc))); + lua_Number nb = nvalue(rb), nc = nvalue(rc); + setnvalue(ra, luai_numdiv(nb, nc)); + } + else + Protect(Arith(L, ra, rb, rc, TM_DIV)); + continue; + } + case OP_MOD: { + TValue *rb = RKB(i); + TValue *rc = RKC(i); + if (ttisnumber(rb) && ttisnumber(rc)) { + lua_Number nb = nvalue(rb), nc = nvalue(rc); + setnvalue(ra, luai_nummod(nb, nc)); } else - base = Arith(L, ra, rb, rc, TM_DIV, pc); /***/ + Protect(Arith(L, ra, rb, rc, TM_MOD)); continue; } case OP_POW: { TValue *rb = RKB(i); TValue *rc = RKC(i); if (ttisnumber(rb) && ttisnumber(rc)) { - setnvalue(ra, num_pow(nvalue(rb), nvalue(rc))); + lua_Number nb = nvalue(rb), nc = nvalue(rc); + setnvalue(ra, luai_numpow(nb, nc)); } else - base = Arith(L, ra, rb, rc, TM_POW, pc); /***/ + Protect(Arith(L, ra, rb, rc, TM_POW)); continue; } case OP_UNM: { const TValue *rb = RB(i); TValue temp; if (tonumber(rb, &temp)) { - setnvalue(ra, num_unm(nvalue(rb))); + lua_Number nb = nvalue(rb); + setnvalue(ra, luai_numunm(nb)); } else { - setnilvalue(&temp); - L->ci->savedpc = pc; - if (!call_binTM(L, RB(i), &temp, ra, TM_UNM)) /***/ - luaG_aritherror(L, RB(i), &temp); - base = L->base; + rb = RB(i); /* `tonumber' erased `rb' */ + Protect( + if (!call_binTM(L, rb, &luaO_nilobject, ra, TM_UNM)) + luaG_aritherror(L, rb, &luaO_nilobject); + ) } continue; } @@ -541,13 +544,23 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { setbvalue(ra, res); continue; } + case OP_SIZ: { + 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"); + ) + } + continue; + } case OP_CONCAT: { int b = GETARG_B(i); int c = GETARG_C(i); - L->ci->savedpc = pc; - luaV_concat(L, c-b+1, c); /* may change `base' (and `ra') */ /***/ - luaC_checkGC(L); /***/ - base = L->base; + Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L)); setobjs2s(L, RA(i), base+b); continue; } @@ -556,24 +569,27 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { continue; } case OP_EQ: { - L->ci->savedpc = pc; - if (equalobj(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; /***/ - else dojump(L, pc, GETARG_sBx(*pc) + 1); - base = L->base; + Protect( + if (equalobj(L, RKB(i), RKC(i)) == GETARG_A(i)) + dojump(L, pc, GETARG_sBx(*pc)); + ) + pc++; continue; } case OP_LT: { - L->ci->savedpc = pc; - if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; /***/ - else dojump(L, pc, GETARG_sBx(*pc) + 1); - base = L->base; + Protect( + if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) + dojump(L, pc, GETARG_sBx(*pc)); + ) + pc++; continue; } case OP_LE: { - L->ci->savedpc = pc; - if (lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; /***/ - else dojump(L, pc, GETARG_sBx(*pc) + 1); - base = L->base; + Protect( + if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) + dojump(L, pc, GETARG_sBx(*pc)); + ) + pc++; continue; } case OP_TEST: { @@ -585,75 +601,71 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { } continue; } - case OP_CALL: { /***/ - int pcr; + case OP_CALL: { int b = GETARG_B(i); int nresults = GETARG_C(i) - 1; if (b != 0) L->top = ra+b; /* else previous instruction set top */ - L->ci->savedpc = pc; - pcr = luaD_precall(L, ra, nresults); - if (pcr == PCRLUA) { - nexeccalls++; - goto callentry; /* restart luaV_execute over new Lua function */ - } - else if (pcr == PCRC) { - /* it was a C function (`precall' called it); adjust results */ - if (nresults >= 0) L->top = L->ci->top; - base = L->base; - continue; - } - else { - lua_assert(pcr == PCRYIELD); - return NULL; + L->savedpc = pc; + switch (luaD_precall(L, ra, nresults)) { + case PCRLUA: { + nexeccalls++; + goto callentry; /* restart luaV_execute over new Lua function */ + } + case PCRC: { + /* it was a C function (`precall' called it); adjust results */ + if (nresults >= 0) L->top = L->ci->top; + base = L->base; + continue; + } + default: { + return NULL; + } } } - case OP_TAILCALL: { /***/ - int pcr; + case OP_TAILCALL: { int b = GETARG_B(i); if (b != 0) L->top = ra+b; /* else previous instruction set top */ - L->ci->savedpc = pc; + L->savedpc = pc; lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); - pcr = luaD_precall(L, ra, LUA_MULTRET); - if (pcr == PCRLUA) { - /* tail call: put new frame in place of previous one */ - CallInfo *ci = L->ci - 1; /* previous frame */ - int aux; - StkId func = ci->func; - StkId pfunc = (ci+1)->func; /* previous function index */ - if (L->openupval) luaF_close(L, base); - base = ci->base = ci->func + ((ci+1)->base - pfunc); - L->base = base; - for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */ - setobjs2s(L, func+aux, pfunc+aux); - ci->top = L->top = func+aux; /* correct top */ - lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); - ci->savedpc = L->ci->savedpc; - ci->tailcalls++; /* one more call lost */ - L->ci--; /* remove new frame */ - goto callentry; - } - else if (pcr == PCRC) { - /* it was a C function (`precall' called it) */ - base = L->base; - continue; - } - else { - lua_assert(pcr == PCRYIELD); - return NULL; + switch (luaD_precall(L, ra, LUA_MULTRET)) { + case PCRLUA: { + /* tail call: put new frame in place of previous one */ + CallInfo *ci = L->ci - 1; /* previous frame */ + int aux; + StkId func = ci->func; + StkId pfunc = (ci+1)->func; /* previous function index */ + if (L->openupval) luaF_close(L, ci->base); + L->base = ci->base = ci->func + ((ci+1)->base - pfunc); + for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */ + setobjs2s(L, func+aux, pfunc+aux); + ci->top = L->top = func+aux; /* correct top */ + lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); + ci->savedpc = L->savedpc; + ci->tailcalls++; /* one more call lost */ + L->ci--; /* remove new frame */ + goto callentry; + } + case PCRC: { + /* it was a C function (`precall' called it) */ + base = L->base; + continue; + } + default: { + return NULL; + } } } case OP_RETURN: { - CallInfo *ci = L->ci - 1; /* previous function frame */ int b = GETARG_B(i); if (b != 0) L->top = ra+b-1; if (L->openupval) luaF_close(L, base); - L->ci->savedpc = pc; + L->savedpc = pc; if (--nexeccalls == 0) /* was previous function running `here'? */ return ra; /* no: return */ else { /* yes: continue its execution */ - int nresults = (ci+1)->nresults; - lua_assert(isLua(ci)); - lua_assert(GET_OPCODE(*(ci->savedpc - 1)) == OP_CALL); + 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; @@ -661,27 +673,27 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { } case OP_FORLOOP: { lua_Number step = nvalue(ra+2); - lua_Number idx = num_add(nvalue(ra), step); /* increment index */ + lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */ lua_Number limit = nvalue(ra+1); - if (step > 0 ? num_le(idx, limit) : num_le(limit, idx)) { + if (step > 0 ? luai_numle(idx, limit) : luai_numle(limit, idx)) { dojump(L, pc, GETARG_sBx(i)); /* jump back */ setnvalue(ra, idx); /* update internal index... */ setnvalue(ra+3, idx); /* ...and external index */ } continue; } - case OP_FORPREP: { /***/ + case OP_FORPREP: { const TValue *init = ra; const TValue *plimit = ra+1; const TValue *pstep = ra+2; - L->ci->savedpc = pc; + L->savedpc = pc; /* next steps may throw errors */ if (!tonumber(init, ra)) - luaG_runerror(L, "`for' initial value must be a number"); + luaG_runerror(L, LUA_QL("for") " initial value must be a number"); else if (!tonumber(plimit, ra+1)) - luaG_runerror(L, "`for' limit must be a number"); + luaG_runerror(L, LUA_QL("for") " limit must be a number"); else if (!tonumber(pstep, ra+2)) - luaG_runerror(L, "`for' step must be a number"); - setnvalue(ra, num_sub(nvalue(ra), nvalue(pstep))); + luaG_runerror(L, LUA_QL("for") " step must be a number"); + setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep))); dojump(L, pc, GETARG_sBx(i)); continue; } @@ -691,10 +703,8 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { setobjs2s(L, cb+1, ra+1); setobjs2s(L, cb, ra); L->top = cb+3; /* func. + 2 args (state and index) */ - L->ci->savedpc = pc; - luaD_call(L, cb, GETARG_C(i)); /***/ + Protect(luaD_call(L, cb, GETARG_C(i))); L->top = L->ci->top; - base = L->base; cb = RA(i) + 3; /* previous call may change the stack */ if (ttisnil(cb)) /* break loop? */ pc++; /* skip jump (break loop) */ @@ -704,27 +714,19 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { } continue; } - case OP_TFORPREP: { /* for compatibility only */ - if (ttistable(ra)) { - setobjs2s(L, ra+1, ra); - setobj2s(L, ra, luaH_getstr(hvalue(gt(L)), luaS_new(L, "next"))); - } - dojump(L, pc, GETARG_sBx(i)); - continue; - } case OP_SETLIST: { int n = GETARG_B(i); int c = GETARG_C(i); int last; Table *h; - runtime_check(L, ttistable(ra)); - h = hvalue(ra); if (n == 0) { n = L->top - ra - 1; L->top = L->ci->top; } if (c == 0) c = cast(int, *pc++); - last = ((c-1)*LFIELDS_PER_FLUSH) + n + LUA_FIRSTINDEX - 1; + runtime_check(L, ttistable(ra)); + h = hvalue(ra); + last = ((c-1)*LFIELDS_PER_FLUSH) + n; if (last > h->sizearray) /* needs more space? */ luaH_resizearray(L, h, last); /* pre-alloc it at once */ for (; n > 0; n--) { @@ -755,9 +757,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { } } setclvalue(L, ra, ncl); - L->ci->savedpc = pc; - luaC_checkGC(L); /***/ - base = L->base; + Protect(luaC_checkGC(L)); continue; } case OP_VARARG: { @@ -1,5 +1,5 @@ /* -** $Id: lvm.h,v 2.2 2004/05/14 19:25:09 roberto Exp $ +** $Id: lvm.h,v 2.4 2005/04/25 19:24:10 roberto Exp $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -22,15 +22,15 @@ (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) -int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); -int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2); -const TValue *luaV_tonumber (const TValue *obj, TValue *n); -int luaV_tostring (lua_State *L, StkId obj); -StkId luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val, - const Instruction *pc); -StkId luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val, - const Instruction *pc); -StkId luaV_execute (lua_State *L, int nexeccalls); -void luaV_concat (lua_State *L, int total, int last); +LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); +LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2); +LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n); +LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); +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_concat (lua_State *L, int total, int last); #endif @@ -1,5 +1,5 @@ /* -** $Id: lzio.c,v 1.29 2004/04/30 20:13:38 roberto Exp $ +** $Id: lzio.c,v 1.30 2005/05/17 19:49:15 roberto Exp $ ** a generic input stream interface ** See Copyright Notice in lua.h */ @@ -43,7 +43,7 @@ int luaZ_lookahead (ZIO *z) { } -void luaZ_init (lua_State *L, ZIO *z, lua_Chunkreader reader, void *data) { +void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { z->L = L; z->reader = reader; z->data = data; @@ -1,5 +1,5 @@ /* -** $Id: lzio.h,v 1.19 2003/10/03 16:05:34 roberto Exp $ +** $Id: lzio.h,v 1.21 2005/05/17 19:49:15 roberto Exp $ ** Buffered streams ** See Copyright Notice in lua.h */ @@ -17,26 +17,16 @@ typedef struct Zio ZIO; - #define char2int(c) cast(int, cast(unsigned char, (c))) #define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z)) -void luaZ_init (lua_State *L, ZIO *z, lua_Chunkreader reader, void *data); -size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ -int luaZ_lookahead (ZIO *z); - - - typedef struct Mbuffer { char *buffer; size_t n; size_t buffsize; } Mbuffer; - -char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); - #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) #define luaZ_buffer(buff) ((buff)->buffer) @@ -53,18 +43,25 @@ char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) +LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); +LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, + void *data); +LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ +LUAI_FUNC int luaZ_lookahead (ZIO *z); + + /* --------- Private Part ------------------ */ struct Zio { size_t n; /* bytes still unread */ const char *p; /* current position in buffer */ - lua_Chunkreader reader; + lua_Reader reader; void* data; /* additional data */ lua_State *L; /* Lua state (for reader) */ }; -int luaZ_fill (ZIO *z); +LUAI_FUNC int luaZ_fill (ZIO *z); #endif diff --git a/src/print.c b/src/print.c index f273ebfc..85308705 100644 --- a/src/print.c +++ b/src/print.c @@ -1,5 +1,5 @@ /* -** $Id: print.c,v 1.49 2004/11/25 09:31:41 lhf Exp $ +** $Id: print.c,v 1.50 2005/05/12 00:26:50 lhf Exp $ ** print bytecodes ** See Copyright Notice in lua.h */ @@ -76,9 +76,6 @@ static void PrintCode(const Proto* f) int bx=GETARG_Bx(i); int sbx=GETARG_sBx(i); int line=getline(f,pc); -#if 0 - printf("%0*lX",Sizeof(i)*2,i); -#endif printf("\t%d\t",pc+1); if (line>0) printf("[%d]\t",line); else printf("[-]\t"); printf("%-9s\t",luaP_opnames[o]); @@ -133,7 +130,6 @@ static void PrintCode(const Proto* f) case OP_JMP: case OP_FORLOOP: case OP_FORPREP: - case OP_TFORPREP: printf("\t; to %d",sbx+pc+2); break; case OP_CLOSURE: @@ -146,28 +142,25 @@ static void PrintCode(const Proto* f) } } -static const char* Source(const Proto* f) -{ - const char* s=getstr(f->source); - if (*s=='@' || *s=='=') - return s+1; - else if (*s==LUA_SIGNATURE[0]) - return "(bstring)"; - else - return "(string)"; -} - #define SS(x) (x==1)?"":"s" #define S(x) x,SS(x) static void PrintHeader(const Proto* f) { - printf("\n%s <%s:%d> (%d instruction%s, %d bytes at %p)\n", - (f->lineDefined==0)?"main":"function",Source(f),f->lineDefined, + const char* s=getstr(f->source); + if (*s=='@' || *s=='=') + s++; + else if (*s==LUA_SIGNATURE[0]) + s="(bstring)"; + else + s="(string)"; + printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n", + (f->linedefined==0)?"main":"function",s, + f->linedefined,f->lastlinedefined, S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f)); printf("%d%s param%s, %d stack%s, %d upvalue%s, ", - f->numparams,f->is_vararg?"+":"",SS(f->numparams),S(f->maxstacksize), - S(f->nups)); + f->numparams,f->is_vararg?"+":"",SS(f->numparams), + S(f->maxstacksize),S(f->nups)); printf("%d local%s, %d constant%s, %d function%s\n", S(f->sizelocvars),S(f->sizek),S(f->sizep)); } |