summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLua Team <team@lua.org>2004-12-07 12:00:00 +0000
committerrepogen <>2004-12-07 12:00:00 +0000
commit226f7859b5392b6680b7e703f9cc7f7f101fd365 (patch)
tree4345e84719d7f9ccf8d62fa007cbd386f235c58a
parentd8fd22e11b391cf183068049bebbee9702c8f78f (diff)
downloadlua-github-226f7859b5392b6680b7e703f9cc7f7f101fd365.tar.gz
Lua 5.1-work35.1-work3
-rw-r--r--INSTALL2
-rw-r--r--MANIFEST227
-rw-r--r--Makefile27
-rw-r--r--README5
-rw-r--r--config6
-rw-r--r--etc/all.c1
-rw-r--r--etc/lua.hpp8
-rw-r--r--etc/min.c1
-rw-r--r--include/lauxlib.h22
-rw-r--r--include/lua.h46
-rw-r--r--include/luaconf.h110
-rw-r--r--src/lapi.c94
-rw-r--r--src/lcode.c77
-rw-r--r--src/lcode.h3
-rw-r--r--src/ldebug.c23
-rw-r--r--src/ldo.c12
-rw-r--r--src/ldump.c9
-rw-r--r--src/lfunc.c8
-rw-r--r--src/lgc.c50
-rw-r--r--src/lib/lauxlib.c78
-rw-r--r--src/lib/lbaselib.c76
-rw-r--r--src/lib/ldblib.c9
-rw-r--r--src/lib/loadlib.c397
-rw-r--r--src/lib/loslib.c8
-rw-r--r--src/lib/lstrlib.c50
-rw-r--r--src/llex.c76
-rw-r--r--src/llex.h10
-rw-r--r--src/llimits.h23
-rw-r--r--src/lmem.c25
-rw-r--r--src/lmem.h38
-rw-r--r--src/lobject.c23
-rw-r--r--src/lobject.h22
-rw-r--r--src/lopcodes.c11
-rw-r--r--src/lopcodes.h18
-rw-r--r--src/lparser.c35
-rw-r--r--src/lstate.c10
-rw-r--r--src/lstate.h4
-rw-r--r--src/lstring.c13
-rw-r--r--src/lstring.h7
-rw-r--r--src/ltable.c85
-rw-r--r--src/ltable.h5
-rw-r--r--src/lua/lua.c8
-rw-r--r--src/luac/print.c13
-rw-r--r--src/lundump.c21
-rw-r--r--src/lundump.h12
-rw-r--r--src/lvm.c37
46 files changed, 1107 insertions, 738 deletions
diff --git a/INSTALL b/INSTALL
index 9d489301..228be50f 100644
--- a/INSTALL
+++ b/INSTALL
@@ -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
diff --git a/MANIFEST b/MANIFEST
index 7c81b934..494d4328 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -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
diff --git a/Makefile b/Makefile
index 19392435..d6e04bd8 100644
--- a/Makefile
+++ b/Makefile
@@ -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)
diff --git a/README b/README
index 8f4aa49a..7c5b0b76 100644
--- a/README
+++ b/README
@@ -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 .
diff --git a/config b/config
index fe39c134..75ae76f1 100644
--- a/config
+++ b/config
@@ -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.
diff --git a/etc/all.c b/etc/all.c
index fc4b045a..720be1b2 100644
--- a/etc/all.c
+++ b/etc/all.c
@@ -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"
+}
diff --git a/etc/min.c b/etc/min.c
index dfcc805a..b1200c05 100644
--- a/etc/min.c
+++ b/etc/min.c
@@ -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
diff --git a/src/lapi.c b/src/lapi.c
index ce32f3b0..c2c752e5 100644
--- a/src/lapi.c
+++ b/src/lapi.c
@@ -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: {
diff --git a/src/ldo.c b/src/ldo.c
index ad9cbc3d..d75a7063 100644
--- a/src/ldo.c
+++ b/src/ldo.c
@@ -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);
}
diff --git a/src/lgc.c b/src/lgc.c
index b3661fd7..87a3b534 100644
--- a/src/lgc.c
+++ b/src/lgc.c
@@ -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': {
diff --git a/src/llex.c b/src/llex.c
index c5e491e5..3940b955 100644
--- a/src/llex.c
+++ b/src/llex.c
@@ -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 '=': {
diff --git a/src/llex.h b/src/llex.h
index 6cfc3fdd..a16bba8d 100644
--- a/src/llex.h
+++ b/src/llex.h
@@ -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))
diff --git a/src/lmem.c b/src/lmem.c
index c1802ff9..632990fc 100644
--- a/src/lmem.c
+++ b/src/lmem.c
@@ -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);
diff --git a/src/lmem.h b/src/lmem.h
index 1bb4fde0..13a1658b 100644
--- a/src/lmem.h
+++ b/src/lmem.h
@@ -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
diff --git a/src/lvm.c b/src/lvm.c
index 94f98147..1a295d1b 100644
--- a/src/lvm.c
+++ b/src/lvm.c
@@ -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--) {