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