diff options
-rw-r--r-- | INSTALL | 2 | ||||
-rw-r--r-- | MANIFEST | 227 | ||||
-rw-r--r-- | Makefile | 27 | ||||
-rw-r--r-- | README | 5 | ||||
-rw-r--r-- | config | 6 | ||||
-rw-r--r-- | etc/all.c | 1 | ||||
-rw-r--r-- | etc/lua.hpp | 8 | ||||
-rw-r--r-- | etc/min.c | 1 | ||||
-rw-r--r-- | include/lauxlib.h | 22 | ||||
-rw-r--r-- | include/lua.h | 46 | ||||
-rw-r--r-- | include/luaconf.h | 110 | ||||
-rw-r--r-- | src/lapi.c | 94 | ||||
-rw-r--r-- | src/lcode.c | 77 | ||||
-rw-r--r-- | src/lcode.h | 3 | ||||
-rw-r--r-- | src/ldebug.c | 23 | ||||
-rw-r--r-- | src/ldo.c | 12 | ||||
-rw-r--r-- | src/ldump.c | 9 | ||||
-rw-r--r-- | src/lfunc.c | 8 | ||||
-rw-r--r-- | src/lgc.c | 50 | ||||
-rw-r--r-- | src/lib/lauxlib.c | 78 | ||||
-rw-r--r-- | src/lib/lbaselib.c | 76 | ||||
-rw-r--r-- | src/lib/ldblib.c | 9 | ||||
-rw-r--r-- | src/lib/loadlib.c | 397 | ||||
-rw-r--r-- | src/lib/loslib.c | 8 | ||||
-rw-r--r-- | src/lib/lstrlib.c | 50 | ||||
-rw-r--r-- | src/llex.c | 76 | ||||
-rw-r--r-- | src/llex.h | 10 | ||||
-rw-r--r-- | src/llimits.h | 23 | ||||
-rw-r--r-- | src/lmem.c | 25 | ||||
-rw-r--r-- | src/lmem.h | 38 | ||||
-rw-r--r-- | src/lobject.c | 23 | ||||
-rw-r--r-- | src/lobject.h | 22 | ||||
-rw-r--r-- | src/lopcodes.c | 11 | ||||
-rw-r--r-- | src/lopcodes.h | 18 | ||||
-rw-r--r-- | src/lparser.c | 35 | ||||
-rw-r--r-- | src/lstate.c | 10 | ||||
-rw-r--r-- | src/lstate.h | 4 | ||||
-rw-r--r-- | src/lstring.c | 13 | ||||
-rw-r--r-- | src/lstring.h | 7 | ||||
-rw-r--r-- | src/ltable.c | 85 | ||||
-rw-r--r-- | src/ltable.h | 5 | ||||
-rw-r--r-- | src/lua/lua.c | 8 | ||||
-rw-r--r-- | src/luac/print.c | 13 | ||||
-rw-r--r-- | src/lundump.c | 21 | ||||
-rw-r--r-- | src/lundump.h | 12 | ||||
-rw-r--r-- | src/lvm.c | 37 |
46 files changed, 1107 insertions, 738 deletions
@@ -32,7 +32,7 @@ This is Lua 5.1 (work). * If you have problems (and solutions!) ------------------------------------- - If "make" fails, please let us know (lua@tecgraf.puc-rio.br). + If "make" fails, please let us know. If you make changes to "config" or to the Makefiles, please send them to us. * Shared libraries @@ -1,114 +1,115 @@ -MANIFEST contents of Lua 5.1 (work2) distribution on Mon Sep 20 21:28:06 BRT 2004 -lua-5.1-work2 -lua-5.1-work2/COPYRIGHT -lua-5.1-work2/HISTORY -lua-5.1-work2/INSTALL -lua-5.1-work2/MANIFEST -lua-5.1-work2/Makefile -lua-5.1-work2/README -lua-5.1-work2/bin -lua-5.1-work2/build -lua-5.1-work2/config -lua-5.1-work2/etc -lua-5.1-work2/etc/Makefile -lua-5.1-work2/etc/README -lua-5.1-work2/etc/all.c -lua-5.1-work2/etc/lua.ico -lua-5.1-work2/etc/min.c -lua-5.1-work2/etc/noparser.c -lua-5.1-work2/etc/saconfig.c -lua-5.1-work2/include -lua-5.1-work2/include/Makefile -lua-5.1-work2/include/lauxlib.h -lua-5.1-work2/include/lua.h -lua-5.1-work2/include/luaconf.h -lua-5.1-work2/include/lualib.h -lua-5.1-work2/lib -lua-5.1-work2/src -lua-5.1-work2/src/Makefile -lua-5.1-work2/src/README -lua-5.1-work2/src/lapi.c -lua-5.1-work2/src/lapi.h -lua-5.1-work2/src/lcode.c -lua-5.1-work2/src/lcode.h -lua-5.1-work2/src/ldebug.c -lua-5.1-work2/src/ldebug.h -lua-5.1-work2/src/ldo.c -lua-5.1-work2/src/ldo.h -lua-5.1-work2/src/ldump.c -lua-5.1-work2/src/lfunc.c -lua-5.1-work2/src/lfunc.h -lua-5.1-work2/src/lgc.c -lua-5.1-work2/src/lgc.h -lua-5.1-work2/src/lib -lua-5.1-work2/src/lib/Makefile -lua-5.1-work2/src/lib/README -lua-5.1-work2/src/lib/lauxlib.c -lua-5.1-work2/src/lib/lbaselib.c -lua-5.1-work2/src/lib/ldblib.c -lua-5.1-work2/src/lib/linit.c -lua-5.1-work2/src/lib/liolib.c -lua-5.1-work2/src/lib/lmathlib.c -lua-5.1-work2/src/lib/loadlib.c -lua-5.1-work2/src/lib/loslib.c -lua-5.1-work2/src/lib/lstrlib.c -lua-5.1-work2/src/lib/ltablib.c -lua-5.1-work2/src/llex.c -lua-5.1-work2/src/llex.h -lua-5.1-work2/src/llimits.h -lua-5.1-work2/src/lmem.c -lua-5.1-work2/src/lmem.h -lua-5.1-work2/src/lobject.c -lua-5.1-work2/src/lobject.h -lua-5.1-work2/src/lopcodes.c -lua-5.1-work2/src/lopcodes.h -lua-5.1-work2/src/lparser.c -lua-5.1-work2/src/lparser.h -lua-5.1-work2/src/lstate.c -lua-5.1-work2/src/lstate.h -lua-5.1-work2/src/lstring.c -lua-5.1-work2/src/lstring.h -lua-5.1-work2/src/ltable.c -lua-5.1-work2/src/ltable.h -lua-5.1-work2/src/ltm.c -lua-5.1-work2/src/ltm.h -lua-5.1-work2/src/lua -lua-5.1-work2/src/lua/Makefile -lua-5.1-work2/src/lua/README -lua-5.1-work2/src/lua/lua.c -lua-5.1-work2/src/luac -lua-5.1-work2/src/luac/Makefile -lua-5.1-work2/src/luac/README -lua-5.1-work2/src/luac/luac.c -lua-5.1-work2/src/luac/print.c -lua-5.1-work2/src/lundump.c -lua-5.1-work2/src/lundump.h -lua-5.1-work2/src/lvm.c -lua-5.1-work2/src/lvm.h -lua-5.1-work2/src/lzio.c -lua-5.1-work2/src/lzio.h -lua-5.1-work2/test -lua-5.1-work2/test/README -lua-5.1-work2/test/bisect.lua -lua-5.1-work2/test/cf.lua -lua-5.1-work2/test/echo.lua -lua-5.1-work2/test/env.lua -lua-5.1-work2/test/factorial.lua -lua-5.1-work2/test/fib.lua -lua-5.1-work2/test/fibfor.lua -lua-5.1-work2/test/globals.lua -lua-5.1-work2/test/hello.lua -lua-5.1-work2/test/life.lua -lua-5.1-work2/test/lua -lua-5.1-work2/test/luac -lua-5.1-work2/test/luac.lua -lua-5.1-work2/test/printf.lua -lua-5.1-work2/test/readonly.lua -lua-5.1-work2/test/sieve.lua -lua-5.1-work2/test/sort.lua -lua-5.1-work2/test/table.lua -lua-5.1-work2/test/trace-calls.lua -lua-5.1-work2/test/trace-globals.lua -lua-5.1-work2/test/undefined.lua -lua-5.1-work2/test/xd.lua +MANIFEST contents of Lua 5.1 (work3) distribution on Mon Dec 6 23:00:22 BRST 2004 +lua-5.1-work3 +lua-5.1-work3/COPYRIGHT +lua-5.1-work3/HISTORY +lua-5.1-work3/INSTALL +lua-5.1-work3/MANIFEST +lua-5.1-work3/Makefile +lua-5.1-work3/README +lua-5.1-work3/bin +lua-5.1-work3/build +lua-5.1-work3/config +lua-5.1-work3/etc +lua-5.1-work3/etc/Makefile +lua-5.1-work3/etc/README +lua-5.1-work3/etc/all.c +lua-5.1-work3/etc/lua.hpp +lua-5.1-work3/etc/lua.ico +lua-5.1-work3/etc/min.c +lua-5.1-work3/etc/noparser.c +lua-5.1-work3/etc/saconfig.c +lua-5.1-work3/include +lua-5.1-work3/include/Makefile +lua-5.1-work3/include/lauxlib.h +lua-5.1-work3/include/lua.h +lua-5.1-work3/include/luaconf.h +lua-5.1-work3/include/lualib.h +lua-5.1-work3/lib +lua-5.1-work3/src +lua-5.1-work3/src/Makefile +lua-5.1-work3/src/README +lua-5.1-work3/src/lapi.c +lua-5.1-work3/src/lapi.h +lua-5.1-work3/src/lcode.c +lua-5.1-work3/src/lcode.h +lua-5.1-work3/src/ldebug.c +lua-5.1-work3/src/ldebug.h +lua-5.1-work3/src/ldo.c +lua-5.1-work3/src/ldo.h +lua-5.1-work3/src/ldump.c +lua-5.1-work3/src/lfunc.c +lua-5.1-work3/src/lfunc.h +lua-5.1-work3/src/lgc.c +lua-5.1-work3/src/lgc.h +lua-5.1-work3/src/lib +lua-5.1-work3/src/lib/Makefile +lua-5.1-work3/src/lib/README +lua-5.1-work3/src/lib/lauxlib.c +lua-5.1-work3/src/lib/lbaselib.c +lua-5.1-work3/src/lib/ldblib.c +lua-5.1-work3/src/lib/linit.c +lua-5.1-work3/src/lib/liolib.c +lua-5.1-work3/src/lib/lmathlib.c +lua-5.1-work3/src/lib/loadlib.c +lua-5.1-work3/src/lib/loslib.c +lua-5.1-work3/src/lib/lstrlib.c +lua-5.1-work3/src/lib/ltablib.c +lua-5.1-work3/src/llex.c +lua-5.1-work3/src/llex.h +lua-5.1-work3/src/llimits.h +lua-5.1-work3/src/lmem.c +lua-5.1-work3/src/lmem.h +lua-5.1-work3/src/lobject.c +lua-5.1-work3/src/lobject.h +lua-5.1-work3/src/lopcodes.c +lua-5.1-work3/src/lopcodes.h +lua-5.1-work3/src/lparser.c +lua-5.1-work3/src/lparser.h +lua-5.1-work3/src/lstate.c +lua-5.1-work3/src/lstate.h +lua-5.1-work3/src/lstring.c +lua-5.1-work3/src/lstring.h +lua-5.1-work3/src/ltable.c +lua-5.1-work3/src/ltable.h +lua-5.1-work3/src/ltm.c +lua-5.1-work3/src/ltm.h +lua-5.1-work3/src/lua +lua-5.1-work3/src/lua/Makefile +lua-5.1-work3/src/lua/README +lua-5.1-work3/src/lua/lua.c +lua-5.1-work3/src/luac +lua-5.1-work3/src/luac/Makefile +lua-5.1-work3/src/luac/README +lua-5.1-work3/src/luac/luac.c +lua-5.1-work3/src/luac/print.c +lua-5.1-work3/src/lundump.c +lua-5.1-work3/src/lundump.h +lua-5.1-work3/src/lvm.c +lua-5.1-work3/src/lvm.h +lua-5.1-work3/src/lzio.c +lua-5.1-work3/src/lzio.h +lua-5.1-work3/test +lua-5.1-work3/test/README +lua-5.1-work3/test/bisect.lua +lua-5.1-work3/test/cf.lua +lua-5.1-work3/test/echo.lua +lua-5.1-work3/test/env.lua +lua-5.1-work3/test/factorial.lua +lua-5.1-work3/test/fib.lua +lua-5.1-work3/test/fibfor.lua +lua-5.1-work3/test/globals.lua +lua-5.1-work3/test/hello.lua +lua-5.1-work3/test/life.lua +lua-5.1-work3/test/lua +lua-5.1-work3/test/luac +lua-5.1-work3/test/luac.lua +lua-5.1-work3/test/printf.lua +lua-5.1-work3/test/readonly.lua +lua-5.1-work3/test/sieve.lua +lua-5.1-work3/test/sort.lua +lua-5.1-work3/test/table.lua +lua-5.1-work3/test/trace-calls.lua +lua-5.1-work3/test/trace-globals.lua +lua-5.1-work3/test/undefined.lua +lua-5.1-work3/test/xd.lua END OF MANIFEST @@ -14,8 +14,6 @@ all clean co klean: cd src/luac; $(MAKE) $@ cd src/lua; $(MAKE) $@ -clean klean: soclean - # in case they were not created during unpacking all: bin lib @@ -38,27 +36,6 @@ install: all strip $(INSTALL_DATA) lib/*.a $(INSTALL_LIB) $(INSTALL_DATA) doc/*.1 $(INSTALL_MAN) -# shared libraries (for Linux) -so: - ld -o lib/liblua.so.$V -shared src/*.o - ld -o lib/liblualib.so.$V -shared src/lib/*.o - cd lib; ln -fs liblua.so.$V liblua.so; ln -fs liblualib.so.$V liblualib.so - -# binaries using shared libraries -sobin: - rm -f bin/lua* - cd src/lua; $(MAKE) - cd src/luac; $(MAKE) - -# install shared libraries -soinstall: - $(INSTALL_EXEC) lib/*.so.* $(INSTALL_LIB) - cd $(INSTALL_LIB); ln -fs liblua.so.$V liblua.so; ln -fs liblualib.so.$V liblualib.so - -# clean shared libraries -soclean: - rm -f lib/*.so* bin/lua* - # echo config parameters echo: @echo "" @@ -98,7 +75,7 @@ lecho: @make echo | grep = | sed -e 's/= /= "/' -e 's/$$/"/' #-e 's/""/nil/' @echo "-- EOF" -# (end of Makefile) - newer: @find . -newer MANIFEST -type f + +# (end of Makefile) @@ -29,9 +29,10 @@ See HISTORY for a summary of changes since the last released version. * Contacting the authors ---------------------- - Send your comments, questions, and bug reports to lua@tecgraf.puc-rio.br. + Send your comments, questions, and bug reports to + lua-team AT tecgraf.puc-rio.br. For more information about the authors, see http://www.lua.org/authors.html . - For reporting bugs, try also the mailing list: lua-l@tecgraf.puc-rio.br. + For reporting bugs, try also the mailing list: lua@bazar2.conectiva.com.br . For more information about this list, including instructions on how to subscribe and access the archives, see http://www.lua.org/lua-l.html . @@ -21,15 +21,15 @@ USERCONF= # interface (e.g., Linux, Solaris, IRIX, BSD, AIX, HPUX, and probably others), # uncomment the next two lines. Also read the next paragraph. # -#LOADLIB= -DUSE_DLOPEN=1 -#DLLIB= -ldl +LOADLIB= -DUSE_DLOPEN=1 +DLLIB= -ldl # # In Linux with gcc, you should also uncomment the next definition for # MYLDFLAGS, which passes -E (= -export-dynamic) to the linker. This option # allows dynamic libraries to link back to the `lua' program, so that they do # not need the Lua libraries. (Other systems may have an equivalent facility.) # -#MYLDFLAGS= -Wl,-E +MYLDFLAGS= -Wl,-E # # On Windows systems. support for dynamic loading is enabled by default. # To disable this support, uncomment the next line. @@ -33,7 +33,6 @@ #include "linit.c" #include "lmathlib.c" #include "loadlib.c" -#define pushresult pushresult2 #include "loslib.c" #include "lstrlib.c" #include "ltablib.c" diff --git a/etc/lua.hpp b/etc/lua.hpp new file mode 100644 index 00000000..273ec44c --- /dev/null +++ b/etc/lua.hpp @@ -0,0 +1,8 @@ +// lua.hpp +// Lua header files for C++ + +extern "C" { +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" +} @@ -43,5 +43,6 @@ int main(void) lua_register(L,"print",print); if (lua_load(L,getF,stdin,"=stdin") || lua_pcall(L,0,0,0)) fprintf(stderr,"%s\n",lua_tostring(L,-1)); + lua_close(L); return 0; } diff --git a/include/lauxlib.h b/include/lauxlib.h index 22afc245..b47663ce 100644 --- a/include/lauxlib.h +++ b/include/lauxlib.h @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.h,v 1.70 2004/07/09 18:23:17 roberto Exp $ +** $Id: lauxlib.h,v 1.73 2004/10/18 12:51:44 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -70,6 +70,12 @@ LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz, LUALIB_API lua_State *(luaL_newstate) (void); +LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, + const char *r); +LUALIB_API const char *luaL_getfield (lua_State *L, int idx, const char *fname); +LUALIB_API const char *luaL_setfield (lua_State *L, int idx, const char *fname); + + /* ** =============================================================== @@ -78,15 +84,15 @@ LUALIB_API lua_State *(luaL_newstate) (void); */ #define luaL_argcheck(L, cond,numarg,extramsg) \ - ((void)((cond) || luaL_argerror(L, numarg,extramsg))) + ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) -#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, n)) -#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, n,d)) -#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, n)) -#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, n,d)) +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) +#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) +#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) +#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) -#define luaL_typename(L,i) lua_typename(L,lua_type(L,(i))) +#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) /* ** {====================================================== @@ -131,7 +137,7 @@ LUALIB_API void luaL_pushresult (luaL_Buffer *B); #define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) -#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, ref) +#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) #endif diff --git a/include/lua.h b/include/lua.h index ac5435e7..aa4401c7 100644 --- a/include/lua.h +++ b/include/lua.h @@ -1,5 +1,5 @@ /* -** $Id: lua.h,v 1.193 2004/09/15 20:39:42 roberto Exp $ +** $Id: lua.h,v 1.196 2004/12/06 17:53:42 roberto Exp $ ** Lua - An Extensible Extension Language ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil ** http://www.lua.org mailto:info@lua.org @@ -17,7 +17,7 @@ #include "luaconf.h" -#define LUA_VERSION "Lua 5.1 (work2)" +#define LUA_VERSION "Lua 5.1 (work3)" #define LUA_COPYRIGHT "Copyright (C) 1994-2004 Tecgraf, PUC-Rio" #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" @@ -81,6 +81,10 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); #define LUA_TTHREAD 8 +/* first index for arrays */ +#define LUA_FIRSTINDEX 1 + + /* minimum Lua stack available to a C function */ #define LUA_MINSTACK 20 @@ -216,11 +220,13 @@ LUA_API int lua_threadstatus (lua_State *L); ** garbage-collection function and options */ -#define LUA_GCSTOP 0 -#define LUA_GCRESTART 1 -#define LUA_GCCOLLECT 2 -#define LUA_GCCOUNT 3 -#define LUA_GCSTEP 4 +#define LUA_GCSTOP 0 +#define LUA_GCRESTART 1 +#define LUA_GCCOLLECT 2 +#define LUA_GCCOUNT 3 +#define LUA_GCSTEP 4 +#define LUA_GCSETSTEPMUL 5 +#define LUA_GCSETINCMODE 6 LUA_API int lua_gc (lua_State *L, int what, int data); @@ -251,26 +257,26 @@ LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud); #define lua_newtable(L) lua_createtable(L, 0, 0) -#define lua_register(L,n,f) (lua_pushcfunction(L,f), lua_setglobal(L,n)) +#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) -#define lua_pushcfunction(L,f) lua_pushcclosure(L, f, 0) +#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) -#define lua_strlen(L,i) lua_objsize(L,i) +#define lua_strlen(L,i) lua_objsize(L, (i)) -#define lua_isfunction(L,n) (lua_type(L,n) == LUA_TFUNCTION) -#define lua_istable(L,n) (lua_type(L,n) == LUA_TTABLE) -#define lua_islightuserdata(L,n) (lua_type(L,n) == LUA_TLIGHTUSERDATA) -#define lua_isnil(L,n) (lua_type(L,n) == LUA_TNIL) -#define lua_isboolean(L,n) (lua_type(L,n) == LUA_TBOOLEAN) -#define lua_isthread(L,n) (lua_type(L,n) == LUA_TTHREAD) -#define lua_isnone(L,n) (lua_type(L,n) == LUA_TNONE) -#define lua_isnoneornil(L, n) (lua_type(L,n) <= 0) +#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) +#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) +#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) +#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) +#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) +#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) +#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) +#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) #define lua_pushliteral(L, s) \ lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) -#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, s) -#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, s) +#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) +#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) diff --git a/include/luaconf.h b/include/luaconf.h index 7ef4cedf..f00bbd05 100644 --- a/include/luaconf.h +++ b/include/luaconf.h @@ -1,5 +1,5 @@ /* -** $Id: luaconf.h,v 1.12 2004/09/10 17:30:46 roberto Exp $ +** $Id: luaconf.h,v 1.20 2004/12/06 17:53:42 roberto Exp $ ** Configuration file for Lua ** See Copyright Notice in lua.h */ @@ -31,7 +31,11 @@ */ /* default path */ -#define LUA_PATH_DEFAULT "?;?.lua" +#define LUA_PATH_DEFAULT \ + "./?.lua;/usr/local/share/lua/5.0/?.lua;/usr/local/share/lua/5.0/?/init.lua" +#define LUA_CPATH_DEFAULT \ + "./?.so;/usr/local/lib/lua/5.0/?.so;/usr/local/lib/lua/5.0/lib?.so" + /* type of numbers in Lua */ @@ -42,8 +46,11 @@ #define LUA_NUMBER_FMT "%.14g" -/* type for integer functions */ -#define LUA_INTEGER long +/* +** type for integer functions +** on most machines, `ptrdiff_t' gives a reasonable size for integers +*/ +#define LUA_INTEGER ptrdiff_t /* mark for all API functions */ @@ -56,9 +63,6 @@ #define LUAL_BUFFERSIZE BUFSIZ -/* first index for arrays */ -#define LUA_FIRSTINDEX 1 - /* assertions in Lua (mainly for internal debugging) */ #define lua_assert(c) ((void)0) @@ -123,19 +127,45 @@ #ifdef LUA_CORE /* LUA-C API assertions */ -#define api_check(L, o) lua_assert(o) +#define api_check(L,o) lua_assert(o) -/* an unsigned integer with at least 32 bits */ -#define LUA_UINT32 unsigned long +/* number of bits in an `int' */ +/* avoid overflows in comparison */ +#if INT_MAX-20 < 32760 +#define LUA_BITSINT 16 +#elif INT_MAX > 2147483640L +/* `int' has at least 32 bits */ +#define LUA_BITSINT 32 +#else +#error "you must define LUA_BITSINT with number of bits in an integer" +#endif + -/* a signed integer with at least 32 bits */ +/* +** 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 +*/ +#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 +#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 +#endif /* maximum depth for calls (unsigned short) */ -#define LUA_MAXCALLS 4096 +#define LUA_MAXCALLS 10000 /* ** maximum depth for C calls (unsigned short): Not too big, or may @@ -160,7 +190,7 @@ /* maximum number of upvalues per function */ -#define MAXUPVALUES 32 /* <MAXSTACK */ +#define MAXUPVALUES 60 /* <MAXSTACK */ /* maximum size of expressions for optimizing `while' code */ @@ -170,7 +200,7 @@ /* 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") -#elif 0 +#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)) @@ -179,7 +209,7 @@ #endif /* function to convert a lua_Number to lua_Integer (with any rounding method) */ -#define lua_number2integer(i,n) lua_number2int(i,n) +#define lua_number2integer(i,n) lua_number2int((i), (n)) /* function to convert a lua_Number to a string */ @@ -195,17 +225,6 @@ #define LUA_UACNUMBER double -/* number of bits in an `int' */ -/* avoid overflows in comparison */ -#if INT_MAX-20 < 32760 -#define LUA_BITSINT 16 -#elif INT_MAX > 2147483640L -/* machine has at least 32 bits */ -#define LUA_BITSINT 32 -#else -#error "you must define LUA_BITSINT with number of bits in an integer" -#endif - /* type to ensure maximum alignment */ #define LUSER_ALIGNMENT_T union { double u; void *s; long l; } @@ -215,14 +234,14 @@ #ifndef __cplusplus /* default handling with long jumps */ #include <setjmp.h> -#define L_THROW(c) longjmp((c)->b, 1) -#define L_TRY(c,a) if (setjmp((c)->b) == 0) { a } +#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 #else /* C++ exceptions */ -#define L_THROW(c) throw(c) -#define L_TRY(c,a) try { a } catch(...) \ +#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 */ #endif @@ -251,9 +270,12 @@ /* allows user-specific initialization on new threads */ -#define lua_userstateopen(l) /* empty */ +#define lua_userstateopen(L) /* empty */ +/* initial GC parameters */ +#define STEPMUL 4 + #endif /* }====================================================== */ @@ -272,8 +294,19 @@ /* `assert' options */ -/* environment variable that holds the search path for packages */ +/* 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 */ +#if defined(__APPLE__) && defined(__MACH__) +#define LUA_POF "_luaopen_" +#else +#define LUA_POF "luaopen_" +#endif + +/* directory separator (for submodules) */ +#define LUA_DIRSEP "/" /* separator of templates in a path */ #define LUA_PATH_SEP ';' @@ -288,7 +321,7 @@ /* ** by default, gcc does not get `tmpname' -*/ +*/ #ifdef __GNUC__ #define USE_TMPNAME 0 #else @@ -296,6 +329,17 @@ #endif +/* +** Configuration for loadlib +*/ +#if defined(__linux) || defined(sun) || defined(sgi) || defined(BSD) +#define USE_DLOPEN +#elif defined(_WIN32) +#define USE_DLL +#elif defined(__APPLE__) && defined(__MACH__) +#define USE_DYLD +#endif + #endif @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 2.19 2004/09/15 20:39:42 roberto Exp $ +** $Id: lapi.c,v 2.22 2004/12/06 17:53:42 roberto Exp $ ** Lua API ** See Copyright Notice in lua.h */ @@ -45,7 +45,7 @@ const char lua_ident[] = -static TValue *luaA_index (lua_State *L, int idx) { +static TValue *index2adr (lua_State *L, int idx) { if (idx > 0) { TValue *o = L->base + (idx - 1); api_check(L, idx <= L->ci->top - L->base); @@ -160,7 +160,7 @@ LUA_API void lua_settop (lua_State *L, int idx) { LUA_API void lua_remove (lua_State *L, int idx) { StkId p; lua_lock(L); - p = luaA_index(L, idx); + p = index2adr(L, idx); api_checkvalidindex(L, p); while (++p < L->top) setobjs2s(L, p-1, p); L->top--; @@ -172,7 +172,7 @@ LUA_API void lua_insert (lua_State *L, int idx) { StkId p; StkId q; lua_lock(L); - p = luaA_index(L, idx); + p = index2adr(L, idx); api_checkvalidindex(L, p); for (q = L->top; q>p; q--) setobjs2s(L, q, q-1); setobjs2s(L, p, L->top); @@ -184,7 +184,7 @@ LUA_API void lua_replace (lua_State *L, int idx) { StkId o; lua_lock(L); api_checknelems(L, 1); - o = luaA_index(L, idx); + o = index2adr(L, idx); api_checkvalidindex(L, o); setobj(L, o, L->top - 1); if (idx < LUA_GLOBALSINDEX) /* function upvalue? */ @@ -196,7 +196,7 @@ LUA_API void lua_replace (lua_State *L, int idx) { LUA_API void lua_pushvalue (lua_State *L, int idx) { lua_lock(L); - setobj2s(L, L->top, luaA_index(L, idx)); + setobj2s(L, L->top, index2adr(L, idx)); api_incr_top(L); lua_unlock(L); } @@ -209,7 +209,7 @@ LUA_API void lua_pushvalue (lua_State *L, int idx) { LUA_API int lua_type (lua_State *L, int idx) { - StkId o = luaA_index(L, idx); + StkId o = index2adr(L, idx); return (o == &luaO_nilobject) ? LUA_TNONE : ttype(o); } @@ -221,14 +221,14 @@ LUA_API const char *lua_typename (lua_State *L, int t) { LUA_API int lua_iscfunction (lua_State *L, int idx) { - StkId o = luaA_index(L, idx); + StkId o = index2adr(L, idx); return iscfunction(o); } LUA_API int lua_isnumber (lua_State *L, int idx) { TValue n; - const TValue *o = luaA_index(L, idx); + const TValue *o = index2adr(L, idx); return tonumber(o, &n); } @@ -240,14 +240,14 @@ LUA_API int lua_isstring (lua_State *L, int idx) { LUA_API int lua_isuserdata (lua_State *L, int idx) { - const TValue *o = luaA_index(L, idx); + const TValue *o = index2adr(L, idx); return (ttisuserdata(o) || ttislightuserdata(o)); } LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { - StkId o1 = luaA_index(L, index1); - StkId o2 = luaA_index(L, index2); + StkId o1 = index2adr(L, index1); + StkId o2 = index2adr(L, index2); return (o1 == &luaO_nilobject || o2 == &luaO_nilobject) ? 0 : luaO_rawequalObj(o1, o2); } @@ -257,8 +257,8 @@ LUA_API int lua_equal (lua_State *L, int index1, int index2) { StkId o1, o2; int i; lua_lock(L); /* may call tag method */ - o1 = luaA_index(L, index1); - o2 = luaA_index(L, index2); + o1 = index2adr(L, index1); + o2 = index2adr(L, index2); i = (o1 == &luaO_nilobject || o2 == &luaO_nilobject) ? 0 : equalobj(L, o1, o2); lua_unlock(L); @@ -270,8 +270,8 @@ LUA_API int lua_lessthan (lua_State *L, int index1, int index2) { StkId o1, o2; int i; lua_lock(L); /* may call tag method */ - o1 = luaA_index(L, index1); - o2 = luaA_index(L, index2); + o1 = index2adr(L, index1); + o2 = index2adr(L, index2); i = (o1 == &luaO_nilobject || o2 == &luaO_nilobject) ? 0 : luaV_lessthan(L, o1, o2); lua_unlock(L); @@ -282,7 +282,7 @@ LUA_API int lua_lessthan (lua_State *L, int index1, int index2) { LUA_API lua_Number lua_tonumber (lua_State *L, int idx) { TValue n; - const TValue *o = luaA_index(L, idx); + const TValue *o = index2adr(L, idx); if (tonumber(o, &n)) return nvalue(o); else @@ -292,7 +292,7 @@ LUA_API lua_Number lua_tonumber (lua_State *L, int idx) { LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) { TValue n; - const TValue *o = luaA_index(L, idx); + const TValue *o = index2adr(L, idx); if (tonumber(o, &n)) { lua_Integer res; lua_number2integer(res, nvalue(o)); @@ -304,13 +304,13 @@ LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) { LUA_API int lua_toboolean (lua_State *L, int idx) { - const TValue *o = luaA_index(L, idx); + const TValue *o = index2adr(L, idx); return !l_isfalse(o); } LUA_API const char *lua_tostring (lua_State *L, int idx) { - StkId o = luaA_index(L, idx); + StkId o = index2adr(L, idx); if (ttisstring(o)) return svalue(o); else { @@ -325,7 +325,7 @@ LUA_API const char *lua_tostring (lua_State *L, int idx) { LUA_API size_t lua_objsize (lua_State *L, int idx) { - StkId o = luaA_index(L, idx); + StkId o = index2adr(L, idx); if (ttisstring(o)) return tsvalue(o)->len; else if (ttisuserdata(o)) @@ -341,13 +341,13 @@ LUA_API size_t lua_objsize (lua_State *L, int idx) { LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { - StkId o = luaA_index(L, idx); + StkId o = index2adr(L, idx); return (!iscfunction(o)) ? NULL : clvalue(o)->c.f; } LUA_API void *lua_touserdata (lua_State *L, int idx) { - StkId o = luaA_index(L, idx); + StkId o = index2adr(L, idx); switch (ttype(o)) { case LUA_TUSERDATA: return (rawuvalue(o) + 1); case LUA_TLIGHTUSERDATA: return pvalue(o); @@ -357,13 +357,13 @@ LUA_API void *lua_touserdata (lua_State *L, int idx) { LUA_API lua_State *lua_tothread (lua_State *L, int idx) { - StkId o = luaA_index(L, idx); + StkId o = index2adr(L, idx); return (!ttisthread(o)) ? NULL : thvalue(o); } LUA_API const void *lua_topointer (lua_State *L, int idx) { - StkId o = luaA_index(L, idx); + StkId o = index2adr(L, idx); switch (ttype(o)) { case LUA_TTABLE: return hvalue(o); case LUA_TFUNCTION: return clvalue(o); @@ -498,7 +498,7 @@ LUA_API int lua_pushthread (lua_State *L) { LUA_API void lua_gettable (lua_State *L, int idx) { StkId t; lua_lock(L); - t = luaA_index(L, idx); + t = index2adr(L, idx); api_checkvalidindex(L, t); luaV_gettable(L, t, L->top - 1, L->top - 1, NULL); lua_unlock(L); @@ -509,7 +509,7 @@ LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { StkId t; TValue key; lua_lock(L); - t = luaA_index(L, idx); + t = index2adr(L, idx); api_checkvalidindex(L, t); setsvalue(L, &key, luaS_new(L, k)); luaV_gettable(L, t, &key, L->top, NULL); @@ -521,7 +521,7 @@ LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { LUA_API void lua_rawget (lua_State *L, int idx) { StkId t; lua_lock(L); - t = luaA_index(L, idx); + t = index2adr(L, idx); api_check(L, ttistable(t)); setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); lua_unlock(L); @@ -531,7 +531,7 @@ LUA_API void lua_rawget (lua_State *L, int idx) { LUA_API void lua_rawgeti (lua_State *L, int idx, int n) { StkId o; lua_lock(L); - o = luaA_index(L, idx); + o = index2adr(L, idx); api_check(L, ttistable(o)); setobj2s(L, L->top, luaH_getnum(hvalue(o), n)); api_incr_top(L); @@ -553,7 +553,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) { Table *mt = NULL; int res; lua_lock(L); - obj = luaA_index(L, objindex); + obj = index2adr(L, objindex); switch (ttype(obj)) { case LUA_TTABLE: mt = hvalue(obj)->metatable; @@ -577,7 +577,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) { LUA_API void lua_getfenv (lua_State *L, int idx) { StkId o; lua_lock(L); - o = luaA_index(L, idx); + o = index2adr(L, idx); api_checkvalidindex(L, o); setobj2s(L, L->top, isLfunction(o) ? &clvalue(o)->l.g : gt(L)); api_incr_top(L); @@ -594,7 +594,7 @@ LUA_API void lua_settable (lua_State *L, int idx) { StkId t; lua_lock(L); api_checknelems(L, 2); - t = luaA_index(L, idx); + t = index2adr(L, idx); api_checkvalidindex(L, t); luaV_settable(L, t, L->top - 2, L->top - 1, NULL); L->top -= 2; /* pop index and value */ @@ -607,7 +607,7 @@ LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { TValue key; lua_lock(L); api_checknelems(L, 1); - t = luaA_index(L, idx); + t = index2adr(L, idx); api_checkvalidindex(L, t); setsvalue(L, &key, luaS_new(L, k)); luaV_settable(L, t, &key, L->top - 1, NULL); @@ -620,7 +620,7 @@ LUA_API void lua_rawset (lua_State *L, int idx) { StkId t; lua_lock(L); api_checknelems(L, 2); - t = luaA_index(L, idx); + t = index2adr(L, idx); api_check(L, ttistable(t)); setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); luaC_barriert(L, hvalue(t), L->top-1); @@ -633,7 +633,7 @@ LUA_API void lua_rawseti (lua_State *L, int idx, int n) { StkId o; lua_lock(L); api_checknelems(L, 1); - o = luaA_index(L, idx); + o = index2adr(L, idx); api_check(L, ttistable(o)); setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1); luaC_barriert(L, hvalue(o), L->top-1); @@ -648,7 +648,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { int res = 1; lua_lock(L); api_checknelems(L, 1); - obj = luaA_index(L, objindex); + obj = index2adr(L, objindex); api_checkvalidindex(L, obj); if (ttisnil(L->top - 1)) mt = NULL; @@ -685,7 +685,7 @@ LUA_API int lua_setfenv (lua_State *L, int idx) { int res = 0; lua_lock(L); api_checknelems(L, 1); - o = luaA_index(L, idx); + o = index2adr(L, idx); api_checkvalidindex(L, o); api_check(L, ttistable(L->top - 1)); if (isLfunction(o)) { @@ -751,7 +751,7 @@ LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) { if (errfunc == 0) func = 0; else { - StkId o = luaA_index(L, errfunc); + StkId o = index2adr(L, errfunc); api_checkvalidindex(L, o); func = savestack(L, o); } @@ -842,7 +842,7 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { g = G(L); switch (what) { case LUA_GCSTOP: { - g->GCthreshold = MAXLMEM; + g->GCthreshold = MAX_LUMEM; break; } case LUA_GCRESTART: { @@ -867,6 +867,16 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { luaC_step(L); break; } + case LUA_GCSETSTEPMUL: { + res = g->stepmul; + g->stepmul = data; + break; + } + case LUA_GCSETINCMODE: { + res = g->incgc; + g->incgc = data; + break; + } default: res = -1; /* invalid option */ } lua_unlock(L); @@ -898,7 +908,7 @@ LUA_API int lua_next (lua_State *L, int idx) { StkId t; int more; lua_lock(L); - t = luaA_index(L, idx); + t = index2adr(L, idx); api_check(L, ttistable(t)); more = luaH_next(L, hvalue(t), L->top - 1); if (more) { @@ -970,7 +980,7 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { const char *name; TValue *val; lua_lock(L); - name = aux_upvalue(L, luaA_index(L, funcindex), n, &val); + name = aux_upvalue(L, index2adr(L, funcindex), n, &val); if (name) { setobj2s(L, L->top, val); api_incr_top(L); @@ -985,7 +995,7 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { TValue *val; StkId fi; lua_lock(L); - fi = luaA_index(L, funcindex); + fi = index2adr(L, funcindex); api_checknelems(L, 1); name = aux_upvalue(L, fi, n, &val); if (name) { diff --git a/src/lcode.c b/src/lcode.c index 54ef0581..f7f1182d 100644 --- a/src/lcode.c +++ b/src/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 2.6 2004/08/24 20:09:11 roberto Exp $ +** $Id: lcode.c,v 2.8 2004/12/03 20:35:33 roberto Exp $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -53,13 +53,13 @@ int luaK_jump (FuncState *fs) { } -static int luaK_condjump (FuncState *fs, OpCode op, int A, int B, int C) { +static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { luaK_codeABC(fs, op, A, B, C); return luaK_jump(fs); } -static void luaK_fixjump (FuncState *fs, int pc, int dest) { +static void fixjump (FuncState *fs, int pc, int dest) { Instruction *jmp = &fs->f->code[pc]; int offset = dest-(pc+1); lua_assert(dest != NO_JUMP); @@ -79,7 +79,7 @@ int luaK_getlabel (FuncState *fs) { } -static int luaK_getjump (FuncState *fs, int pc) { +static int getjump (FuncState *fs, int pc) { int offset = GETARG_sBx(fs->f->code[pc]); if (offset == NO_JUMP) /* point to itself represents end of list */ return NO_JUMP; /* end of list */ @@ -102,7 +102,7 @@ static Instruction *getjumpcontrol (FuncState *fs, int pc) { ** (or produce an inverted value) */ static int need_value (FuncState *fs, int list, int cond) { - for (; list != NO_JUMP; list = luaK_getjump(fs, list)) { + for (; list != NO_JUMP; list = getjump(fs, list)) { Instruction i = *getjumpcontrol(fs, list); if (GET_OPCODE(i) != OP_TEST || GETARG_C(i) != cond) return 1; } @@ -116,25 +116,25 @@ static void patchtestreg (Instruction *i, int reg) { } -static void luaK_patchlistaux (FuncState *fs, int list, +static void patchlistaux (FuncState *fs, int list, int ttarget, int treg, int ftarget, int freg, int dtarget) { while (list != NO_JUMP) { - int next = luaK_getjump(fs, list); + int next = getjump(fs, list); Instruction *i = getjumpcontrol(fs, list); if (GET_OPCODE(*i) != OP_TEST) { lua_assert(dtarget != NO_JUMP); - luaK_fixjump(fs, list, dtarget); /* jump to default target */ + fixjump(fs, list, dtarget); /* jump to default target */ } else { if (GETARG_C(*i)) { lua_assert(ttarget != NO_JUMP); patchtestreg(i, treg); - luaK_fixjump(fs, list, ttarget); + fixjump(fs, list, ttarget); } else { lua_assert(ftarget != NO_JUMP); patchtestreg(i, freg); - luaK_fixjump(fs, list, ftarget); + fixjump(fs, list, ftarget); } } list = next; @@ -142,8 +142,8 @@ static void luaK_patchlistaux (FuncState *fs, int list, } -static void luaK_dischargejpc (FuncState *fs) { - luaK_patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc, NO_REG, fs->pc); +static void dischargejpc (FuncState *fs) { + patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc, NO_REG, fs->pc); fs->jpc = NO_JUMP; } @@ -153,7 +153,7 @@ void luaK_patchlist (FuncState *fs, int list, int target) { luaK_patchtohere(fs, list); else { lua_assert(target < fs->pc); - luaK_patchlistaux(fs, list, target, NO_REG, target, NO_REG, target); + patchlistaux(fs, list, target, NO_REG, target, NO_REG, target); } } @@ -171,9 +171,9 @@ void luaK_concat (FuncState *fs, int *l1, int l2) { else { int list = *l1; int next; - while ((next = luaK_getjump(fs, list)) != NO_JUMP) /* find last element */ + while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ list = next; - luaK_fixjump(fs, list, l2); + fixjump(fs, list, l2); } } @@ -243,7 +243,14 @@ int luaK_numberK (FuncState *fs, lua_Number r) { } -static int nil_constant (FuncState *fs) { +static int boolK (FuncState *fs, int b) { + TValue o; + setbvalue(&o, b); + return addk(fs, &o, &o); +} + + +static int nilK (FuncState *fs) { TValue k, v; setnilvalue(&v); /* cannot use nil as key; instead use table itself to represent nil */ @@ -358,7 +365,7 @@ static void discharge2anyreg (FuncState *fs, expdesc *e) { } -static void luaK_exp2reg (FuncState *fs, expdesc *e, int reg) { +static void exp2reg (FuncState *fs, expdesc *e, int reg) { discharge2reg(fs, e, reg); if (e->k == VJMP) luaK_concat(fs, &e->t, e->info); /* put this jump in `t' list */ @@ -375,8 +382,8 @@ static void luaK_exp2reg (FuncState *fs, expdesc *e, int reg) { luaK_patchtohere(fs, fj); } final = luaK_getlabel(fs); - luaK_patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f); - luaK_patchlistaux(fs, e->t, final, reg, p_t, NO_REG, p_t); + patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f); + patchlistaux(fs, e->t, final, reg, p_t, NO_REG, p_t); } e->f = e->t = NO_JUMP; e->info = reg; @@ -388,7 +395,7 @@ void luaK_exp2nextreg (FuncState *fs, expdesc *e) { luaK_dischargevars(fs, e); freeexp(fs, e); luaK_reserveregs(fs, 1); - luaK_exp2reg(fs, e, fs->freereg - 1); + exp2reg(fs, e, fs->freereg - 1); } @@ -397,7 +404,7 @@ int luaK_exp2anyreg (FuncState *fs, expdesc *e) { if (e->k == VNONRELOC) { if (!hasjumps(e)) return e->info; /* exp is already in a register */ if (e->info >= fs->nactvar) { /* reg. is not a local? */ - luaK_exp2reg(fs, e, e->info); /* put value on it */ + exp2reg(fs, e, e->info); /* put value on it */ return e->info; } } @@ -417,9 +424,11 @@ void luaK_exp2val (FuncState *fs, expdesc *e) { int luaK_exp2RK (FuncState *fs, expdesc *e) { luaK_exp2val(fs, e); switch (e->k) { + case VTRUE: + case VFALSE: case VNIL: { if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */ - e->info = nil_constant(fs); + e->info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE)); e->k = VK; return RKASK(e->info); } @@ -441,7 +450,7 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { switch (var->k) { case VLOCAL: { freeexp(fs, ex); - luaK_exp2reg(fs, ex, var->info); + exp2reg(fs, ex, var->info); return; } case VUPVAL: { @@ -493,13 +502,13 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) { Instruction ie = getcode(fs, e); if (GET_OPCODE(ie) == OP_NOT) { fs->pc--; /* remove previous OP_NOT */ - return luaK_condjump(fs, OP_TEST, NO_REG, GETARG_B(ie), !cond); + return condjump(fs, OP_TEST, NO_REG, GETARG_B(ie), !cond); } /* else go through */ } discharge2anyreg(fs, e); freeexp(fs, e); - return luaK_condjump(fs, OP_TEST, NO_REG, e->info, cond); + return condjump(fs, OP_TEST, NO_REG, e->info, cond); } @@ -651,7 +660,7 @@ static void codebinop (FuncState *fs, expdesc *res, BinOpr op, temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ } else if (op == OPR_NE) cond = 0; - res->info = luaK_condjump(fs, ops[op - OPR_NE], cond, o1, o2); + res->info = condjump(fs, ops[op - OPR_NE], cond, o1, o2); res->k = VJMP; } } @@ -708,7 +717,7 @@ void luaK_fixline (FuncState *fs, int line) { int luaK_code (FuncState *fs, Instruction i, int line) { Proto *f = fs->f; - luaK_dischargejpc(fs); /* `pc' will change */ + dischargejpc(fs); /* `pc' will change */ /* put new instruction in code array */ luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction, MAX_INT, "code size overflow"); @@ -735,3 +744,17 @@ int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline); } + +void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { + int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; + int b = (tostore == LUA_MULTRET) ? 0 : tostore; + lua_assert(tostore != 0); + if (c <= MAXARG_C) + luaK_codeABC(fs, OP_SETLIST, base, b, c); + else { + luaK_codeABC(fs, OP_SETLIST, base, b, 0); + luaK_code(fs, cast(Instruction, c), fs->ls->lastline); + } + fs->freereg = base + 1; /* free registers with list values */ +} + diff --git a/src/lcode.h b/src/lcode.h index b854d5cd..532b3478 100644 --- a/src/lcode.h +++ b/src/lcode.h @@ -1,5 +1,5 @@ /* -** $Id: lcode.h,v 1.39 2004/05/31 18:51:50 roberto Exp $ +** $Id: lcode.h,v 1.40 2004/10/04 19:01:53 roberto Exp $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -72,6 +72,7 @@ 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); #endif diff --git a/src/ldebug.c b/src/ldebug.c index 139e4cdb..17727d37 100644 --- a/src/ldebug.c +++ b/src/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 2.8 2004/09/01 13:47:31 roberto Exp $ +** $Id: ldebug.c,v 2.11 2004/12/03 20:35:33 roberto Exp $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -261,11 +261,11 @@ int luaG_checkopenop (Instruction i) { switch (GET_OPCODE(i)) { case OP_CALL: case OP_TAILCALL: - case OP_RETURN: { + case OP_RETURN: + case OP_SETLIST: { check(GETARG_B(i) == 0); return 1; } - case OP_SETLISTO: return 1; default: return 0; /* invalid instruction after an open call */ } } @@ -284,7 +284,7 @@ static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) { } -static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { +static Instruction symbexec (const Proto *pt, int lastpc, int reg) { int pc; int last; /* stores position of last instruction that changed `reg' */ last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */ @@ -315,6 +315,11 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { if (getBMode(op) == OpArgR) { int dest = pc+1+b; check(0 <= dest && dest < pt->sizecode); + if (dest > 0) { + /* cannot jump to a setlist count */ + const Instruction d = pt->code[dest-1]; + check(!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)); + } } break; } @@ -356,7 +361,8 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { break; } case OP_TFORLOOP: { - checkreg(pt, a+5); /* space for control variables */ + check(c >= 1); /* at least one result (control variable) */ + checkreg(pt, a+3+c); /* space for results */ if (reg >= a+3) last = pc; /* affect all regs above its call base */ break; } @@ -392,7 +398,8 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { break; } case OP_SETLIST: { - checkreg(pt, a + (b&(LFIELDS_PER_FLUSH-1)) + 1); + if (b > 0) checkreg(pt, a + b); + if (c == 0) pc++; break; } case OP_CLOSURE: { @@ -427,7 +434,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { int luaG_checkcode (const Proto *pt) { - return (luaG_symbexec(pt, pt->sizecode, NO_REG) != 0); + return (symbexec(pt, pt->sizecode, NO_REG) != 0); } @@ -447,7 +454,7 @@ static const char *getobjname (CallInfo *ci, int stackpos, const char **name) { *name = luaF_getlocalname(p, stackpos+1, pc); if (*name) /* is a local? */ return "local"; - i = luaG_symbexec(p, pc, stackpos); /* try symbolic execution */ + i = symbexec(p, pc, stackpos); /* try symbolic execution */ lua_assert(pc != -1); switch (GET_OPCODE(i)) { case OP_GETGLOBAL: { @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 2.10 2004/09/15 20:39:42 roberto Exp $ +** $Id: ldo.c,v 2.13 2004/12/03 20:35:33 roberto Exp $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -70,7 +70,7 @@ 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->errorJmp); + L_THROW(L, L->errorJmp); } else { if (G(L)->panic) G(L)->panic(L); @@ -84,7 +84,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(&lj, + L_TRY(L, &lj, (*f)(L, ud); ); L->errorJmp = lj.previous; /* restore old error handler */ @@ -147,7 +147,7 @@ void luaD_growstack (lua_State *L, int n) { } -static CallInfo *luaD_growCI (lua_State *L) { +static CallInfo *growCI (lua_State *L) { if (L->size_ci > LUA_MAXCALLS) /* overflow while handling overflow? */ luaD_throw(L, LUA_ERRERR); else { @@ -238,7 +238,7 @@ static StkId tryfuncTM (lua_State *L, StkId func) { #define inc_ci(L) \ - ((L->ci == L->end_ci) ? luaD_growCI(L) : \ + ((L->ci == L->end_ci) ? growCI(L) : \ (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci)) @@ -391,7 +391,6 @@ static int resume_error (lua_State *L, const char *msg) { LUA_API int lua_resume (lua_State *L, int nargs) { int status; - lu_byte old_allowhooks; lua_lock(L); lua_assert(L->errfunc == 0 && L->nCcalls == 0); if (L->status != LUA_YIELD) { @@ -400,7 +399,6 @@ LUA_API int lua_resume (lua_State *L, int nargs) { else if (L->ci != L->base_ci) return resume_error(L, "cannot resume non-suspended coroutine"); } - old_allowhooks = L->allowhook; status = luaD_rawrunprotected(L, resume, &nargs); if (status != 0) { /* error? */ L->status = status; /* mark thread as `dead' */ diff --git a/src/ldump.c b/src/ldump.c index bd0becb9..967596a1 100644 --- a/src/ldump.c +++ b/src/ldump.c @@ -1,5 +1,5 @@ /* -** $Id: ldump.c,v 1.8 2004/09/01 21:22:34 lhf Exp $ +** $Id: ldump.c,v 1.9 2004/11/25 09:31:41 lhf Exp $ ** save pre-compiled Lua chunks ** See Copyright Notice in lua.h */ @@ -113,14 +113,17 @@ static void DumpConstants(const Proto* f, DumpState* D) DumpByte(ttype(o),D); switch (ttype(o)) { + case LUA_TNIL: + break; + case LUA_TBOOLEAN: + DumpByte(bvalue(o),D); + break; case LUA_TNUMBER: DumpNumber(nvalue(o),D); break; case LUA_TSTRING: DumpString(rawtsvalue(o),D); break; - case LUA_TNIL: - break; default: lua_assert(0); /* cannot happen */ break; diff --git a/src/lfunc.c b/src/lfunc.c index 7d4fbf20..af431cc3 100644 --- a/src/lfunc.c +++ b/src/lfunc.c @@ -1,5 +1,5 @@ /* -** $Id: lfunc.c,v 2.4 2004/04/30 20:13:38 roberto Exp $ +** $Id: lfunc.c,v 2.5 2004/11/24 19:20:21 roberto Exp $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ @@ -75,7 +75,7 @@ void luaF_close (lua_State *L, StkId level) { lua_assert(!isblack(o)); L->openupval = uv->next; /* remove from `open' list */ if (isdead(g, o)) - luaM_freelem(L, uv); /* free upvalue */ + luaM_free(L, uv); /* free upvalue */ else { setobj(L, &uv->value, uv->v); uv->v = &uv->value; /* now current value lives here */ @@ -117,14 +117,14 @@ void luaF_freeproto (lua_State *L, Proto *f) { luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); - luaM_freelem(L, f); + luaM_free(L, f); } void luaF_freeclosure (lua_State *L, Closure *c) { int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : sizeLclosure(c->l.nupvalues); - luaM_free(L, c, size); + luaM_freemem(L, c, size); } @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.12 2004/09/15 20:38:15 roberto Exp $ +** $Id: lgc.c,v 2.18 2004/12/06 17:53:42 roberto Exp $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -24,7 +24,6 @@ #define GCSTEPSIZE 1000 -#define STEPMUL 2 #define GCSWEEPMAX 10 #define GCSWEEPCOST 30 #define GCFINALIZECOST 100 @@ -65,7 +64,7 @@ static void removeentry (Node *n) { setnilvalue(gval(n)); /* remove corresponding value ... */ if (iscollectable(gkey(n))) - setttype(gkey(n), LUA_TNONE); /* dead key; remove it */ + setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */ } @@ -139,7 +138,7 @@ size_t luaC_separateudata (lua_State *L, int all) { p = &curr->gch.next; } else { /* must call its gc method */ - deadmem += sizeudata(gco2u(curr)->len); + deadmem += sizeudata(gco2u(curr)); markfinalized(gco2u(curr)); *p = curr->gch.next; curr->gch.next = NULL; /* link `curr' at the end of `collected' list */ @@ -184,6 +183,7 @@ static int traversetable (global_State *g, Table *h) { i = sizenode(h); while (i--) { Node *n = gnode(h, i); + lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); if (ttisnil(gval(n))) removeentry(n); /* remove empty entries */ else { @@ -367,7 +367,7 @@ static void cleartable (GCObject *l) { while (i--) { Node *n = gnode(h, i); if (!ttisnil(gval(n)) && /* non-empty entry? */ - (iscleared(gkey(n), 1) || iscleared(gval(n), 0))) + (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) removeentry(n); /* remove entry from table */ } l = h->gclist; @@ -379,7 +379,7 @@ static void freeobj (lua_State *L, GCObject *o) { switch (o->gch.tt) { case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break; - case LUA_TUPVAL: luaM_freelem(L, gco2uv(o)); break; + case LUA_TUPVAL: luaM_free(L, gco2uv(o)); break; case LUA_TTABLE: luaH_free(L, gco2h(o)); break; case LUA_TTHREAD: { lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread); @@ -388,11 +388,11 @@ static void freeobj (lua_State *L, GCObject *o) { } case LUA_TSTRING: { G(L)->strt.nuse--; - luaM_free(L, o, sizestring(gco2ts(o)->len)); + luaM_freemem(L, o, sizestring(gco2ts(o))); break; } case LUA_TUSERDATA: { - luaM_free(L, o, sizeudata(gco2u(o)->len)); + luaM_freemem(L, o, sizeudata(gco2u(o))); break; } default: lua_assert(0); @@ -529,6 +529,7 @@ static void remarkupvals (global_State *g) { static void atomic (lua_State *L) { global_State *g = G(L); + size_t udsize; /* total size of userdata to be finalized */ int aux; /* remark objects cautch by write barrier */ propagateall(g); @@ -544,7 +545,7 @@ static void atomic (lua_State *L) { g->gray = g->grayagain; g->grayagain = NULL; propagateall(g); - luaC_separateudata(L, 0); /* separate userdata to be preserved */ + udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */ marktmu(g); /* mark `preserved' userdata */ propagateall(g); /* remark, to propagate `preserveness' */ cleartable(g->weak); /* remove collected objects from weak tables */ @@ -554,10 +555,10 @@ static void atomic (lua_State *L) { g->sweepgc = &g->rootgc; g->gcstate = GCSsweepstring; aux = g->gcgenerational; - g->gcgenerational = (g->estimate <= 4*g->prevestimate/2); + g->gcgenerational = g->incgc && (g->estimate/2 <= g->prevestimate); if (!aux) /* last collection was full? */ g->prevestimate = g->estimate; /* keep estimate of last full collection */ - g->estimate = g->totalbytes; /* first estimate */ + g->estimate = g->totalbytes - udsize; /* first estimate */ } @@ -586,6 +587,7 @@ static l_mem singlestep (lua_State *L) { sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */ g->gcstate = GCSsweep; /* end sweep-string phase */ + lua_assert(old >= g->totalbytes); g->estimate -= old - g->totalbytes; return GCSWEEPCOST; } @@ -596,12 +598,15 @@ static l_mem singlestep (lua_State *L) { checkSizes(L); g->gcstate = GCSfinalize; /* end sweep phase */ } + lua_assert(old >= g->totalbytes); g->estimate -= old - g->totalbytes; return GCSWEEPMAX*GCSWEEPCOST; } case GCSfinalize: { if (g->tmudata) { + g->GCthreshold += GCFINALIZECOST; /* avoid GC steps inside method */ GCTM(L); + g->GCthreshold -= GCFINALIZECOST; /* correct threshold */ return GCFINALIZECOST; } else { @@ -616,23 +621,18 @@ static l_mem singlestep (lua_State *L) { void luaC_step (lua_State *L) { global_State *g = G(L); - l_mem lim = (g->totalbytes - (g->GCthreshold - GCSTEPSIZE)) * STEPMUL; -/*printf("step(%c): ", g->gcgenerational?'g':' ');*/ + l_mem lim = (g->totalbytes - (g->GCthreshold - GCSTEPSIZE)) * g->stepmul; do { - /*printf("%c", "_pswf"[g->gcstate]);*/ lim -= singlestep(L); if (g->gcstate == GCSpause) break; - } while (lim > 0); -/*printf("\n");*/ - if (g->gcstate != GCSpause) + } while (lim > 0 || !g->incgc); + if (g->incgc) g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/STEPMUL; */ else { -/*printf("---\n");*/ lua_assert(g->totalbytes >= g->estimate); + lua_assert(g->gcstate == GCSpause); g->GCthreshold = 2*g->estimate; - if (g->GCthreshold < g->totalbytes + GCSTEPSIZE) - g->GCthreshold = g->totalbytes + GCSTEPSIZE; } } @@ -657,20 +657,19 @@ void luaC_fullgc (lua_State *L) { } markroot(L); lua_assert(!g->gcgenerational); - while (g->gcstate != GCSfinalize) { + while (g->gcstate != GCSpause) { singlestep(L); g->gcgenerational = 0; /* keep it in this mode */ } - lua_assert(g->estimate == g->totalbytes); g->GCthreshold = 2*g->estimate; - luaC_callGCTM(L); /* call finalizers */ } void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { global_State *g = G(L); lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); - lua_assert(g->gcgenerational || g->gcstate != GCSfinalize); + lua_assert(g->gcgenerational || + (g->gcstate != GCSfinalize && g->gcstate != GCSpause)); lua_assert(ttype(&o->gch) != LUA_TTABLE); /* must keep invariant? */ if (g->gcstate == GCSpropagate || g->gcgenerational) @@ -683,7 +682,8 @@ void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { void luaC_barrierback (lua_State *L, GCObject *o, GCObject *v) { global_State *g = G(L); lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); - lua_assert(g->gcgenerational || g->gcstate != GCSfinalize); + lua_assert(g->gcgenerational || + (g->gcstate != GCSfinalize && g->gcstate != GCSpause)); black2gray(o); /* make table gray (again) */ gco2h(o)->gclist = g->grayagain; g->grayagain = o; diff --git a/src/lib/lauxlib.c b/src/lib/lauxlib.c index 7c14d001..615be8f2 100644 --- a/src/lib/lauxlib.c +++ b/src/lib/lauxlib.c @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.c,v 1.124 2004/09/03 13:17:14 roberto Exp $ +** $Id: lauxlib.c,v 1.126 2004/09/29 21:03:14 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -239,16 +239,22 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname, const luaL_reg *l, int nup) { if (libname) { /* check whether lib already exists */ - lua_getglobal(L, libname); - if (lua_isnil(L, -1)) { /* no? */ - lua_pop(L, 1); + luaL_getfield(L, LUA_GLOBALSINDEX, libname); + if (lua_isnil(L, -1)) { /* not found? */ + lua_pop(L, 1); /* remove previous result */ lua_newtable(L); /* create it */ if (lua_getmetatable(L, LUA_GLOBALSINDEX)) lua_setmetatable(L, -2); /* share metatable with global table */ - lua_pushvalue(L, -1); /* register it with given name */ - lua_setglobal(L, libname); + lua_pushvalue(L, -1); + luaL_setfield(L, LUA_GLOBALSINDEX, libname); } + else if (!lua_istable(L, -1)) + luaL_error(L, "name conflict for library `%s'", libname); + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_pushvalue(L, -2); + lua_setfield(L, -2, libname); /* _LOADED[modname] = new table */ + lua_pop(L, 1); /* remove _LOADED table */ lua_insert(L, -(nup+1)); /* move library table to below upvalues */ } for (; l->name; l++) { @@ -352,8 +358,8 @@ static const char *pushnexttemplate (lua_State *L, const char *path) { } -static const char *luaL_gsub (lua_State *L, const char *s, - const char *p, const char *r) { +LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, + const char *r) { const char *wild; int l = strlen(p); luaL_Buffer b; @@ -381,16 +387,68 @@ LUALIB_API const char *luaL_searchpath (lua_State *L, const char *name, } fname = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name); lua_remove(L, -2); /* remove path template */ - f = fopen(fname, "r"); /* try to read it */ + f = fopen(fname, "r"); /* try to open it */ if (f) { + int err; + getc(f); /* try to read file */ + err = ferror(f); fclose(f); - return fname; + if (err == 0) /* open and read sucessful? */ + return fname; /* return that file name */ } lua_pop(L, 1); /* remove file name */ } } +LUALIB_API const char *luaL_getfield (lua_State *L, int idx, + const char *fname) { + const char *e; + lua_pushvalue(L, idx); + while ((e = strchr(fname, '.')) != NULL) { + lua_pushlstring(L, fname, e - fname); + lua_rawget(L, -2); + lua_remove(L, -2); /* remove previous table */ + fname = e + 1; + if (!lua_istable(L, -1)) return fname; + } + lua_pushstring(L, fname); + lua_rawget(L, -2); /* get last field */ + lua_remove(L, -2); /* remove previous table */ + return NULL; +} + + +LUALIB_API const char *luaL_setfield (lua_State *L, int idx, + const char *fname) { + const char *e; + lua_pushvalue(L, idx); + while ((e = strchr(fname, '.')) != NULL) { + lua_pushlstring(L, fname, e - fname); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) { /* no such field? */ + lua_pop(L, 1); /* remove this nil */ + lua_newtable(L); /* create a new table for field */ + lua_pushlstring(L, fname, e - fname); + lua_pushvalue(L, -2); + lua_settable(L, -4); /* set new table into field */ + } + lua_remove(L, -2); /* remove previous table */ + fname = e + 1; + if (!lua_istable(L, -1)) { + lua_pop(L, 2); /* remove table and value */ + return fname; + } + } + lua_pushstring(L, fname); + lua_pushvalue(L, -3); /* move value to the top */ + lua_rawset(L, -3); /* set last field */ + lua_pop(L, 2); /* remove value and table */ + return NULL; +} + + + /* ** {====================================================== ** Generic Buffer manipulation diff --git a/src/lib/lbaselib.c b/src/lib/lbaselib.c index 82a8f509..8c628097 100644 --- a/src/lib/lbaselib.c +++ b/src/lib/lbaselib.c @@ -1,5 +1,5 @@ /* -** $Id: lbaselib.c,v 1.158 2004/09/15 20:39:42 roberto Exp $ +** $Id: lbaselib.c,v 1.161 2004/12/06 17:53:42 roberto Exp $ ** Basic library ** See Copyright Notice in lua.h */ @@ -181,10 +181,10 @@ static int luaB_gcinfo (lua_State *L) { static int luaB_collectgarbage (lua_State *L) { - static const char *const opts[] = {"stop", "restart", "collect", "count", - "step", NULL}; - static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, - LUA_GCCOLLECT, LUA_GCCOUNT, LUA_GCSTEP}; + static const char *const opts[] = {"stop", "restart", "collect", + "count", "step", "setstepmul", "setincmode", NULL}; + static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, + LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETSTEPMUL, LUA_GCSETINCMODE}; int o = luaL_findstring(luaL_optstring(L, 1, "collect"), opts); int ex = luaL_optint(L, 2, 0); luaL_argcheck(L, o >= 0, 1, "invalid option"); @@ -440,50 +440,6 @@ static int luaB_newproxy (lua_State *L) { } -/* -** {====================================================== -** `require' function -** ======================================================= -*/ - - -static const char *getpath (lua_State *L) { - /* try first `LUA_PATH' for compatibility */ - lua_getfield(L, LUA_GLOBALSINDEX, "LUA_PATH"); - if (!lua_isstring(L, -1)) { - lua_pop(L, 1); - lua_getfield(L, LUA_GLOBALSINDEX, "_PATH"); - } - if (!lua_isstring(L, -1)) - luaL_error(L, "global _PATH must be a string"); - return lua_tostring(L, -1); -} - - -static int luaB_require (lua_State *L) { - const char *name = luaL_checkstring(L, 1); - const char *fname; - lua_getfield(L, lua_upvalueindex(1), name); - if (lua_toboolean(L, -1)) /* is it there? */ - return 1; /* package is already loaded; return its result */ - /* else must load it; first mark it as loaded */ - lua_pushboolean(L, 1); - lua_setfield(L, lua_upvalueindex(1), name); /* _LOADED[name] = true */ - fname = luaL_searchpath(L, name, getpath(L)); - if (fname == NULL || luaL_loadfile(L, fname) != 0) - return luaL_error(L, "error loading package `%s' (%s)", name, - lua_tostring(L, -1)); - lua_pushvalue(L, 1); /* pass name as argument to module */ - lua_call(L, 1, 1); /* run loaded module */ - if (!lua_isnil(L, -1)) /* nil return? */ - lua_setfield(L, lua_upvalueindex(1), name); - lua_getfield(L, lua_upvalueindex(1), name); /* return _LOADED[name] */ - return 1; -} - -/* }====================================================== */ - - static const luaL_reg base_funcs[] = { {"error", luaB_error}, {"getmetatable", luaB_getmetatable}, @@ -656,11 +612,10 @@ static void auxopen (lua_State *L, const char *name, static void base_open (lua_State *L) { - const char *path; lua_pushvalue(L, LUA_GLOBALSINDEX); luaL_openlib(L, NULL, base_funcs, 0); /* open lib into global table */ lua_pushliteral(L, LUA_VERSION); - lua_setfield(L, LUA_GLOBALSINDEX, "_VERSION"); /* set global _VERSION */ + lua_setglobal(L, "_VERSION"); /* set global _VERSION */ /* `ipairs' and `pairs' need auxliliary functions as upvalues */ auxopen(L, "ipairs", luaB_ipairs, ipairsaux); auxopen(L, "pairs", luaB_pairs, luaB_next); @@ -671,21 +626,16 @@ static void base_open (lua_State *L) { lua_pushliteral(L, "kv"); lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ lua_pushcclosure(L, luaB_newproxy, 1); - lua_setfield(L, LUA_GLOBALSINDEX, "newproxy"); /* set global `newproxy' */ - /* `require' needs a table to keep loaded chunks */ + lua_setglobal(L, "newproxy"); /* set global `newproxy' */ + /* create register._LOADED to track loaded modules */ + lua_newtable(L); + lua_setfield(L, LUA_REGISTRYINDEX, "_LOADED"); + /* create register._PRELOAD to allow pre-loaded modules */ lua_newtable(L); - lua_pushvalue(L, -1); - lua_setglobal(L, "_LOADED"); - lua_pushcclosure(L, luaB_require, 1); - lua_setfield(L, LUA_GLOBALSINDEX, "require"); + lua_setfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); /* set global _G */ lua_pushvalue(L, LUA_GLOBALSINDEX); - lua_setfield(L, LUA_GLOBALSINDEX, "_G"); - /* set global _PATH */ - path = getenv(LUA_PATH); - if (path == NULL) path = LUA_PATH_DEFAULT; - lua_pushstring(L, path); - lua_setfield(L, LUA_GLOBALSINDEX, "_PATH"); + lua_setglobal(L, "_G"); } diff --git a/src/lib/ldblib.c b/src/lib/ldblib.c index 4ec5f393..36d647aa 100644 --- a/src/lib/ldblib.c +++ b/src/lib/ldblib.c @@ -1,5 +1,5 @@ /* -** $Id: ldblib.c,v 1.87 2004/08/13 18:02:36 roberto Exp $ +** $Id: ldblib.c,v 1.89 2004/11/17 12:02:41 roberto Exp $ ** Interface from Lua to its debug API ** See Copyright Notice in lua.h */ @@ -261,7 +261,7 @@ static int debug (lua_State *L) { if (fgets(buffer, sizeof(buffer), stdin) == 0 || strcmp(buffer, "cont\n") == 0) return 0; - if (luaL_loadbuffer(L, buffer, strlen(buffer), "=debug command") || + if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || lua_pcall(L, 0, 0, 0)) { fputs(lua_tostring(L, -1), stderr); fputs("\n", stderr); @@ -275,14 +275,15 @@ static int debug (lua_State *L) { #define LEVELS2 10 /* size of the second part of the stack */ static int errorfb (lua_State *L) { - int level = 1; /* skip level 0 (it's this function) */ + int level = 0; int firstpart = 1; /* still before eventual `...' */ int arg; lua_State *L1 = getthread(L, &arg); lua_Debug ar; + if (L == L1) level++; /* skip level 0 (it's this function) */ if (lua_gettop(L) == arg) lua_pushliteral(L, ""); - else if (!lua_isstring(L, arg+1)) return 1; /* no string message */ + else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */ else lua_pushliteral(L, "\n"); lua_pushliteral(L, "stack traceback:"); while (lua_getstack(L1, level++, &ar)) { diff --git a/src/lib/loadlib.c b/src/lib/loadlib.c index 8b98a2bf..63bc0bcc 100644 --- a/src/lib/loadlib.c +++ b/src/lib/loadlib.c @@ -1,31 +1,35 @@ /* -** $Id: loadlib.c,v 1.6 2004/04/30 20:13:38 roberto Exp $ +** $Id: loadlib.c,v 1.11 2004/11/19 15:52:12 roberto Exp $ ** Dynamic library loader for Lua ** See Copyright Notice in lua.h * -* This Lua library exports a single function, called loadlib, which is -* called from Lua as loadlib(lib,init), where lib is the full name of the -* library to be loaded (including the complete path) and init is the name -* of a function to be called after the library is loaded. Typically, this -* function will register other functions, thus making the complete library -* available to Lua. The init function is *not* automatically called by -* loadlib. Instead, loadlib returns the init function as a Lua function -* that the client can call when it thinks is appropriate. In the case of -* errors, loadlib returns nil and two strings describing the error. -* The first string is supplied by the operating system; it should be -* informative and useful for error messages. The second string is "open", -* "init", or "absent" to identify the error and is meant to be used for -* making decisions without having to look into the first string (whose -* format is system-dependent). -* -* This module contains an implementation of loadlib for Unix systems that -* have dlfcn, an implementation for Windows, and a stub for other systems. -* See the list at the end of this file for some links to available -* implementations of dlfcn and interfaces to other native dynamic loaders -* on top of which loadlib could be implemented. -* +* This Lua library exports a single function, called loadlib, which +* is called from Lua as loadlib(lib,init), where lib is the full +* name of the library to be loaded (including the complete path) and +* init is the name of a function to be called after the library is +* loaded. Typically, this function will register other functions, thus +* making the complete library available to Lua. The init function is +* *not* automatically called by loadlib. Instead, loadlib returns the +* init function as a Lua function that the client can call when it +* thinks is appropriate. In the case of errors, loadlib returns nil and +* two strings describing the error. The first string is supplied by +* the operating system; it should be informative and useful for error +* messages. The second string is "open", "init", or "absent" to identify +* the error and is meant to be used for making decisions without having +* to look into the first string (whose format is system-dependent). +* 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. See +* the list at the end of this file for some links to available +* implementations of dlfcn and interfaces to other native dynamic +* loaders on top of which loadlib could be implemented. */ + +#include <stdlib.h> +#include <string.h> + + #define loadlib_c #define LUA_LIB @@ -34,11 +38,14 @@ #include "lualib.h" -#undef LOADLIB +#define ERR_OPEN 1 +#define ERR_FUNCTION 2 + + +static void registerlib (lua_State *L, const void *lib); -#ifdef USE_DLOPEN -#define LOADLIB +#if defined(USE_DLOPEN) /* * This is an implementation of loadlib based on the dlfcn interface. * The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, @@ -48,53 +55,41 @@ #include <dlfcn.h> -static int loadlib(lua_State *L) +#define freelib dlclose + +static int loadlib(lua_State *L, const char *path, const char *init) { - const char *path=luaL_checkstring(L,1); - const char *init=luaL_checkstring(L,2); void *lib=dlopen(path,RTLD_NOW); if (lib!=NULL) { lua_CFunction f=(lua_CFunction) dlsym(lib,init); if (f!=NULL) { - lua_pushlightuserdata(L,lib); - lua_pushcclosure(L,f,1); - return 1; + registerlib(L, lib); + lua_pushcfunction(L,f); + return 0; } } - /* else return appropriate error messages */ - lua_pushnil(L); + /* else return appropriate error message */ lua_pushstring(L,dlerror()); - lua_pushstring(L,(lib!=NULL) ? "init" : "open"); - if (lib!=NULL) dlclose(lib); - return 3; + if (lib!=NULL) { + dlclose(lib); + return ERR_FUNCTION; /* error loading function */ + } + else return ERR_OPEN; /* error loading library */ } -#endif - - - -/* -** In Windows, default is to use dll; otherwise, default is not to use dll -*/ -#ifndef USE_DLL -#ifdef _WIN32 -#define USE_DLL 1 -#else -#define USE_DLL 0 -#endif -#endif -#if USE_DLL -#define LOADLIB +#elif defined(USE_DLL) /* * This is an implementation of loadlib for Windows using native functions. */ #include <windows.h> +#define freelib(lib) FreeLibrary((HINSTANCE)lib) + static void pusherror(lua_State *L) { int error=GetLastError(); @@ -106,61 +101,310 @@ static void pusherror(lua_State *L) lua_pushfstring(L,"system error %d\n",error); } -static int loadlib(lua_State *L) +static int loadlib(lua_State *L, const char *path, const char *init) { - const char *path=luaL_checkstring(L,1); - const char *init=luaL_checkstring(L,2); HINSTANCE lib=LoadLibrary(path); if (lib!=NULL) { lua_CFunction f=(lua_CFunction) GetProcAddress(lib,init); if (f!=NULL) { - lua_pushlightuserdata(L,lib); - lua_pushcclosure(L,f,1); + registerlib(L, lib); + lua_pushcfunction(L,f); return 1; } } - lua_pushnil(L); pusherror(L); - lua_pushstring(L,(lib!=NULL) ? "init" : "open"); - if (lib!=NULL) FreeLibrary(lib); - return 3; + if (lib!=NULL) { + FreeLibrary(lib); + return ERR_OPEN; + } + else return ERR_FUNCTION; } -#endif +/* Native Mac OS X / Darwin Implementation */ +#elif defined(USE_DYLD) + +#include <mach-o/dyld.h> + + +/* Mach cannot unload images (?) */ +#define freelib(lib) ((void)lib) + +static void pusherror (lua_State *L) +{ + const char *err_str; + const char *err_file; + NSLinkEditErrors err; + int err_num; + NSLinkEditError(&err, &err_num, &err_file, &err_str); + lua_pushstring(L, err_str); +} + +static int loadlib (lua_State *L, const char *path, const char *init) { + const struct mach_header *lib; + /* this would be a rare case, but prevents crashing if it happens */ + if(!_dyld_present()) { + lua_pushstring(L,"dyld not present."); + return ERR_OPEN; + } + lib = NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR); + if(lib != NULL) { + NSSymbol init_sym = NSLookupSymbolInImage(lib, init, + NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | + NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); + if(init_sym != NULL) { + lua_CFunction f = (lua_CFunction)NSAddressOfSymbol(init_sym); + registerlib(L, lib); + lua_pushcfunction(L,f); + return 0; + } + } + /* else an error ocurred */ + pusherror(L); + /* Can't unload image */ + return (lib != NULL) ? ERR_FUNCTION : ERR_OPEN; +} + -#ifndef LOADLIB -/* Fallback for other systems */ -/* -** Those systems support dlopen, so they should have defined USE_DLOPEN. -** The default (no)implementation gives them a special error message. -*/ -#if defined(linux) || defined(sun) || defined(sgi) || defined(BSD) || defined(_WIN32) -#define LOADLIB "`loadlib' not installed (check your Lua configuration)" #else -#define LOADLIB "`loadlib' not supported" -#endif +/* Fallback for other systems */ + +#define freelib(lib) ((void)lib) static int loadlib(lua_State *L) { + registerlib(L, NULL); /* to avoid warnings */ lua_pushnil(L); - lua_pushliteral(L,LOADLIB); + lua_pushliteral(L,"`loadlib' not supported"); lua_pushliteral(L,"absent"); return 3; } + #endif -LUALIB_API int luaopen_loadlib (lua_State *L) + +/* +** common code for all implementations: put a library into the registry +** so that, when Lua closes its state, the library's __gc metamethod +** will be called to unload the library. +*/ +static void registerlib (lua_State *L, const void *lib) +{ + const void **plib = (const void **)lua_newuserdata(L, sizeof(const void *)); + *plib = lib; + luaL_getmetatable(L, "_LOADLIB"); + lua_setmetatable(L, -2); + lua_pushboolean(L, 1); + lua_settable(L, LUA_REGISTRYINDEX); /* registry[lib] = true */ +} + +/* +** __gc tag method: calls library's `freelib' function with the lib +** handle +*/ +static int gctm (lua_State *L) { - lua_register(L,"loadlib",loadlib); + void *lib = *(void **)luaL_checkudata(L, 1, "_LOADLIB"); + freelib(lib); return 0; } + +static int loadlib1 (lua_State *L) { + const char *path=luaL_checkstring(L,1); + const char *init=luaL_checkstring(L,2); + int res = loadlib(L,path,init); + if (res == 0) /* no error? */ + return 1; /* function is at stack top */ + else { /* error */ + lua_pushnil(L); + lua_insert(L,-2); /* insert nil before error message */ + lua_pushstring(L, (res==ERR_OPEN)?"open":"init"); + return 3; + } +} + + + +/* +** {====================================================== +** `require' and `module' functions +** ======================================================= +*/ + + +static const char *loadLua (lua_State *L, const char *fname, const char *name) { + const char *path; + /* try first `LUA_PATH' for compatibility */ + lua_getglobal(L, "LUA_PATH"); + path = lua_tostring(L, -1); + if (!path) { + lua_pop(L, 1); + luaL_getfield(L, LUA_GLOBALSINDEX, "package.path"); + path = lua_tostring(L, -1); + } + if (path == NULL) + luaL_error(L, "`package.path' must be a string"); + fname = luaL_searchpath(L, fname, path); + if (fname == NULL) return path; /* 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)); + return NULL; /* library loaded successfully */ +} + + +static const char *loadC (lua_State *L, const char *fname, const char *name) { + const char *path; + const char *funcname; + luaL_getfield(L, LUA_GLOBALSINDEX, "package.cpath"); + path = lua_tostring(L, -1); + if (path == NULL) + luaL_error(L, "global _CPATH must be a string"); + fname = luaL_searchpath(L, fname, path); + if (fname == NULL) return path; /* library not found in this path */ + funcname = luaL_gsub(L, name, ".", ""); + funcname = lua_pushfstring(L, "%s%s", LUA_POF, funcname); + if (loadlib(L, fname, funcname) != 0) + luaL_error(L, "error loading package `%s' (%s)", name, lua_tostring(L, -1)); + return NULL; /* library loaded successfully */ +} + + +static int ll_require (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + lua_settop(L, 1); + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_getfield(L, 2, name); + if (lua_toboolean(L, -1)) /* is it there? */ + return 1; /* package is already loaded; return its result */ + /* else must load it; first mark it as loaded */ + lua_pushboolean(L, 1); + lua_setfield(L, 2, name); /* _LOADED[name] = true */ + /* check whether it is preloaded */ + lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); + lua_getfield(L, -1, name); + if (lua_isnil(L, -1)) { /* no preload function for that module? */ + const char *fname = luaL_gsub(L, name, ".", LUA_DIRSEP); + const char *cpath = loadC(L, fname, name); /* try a C module */ + if (cpath) { /* not found? */ + const char *path = loadLua(L, fname, name); /* try a Lua module */ + if (path) { /* yet not found? */ + lua_pushnil(L); + lua_setfield(L, 2, name); /* unmark _LOADED[name] */ + return luaL_error(L, "package `%s' not found\n" + " cpath: %s\n path: %s", + name, cpath, path); + } + } + } + lua_pushvalue(L, 1); /* pass name as argument to module */ + lua_call(L, 1, 1); /* run loaded module */ + if (!lua_isnil(L, -1)) /* non-nil return? */ + lua_setfield(L, 2, name); /* update _LOADED[name] with returned value */ + lua_getfield(L, 2, name); /* return _LOADED[name] */ + return 1; +} + + +static void setfenv (lua_State *L) { + lua_Debug ar; + lua_getstack(L, 1, &ar); + lua_getinfo(L, "f", &ar); + lua_pushvalue(L, -2); + lua_setfenv(L, -2); +} + + +static int ll_module (lua_State *L) { + const char *modname = luaL_checkstring(L, 1); + const char *dot; + lua_settop(L, 1); + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + /* try to find given table */ + luaL_getfield(L, LUA_GLOBALSINDEX, modname); + if (lua_isnil(L, -1)) { /* not found? */ + lua_pop(L, 1); /* remove previous result */ + lua_newtable(L); /* create it */ + /* register it with given name */ + lua_pushvalue(L, -1); + luaL_setfield(L, LUA_GLOBALSINDEX, modname); + } + else if (!lua_istable(L, -1)) + return luaL_error(L, "name conflict for module `%s'", modname); + /* check whether table already has a _NAME field */ + lua_getfield(L, -1, "_NAME"); + if (!lua_isnil(L, -1)) /* is table an initialized module? */ + lua_pop(L, 1); + else { /* no; initialize it */ + lua_pop(L, 1); + lua_newtable(L); /* create new metatable */ + lua_pushvalue(L, LUA_GLOBALSINDEX); + lua_setfield(L, -2, "__index"); /* mt.__index = _G */ + lua_setmetatable(L, -2); + lua_pushstring(L, modname); + lua_setfield(L, -2, "_NAME"); + dot = strrchr(modname, '.'); /* look for last dot in module name */ + if (dot == NULL) dot = modname; + else dot++; + /* set _PACKAGE as package name (full module name minus last part) */ + lua_pushlstring(L, modname, dot - modname); + lua_setfield(L, -2, "_PACKAGE"); + } + lua_pushvalue(L, -1); + lua_setfield(L, 2, modname); /* _LOADED[modname] = new table */ + setfenv(L); + return 0; +} + + +/* }====================================================== */ + + +static const luaL_reg ll_funcs[] = { + {"loadlib", loadlib1}, + {"require", ll_require}, + {"module", ll_module}, + {NULL, NULL} +}; + + + +LUALIB_API int luaopen_loadlib (lua_State *L) { + const char *path; + /* create new type _LOADLIB */ + luaL_newmetatable(L, "_LOADLIB"); + lua_pushcfunction(L, gctm); + lua_setfield(L, -2, "__gc"); + /* create `package' table */ + lua_newtable(L); + lua_pushvalue(L, -1); + lua_setglobal(L, "package"); + /* set field `path' */ + path = getenv(LUA_PATH); + if (path == NULL) path = LUA_PATH_DEFAULT; + lua_pushstring(L, path); + lua_setfield(L, -2, "path"); + /* set field `cpath' */ + path = getenv(LUA_CPATH); + if (path == NULL) path = LUA_CPATH_DEFAULT; + lua_pushstring(L, path); + lua_setfield(L, -2, "cpath"); + /* set field `loaded' */ + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_setfield(L, -2, "loaded"); + /* set field `preload' */ + lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); + lua_setfield(L, -2, "preload"); + lua_pushvalue(L, LUA_GLOBALSINDEX); + luaL_openlib(L, NULL, ll_funcs, 0); /* open lib into global table */ + return 1; +} + /* * Here are some links to available implementations of dlfcn and * interfaces to other native dynamic loaders on top of which loadlib @@ -179,9 +423,6 @@ LUALIB_API int luaopen_loadlib (lua_State *L) * Macintosh, Windows * http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html * -* Mac OS X/Darwin -* http://www.opendarwin.org/projects/dlcompat/ -* * GLIB has wrapper code for BeOS, OS2, Unix and Windows * http://cvs.gnome.org/lxr/source/glib/gmodule/ * diff --git a/src/lib/loslib.c b/src/lib/loslib.c index c5726cfe..4f1d2d03 100644 --- a/src/lib/loslib.c +++ b/src/lib/loslib.c @@ -1,5 +1,5 @@ /* -** $Id: loslib.c,v 1.2 2004/08/05 19:30:37 roberto Exp $ +** $Id: loslib.c,v 1.3 2004/10/08 18:57:16 roberto Exp $ ** Standard Operating System library ** See Copyright Notice in lua.h */ @@ -20,7 +20,7 @@ #include "lualib.h" -static int pushresult (lua_State *L, int i, const char *filename) { +static int os_pushresult (lua_State *L, int i, const char *filename) { if (i) { lua_pushboolean(L, 1); return 1; @@ -45,14 +45,14 @@ static int io_execute (lua_State *L) { static int io_remove (lua_State *L) { const char *filename = luaL_checkstring(L, 1); - return pushresult(L, remove(filename) == 0, filename); + return os_pushresult(L, remove(filename) == 0, filename); } static int io_rename (lua_State *L) { const char *fromname = luaL_checkstring(L, 1); const char *toname = luaL_checkstring(L, 2); - return pushresult(L, rename(fromname, toname) == 0, fromname); + return os_pushresult(L, rename(fromname, toname) == 0, fromname); } diff --git a/src/lib/lstrlib.c b/src/lib/lstrlib.c index 7fa205c0..a9c002fb 100644 --- a/src/lib/lstrlib.c +++ b/src/lib/lstrlib.c @@ -1,5 +1,5 @@ /* -** $Id: lstrlib.c,v 1.106 2004/08/09 13:30:33 roberto Exp $ +** $Id: lstrlib.c,v 1.109 2004/12/01 15:46:06 roberto Exp $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ @@ -24,8 +24,6 @@ #define uchar(c) ((unsigned char)(c)) -typedef lua_Integer sint32; /* a signed version for size_t */ - static int str_len (lua_State *L) { size_t l; @@ -35,19 +33,19 @@ static int str_len (lua_State *L) { } -static sint32 posrelat (sint32 pos, size_t len) { +static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) { /* relative string position: negative means back from end */ - return (pos>=0) ? pos : (sint32)len+pos+1; + return (pos>=0) ? pos : (ptrdiff_t)len+pos+1; } static int str_sub (lua_State *L) { size_t l; const char *s = luaL_checklstring(L, 1, &l); - sint32 start = posrelat(luaL_checkinteger(L, 2), l); - sint32 end = posrelat(luaL_optinteger(L, 3, -1), l); + ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l); + ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l); if (start < 1) start = 1; - if (end > (sint32)l) end = (sint32)l; + if (end > (ptrdiff_t)l) end = (ptrdiff_t)l; if (start <= end) lua_pushlstring(L, s+start-1, end-start+1); else lua_pushliteral(L, ""); @@ -107,8 +105,8 @@ static int str_rep (lua_State *L) { static int str_byte (lua_State *L) { size_t l; const char *s = luaL_checklstring(L, 1, &l); - sint32 posi = posrelat(luaL_optinteger(L, 2, 1), l); - sint32 pose = posrelat(luaL_optinteger(L, 3, posi), l); + ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l); + ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l); int n, i; if (posi <= 0) posi = 1; if ((size_t)pose > l) pose = l; @@ -173,7 +171,7 @@ typedef struct MatchState { int level; /* total number of captures (finished or unfinished) */ struct { const char *init; - sint32 len; + ptrdiff_t len; } capture[MAX_CAPTURES]; } MatchState; @@ -198,7 +196,7 @@ static int capture_to_close (MatchState *ms) { } -static const char *luaI_classend (MatchState *ms, const char *p) { +static const char *classend (MatchState *ms, const char *p) { switch (*p++) { case ESC: { if (*p == '\0') @@ -250,7 +248,7 @@ static int matchbracketclass (int c, const char *p, const char *ec) { while (++p < ec) { if (*p == ESC) { p++; - if (match_class(c, *p)) + if (match_class(c, uchar(*p))) return sig; } else if ((*(p+1) == '-') && (p+2 < ec)) { @@ -264,10 +262,10 @@ static int matchbracketclass (int c, const char *p, const char *ec) { } -static int luaI_singlematch (int c, const char *p, const char *ep) { +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, *(p+1)); + case ESC: return match_class(c, uchar(*(p+1))); case '[': return matchbracketclass(c, p, ep-1); default: return (uchar(*p) == c); } @@ -299,8 +297,8 @@ static const char *matchbalance (MatchState *ms, const char *s, static const char *max_expand (MatchState *ms, const char *s, const char *p, const char *ep) { - sint32 i = 0; /* counts maximum expand for item */ - while ((s+i)<ms->src_end && luaI_singlematch(uchar(*(s+i)), p, ep)) + ptrdiff_t i = 0; /* counts maximum expand for item */ + while ((s+i)<ms->src_end && singlematch(uchar(*(s+i)), p, ep)) i++; /* keeps trying to match with the maximum repetitions */ while (i>=0) { @@ -318,7 +316,7 @@ static const char *min_expand (MatchState *ms, const char *s, const char *res = match(ms, s, ep+1); if (res != NULL) return res; - else if (s<ms->src_end && luaI_singlematch(uchar(*s), p, ep)) + else if (s<ms->src_end && singlematch(uchar(*s), p, ep)) s++; /* try with one more repetition */ else return NULL; } @@ -385,7 +383,7 @@ static const char *match (MatchState *ms, const char *s, const char *p) { p += 2; if (*p != '[') luaL_error(ms->L, "missing `[' after `%%f' in pattern"); - ep = luaI_classend(ms, p); /* points to what is next */ + ep = classend(ms, p); /* points to what is next */ previous = (s == ms->src_init) ? '\0' : *(s-1); if (matchbracketclass(uchar(previous), p, ep-1) || !matchbracketclass(uchar(*s), p, ep-1)) return NULL; @@ -393,7 +391,7 @@ static const char *match (MatchState *ms, const char *s, const char *p) { } default: { if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */ - s = match_capture(ms, s, *(p+1)); + s = match_capture(ms, s, uchar(*(p+1))); if (s == NULL) return NULL; p+=2; goto init; /* else return match(ms, s, p+2) */ } @@ -410,8 +408,8 @@ static const char *match (MatchState *ms, const char *s, const char *p) { else goto dflt; } default: dflt: { /* it is a pattern item */ - const char *ep = luaI_classend(ms, p); /* points to what is next */ - int m = s<ms->src_end && luaI_singlematch(uchar(*s), p, ep); + const char *ep = classend(ms, p); /* points to what is next */ + int m = s<ms->src_end && singlematch(uchar(*s), p, ep); switch (*ep) { case '?': { /* optional */ const char *res; @@ -490,9 +488,9 @@ static int str_find (lua_State *L) { size_t l1, l2; const char *s = luaL_checklstring(L, 1, &l1); const char *p = luaL_checklstring(L, 2, &l2); - sint32 init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1; + ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1; if (init < 0) init = 0; - else if ((size_t)(init) > l1) init = (sint32)l1; + else if ((size_t)(init) > l1) init = (ptrdiff_t)l1; if (lua_toboolean(L, 4) || /* explicit request? */ strpbrk(p, SPECIALS) == NULL) { /* or no special characters? */ /* do a plain search */ @@ -642,7 +640,7 @@ static int str_gsub (lua_State *L) { #define MAX_FORMAT 20 -static void luaI_addquoted (lua_State *L, luaL_Buffer *b, int arg) { +static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { size_t l; const char *s = luaL_checklstring(L, arg, &l); luaL_putchar(b, '"'); @@ -726,7 +724,7 @@ static int str_format (lua_State *L) { break; } case 'q': { - luaI_addquoted(L, &b, arg); + addquoted(L, &b, arg); continue; /* skip the `addsize' at the end */ } case 's': { @@ -1,5 +1,5 @@ /* -** $Id: llex.c,v 2.3 2004/04/30 20:13:38 roberto Exp $ +** $Id: llex.c,v 2.9 2004/12/03 20:54:12 roberto Exp $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ @@ -26,34 +26,45 @@ #define next(ls) (ls->current = zgetc(ls->z)) -#define save(ls,c) { \ - Mbuffer *b = ls->buff; \ - if (b->n + 1 > b->buffsize) \ - luaZ_resizebuffer(ls->L, b, ((b->buffsize*2) + LUA_MINBUFFER)); \ - b->buffer[b->n++] = cast(char, c); } - #define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') /* ORDER RESERVED */ -static const char *const token2string [] = { +const char *const luaX_tokens [] = { "and", "break", "do", "else", "elseif", "end", "false", "for", "function", "if", "in", "local", "nil", "not", "or", "repeat", - "return", "then", "true", "until", "while", "*name", + "return", "then", "true", "until", "while", "..", "...", "==", ">=", "<=", "~=", - "*number", "*string", "<eof>" + "<number>", "<name>", "<string>", "<eof>", + NULL }; +#define save_and_next(ls) (save(ls, ls->current), next(ls)) + + +static void save (LexState *ls, int c) { + Mbuffer *b = ls->buff; + if (b->n + 1 > b->buffsize) { + size_t newsize; + if (b->buffsize >= MAX_SIZET/2) + luaX_lexerror(ls, "lexical element too long", 0); + newsize = b->buffsize * 2; + luaZ_resizebuffer(ls->L, b, newsize); + } + b->buffer[b->n++] = cast(char, c); +} + + void luaX_init (lua_State *L) { int i; for (i=0; i<NUM_RESERVED; i++) { - TString *ts = luaS_new(L, token2string[i]); + TString *ts = luaS_new(L, luaX_tokens[i]); luaS_fix(ts); /* reserved words are never collected */ - lua_assert(strlen(token2string[i])+1 <= TOKEN_LEN); + lua_assert(strlen(luaX_tokens[i])+1 <= TOKEN_LEN); ts->tsv.reserved = cast(lu_byte, i+1); /* reserved word */ } } @@ -64,12 +75,12 @@ void luaX_init (lua_State *L) { const char *luaX_token2str (LexState *ls, int token) { if (token < FIRST_RESERVED) { - lua_assert(token == (unsigned char)token); + lua_assert(token == cast(unsigned char, token)); return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) : luaO_pushfstring(ls->L, "%c", token); } else - return token2string[token-FIRST_RESERVED]; + return luaX_tokens[token-FIRST_RESERVED]; } @@ -130,6 +141,7 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { ls->linenumber = 1; ls->lastline = 1; ls->source = source; + luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ next(ls); /* read first char */ } @@ -143,12 +155,6 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { -static void save_and_next (LexState *ls) { - save(ls, ls->current); - next(ls); -} - - /* LUA_NUMBER */ static void read_numeral (LexState *ls, SemInfo *seminfo) { @@ -181,12 +187,12 @@ static void read_numeral (LexState *ls, SemInfo *seminfo) { } -static int skip_ast (LexState *ls) { +static int skip_sep (LexState *ls) { int count = 0; int s = ls->current; lua_assert(s == '[' || s == ']'); save_and_next(ls); - while (ls->current == '*') { + while (ls->current == '=') { save_and_next(ls); count++; } @@ -194,7 +200,7 @@ static int skip_ast (LexState *ls) { } -static void read_long_string (LexState *ls, SemInfo *seminfo, int ast) { +static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { int cont = 0; save_and_next(ls); /* skip 2nd `[' */ if (currIsNewline(ls)) /* string starts with a newline? */ @@ -206,13 +212,13 @@ static void read_long_string (LexState *ls, SemInfo *seminfo, int ast) { "unfinished long comment", TK_EOS); break; /* to avoid warnings */ case '[': - if (skip_ast(ls) == ast) { + if (skip_sep(ls) == sep) { save_and_next(ls); /* skip 2nd `[' */ cont++; } continue; case ']': - if (skip_ast(ls) == ast) { + if (skip_sep(ls) == sep) { save_and_next(ls); /* skip 2nd `]' */ if (cont-- == 0) goto endloop; } @@ -229,8 +235,8 @@ static void read_long_string (LexState *ls, SemInfo *seminfo, int ast) { } } endloop: if (seminfo) - seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + ast), - luaZ_bufflen(ls->buff) - 2*(2 + ast)); + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), + luaZ_bufflen(ls->buff) - 2*(2 + sep)); } @@ -305,10 +311,10 @@ int luaX_lex (LexState *ls, SemInfo *seminfo) { /* else is a comment */ next(ls); if (ls->current == '[') { - int ast = skip_ast(ls); - luaZ_resetbuffer(ls->buff); /* `skip_ast' may dirty the buffer */ - if (ast >= 0) { - read_long_string(ls, NULL, ast); /* long comment */ + int sep = skip_sep(ls); + luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ + if (sep >= 0) { + read_long_string(ls, NULL, sep); /* long comment */ luaZ_resetbuffer(ls->buff); continue; } @@ -319,12 +325,12 @@ int luaX_lex (LexState *ls, SemInfo *seminfo) { continue; } case '[': { - int ast = skip_ast(ls); - if (ast >= 0) { - read_long_string(ls, seminfo, ast); + int sep = skip_sep(ls); + if (sep >= 0) { + read_long_string(ls, seminfo, sep); return TK_STRING; } - else if (ast == -1) return '['; + else if (sep == -1) return '['; else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING); } case '=': { @@ -1,5 +1,5 @@ /* -** $Id: llex.h,v 1.50 2004/03/12 19:53:56 roberto Exp $ +** $Id: llex.h,v 1.52 2004/12/03 20:54:12 roberto Exp $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ @@ -28,14 +28,18 @@ enum RESERVED { TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, /* other terminal symbols */ - TK_NAME, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER, - TK_STRING, TK_EOS + TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER, + TK_NAME, TK_STRING, TK_EOS }; /* number of reserved words */ #define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) +/* array with token `names' */ +extern const char *const luaX_tokens []; + + typedef union { lua_Number r; TString *ts; diff --git a/src/llimits.h b/src/llimits.h index 95a51a0b..6be658f0 100644 --- a/src/llimits.h +++ b/src/llimits.h @@ -1,5 +1,5 @@ /* -** $Id: llimits.h,v 1.60 2004/09/10 17:30:46 roberto Exp $ +** $Id: llimits.h,v 1.61 2004/11/24 18:55:56 roberto Exp $ ** Limits, basic types, and some other `installation-dependent' definitions ** See Copyright Notice in lua.h */ @@ -18,22 +18,9 @@ typedef LUA_UINT32 lu_int32; -typedef LUA_INT32 l_int32; +typedef LU_MEM lu_mem; - -/* -** an unsigned integer big enough to count the total memory used by Lua; -** it should be at least as large as `size_t' -*/ -typedef lu_int32 lu_mem; - - -/* -** a signed integer big enough to count the total memory used by Lua; -** it should be at least as large as `size_t' -*/ -typedef l_int32 l_mem; -#define MAXLMEM LUA_MAXINT32 +typedef L_MEM l_mem; @@ -43,6 +30,8 @@ typedef unsigned char lu_byte; #define MAX_SIZET ((size_t)(~(size_t)0)-2) +#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) + #define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ @@ -51,7 +40,7 @@ typedef unsigned char lu_byte; ** this is for hashing only; there is no problem if the integer ** cannot hold the whole pointer value */ -#define IntPoint(p) ((unsigned int)(p)) +#define IntPoint(p) ((unsigned int)(lu_mem)(p)) @@ -1,5 +1,5 @@ /* -** $Id: lmem.c,v 1.65 2004/08/30 13:44:44 roberto Exp $ +** $Id: lmem.c,v 1.67 2004/12/01 15:46:18 roberto Exp $ ** Interface to Memory Manager ** See Copyright Notice in lua.h */ @@ -43,36 +43,39 @@ #define MINSIZEARRAY 4 -void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems, - int limit, const char *errormsg) { +void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, + int limit, const char *errormsg) { void *newblock; int newsize; if (*size >= limit/2) { /* cannot double it? */ - if (*size >= limit - MINSIZEARRAY) /* try something smaller... */ + if (*size >= limit) /* cannot grow even a little? */ luaG_runerror(L, errormsg); - newsize = limit; /* still have at least MINSIZEARRAY free places */ + newsize = limit; /* still have at least one free place */ } else { newsize = (*size)*2; if (newsize < MINSIZEARRAY) newsize = MINSIZEARRAY; /* minimum size */ } - newblock = luaM_realloc(L, block, - cast(lu_mem, *size)*cast(lu_mem, size_elems), - cast(lu_mem, newsize)*cast(lu_mem, size_elems)); + newblock = luaM_reallocv(L, block, *size, newsize, size_elems); *size = newsize; /* update only when everything else is OK */ return newblock; } +void *luaM_toobig (lua_State *L) { + luaG_runerror(L, "memory allocation error: block too big"); + return NULL; /* to avoid warnings */ +} + + + /* ** generic allocation routine. */ -void *luaM_realloc (lua_State *L, void *block, lu_mem osize, lu_mem nsize) { +void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { global_State *g = G(L); lua_assert((osize == 0) == (block == NULL)); - if (nsize >= MAX_SIZET) - luaG_runerror(L, "memory allocation error: block too big"); block = (*g->realloc)(g->ud, block, osize, nsize); if (block == NULL && nsize > 0) luaD_throw(L, LUA_ERRMEM); @@ -1,5 +1,5 @@ /* -** $Id: lmem.h,v 1.26 2002/05/01 20:40:42 roberto Exp $ +** $Id: lmem.h,v 1.29 2004/12/01 15:46:18 roberto Exp $ ** Interface to Memory Manager ** See Copyright Notice in lua.h */ @@ -16,28 +16,34 @@ #define MEMERRMSG "not enough memory" -void *luaM_realloc (lua_State *L, void *oldblock, lu_mem oldsize, lu_mem size); +void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, size_t size); -void *luaM_growaux (lua_State *L, void *block, int *size, int size_elem, - int limit, const char *errormsg); +void *luaM_toobig (lua_State *L); -#define luaM_free(L, b, s) luaM_realloc(L, (b), (s), 0) -#define luaM_freelem(L, b) luaM_realloc(L, (b), sizeof(*(b)), 0) -#define luaM_freearray(L, b, n, t) luaM_realloc(L, (b), \ - cast(lu_mem, n)*cast(lu_mem, sizeof(t)), 0) +#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)) -#define luaM_malloc(L, t) luaM_realloc(L, NULL, 0, (t)) -#define luaM_new(L, t) cast(t *, luaM_malloc(L, sizeof(t))) -#define luaM_newvector(L, n,t) cast(t *, luaM_malloc(L, \ - cast(lu_mem, n)*cast(lu_mem, sizeof(t)))) + +void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elem, + int limit, const char *errormsg); + +#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) +#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) +#define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t)) + +#define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t)) +#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) +#define luaM_newvector(L,n,t) \ + cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) #define luaM_growvector(L,v,nelems,size,t,limit,e) \ - if (((nelems)+1) > (size)) \ - ((v)=cast(t *, luaM_growaux(L,v,&(size),sizeof(t),limit,e))) + if ((nelems)+1 > (size)) \ + ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) #define luaM_reallocvector(L, v,oldn,n,t) \ - ((v)=cast(t *, luaM_realloc(L, v,cast(lu_mem, oldn)*cast(lu_mem, sizeof(t)), \ - cast(lu_mem, n)*cast(lu_mem, sizeof(t))))) + ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) #endif diff --git a/src/lobject.c b/src/lobject.c index 1e24bb5d..154a0faf 100644 --- a/src/lobject.c +++ b/src/lobject.c @@ -1,5 +1,5 @@ /* -** $Id: lobject.c,v 2.4 2004/07/09 16:01:38 roberto Exp $ +** $Id: lobject.c,v 2.7 2004/11/24 19:16:03 roberto Exp $ ** Some generic functions over Lua objects ** See Copyright Notice in lua.h */ @@ -23,7 +23,7 @@ -const TValue luaO_nilobject = {LUA_TNIL, {NULL}}; +const TValue luaO_nilobject = {{NULL}, LUA_TNIL}; /* @@ -31,12 +31,21 @@ const TValue luaO_nilobject = {LUA_TNIL, {NULL}}; ** (mmmmmxxx), where the real value is (xxx) * 2^(mmmmm) */ int luaO_int2fb (unsigned int x) { - int m = 0; /* mantissa */ - while (x >= (1<<3)) { + int e = 0; /* expoent */ + while (x >= 16) { x = (x+1) >> 1; - m++; + e++; } - return (m << 3) | cast(int, x); + if (x < 8) return x; + else return ((e+1) << 3) | (cast(int, x) - 8); +} + + +/* converts back */ +int luaO_fb2int (int x) { + int e = (x >> 3) & 31; + if (e == 0) return x; + else return ((x & 7)+8) << (e - 1); } @@ -80,7 +89,7 @@ int luaO_str2d (const char *s, lua_Number *result) { char *endptr; lua_Number res = lua_str2number(s, &endptr); if (endptr == s) return 0; /* no conversion */ - while (isspace((unsigned char)(*endptr))) endptr++; + while (isspace(cast(unsigned char, *endptr))) endptr++; if (*endptr != '\0') return 0; /* invalid trailing characters? */ *result = res; return 1; diff --git a/src/lobject.h b/src/lobject.h index 4b6a684b..56c0fe8a 100644 --- a/src/lobject.h +++ b/src/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 2.5 2004/05/31 18:51:50 roberto Exp $ +** $Id: lobject.h,v 2.8 2004/12/04 18:10:22 roberto Exp $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -25,6 +25,7 @@ */ #define LUA_TPROTO (NUM_TAGS+1) #define LUA_TUPVAL (NUM_TAGS+2) +#define LUA_TDEADKEY (NUM_TAGS+3) /* @@ -64,9 +65,11 @@ typedef union { /* ** Tagged Values */ + +#define TValuefields Value value; int tt + typedef struct lua_TValue { - int tt; - Value value; + TValuefields; } TValue; @@ -158,7 +161,7 @@ typedef struct lua_TValue { #define setobj(L,obj1,obj2) \ { const TValue *o2=(obj2); TValue *o1=(obj1); \ - o1->tt=o2->tt; o1->value = o2->value; \ + o1->value = o2->value; o1->tt=o2->tt; \ checkliveness(G(L),o1); } @@ -308,10 +311,15 @@ typedef union Closure { ** Tables */ +typedef struct TKey { + TValuefields; + struct Node *next; /* for chaining */ +} TKey; + + typedef struct Node { - TValue i_key; TValue i_val; - struct Node *next; /* for chaining */ + TKey i_key; } Node; @@ -345,7 +353,7 @@ extern const TValue luaO_nilobject; int luaO_log2 (unsigned int x); int luaO_int2fb (unsigned int x); -#define fb2int(x) (((x) & 7) << ((x) >> 3)) +int luaO_fb2int (int x); int luaO_rawequalObj (const TValue *t1, const TValue *t2); int luaO_str2d (const char *s, lua_Number *result); diff --git a/src/lopcodes.c b/src/lopcodes.c index 87ec8939..24cd31d5 100644 --- a/src/lopcodes.c +++ b/src/lopcodes.c @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.c,v 1.28 2004/07/16 13:15:32 roberto Exp $ +** $Id: lopcodes.c,v 1.30 2004/12/02 12:59:10 roberto Exp $ ** See Copyright Notice in lua.h */ @@ -15,7 +15,7 @@ /* ORDER OP */ -const char *const luaP_opnames[NUM_OPCODES] = { +const char *const luaP_opnames[NUM_OPCODES+1] = { "MOVE", "LOADK", "LOADBOOL", @@ -49,10 +49,10 @@ const char *const luaP_opnames[NUM_OPCODES] = { "TFORLOOP", "TFORPREP", "SETLIST", - "SETLISTO", "CLOSE", "CLOSURE", - "VARARG" + "VARARG", + NULL }; @@ -92,8 +92,7 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = { ,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, OpArgN, iABx) /* OP_SETLIST */ - ,opmode(0, 0, OpArgU, OpArgN, iABx) /* OP_SETLISTO */ + ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ diff --git a/src/lopcodes.h b/src/lopcodes.h index d3429a59..dfbcaffe 100644 --- a/src/lopcodes.h +++ b/src/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.111 2004/08/04 20:18:13 roberto Exp $ +** $Id: lopcodes.h,v 1.114 2004/12/02 12:59:10 roberto Exp $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -198,8 +198,7 @@ OP_TFORLOOP,/* A C R(A+2), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); OP_TFORPREP,/* A sBx if type(R(A)) == table then R(A+1):=R(A), R(A):=next; pc+=sBx */ -OP_SETLIST,/* A Bx R(A)[Bx-Bx%FPF+i] := R(A+i), 1 <= i <= Bx%FPF+1 */ -OP_SETLISTO,/* A Bx */ +OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */ OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/ OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ @@ -219,11 +218,15 @@ OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. (*) In OP_VARARG, if (B == 0) then use actual number of varargs and - set top (like in OP_CALL). + set top (like in OP_CALL with C == 0). (*) In OP_RETURN, if (B == 0) then return up to `top' - (*) For comparisons, B specifies what conditions the test should accept. + (*) In OP_SETLIST, if (B == 0) then B = `top'; + if (C == 0) then next `instruction' is real C + + (*) For comparisons, A specifies what condition the test should accept + (true or false). (*) All `skips' (pc++) assume that next instruction is a jump ===========================================================================*/ @@ -254,12 +257,11 @@ extern const lu_byte luaP_opmodes[NUM_OPCODES]; #define testTMode(m) (luaP_opmodes[m] & (1 << 7)) -extern const char *const luaP_opnames[NUM_OPCODES]; /* opcode names */ +extern const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */ /* number of list items to accumulate before a SETLIST instruction */ -/* (must be a power of 2) */ -#define LFIELDS_PER_FLUSH 32 +#define LFIELDS_PER_FLUSH 50 #endif diff --git a/src/lparser.c b/src/lparser.c index c0fc1579..b40cf7c7 100644 --- a/src/lparser.c +++ b/src/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 2.5 2004/05/31 18:51:50 roberto Exp $ +** $Id: lparser.c,v 2.10 2004/12/03 20:50:25 roberto Exp $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -31,7 +31,7 @@ #define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) -#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) luaY_errorlimit(fs,l,m) +#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) @@ -90,7 +90,7 @@ static void error_expected (LexState *ls, int token) { } -static void luaY_errorlimit (FuncState *fs, int limit, const char *what) { +static void errorlimit (FuncState *fs, int limit, const char *what) { 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", @@ -133,7 +133,7 @@ static void check_match (LexState *ls, int what, int who, int where) { static TString *str_checkname (LexState *ls) { TString *ts; - check_condition(ls, (ls->t.token == TK_NAME), "<name> expected"); + if (ls->t.token != TK_NAME) error_expected(ls, TK_NAME); ts = ls->t.seminfo.ts; next(ls); return ts; @@ -157,7 +157,7 @@ static void checkname(LexState *ls, expdesc *e) { } -static int luaI_registerlocalvar (LexState *ls, TString *varname) { +static int registerlocalvar (LexState *ls, TString *varname) { FuncState *fs = ls->fs; Proto *f = fs->f; int oldsize = f->sizelocvars; @@ -177,8 +177,7 @@ static int luaI_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"); - fs->actvar[fs->nactvar+n] = cast(unsigned short, - luaI_registerlocalvar(ls, name)); + fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name)); } @@ -413,7 +412,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { /*============================================================*/ -static void luaY_field (LexState *ls, expdesc *v) { +static void field (LexState *ls, expdesc *v) { /* field -> ['.' | ':'] NAME */ FuncState *fs = ls->fs; expdesc key; @@ -424,7 +423,7 @@ static void luaY_field (LexState *ls, expdesc *v) { } -static void luaY_index (LexState *ls, expdesc *v) { +static void yindex (LexState *ls, expdesc *v) { /* index -> '[' expr ']' */ next(ls); /* skip the '[' */ expr(ls, v); @@ -460,7 +459,7 @@ static void recfield (LexState *ls, struct ConsControl *cc) { checkname(ls, &key); } else /* ls->t.token == '[' */ - luaY_index(ls, &key); + yindex(ls, &key); check(ls, '='); luaK_exp2RK(fs, &key); expr(ls, &val); @@ -475,9 +474,8 @@ static void closelistfield (FuncState *fs, struct ConsControl *cc) { luaK_exp2nextreg(fs, &cc->v); cc->v.k = VVOID; if (cc->tostore == LFIELDS_PER_FLUSH) { - luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1); /* flush */ + luaK_setlist(fs, cc->t->info, cc->na, cc->tostore); /* flush */ cc->tostore = 0; /* no more items pending */ - fs->freereg = cc->t->info + 1; /* free registers */ } } @@ -486,15 +484,14 @@ static void lastlistfield (FuncState *fs, struct ConsControl *cc) { if (cc->tostore == 0) return; if (hasmultret(cc->v.k)) { luaK_setmultret(fs, &cc->v); - luaK_codeABx(fs, OP_SETLISTO, cc->t->info, cc->na-1); + luaK_setlist(fs, cc->t->info, cc->na, LUA_MULTRET); cc->na--; /* do not count last expression (unknown number of elements) */ } else { if (cc->v.k != VVOID) luaK_exp2nextreg(fs, &cc->v); - luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1); + luaK_setlist(fs, cc->t->info, cc->na, cc->tostore); } - fs->freereg = cc->t->info + 1; /* free registers */ } @@ -703,13 +700,13 @@ static void primaryexp (LexState *ls, expdesc *v) { for (;;) { switch (ls->t.token) { case '.': { /* field */ - luaY_field(ls, v); + field(ls, v); break; } case '[': { /* `[' exp1 `]' */ expdesc key; luaK_exp2anyreg(fs, v); - luaY_index(ls, &key); + yindex(ls, &key); luaK_indexed(fs, v, &key); break; } @@ -1213,10 +1210,10 @@ static int funcname (LexState *ls, expdesc *v) { int needself = 0; singlevar(ls, v, 1); while (ls->t.token == '.') - luaY_field(ls, v); + field(ls, v); if (ls->t.token == ':') { needself = 1; - luaY_field(ls, v); + field(ls, v); } return needself; } diff --git a/src/lstate.c b/src/lstate.c index 9f55f997..dfd35be6 100644 --- a/src/lstate.c +++ b/src/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 2.14 2004/09/15 20:39:42 roberto Exp $ +** $Id: lstate.c,v 2.18 2004/12/06 17:53:42 roberto Exp $ ** Global State ** See Copyright Notice in lua.h */ @@ -79,7 +79,7 @@ static void f_luaopen (lua_State *L, void *ud) { Udata *u; /* head of udata list */ global_State *g = G(L); UNUSED(ud); - u = cast(Udata *, luaM_malloc(L, sizeudata(0))); + u = luaM_new(L, Udata); u->uv.len = 0; u->uv.metatable = NULL; g->firstudata = obj2gco(u); @@ -155,7 +155,7 @@ void luaE_freethread (lua_State *L, lua_State *L1) { luaF_close(L1, L1->stack); /* close all upvalues for this thread */ lua_assert(L1->openupval == NULL); freestack(L, L1); - luaM_free(L, fromstate(L1), state_size(lua_State)); + luaM_freemem(L, fromstate(L1), state_size(lua_State)); } @@ -191,8 +191,10 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { g->tmudata = NULL; setnilvalue(gkey(g->dummynode)); setnilvalue(gval(g->dummynode)); - g->dummynode->next = NULL; + gnext(g->dummynode) = NULL; g->totalbytes = sizeof(LG); + g->stepmul = STEPMUL; + g->incgc = 1; if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { /* memory allocation error: free partial state */ close_state(L); diff --git a/src/lstate.h b/src/lstate.h index d7583d27..81fb75a0 100644 --- a/src/lstate.h +++ b/src/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 2.8 2004/09/15 20:39:42 roberto Exp $ +** $Id: lstate.h,v 2.9 2004/12/06 17:53:42 roberto Exp $ ** Global State ** See Copyright Notice in lua.h */ @@ -85,6 +85,8 @@ 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 prevestimate; /* previous estimate */ + int stepmul; /* relative `speed' of the GC */ + int incgc; /* 0 if GC is done non-incrementally */ lua_CFunction panic; /* to be called in unprotected errors */ TValue _registry; struct lua_State *mainthread; diff --git a/src/lstring.c b/src/lstring.c index 4c34dc9b..af2c6963 100644 --- a/src/lstring.c +++ b/src/lstring.c @@ -1,5 +1,5 @@ /* -** $Id: lstring.c,v 2.3 2004/08/24 20:12:06 roberto Exp $ +** $Id: lstring.c,v 2.5 2004/11/24 19:16:03 roberto Exp $ ** String table (keeps all strings handled by Lua) ** See Copyright Notice in lua.h */ @@ -49,8 +49,11 @@ void luaS_resize (lua_State *L, int newsize) { static TString *newlstr (lua_State *L, const char *str, size_t l, unsigned int h) { - TString *ts = cast(TString *, luaM_malloc(L, sizestring(l))); + TString *ts; stringtable *tb; + if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) + luaM_toobig(L); + ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString))); ts->tsv.len = l; ts->tsv.hash = h; ts->tsv.marked = luaC_white(G(L)); @@ -75,7 +78,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ size_t l1; for (l1=l; l1>=step; l1-=step) /* compute hash */ - h = h ^ ((h<<5)+(h>>2)+(unsigned char)(str[l1-1])); + h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1])); for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; o != NULL; o = o->gch.next) { @@ -92,7 +95,9 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { Udata *luaS_newudata (lua_State *L, size_t s) { Udata *u; - u = cast(Udata *, luaM_malloc(L, sizeudata(s))); + if (s > MAX_SIZET - sizeof(Udata)) + luaM_toobig(L); + u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata))); u->uv.marked = luaC_white(G(L)); /* is not finalized */ u->uv.tt = LUA_TUSERDATA; u->uv.len = s; diff --git a/src/lstring.h b/src/lstring.h index 2d6e74a4..4198f57c 100644 --- a/src/lstring.h +++ b/src/lstring.h @@ -1,5 +1,5 @@ /* -** $Id: lstring.h,v 1.39 2004/08/24 20:12:06 roberto Exp $ +** $Id: lstring.h,v 1.40 2004/11/19 15:52:40 roberto Exp $ ** String table (keep all strings handled by Lua) ** See Copyright Notice in lua.h */ @@ -13,10 +13,9 @@ #include "lstate.h" -#define sizestring(l) (cast(lu_mem, sizeof(union TString))+ \ - (cast(lu_mem, l)+1)*sizeof(char)) +#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char)) -#define sizeudata(l) (cast(lu_mem, sizeof(union Udata))+(l)) +#define sizeudata(u) (sizeof(union Udata)+(u)->len) #define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ diff --git a/src/ltable.c b/src/ltable.c index 10008c54..8bfbf641 100644 --- a/src/ltable.c +++ b/src/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 2.5 2004/08/31 17:57:33 roberto Exp $ +** $Id: ltable.c,v 2.12 2004/12/04 18:10:22 roberto Exp $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -38,7 +38,7 @@ ** max size of array part is 2^MAXBITS */ #if LUA_BITSINT > 26 -#define MAXBITS 24 +#define MAXBITS 26 #else #define MAXBITS (LUA_BITSINT-2) #endif @@ -107,11 +107,10 @@ Node *luaH_mainposition (const Table *t, const TValue *key) { ** returns the index for `key' if `key' is an appropriate key to live in ** the array part of the table, -1 otherwise. */ -static int arrayindex (const TValue *key, lua_Number lim) { +static int arrayindex (const TValue *key) { if (ttisnumber(key)) { lua_Number n = nvalue(key); int k; - if (n <= 0 || n > lim) return -1; /* out of range? */ lua_number2int(k, n); if (cast(lua_Number, k) == nvalue(key)) return k; @@ -123,28 +122,35 @@ static int arrayindex (const TValue *key, lua_Number lim) { /* ** returns the index of a `key' for table traversals. First goes all ** elements in the array part, then elements in the hash part. The -** beginning and end of a traversal are signalled by -1. +** beginning of a traversal is signalled by -1. */ -static int luaH_index (lua_State *L, Table *t, StkId key) { +static int findindex (lua_State *L, Table *t, StkId key) { int i; if (ttisnil(key)) return -1; /* first iteration */ - i = arrayindex(key, t->sizearray); - if (0 <= i) { /* is `key' inside array part? */ + i = arrayindex(key); + if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ return i-1; /* yes; that's the index (corrected to C) */ - } else { - const TValue *v = luaH_get(t, key); - if (v == &luaO_nilobject) - luaG_runerror(L, "invalid key for `next'"); - i = cast(int, (cast(const lu_byte *, v) - - cast(const lu_byte *, gval(gnode(t, 0)))) / sizeof(Node)); - return i + t->sizearray; /* hash elements are numbered after array ones */ + Node *n = luaH_mainposition(t, key); + do { /* check whether `key' is somewhere in the chain */ + /* key may be dead already, but it is ok to use it in `next' */ + if (luaO_rawequalObj(key2tval(n), key) || + (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) && + gcvalue(gkey(n)) == gcvalue(key))) { + i = n - gnode(t, 0); /* key index in hash table */ + /* hash elements are numbered after array ones */ + return i + t->sizearray; + } + else n = gnext(n); + } while (n); + luaG_runerror(L, "invalid key for `next'"); /* key not found */ + return 0; /* to avoid warnings */ } } int luaH_next (lua_State *L, Table *t, StkId key) { - int i = luaH_index(L, t, key); /* find original element */ + int i = findindex(L, t, key); /* find original element */ for (i++; i < t->sizearray; i++) { /* try first array part */ if (!ttisnil(&t->array[i])) { /* a non-nil value? */ setnvalue(key, cast(lua_Number, i+1)); @@ -154,7 +160,7 @@ int luaH_next (lua_State *L, Table *t, StkId key) { } for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ - setobj2s(L, key, gkey(gnode(t, i))); + setobj2s(L, key, key2tval(gnode(t, i))); setobj2s(L, key+1, gval(gnode(t, i))); return 1; } @@ -195,7 +201,6 @@ static void numuse (const Table *t, int *narray, int *nhash) { int nums[MAXBITS+1]; int i, lg; int totaluse = 0; - lua_Number sizelimit; /* an upper bound for the array size */ /* count elements in array part */ for (i=0, lg=0; lg<=MAXBITS; lg++) { /* for each slice [2^(lg-1) to 2^lg) */ int ttlg = twoto(lg); /* 2^lg */ @@ -215,14 +220,11 @@ static void numuse (const Table *t, int *narray, int *nhash) { *narray = totaluse; /* all previous uses were in array part */ /* count elements in hash part */ i = sizenode(t); - /* array part cannot be larger than twice the maximum number of elements */ - sizelimit = cast(lua_Number, totaluse + i) * 2; - if (sizelimit >= MAXASIZE) sizelimit = MAXASIZE; while (i--) { Node *n = &t->node[i]; if (!ttisnil(gval(n))) { - int k = arrayindex(gkey(n), sizelimit); - if (k >= 0) { /* is `key' an appropriate array index? */ + int k = arrayindex(key2tval(n)); + if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */ nums[luaO_log2(k-1)+1]++; /* count as such */ (*narray)++; } @@ -251,12 +253,12 @@ static void setnodevector (lua_State *L, Table *t, int lsize) { t->node = G(L)->dummynode; /* use common `dummynode' */ lua_assert(ttisnil(gkey(t->node))); /* assert invariants: */ lua_assert(ttisnil(gval(t->node))); - lua_assert(t->node->next == NULL); /* (`dummynode' must be empty) */ + lua_assert(gnext(t->node) == NULL); /* (`dummynode' must be empty) */ } else { t->node = luaM_newvector(L, size, Node); for (i=0; i<size; i++) { - t->node[i].next = NULL; + gnext(&t->node[i]) = NULL; setnilvalue(gkey(gnode(t, i))); setnilvalue(gval(gnode(t, i))); } @@ -280,7 +282,7 @@ void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) { nold = temp; setnilvalue(gkey(G(L)->dummynode)); /* restate invariant */ setnilvalue(gval(G(L)->dummynode)); - lua_assert(G(L)->dummynode->next == NULL); + lua_assert(gnext(G(L)->dummynode) == NULL); } if (nasize > oldasize) /* array part must grow? */ setarrayvector(L, t, nasize); @@ -301,7 +303,7 @@ void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) { for (i = twoto(oldhsize) - 1; i >= 0; i--) { Node *old = nold+i; if (!ttisnil(gval(old))) - setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old)); + setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old)); } if (oldhsize) luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */ @@ -341,7 +343,7 @@ void luaH_free (lua_State *L, Table *t) { if (t->lsizenode) luaM_freearray(L, t->node, sizenode(t), Node); luaM_freearray(L, t->array, t->sizearray, TValue); - luaM_freelem(L, t); + luaM_free(L, t); } @@ -357,24 +359,25 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) { TValue *val; Node *mp = luaH_mainposition(t, key); if (!ttisnil(gval(mp))) { /* main position is not free? */ - Node *othern = luaH_mainposition(t, gkey(mp)); /* `mp' of colliding node */ + /* `mp' of colliding node */ + Node *othern = luaH_mainposition(t, key2tval(mp)); Node *n = t->firstfree; /* get a free place */ if (othern != mp) { /* is colliding node out of its main position? */ /* yes; move colliding node into free position */ - while (othern->next != mp) othern = othern->next; /* find previous */ - othern->next = n; /* redo the chain with `n' in place of `mp' */ + while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ + gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ - mp->next = NULL; /* now `mp' is free */ + gnext(mp) = NULL; /* now `mp' is free */ setnilvalue(gval(mp)); } else { /* colliding node is in its own main position */ /* new node will go into free position */ - n->next = mp->next; /* chain new position */ - mp->next = n; + gnext(n) = gnext(mp); /* chain new position */ + gnext(mp) = n; mp = n; } } - setobj2t(L, gkey(mp), key); + gkey(mp)->value = key->value; gkey(mp)->tt = key->tt; luaC_barriert(L, t, key); lua_assert(ttisnil(gval(mp))); for (;;) { /* correct `firstfree' */ @@ -397,7 +400,8 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) { ** search function for integers */ const TValue *luaH_getnum (Table *t, int key) { - if (1 <= key && key <= t->sizearray) + /* (1 <= key && key <= t->sizearray) */ + if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) return &t->array[key-1]; else { lua_Number nk = cast(lua_Number, key); @@ -405,7 +409,7 @@ const TValue *luaH_getnum (Table *t, int key) { do { /* check whether `key' is somewhere in the chain */ if (ttisnumber(gkey(n)) && nvalue(gkey(n)) == nk) return gval(n); /* that's it */ - else n = n->next; + else n = gnext(n); } while (n); return &luaO_nilobject; } @@ -420,7 +424,7 @@ const TValue *luaH_getstr (Table *t, TString *key) { do { /* check whether `key' is somewhere in the chain */ if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key) return gval(n); /* that's it */ - else n = n->next; + else n = gnext(n); } while (n); return &luaO_nilobject; } @@ -443,8 +447,9 @@ const TValue *luaH_get (Table *t, const TValue *key) { default: { Node *n = luaH_mainposition(t, key); do { /* check whether `key' is somewhere in the chain */ - if (luaO_rawequalObj(gkey(n), key)) return gval(n); /* that's it */ - else n = n->next; + if (luaO_rawequalObj(key2tval(n), key)) + return gval(n); /* that's it */ + else n = gnext(n); } while (n); return &luaO_nilobject; } diff --git a/src/ltable.h b/src/ltable.h index d72cf9f5..cfc86017 100644 --- a/src/ltable.h +++ b/src/ltable.h @@ -1,5 +1,5 @@ /* -** $Id: ltable.h,v 2.2 2004/03/26 14:02:41 roberto Exp $ +** $Id: ltable.h,v 2.3 2004/10/06 18:34:16 roberto Exp $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -13,6 +13,9 @@ #define gnode(t,i) (&(t)->node[i]) #define gkey(n) (&(n)->i_key) #define gval(n) (&(n)->i_val) +#define gnext(n) ((n)->i_key.next) + +#define key2tval(n) (cast(const TValue *, gkey(n))) const TValue *luaH_getnum (Table *t, int key); diff --git a/src/lua/lua.c b/src/lua/lua.c index 6fe479b3..6a21a6ae 100644 --- a/src/lua/lua.c +++ b/src/lua/lua.c @@ -1,5 +1,5 @@ /* -** $Id: lua.c,v 1.132 2004/08/30 18:35:14 roberto Exp $ +** $Id: lua.c,v 1.133 2004/11/18 19:53:49 roberto Exp $ ** Lua stand-alone interpreter ** See Copyright Notice in lua.h */ @@ -127,9 +127,9 @@ static int dostring (lua_State *L, const char *s, const char *name) { static int dolibrary (lua_State *L, const char *name) { - lua_getfield(L, LUA_GLOBALSINDEX, "_PATH"); + luaL_getfield(L, LUA_GLOBALSINDEX, "package.path"); if (!lua_isstring(L, -1)) { - l_message(progname, "global _PATH must be a string"); + l_message(progname, "`package.path' must be a string"); return 1; } name = luaL_searchpath(L, name, lua_tostring(L, -1)); @@ -295,7 +295,7 @@ static int handle_argv (lua_State *L, char *argv[], int *interactive) { print_usage(); return 1; } - if (dostring(L, chunk, "=<command line>") != 0) + if (dostring(L, chunk, "=(command line)") != 0) return 1; break; } diff --git a/src/luac/print.c b/src/luac/print.c index 0d3f18bf..f273ebfc 100644 --- a/src/luac/print.c +++ b/src/luac/print.c @@ -1,5 +1,5 @@ /* -** $Id: print.c,v 1.48 2004/09/01 21:22:34 lhf Exp $ +** $Id: print.c,v 1.49 2004/11/25 09:31:41 lhf Exp $ ** print bytecodes ** See Copyright Notice in lua.h */ @@ -33,7 +33,7 @@ static void PrintString(const Proto* f, int n) case '\r': printf("\\r"); break; case '\t': printf("\\t"); break; case '\v': printf("\\v"); break; - default: printf(isprint(*s) ? "%c" : "\\%03d",*s); + default: printf(isprint((unsigned char)*s) ? "%c" : "\\%03d",*s); } } putchar('"'); @@ -44,15 +44,18 @@ static void PrintConstant(const Proto* f, int i) const TValue* o=&f->k[i]; switch (ttype(o)) { + case LUA_TNIL: + printf("nil"); + break; + case LUA_TBOOLEAN: + printf(bvalue(o) ? "true" : "false"); + break; case LUA_TNUMBER: printf(LUA_NUMBER_FMT,nvalue(o)); break; case LUA_TSTRING: PrintString(f,i); break; - case LUA_TNIL: - printf("nil"); - break; default: /* cannot happen */ printf("? type=%d",ttype(o)); break; diff --git a/src/lundump.c b/src/lundump.c index ee091602..e13a4e48 100644 --- a/src/lundump.c +++ b/src/lundump.c @@ -1,5 +1,5 @@ /* -** $Id: lundump.c,v 1.53 2004/09/01 21:22:34 lhf Exp $ +** $Id: lundump.c,v 1.54 2004/11/25 09:31:41 lhf Exp $ ** load pre-compiled Lua chunks ** See Copyright Notice in lua.h */ @@ -177,15 +177,18 @@ static void LoadConstants (LoadState* S, Proto* f) int t=LoadByte(S); switch (t) { + case LUA_TNIL: + setnilvalue(o); + break; + case LUA_TBOOLEAN: + setbvalue(o,LoadByte(S)); + break; case LUA_TNUMBER: setnvalue(o,LoadNumber(S)); break; case LUA_TSTRING: setsvalue2n(S->L,o,LoadString(S)); break; - case LUA_TNIL: - setnilvalue(o); - break; default: error(S,"bad constant type (%d)",t); break; @@ -243,19 +246,15 @@ static void LoadHeader (LoadState* S) lua_Number x,tx=TEST_NUMBER; LoadSignature(S); version=LoadByte(S); - if (version>VERSION) - error(S,"bad version (read %d.%d; expected at %s %d.%d)", - V(version),"most",V(VERSION)); - if (version<VERSION0) /* check last major change */ - error(S,"bad version (read %d.%d; expected at %s %d.%d)", - V(version),"least",V(VERSION0)); + if (version!=VERSION) + error(S,"bad version (read %d.%d; expected %d.%d)",V(version),V(VERSION)); S->swap=(luaU_endianness()!=LoadByte(S)); /* need to swap bytes? */ TestSize(S,sizeof(int),"int"); TestSize(S,sizeof(size_t),"size_t"); TestSize(S,sizeof(Instruction),"instruction"); TestSize(S,sizeof(lua_Number),"number"); x=LoadNumber(S); - if ((long)x!=(long)tx) /* disregard errors in last bits of fraction */ + if (x!=tx) error(S,"unknown number format"); } diff --git a/src/lundump.h b/src/lundump.h index 4628b81d..1a7b897b 100644 --- a/src/lundump.h +++ b/src/lundump.h @@ -1,5 +1,5 @@ /* -** $Id: lundump.h,v 1.33 2004/06/09 21:03:53 lhf Exp $ +** $Id: lundump.h,v 1.34 2004/11/25 09:31:41 lhf Exp $ ** load pre-compiled Lua chunks ** See Copyright Notice in lua.h */ @@ -22,12 +22,10 @@ int luaU_dump (lua_State* L, const Proto* f, lua_Chunkwriter w, void* data, int /* print one chunk; from print.c */ void luaU_print (const Proto* f, int full); -/* definitions for headers of binary files */ -#define VERSION 0x51 /* last format change was in 5.1 */ -#define VERSION0 0x51 /* last major change was in 5.1 */ +/* for header of binary files -- this is Lua 5.1 */ +#define VERSION 0x51 -/* a multiple of PI for testing native format */ -/* multiplying by 1E7 gives non-trivial integer values */ -#define TEST_NUMBER ((lua_Number)3.14159265358979323846E7) +/* for testing native format of lua_Numbers */ +#define TEST_NUMBER ((lua_Number)31415926.0) #endif @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 2.14 2004/09/15 20:39:42 roberto Exp $ +** $Id: lvm.c,v 2.18 2004/12/03 20:35:33 roberto Exp $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -214,7 +214,7 @@ static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, } -static int luaV_strcmp (const TString *ls, const TString *rs) { +static int l_strcmp (const TString *ls, const TString *rs) { const char *l = getstr(ls); size_t ll = ls->tsv.len; const char *r = getstr(rs); @@ -243,21 +243,21 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { else if (ttisnumber(l)) return nvalue(l) < nvalue(r); else if (ttisstring(l)) - return luaV_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) return res; return luaG_ordererror(L, l, r); } -static int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { +static int lessequal (lua_State *L, const TValue *l, const TValue *r) { int res; if (ttype(l) != ttype(r)) return luaG_ordererror(L, l, r); else if (ttisnumber(l)) return nvalue(l) <= nvalue(r); else if (ttisstring(l)) - return luaV_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ return res; else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */ @@ -303,15 +303,14 @@ void luaV_concat (lua_State *L, int total, int last) { luaG_concaterror(L, top-2, top-1); } else if (tsvalue(top-1)->len > 0) { /* if len=0, do nothing */ /* at least two string values; get as many as possible */ - lu_mem tl = cast(lu_mem, tsvalue(top-1)->len) + - cast(lu_mem, tsvalue(top-2)->len); + size_t tl = tsvalue(top-1)->len; char *buffer; int i; - while (n < total && tostring(L, top-n-1)) { /* collect total length */ + /* collect total length */ + for (n = 1; n < total && tostring(L, top-n-1); n++) { size_t l = tsvalue(top-n-1)->len; if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow"); tl += l; - n++; } buffer = luaZ_openspace(L, &G(L)->buff, tl); tl = 0; @@ -462,7 +461,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { } case OP_NEWTABLE: { int b = GETARG_B(i); - b = fb2int(b); + b = luaO_fb2int(b); sethvalue(L, ra, luaH_new(L, b, GETARG_C(i))); L->ci->savedpc = pc; luaC_checkGC(L); /***/ @@ -569,7 +568,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { } case OP_LE: { L->ci->savedpc = pc; - if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; /***/ + if (lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; /***/ else dojump(L, pc, GETARG_sBx(*pc) + 1); base = L->base; continue; @@ -710,21 +709,19 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { dojump(L, pc, GETARG_sBx(i)); continue; } - case OP_SETLIST: - case OP_SETLISTO: { - int bc = GETARG_Bx(i); - int n, last; + 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 (GET_OPCODE(i) == OP_SETLIST) - n = (bc&(LFIELDS_PER_FLUSH-1)) + 1; - else { + if (n == 0) { n = L->top - ra - 1; L->top = L->ci->top; } - bc &= ~(LFIELDS_PER_FLUSH-1); /* bc = bc - bc%FPF */ - last = bc + n + LUA_FIRSTINDEX - 1; + if (c == 0) c = cast(int, *pc++); + last = ((c-1)*LFIELDS_PER_FLUSH) + n + LUA_FIRSTINDEX - 1; if (last > h->sizearray) /* needs more space? */ luaH_resize(L, h, last, h->lsizenode); /* pre-alloc it at once */ for (; n > 0; n--) { |