summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLua Team <team@lua.org>2005-03-04 12:00:00 +0000
committerrepogen <>2005-03-04 12:00:00 +0000
commite6ddfd3b09c0a3727afc773029c323a3defe50fa (patch)
tree70e021a2b008f43064eeb04e002a31ba371b5108
parente2493a40ee611d5a718fd2a81fe67e24c04c91a0 (diff)
downloadlua-github-e6ddfd3b09c0a3727afc773029c323a3defe50fa.tar.gz
Lua 5.1-work55.1-work5
-rw-r--r--COPYRIGHT2
-rw-r--r--HISTORY19
-rw-r--r--MANIFEST208
-rw-r--r--Makefile2
-rw-r--r--src/Makefile19
-rw-r--r--src/lapi.c89
-rw-r--r--src/lauxlib.c7
-rw-r--r--src/lauxlib.h89
-rw-r--r--src/lbaselib.c29
-rw-r--r--src/lcode.c4
-rw-r--r--src/ldblib.c51
-rw-r--r--src/ldo.c4
-rw-r--r--src/lfunc.c53
-rw-r--r--src/lfunc.h7
-rw-r--r--src/lgc.c198
-rw-r--r--src/lgc.h23
-rw-r--r--src/linit.c4
-rw-r--r--src/liolib.c34
-rw-r--r--src/llimits.h4
-rw-r--r--src/lmathlib.c4
-rw-r--r--src/lmem.c32
-rw-r--r--src/loadlib.c82
-rw-r--r--src/lobject.c4
-rw-r--r--src/lobject.h19
-rw-r--r--src/loslib.c8
-rw-r--r--src/lparser.c4
-rw-r--r--src/lstate.c43
-rw-r--r--src/lstate.h19
-rw-r--r--src/lstring.c11
-rw-r--r--src/lstring.h6
-rw-r--r--src/ltable.c221
-rw-r--r--src/ltable.h6
-rw-r--r--src/lua.c20
-rw-r--r--src/lua.h156
-rw-r--r--src/luaconf.h79
-rw-r--r--src/lualib.h20
-rw-r--r--src/lvm.c75
37 files changed, 938 insertions, 717 deletions
diff --git a/COPYRIGHT b/COPYRIGHT
index 16321abf..ba498733 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -9,7 +9,7 @@ For details and rationale, see http://www.lua.org/license.html .
===============================================================================
-Copyright (C) 2003-2004 Tecgraf, PUC-Rio.
+Copyright (C) 1994-2005 Tecgraf, PUC-Rio.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/HISTORY b/HISTORY
index dd29bc7c..3be1eb55 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,5 +1,24 @@
This is Lua 5.1 (work).
+* Changes from version 5.0 to 5.1
+ -------------------------------
+ Language:
+ + new module system.
+ + new semantics for control variables of fors.
+ + new semantics for setn/getn.
+ + new syntax/semantics for varargs.
+ + new long strings.
+ API:
+ + new functions: lua_createtable, lua_get(set)field, lua_push(to)integer.
+ + user supplies memory allocator (lua_open becomes lua_newstate).
+ Implementation:
+ + incremental garbage collection.
+ + debug works over other threads.
+ + better handling of end-of-line in the lexer.
+ + fully reentrant parser (new Lua function `load')
+ + better support for 64-bit machines (special thanks to Mike Pall).
+ + native loadlib support for Mac OS X (thanks to Matthew Cox).
+
* Changes from version 4.0 to 5.0
-------------------------------
Language:
diff --git a/MANIFEST b/MANIFEST
index 38ca97df..01a2a7e7 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,105 +1,105 @@
-MANIFEST contents of Lua 5.1 (work4) distribution on Thu Dec 30 12:00:49 BRST 2004
-lua-5.1-work4
-lua-5.1-work4/COPYRIGHT
-lua-5.1-work4/HISTORY
-lua-5.1-work4/INSTALL
-lua-5.1-work4/MANIFEST
-lua-5.1-work4/Makefile
-lua-5.1-work4/README
-lua-5.1-work4/doc
-lua-5.1-work4/doc/contents.html
-lua-5.1-work4/doc/logo.gif
-lua-5.1-work4/doc/lua.1
-lua-5.1-work4/doc/lua.html
-lua-5.1-work4/doc/luac.1
-lua-5.1-work4/doc/luac.html
-lua-5.1-work4/doc/readme.html
-lua-5.1-work4/etc
-lua-5.1-work4/etc/Makefile
-lua-5.1-work4/etc/README
-lua-5.1-work4/etc/all.c
-lua-5.1-work4/etc/lua.hpp
-lua-5.1-work4/etc/lua.ico
-lua-5.1-work4/etc/min.c
-lua-5.1-work4/etc/noparser.c
-lua-5.1-work4/etc/saconfig.c
-lua-5.1-work4/src
-lua-5.1-work4/src/Makefile
-lua-5.1-work4/src/lapi.c
-lua-5.1-work4/src/lapi.h
-lua-5.1-work4/src/lauxlib.c
-lua-5.1-work4/src/lauxlib.h
-lua-5.1-work4/src/lbaselib.c
-lua-5.1-work4/src/lcode.c
-lua-5.1-work4/src/lcode.h
-lua-5.1-work4/src/ldblib.c
-lua-5.1-work4/src/ldebug.c
-lua-5.1-work4/src/ldebug.h
-lua-5.1-work4/src/ldo.c
-lua-5.1-work4/src/ldo.h
-lua-5.1-work4/src/ldump.c
-lua-5.1-work4/src/lfunc.c
-lua-5.1-work4/src/lfunc.h
-lua-5.1-work4/src/lgc.c
-lua-5.1-work4/src/lgc.h
-lua-5.1-work4/src/linit.c
-lua-5.1-work4/src/liolib.c
-lua-5.1-work4/src/llex.c
-lua-5.1-work4/src/llex.h
-lua-5.1-work4/src/llimits.h
-lua-5.1-work4/src/lmathlib.c
-lua-5.1-work4/src/lmem.c
-lua-5.1-work4/src/lmem.h
-lua-5.1-work4/src/loadlib.c
-lua-5.1-work4/src/lobject.c
-lua-5.1-work4/src/lobject.h
-lua-5.1-work4/src/lopcodes.c
-lua-5.1-work4/src/lopcodes.h
-lua-5.1-work4/src/loslib.c
-lua-5.1-work4/src/lparser.c
-lua-5.1-work4/src/lparser.h
-lua-5.1-work4/src/lstate.c
-lua-5.1-work4/src/lstate.h
-lua-5.1-work4/src/lstring.c
-lua-5.1-work4/src/lstring.h
-lua-5.1-work4/src/lstrlib.c
-lua-5.1-work4/src/ltable.c
-lua-5.1-work4/src/ltable.h
-lua-5.1-work4/src/ltablib.c
-lua-5.1-work4/src/ltm.c
-lua-5.1-work4/src/ltm.h
-lua-5.1-work4/src/lua.c
-lua-5.1-work4/src/lua.h
-lua-5.1-work4/src/luac.c
-lua-5.1-work4/src/luaconf.h
-lua-5.1-work4/src/lualib.h
-lua-5.1-work4/src/lundump.c
-lua-5.1-work4/src/lundump.h
-lua-5.1-work4/src/lvm.c
-lua-5.1-work4/src/lvm.h
-lua-5.1-work4/src/lzio.c
-lua-5.1-work4/src/lzio.h
-lua-5.1-work4/src/print.c
-lua-5.1-work4/test
-lua-5.1-work4/test/README
-lua-5.1-work4/test/bisect.lua
-lua-5.1-work4/test/cf.lua
-lua-5.1-work4/test/echo.lua
-lua-5.1-work4/test/env.lua
-lua-5.1-work4/test/factorial.lua
-lua-5.1-work4/test/fib.lua
-lua-5.1-work4/test/fibfor.lua
-lua-5.1-work4/test/globals.lua
-lua-5.1-work4/test/hello.lua
-lua-5.1-work4/test/life.lua
-lua-5.1-work4/test/luac.lua
-lua-5.1-work4/test/printf.lua
-lua-5.1-work4/test/readonly.lua
-lua-5.1-work4/test/sieve.lua
-lua-5.1-work4/test/sort.lua
-lua-5.1-work4/test/table.lua
-lua-5.1-work4/test/trace-calls.lua
-lua-5.1-work4/test/trace-globals.lua
-lua-5.1-work4/test/undefined.lua
-lua-5.1-work4/test/xd.lua
+MANIFEST contents of Lua 5.1 (work5) distribution on Fri Mar 4 13:32:55 BRST 2005
+lua-5.1-work5
+lua-5.1-work5/COPYRIGHT
+lua-5.1-work5/HISTORY
+lua-5.1-work5/INSTALL
+lua-5.1-work5/MANIFEST
+lua-5.1-work5/Makefile
+lua-5.1-work5/README
+lua-5.1-work5/doc
+lua-5.1-work5/doc/contents.html
+lua-5.1-work5/doc/logo.gif
+lua-5.1-work5/doc/lua.1
+lua-5.1-work5/doc/lua.html
+lua-5.1-work5/doc/luac.1
+lua-5.1-work5/doc/luac.html
+lua-5.1-work5/doc/readme.html
+lua-5.1-work5/etc
+lua-5.1-work5/etc/Makefile
+lua-5.1-work5/etc/README
+lua-5.1-work5/etc/all.c
+lua-5.1-work5/etc/lua.hpp
+lua-5.1-work5/etc/lua.ico
+lua-5.1-work5/etc/min.c
+lua-5.1-work5/etc/noparser.c
+lua-5.1-work5/etc/saconfig.c
+lua-5.1-work5/src
+lua-5.1-work5/src/Makefile
+lua-5.1-work5/src/lapi.c
+lua-5.1-work5/src/lapi.h
+lua-5.1-work5/src/lauxlib.c
+lua-5.1-work5/src/lauxlib.h
+lua-5.1-work5/src/lbaselib.c
+lua-5.1-work5/src/lcode.c
+lua-5.1-work5/src/lcode.h
+lua-5.1-work5/src/ldblib.c
+lua-5.1-work5/src/ldebug.c
+lua-5.1-work5/src/ldebug.h
+lua-5.1-work5/src/ldo.c
+lua-5.1-work5/src/ldo.h
+lua-5.1-work5/src/ldump.c
+lua-5.1-work5/src/lfunc.c
+lua-5.1-work5/src/lfunc.h
+lua-5.1-work5/src/lgc.c
+lua-5.1-work5/src/lgc.h
+lua-5.1-work5/src/linit.c
+lua-5.1-work5/src/liolib.c
+lua-5.1-work5/src/llex.c
+lua-5.1-work5/src/llex.h
+lua-5.1-work5/src/llimits.h
+lua-5.1-work5/src/lmathlib.c
+lua-5.1-work5/src/lmem.c
+lua-5.1-work5/src/lmem.h
+lua-5.1-work5/src/loadlib.c
+lua-5.1-work5/src/lobject.c
+lua-5.1-work5/src/lobject.h
+lua-5.1-work5/src/lopcodes.c
+lua-5.1-work5/src/lopcodes.h
+lua-5.1-work5/src/loslib.c
+lua-5.1-work5/src/lparser.c
+lua-5.1-work5/src/lparser.h
+lua-5.1-work5/src/lstate.c
+lua-5.1-work5/src/lstate.h
+lua-5.1-work5/src/lstring.c
+lua-5.1-work5/src/lstring.h
+lua-5.1-work5/src/lstrlib.c
+lua-5.1-work5/src/ltable.c
+lua-5.1-work5/src/ltable.h
+lua-5.1-work5/src/ltablib.c
+lua-5.1-work5/src/ltm.c
+lua-5.1-work5/src/ltm.h
+lua-5.1-work5/src/lua.c
+lua-5.1-work5/src/lua.h
+lua-5.1-work5/src/luac.c
+lua-5.1-work5/src/luaconf.h
+lua-5.1-work5/src/lualib.h
+lua-5.1-work5/src/lundump.c
+lua-5.1-work5/src/lundump.h
+lua-5.1-work5/src/lvm.c
+lua-5.1-work5/src/lvm.h
+lua-5.1-work5/src/lzio.c
+lua-5.1-work5/src/lzio.h
+lua-5.1-work5/src/print.c
+lua-5.1-work5/test
+lua-5.1-work5/test/README
+lua-5.1-work5/test/bisect.lua
+lua-5.1-work5/test/cf.lua
+lua-5.1-work5/test/echo.lua
+lua-5.1-work5/test/env.lua
+lua-5.1-work5/test/factorial.lua
+lua-5.1-work5/test/fib.lua
+lua-5.1-work5/test/fibfor.lua
+lua-5.1-work5/test/globals.lua
+lua-5.1-work5/test/hello.lua
+lua-5.1-work5/test/life.lua
+lua-5.1-work5/test/luac.lua
+lua-5.1-work5/test/printf.lua
+lua-5.1-work5/test/readonly.lua
+lua-5.1-work5/test/sieve.lua
+lua-5.1-work5/test/sort.lua
+lua-5.1-work5/test/table.lua
+lua-5.1-work5/test/trace-calls.lua
+lua-5.1-work5/test/trace-globals.lua
+lua-5.1-work5/test/undefined.lua
+lua-5.1-work5/test/xd.lua
END OF MANIFEST
diff --git a/Makefile b/Makefile
index 62bb7e49..d01b51a9 100644
--- a/Makefile
+++ b/Makefile
@@ -44,7 +44,7 @@ install: all
cd doc; $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN)
local:
- $(MAKE) install INSTALL_TOP=.. INSTALL_EXEC="cp -up" INSTALL_DATA="cp -up"
+ $(MAKE) install INSTALL_TOP=.. INSTALL_EXEC="cp -p" INSTALL_DATA="cp -p"
# echo config parameters
echo:
diff --git a/src/Makefile b/src/Makefile
index cf7ff181..9ec6d349 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -6,13 +6,15 @@
CC= gcc
CFLAGS= -O2 -Wall $(MYCFLAGS)
-MYCFLAGS=
-MYLDFLAGS= -Wl,-E # enable dynamic loading in Linux
-MYLIBS= -lm -ldl # enable dynamic loading in Linux
AR= ar rcu
RANLIB= ranlib
RM= rm -f
+MYCFLAGS=
+MYLDFLAGS=
+MYLIBS= -lm
+DL= -ldl -Wl,-E # enable dynamic loading in Linux
+
# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE =========
CORE_T= liblua.a
@@ -49,10 +51,10 @@ $(LIB_T): $(LIB_O)
$(RANLIB) $@
$(LUA_T): $(LUA_O) $(CORE_T) $(LIB_T)
- $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) -L. -llua -llualib $(MYLIBS)
+ $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) -L. -llua -llualib $(MYLIBS) $(DL)
$(LUAC_T): $(LUAC_O) $(CORE_T)
- $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) -L. -llua
+ $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) -L. -llua $(MYLIBS)
clean:
$(RM) $(ALL_T) $(ALL_O)
@@ -63,12 +65,13 @@ depend:
echo:
@echo "CC = $(CC)"
@echo "CFLAGS = $(CFLAGS)"
- @echo "MYCFLAGS = $(MYCFLAGS)"
- @echo "MYLDFLAGS = $(MYLDFLAGS)"
- @echo "MYLIBS = $(MYLIBS)"
@echo "AR = $(AR)"
@echo "RANLIB = $(RANLIB)"
@echo "RM = $(RM)"
+ @echo "MYCFLAGS = $(MYCFLAGS)"
+ @echo "MYLDFLAGS = $(MYLDFLAGS)"
+ @echo "MYLIBS = $(MYLIBS)"
+ @echo "DL = $(DL)"
# DO NOT DELETE
diff --git a/src/lapi.c b/src/lapi.c
index e2dd11d1..9b4b5b33 100644
--- a/src/lapi.c
+++ b/src/lapi.c
@@ -1,5 +1,5 @@
/*
-** $Id: lapi.c,v 2.23 2004/12/13 12:15:11 roberto Exp $
+** $Id: lapi.c,v 2.28 2005/02/23 17:30:22 roberto Exp $
** Lua API
** See Copyright Notice in lua.h
*/
@@ -58,6 +58,11 @@ static TValue *index2adr (lua_State *L, int idx) {
}
else switch (idx) { /* pseudo-indices */
case LUA_REGISTRYINDEX: return registry(L);
+ case LUA_ENVIRONINDEX: {
+ Closure *func = curr_func(L);
+ sethvalue(L, &L->env, func->c.env);
+ return &L->env;
+ }
case LUA_GLOBALSINDEX: return gt(L);
default: {
Closure *func = curr_func(L);
@@ -70,6 +75,16 @@ static TValue *index2adr (lua_State *L, int idx) {
}
+static Table *getcurrenv (lua_State *L) {
+ if (L->ci == L->base_ci) /* no enclosing function? */
+ return hvalue(gt(L)); /* use global table as environment */
+ else {
+ Closure *func = curr_func(L);
+ return func->c.env;
+ }
+}
+
+
void luaA_pushobject (lua_State *L, const TValue *o) {
setobj2s(L, L->top, o);
incr_top(L);
@@ -186,9 +201,17 @@ LUA_API void lua_replace (lua_State *L, int idx) {
api_checknelems(L, 1);
o = index2adr(L, idx);
api_checkvalidindex(L, o);
- setobj(L, o, L->top - 1);
- if (idx < LUA_GLOBALSINDEX) /* function upvalue? */
- luaC_barrier(L, curr_func(L), L->top - 1);
+ if (idx == LUA_ENVIRONINDEX) {
+ Closure *func = curr_func(L);
+ api_check(L, ttistable(L->top - 1));
+ func->c.env = hvalue(L->top - 1);
+ luaC_barrier(L, func, L->top - 1);
+ }
+ else {
+ setobj(L, o, L->top - 1);
+ if (idx < LUA_GLOBALSINDEX) /* function upvalue? */
+ luaC_barrier(L, curr_func(L), L->top - 1);
+ }
L->top--;
lua_unlock(L);
}
@@ -452,7 +475,7 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
lua_lock(L);
luaC_checkGC(L);
api_checknelems(L, n);
- cl = luaF_newCclosure(L, n);
+ cl = luaF_newCclosure(L, n, getcurrenv(L));
cl->c.f = fn;
L->top -= n;
while (n--)
@@ -542,7 +565,7 @@ LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
lua_lock(L);
luaC_checkGC(L);
- sethvalue(L, L->top, luaH_new(L, narray, luaO_log2(nrec) + 1));
+ sethvalue(L, L->top, luaH_new(L, narray, nrec));
api_incr_top(L);
lua_unlock(L);
}
@@ -579,7 +602,17 @@ LUA_API void lua_getfenv (lua_State *L, int idx) {
lua_lock(L);
o = index2adr(L, idx);
api_checkvalidindex(L, o);
- setobj2s(L, L->top, isLfunction(o) ? &clvalue(o)->l.g : gt(L));
+ switch (ttype(o)) {
+ case LUA_TFUNCTION:
+ sethvalue(L, L->top, clvalue(o)->c.env);
+ break;
+ case LUA_TUSERDATA:
+ sethvalue(L, L->top, uvalue(o)->env);
+ break;
+ default:
+ setnilvalue(L->top);
+ break;
+ }
api_incr_top(L);
lua_unlock(L);
}
@@ -682,17 +715,24 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
LUA_API int lua_setfenv (lua_State *L, int idx) {
StkId o;
- int res = 0;
+ int res = 1;
lua_lock(L);
api_checknelems(L, 1);
o = index2adr(L, idx);
api_checkvalidindex(L, o);
api_check(L, ttistable(L->top - 1));
- if (isLfunction(o)) {
- res = 1;
- clvalue(o)->l.g = *(L->top - 1);
- luaC_objbarrier(L, clvalue(o), hvalue(L->top - 1));
+ switch (ttype(o)) {
+ case LUA_TFUNCTION:
+ clvalue(o)->c.env = hvalue(L->top - 1);
+ break;
+ case LUA_TUSERDATA:
+ uvalue(o)->env = hvalue(L->top - 1);
+ break;
+ default:
+ res = 0;
+ break;
}
+ luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
L->top--;
lua_unlock(L);
return res;
@@ -776,7 +816,7 @@ struct CCallS { /* data to `f_Ccall' */
static void f_Ccall (lua_State *L, void *ud) {
struct CCallS *c = cast(struct CCallS *, ud);
Closure *cl;
- cl = luaF_newCclosure(L, 0);
+ cl = luaF_newCclosure(L, 0, getcurrenv(L));
cl->c.f = c->func;
setclvalue(L, L->top, cl); /* push function */
incr_top(L);
@@ -826,7 +866,7 @@ LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data) {
}
-LUA_API int lua_threadstatus (lua_State *L) {
+LUA_API int lua_status (lua_State *L) {
return L->status;
}
@@ -872,9 +912,9 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
g->gcpace = data;
break;
}
- case LUA_GCSETINCMODE: {
- res = g->incgc;
- g->incgc = data;
+ case LUA_GCSETSTEPMUL: {
+ res = g->gcstepmul;
+ g->gcstepmul = data;
break;
}
default: res = -1; /* invalid option */
@@ -890,11 +930,6 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
*/
-LUA_API const char *lua_version (void) {
- return LUA_VERSION;
-}
-
-
LUA_API int lua_error (lua_State *L) {
lua_lock(L);
api_checknelems(L, 1);
@@ -940,7 +975,7 @@ LUA_API void lua_concat (lua_State *L, int n) {
LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
*ud = G(L)->ud;
- return G(L)->realloc;
+ return G(L)->frealloc;
}
@@ -948,7 +983,7 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
Udata *u;
lua_lock(L);
luaC_checkGC(L);
- u = luaS_newudata(L, size);
+ u = luaS_newudata(L, size, getcurrenv(L));
setuvalue(L, L->top, u);
api_incr_top(L);
lua_unlock(L);
@@ -958,7 +993,7 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
-static const char *aux_upvalue (lua_State *L, StkId fi, int n, TValue **val) {
+static const char *aux_upvalue (StkId fi, int n, TValue **val) {
Closure *f;
if (!ttisfunction(fi)) return NULL;
f = clvalue(fi);
@@ -980,7 +1015,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, index2adr(L, funcindex), n, &val);
+ name = aux_upvalue(index2adr(L, funcindex), n, &val);
if (name) {
setobj2s(L, L->top, val);
api_incr_top(L);
@@ -997,7 +1032,7 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
lua_lock(L);
fi = index2adr(L, funcindex);
api_checknelems(L, 1);
- name = aux_upvalue(L, fi, n, &val);
+ name = aux_upvalue(fi, n, &val);
if (name) {
L->top--;
setobj(L, val, L->top);
diff --git a/src/lauxlib.c b/src/lauxlib.c
index 5bbe918b..ac53db39 100644
--- a/src/lauxlib.c
+++ b/src/lauxlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.c,v 1.127 2004/12/20 13:47:29 roberto Exp $
+** $Id: lauxlib.c,v 1.129 2005/02/23 17:30:22 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -350,8 +350,8 @@ LUALIB_API int luaL_getn (lua_State *L, int t) {
static const char *pushnexttemplate (lua_State *L, const char *path) {
const char *l;
if (*path == '\0') return NULL; /* no more templates */
- if (*path == LUA_PATH_SEP) path++; /* skip separator */
- l = strchr(path, LUA_PATH_SEP); /* find next separator */
+ if (*path == LUA_PATHSEP) path++; /* skip separator */
+ l = strchr(path, LUA_PATHSEP); /* find next separator */
if (l == NULL) l = path+strlen(path);
lua_pushlstring(L, path, l - path); /* template */
return l;
@@ -704,6 +704,7 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
static int panic (lua_State *L) {
+ (void)L; /* to avoid warnings */
fprintf(stderr, "PANIC: unprotected error during Lua-API call\n");
return 0;
}
diff --git a/src/lauxlib.h b/src/lauxlib.h
index b47663ce..82585cf4 100644
--- a/src/lauxlib.h
+++ b/src/lauxlib.h
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.h,v 1.73 2004/10/18 12:51:44 roberto Exp $
+** $Id: lauxlib.h,v 1.74 2005/01/10 17:31:50 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -25,55 +25,58 @@ typedef struct luaL_reg {
} luaL_reg;
-LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
- const luaL_reg *l, int nup);
-LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *e);
-LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *e);
-LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname);
-LUALIB_API int luaL_argerror (lua_State *L, int numarg, const char *extramsg);
-LUALIB_API const char *luaL_checklstring (lua_State *L, int numArg, size_t *l);
-LUALIB_API const char *luaL_optlstring (lua_State *L, int numArg,
- const char *def, size_t *l);
-LUALIB_API lua_Number luaL_checknumber (lua_State *L, int numArg);
-LUALIB_API lua_Number luaL_optnumber (lua_State *L, int nArg, lua_Number def);
+LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
+ const luaL_reg *l, int nup);
+LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
+LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
+LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname);
+LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
+LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
+ size_t *l);
+LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
+ const char *def, size_t *l);
+LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
+LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
-LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int numArg);
-LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int nArg,
- lua_Integer def);
+LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
+LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
+ lua_Integer def);
-LUALIB_API void luaL_checkstack (lua_State *L, int sz, const char *msg);
-LUALIB_API void luaL_checktype (lua_State *L, int narg, int t);
-LUALIB_API void luaL_checkany (lua_State *L, int narg);
+LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
+LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
+LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
-LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname);
-LUALIB_API void luaL_getmetatable (lua_State *L, const char *tname);
-LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname);
+LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
+LUALIB_API void (luaL_getmetatable) (lua_State *L, const char *tname);
+LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
-LUALIB_API void luaL_where (lua_State *L, int lvl);
-LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...);
+LUALIB_API void (luaL_where) (lua_State *L, int lvl);
+LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
-LUALIB_API int luaL_findstring (const char *st, const char *const lst[]);
+LUALIB_API int (luaL_findstring) (const char *st, const char *const lst[]);
-LUALIB_API const char *luaL_searchpath (lua_State *L, const char *name,
- const char *path);
+LUALIB_API const char *(luaL_searchpath) (lua_State *L, const char *name,
+ const char *path);
-LUALIB_API int luaL_ref (lua_State *L, int t);
-LUALIB_API void luaL_unref (lua_State *L, int t, int ref);
+LUALIB_API int (luaL_ref) (lua_State *L, int t);
+LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
-LUALIB_API int luaL_getn (lua_State *L, int t);
-LUALIB_API void luaL_setn (lua_State *L, int t, int n);
+LUALIB_API int (luaL_getn) (lua_State *L, int t);
+LUALIB_API void (luaL_setn) (lua_State *L, int t, int n);
-LUALIB_API int luaL_loadfile (lua_State *L, const char *filename);
-LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz,
- const char *name);
+LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
+LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
+ const char *name);
LUALIB_API lua_State *(luaL_newstate) (void);
-LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
- const char *r);
-LUALIB_API const char *luaL_getfield (lua_State *L, int idx, const char *fname);
-LUALIB_API const char *luaL_setfield (lua_State *L, int idx, const char *fname);
+LUALIB_API const char *(luaL_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);
@@ -115,12 +118,12 @@ typedef struct luaL_Buffer {
#define luaL_addsize(B,n) ((B)->p += (n))
-LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B);
-LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B);
-LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);
-LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s);
-LUALIB_API void luaL_addvalue (luaL_Buffer *B);
-LUALIB_API void luaL_pushresult (luaL_Buffer *B);
+LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
+LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B);
+LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
+LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
+LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
+LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
/* }====================================================== */
diff --git a/src/lbaselib.c b/src/lbaselib.c
index 3b034bbc..9e1573cb 100644
--- a/src/lbaselib.c
+++ b/src/lbaselib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbaselib.c,v 1.163 2004/12/13 12:15:11 roberto Exp $
+** $Id: lbaselib.c,v 1.169 2005/02/28 17:24:41 roberto Exp $
** Basic library
** See Copyright Notice in lua.h
*/
@@ -131,7 +131,10 @@ static void getfunc (lua_State *L) {
static int luaB_getfenv (lua_State *L) {
getfunc(L);
- lua_getfenv(L, -1);
+ if (lua_iscfunction(L, -1)) /* is a C function? */
+ lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the global env. */
+ else
+ lua_getfenv(L, -1);
return 1;
}
@@ -144,8 +147,8 @@ static int luaB_setfenv (lua_State *L) {
lua_replace(L, LUA_GLOBALSINDEX);
return 0;
}
- else if (lua_setfenv(L, -2) == 0)
- luaL_error(L, "`setfenv' cannot change environment of given function");
+ else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
+ luaL_error(L, "`setfenv' cannot change environment of given object");
return 1;
}
@@ -182,11 +185,11 @@ static int luaB_gcinfo (lua_State *L) {
static int luaB_collectgarbage (lua_State *L) {
static const char *const opts[] = {"stop", "restart", "collect",
- "count", "step", "setpace", "setincmode", NULL};
+ "count", "step", "setpace", "setstepmul", NULL};
static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
- LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPACE, LUA_GCSETINCMODE};
+ LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPACE, LUA_GCSETSTEPMUL};
int o = luaL_findstring(luaL_optstring(L, 1, "collect"), opts);
- int ex = luaL_optint(L, 2, 0);
+ int ex = luaL_optinteger(L, 2, 0);
luaL_argcheck(L, o >= 0, 1, "invalid option");
lua_pushinteger(L, lua_gc(L, optsnum[o], ex));
return 1;
@@ -280,6 +283,7 @@ static int luaB_loadfile (lua_State *L) {
** reserved slot inside the stack.
*/
static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
+ (void)ud; /* to avoid warnings */
luaL_checkstack(L, 2, "too many nested functions");
lua_pushvalue(L, 1); /* get function */
lua_call(L, 0, 1); /* call it */
@@ -469,7 +473,7 @@ static int auxresume (lua_State *L, lua_State *co, int narg) {
int status;
if (!lua_checkstack(co, narg))
luaL_error(L, "too many arguments to resume");
- if (lua_threadstatus(co) == 0 && lua_gettop(co) == 0) {
+ if (lua_status(co) == 0 && lua_gettop(co) == 0) {
lua_pushliteral(L, "cannot resume dead coroutine");
return -1; /* error flag */
}
@@ -549,7 +553,7 @@ static int luaB_costatus (lua_State *L) {
luaL_argcheck(L, co, 1, "coroutine expected");
if (L == co) lua_pushliteral(L, "running");
else {
- switch (lua_threadstatus(co)) {
+ switch (lua_status(co)) {
case LUA_YIELD:
lua_pushliteral(L, "suspended");
break;
@@ -572,7 +576,7 @@ static int luaB_costatus (lua_State *L) {
}
-static int luaB_cocurrent (lua_State *L) {
+static int luaB_corunning (lua_State *L) {
if (lua_pushthread(L))
return 0; /* main thread is not a coroutine */
else
@@ -586,7 +590,7 @@ static const luaL_reg co_funcs[] = {
{"resume", luaB_coresume},
{"yield", luaB_yield},
{"status", luaB_costatus},
- {"current", luaB_cocurrent},
+ {"running", luaB_corunning},
{NULL, NULL}
};
@@ -620,9 +624,6 @@ static void base_open (lua_State *L) {
/* 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_setfield(L, LUA_REGISTRYINDEX, "_PRELOAD");
/* set global _G */
lua_pushvalue(L, LUA_GLOBALSINDEX);
lua_setglobal(L, "_G");
diff --git a/src/lcode.c b/src/lcode.c
index f7f1182d..b40bc5a1 100644
--- a/src/lcode.c
+++ b/src/lcode.c
@@ -1,5 +1,5 @@
/*
-** $Id: lcode.c,v 2.8 2004/12/03 20:35:33 roberto Exp $
+** $Id: lcode.c,v 2.9 2005/01/10 18:17:39 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -606,7 +606,7 @@ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
if (op == OPR_MINUS) {
luaK_exp2val(fs, e);
if (e->k == VK && ttisnumber(&fs->f->k[e->info]))
- e->info = luaK_numberK(fs, -nvalue(&fs->f->k[e->info]));
+ e->info = luaK_numberK(fs, num_unm(nvalue(&fs->f->k[e->info])));
else {
luaK_exp2anyreg(fs, e);
freeexp(fs, e);
diff --git a/src/ldblib.c b/src/ldblib.c
index 36d647aa..7f8bde1f 100644
--- a/src/ldblib.c
+++ b/src/ldblib.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldblib.c,v 1.89 2004/11/17 12:02:41 roberto Exp $
+** $Id: ldblib.c,v 1.93 2005/02/18 12:40:02 roberto Exp $
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/
@@ -19,6 +19,40 @@
+static int getmetatable (lua_State *L) {
+ luaL_checkany(L, 1);
+ if (!lua_getmetatable(L, 1)) {
+ lua_pushnil(L); /* no metatable */
+ }
+ return 1;
+}
+
+
+static int setmetatable (lua_State *L) {
+ int t = lua_type(L, 2);
+ luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
+ "nil or table expected");
+ lua_settop(L, 2);
+ lua_pushboolean(L, lua_setmetatable(L, 1));
+ return 1;
+}
+
+
+static int getfenv (lua_State *L) {
+ lua_getfenv(L, 1);
+ return 1;
+}
+
+
+static int setfenv (lua_State *L) {
+ luaL_checktype(L, 2, LUA_TTABLE);
+ lua_settop(L, 2);
+ if (lua_setfenv(L, 1) == 0)
+ luaL_error(L, "`setfenv' cannot change environment of given object");
+ return 1;
+}
+
+
static void settabss (lua_State *L, const char *i, const char *v) {
lua_pushstring(L, v);
lua_setfield(L, -2, i);
@@ -275,12 +309,17 @@ 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 = 0;
+ int level;
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_isnumber(L, arg+2)) {
+ level = lua_tointeger(L, arg+2);
+ lua_pop(L, 1);
+ }
+ else
+ level = (L == L1) ? 1 : 0; /* level 0 may be this own function */
if (lua_gettop(L) == arg)
lua_pushliteral(L, "");
else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */
@@ -323,6 +362,10 @@ static int errorfb (lua_State *L) {
static const luaL_reg dblib[] = {
+ {"getmetatable", getmetatable},
+ {"setmetatable", setmetatable},
+ {"getfenv", getfenv},
+ {"setfenv", setfenv},
{"getlocal", getlocal},
{"getinfo", getinfo},
{"gethook", gethook},
@@ -338,8 +381,6 @@ static const luaL_reg dblib[] = {
LUALIB_API int luaopen_debug (lua_State *L) {
luaL_openlib(L, LUA_DBLIBNAME, dblib, 0);
- lua_pushcfunction(L, errorfb);
- lua_setglobal(L, "_TRACEBACK");
return 1;
}
diff --git a/src/ldo.c b/src/ldo.c
index d75a7063..da46d39d 100644
--- a/src/ldo.c
+++ b/src/ldo.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldo.c,v 2.13 2004/12/03 20:35:33 roberto Exp $
+** $Id: ldo.c,v 2.14 2005/02/18 12:40:02 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -474,7 +474,7 @@ static void f_parser (lua_State *L, void *ud) {
luaC_checkGC(L);
tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z,
&p->buff, p->name);
- cl = luaF_newLclosure(L, tf->nups, gt(L));
+ cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L)));
cl->l.p = tf;
for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */
cl->l.upvals[i] = luaF_newupval(L);
diff --git a/src/lfunc.c b/src/lfunc.c
index af431cc3..1c95e781 100644
--- a/src/lfunc.c
+++ b/src/lfunc.c
@@ -1,5 +1,5 @@
/*
-** $Id: lfunc.c,v 2.5 2004/11/24 19:20:21 roberto Exp $
+** $Id: lfunc.c,v 2.9 2005/02/18 12:40:02 roberto Exp $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
@@ -20,20 +20,21 @@
-Closure *luaF_newCclosure (lua_State *L, int nelems) {
+Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) {
Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems)));
luaC_link(L, obj2gco(c), LUA_TFUNCTION);
c->c.isC = 1;
+ c->c.env = e;
c->c.nupvalues = cast(lu_byte, nelems);
return c;
}
-Closure *luaF_newLclosure (lua_State *L, int nelems, TValue *e) {
+Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) {
Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems)));
luaC_link(L, obj2gco(c), LUA_TFUNCTION);
c->l.isC = 0;
- c->l.g = *e;
+ c->l.env = e;
c->l.nupvalues = cast(lu_byte, nelems);
while (nelems--) c->l.upvals[nelems] = NULL;
return c;
@@ -43,42 +44,72 @@ Closure *luaF_newLclosure (lua_State *L, int nelems, TValue *e) {
UpVal *luaF_newupval (lua_State *L) {
UpVal *uv = luaM_new(L, UpVal);
luaC_link(L, obj2gco(uv), LUA_TUPVAL);
- uv->v = &uv->value;
+ uv->v = &uv->u.value;
setnilvalue(uv->v);
return uv;
}
UpVal *luaF_findupval (lua_State *L, StkId level) {
+ global_State *g = G(L);
GCObject **pp = &L->openupval;
UpVal *p;
UpVal *uv;
while ((p = ngcotouv(*pp)) != NULL && p->v >= level) {
- if (p->v == level) return p;
+ lua_assert(p->v != &p->u.value);
+ if (p->v == level) { /* found a corresponding upvalue? */
+ if (isdead(g, obj2gco(p))) /* is it dead? */
+ changewhite(obj2gco(p)); /* ressurect it */
+ return p;
+ }
pp = &p->next;
}
uv = luaM_new(L, UpVal); /* not found: create a new one */
uv->tt = LUA_TUPVAL;
- uv->marked = luaC_white(G(L));
+ uv->marked = luaC_white(g);
uv->v = level; /* current value lives in the stack */
uv->next = *pp; /* chain it in the proper position */
*pp = obj2gco(uv);
+ uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */
+ uv->u.l.next = g->uvhead.u.l.next;
+ uv->u.l.next->u.l.prev = uv;
+ g->uvhead.u.l.next = uv;
+ lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
return uv;
}
+static void unlinkupval (UpVal *uv) {
+ lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
+ uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */
+ uv->u.l.prev->u.l.next = uv->u.l.next;
+}
+
+
+void luaF_freeupval (lua_State *L, UpVal *uv) {
+ if (uv->v != &uv->u.value) /* is it open? */
+ unlinkupval(uv); /* remove from open list */
+ luaM_free(L, uv); /* free upvalue */
+}
+
+
void luaF_close (lua_State *L, StkId level) {
UpVal *uv;
global_State *g = G(L);
while ((uv = ngcotouv(L->openupval)) != NULL && uv->v >= level) {
GCObject *o = obj2gco(uv);
- lua_assert(!isblack(o));
+ lua_assert(!isblack(o) && uv->v != &uv->u.value);
L->openupval = uv->next; /* remove from `open' list */
if (isdead(g, o))
- luaM_free(L, uv); /* free upvalue */
+ luaF_freeupval(L, uv); /* free upvalue */
else {
- setobj(L, &uv->value, uv->v);
- uv->v = &uv->value; /* now current value lives here */
+ unlinkupval(uv);
+ setobj(L, &uv->u.value, uv->v);
+ if (isgray(o)) {
+ gray2black(o); /* closed upvalues are never gray */
+ luaC_barrier(L, uv, &uv->u.value);
+ }
+ uv->v = &uv->u.value; /* now current value lives here */
luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */
}
}
diff --git a/src/lfunc.h b/src/lfunc.h
index 04437601..93f7b888 100644
--- a/src/lfunc.h
+++ b/src/lfunc.h
@@ -1,5 +1,5 @@
/*
-** $Id: lfunc.h,v 2.1 2003/12/10 12:13:36 roberto Exp $
+** $Id: lfunc.h,v 2.3 2005/02/18 12:40:02 roberto Exp $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
@@ -19,13 +19,14 @@
Proto *luaF_newproto (lua_State *L);
-Closure *luaF_newCclosure (lua_State *L, int nelems);
-Closure *luaF_newLclosure (lua_State *L, int nelems, TValue *e);
+Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e);
+Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e);
UpVal *luaF_newupval (lua_State *L);
UpVal *luaF_findupval (lua_State *L, StkId level);
void luaF_close (lua_State *L, StkId level);
void luaF_freeproto (lua_State *L, Proto *f);
void luaF_freeclosure (lua_State *L, Closure *c);
+void luaF_freeupval (lua_State *L, UpVal *uv);
const char *luaF_getlocalname (const Proto *func, int local_number, int pc);
diff --git a/src/lgc.c b/src/lgc.c
index 9259bff0..dd7a6850 100644
--- a/src/lgc.c
+++ b/src/lgc.c
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.c,v 2.19 2004/12/13 12:15:11 roberto Exp $
+** $Id: lgc.c,v 2.27 2005/02/23 17:30:22 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -23,30 +23,26 @@
#include "ltm.h"
-#define GCSTEPSIZE 1000
-#define GCSWEEPMAX 10
-#define GCSWEEPCOST 30
+#define GCSTEPSIZE 1024u
+#define GCSWEEPMAX 40
+#define GCSWEEPCOST 10
#define GCFINALIZECOST 100
-#define GCSTEPMUL 8
-#define FIXEDMASK bitmask(FIXEDBIT)
-
#define maskmarks \
- cast(lu_byte, ~(bitmask(BLACKBIT)|bit2mask(WHITE0BIT, WHITE1BIT)))
+ cast(lu_byte, ~(bitmask(BLACKBIT)|WHITEBITS))
#define makewhite(g,x) \
- ((x)->gch.marked = ((x)->gch.marked & maskmarks) | g->currentwhite)
+ ((x)->gch.marked = ((x)->gch.marked & maskmarks) | luaC_white(g))
#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
-#define gray2black(x) setbit((x)->gch.marked, BLACKBIT)
#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT)
#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT)
#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT)
-#define markfinalized(u) setbit((u)->marked, FINALIZEDBIT)
+#define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT)
#define KEYWEAK bitmask(KEYWEAKBIT)
@@ -61,9 +57,11 @@
reallymarkobject(g, obj2gco(t)); }
+#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpace)
+
static void removeentry (Node *n) {
- setnilvalue(gval(n)); /* remove corresponding value ... */
+ lua_assert(ttisnil(gval(n)));
if (iscollectable(gkey(n)))
setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */
}
@@ -80,14 +78,14 @@ static void reallymarkobject (global_State *g, GCObject *o) {
Table *mt = gco2u(o)->metatable;
gray2black(o); /* udata are never gray */
if (mt) markobject(g, mt);
+ markobject(g, gco2u(o)->env);
return;
}
case LUA_TUPVAL: {
UpVal *uv = gco2uv(o);
- if (uv->v == &uv->value) { /* closed? */
- markvalue(g, uv->v);
- gray2black(o);
- }
+ markvalue(g, uv->v);
+ if (uv->v == &uv->u.value) /* closed? */
+ gray2black(o); /* open upvalues are never black */
return;
}
case LUA_TFUNCTION: {
@@ -116,22 +114,24 @@ static void reallymarkobject (global_State *g, GCObject *o) {
static void marktmu (global_State *g) {
- GCObject *u;
- for (u = g->tmudata; u; u = u->gch.next) {
- makewhite(g, u); /* may be marked, if left from previous GC */
- reallymarkobject(g, u);
+ GCObject *u = g->tmudata;
+ if (u) {
+ do {
+ u = u->gch.next;
+ makewhite(g, u); /* may be marked, if left from previous GC */
+ reallymarkobject(g, u);
+ } while (u != g->tmudata);
}
}
/* move `dead' udata that need finalization to list `tmudata' */
size_t luaC_separateudata (lua_State *L, int all) {
+ global_State *g = G(L);
size_t deadmem = 0;
- GCObject **p = &G(L)->firstudata;
+ GCObject **p = &g->mainthread->next;
GCObject *curr;
- GCObject *collected = NULL; /* to collect udata with gc event */
- GCObject **lastcollected = &collected;
- while ((curr = *p)->gch.tt == LUA_TUSERDATA) {
+ while ((curr = *p) != NULL) {
if (!(iswhite(curr) || all) || isfinalized(gco2u(curr)))
p = &curr->gch.next; /* don't bother with them */
else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) {
@@ -142,15 +142,16 @@ size_t luaC_separateudata (lua_State *L, int all) {
deadmem += sizeudata(gco2u(curr));
markfinalized(gco2u(curr));
*p = curr->gch.next;
- curr->gch.next = NULL; /* link `curr' at the end of `collected' list */
- *lastcollected = curr;
- lastcollected = &curr->gch.next;
+ /* link `curr' at the end of `tmudata' list */
+ if (g->tmudata == NULL) /* list is empty? */
+ g->tmudata = curr->gch.next = curr; /* creates a circular list */
+ else {
+ curr->gch.next = g->tmudata->gch.next;
+ g->tmudata->gch.next = curr;
+ g->tmudata = curr;
+ }
}
}
- lua_assert(curr == obj2gco(G(L)->mainthread));
- /* insert collected udata with gc event into `tmudata' list */
- *lastcollected = G(L)->tmudata;
- G(L)->tmudata = collected;
return deadmem;
}
@@ -162,7 +163,6 @@ static int traversetable (global_State *g, Table *h) {
const TValue *mode;
if (h->metatable)
markobject(g, h->metatable);
- lua_assert(h->lsizenode || h->node == g->dummynode);
mode = gfasttm(g, h->metatable, TM_MODE);
if (mode && ttisstring(mode)) { /* is there a weak mode? */
weakkey = (strchr(svalue(mode), 'k') != NULL);
@@ -223,6 +223,7 @@ static void traverseproto (global_State *g, Proto *f) {
static void traverseclosure (global_State *g, Closure *cl) {
+ markobject(g, cl->c.env);
if (cl->c.isC) {
int i;
for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */
@@ -231,7 +232,6 @@ static void traverseclosure (global_State *g, Closure *cl) {
else {
int i;
lua_assert(cl->l.nupvalues == cl->l.p->nups);
- markobject(g, hvalue(&cl->l.g));
markobject(g, cl->l.p);
for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */
markobject(g, cl->l.upvals[i]);
@@ -368,8 +368,10 @@ static void cleartable (GCObject *l) {
while (i--) {
Node *n = gnode(h, i);
if (!ttisnil(gval(n)) && /* non-empty entry? */
- (iscleared(key2tval(n), 1) || iscleared(gval(n), 0)))
+ (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) {
+ setnilvalue(gval(n)); /* remove value ... */
removeentry(n); /* remove entry from table */
+ }
}
l = h->gclist;
}
@@ -380,7 +382,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_free(L, gco2uv(o)); break;
+ case LUA_TUPVAL: luaF_freeupval(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);
@@ -402,26 +404,23 @@ static void freeobj (lua_State *L, GCObject *o) {
-#define sweepwholelist(L,p) sweeplist(L,p,LUA_MAXINT32)
+#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM)
-static GCObject **sweeplist (lua_State *L, GCObject **p, lu_int32 count) {
+static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
GCObject *curr;
global_State *g = G(L);
- int whitebit = otherwhite(g);
- int deadmask = whitebit | FIXEDMASK;
- int generational = g->gcgenerational;
+ int deadmask = otherwhite(g);
while ((curr = *p) != NULL && count-- > 0) {
- if ((curr->gch.marked ^ whitebit) & deadmask) {
+ if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */
+ sweepwholelist(L, &gco2th(curr)->openupval);
+ if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */
lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT));
- if (!generational || isdead(g, curr))
- makewhite(g, curr);
- if (curr->gch.tt == LUA_TTHREAD)
- sweepwholelist(L, &gco2th(curr)->openupval);
+ makewhite(g, curr); /* make it white (for next cycle) */
p = &curr->gch.next;
}
- else {
- lua_assert(isdead(g, curr));
+ else { /* must erase `curr' */
+ lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT));
*p = curr->gch.next;
if (curr == g->rootgc) /* is the first element of the list? */
g->rootgc = curr->gch.next; /* adjust first */
@@ -432,21 +431,10 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_int32 count) {
}
-
-static void freelist (lua_State *L, GCObject **p) {
- while (*p) {
- GCObject *curr = *p;
- *p = (*p)->gch.next;
- if (curr != obj2gco(L))
- freeobj(L, curr);
- }
-}
-
-
static void checkSizes (lua_State *L) {
global_State *g = G(L);
/* check size of string hash */
- if (g->strt.nuse < cast(lu_int32, G(L)->strt.size/4) &&
+ if (g->strt.nuse < cast(lu_int32, g->strt.size/4) &&
g->strt.size > MINSTRTABSIZE*2)
luaS_resize(L, g->strt.size/2); /* table is too big */
/* check size of buffer */
@@ -459,22 +447,29 @@ static void checkSizes (lua_State *L) {
static void GCTM (lua_State *L) {
global_State *g = G(L);
- GCObject *o = g->tmudata;
+ GCObject *o = g->tmudata->gch.next; /* get first element */
Udata *udata = rawgco2u(o);
const TValue *tm;
- g->tmudata = udata->uv.next; /* remove udata from `tmudata' */
- udata->uv.next = g->firstudata->uv.next; /* return it to `root' list */
- g->firstudata->uv.next = o;
+ /* remove udata from `tmudata' */
+ if (o == g->tmudata) /* last element? */
+ g->tmudata = NULL;
+ else
+ g->tmudata->gch.next = udata->uv.next;
+ udata->uv.next = g->mainthread->next; /* return it to `root' list */
+ g->mainthread->next = o;
makewhite(g, o);
tm = fasttm(L, udata->uv.metatable, TM_GC);
if (tm != NULL) {
lu_byte oldah = L->allowhook;
+ lu_mem oldt = g->GCthreshold;
L->allowhook = 0; /* stop debug hooks during GC tag method */
+ g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */
setobj2s(L, L->top, tm);
setuvalue(L, L->top+1, udata);
L->top += 2;
luaD_call(L, L->top - 2, 0);
L->allowhook = oldah; /* restore hooks */
+ g->GCthreshold = oldt; /* restore threshold */
}
}
@@ -491,9 +486,10 @@ void luaC_callGCTM (lua_State *L) {
void luaC_freeall (lua_State *L) {
global_State *g = G(L);
int i;
- freelist(L, &g->rootgc);
+ g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */
+ sweepwholelist(L, &g->rootgc);
for (i = 0; i < g->strt.size; i++) /* free all string lists */
- freelist(L, &G(L)->strt.hash[i]);
+ sweepwholelist(L, &g->strt.hash[i]);
}
@@ -512,18 +508,11 @@ static void markroot (lua_State *L) {
static void remarkupvals (global_State *g) {
- GCObject *o;
- for (o = obj2gco(g->mainthread); o; o = o->gch.next) {
- lua_assert(!isblack(o));
- if (iswhite(o)) {
- GCObject *curr;
- for (curr = gco2th(o)->openupval; curr != NULL; curr = curr->gch.next) {
- if (isgray(curr)) {
- UpVal *uv = gco2uv(curr);
- markvalue(g, uv->v);
- }
- }
- }
+ UpVal *uv;
+ for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {
+ lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
+ if (isgray(obj2gco(uv)))
+ markvalue(g, uv->v);
}
}
@@ -531,7 +520,6 @@ 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);
/* remark occasional upvalues of (maybe) dead threads */
@@ -555,10 +543,6 @@ static void atomic (lua_State *L) {
g->sweepstrgc = 0;
g->sweepgc = &g->rootgc;
g->gcstate = GCSsweepstring;
- aux = g->gcgenerational;
- 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 - udsize; /* first estimate */
}
@@ -568,11 +552,7 @@ static l_mem singlestep (lua_State *L) {
/*lua_checkmemory(L);*/
switch (g->gcstate) {
case GCSpause: {
- /* start a new collection */
- if (g->gcgenerational)
- atomic(L);
- else
- markroot(L);
+ markroot(L); /* start a new collection */
return 0;
}
case GCSpropagate: {
@@ -605,13 +585,12 @@ static l_mem singlestep (lua_State *L) {
}
case GCSfinalize: {
if (g->tmudata) {
- g->GCthreshold += GCFINALIZECOST; /* avoid GC steps inside method */
GCTM(L);
- g->GCthreshold -= GCFINALIZECOST; /* correct threshold */
return GCFINALIZECOST;
}
else {
g->gcstate = GCSpause; /* end collection */
+ g->gcdept = 0;
return 0;
}
}
@@ -622,25 +601,33 @@ 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)) * GCSTEPMUL;
+ l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul;
+ if (lim == 0)
+ lim = (MAX_LUMEM-1)/2; /* no limit */
+ g->gcdept += g->totalbytes - g->GCthreshold;
do {
lim -= singlestep(L);
if (g->gcstate == GCSpause)
break;
- } while (lim > 0 || !g->incgc);
- if (g->gcstate != GCSpause)
- g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/STEPMUL; */
+ } while (lim > 0);
+ if (g->gcstate != GCSpause) {
+ if (g->gcdept < GCSTEPSIZE)
+ g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/
+ else {
+ g->gcdept -= GCSTEPSIZE;
+ g->GCthreshold = g->totalbytes;
+ }
+ }
else {
lua_assert(g->totalbytes >= g->estimate);
- g->GCthreshold = g->estimate + ((g->estimate/GCDIV) * g->gcpace);
+ setthreshold(g);
}
}
void luaC_fullgc (lua_State *L) {
global_State *g = G(L);
- if (g->gcstate <= GCSpropagate || g->gcgenerational) {
- g->gcgenerational = 0;
+ if (g->gcstate <= GCSpropagate) {
/* reset sweep marks to sweep all elements (returning them to white) */
g->sweepstrgc = 0;
g->sweepgc = &g->rootgc;
@@ -650,40 +637,37 @@ void luaC_fullgc (lua_State *L) {
g->weak = NULL;
g->gcstate = GCSsweepstring;
}
+ lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate);
/* finish any pending sweep phase */
while (g->gcstate != GCSfinalize) {
lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);
singlestep(L);
}
markroot(L);
- lua_assert(!g->gcgenerational);
while (g->gcstate != GCSpause) {
singlestep(L);
- g->gcgenerational = 0; /* keep it in this mode */
}
- g->GCthreshold = 2*g->estimate;
+ setthreshold(g);
}
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 && g->gcstate != GCSpause));
+ lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
lua_assert(ttype(&o->gch) != LUA_TTABLE);
/* must keep invariant? */
- if (g->gcstate == GCSpropagate || g->gcgenerational)
+ if (g->gcstate == GCSpropagate)
reallymarkobject(g, v); /* restore invariant */
else /* don't mind */
makewhite(g, o); /* mark as white just to avoid other barriers */
}
-void luaC_barrierback (lua_State *L, GCObject *o, GCObject *v) {
+void luaC_barrierback (lua_State *L, GCObject *o) {
global_State *g = G(L);
- lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
- lua_assert(g->gcgenerational ||
- (g->gcstate != GCSfinalize && g->gcstate != GCSpause));
+ lua_assert(isblack(o) && !isdead(g, o));
+ lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
black2gray(o); /* make table gray (again) */
gco2h(o)->gclist = g->grayagain;
g->grayagain = o;
@@ -705,7 +689,7 @@ void luaC_linkupval (lua_State *L, UpVal *uv) {
o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */
g->rootgc = o;
if (isgray(o)) {
- if (g->gcstate == GCSpropagate || g->gcgenerational) {
+ if (g->gcstate == GCSpropagate) {
gray2black(o); /* closed upvalues need barrier */
luaC_barrier(L, uv, uv->v);
}
diff --git a/src/lgc.h b/src/lgc.h
index 81f6da5f..43d4009a 100644
--- a/src/lgc.h
+++ b/src/lgc.h
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.h,v 2.9 2004/09/15 20:38:15 roberto Exp $
+** $Id: lgc.h,v 2.12 2005/02/23 17:30:22 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -29,7 +29,7 @@
#define testbits(x,m) ((x) & (m))
#define bitmask(b) (1<<(b))
#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2))
-#define setbit(x,b) setbits(x, bitmask(b))
+#define l_setbit(x,b) setbits(x, bitmask(b))
#define resetbit(x,b) resetbits(x, bitmask(b))
#define testbit(x,b) testbits(x, bitmask(b))
#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2)))
@@ -47,8 +47,10 @@
** bit 3 - for tables: has weak keys
** bit 4 - for tables: has weak values
** bit 5 - object is fixed (should not be collected)
+** bit 6 - object is "super" fixed (only the main thread)
*/
+
#define WHITE0BIT 0
#define WHITE1BIT 1
#define BLACKBIT 2
@@ -56,20 +58,23 @@
#define KEYWEAKBIT 3
#define VALUEWEAKBIT 4
#define FIXEDBIT 5
+#define SFIXEDBIT 6
+#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
#define isblack(x) testbit((x)->gch.marked, BLACKBIT)
#define isgray(x) (!isblack(x) && !iswhite(x))
-#define otherwhite(g) (g->currentwhite ^ bit2mask(WHITE0BIT, WHITE1BIT))
-#define isdead(g,v) ((v)->gch.marked & otherwhite(g))
+#define otherwhite(g) (g->currentwhite ^ WHITEBITS)
+#define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS)
-#define changewhite(x) ((x)->gch.marked ^= bit2mask(WHITE0BIT, WHITE1BIT))
+#define changewhite(x) ((x)->gch.marked ^= WHITEBITS)
+#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT)
#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x)))
-#define luaC_white(g) cast(lu_byte, (g)->currentwhite)
+#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
#define luaC_checkGC(L) { if (G(L)->totalbytes >= G(L)->GCthreshold) \
@@ -80,7 +85,7 @@
luaC_barrierf(L,obj2gco(p),gcvalue(v)); }
#define luaC_barriert(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \
- luaC_barrierback(L,obj2gco(p),gcvalue(v)); }
+ luaC_barrierback(L,obj2gco(p)); }
#define luaC_objbarrier(L,p,o) \
{ if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
@@ -88,7 +93,7 @@
#define luaC_objbarriert(L,p,o) \
{ if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
- luaC_barrierback(L,obj2gco(p),obj2gco(o)); }
+ luaC_barrierback(L,obj2gco(p)); }
size_t luaC_separateudata (lua_State *L, int all);
void luaC_callGCTM (lua_State *L);
@@ -98,7 +103,7 @@ void luaC_fullgc (lua_State *L);
void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
void luaC_linkupval (lua_State *L, UpVal *uv);
void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v);
-void luaC_barrierback (lua_State *L, GCObject *o, GCObject *v);
+void luaC_barrierback (lua_State *L, GCObject *o);
#endif
diff --git a/src/linit.c b/src/linit.c
index 0d5f9cd4..24f70edb 100644
--- a/src/linit.c
+++ b/src/linit.c
@@ -1,5 +1,5 @@
/*
-** $Id: linit.c,v 1.8 2004/07/09 15:47:48 roberto Exp $
+** $Id: linit.c,v 1.9 2005/02/18 12:40:02 roberto Exp $
** Initialization of libraries for lua.c
** See Copyright Notice in lua.h
*/
@@ -32,6 +32,8 @@ LUALIB_API int luaopen_stdlibs (lua_State *L) {
for (; lib->func; lib++) {
lib->func(L); /* open library */
lua_settop(L, 0); /* discard any results */
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
+ lua_replace(L, LUA_ENVIRONINDEX); /* restore environment */
}
return 0;
}
diff --git a/src/liolib.c b/src/liolib.c
index ca9b8025..854ba3ba 100644
--- a/src/liolib.c
+++ b/src/liolib.c
@@ -1,5 +1,5 @@
/*
-** $Id: liolib.c,v 2.57 2004/08/13 19:52:13 roberto Exp $
+** $Id: liolib.c,v 2.58 2005/02/18 12:40:02 roberto Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@@ -105,8 +105,8 @@ static int aux_close (lua_State *L) {
static int io_close (lua_State *L) {
- if (lua_isnone(L, 1) && lua_type(L, lua_upvalueindex(1)) == LUA_TTABLE)
- lua_rawgeti(L, lua_upvalueindex(1), IO_OUTPUT);
+ if (lua_isnone(L, 1))
+ lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT);
return pushresult(L, aux_close(L), NULL);
}
@@ -147,7 +147,7 @@ static int io_tmpfile (lua_State *L) {
static FILE *getiofile (lua_State *L, int findex) {
FILE *f;
- lua_rawgeti(L, lua_upvalueindex(1), findex);
+ lua_rawgeti(L, LUA_ENVIRONINDEX, findex);
lua_assert(luaL_checkudata(L, -1, LUA_FILEHANDLE));
f = *(FILE **)lua_touserdata(L, -1);
if (f == NULL)
@@ -170,10 +170,10 @@ static int g_iofile (lua_State *L, int f, const char *mode) {
lua_pushvalue(L, 1);
}
lua_assert(luaL_checkudata(L, -1, LUA_FILEHANDLE));
- lua_rawseti(L, lua_upvalueindex(1), f);
+ lua_rawseti(L, LUA_ENVIRONINDEX, f);
}
/* return current value */
- lua_rawgeti(L, lua_upvalueindex(1), f);
+ lua_rawgeti(L, LUA_ENVIRONINDEX, f);
return 1;
}
@@ -192,10 +192,9 @@ static int io_readline (lua_State *L);
static void aux_lines (lua_State *L, int idx, int close) {
- lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
lua_pushvalue(L, idx);
lua_pushboolean(L, close); /* close/not close file when finished */
- lua_pushcclosure(L, io_readline, 3);
+ lua_pushcclosure(L, io_readline, 2);
}
@@ -209,7 +208,7 @@ static int f_lines (lua_State *L) {
static int io_lines (lua_State *L) {
if (lua_isnoneornil(L, 1)) { /* no arguments? */
/* will iterate over default input */
- lua_rawgeti(L, lua_upvalueindex(1), IO_INPUT);
+ lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT);
return f_lines(L);
}
else {
@@ -349,7 +348,7 @@ static int f_read (lua_State *L) {
static int io_readline (lua_State *L) {
- FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(2));
+ FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1));
int sucess;
if (f == NULL) /* file is already closed? */
luaL_error(L, "file is already closed");
@@ -358,9 +357,9 @@ static int io_readline (lua_State *L) {
luaL_error(L, "%s", strerror(errno));
if (sucess) return 1;
else { /* EOF */
- if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */
+ if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */
lua_settop(L, 0);
- lua_pushvalue(L, lua_upvalueindex(2));
+ lua_pushvalue(L, lua_upvalueindex(1));
aux_close(L); /* close it */
}
return 0;
@@ -489,12 +488,13 @@ LUALIB_API int luaopen_io (lua_State *L) {
createmeta(L);
createupval(L);
lua_pushvalue(L, -1);
- luaL_openlib(L, LUA_IOLIBNAME, iolib, 1);
+ lua_replace(L, LUA_ENVIRONINDEX);
+ luaL_openlib(L, LUA_IOLIBNAME, iolib, 0);
/* put predefined file handles into `io' table */
- lua_rawgeti(L, -2, IO_INPUT); /* get current input from metatable */
- lua_setfield(L, -2, "stdin"); /* io.stdin = metatable[IO_INPUT] */
- lua_rawgeti(L, -2, IO_OUTPUT); /* get current output from metatable */
- lua_setfield(L, -2, "stdout"); /* io.stdout = metatable[IO_OUTPUT] */
+ lua_rawgeti(L, -2, IO_INPUT); /* get current input from upval */
+ lua_setfield(L, -2, "stdin"); /* io.stdin = upval[IO_INPUT] */
+ lua_rawgeti(L, -2, IO_OUTPUT); /* get current output from upval */
+ lua_setfield(L, -2, "stdout"); /* io.stdout = upval[IO_OUTPUT] */
*newfile(L) = stderr;
lua_setfield(L, -2, "stderr"); /* io.stderr = newfile(stderr) */
return 1;
diff --git a/src/llimits.h b/src/llimits.h
index c3d5d532..5b11e820 100644
--- a/src/llimits.h
+++ b/src/llimits.h
@@ -1,5 +1,5 @@
/*
-** $Id: llimits.h,v 1.62 2004/12/13 12:15:11 roberto Exp $
+** $Id: llimits.h,v 1.63 2005/01/14 14:19:42 roberto Exp $
** Limits, basic types, and some other `installation-dependent' definitions
** See Copyright Notice in lua.h
*/
@@ -73,8 +73,6 @@ typedef LUA_UACNUMBER l_uacNumber;
typedef lu_int32 Instruction;
-/* divisor for GC pace */
-#define GCDIV 8
/* maximum stack for a Lua function */
#define MAXSTACK 250
diff --git a/src/lmathlib.c b/src/lmathlib.c
index fcd2eefb..add88970 100644
--- a/src/lmathlib.c
+++ b/src/lmathlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lmathlib.c,v 1.61 2004/05/10 18:11:32 roberto Exp $
+** $Id: lmathlib.c,v 1.62 2005/01/07 20:00:33 roberto Exp $
** Standard mathematical library
** See Copyright Notice in lua.h
*/
@@ -225,8 +225,6 @@ LUALIB_API int luaopen_math (lua_State *L) {
luaL_openlib(L, LUA_MATHLIBNAME, mathlib, 0);
lua_pushnumber(L, PI);
lua_setfield(L, -2, "pi");
- lua_pushcfunction(L, math_pow);
- lua_setglobal(L, "__pow");
return 1;
}
diff --git a/src/lmem.c b/src/lmem.c
index 632990fc..dd909655 100644
--- a/src/lmem.c
+++ b/src/lmem.c
@@ -1,5 +1,5 @@
/*
-** $Id: lmem.c,v 1.67 2004/12/01 15:46:18 roberto Exp $
+** $Id: lmem.c,v 1.69 2005/02/23 17:30:22 roberto Exp $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
@@ -22,19 +22,19 @@
/*
** About the realloc function:
-** void * realloc (void *ud, void *ptr, size_t osize, size_t nsize);
+** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
** (`osize' is the old size, `nsize' is the new size)
**
** Lua ensures that (ptr == NULL) iff (osize == 0).
**
-** * realloc(ud, NULL, 0, x) creates a new block of size `x'
+** * frealloc(ud, NULL, 0, x) creates a new block of size `x'
**
-** * realloc(ud, p, x, 0) frees the block `p'
-** (in this specific case, realloc must return NULL).
-** particularly, realloc(ud, NULL, 0, 0) does nothing
+** * frealloc(ud, p, x, 0) frees the block `p'
+** (in this specific case, frealloc must return NULL).
+** particularly, frealloc(ud, NULL, 0, 0) does nothing
** (which is equivalent to free(NULL) in ANSI C)
**
-** realloc returns NULL if it cannot create or reallocate the area
+** frealloc returns NULL if it cannot create or reallocate the area
** (any reallocation to an equal or smaller size cannot fail!)
*/
@@ -76,11 +76,27 @@ void *luaM_toobig (lua_State *L) {
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));
- block = (*g->realloc)(g->ud, block, osize, nsize);
+ block = (*g->frealloc)(g->ud, block, osize, nsize);
if (block == NULL && nsize > 0)
luaD_throw(L, LUA_ERRMEM);
lua_assert((nsize == 0) == (block == NULL));
g->totalbytes = (g->totalbytes - osize) + nsize;
+#if 0
+ { /* auxiliar patch to monitor garbage collection */
+ static unsigned long total = 0; /* our "time" */
+ static lu_mem last = 0; /* last totalmem that generated an output */
+ static FILE *f = NULL; /* output file */
+ if (nsize <= osize) total += 1; /* "time" always grow */
+ else total += (nsize - osize);
+ if ((int)g->totalbytes - (int)last > 1000 ||
+ (int)g->totalbytes - (int)last < -1000) {
+ last = g->totalbytes;
+ if (f == NULL) f = fopen("trace", "w");
+ fprintf(f, "%lu %u %u %u %d\n", total, g->totalbytes, g->GCthreshold,
+ g->estimate, g->gcstate);
+ }
+ }
+#endif
return block;
}
diff --git a/src/loadlib.c b/src/loadlib.c
index 4adcbdc0..957310b6 100644
--- a/src/loadlib.c
+++ b/src/loadlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: loadlib.c,v 1.15 2004/12/29 18:56:34 roberto Exp $
+** $Id: loadlib.c,v 1.18 2005/02/28 15:58:48 roberto Exp $
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
*
@@ -293,45 +293,60 @@ static int ll_loadlib (lua_State *L) {
*/
-static const char *loadLua (lua_State *L, const char *fname, const char *name) {
+static int loader_Lua (lua_State *L) {
+ const char *name = luaL_checkstring(L, 1);
+ const char *fname = luaL_gsub(L, name, ".", LUA_DIRSEP);
const char *path;
/* try first `LUA_PATH' for compatibility */
- lua_getglobal(L, "LUA_PATH");
+ lua_pushstring(L, "LUA_PATH");
+ lua_rawget(L, LUA_GLOBALSINDEX);
path = lua_tostring(L, -1);
if (!path) {
lua_pop(L, 1);
- luaL_getfield(L, LUA_GLOBALSINDEX, "package.path");
+ lua_getfield(L, LUA_ENVIRONINDEX, "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 (fname == NULL) return 0; /* library not found in this path */
if (luaL_loadfile(L, fname) != 0)
luaL_error(L, "error loading package `%s' (%s)", name, lua_tostring(L, -1));
- return NULL; /* library loaded successfully */
+ return 1; /* library loaded successfully */
}
-static const char *loadC (lua_State *L, const char *fname, const char *name) {
+static int loader_C (lua_State *L) {
+ const char *name = luaL_checkstring(L, 1);
+ const char *fname = luaL_gsub(L, name, ".", LUA_DIRSEP);
const char *path;
const char *funcname;
- luaL_getfield(L, LUA_GLOBALSINDEX, "package.cpath");
+ lua_getfield(L, LUA_ENVIRONINDEX, "cpath");
path = lua_tostring(L, -1);
if (path == NULL)
luaL_error(L, "`package.cpath' must be a string");
fname = luaL_searchpath(L, fname, path);
- if (fname == NULL) return path; /* library not found in this path */
+ if (fname == NULL) return 0; /* library not found in this path */
funcname = luaL_gsub(L, name, ".", LUA_OFSEP);
funcname = lua_pushfstring(L, "%s%s", POF, funcname);
if (ll_loadfunc(L, fname, funcname) != 1)
luaL_error(L, "error loading package `%s' (%s)", name, lua_tostring(L, -2));
- return NULL; /* library loaded successfully */
+ return 1; /* library loaded successfully */
+}
+
+
+static int loader_preload (lua_State *L) {
+ lua_getfield(L, LUA_ENVIRONINDEX, "preload");
+ if (!lua_istable(L, -1))
+ luaL_error(L, "`package.preload' must be a table");
+ lua_getfield(L, -1, luaL_checkstring(L, 1));
+ return 1;
}
static int ll_require (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
+ int i;
lua_settop(L, 1);
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
lua_getfield(L, 2, name);
@@ -340,22 +355,18 @@ static int ll_require (lua_State *L) {
/* 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);
- }
- }
+ /* iterate over available loaders */
+ lua_getfield(L, LUA_ENVIRONINDEX, "loaders");
+ if (!lua_istable(L, -1))
+ luaL_error(L, "`package.loaders' must be a table");
+ for (i=1;; i++) {
+ lua_rawgeti(L, -1, i); /* get a loader */
+ if (lua_isnil(L, -1))
+ return luaL_error(L, "package `%s' not found", name);
+ lua_pushstring(L, name);
+ lua_call(L, 1, 1); /* call it */
+ if (lua_isnil(L, -1)) lua_pop(L, 1);
+ else break; /* module loaded successfully */
}
lua_pushvalue(L, 1); /* pass name as argument to module */
lua_call(L, 1, 1); /* run loaded module */
@@ -430,9 +441,13 @@ static const luaL_reg ll_funcs[] = {
};
+static const lua_CFunction loaders[] =
+ {loader_preload, loader_C, loader_Lua, NULL};
+
LUALIB_API int luaopen_loadlib (lua_State *L) {
const char *path;
+ int i;
/* create new type _LOADLIB */
luaL_newmetatable(L, "_LOADLIB");
lua_pushcfunction(L, gctm);
@@ -441,6 +456,19 @@ LUALIB_API int luaopen_loadlib (lua_State *L) {
lua_newtable(L);
lua_pushvalue(L, -1);
lua_setglobal(L, "package");
+ lua_pushvalue(L, -1);
+ lua_setfield(L, LUA_REGISTRYINDEX, "_PACKAGE");
+ lua_pushvalue(L, -1);
+ lua_replace(L, LUA_ENVIRONINDEX);
+ /* create `loaders' table */
+ lua_newtable(L);
+ /* fill it with pre-defined loaders */
+ for (i=0; loaders[i] != NULL; i++) {
+ lua_pushcfunction(L, loaders[i]);
+ lua_rawseti(L, -2, i+1);
+ }
+ /* put it in field `loaders' */
+ lua_setfield(L, -2, "loaders");
/* set field `path' */
path = getenv(LUA_PATH);
if (path == NULL) path = LUA_PATH_DEFAULT;
@@ -455,7 +483,7 @@ LUALIB_API int luaopen_loadlib (lua_State *L) {
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
lua_setfield(L, -2, "loaded");
/* set field `preload' */
- lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD");
+ lua_newtable(L);
lua_setfield(L, -2, "preload");
lua_pushvalue(L, LUA_GLOBALSINDEX);
luaL_openlib(L, NULL, ll_funcs, 0); /* open lib into global table */
diff --git a/src/lobject.c b/src/lobject.c
index 154a0faf..f4464474 100644
--- a/src/lobject.c
+++ b/src/lobject.c
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.c,v 2.7 2004/11/24 19:16:03 roberto Exp $
+** $Id: lobject.c,v 2.8 2005/01/10 18:17:39 roberto Exp $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
@@ -73,7 +73,7 @@ int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
case LUA_TNIL:
return 1;
case LUA_TNUMBER:
- return nvalue(t1) == nvalue(t2);
+ return num_eq(nvalue(t1), nvalue(t2));
case LUA_TBOOLEAN:
return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
case LUA_TLIGHTUSERDATA:
diff --git a/src/lobject.h b/src/lobject.h
index 56c0fe8a..967b46c7 100644
--- a/src/lobject.h
+++ b/src/lobject.h
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.h,v 2.8 2004/12/04 18:10:22 roberto Exp $
+** $Id: lobject.h,v 2.11 2005/02/18 12:40:02 roberto Exp $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@@ -218,6 +218,7 @@ typedef union Udata {
struct {
CommonHeader;
struct Table *metatable;
+ struct Table *env;
size_t len;
} uv;
} Udata;
@@ -271,7 +272,13 @@ typedef struct LocVar {
typedef struct UpVal {
CommonHeader;
TValue *v; /* points to stack or to its own value */
- TValue value; /* the value (when closed) */
+ union {
+ TValue value; /* the value (when closed) */
+ struct { /* double linked list (when open) */
+ struct UpVal *prev;
+ struct UpVal *next;
+ } l;
+ } u;
} UpVal;
@@ -280,7 +287,8 @@ typedef struct UpVal {
*/
#define ClosureHeader \
- CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist
+ CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \
+ struct Table *env
typedef struct CClosure {
ClosureHeader;
@@ -292,7 +300,6 @@ typedef struct CClosure {
typedef struct LClosure {
ClosureHeader;
struct Proto *p;
- TValue g; /* global table for this closure */
UpVal *upvals[1];
} LClosure;
@@ -330,7 +337,7 @@ typedef struct Table {
struct Table *metatable;
TValue *array; /* array part */
Node *node;
- Node *firstfree; /* this position is free; all positions after it are full */
+ Node *lastfree; /* any free position is before this position */
GCObject *gclist;
int sizearray; /* size of `array' array */
} Table;
@@ -351,6 +358,8 @@ typedef struct Table {
extern const TValue luaO_nilobject;
+#define ceillog2(x) (luaO_log2((x)-1) + 1)
+
int luaO_log2 (unsigned int x);
int luaO_int2fb (unsigned int x);
int luaO_fb2int (int x);
diff --git a/src/loslib.c b/src/loslib.c
index 4f1d2d03..dad959e2 100644
--- a/src/loslib.c
+++ b/src/loslib.c
@@ -1,5 +1,5 @@
/*
-** $Id: loslib.c,v 1.3 2004/10/08 18:57:16 roberto Exp $
+** $Id: loslib.c,v 1.4 2005/01/10 19:16:29 roberto Exp $
** Standard Operating System library
** See Copyright Notice in lua.h
*/
@@ -91,15 +91,13 @@ static int io_clock (lua_State *L) {
*/
static void setfield (lua_State *L, const char *key, int value) {
- lua_pushstring(L, key);
lua_pushinteger(L, value);
- lua_rawset(L, -3);
+ lua_setfield(L, -2, key);
}
static void setboolfield (lua_State *L, const char *key, int value) {
- lua_pushstring(L, key);
lua_pushboolean(L, value);
- lua_rawset(L, -3);
+ lua_setfield(L, -2, key);
}
static int getboolfield (lua_State *L, const char *key) {
diff --git a/src/lparser.c b/src/lparser.c
index b6b3c0a0..19e048ce 100644
--- a/src/lparser.c
+++ b/src/lparser.c
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.c,v 2.11 2004/12/07 18:31:16 roberto Exp $
+** $Id: lparser.c,v 2.13 2005/01/05 18:20:51 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -547,7 +547,7 @@ static void constructor (LexState *ls, expdesc *t) {
check_match(ls, '}', '{', line);
lastlistfield(fs, &cc);
SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
- SETARG_C(fs->f->code[pc], luaO_log2(cc.nh)+1); /* set initial table size */
+ SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */
}
/* }====================================================================== */
diff --git a/src/lstate.c b/src/lstate.c
index bd238c58..18dd4f95 100644
--- a/src/lstate.c
+++ b/src/lstate.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.c,v 2.19 2004/12/13 12:15:11 roberto Exp $
+** $Id: lstate.c,v 2.25 2005/02/23 17:30:22 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
@@ -76,33 +76,22 @@ static void freestack (lua_State *L, lua_State *L1) {
** open parts that may cause memory-allocation errors
*/
static void f_luaopen (lua_State *L, void *ud) {
- Udata *u; /* head of udata list */
global_State *g = G(L);
UNUSED(ud);
- u = luaM_new(L, Udata);
- u->uv.len = 0;
- u->uv.metatable = NULL;
- g->firstudata = obj2gco(u);
- luaC_link(L, obj2gco(u), LUA_TUSERDATA);
- setbit(u->uv.marked, FIXEDBIT);
- setbit(L->marked, FIXEDBIT);
stack_init(L, L); /* init stack */
- sethvalue(L, gt(L), luaH_new(L, 0, 4)); /* table of globals */
+ sethvalue(L, gt(L), luaH_new(L, 0, 20)); /* table of globals */
hvalue(gt(L))->metatable = luaH_new(L, 0, 0); /* globals metatable */
- sethvalue(L, registry(L), luaH_new(L, 4, 4)); /* registry */
+ sethvalue(L, registry(L), luaH_new(L, 6, 20)); /* registry */
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
luaT_init(L);
luaX_init(L);
luaS_fix(luaS_newliteral(L, MEMERRMSG));
g->GCthreshold = 4*g->totalbytes;
- g->prevestimate = g->estimate = g->totalbytes;
}
static void preinit_state (lua_State *L, global_State *g) {
L->l_G = g;
- L->tt = LUA_TTHREAD;
- L->marked = luaC_white(g);
L->stack = NULL;
L->stacksize = 0;
L->errorJmp = NULL;
@@ -125,20 +114,19 @@ static void close_state (lua_State *L) {
global_State *g = G(L);
luaF_close(L, L->stack); /* close all upvalues for this thread */
luaC_freeall(L); /* collect all objects */
- lua_assert(g->rootgc == NULL);
+ lua_assert(g->rootgc == obj2gco(L));
lua_assert(g->strt.nuse == 0);
luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
luaZ_freebuffer(L, &g->buff);
freestack(L, L);
lua_assert(g->totalbytes == sizeof(LG));
- (*g->realloc)(g->ud, fromstate(L), state_size(LG), 0);
+ (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0);
}
lua_State *luaE_newthread (lua_State *L) {
lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State)));
- L1->next = L->next; /* link new thread after `L' */
- L->next = obj2gco(L1);
+ luaC_link(L, obj2gco(L1), LUA_TTHREAD);
preinit_state(L1, G(L));
stack_init(L1, L); /* init stack */
setobj2n(L, gt(L1), gt(L)); /* share table of globals */
@@ -167,11 +155,16 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
L = tostate(l);
g = &((LG *)L)->g;
L->next = NULL;
- g->currentwhite = bitmask(WHITE0BIT);
+ L->tt = LUA_TTHREAD;
+ g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
+ L->marked = luaC_white(g);
+ set2bits(L->marked, FIXEDBIT, SFIXEDBIT);
preinit_state(L, g);
- g->realloc = f;
+ g->frealloc = f;
g->ud = ud;
g->mainthread = L;
+ g->uvhead.u.l.prev = &g->uvhead;
+ g->uvhead.u.l.next = &g->uvhead;
g->GCthreshold = 0; /* mark it as unfinished state */
g->strt.size = 0;
g->strt.nuse = 0;
@@ -180,21 +173,17 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
luaZ_initbuffer(L, &g->buff);
g->panic = NULL;
g->gcstate = GCSpause;
- g->gcgenerational = 0;
g->rootgc = obj2gco(L);
g->sweepstrgc = 0;
g->sweepgc = &g->rootgc;
- g->firstudata = NULL;
g->gray = NULL;
g->grayagain = NULL;
g->weak = NULL;
g->tmudata = NULL;
- setnilvalue(gkey(g->dummynode));
- setnilvalue(gval(g->dummynode));
- gnext(g->dummynode) = NULL;
g->totalbytes = sizeof(LG);
- g->gcpace = GCDIV;
- g->incgc = 1;
+ g->gcpace = 200; /* 200% (wait memory to double before next collection) */
+ g->gcstepmul = 200; /* GC runs `twice the speed' of memory allocation */
+ g->gcdept = 0;
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 4f29190a..54469172 100644
--- a/src/lstate.h
+++ b/src/lstate.h
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.h,v 2.10 2004/12/13 12:15:11 roberto Exp $
+** $Id: lstate.h,v 2.16 2005/02/23 17:30:22 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
@@ -67,30 +67,28 @@ typedef struct CallInfo {
*/
typedef struct global_State {
stringtable strt; /* hash table for strings */
- lua_Alloc realloc; /* function to reallocate memory */
- void *ud; /* auxiliary data to `realloc' */
+ lua_Alloc frealloc; /* function to reallocate memory */
+ void *ud; /* auxiliary data to `frealloc' */
lu_byte currentwhite;
lu_byte gcstate; /* state of garbage collector */
- lu_byte gcgenerational;
GCObject *rootgc; /* list of all collectable objects */
- GCObject *firstudata; /* udata go to the end of `rootgc' */
GCObject **sweepgc; /* position of sweep in `rootgc' */
int sweepstrgc; /* position of sweep in `strt' */
GCObject *gray; /* list of gray objects */
GCObject *grayagain; /* list of objects to be traversed atomically */
GCObject *weak; /* list of weak tables (to be cleared) */
- GCObject *tmudata; /* list of userdata to be GC */
+ GCObject *tmudata; /* last element of list of userdata to be GC */
Mbuffer buff; /* temporary buffer for string concatentation */
lu_mem GCthreshold;
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 gcpace; /* relative `speed' of the GC */
- int incgc; /* 0 if GC is done non-incrementally */
+ lu_mem gcdept; /* how much GC is `behind schedule' */
+ int gcpace; /* size of pause between successive GCs */
+ int gcstepmul; /* GC `granularity' */
lua_CFunction panic; /* to be called in unprotected errors */
TValue _registry;
struct lua_State *mainthread;
- Node dummynode[1]; /* common node array for all empty tables */
+ UpVal uvhead; /* head of double-linked list of all open upvalues */
TString *tmname[TM_N]; /* array with tag-method names */
} global_State;
@@ -118,6 +116,7 @@ struct lua_State {
int hookcount;
lua_Hook hook;
TValue _gt; /* table of globals */
+ TValue env; /* temporary place for environments */
GCObject *openupval; /* list of open upvalues in this stack */
GCObject *gclist;
struct lua_longjmp *errorJmp; /* current error recover point */
diff --git a/src/lstring.c b/src/lstring.c
index af2c6963..897089a4 100644
--- a/src/lstring.c
+++ b/src/lstring.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstring.c,v 2.5 2004/11/24 19:16:03 roberto Exp $
+** $Id: lstring.c,v 2.7 2005/02/18 12:40:02 roberto Exp $
** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h
*/
@@ -93,7 +93,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
}
-Udata *luaS_newudata (lua_State *L, size_t s) {
+Udata *luaS_newudata (lua_State *L, size_t s, Table *e) {
Udata *u;
if (s > MAX_SIZET - sizeof(Udata))
luaM_toobig(L);
@@ -102,9 +102,10 @@ Udata *luaS_newudata (lua_State *L, size_t s) {
u->uv.tt = LUA_TUSERDATA;
u->uv.len = s;
u->uv.metatable = NULL;
- /* chain it on udata list */
- u->uv.next = G(L)->firstudata->uv.next;
- G(L)->firstudata->uv.next = obj2gco(u);
+ u->uv.env = e;
+ /* chain it on udata list (after main thread) */
+ u->uv.next = G(L)->mainthread->next;
+ G(L)->mainthread->next = obj2gco(u);
return u;
}
diff --git a/src/lstring.h b/src/lstring.h
index 4198f57c..88f6da80 100644
--- a/src/lstring.h
+++ b/src/lstring.h
@@ -1,5 +1,5 @@
/*
-** $Id: lstring.h,v 1.40 2004/11/19 15:52:40 roberto Exp $
+** $Id: lstring.h,v 1.42 2005/02/23 17:30:22 roberto Exp $
** String table (keep all strings handled by Lua)
** See Copyright Notice in lua.h
*/
@@ -21,10 +21,10 @@
#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
(sizeof(s)/sizeof(char))-1))
-#define luaS_fix(s) setbit((s)->tsv.marked, FIXEDBIT)
+#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
void luaS_resize (lua_State *L, int newsize);
-Udata *luaS_newudata (lua_State *L, size_t s);
+Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
diff --git a/src/ltable.c b/src/ltable.c
index 8bfbf641..d4070dd5 100644
--- a/src/ltable.c
+++ b/src/ltable.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.c,v 2.12 2004/12/04 18:10:22 roberto Exp $
+** $Id: ltable.c,v 2.15 2005/01/10 18:17:39 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -68,6 +68,13 @@
#define numints cast(int, sizeof(lua_Number)/sizeof(int))
+
+const Node luaH_dummynode = {
+ {{NULL}, LUA_TNIL}, /* value */
+ {{NULL}, LUA_TNIL, NULL} /* key */
+};
+
+
/*
** hash for lua_Numbers
*/
@@ -112,7 +119,7 @@ static int arrayindex (const TValue *key) {
lua_Number n = nvalue(key);
int k;
lua_number2int(k, n);
- if (cast(lua_Number, k) == nvalue(key))
+ if (num_eq(cast(lua_Number, k), nvalue(key)))
return k;
}
return -1; /* `key' did not match some condition */
@@ -176,62 +183,77 @@ int luaH_next (lua_State *L, Table *t, StkId key) {
*/
-static void computesizes (int nums[], int ntotal, int *narray, int *nhash) {
+static int computesizes (int nums[], int *narray) {
int i;
- int a = nums[0]; /* number of elements smaller than 2^i */
- int na = a; /* number of elements to go to array part */
- int n = (na == 0) ? -1 : 0; /* (log of) optimal size for array part */
- for (i = 1; a < *narray && *narray >= twoto(i-1); i++) {
+ int twotoi; /* 2^i */
+ int a = 0; /* number of elements smaller than 2^i */
+ int na = 0; /* number of elements to go to array part */
+ int n = 0; /* optimal size for array part */
+ for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
if (nums[i] > 0) {
a += nums[i];
- if (a >= twoto(i-1)) { /* more than half elements in use? */
- n = i;
- na = a;
+ if (a > twotoi/2) { /* more than half elements present? */
+ n = twotoi; /* optimal size (till now) */
+ na = a; /* all elements smaller than n will go to array part */
}
}
+ if (a == *narray) break; /* all elements already counted */
+ }
+ *narray = n;
+ lua_assert(*narray/2 <= na && na <= *narray);
+ return na;
+}
+
+
+static int countint (const TValue *key, int *nums) {
+ int k = arrayindex(key);
+ if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */
+ nums[ceillog2(k)]++; /* count as such */
+ return 1;
}
- lua_assert(na <= *narray && *narray <= ntotal);
- *nhash = ntotal - na;
- *narray = (n == -1) ? 0 : twoto(n);
- lua_assert(na <= *narray && na >= *narray/2);
+ else
+ return 0;
}
-static void numuse (const Table *t, int *narray, int *nhash) {
- int nums[MAXBITS+1];
- int i, lg;
- int totaluse = 0;
- /* 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 */
- if (ttlg > t->sizearray) {
- ttlg = t->sizearray;
- if (i >= ttlg) break;
+static int numusearray (const Table *t, int *nums) {
+ int lg;
+ int ttlg; /* 2^lg */
+ int ause = 0; /* summation of `nums' */
+ int i = 1; /* count to traverse all array keys */
+ for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */
+ int lc = 0; /* counter */
+ int lim = ttlg;
+ if (lim > t->sizearray) {
+ lim = t->sizearray; /* adjust upper limit */
+ if (i > lim)
+ break; /* no more elements to count */
}
- nums[lg] = 0;
- for (; i<ttlg; i++) {
- if (!ttisnil(&t->array[i])) {
- nums[lg]++;
- totaluse++;
- }
+ /* count elements in range (2^(lg-1), 2^lg] */
+ for (; i <= lim; i++) {
+ if (!ttisnil(&t->array[i-1]))
+ lc++;
}
+ nums[lg] += lc;
+ ause += lc;
}
- for (; lg<=MAXBITS; lg++) nums[lg] = 0; /* reset other counts */
- *narray = totaluse; /* all previous uses were in array part */
- /* count elements in hash part */
- i = sizenode(t);
+ return ause;
+}
+
+
+static int numusehash (const Table *t, int *nums, int *pnasize) {
+ int totaluse = 0; /* total number of elements */
+ int ause = 0; /* summation of `nums' */
+ int i = sizenode(t);
while (i--) {
Node *n = &t->node[i];
if (!ttisnil(gval(n))) {
- 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)++;
- }
+ ause += countint(key2tval(n), nums);
totaluse++;
}
}
- computesizes(nums, totaluse, narray, nhash);
+ *pnasize += ause;
+ return totaluse;
}
@@ -244,18 +266,18 @@ static void setarrayvector (lua_State *L, Table *t, int size) {
}
-static void setnodevector (lua_State *L, Table *t, int lsize) {
- int i;
- int size = twoto(lsize);
- if (lsize > MAXBITS)
- luaG_runerror(L, "table overflow");
- if (lsize == 0) { /* no elements to hash part? */
- t->node = G(L)->dummynode; /* use common `dummynode' */
- lua_assert(ttisnil(gkey(t->node))); /* assert invariants: */
- lua_assert(ttisnil(gval(t->node)));
- lua_assert(gnext(t->node) == NULL); /* (`dummynode' must be empty) */
+static void setnodevector (lua_State *L, Table *t, int size) {
+ int lsize;
+ if (size == 0) { /* no elements to hash part? */
+ t->node = cast(Node *, &luaH_dummynode); /* use common `dummynode' */
+ lsize = 0;
}
else {
+ int i;
+ lsize = ceillog2(size);
+ if (lsize > MAXBITS)
+ luaG_runerror(L, "table overflow");
+ size = twoto(lsize);
t->node = luaM_newvector(L, size, Node);
for (i=0; i<size; i++) {
gnext(&t->node[i]) = NULL;
@@ -264,31 +286,19 @@ static void setnodevector (lua_State *L, Table *t, int lsize) {
}
}
t->lsizenode = cast(lu_byte, lsize);
- t->firstfree = gnode(t, size-1); /* first free position to be used */
+ t->lastfree = gnode(t, size); /* all positions are free */
}
-void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) {
+static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
int i;
int oldasize = t->sizearray;
int oldhsize = t->lsizenode;
- Node *nold;
- Node temp[1];
- if (oldhsize)
- nold = t->node; /* save old hash ... */
- else { /* old hash is `dummynode' */
- lua_assert(t->node == G(L)->dummynode);
- temp[0] = t->node[0]; /* copy it to `temp' */
- nold = temp;
- setnilvalue(gkey(G(L)->dummynode)); /* restate invariant */
- setnilvalue(gval(G(L)->dummynode));
- lua_assert(gnext(G(L)->dummynode) == NULL);
- }
+ Node *nold = t->node; /* save old hash ... */
if (nasize > oldasize) /* array part must grow? */
setarrayvector(L, t, nasize);
/* create new hash part with appropriate size */
setnodevector(L, t, nhsize);
- /* re-insert elements */
if (nasize < oldasize) { /* array part must shrink? */
t->sizearray = nasize;
/* re-insert elements from vanishing slice */
@@ -299,21 +309,39 @@ void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) {
/* shrink array */
luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
}
- /* re-insert elements in hash part */
+ /* re-insert elements from hash part */
for (i = twoto(oldhsize) - 1; i >= 0; i--) {
Node *old = nold+i;
if (!ttisnil(gval(old)))
setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old));
}
- if (oldhsize)
+ if (nold != &luaH_dummynode)
luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */
}
-static void rehash (lua_State *L, Table *t) {
- int nasize, nhsize;
- numuse(t, &nasize, &nhsize); /* compute new sizes for array and hash parts */
- luaH_resize(L, t, nasize, luaO_log2(nhsize)+1);
+void luaH_resizearray (lua_State *L, Table *t, int nasize) {
+ int nsize = (t->node == &luaH_dummynode) ? 0 : sizenode(t);
+ resize(L, t, nasize, nsize);
+}
+
+
+static void rehash (lua_State *L, Table *t, const TValue *ek) {
+ int nasize, na;
+ int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */
+ int i;
+ int totaluse;
+ for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */
+ nasize = numusearray(t, nums); /* count keys in array part */
+ totaluse = nasize; /* all those keys are integer keys */
+ totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */
+ /* count extra key */
+ nasize += countint(ek, nums);
+ totaluse++;
+ /* compute new size for array part */
+ na = computesizes(nums, &nasize);
+ /* resize the table to new computed sizes */
+ resize(L, t, nasize, totaluse - na);
}
@@ -323,7 +351,7 @@ static void rehash (lua_State *L, Table *t) {
*/
-Table *luaH_new (lua_State *L, int narray, int lnhash) {
+Table *luaH_new (lua_State *L, int narray, int nhash) {
Table *t = luaM_new(L, Table);
luaC_link(L, obj2gco(t), LUA_TTABLE);
t->metatable = NULL;
@@ -332,21 +360,30 @@ Table *luaH_new (lua_State *L, int narray, int lnhash) {
t->array = NULL;
t->sizearray = 0;
t->lsizenode = 0;
- t->node = NULL;
+ t->node = cast(Node *, &luaH_dummynode);
setarrayvector(L, t, narray);
- setnodevector(L, t, lnhash);
+ setnodevector(L, t, nhash);
return t;
}
void luaH_free (lua_State *L, Table *t) {
- if (t->lsizenode)
+ if (t->node != &luaH_dummynode)
luaM_freearray(L, t->node, sizenode(t), Node);
luaM_freearray(L, t->array, t->sizearray, TValue);
luaM_free(L, t);
}
+static Node *getfreepos (lua_State *L, Table *t) {
+ while (t->lastfree-- > t->node) {
+ if (ttisnil(gkey(t->lastfree)))
+ return t->lastfree;
+ }
+ return NULL; /* could not find a free place */
+}
+
+
/*
** inserts a new key into a hash table; first, check whether key's main
@@ -356,12 +393,16 @@ void luaH_free (lua_State *L, Table *t) {
** position), new key goes to an empty position.
*/
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? */
- /* `mp' of colliding node */
- Node *othern = luaH_mainposition(t, key2tval(mp));
- Node *n = t->firstfree; /* get a free place */
+ if (!ttisnil(gval(mp)) || mp == &luaH_dummynode) {
+ Node *othern;
+ Node *n = getfreepos(L, t); /* get a free place */
+ if (n == NULL) { /* cannot find a free place? */
+ rehash(L, t, key); /* grow table */
+ return luaH_set(L, t, key); /* re-insert key into grown table */
+ }
+ lua_assert(n != &luaH_dummynode);
+ othern = luaH_mainposition(t, key2tval(mp));
if (othern != mp) { /* is colliding node out of its main position? */
/* yes; move colliding node into free position */
while (gnext(othern) != mp) othern = gnext(othern); /* find previous */
@@ -380,19 +421,7 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
gkey(mp)->value = key->value; gkey(mp)->tt = key->tt;
luaC_barriert(L, t, key);
lua_assert(ttisnil(gval(mp)));
- for (;;) { /* correct `firstfree' */
- if (ttisnil(gkey(t->firstfree)))
- return gval(mp); /* OK; table still has a free place */
- else if (t->firstfree == t->node) break; /* cannot decrement from here */
- else (t->firstfree)--;
- }
- /* no more free places; must create one */
- setbvalue(gval(mp), 0); /* avoid new key being removed */
- rehash(L, t); /* grow table */
- val = cast(TValue *, luaH_get(t, key)); /* get new position */
- lua_assert(ttisboolean(val));
- setnilvalue(val);
- return val;
+ return gval(mp);
}
@@ -407,7 +436,7 @@ const TValue *luaH_getnum (Table *t, int key) {
lua_Number nk = cast(lua_Number, key);
Node *n = hashnum(t, nk);
do { /* check whether `key' is somewhere in the chain */
- if (ttisnumber(gkey(n)) && nvalue(gkey(n)) == nk)
+ if (ttisnumber(gkey(n)) && num_eq(nvalue(gkey(n)), nk))
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
@@ -440,7 +469,7 @@ const TValue *luaH_get (Table *t, const TValue *key) {
case LUA_TNUMBER: {
int k;
lua_number2int(k, (nvalue(key)));
- if (cast(lua_Number, k) == nvalue(key)) /* is an integer index? */
+ if (num_eq(cast(lua_Number, k), nvalue(key))) /* is an integer index? */
return luaH_getnum(t, k); /* use specialized version */
/* else go through */
}
@@ -464,7 +493,7 @@ TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
return cast(TValue *, p);
else {
if (ttisnil(key)) luaG_runerror(L, "table index is nil");
- else if (ttisnumber(key) && nvalue(key) != nvalue(key))
+ else if (ttisnumber(key) && !num_eq(nvalue(key), nvalue(key)))
luaG_runerror(L, "table index is NaN");
return newkey(L, t, key);
}
diff --git a/src/ltable.h b/src/ltable.h
index cfc86017..9700062e 100644
--- a/src/ltable.h
+++ b/src/ltable.h
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.h,v 2.3 2004/10/06 18:34:16 roberto Exp $
+** $Id: ltable.h,v 2.5 2005/01/05 18:20:51 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -18,6 +18,8 @@
#define key2tval(n) (cast(const TValue *, gkey(n)))
+extern const Node luaH_dummynode;
+
const TValue *luaH_getnum (Table *t, int key);
TValue *luaH_setnum (lua_State *L, Table *t, int key);
const TValue *luaH_getstr (Table *t, TString *key);
@@ -25,7 +27,7 @@ TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
const TValue *luaH_get (Table *t, const TValue *key);
TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
Table *luaH_new (lua_State *L, int narray, int lnhash);
-void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize);
+void luaH_resizearray (lua_State *L, Table *t, int nasize);
void luaH_free (lua_State *L, Table *t);
int luaH_next (lua_State *L, Table *t, StkId key);
diff --git a/src/lua.c b/src/lua.c
index 6a21a6ae..1d2fc757 100644
--- a/src/lua.c
+++ b/src/lua.c
@@ -1,5 +1,5 @@
/*
-** $Id: lua.c,v 1.133 2004/11/18 19:53:49 roberto Exp $
+** $Id: lua.c,v 1.135 2005/01/10 17:21:10 roberto Exp $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
@@ -79,11 +79,23 @@ static int report (lua_State *L, int status) {
}
+static int traceback (lua_State *L) {
+ luaL_getfield(L, LUA_GLOBALSINDEX, "debug.traceback");
+ if (!lua_isfunction(L, -1))
+ lua_pop(L, 1);
+ else {
+ lua_pushvalue(L, 1); /* pass error message */
+ lua_pushinteger(L, 2); /* skip this function and traceback */
+ lua_call(L, 2, 1); /* call debug.traceback */
+ }
+ return 1;
+}
+
+
static int docall (lua_State *L, int narg, int clear) {
int status;
int base = lua_gettop(L) - narg; /* function index */
- lua_pushliteral(L, "_TRACEBACK");
- lua_rawget(L, LUA_GLOBALSINDEX); /* get traceback function */
+ lua_pushcfunction(L, traceback); /* push traceback function */
lua_insert(L, base); /* put it under chunk and args */
signal(SIGINT, laction);
status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base);
@@ -359,7 +371,7 @@ static int pmain (lua_State *L) {
int interactive = 1;
if (s->argv[0] && s->argv[0][0]) progname = s->argv[0];
globalL = L;
- lua_userinit(L); /* open libraries */
+ luaopen_stdlibs(L); /* open libraries */
status = handle_luainit(L);
if (status == 0) {
status = handle_argv(L, s->argv, &interactive);
diff --git a/src/lua.h b/src/lua.h
index 25fc8405..1020abd1 100644
--- a/src/lua.h
+++ b/src/lua.h
@@ -1,5 +1,5 @@
/*
-** $Id: lua.h,v 1.197 2004/12/13 12:15:11 roberto Exp $
+** $Id: lua.h,v 1.202 2005/02/18 12:40:02 roberto Exp $
** Lua - An Extensible Extension Language
** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
** http://www.lua.org mailto:info@lua.org
@@ -17,8 +17,9 @@
#include "luaconf.h"
-#define LUA_VERSION "Lua 5.1 (work4)"
-#define LUA_COPYRIGHT "Copyright (C) 1994-2004 Tecgraf, PUC-Rio"
+#define LUA_VERSION "Lua 5.1 (work5)"
+#define LUA_VERSION_NUM 501
+#define LUA_COPYRIGHT "Copyright (C) 1994-2005 Tecgraf, PUC-Rio"
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
@@ -33,11 +34,12 @@
** pseudo-indices
*/
#define LUA_REGISTRYINDEX (-10000)
-#define LUA_GLOBALSINDEX (-10001)
+#define LUA_ENVIRONINDEX (-10001)
+#define LUA_GLOBALSINDEX (-10002)
#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
-/* return codes for `lua_pcall', `lua_resume', and `lua_threadstatus' */
+/* return codes for `lua_pcall', `lua_resume', and `lua_status' */
#define LUA_YIELD 1
#define LUA_ERRRUN 2
#define LUA_ERRSYNTAX 3
@@ -109,112 +111,112 @@ typedef LUA_INTEGER lua_Integer;
/*
** state manipulation
*/
-LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud);
-LUA_API void lua_close (lua_State *L);
-LUA_API lua_State *lua_newthread (lua_State *L);
+LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
+LUA_API void (lua_close) (lua_State *L);
+LUA_API lua_State *(lua_newthread) (lua_State *L);
-LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);
+LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
/*
** basic stack manipulation
*/
-LUA_API int lua_gettop (lua_State *L);
-LUA_API void lua_settop (lua_State *L, int idx);
-LUA_API void lua_pushvalue (lua_State *L, int idx);
-LUA_API void lua_remove (lua_State *L, int idx);
-LUA_API void lua_insert (lua_State *L, int idx);
-LUA_API void lua_replace (lua_State *L, int idx);
-LUA_API int lua_checkstack (lua_State *L, int sz);
+LUA_API int (lua_gettop) (lua_State *L);
+LUA_API void (lua_settop) (lua_State *L, int idx);
+LUA_API void (lua_pushvalue) (lua_State *L, int idx);
+LUA_API void (lua_remove) (lua_State *L, int idx);
+LUA_API void (lua_insert) (lua_State *L, int idx);
+LUA_API void (lua_replace) (lua_State *L, int idx);
+LUA_API int (lua_checkstack) (lua_State *L, int sz);
-LUA_API void lua_xmove (lua_State *from, lua_State *to, int n);
+LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);
/*
** access functions (stack -> C)
*/
-LUA_API int lua_isnumber (lua_State *L, int idx);
-LUA_API int lua_isstring (lua_State *L, int idx);
-LUA_API int lua_iscfunction (lua_State *L, int idx);
-LUA_API int lua_isuserdata (lua_State *L, int idx);
-LUA_API int lua_type (lua_State *L, int idx);
-LUA_API const char *lua_typename (lua_State *L, int tp);
+LUA_API int (lua_isnumber) (lua_State *L, int idx);
+LUA_API int (lua_isstring) (lua_State *L, int idx);
+LUA_API int (lua_iscfunction) (lua_State *L, int idx);
+LUA_API int (lua_isuserdata) (lua_State *L, int idx);
+LUA_API int (lua_type) (lua_State *L, int idx);
+LUA_API const char *(lua_typename) (lua_State *L, int tp);
-LUA_API int lua_equal (lua_State *L, int idx1, int idx2);
-LUA_API int lua_rawequal (lua_State *L, int idx1, int idx2);
-LUA_API int lua_lessthan (lua_State *L, int idx1, int idx2);
+LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2);
+LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
+LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2);
-LUA_API lua_Number lua_tonumber (lua_State *L, int idx);
-LUA_API lua_Integer lua_tointeger (lua_State *L, int idx);
-LUA_API int lua_toboolean (lua_State *L, int idx);
-LUA_API const char *lua_tostring (lua_State *L, int idx);
-LUA_API size_t lua_objsize (lua_State *L, int idx);
-LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx);
-LUA_API void *lua_touserdata (lua_State *L, int idx);
-LUA_API lua_State *lua_tothread (lua_State *L, int idx);
-LUA_API const void *lua_topointer (lua_State *L, int idx);
+LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx);
+LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx);
+LUA_API int (lua_toboolean) (lua_State *L, int idx);
+LUA_API const char *(lua_tostring) (lua_State *L, int idx);
+LUA_API size_t (lua_objsize) (lua_State *L, int idx);
+LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
+LUA_API void *(lua_touserdata) (lua_State *L, int idx);
+LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
+LUA_API const void *(lua_topointer) (lua_State *L, int idx);
/*
** push functions (C -> stack)
*/
-LUA_API void lua_pushnil (lua_State *L);
-LUA_API void lua_pushnumber (lua_State *L, lua_Number n);
-LUA_API void lua_pushinteger (lua_State *L, lua_Integer n);
-LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t l);
-LUA_API void lua_pushstring (lua_State *L, const char *s);
-LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
- va_list argp);
-LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
-LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
-LUA_API void lua_pushboolean (lua_State *L, int b);
-LUA_API void lua_pushlightuserdata (lua_State *L, void *p);
-LUA_API int lua_pushthread (lua_State *L);
+LUA_API void (lua_pushnil) (lua_State *L);
+LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
+LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
+LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l);
+LUA_API void (lua_pushstring) (lua_State *L, const char *s);
+LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
+ va_list argp);
+LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
+LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
+LUA_API void (lua_pushboolean) (lua_State *L, int b);
+LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
+LUA_API int (lua_pushthread) (lua_State *L);
/*
** get functions (Lua -> stack)
*/
-LUA_API void lua_gettable (lua_State *L, int idx);
-LUA_API void lua_getfield (lua_State *L, int idx, const char *k);
-LUA_API void lua_rawget (lua_State *L, int idx);
-LUA_API void lua_rawgeti (lua_State *L, int idx, int n);
-LUA_API void lua_createtable (lua_State *L, int narr, int nrec);
-LUA_API void *lua_newuserdata (lua_State *L, size_t sz);
-LUA_API int lua_getmetatable (lua_State *L, int objindex);
-LUA_API void lua_getfenv (lua_State *L, int idx);
+LUA_API void (lua_gettable) (lua_State *L, int idx);
+LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k);
+LUA_API void (lua_rawget) (lua_State *L, int idx);
+LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n);
+LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
+LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
+LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
+LUA_API void (lua_getfenv) (lua_State *L, int idx);
/*
** set functions (stack -> Lua)
*/
-LUA_API void lua_settable (lua_State *L, int idx);
-LUA_API void lua_setfield (lua_State *L, int idx, const char *k);
-LUA_API void lua_rawset (lua_State *L, int idx);
-LUA_API void lua_rawseti (lua_State *L, int idx, int n);
-LUA_API int lua_setmetatable (lua_State *L, int objindex);
-LUA_API int lua_setfenv (lua_State *L, int idx);
+LUA_API void (lua_settable) (lua_State *L, int idx);
+LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
+LUA_API void (lua_rawset) (lua_State *L, int idx);
+LUA_API void (lua_rawseti) (lua_State *L, int idx, int n);
+LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
+LUA_API int (lua_setfenv) (lua_State *L, int idx);
/*
** `load' and `call' functions (load and run Lua code)
*/
-LUA_API void lua_call (lua_State *L, int nargs, int nresults);
-LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);
-LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud);
-LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *dt,
- const char *chunkname);
+LUA_API void (lua_call) (lua_State *L, int nargs, int nresults);
+LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
+LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud);
+LUA_API int (lua_load) (lua_State *L, lua_Chunkreader reader, void *dt,
+ const char *chunkname);
-LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data);
+LUA_API int (lua_dump) (lua_State *L, lua_Chunkwriter writer, void *data);
/*
** coroutine functions
*/
-LUA_API int lua_yield (lua_State *L, int nresults);
-LUA_API int lua_resume (lua_State *L, int narg);
-LUA_API int lua_threadstatus (lua_State *L);
+LUA_API int (lua_yield) (lua_State *L, int nresults);
+LUA_API int (lua_resume) (lua_State *L, int narg);
+LUA_API int (lua_status) (lua_State *L);
/*
** garbage-collection function and options
@@ -226,24 +228,22 @@ LUA_API int lua_threadstatus (lua_State *L);
#define LUA_GCCOUNT 3
#define LUA_GCSTEP 4
#define LUA_GCSETPACE 5
-#define LUA_GCSETINCMODE 6
+#define LUA_GCSETSTEPMUL 6
-LUA_API int lua_gc (lua_State *L, int what, int data);
+LUA_API int (lua_gc) (lua_State *L, int what, int data);
/*
** miscellaneous functions
*/
-LUA_API const char *lua_version (void);
+LUA_API int (lua_error) (lua_State *L);
-LUA_API int lua_error (lua_State *L);
+LUA_API int (lua_next) (lua_State *L, int idx);
-LUA_API int lua_next (lua_State *L, int idx);
+LUA_API void (lua_concat) (lua_State *L, int n);
-LUA_API void lua_concat (lua_State *L, int n);
-
-LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud);
+LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
diff --git a/src/luaconf.h b/src/luaconf.h
index 7ea477e2..04b8e990 100644
--- a/src/luaconf.h
+++ b/src/luaconf.h
@@ -1,5 +1,5 @@
/*
-** $Id: luaconf.h,v 1.22 2004/12/27 15:58:15 roberto Exp $
+** $Id: luaconf.h,v 1.30 2005/02/28 15:59:11 roberto Exp $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
@@ -96,7 +96,7 @@
#define stdin_is_tty() isatty(0)
#elif defined(_WIN32)
#include <io.h>
-#include <fcntl.h>
+#include <stdio.h>
#define stdin_is_tty() _isatty(_fileno(stdin))
#else
#define stdin_is_tty() 1 /* assume stdin is a tty */
@@ -108,16 +108,6 @@
#define PROGNAME "lua"
-/*
-** this macro allows you to open other libraries when starting the
-** stand-alone interpreter
-*/
-#define lua_userinit(L) luaopen_stdlibs(L)
-/*
-** #define lua_userinit(L) { int luaopen_mylibs(lua_State *L); \
-** luaopen_stdlibs(L); luaopen_mylibs(L); }
-*/
-
/*
@@ -217,8 +207,7 @@
#if defined(__GNUC__) && defined(__i386)
#define lua_number2int(i,d) __asm__ ("fistpl %0":"=m"(i):"t"(d):"st")
-#elif defined(_WIN32) && defined(_M_IX86)
-#include <math.h>
+#elif defined(_MSC_VER) && defined(_M_IX86)
#pragma warning(disable: 4514)
__inline int l_lrint (double flt)
{ int i;
@@ -248,6 +237,8 @@ __inline int l_lrint (double flt)
/* function to convert a lua_Number to a string */
#include <stdio.h>
#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
+/* maximum size of previous conversion */
+#define MAX_NUMBER2STR 32 /* 16 digits, sign, point and \0 (+ some extra) */
/* function to convert a string to a lua_Number */
#define lua_str2number(s,p) strtod((s), (p))
@@ -258,12 +249,29 @@ __inline int l_lrint (double flt)
#define LUA_UACNUMBER double
+/* primitive operators for numbers */
+#define num_add(a,b) ((a)+(b))
+#define num_sub(a,b) ((a)-(b))
+#define num_mul(a,b) ((a)*(b))
+#define num_div(a,b) ((a)/(b))
+#define num_unm(a) (-(a))
+#define num_eq(a,b) ((a)==(b))
+#define num_lt(a,b) ((a)<(b))
+#define num_le(a,b) ((a)<=(b))
+#include <math.h>
+#define num_pow(a,b) pow(a,b)
+
+
/* type to ensure maximum alignment */
#define LUSER_ALIGNMENT_T union { double u; void *s; long l; }
-/* exception handling */
+/*
+** exception handling: by default, Lua handles errors with longjmp/setjmp
+** when compiling as C code and with exceptions when compiling as C++ code.
+** Change that if you prefer to use longjmp/setjmp even with C++.
+*/
#ifndef __cplusplus
/* default handling with long jumps */
#include <setjmp.h>
@@ -282,18 +290,20 @@ __inline int l_lrint (double flt)
/*
-** macros for thread synchronization inside Lua core machine:
-** all accesses to the global state and to global objects are synchronized.
-** Because threads can read the stack of other threads
-** (when running garbage collection),
-** a thread must also synchronize any write-access to its own stack.
-** Unsynchronized accesses are allowed only when reading its own stack,
-** or when reading immutable fields from global objects
-** (such as string values and udata values).
+** macros for thread synchronization inside Lua core machine: This is
+** an attempt to simplify the implementation of a multithreaded version
+** of Lua. Do not change that unless you know what you are doing. all
+** accesses to the global state and to global objects are synchronized.
+** Because threads can read the stack of other threads (when running
+** garbage collection), a thread must also synchronize any write-access
+** to its own stack. Unsynchronized accesses are allowed only when
+** reading its own stack, or when reading immutable fields from global
+** objects (such as string values and udata values).
*/
#define lua_lock(L) ((void) 0)
#define lua_unlock(L) ((void) 0)
+
/*
** this macro allows a thread switch in appropriate places in the Lua
** core
@@ -303,7 +313,7 @@ __inline int l_lrint (double flt)
/* allows user-specific initialization on new threads */
-#define lua_userstateopen(L) /* empty */
+#define lua_userstateopen(L) ((void)0)
#endif
@@ -321,9 +331,6 @@ __inline int l_lrint (double flt)
#ifdef LUA_LIB
-
-/* `assert' options */
-
/* environment variables that hold the search path for packages */
#define LUA_PATH "LUA_PATH"
#define LUA_CPATH "LUA_CPATH"
@@ -332,7 +339,7 @@ __inline int l_lrint (double flt)
#define LUA_POF "luaopen_"
/* separator for open functions in C libraries */
-#define LUA_OFSEP ""
+#define LUA_OFSEP "_"
/* directory separator (for submodules) */
#if defined(_WIN32)
@@ -342,18 +349,20 @@ __inline int l_lrint (double flt)
#endif
/* separator of templates in a path */
-#define LUA_PATH_SEP ';'
+#define LUA_PATHSEP ';'
/* wild char in each template */
#define LUA_PATH_MARK "?"
-/* maximum number of captures in pattern-matching */
-#define MAX_CAPTURES 32 /* arbitrary limit */
+/* maximum number of captures in pattern-matching (arbitrary limit) */
+#define MAX_CAPTURES 32
/*
-** by default, gcc does not get `tmpname'
+** by default, gcc does not get `os.tmpname', because it generates a warning
+** when using `tmpname'. Change that if you really want (or do not want)
+** `os.tmpname' available.
*/
#ifdef __GNUC__
#define USE_TMPNAME 0
@@ -363,7 +372,11 @@ __inline int l_lrint (double flt)
/*
-** Configuration for loadlib
+** Configuration for loadlib: Lua tries to guess the dynamic-library
+** system that your platform uses (either Windows' DLL, Mac's dyld, or
+** dlopen). If your system is some kind of Unix, there is a good chance
+** that USE_DLOPEN will work for it. You may need to adapt also the
+** makefile.
*/
#if defined(_WIN32)
#define USE_DLL
diff --git a/src/lualib.h b/src/lualib.h
index c8114ed2..a5dde236 100644
--- a/src/lualib.h
+++ b/src/lualib.h
@@ -1,5 +1,5 @@
/*
-** $Id: lualib.h,v 1.32 2004/07/09 15:47:48 roberto Exp $
+** $Id: lualib.h,v 1.33 2005/01/10 16:31:30 roberto Exp $
** Lua standard libraries
** See Copyright Notice in lua.h
*/
@@ -16,32 +16,32 @@
#define LUA_COLIBNAME "coroutine"
-LUALIB_API int luaopen_base (lua_State *L);
+LUALIB_API int (luaopen_base) (lua_State *L);
#define LUA_TABLIBNAME "table"
-LUALIB_API int luaopen_table (lua_State *L);
+LUALIB_API int (luaopen_table) (lua_State *L);
#define LUA_IOLIBNAME "io"
-LUALIB_API int luaopen_io (lua_State *L);
+LUALIB_API int (luaopen_io) (lua_State *L);
#define LUA_OSLIBNAME "os"
-LUALIB_API int luaopen_os (lua_State *L);
+LUALIB_API int (luaopen_os) (lua_State *L);
#define LUA_STRLIBNAME "string"
-LUALIB_API int luaopen_string (lua_State *L);
+LUALIB_API int (luaopen_string) (lua_State *L);
#define LUA_MATHLIBNAME "math"
-LUALIB_API int luaopen_math (lua_State *L);
+LUALIB_API int (luaopen_math) (lua_State *L);
#define LUA_DBLIBNAME "debug"
-LUALIB_API int luaopen_debug (lua_State *L);
+LUALIB_API int (luaopen_debug) (lua_State *L);
-LUALIB_API int luaopen_loadlib (lua_State *L);
+LUALIB_API int (luaopen_loadlib) (lua_State *L);
/* open all previous libraries */
-LUALIB_API int luaopen_stdlibs (lua_State *L);
+LUALIB_API int (luaopen_stdlibs) (lua_State *L);
#endif
diff --git a/src/lvm.c b/src/lvm.c
index 1a295d1b..1fd2ae75 100644
--- a/src/lvm.c
+++ b/src/lvm.c
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.c,v 2.18 2004/12/03 20:35:33 roberto Exp $
+** $Id: lvm.c,v 2.26 2005/02/23 17:30:22 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -47,7 +47,7 @@ int luaV_tostring (lua_State *L, StkId obj) {
if (!ttisnumber(obj))
return 0;
else {
- char s[32]; /* 16 digits, sign, point and \0 (+ some extra...) */
+ char s[MAX_NUMBER2STR];
lua_number2str(s, nvalue(obj));
setsvalue2s(L, obj, luaS_new(L, s));
return 1;
@@ -113,7 +113,7 @@ StkId luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val,
const TValue *tm;
if (ttistable(t)) { /* `t' is a table? */
Table *h = hvalue(t);
- const TValue *res = luaH_get(h, key); /* do a primitive set */
+ const TValue *res = luaH_get(h, key); /* do a primitive get */
if (!ttisnil(res) || /* result is no nil? */
(tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
setobj2s(L, val, res);
@@ -241,7 +241,7 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
if (ttype(l) != ttype(r))
return luaG_ordererror(L, l, r);
else if (ttisnumber(l))
- return nvalue(l) < nvalue(r);
+ return num_lt(nvalue(l), nvalue(r));
else if (ttisstring(l))
return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
@@ -255,7 +255,7 @@ static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
if (ttype(l) != ttype(r))
return luaG_ordererror(L, l, r);
else if (ttisnumber(l))
- return nvalue(l) <= nvalue(r);
+ return num_le(nvalue(l), nvalue(r));
else if (ttisstring(l))
return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
@@ -271,7 +271,7 @@ int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
lua_assert(ttype(t1) == ttype(t2));
switch (ttype(t1)) {
case LUA_TNIL: return 1;
- case LUA_TNUMBER: return nvalue(t1) == nvalue(t2);
+ case LUA_TNUMBER: return num_eq(nvalue(t1), nvalue(t2));
case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
case LUA_TUSERDATA: {
@@ -335,18 +335,11 @@ static StkId Arith (lua_State *L, StkId ra, const TValue *rb,
if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
(c = luaV_tonumber(rc, &tempc)) != NULL) {
switch (op) {
- case TM_ADD: setnvalue(ra, nvalue(b) + nvalue(c)); break;
- case TM_SUB: setnvalue(ra, nvalue(b) - nvalue(c)); break;
- case TM_MUL: setnvalue(ra, nvalue(b) * nvalue(c)); break;
- case TM_DIV: setnvalue(ra, nvalue(b) / nvalue(c)); break;
- case TM_POW: {
- const TValue *f = luaH_getstr(hvalue(gt(L)), G(L)->tmname[TM_POW]);
- if (!ttisfunction(f))
- luaG_runerror(L, "`__pow' (`^' operator) is not a function");
- prepTMcall(L, f, b, c);
- callTMres(L, ra);
- break;
- }
+ case TM_ADD: setnvalue(ra, num_add(nvalue(b), nvalue(c))); break;
+ case TM_SUB: setnvalue(ra, num_sub(nvalue(b), nvalue(c))); break;
+ case TM_MUL: setnvalue(ra, num_mul(nvalue(b), nvalue(c))); break;
+ case TM_DIV: setnvalue(ra, num_div(nvalue(b), nvalue(c))); break;
+ case TM_POW: setnvalue(ra, num_pow(nvalue(b), nvalue(c))); break;
default: lua_assert(0); break;
}
}
@@ -435,9 +428,11 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
continue;
}
case OP_GETGLOBAL: {
+ TValue g;
TValue *rb = KBx(i);
- lua_assert(ttisstring(rb) && ttistable(&cl->g));
- base = luaV_gettable(L, &cl->g, rb, ra, pc); /***/
+ sethvalue(L, &g, cl->env);
+ lua_assert(ttisstring(rb));
+ base = luaV_gettable(L, &g, rb, ra, pc); /***/
continue;
}
case OP_GETTABLE: {
@@ -445,8 +440,10 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
continue;
}
case OP_SETGLOBAL: {
- lua_assert(ttisstring(KBx(i)) && ttistable(&cl->g));
- base = luaV_settable(L, &cl->g, KBx(i), ra, pc); /***/
+ TValue g;
+ sethvalue(L, &g, cl->env);
+ lua_assert(ttisstring(KBx(i)));
+ base = luaV_settable(L, &g, KBx(i), ra, pc); /***/
continue;
}
case OP_SETUPVAL: {
@@ -461,8 +458,8 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
}
case OP_NEWTABLE: {
int b = GETARG_B(i);
- b = luaO_fb2int(b);
- sethvalue(L, ra, luaH_new(L, b, GETARG_C(i)));
+ int c = GETARG_C(i);
+ sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
L->ci->savedpc = pc;
luaC_checkGC(L); /***/
base = L->base;
@@ -478,7 +475,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
TValue *rb = RKB(i);
TValue *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) {
- setnvalue(ra, nvalue(rb) + nvalue(rc));
+ setnvalue(ra, num_add(nvalue(rb), nvalue(rc)));
}
else
base = Arith(L, ra, rb, rc, TM_ADD, pc); /***/
@@ -488,7 +485,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
TValue *rb = RKB(i);
TValue *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) {
- setnvalue(ra, nvalue(rb) - nvalue(rc));
+ setnvalue(ra, num_sub(nvalue(rb), nvalue(rc)));
}
else
base = Arith(L, ra, rb, rc, TM_SUB, pc); /***/
@@ -498,7 +495,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
TValue *rb = RKB(i);
TValue *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) {
- setnvalue(ra, nvalue(rb) * nvalue(rc));
+ setnvalue(ra, num_mul(nvalue(rb), nvalue(rc)));
}
else
base = Arith(L, ra, rb, rc, TM_MUL, pc); /***/
@@ -508,21 +505,27 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
TValue *rb = RKB(i);
TValue *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) {
- setnvalue(ra, nvalue(rb) / nvalue(rc));
+ setnvalue(ra, num_div(nvalue(rb), nvalue(rc)));
}
else
base = Arith(L, ra, rb, rc, TM_DIV, pc); /***/
continue;
}
case OP_POW: {
- base = Arith(L, ra, RKB(i), RKC(i), TM_POW, pc); /***/
+ TValue *rb = RKB(i);
+ TValue *rc = RKC(i);
+ if (ttisnumber(rb) && ttisnumber(rc)) {
+ setnvalue(ra, num_pow(nvalue(rb), nvalue(rc)));
+ }
+ else
+ base = Arith(L, ra, rb, rc, TM_POW, pc); /***/
continue;
}
case OP_UNM: {
const TValue *rb = RB(i);
TValue temp;
if (tonumber(rb, &temp)) {
- setnvalue(ra, -nvalue(rb));
+ setnvalue(ra, num_unm(nvalue(rb)));
}
else {
setnilvalue(&temp);
@@ -617,9 +620,9 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
int aux;
StkId func = ci->func;
StkId pfunc = (ci+1)->func; /* previous function index */
+ if (L->openupval) luaF_close(L, base);
base = ci->base = ci->func + ((ci+1)->base - pfunc);
L->base = base;
- if (L->openupval) luaF_close(L, base);
for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */
setobjs2s(L, func+aux, pfunc+aux);
ci->top = L->top = func+aux; /* correct top */
@@ -658,9 +661,9 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
}
case OP_FORLOOP: {
lua_Number step = nvalue(ra+2);
- lua_Number idx = nvalue(ra) + step; /* increment index */
+ lua_Number idx = num_add(nvalue(ra), step); /* increment index */
lua_Number limit = nvalue(ra+1);
- if (step > 0 ? idx <= limit : idx >= limit) {
+ if (step > 0 ? num_le(idx, limit) : num_le(limit, idx)) {
dojump(L, pc, GETARG_sBx(i)); /* jump back */
setnvalue(ra, idx); /* update internal index... */
setnvalue(ra+3, idx); /* ...and external index */
@@ -678,7 +681,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
luaG_runerror(L, "`for' limit must be a number");
else if (!tonumber(pstep, ra+2))
luaG_runerror(L, "`for' step must be a number");
- setnvalue(ra, nvalue(ra) - nvalue(pstep));
+ setnvalue(ra, num_sub(nvalue(ra), nvalue(pstep)));
dojump(L, pc, GETARG_sBx(i));
continue;
}
@@ -723,7 +726,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
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 */
+ luaH_resizearray(L, h, last); /* pre-alloc it at once */
for (; n > 0; n--) {
TValue *val = ra+n;
setobj2t(L, luaH_setnum(L, h, last--), val);
@@ -741,7 +744,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
int nup, j;
p = cl->p->p[GETARG_Bx(i)];
nup = p->nups;
- ncl = luaF_newLclosure(L, nup, &cl->g);
+ ncl = luaF_newLclosure(L, nup, cl->env);
ncl->l.p = p;
for (j=0; j<nup; j++, pc++) {
if (GET_OPCODE(*pc) == OP_GETUPVAL)