mirror of
https://github.com/lua/lua.git
synced 2026-07-27 00:19:07 +00:00
Compare commits
93 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
762c737037 | ||
|
|
de57dc2653 | ||
|
|
d1df829f8d | ||
|
|
2ad947fe03 | ||
|
|
f0cc013afa | ||
|
|
0d88545b82 | ||
|
|
f84c5a5fc6 | ||
|
|
05d35d8f3c | ||
|
|
3a6230ef7c | ||
|
|
a424a112b5 | ||
|
|
b858161fbc | ||
|
|
80bac182db | ||
|
|
30a411ab3c | ||
|
|
5bb5a1831d | ||
|
|
b518d14071 | ||
|
|
15dbb53461 | ||
|
|
abc304f9da | ||
|
|
1a553f9199 | ||
|
|
0ca225d33a | ||
|
|
70e2b7ab86 | ||
|
|
5a144e891a | ||
|
|
b12776f29c | ||
|
|
ab9e062928 | ||
|
|
81cdbabf09 | ||
|
|
40cfb0691e | ||
|
|
9b7af7e45b | ||
|
|
2e66248f8a | ||
|
|
79db75101e | ||
|
|
b0c40e2405 | ||
|
|
4734e2de05 | ||
|
|
7ea180af6e | ||
|
|
05d567d52e | ||
|
|
d8a3a00d84 | ||
|
|
c9ea94ec92 | ||
|
|
fa4b4c1100 | ||
|
|
4039bf457d | ||
|
|
034de1fe73 | ||
|
|
430d6db928 | ||
|
|
7c3857cded | ||
|
|
8ce6f0b418 | ||
|
|
572bddc0b0 | ||
|
|
3684f67771 | ||
|
|
69dd9461e5 | ||
|
|
6b6bc532a4 | ||
|
|
ea16ee41a8 | ||
|
|
60d11ec316 | ||
|
|
e1a424e8a3 | ||
|
|
59ce42dbd5 | ||
|
|
92f6e0c1bf | ||
|
|
5cd99b82b7 | ||
|
|
07e210e655 | ||
|
|
feb724c122 | ||
|
|
67f9a2a98f | ||
|
|
c4f9c887fc | ||
|
|
9866fb0ef1 | ||
|
|
60c83ded30 | ||
|
|
07948c3181 | ||
|
|
dce9a49a08 | ||
|
|
15db58a2f5 | ||
|
|
d6826dbc80 | ||
|
|
e75a6ae9ee | ||
|
|
2866fb2dd0 | ||
|
|
4b6f436d67 | ||
|
|
8f105d6b59 | ||
|
|
2fef8c772b | ||
|
|
7285fa393b | ||
|
|
5085f09ce5 | ||
|
|
d674626392 | ||
|
|
7a40cdbda0 | ||
|
|
3cdeacbbfb | ||
|
|
6f207b15fb | ||
|
|
3184314bf3 | ||
|
|
7964f7cbbd | ||
|
|
383a6e88f9 | ||
|
|
871166d7db | ||
|
|
592cf2334e | ||
|
|
0175f8d5d1 | ||
|
|
e79bf02f33 | ||
|
|
41ed3c4771 | ||
|
|
635b7c707d | ||
|
|
83f0d6ef1a | ||
|
|
3088ebd95b | ||
|
|
797d964df9 | ||
|
|
e44e579dc1 | ||
|
|
a153cafd8d | ||
|
|
3b5158f2a1 | ||
|
|
60a8b94fd0 | ||
|
|
c499442e5f | ||
|
|
9a5bab82ff | ||
|
|
32fd039bb5 | ||
|
|
75f73172c4 | ||
|
|
754c630754 | ||
|
|
dd8edecae1 |
31
bugs
31
bugs
@@ -298,8 +298,39 @@ Fri Aug 30 13:49:14 EST 2002
|
||||
>> userdata may not be cleared properly
|
||||
(by Roberto; since 5.0a)
|
||||
|
||||
** lapi.c
|
||||
Thu Nov 21 11:00:00 EST 2002
|
||||
>> ULONG_MAX>>10 may not fit into an int
|
||||
(by Jeff Petkau; since 4.0)
|
||||
|
||||
** lparser.c
|
||||
Fri Dec 6 17:06:40 UTC 2002
|
||||
>> scope of generic for variables is not sound
|
||||
(by Gavin Wraith; since 5.0a)
|
||||
|
||||
|
||||
|
||||
|
||||
=================================================================
|
||||
--- Version 5.0 beta
|
||||
** lbaselib.c
|
||||
Fri Dec 20 09:53:19 UTC 2002
|
||||
>> `resume' was checking the wrong value for stack overflow
|
||||
(by Maik Zimmermann; since 5.0b)
|
||||
|
||||
** ldo.c
|
||||
Thu Jan 23 11:29:06 UTC 2003
|
||||
>> error during garbage collection in luaD_protectedparser is not being
|
||||
>> protected
|
||||
(by Benoit Germain; since 5.0a)
|
||||
|
||||
** ldo.c (and others)
|
||||
Fri Feb 28 14:20:33 EST 2003
|
||||
>> GC metamethod calls could mess C/Lua stack syncronization
|
||||
(by Roberto; since 5.0b)
|
||||
|
||||
** lzio.h/zlio.c
|
||||
Thu Mar 20 11:40:12 EST 2003
|
||||
>> zio mixes a 255 as first char in a buffer with EOZ
|
||||
(by lhf; since 5.0a)
|
||||
|
||||
|
||||
248
lapi.c
248
lapi.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lapi.c,v 1.225 2002/12/04 17:28:27 roberto Exp roberto $
|
||||
** $Id: lapi.c,v 1.234 2003/04/03 13:35:34 roberto Exp roberto $
|
||||
** Lua API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -45,43 +45,48 @@ const char lua_ident[] =
|
||||
|
||||
|
||||
|
||||
static TObject *negindex (lua_State *L, int index) {
|
||||
if (index > LUA_REGISTRYINDEX) {
|
||||
api_check(L, index != 0 && -index <= L->top - L->base);
|
||||
return L->top+index;
|
||||
static TObject *negindex (lua_State *L, int idx) {
|
||||
if (idx > LUA_REGISTRYINDEX) {
|
||||
api_check(L, idx != 0 && -idx <= L->top - L->base);
|
||||
return L->top+idx;
|
||||
}
|
||||
else switch (index) { /* pseudo-indices */
|
||||
else switch (idx) { /* pseudo-indices */
|
||||
case LUA_REGISTRYINDEX: return registry(L);
|
||||
case LUA_GLOBALSINDEX: return gt(L);
|
||||
default: {
|
||||
TObject *func = (L->base - 1);
|
||||
index = LUA_GLOBALSINDEX - index;
|
||||
api_check(L, iscfunction(func) && index <= clvalue(func)->c.nupvalues);
|
||||
return &clvalue(func)->c.upvalue[index-1];
|
||||
idx = LUA_GLOBALSINDEX - idx;
|
||||
lua_assert(iscfunction(func));
|
||||
return (idx <= clvalue(func)->c.nupvalues)
|
||||
? &clvalue(func)->c.upvalue[idx-1]
|
||||
: NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static TObject *luaA_index (lua_State *L, int index) {
|
||||
if (index > 0) {
|
||||
api_check(L, index <= L->top - L->base);
|
||||
return L->base + index - 1;
|
||||
static TObject *luaA_index (lua_State *L, int idx) {
|
||||
if (idx > 0) {
|
||||
api_check(L, idx <= L->top - L->base);
|
||||
return L->base + idx - 1;
|
||||
}
|
||||
else {
|
||||
TObject *o = negindex(L, idx);
|
||||
api_check(L, o != NULL);
|
||||
return o;
|
||||
}
|
||||
else
|
||||
return negindex(L, index);
|
||||
}
|
||||
|
||||
|
||||
static TObject *luaA_indexAcceptable (lua_State *L, int index) {
|
||||
if (index > 0) {
|
||||
TObject *o = L->base+(index-1);
|
||||
api_check(L, index <= L->stack_last - L->base);
|
||||
static TObject *luaA_indexAcceptable (lua_State *L, int idx) {
|
||||
if (idx > 0) {
|
||||
TObject *o = L->base+(idx-1);
|
||||
api_check(L, idx <= L->stack_last - L->base);
|
||||
if (o >= L->top) return NULL;
|
||||
else return o;
|
||||
}
|
||||
else
|
||||
return negindex(L, index);
|
||||
return negindex(L, idx);
|
||||
}
|
||||
|
||||
|
||||
@@ -154,55 +159,55 @@ LUA_API int lua_gettop (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_settop (lua_State *L, int index) {
|
||||
LUA_API void lua_settop (lua_State *L, int idx) {
|
||||
lua_lock(L);
|
||||
if (index >= 0) {
|
||||
api_check(L, index <= L->stack_last - L->base);
|
||||
while (L->top < L->base + index)
|
||||
if (idx >= 0) {
|
||||
api_check(L, idx <= L->stack_last - L->base);
|
||||
while (L->top < L->base + idx)
|
||||
setnilvalue(L->top++);
|
||||
L->top = L->base + index;
|
||||
L->top = L->base + idx;
|
||||
}
|
||||
else {
|
||||
api_check(L, -(index+1) <= (L->top - L->base));
|
||||
L->top += index+1; /* `subtract' index (index is negative) */
|
||||
api_check(L, -(idx+1) <= (L->top - L->base));
|
||||
L->top += idx+1; /* `subtract' index (index is negative) */
|
||||
}
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_remove (lua_State *L, int index) {
|
||||
LUA_API void lua_remove (lua_State *L, int idx) {
|
||||
StkId p;
|
||||
lua_lock(L);
|
||||
p = luaA_index(L, index);
|
||||
p = luaA_index(L, idx);
|
||||
while (++p < L->top) setobjs2s(p-1, p);
|
||||
L->top--;
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_insert (lua_State *L, int index) {
|
||||
LUA_API void lua_insert (lua_State *L, int idx) {
|
||||
StkId p;
|
||||
StkId q;
|
||||
lua_lock(L);
|
||||
p = luaA_index(L, index);
|
||||
p = luaA_index(L, idx);
|
||||
for (q = L->top; q>p; q--) setobjs2s(q, q-1);
|
||||
setobjs2s(p, L->top);
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_replace (lua_State *L, int index) {
|
||||
LUA_API void lua_replace (lua_State *L, int idx) {
|
||||
lua_lock(L);
|
||||
api_checknelems(L, 1);
|
||||
setobj(luaA_index(L, index), L->top - 1); /* write barrier */
|
||||
setobj(luaA_index(L, idx), L->top - 1); /* write barrier */
|
||||
L->top--;
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_pushvalue (lua_State *L, int index) {
|
||||
LUA_API void lua_pushvalue (lua_State *L, int idx) {
|
||||
lua_lock(L);
|
||||
setobj2s(L->top, luaA_index(L, index));
|
||||
setobj2s(L->top, luaA_index(L, idx));
|
||||
api_incr_top(L);
|
||||
lua_unlock(L);
|
||||
}
|
||||
@@ -214,8 +219,8 @@ LUA_API void lua_pushvalue (lua_State *L, int index) {
|
||||
*/
|
||||
|
||||
|
||||
LUA_API int lua_type (lua_State *L, int index) {
|
||||
StkId o = luaA_indexAcceptable(L, index);
|
||||
LUA_API int lua_type (lua_State *L, int idx) {
|
||||
StkId o = luaA_indexAcceptable(L, idx);
|
||||
return (o == NULL) ? LUA_TNONE : ttype(o);
|
||||
}
|
||||
|
||||
@@ -226,27 +231,27 @@ LUA_API const char *lua_typename (lua_State *L, int t) {
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_iscfunction (lua_State *L, int index) {
|
||||
StkId o = luaA_indexAcceptable(L, index);
|
||||
LUA_API int lua_iscfunction (lua_State *L, int idx) {
|
||||
StkId o = luaA_indexAcceptable(L, idx);
|
||||
return (o == NULL) ? 0 : iscfunction(o);
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_isnumber (lua_State *L, int index) {
|
||||
LUA_API int lua_isnumber (lua_State *L, int idx) {
|
||||
TObject n;
|
||||
const TObject *o = luaA_indexAcceptable(L, index);
|
||||
const TObject *o = luaA_indexAcceptable(L, idx);
|
||||
return (o != NULL && tonumber(o, &n));
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_isstring (lua_State *L, int index) {
|
||||
int t = lua_type(L, index);
|
||||
LUA_API int lua_isstring (lua_State *L, int idx) {
|
||||
int t = lua_type(L, idx);
|
||||
return (t == LUA_TSTRING || t == LUA_TNUMBER);
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_isuserdata (lua_State *L, int index) {
|
||||
const TObject *o = luaA_indexAcceptable(L, index);
|
||||
LUA_API int lua_isuserdata (lua_State *L, int idx) {
|
||||
const TObject *o = luaA_indexAcceptable(L, idx);
|
||||
return (o != NULL && (ttisuserdata(o) || ttislightuserdata(o)));
|
||||
}
|
||||
|
||||
@@ -286,9 +291,9 @@ LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
|
||||
|
||||
|
||||
|
||||
LUA_API lua_Number lua_tonumber (lua_State *L, int index) {
|
||||
LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
|
||||
TObject n;
|
||||
const TObject *o = luaA_indexAcceptable(L, index);
|
||||
const TObject *o = luaA_indexAcceptable(L, idx);
|
||||
if (o != NULL && tonumber(o, &n))
|
||||
return nvalue(o);
|
||||
else
|
||||
@@ -296,14 +301,14 @@ LUA_API lua_Number lua_tonumber (lua_State *L, int index) {
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_toboolean (lua_State *L, int index) {
|
||||
const TObject *o = luaA_indexAcceptable(L, index);
|
||||
LUA_API int lua_toboolean (lua_State *L, int idx) {
|
||||
const TObject *o = luaA_indexAcceptable(L, idx);
|
||||
return (o != NULL) && !l_isfalse(o);
|
||||
}
|
||||
|
||||
|
||||
LUA_API const char *lua_tostring (lua_State *L, int index) {
|
||||
StkId o = luaA_indexAcceptable(L, index);
|
||||
LUA_API const char *lua_tostring (lua_State *L, int idx) {
|
||||
StkId o = luaA_indexAcceptable(L, idx);
|
||||
if (o == NULL)
|
||||
return NULL;
|
||||
else if (ttisstring(o))
|
||||
@@ -319,8 +324,8 @@ LUA_API const char *lua_tostring (lua_State *L, int index) {
|
||||
}
|
||||
|
||||
|
||||
LUA_API size_t lua_strlen (lua_State *L, int index) {
|
||||
StkId o = luaA_indexAcceptable(L, index);
|
||||
LUA_API size_t lua_strlen (lua_State *L, int idx) {
|
||||
StkId o = luaA_indexAcceptable(L, idx);
|
||||
if (o == NULL)
|
||||
return 0;
|
||||
else if (ttisstring(o))
|
||||
@@ -335,14 +340,14 @@ LUA_API size_t lua_strlen (lua_State *L, int index) {
|
||||
}
|
||||
|
||||
|
||||
LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index) {
|
||||
StkId o = luaA_indexAcceptable(L, index);
|
||||
LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
|
||||
StkId o = luaA_indexAcceptable(L, idx);
|
||||
return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->c.f;
|
||||
}
|
||||
|
||||
|
||||
LUA_API void *lua_touserdata (lua_State *L, int index) {
|
||||
StkId o = luaA_indexAcceptable(L, index);
|
||||
LUA_API void *lua_touserdata (lua_State *L, int idx) {
|
||||
StkId o = luaA_indexAcceptable(L, idx);
|
||||
if (o == NULL) return NULL;
|
||||
switch (ttype(o)) {
|
||||
case LUA_TUSERDATA: return (uvalue(o) + 1);
|
||||
@@ -352,22 +357,23 @@ LUA_API void *lua_touserdata (lua_State *L, int index) {
|
||||
}
|
||||
|
||||
|
||||
LUA_API lua_State *lua_tothread (lua_State *L, int index) {
|
||||
StkId o = luaA_indexAcceptable(L, index);
|
||||
LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
|
||||
StkId o = luaA_indexAcceptable(L, idx);
|
||||
return (o == NULL || !ttisthread(o)) ? NULL : thvalue(o);
|
||||
}
|
||||
|
||||
|
||||
LUA_API const void *lua_topointer (lua_State *L, int index) {
|
||||
StkId o = luaA_indexAcceptable(L, index);
|
||||
LUA_API const void *lua_topointer (lua_State *L, int idx) {
|
||||
StkId o = luaA_indexAcceptable(L, idx);
|
||||
if (o == NULL) return NULL;
|
||||
else {
|
||||
switch (ttype(o)) {
|
||||
case LUA_TTABLE: return hvalue(o);
|
||||
case LUA_TFUNCTION: return clvalue(o);
|
||||
case LUA_TTHREAD: return thvalue(o);
|
||||
case LUA_TUSERDATA:
|
||||
case LUA_TLIGHTUSERDATA:
|
||||
return lua_touserdata(L, index);
|
||||
return lua_touserdata(L, idx);
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
@@ -475,29 +481,29 @@ LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
|
||||
*/
|
||||
|
||||
|
||||
LUA_API void lua_gettable (lua_State *L, int index) {
|
||||
LUA_API void lua_gettable (lua_State *L, int idx) {
|
||||
StkId t;
|
||||
lua_lock(L);
|
||||
t = luaA_index(L, index);
|
||||
t = luaA_index(L, idx);
|
||||
setobj2s(L->top - 1, luaV_gettable(L, t, L->top - 1, 0));
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_rawget (lua_State *L, int index) {
|
||||
LUA_API void lua_rawget (lua_State *L, int idx) {
|
||||
StkId t;
|
||||
lua_lock(L);
|
||||
t = luaA_index(L, index);
|
||||
t = luaA_index(L, idx);
|
||||
api_check(L, ttistable(t));
|
||||
setobj2s(L->top - 1, luaH_get(hvalue(t), L->top - 1));
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_rawgeti (lua_State *L, int index, int n) {
|
||||
LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
|
||||
StkId o;
|
||||
lua_lock(L);
|
||||
o = luaA_index(L, index);
|
||||
o = luaA_index(L, idx);
|
||||
api_check(L, ttistable(o));
|
||||
setobj2s(L->top, luaH_getnum(hvalue(o), n));
|
||||
api_incr_top(L);
|
||||
@@ -515,22 +521,22 @@ LUA_API void lua_newtable (lua_State *L) {
|
||||
|
||||
|
||||
LUA_API int lua_getmetatable (lua_State *L, int objindex) {
|
||||
StkId obj;
|
||||
Table *mt;
|
||||
const TObject *obj;
|
||||
Table *mt = NULL;
|
||||
int res;
|
||||
lua_lock(L);
|
||||
obj = luaA_indexAcceptable(L, objindex);
|
||||
switch (ttype(obj)) {
|
||||
case LUA_TTABLE:
|
||||
mt = hvalue(obj)->metatable;
|
||||
break;
|
||||
case LUA_TUSERDATA:
|
||||
mt = uvalue(obj)->uv.metatable;
|
||||
break;
|
||||
default:
|
||||
mt = hvalue(defaultmeta(L));
|
||||
if (obj != NULL) {
|
||||
switch (ttype(obj)) {
|
||||
case LUA_TTABLE:
|
||||
mt = hvalue(obj)->metatable;
|
||||
break;
|
||||
case LUA_TUSERDATA:
|
||||
mt = uvalue(obj)->uv.metatable;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mt == hvalue(defaultmeta(L)))
|
||||
if (mt == NULL || mt == hvalue(defaultmeta(L)))
|
||||
res = 0;
|
||||
else {
|
||||
sethvalue(L->top, mt);
|
||||
@@ -542,10 +548,10 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_getglobals (lua_State *L, int index) {
|
||||
LUA_API void lua_getfenv (lua_State *L, int idx) {
|
||||
StkId o;
|
||||
lua_lock(L);
|
||||
o = luaA_index(L, index);
|
||||
o = luaA_index(L, idx);
|
||||
setobj2s(L->top, isLfunction(o) ? &clvalue(o)->l.g : gt(L));
|
||||
api_incr_top(L);
|
||||
lua_unlock(L);
|
||||
@@ -557,22 +563,22 @@ LUA_API void lua_getglobals (lua_State *L, int index) {
|
||||
*/
|
||||
|
||||
|
||||
LUA_API void lua_settable (lua_State *L, int index) {
|
||||
LUA_API void lua_settable (lua_State *L, int idx) {
|
||||
StkId t;
|
||||
lua_lock(L);
|
||||
api_checknelems(L, 2);
|
||||
t = luaA_index(L, index);
|
||||
t = luaA_index(L, idx);
|
||||
luaV_settable(L, t, L->top - 2, L->top - 1);
|
||||
L->top -= 2; /* pop index and value */
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_rawset (lua_State *L, int index) {
|
||||
LUA_API void lua_rawset (lua_State *L, int idx) {
|
||||
StkId t;
|
||||
lua_lock(L);
|
||||
api_checknelems(L, 2);
|
||||
t = luaA_index(L, index);
|
||||
t = luaA_index(L, idx);
|
||||
api_check(L, ttistable(t));
|
||||
setobj2t(luaH_set(L, hvalue(t), L->top-2), L->top-1); /* write barrier */
|
||||
L->top -= 2;
|
||||
@@ -580,11 +586,11 @@ LUA_API void lua_rawset (lua_State *L, int index) {
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_rawseti (lua_State *L, int index, int n) {
|
||||
LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
|
||||
StkId o;
|
||||
lua_lock(L);
|
||||
api_checknelems(L, 1);
|
||||
o = luaA_index(L, index);
|
||||
o = luaA_index(L, idx);
|
||||
api_check(L, ttistable(o));
|
||||
setobj2t(luaH_setnum(L, hvalue(o), n), L->top-1); /* write barrier */
|
||||
L->top--;
|
||||
@@ -620,12 +626,12 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_setglobals (lua_State *L, int index) {
|
||||
LUA_API int lua_setfenv (lua_State *L, int idx) {
|
||||
StkId o;
|
||||
int res = 0;
|
||||
lua_lock(L);
|
||||
api_checknelems(L, 1);
|
||||
o = luaA_index(L, index);
|
||||
o = luaA_index(L, idx);
|
||||
L->top--;
|
||||
api_check(L, ttistable(L->top));
|
||||
if (isLfunction(o)) {
|
||||
@@ -676,7 +682,7 @@ LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
|
||||
func = (errfunc == 0) ? 0 : savestack(L, luaA_index(L, errfunc));
|
||||
c.func = L->top - (nargs+1); /* function to be called */
|
||||
c.nresults = nresults;
|
||||
status = luaD_pcall(L, &f_call, &c, savestack(L, c.func), func);
|
||||
status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
|
||||
lua_unlock(L);
|
||||
return status;
|
||||
}
|
||||
@@ -710,7 +716,7 @@ LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
|
||||
lua_lock(L);
|
||||
c.func = func;
|
||||
c.ud = ud;
|
||||
status = luaD_pcall(L, &f_Ccall, &c, savestack(L, L->top), 0);
|
||||
status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
|
||||
lua_unlock(L);
|
||||
return status;
|
||||
}
|
||||
@@ -755,7 +761,7 @@ LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data) {
|
||||
/* GC values are expressed in Kbytes: #bytes/2^10 */
|
||||
#define GCscalel(x) ((x)>>10)
|
||||
#define GCscale(x) (cast(int, GCscalel(x)))
|
||||
#define GCunscale(x) (cast(lu_mem, (x)<<10))
|
||||
#define GCunscale(x) (cast(lu_mem, x)<<10)
|
||||
|
||||
LUA_API int lua_getgcthreshold (lua_State *L) {
|
||||
int threshold;
|
||||
@@ -775,8 +781,8 @@ LUA_API int lua_getgccount (lua_State *L) {
|
||||
|
||||
LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
|
||||
lua_lock(L);
|
||||
if (cast(lu_mem, newthreshold) > GCscalel(ULONG_MAX))
|
||||
G(L)->GCthreshold = ULONG_MAX;
|
||||
if (cast(lu_mem, newthreshold) > GCscalel(MAX_LUMEM))
|
||||
G(L)->GCthreshold = MAX_LUMEM;
|
||||
else
|
||||
G(L)->GCthreshold = GCunscale(newthreshold);
|
||||
luaC_checkGC(L);
|
||||
@@ -803,11 +809,11 @@ LUA_API int lua_error (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_next (lua_State *L, int index) {
|
||||
LUA_API int lua_next (lua_State *L, int idx) {
|
||||
StkId t;
|
||||
int more;
|
||||
lua_lock(L);
|
||||
t = luaA_index(L, index);
|
||||
t = luaA_index(L, idx);
|
||||
api_check(L, ttistable(t));
|
||||
more = luaH_next(L, hvalue(t), L->top - 1);
|
||||
if (more) {
|
||||
@@ -866,3 +872,51 @@ LUA_API int lua_pushupvalues (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
static const char *aux_upvalue (lua_State *L, int funcindex, int n,
|
||||
TObject **val) {
|
||||
Closure *f;
|
||||
StkId fi = luaA_index(L, funcindex);
|
||||
if (!ttisfunction(fi)) return NULL;
|
||||
f = clvalue(fi);
|
||||
if (f->c.isC) {
|
||||
if (n > f->c.nupvalues) return NULL;
|
||||
*val = &f->c.upvalue[n-1];
|
||||
return "";
|
||||
}
|
||||
else {
|
||||
Proto *p = f->l.p;
|
||||
if (n > p->sizeupvalues) return NULL;
|
||||
*val = f->l.upvals[n-1]->v;
|
||||
return getstr(p->upvalues[n-1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
|
||||
const char *name;
|
||||
TObject *val;
|
||||
lua_lock(L);
|
||||
name = aux_upvalue(L, funcindex, n, &val);
|
||||
if (name) {
|
||||
setobj2s(L->top, val);
|
||||
api_incr_top(L);
|
||||
}
|
||||
lua_unlock(L);
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
|
||||
const char *name;
|
||||
TObject *val;
|
||||
lua_lock(L);
|
||||
api_checknelems(L, 1);
|
||||
name = aux_upvalue(L, funcindex, n, &val);
|
||||
if (name) {
|
||||
L->top--;
|
||||
setobj(val, L->top); /* write barrier */
|
||||
}
|
||||
lua_unlock(L);
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
171
lauxlib.c
171
lauxlib.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lauxlib.c,v 1.90 2002/11/14 15:41:38 roberto Exp roberto $
|
||||
** $Id: lauxlib.c,v 1.99 2003/04/03 13:35:34 roberto Exp roberto $
|
||||
** Auxiliary functions for building Lua libraries
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -23,6 +23,19 @@
|
||||
#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 */
|
||||
|
||||
|
||||
/* convert a stack index to positive */
|
||||
#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \
|
||||
lua_gettop(L) + (i) + 1)
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** Error-report functions
|
||||
@@ -37,9 +50,7 @@ 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 (perhaps using `:' instead of `.')",
|
||||
ar.name);
|
||||
return luaL_error(L, "calling `%s' on bad self (%s)", ar.name, extramsg);
|
||||
}
|
||||
if (ar.name == NULL)
|
||||
ar.name = "?";
|
||||
@@ -95,6 +106,45 @@ LUALIB_API int luaL_findstring (const char *name, const char *const list[]) {
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
|
||||
lua_pushstring(L, tname);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX); /* get registry.name */
|
||||
if (!lua_isnil(L, -1)) /* name already in use? */
|
||||
return 0; /* leave previous value on top, but return 0 */
|
||||
lua_pop(L, 1);
|
||||
lua_newtable(L); /* create metatable */
|
||||
lua_pushstring(L, tname);
|
||||
lua_pushvalue(L, -2);
|
||||
lua_rawset(L, LUA_REGISTRYINDEX); /* registry.name = metatable */
|
||||
lua_pushvalue(L, -1);
|
||||
lua_pushstring(L, tname);
|
||||
lua_rawset(L, LUA_REGISTRYINDEX); /* registry[metatable] = name */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API void luaL_getmetatable (lua_State *L, const char *tname) {
|
||||
lua_pushstring(L, tname);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
|
||||
const char *tn;
|
||||
if (!lua_getmetatable(L, ud)) return NULL; /* no metatable? */
|
||||
lua_rawget(L, LUA_REGISTRYINDEX); /* get registry[metatable] */
|
||||
tn = lua_tostring(L, -1);
|
||||
if (tn && (strcmp(tn, tname) == 0)) {
|
||||
lua_pop(L, 1);
|
||||
return lua_touserdata(L, ud);
|
||||
}
|
||||
else {
|
||||
lua_pop(L, 1);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
|
||||
if (!lua_checkstack(L, space))
|
||||
luaL_error(L, "stack overflow (%s)", mes);
|
||||
@@ -155,11 +205,15 @@ LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
|
||||
lua_pop(L, 2); /* remove metatable and metafield */
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
else {
|
||||
lua_remove(L, -2); /* remove only metatable */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
|
||||
obj = abs_index(L, obj);
|
||||
if (!luaL_getmetafield(L, obj, event)) /* no metafield? */
|
||||
return 0;
|
||||
lua_pushvalue(L, obj);
|
||||
@@ -176,6 +230,9 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
|
||||
if (lua_isnil(L, -1)) { /* no? */
|
||||
lua_pop(L, 1);
|
||||
lua_newtable(L); /* create it */
|
||||
lua_pushstring(L, libname);
|
||||
lua_pushvalue(L, -2);
|
||||
lua_settable(L, LUA_GLOBALSINDEX); /* register it with given name */
|
||||
}
|
||||
lua_insert(L, -(nup+1)); /* move library table to below upvalues */
|
||||
}
|
||||
@@ -188,14 +245,81 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
|
||||
lua_settable(L, -(nup+3));
|
||||
}
|
||||
lua_pop(L, nup); /* remove upvalues */
|
||||
if (libname) {
|
||||
lua_pushstring(L, libname);
|
||||
lua_pushvalue(L, -2);
|
||||
lua_settable(L, LUA_GLOBALSINDEX);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** getn-setn: size for arrays
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
static int checkint (lua_State *L, int topop) {
|
||||
int n = (int)lua_tonumber(L, -1);
|
||||
if (n == 0 && !lua_isnumber(L, -1)) n = -1;
|
||||
lua_pop(L, topop);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static void getsizes (lua_State *L) {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF);
|
||||
if (lua_isnil(L, -1)) { /* no `size' table? */
|
||||
lua_pop(L, 1); /* remove nil */
|
||||
lua_newtable(L); /* create it */
|
||||
lua_pushvalue(L, -1); /* `size' will be its own metatable */
|
||||
lua_setmetatable(L, -2);
|
||||
lua_pushliteral(L, "__mode");
|
||||
lua_pushliteral(L, "k");
|
||||
lua_rawset(L, -3); /* metatable(N).__mode = "k" */
|
||||
lua_pushvalue(L, -1);
|
||||
lua_rawseti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); /* store in register */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void luaL_setn (lua_State *L, int t, int n) {
|
||||
t = abs_index(L, t);
|
||||
lua_pushliteral(L, "n");
|
||||
lua_rawget(L, t);
|
||||
if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */
|
||||
lua_pushliteral(L, "n"); /* use it */
|
||||
lua_pushnumber(L, (lua_Number)n);
|
||||
lua_rawset(L, t);
|
||||
}
|
||||
else { /* use `sizes' */
|
||||
getsizes(L);
|
||||
lua_pushvalue(L, t);
|
||||
lua_pushnumber(L, (lua_Number)n);
|
||||
lua_rawset(L, -3); /* sizes[t] = n */
|
||||
lua_pop(L, 1); /* remove `sizes' */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int luaL_getn (lua_State *L, int t) {
|
||||
int n;
|
||||
t = abs_index(L, t);
|
||||
lua_pushliteral(L, "n"); /* try t.n */
|
||||
lua_rawget(L, t);
|
||||
if ((n = checkint(L, 1)) >= 0) return n;
|
||||
getsizes(L); /* else try sizes[t] */
|
||||
lua_pushvalue(L, t);
|
||||
lua_rawget(L, -2);
|
||||
if ((n = checkint(L, 2)) >= 0) return n;
|
||||
for (n = 1; ; n++) { /* else must count elements */
|
||||
lua_rawgeti(L, t, n);
|
||||
if (lua_isnil(L, -1)) break;
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
return n - 1;
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
@@ -204,7 +328,6 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
|
||||
*/
|
||||
|
||||
|
||||
#define buffempty(B) ((B)->p == (B)->buffer)
|
||||
#define bufflen(B) ((B)->p - (B)->buffer)
|
||||
#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
|
||||
|
||||
@@ -295,25 +418,24 @@ LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
|
||||
|
||||
LUALIB_API int luaL_ref (lua_State *L, int t) {
|
||||
int ref;
|
||||
t = abs_index(L, t);
|
||||
if (lua_isnil(L, -1)) {
|
||||
lua_pop(L, 1); /* remove from stack */
|
||||
return LUA_REFNIL; /* `nil' has a unique fixed reference */
|
||||
}
|
||||
lua_rawgeti(L, t, 0); /* get first free element */
|
||||
ref = (int)lua_tonumber(L, -1); /* ref = t[0] */
|
||||
lua_rawgeti(L, t, FREELIST_REF); /* get first free element */
|
||||
ref = (int)lua_tonumber(L, -1); /* ref = t[FREELIST_REF] */
|
||||
lua_pop(L, 1); /* remove it from stack */
|
||||
if (ref != 0) { /* any free element? */
|
||||
lua_rawgeti(L, t, ref); /* remove it from list */
|
||||
lua_rawseti(L, t, 0); /* (that is, t[0] = t[ref]) */
|
||||
lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */
|
||||
}
|
||||
else { /* no free elements */
|
||||
lua_pushliteral(L, "n");
|
||||
lua_pushvalue(L, -1);
|
||||
lua_rawget(L, t); /* get t.n */
|
||||
ref = (int)lua_tonumber(L, -1) + 1; /* ref = t.n + 1 */
|
||||
lua_pop(L, 1); /* pop t.n */
|
||||
lua_pushnumber(L, ref);
|
||||
lua_rawset(L, t); /* t.n = t.n + 1 */
|
||||
ref = luaL_getn(L, t);
|
||||
if (ref < RESERVED_REFS)
|
||||
ref = RESERVED_REFS; /* skip reserved references */
|
||||
ref++; /* create new reference */
|
||||
luaL_setn(L, t, ref);
|
||||
}
|
||||
lua_rawseti(L, t, ref);
|
||||
return ref;
|
||||
@@ -322,10 +444,11 @@ LUALIB_API int luaL_ref (lua_State *L, int t) {
|
||||
|
||||
LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
|
||||
if (ref >= 0) {
|
||||
lua_rawgeti(L, t, 0);
|
||||
lua_rawseti(L, t, ref); /* t[ref] = t[0] */
|
||||
lua_pushnumber(L, ref);
|
||||
lua_rawseti(L, t, 0); /* t[0] = ref */
|
||||
t = abs_index(L, t);
|
||||
lua_rawgeti(L, t, FREELIST_REF);
|
||||
lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */
|
||||
lua_pushnumber(L, (lua_Number)ref);
|
||||
lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
21
lauxlib.h
21
lauxlib.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lauxlib.h,v 1.54 2002/09/16 19:49:45 roberto Exp roberto $
|
||||
** $Id: lauxlib.h,v 1.59 2003/03/18 12:25:32 roberto Exp roberto $
|
||||
** Auxiliary functions for building Lua libraries
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
|
||||
#ifndef LUALIB_API
|
||||
#define LUALIB_API extern
|
||||
#define LUALIB_API LUA_API
|
||||
#endif
|
||||
|
||||
|
||||
@@ -43,6 +43,10 @@ LUALIB_API void luaL_checkstack (lua_State *L, int sz, const char *msg);
|
||||
LUALIB_API void luaL_checktype (lua_State *L, int narg, int t);
|
||||
LUALIB_API void luaL_checkany (lua_State *L, int narg);
|
||||
|
||||
LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname);
|
||||
LUALIB_API void luaL_getmetatable (lua_State *L, const char *tname);
|
||||
LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname);
|
||||
|
||||
LUALIB_API void luaL_where (lua_State *L, int lvl);
|
||||
LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...);
|
||||
|
||||
@@ -51,6 +55,9 @@ LUALIB_API int luaL_findstring (const char *st, const char *const lst[]);
|
||||
LUALIB_API int luaL_ref (lua_State *L, int t);
|
||||
LUALIB_API void luaL_unref (lua_State *L, int t, int ref);
|
||||
|
||||
LUALIB_API int luaL_getn (lua_State *L, int t);
|
||||
LUALIB_API void luaL_setn (lua_State *L, int t, int n);
|
||||
|
||||
LUALIB_API int luaL_loadfile (lua_State *L, const char *filename);
|
||||
LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz,
|
||||
const char *name);
|
||||
@@ -69,8 +76,8 @@ LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz,
|
||||
#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
|
||||
#define luaL_checkint(L,n) ((int)luaL_checknumber(L, n))
|
||||
#define luaL_checklong(L,n) ((long)luaL_checknumber(L, n))
|
||||
#define luaL_optint(L,n,d) ((int)luaL_optnumber(L, n,d))
|
||||
#define luaL_optlong(L,n,d) ((long)luaL_optnumber(L, n,d))
|
||||
#define luaL_optint(L,n,d) ((int)luaL_optnumber(L, n,(lua_Number)(d)))
|
||||
#define luaL_optlong(L,n,d) ((long)luaL_optnumber(L, n,(lua_Number)(d)))
|
||||
|
||||
|
||||
/*
|
||||
@@ -111,7 +118,7 @@ LUALIB_API void luaL_pushresult (luaL_Buffer *B);
|
||||
|
||||
|
||||
/*
|
||||
** Compatibility macros
|
||||
** Compatibility macros and functions
|
||||
*/
|
||||
|
||||
LUALIB_API int lua_dofile (lua_State *L, const char *filename);
|
||||
@@ -119,7 +126,7 @@ LUALIB_API int lua_dostring (lua_State *L, const char *str);
|
||||
LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t sz,
|
||||
const char *n);
|
||||
|
||||
/*
|
||||
|
||||
#define luaL_check_lstr luaL_checklstring
|
||||
#define luaL_opt_lstr luaL_optlstring
|
||||
#define luaL_check_number luaL_checknumber
|
||||
@@ -131,7 +138,7 @@ LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t sz,
|
||||
#define luaL_check_long luaL_checklong
|
||||
#define luaL_opt_int luaL_optint
|
||||
#define luaL_opt_long luaL_optlong
|
||||
*/
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
133
lbaselib.c
133
lbaselib.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lbaselib.c,v 1.114 2002/12/04 17:38:31 roberto Exp roberto $
|
||||
** $Id: lbaselib.c,v 1.129 2003/03/19 21:14:34 roberto Exp roberto $
|
||||
** Basic library
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -66,7 +66,7 @@ static int luaB_tonumber (lua_State *L) {
|
||||
if (s1 != s2) { /* at least one valid digit? */
|
||||
while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */
|
||||
if (*s2 == '\0') { /* no invalid trailing characters? */
|
||||
lua_pushnumber(L, n);
|
||||
lua_pushnumber(L, (lua_Number)n);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -123,36 +123,41 @@ static void getfunc (lua_State *L) {
|
||||
if (lua_getstack(L, level, &ar) == 0)
|
||||
luaL_argerror(L, 1, "invalid level");
|
||||
lua_getinfo(L, "f", &ar);
|
||||
if (lua_isnil(L, -1))
|
||||
luaL_error(L, "no function environment for tail call at level %d",
|
||||
level);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int aux_getglobals (lua_State *L) {
|
||||
lua_getglobals(L, -1);
|
||||
lua_pushliteral(L, "__globals");
|
||||
static int aux_getfenv (lua_State *L) {
|
||||
lua_getfenv(L, -1);
|
||||
lua_pushliteral(L, "__fenv");
|
||||
lua_rawget(L, -2);
|
||||
return !lua_isnil(L, -1);
|
||||
}
|
||||
|
||||
|
||||
static int luaB_getglobals (lua_State *L) {
|
||||
static int luaB_getfenv (lua_State *L) {
|
||||
getfunc(L);
|
||||
if (!aux_getglobals(L)) /* __globals not defined? */
|
||||
lua_pop(L, 1); /* remove it, to return real globals */
|
||||
if (!aux_getfenv(L)) /* __fenv not defined? */
|
||||
lua_pop(L, 1); /* remove it, to return real environment */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_setglobals (lua_State *L) {
|
||||
static int luaB_setfenv (lua_State *L) {
|
||||
luaL_checktype(L, 2, LUA_TTABLE);
|
||||
getfunc(L);
|
||||
if (aux_getglobals(L)) /* __globals defined? */
|
||||
luaL_error(L, "cannot change a protected global table");
|
||||
if (aux_getfenv(L)) /* __fenv defined? */
|
||||
luaL_error(L, "`setfenv' cannot change a protected environment");
|
||||
else
|
||||
lua_pop(L, 2); /* remove __globals and real global table */
|
||||
lua_pop(L, 2); /* remove __fenv and real environment table */
|
||||
lua_pushvalue(L, 2);
|
||||
if (lua_setglobals(L, -2) == 0)
|
||||
luaL_error(L, "cannot change global table of given function");
|
||||
if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0)
|
||||
lua_replace(L, LUA_GLOBALSINDEX);
|
||||
else if (lua_setfenv(L, -2) == 0)
|
||||
luaL_error(L, "`setfenv' cannot change environment of given function");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -182,8 +187,8 @@ static int luaB_rawset (lua_State *L) {
|
||||
|
||||
|
||||
static int luaB_gcinfo (lua_State *L) {
|
||||
lua_pushnumber(L, lua_getgccount(L));
|
||||
lua_pushnumber(L, lua_getgcthreshold(L));
|
||||
lua_pushnumber(L, (lua_Number)lua_getgccount(L));
|
||||
lua_pushnumber(L, (lua_Number)lua_getgcthreshold(L));
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -243,19 +248,12 @@ static int luaB_ipairs (lua_State *L) {
|
||||
|
||||
|
||||
static int load_aux (lua_State *L, int status) {
|
||||
if (status == 0) { /* OK? */
|
||||
lua_Debug ar;
|
||||
lua_getstack(L, 1, &ar);
|
||||
lua_getinfo(L, "f", &ar); /* get calling function */
|
||||
lua_getglobals(L, -1); /* get its global table */
|
||||
lua_setglobals(L, -3); /* set it as the global table of the new chunk */
|
||||
lua_pop(L, 1); /* remove calling function */
|
||||
if (status == 0) /* OK? */
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
lua_pushnil(L);
|
||||
lua_insert(L, -2);
|
||||
return 2;
|
||||
lua_insert(L, -2); /* put before error message */
|
||||
return 2; /* return nil plus error message */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,20 +293,11 @@ static int luaB_assert (lua_State *L) {
|
||||
static int luaB_unpack (lua_State *L) {
|
||||
int n, i;
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
lua_pushliteral(L, "n");
|
||||
lua_rawget(L, 1);
|
||||
n = (lua_isnumber(L, -1)) ? (int)lua_tonumber(L, -1) : -1;
|
||||
for (i=0; i<n || n==-1; i++) { /* push arg[1...n] */
|
||||
luaL_checkstack(L, LUA_MINSTACK, "table too big to unpack");
|
||||
lua_rawgeti(L, 1, i+1);
|
||||
if (n == -1) { /* no explicit limit? */
|
||||
if (lua_isnil(L, -1)) { /* stop at first `nil' element */
|
||||
lua_pop(L, 1); /* remove `nil' */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return i;
|
||||
n = luaL_getn(L, 1);
|
||||
luaL_checkstack(L, n, "table too big to unpack");
|
||||
for (i=1; i<=n; i++) /* push arg[1...n] */
|
||||
lua_rawgeti(L, 1, i);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
@@ -414,6 +403,10 @@ static int luaB_newproxy (lua_State *L) {
|
||||
#define LUA_PATH_SEP ';'
|
||||
#endif
|
||||
|
||||
#ifndef LUA_PATH_MARK
|
||||
#define LUA_PATH_MARK '?'
|
||||
#endif
|
||||
|
||||
#ifndef LUA_PATH_DEFAULT
|
||||
#define LUA_PATH_DEFAULT "?;?.lua"
|
||||
#endif
|
||||
@@ -444,12 +437,18 @@ static const char *pushnextpath (lua_State *L, const char *path) {
|
||||
|
||||
static void pushcomposename (lua_State *L) {
|
||||
const char *path = lua_tostring(L, -1);
|
||||
const char *wild = strchr(path, '?');
|
||||
if (wild == NULL) return; /* no wild char; path is the file name */
|
||||
lua_pushlstring(L, path, wild - path);
|
||||
lua_pushvalue(L, 1); /* package name */
|
||||
lua_pushstring(L, wild + 1);
|
||||
lua_concat(L, 3);
|
||||
const char *wild;
|
||||
int n = 1;
|
||||
while ((wild = strchr(path, LUA_PATH_MARK)) != NULL) {
|
||||
/* is there stack space for prefix, name, and eventual last sufix? */
|
||||
luaL_checkstack(L, 3, "too many marks in a path component");
|
||||
lua_pushlstring(L, path, wild - path); /* push prefix */
|
||||
lua_pushvalue(L, 1); /* push package name (in place of MARK) */
|
||||
path = wild + 1; /* continue after MARK */
|
||||
n += 2;
|
||||
}
|
||||
lua_pushstring(L, path); /* push last sufix (`n' already includes this) */
|
||||
lua_concat(L, n);
|
||||
}
|
||||
|
||||
|
||||
@@ -458,15 +457,13 @@ static int luaB_require (lua_State *L) {
|
||||
int status = LUA_ERRFILE; /* not found (yet) */
|
||||
luaL_checkstring(L, 1);
|
||||
lua_settop(L, 1);
|
||||
lua_pushvalue(L, 1);
|
||||
lua_setglobal(L, "_REQUIREDNAME");
|
||||
lua_getglobal(L, REQTAB);
|
||||
if (!lua_istable(L, 2)) return luaL_error(L, "`" REQTAB "' is not a table");
|
||||
path = getpath(L);
|
||||
lua_pushvalue(L, 1); /* check package's name in book-keeping table */
|
||||
lua_rawget(L, 2);
|
||||
if (!lua_isnil(L, -1)) /* is it there? */
|
||||
return 0; /* package is already loaded */
|
||||
if (lua_toboolean(L, -1)) /* is it there? */
|
||||
return 1; /* package is already loaded; return its result */
|
||||
else { /* must load it */
|
||||
while (status == LUA_ERRFILE) {
|
||||
lua_settop(L, 3); /* reset stack position */
|
||||
@@ -477,18 +474,29 @@ static int luaB_require (lua_State *L) {
|
||||
}
|
||||
switch (status) {
|
||||
case 0: {
|
||||
lua_call(L, 0, 0); /* run loaded module */
|
||||
lua_getglobal(L, "_REQUIREDNAME"); /* save previous name */
|
||||
lua_insert(L, -2); /* put it below function */
|
||||
lua_pushvalue(L, 1);
|
||||
lua_pushboolean(L, 1);
|
||||
lua_setglobal(L, "_REQUIREDNAME"); /* set new name */
|
||||
lua_call(L, 0, 1); /* run loaded module */
|
||||
lua_insert(L, -2); /* put result below previous name */
|
||||
lua_setglobal(L, "_REQUIREDNAME"); /* reset to previous name */
|
||||
if (lua_isnil(L, -1)) { /* no/nil return? */
|
||||
lua_pushboolean(L, 1);
|
||||
lua_replace(L, -2); /* replace to true */
|
||||
}
|
||||
lua_pushvalue(L, 1);
|
||||
lua_pushvalue(L, -2);
|
||||
lua_rawset(L, 2); /* mark it as loaded */
|
||||
return 0;
|
||||
return 1; /* return value */
|
||||
}
|
||||
case LUA_ERRFILE: { /* file not found */
|
||||
return luaL_error(L, "could not load package `%s' from path `%s'",
|
||||
lua_tostring(L, 1), getpath(L));
|
||||
}
|
||||
default: {
|
||||
return luaL_error(L, "error loading package\n%s", lua_tostring(L, -1));
|
||||
return luaL_error(L, "error loading package `%s' (%s)",
|
||||
lua_tostring(L, 1), lua_tostring(L, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -500,8 +508,8 @@ static const luaL_reg base_funcs[] = {
|
||||
{"error", luaB_error},
|
||||
{"getmetatable", luaB_getmetatable},
|
||||
{"setmetatable", luaB_setmetatable},
|
||||
{"getglobals", luaB_getglobals},
|
||||
{"setglobals", luaB_setglobals},
|
||||
{"getfenv", luaB_getfenv},
|
||||
{"setfenv", luaB_setfenv},
|
||||
{"next", luaB_next},
|
||||
{"ipairs", luaB_ipairs},
|
||||
{"pairs", luaB_pairs},
|
||||
@@ -540,7 +548,7 @@ static int auxresume (lua_State *L, lua_State *co, int narg) {
|
||||
status = lua_resume(co, narg);
|
||||
if (status == 0) {
|
||||
int nres = lua_gettop(co);
|
||||
if (!lua_checkstack(L, narg))
|
||||
if (!lua_checkstack(L, nres))
|
||||
luaL_error(L, "too many results to resume");
|
||||
lua_xmove(co, L, nres); /* move yielded values */
|
||||
return nres;
|
||||
@@ -573,7 +581,14 @@ static int luaB_coresume (lua_State *L) {
|
||||
static int luaB_auxwrap (lua_State *L) {
|
||||
lua_State *co = lua_tothread(L, lua_upvalueindex(1));
|
||||
int r = auxresume(L, co, lua_gettop(L));
|
||||
if (r < 0) lua_error(L); /* propagate error */
|
||||
if (r < 0) {
|
||||
if (lua_isstring(L, -1)) { /* error object is a string? */
|
||||
luaL_where(L, 1); /* add extra info */
|
||||
lua_insert(L, -2);
|
||||
lua_concat(L, 2);
|
||||
}
|
||||
lua_error(L); /* propagate error */
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -649,7 +664,7 @@ static void base_open (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API int lua_baselibopen (lua_State *L) {
|
||||
LUALIB_API int luaopen_base (lua_State *L) {
|
||||
base_open(L);
|
||||
luaL_openlib(L, LUA_COLIBNAME, co_funcs, 0);
|
||||
lua_newtable(L);
|
||||
|
||||
12
lcode.c
12
lcode.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lcode.c,v 1.114 2002/12/04 17:38:31 roberto Exp roberto $
|
||||
** $Id: lcode.c,v 1.116 2003/02/27 12:33:07 roberto Exp roberto $
|
||||
** Code generator for Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -207,17 +207,17 @@ static void freeexp (FuncState *fs, expdesc *e) {
|
||||
|
||||
|
||||
static int addk (FuncState *fs, TObject *k, TObject *v) {
|
||||
const TObject *index = luaH_get(fs->h, k);
|
||||
if (ttisnumber(index)) {
|
||||
lua_assert(luaO_rawequalObj(&fs->f->k[cast(int, nvalue(index))], v));
|
||||
return cast(int, nvalue(index));
|
||||
const TObject *idx = luaH_get(fs->h, k);
|
||||
if (ttisnumber(idx)) {
|
||||
lua_assert(luaO_rawequalObj(&fs->f->k[cast(int, nvalue(idx))], v));
|
||||
return cast(int, nvalue(idx));
|
||||
}
|
||||
else { /* constant not found; create a new entry */
|
||||
Proto *f = fs->f;
|
||||
luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject,
|
||||
MAXARG_Bx, "constant table overflow");
|
||||
setobj2n(&f->k[fs->nk], v);
|
||||
setnvalue(luaH_set(fs->L, fs->h, k), fs->nk);
|
||||
setnvalue(luaH_set(fs->L, fs->h, k), cast(lua_Number, fs->nk));
|
||||
return fs->nk++;
|
||||
}
|
||||
}
|
||||
|
||||
46
ldblib.c
46
ldblib.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldblib.c,v 1.74 2002/12/04 17:38:31 roberto Exp roberto $
|
||||
** $Id: ldblib.c,v 1.79 2003/03/11 12:24:34 roberto Exp roberto $
|
||||
** Interface from Lua to its debug API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -27,7 +27,7 @@ static void settabss (lua_State *L, const char *i, const char *v) {
|
||||
|
||||
static void settabsi (lua_State *L, const char *i, int v) {
|
||||
lua_pushstring(L, i);
|
||||
lua_pushnumber(L, v);
|
||||
lua_pushnumber(L, (lua_Number)v);
|
||||
lua_rawset(L, -3);
|
||||
}
|
||||
|
||||
@@ -108,17 +108,43 @@ static int setlocal (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
static int auxupvalue (lua_State *L, int get) {
|
||||
const char *name;
|
||||
int n = luaL_checkint(L, 2);
|
||||
luaL_checktype(L, 1, LUA_TFUNCTION);
|
||||
if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */
|
||||
name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
|
||||
if (name == NULL) return 0;
|
||||
lua_pushstring(L, name);
|
||||
lua_insert(L, -(get+1));
|
||||
return get + 1;
|
||||
}
|
||||
|
||||
|
||||
static int getupvalue (lua_State *L) {
|
||||
return auxupvalue(L, 1);
|
||||
}
|
||||
|
||||
|
||||
static int setupvalue (lua_State *L) {
|
||||
luaL_checkany(L, 3);
|
||||
return auxupvalue(L, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char KEY_HOOK = 'h';
|
||||
|
||||
|
||||
static void hookf (lua_State *L, lua_Debug *ar) {
|
||||
static const char *const hooknames[] = {"call", "return", "line", "count"};
|
||||
static const char *const hooknames[] =
|
||||
{"call", "return", "line", "count", "tail return"};
|
||||
lua_pushlightuserdata(L, (void *)&KEY_HOOK);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
if (lua_isfunction(L, -1)) {
|
||||
lua_pushstring(L, hooknames[(int)ar->event]);
|
||||
if (ar->currentline >= 0) lua_pushnumber(L, ar->currentline);
|
||||
if (ar->currentline >= 0)
|
||||
lua_pushnumber(L, (lua_Number)ar->currentline);
|
||||
else lua_pushnil(L);
|
||||
lua_assert(lua_getinfo(L, "lS", ar));
|
||||
lua_call(L, 2, 0);
|
||||
@@ -177,7 +203,7 @@ static int gethook (lua_State *L) {
|
||||
lua_rawget(L, LUA_REGISTRYINDEX); /* get hook */
|
||||
}
|
||||
lua_pushstring(L, unmakemask(mask, buff));
|
||||
lua_pushnumber(L, lua_gethookcount(L));
|
||||
lua_pushnumber(L, (lua_Number)lua_gethookcount(L));
|
||||
return 3;
|
||||
}
|
||||
|
||||
@@ -235,8 +261,8 @@ static int errorfb (lua_State *L) {
|
||||
default: {
|
||||
if (*ar.what == 'm') /* main? */
|
||||
lua_pushfstring(L, " in main chunk");
|
||||
else if (*ar.what == 'C') /* C function? */
|
||||
lua_pushfstring(L, "%s", ar.short_src);
|
||||
else if (*ar.what == 'C' || *ar.what == 't')
|
||||
lua_pushliteral(L, " ?"); /* C function or tail call */
|
||||
else
|
||||
lua_pushfstring(L, " in function <%s:%d>",
|
||||
ar.short_src, ar.linedefined);
|
||||
@@ -253,19 +279,21 @@ static const luaL_reg dblib[] = {
|
||||
{"getlocal", getlocal},
|
||||
{"getinfo", getinfo},
|
||||
{"gethook", gethook},
|
||||
{"getupvalue", getupvalue},
|
||||
{"sethook", sethook},
|
||||
{"setlocal", setlocal},
|
||||
{"setupvalue", setupvalue},
|
||||
{"debug", debug},
|
||||
{"traceback", errorfb},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
LUALIB_API int lua_dblibopen (lua_State *L) {
|
||||
LUALIB_API int luaopen_debug (lua_State *L) {
|
||||
luaL_openlib(L, LUA_DBLIBNAME, dblib, 0);
|
||||
lua_pushliteral(L, "_TRACEBACK");
|
||||
lua_pushcfunction(L, errorfb);
|
||||
lua_settable(L, LUA_GLOBALSINDEX);
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
151
ldebug.c
151
ldebug.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldebug.c,v 1.142 2002/12/06 17:15:35 roberto Exp roberto $
|
||||
** $Id: ldebug.c,v 1.149 2003/03/18 12:50:04 roberto Exp roberto $
|
||||
** Debug Interface
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -93,13 +93,21 @@ LUA_API int lua_gethookcount (lua_State *L) {
|
||||
|
||||
LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
|
||||
int status;
|
||||
int ci;
|
||||
CallInfo *ci;
|
||||
lua_lock(L);
|
||||
ci = (L->ci - L->base_ci) - level;
|
||||
if (ci <= 0) status = 0; /* there is no such level */
|
||||
else {
|
||||
ar->i_ci = ci;
|
||||
for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {
|
||||
level--;
|
||||
if (!(ci->state & CI_C)) /* Lua function? */
|
||||
level -= ci->u.l.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 */
|
||||
status = 1;
|
||||
ar->i_ci = 0;
|
||||
}
|
||||
else {
|
||||
status = 1;
|
||||
ar->i_ci = ci - L->base_ci;
|
||||
}
|
||||
lua_unlock(L);
|
||||
return status;
|
||||
@@ -150,31 +158,19 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
|
||||
}
|
||||
|
||||
|
||||
static void infoLproto (lua_Debug *ar, Proto *f) {
|
||||
ar->source = getstr(f->source);
|
||||
ar->linedefined = f->lineDefined;
|
||||
ar->what = "Lua";
|
||||
}
|
||||
|
||||
|
||||
static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) {
|
||||
Closure *cl;
|
||||
if (ttisfunction(func))
|
||||
cl = clvalue(func);
|
||||
else {
|
||||
luaG_runerror(L, "value for `lua_getinfo' is not a function");
|
||||
cl = NULL; /* to avoid warnings */
|
||||
}
|
||||
static void funcinfo (lua_Debug *ar, StkId func) {
|
||||
Closure *cl = clvalue(func);
|
||||
if (cl->c.isC) {
|
||||
ar->source = "=[C]";
|
||||
ar->linedefined = -1;
|
||||
ar->what = "C";
|
||||
}
|
||||
else
|
||||
infoLproto(ar, cl->l.p);
|
||||
else {
|
||||
ar->source = getstr(cl->l.p->source);
|
||||
ar->linedefined = cl->l.p->lineDefined;
|
||||
ar->what = (ar->linedefined == 0) ? "main" : "Lua";
|
||||
}
|
||||
luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
|
||||
if (ar->linedefined == 0)
|
||||
ar->what = "main";
|
||||
}
|
||||
|
||||
|
||||
@@ -182,41 +178,32 @@ static const char *travglobals (lua_State *L, const TObject *o) {
|
||||
Table *g = hvalue(gt(L));
|
||||
int i = sizenode(g);
|
||||
while (i--) {
|
||||
Node *n = node(g, i);
|
||||
if (luaO_rawequalObj(o, val(n)) && ttisstring(key(n)))
|
||||
return getstr(tsvalue(key(n)));
|
||||
Node *n = gnode(g, i);
|
||||
if (luaO_rawequalObj(o, gval(n)) && ttisstring(gkey(n)))
|
||||
return getstr(tsvalue(gkey(n)));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void getname (lua_State *L, const TObject *f, lua_Debug *ar) {
|
||||
/* try to find a name for given function */
|
||||
if ((ar->name = travglobals(L, f)) != NULL)
|
||||
ar->namewhat = "global";
|
||||
else ar->namewhat = ""; /* not found */
|
||||
static void info_tailcall (lua_State *L, lua_Debug *ar) {
|
||||
ar->name = ar->namewhat = "";
|
||||
ar->what = "tail";
|
||||
ar->linedefined = ar->currentline = -1;
|
||||
ar->source = "=(tail call)";
|
||||
luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
|
||||
ar->nups = 0;
|
||||
setnilvalue(L->top);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
|
||||
StkId f;
|
||||
CallInfo *ci;
|
||||
static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
|
||||
StkId f, CallInfo *ci) {
|
||||
int status = 1;
|
||||
lua_lock(L);
|
||||
if (*what != '>') { /* function is active? */
|
||||
ci = L->base_ci + ar->i_ci;
|
||||
f = ci->base - 1;
|
||||
}
|
||||
else {
|
||||
what++; /* skip the `>' */
|
||||
ci = NULL;
|
||||
f = L->top - 1;
|
||||
}
|
||||
for (; *what; what++) {
|
||||
switch (*what) {
|
||||
case 'S': {
|
||||
funcinfo(L, ar, f);
|
||||
funcinfo(ar, f);
|
||||
break;
|
||||
}
|
||||
case 'l': {
|
||||
@@ -224,25 +211,48 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
|
||||
break;
|
||||
}
|
||||
case 'u': {
|
||||
ar->nups = (ttisfunction(f)) ? clvalue(f)->c.nupvalues : 0;
|
||||
ar->nups = clvalue(f)->c.nupvalues;
|
||||
break;
|
||||
}
|
||||
case 'n': {
|
||||
ar->namewhat = (ci) ? getfuncname(ci, &ar->name) : NULL;
|
||||
if (ar->namewhat == NULL)
|
||||
getname(L, f, ar);
|
||||
if (ar->namewhat == NULL) {
|
||||
/* try to find a global name */
|
||||
if ((ar->name = travglobals(L, f)) != NULL)
|
||||
ar->namewhat = "global";
|
||||
else ar->namewhat = ""; /* not found */
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'f': {
|
||||
setobj2s(L->top, f);
|
||||
status = 2;
|
||||
break;
|
||||
}
|
||||
default: status = 0; /* invalid option */
|
||||
}
|
||||
}
|
||||
if (!ci) L->top--; /* pop function */
|
||||
if (status == 2) incr_top(L);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
|
||||
int status = 1;
|
||||
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);
|
||||
L->top--; /* pop function */
|
||||
}
|
||||
else if (ar->i_ci != 0) { /* no tail call? */
|
||||
CallInfo *ci = L->base_ci + ar->i_ci;
|
||||
lua_assert(ttisfunction(ci->base - 1));
|
||||
status = auxgetinfo(L, what, ar, ci->base - 1, ci);
|
||||
}
|
||||
else
|
||||
info_tailcall(L, ar);
|
||||
if (strchr(what, 'f')) incr_top(L);
|
||||
lua_unlock(L);
|
||||
return status;
|
||||
}
|
||||
@@ -345,7 +355,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
|
||||
}
|
||||
case OP_GETUPVAL:
|
||||
case OP_SETUPVAL: {
|
||||
check(b < pt->nupvalues);
|
||||
check(b < pt->nups);
|
||||
break;
|
||||
}
|
||||
case OP_GETGLOBAL:
|
||||
@@ -404,7 +414,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
|
||||
case OP_CLOSURE: {
|
||||
int nup;
|
||||
check(b < pt->sizep);
|
||||
nup = pt->p[b]->nupvalues;
|
||||
nup = pt->p[b]->nups;
|
||||
check(pc + nup < pt->sizecode);
|
||||
for (; nup>0; nup--) {
|
||||
OpCode op1 = GET_OPCODE(pt->code[pc+nup]);
|
||||
@@ -451,8 +461,9 @@ static const char *getobjname (CallInfo *ci, int stackpos, const char **name) {
|
||||
lua_assert(pc != -1);
|
||||
switch (GET_OPCODE(i)) {
|
||||
case OP_GETGLOBAL: {
|
||||
lua_assert(ttisstring(&p->k[GETARG_Bx(i)]));
|
||||
*name = svalue(&p->k[GETARG_Bx(i)]);
|
||||
int g = GETARG_Bx(i); /* global index */
|
||||
lua_assert(ttisstring(&p->k[g]));
|
||||
*name = svalue(&p->k[g]);
|
||||
return "global";
|
||||
}
|
||||
case OP_MOVE: {
|
||||
@@ -463,11 +474,13 @@ static const char *getobjname (CallInfo *ci, int stackpos, const char **name) {
|
||||
break;
|
||||
}
|
||||
case OP_GETTABLE: {
|
||||
*name = kname(p, GETARG_C(i));
|
||||
int k = GETARG_C(i); /* key index */
|
||||
*name = kname(p, k);
|
||||
return "field";
|
||||
}
|
||||
case OP_SELF: {
|
||||
*name = kname(p, GETARG_C(i));
|
||||
int k = GETARG_C(i); /* key index */
|
||||
*name = kname(p, k);
|
||||
return "method";
|
||||
}
|
||||
default: break;
|
||||
@@ -477,18 +490,16 @@ static const char *getobjname (CallInfo *ci, int stackpos, const char **name) {
|
||||
}
|
||||
|
||||
|
||||
static Instruction getcurrentinstr (CallInfo *ci) {
|
||||
return (!isLua(ci)) ? (Instruction)(-1) :
|
||||
ci_func(ci)->l.p->code[currentpc(ci)];
|
||||
}
|
||||
|
||||
|
||||
static const char *getfuncname (CallInfo *ci, const char **name) {
|
||||
Instruction i;
|
||||
if ((isLua(ci) && ci->u.l.tailcalls > 0) || !isLua(ci - 1))
|
||||
return NULL; /* calling function is not Lua (or is unknown) */
|
||||
ci--; /* calling function */
|
||||
i = getcurrentinstr(ci);
|
||||
return (GET_OPCODE(i) == OP_CALL ? getobjname(ci, GETARG_A(i), name)
|
||||
: NULL); /* no useful name found */
|
||||
i = ci_func(ci)->l.p->code[currentpc(ci)];
|
||||
if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL)
|
||||
return getobjname(ci, GETARG_A(i), name);
|
||||
else
|
||||
return NULL; /* no useful name can be found */
|
||||
}
|
||||
|
||||
|
||||
@@ -517,7 +528,7 @@ void luaG_typeerror (lua_State *L, const TObject *o, const char *op) {
|
||||
void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
|
||||
if (ttisstring(p1)) p1 = p2;
|
||||
lua_assert(!ttisstring(p1));
|
||||
luaG_typeerror(L, p1, "concat");
|
||||
luaG_typeerror(L, p1, "concatenate");
|
||||
}
|
||||
|
||||
|
||||
|
||||
63
ldo.c
63
ldo.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldo.c,v 1.210 2002/12/04 17:28:27 roberto Exp roberto $
|
||||
** $Id: ldo.c,v 1.216 2003/02/28 19:45:15 roberto Exp roberto $
|
||||
** Stack and Call structure of Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** Error-recovery functions (based on long jumps)
|
||||
@@ -161,7 +162,10 @@ void luaD_callhook (lua_State *L, int event, int line) {
|
||||
lua_Debug ar;
|
||||
ar.event = event;
|
||||
ar.currentline = line;
|
||||
ar.i_ci = L->ci - L->base_ci;
|
||||
if (event == LUA_HOOKTAILRET)
|
||||
ar.i_ci = 0; /* tail call; no debug information about it */
|
||||
else
|
||||
ar.i_ci = L->ci - L->base_ci;
|
||||
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
|
||||
L->ci->top = L->top + LUA_MINSTACK;
|
||||
L->allowhook = 0; /* cannot call hooks inside a hook */
|
||||
@@ -187,12 +191,12 @@ static void adjust_varargs (lua_State *L, int nfixargs, StkId base) {
|
||||
setnilvalue(L->top++);
|
||||
}
|
||||
actual -= nfixargs; /* number of extra arguments */
|
||||
htab = luaH_new(L, 0, 0); /* create `arg' table */
|
||||
htab = luaH_new(L, actual, 1); /* create `arg' table */
|
||||
for (i=0; i<actual; i++) /* put extra arguments into `arg' table */
|
||||
setobj2n(luaH_setnum(L, htab, i+1), L->top - actual + i);
|
||||
/* store counter in field `n' */
|
||||
setsvalue(&nname, luaS_newliteral(L, "n"));
|
||||
setnvalue(luaH_set(L, htab, &nname), actual);
|
||||
setnvalue(luaH_set(L, htab, &nname), cast(lua_Number, actual));
|
||||
L->top -= actual; /* remove extra elements from the stack */
|
||||
sethvalue(L->top, htab);
|
||||
incr_top(L);
|
||||
@@ -232,6 +236,7 @@ StkId luaD_precall (lua_State *L, StkId func) {
|
||||
L->base = L->ci->base = restorestack(L, funcr) + 1;
|
||||
ci->top = L->base + p->maxstacksize;
|
||||
ci->u.l.savedpc = p->code; /* starting point */
|
||||
ci->u.l.tailcalls = 0;
|
||||
ci->state = CI_SAVEDPC;
|
||||
while (L->top < ci->top)
|
||||
setnilvalue(L->top++);
|
||||
@@ -246,10 +251,8 @@ StkId luaD_precall (lua_State *L, StkId func) {
|
||||
L->base = L->ci->base = restorestack(L, funcr) + 1;
|
||||
ci->top = L->top + LUA_MINSTACK;
|
||||
ci->state = CI_C; /* a C function */
|
||||
if (L->hookmask & LUA_MASKCALL) {
|
||||
if (L->hookmask & LUA_MASKCALL)
|
||||
luaD_callhook(L, LUA_HOOKCALL, -1);
|
||||
ci = L->ci; /* previous call may reallocate `ci' */
|
||||
}
|
||||
lua_unlock(L);
|
||||
#ifdef LUA_COMPATUPVALUES
|
||||
lua_pushupvalues(L);
|
||||
@@ -261,13 +264,21 @@ StkId luaD_precall (lua_State *L, StkId func) {
|
||||
}
|
||||
|
||||
|
||||
static StkId callrethooks (lua_State *L, StkId firstResult) {
|
||||
ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
|
||||
luaD_callhook(L, LUA_HOOKRET, -1);
|
||||
if (!(L->ci->state & CI_C)) { /* Lua function? */
|
||||
while (L->ci->u.l.tailcalls--) /* call hook for eventual tail calls */
|
||||
luaD_callhook(L, LUA_HOOKTAILRET, -1);
|
||||
}
|
||||
return restorestack(L, fr);
|
||||
}
|
||||
|
||||
|
||||
void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
|
||||
StkId res;
|
||||
if (L->hookmask & LUA_MASKRET) {
|
||||
ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
|
||||
luaD_callhook(L, LUA_HOOKRET, -1);
|
||||
firstResult = restorestack(L, fr);
|
||||
}
|
||||
if (L->hookmask & LUA_MASKRET)
|
||||
firstResult = callrethooks(L, firstResult);
|
||||
res = L->base - 1; /* res == final position of 1st result */
|
||||
L->ci--;
|
||||
L->base = L->ci->base; /* restore base */
|
||||
@@ -279,7 +290,6 @@ void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
|
||||
while (wanted-- > 0)
|
||||
setnilvalue(res++);
|
||||
L->top = res;
|
||||
luaC_checkGC(L);
|
||||
}
|
||||
|
||||
|
||||
@@ -291,9 +301,10 @@ void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
|
||||
*/
|
||||
void luaD_call (lua_State *L, StkId func, int nResults) {
|
||||
StkId firstResult;
|
||||
lua_assert(!(L->ci->state & CI_CALLING));
|
||||
if (++L->nCcalls >= LUA_MAXCCALLS) {
|
||||
if (L->nCcalls == LUA_MAXCCALLS)
|
||||
luaG_runerror(L, "stack overflow");
|
||||
luaG_runerror(L, "C stack overflow");
|
||||
else if (L->nCcalls >= (LUA_MAXCCALLS + (LUA_MAXCCALLS>>3)))
|
||||
luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
|
||||
}
|
||||
@@ -302,6 +313,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
|
||||
firstResult = luaV_execute(L); /* call it */
|
||||
luaD_poscall(L, nResults, firstResult);
|
||||
L->nCcalls--;
|
||||
luaC_checkGC(L);
|
||||
}
|
||||
|
||||
|
||||
@@ -415,10 +427,13 @@ struct SParser { /* data to `f_parser' */
|
||||
};
|
||||
|
||||
static void f_parser (lua_State *L, void *ud) {
|
||||
struct SParser *p = cast(struct SParser *, ud);
|
||||
Proto *tf = p->bin ? luaU_undump(L, p->z, &p->buff) :
|
||||
luaY_parser(L, p->z, &p->buff);
|
||||
Closure *cl = luaF_newLclosure(L, 0, gt(L));
|
||||
struct SParser *p;
|
||||
Proto *tf;
|
||||
Closure *cl;
|
||||
luaC_checkGC(L);
|
||||
p = cast(struct SParser *, ud);
|
||||
tf = p->bin ? luaU_undump(L, p->z, &p->buff) : luaY_parser(L, p->z, &p->buff);
|
||||
cl = luaF_newLclosure(L, 0, gt(L));
|
||||
cl->l.p = tf;
|
||||
setclvalue(L->top, cl);
|
||||
incr_top(L);
|
||||
@@ -427,23 +442,13 @@ static void f_parser (lua_State *L, void *ud) {
|
||||
|
||||
int luaD_protectedparser (lua_State *L, ZIO *z, int bin) {
|
||||
struct SParser p;
|
||||
lu_mem old_blocks;
|
||||
int status;
|
||||
ptrdiff_t oldtopr = savestack(L, L->top); /* save current top */
|
||||
p.z = z; p.bin = bin;
|
||||
luaZ_initbuffer(L, &p.buff);
|
||||
/* before parsing, give a (good) chance to GC */
|
||||
if (G(L)->nblocks + G(L)->nblocks/4 >= G(L)->GCthreshold)
|
||||
luaC_collectgarbage(L);
|
||||
old_blocks = G(L)->nblocks;
|
||||
status = luaD_rawrunprotected(L, f_parser, &p);
|
||||
luaZ_freebuffer(L, &p.buff);
|
||||
if (status == 0) {
|
||||
/* add new memory to threshold (as it probably will stay) */
|
||||
lua_assert(G(L)->nblocks >= old_blocks);
|
||||
G(L)->GCthreshold += (G(L)->nblocks - old_blocks);
|
||||
}
|
||||
else { /* error */
|
||||
if (status != 0) { /* error? */
|
||||
StkId oldtop = restorestack(L, oldtopr);
|
||||
seterrorobj(L, status, oldtop);
|
||||
}
|
||||
|
||||
26
ldump.c
26
ldump.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldump.c,v 1.1 2002/10/25 21:31:28 roberto Exp roberto $
|
||||
** $Id: ldump.c,v 1.4 2003/02/11 23:52:12 lhf Exp $
|
||||
** save bytecodes
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -19,13 +19,12 @@
|
||||
#define DumpLiteral(s,D) DumpBlock("" s,(sizeof(s))-1,D)
|
||||
|
||||
typedef struct {
|
||||
lua_State *L;
|
||||
lua_State* L;
|
||||
lua_Chunkwriter write;
|
||||
void *data;
|
||||
void* data;
|
||||
} DumpState;
|
||||
|
||||
|
||||
static void DumpBlock(const void *b, size_t size, DumpState* D)
|
||||
static void DumpBlock(const void* b, size_t size, DumpState* D)
|
||||
{
|
||||
lua_unlock(D->L);
|
||||
(*D->write)(D->L,b,size,D->data);
|
||||
@@ -89,6 +88,13 @@ static void DumpLines(const Proto* f, DumpState* D)
|
||||
DumpVector(f->lineinfo,f->sizelineinfo,sizeof(*f->lineinfo),D);
|
||||
}
|
||||
|
||||
static void DumpUpvalues(const Proto* f, DumpState* D)
|
||||
{
|
||||
int i,n=f->sizeupvalues;
|
||||
DumpInt(n,D);
|
||||
for (i=0; i<n; i++) DumpString(f->upvalues[i],D);
|
||||
}
|
||||
|
||||
static void DumpFunction(const Proto* f, const TString* p, DumpState* D);
|
||||
|
||||
static void DumpConstants(const Proto* f, DumpState* D)
|
||||
@@ -122,12 +128,13 @@ static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
|
||||
{
|
||||
DumpString((f->source==p) ? NULL : f->source,D);
|
||||
DumpInt(f->lineDefined,D);
|
||||
DumpByte(f->nupvalues,D);
|
||||
DumpByte(f->nups,D);
|
||||
DumpByte(f->numparams,D);
|
||||
DumpByte(f->is_vararg,D);
|
||||
DumpByte(f->maxstacksize,D);
|
||||
DumpLocals(f,D);
|
||||
DumpLines(f,D);
|
||||
DumpLocals(f,D);
|
||||
DumpUpvalues(f,D);
|
||||
DumpConstants(f,D);
|
||||
DumpCode(f,D);
|
||||
}
|
||||
@@ -148,7 +155,10 @@ static void DumpHeader(DumpState* D)
|
||||
DumpNumber(TEST_NUMBER,D);
|
||||
}
|
||||
|
||||
void luaU_dump(lua_State *L, const Proto* Main, lua_Chunkwriter w, void* data)
|
||||
/*
|
||||
** dump function as precompiled chunk
|
||||
*/
|
||||
void luaU_dump (lua_State* L, const Proto* Main, lua_Chunkwriter w, void* data)
|
||||
{
|
||||
DumpState D;
|
||||
D.L=L;
|
||||
|
||||
11
lfunc.c
11
lfunc.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lfunc.c,v 1.63 2002/11/14 16:15:53 roberto Exp roberto $
|
||||
** $Id: lfunc.c,v 1.66 2003/02/11 10:46:24 roberto Exp roberto $
|
||||
** Auxiliary functions to manipulate prototypes and closures
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -35,11 +35,11 @@ Closure *luaF_newCclosure (lua_State *L, int nelems) {
|
||||
}
|
||||
|
||||
|
||||
Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *gt) {
|
||||
Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *e) {
|
||||
Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems)));
|
||||
luaC_link(L, valtogco(c), LUA_TFUNCTION);
|
||||
c->l.isC = 0;
|
||||
c->l.g = *gt;
|
||||
c->l.g = *e;
|
||||
c->l.nupvalues = cast(lu_byte, nelems);
|
||||
return c;
|
||||
}
|
||||
@@ -84,7 +84,9 @@ Proto *luaF_newproto (lua_State *L) {
|
||||
f->code = NULL;
|
||||
f->sizecode = 0;
|
||||
f->sizelineinfo = 0;
|
||||
f->nupvalues = 0;
|
||||
f->sizeupvalues = 0;
|
||||
f->nups = 0;
|
||||
f->upvalues = NULL;
|
||||
f->numparams = 0;
|
||||
f->is_vararg = 0;
|
||||
f->maxstacksize = 0;
|
||||
@@ -103,6 +105,7 @@ void luaF_freeproto (lua_State *L, Proto *f) {
|
||||
luaM_freearray(L, f->k, f->sizek, TObject);
|
||||
luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
|
||||
luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
|
||||
luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
|
||||
luaM_freelem(L, f);
|
||||
}
|
||||
|
||||
|
||||
4
lfunc.h
4
lfunc.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lfunc.h,v 1.19 2001/11/29 20:22:22 roberto Exp roberto $
|
||||
** $Id: lfunc.h,v 1.20 2002/06/20 20:41:46 roberto Exp roberto $
|
||||
** Auxiliary functions to manipulate prototypes and closures
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
Proto *luaF_newproto (lua_State *L);
|
||||
Closure *luaF_newCclosure (lua_State *L, int nelems);
|
||||
Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *gt);
|
||||
Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *e);
|
||||
UpVal *luaF_findupval (lua_State *L, StkId level);
|
||||
void luaF_close (lua_State *L, StkId level);
|
||||
void luaF_freeproto (lua_State *L, Proto *f);
|
||||
|
||||
71
lgc.c
71
lgc.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lgc.c,v 1.165 2002/12/02 12:06:10 roberto Exp roberto $
|
||||
** $Id: lgc.c,v 1.170 2003/03/18 12:50:04 roberto Exp roberto $
|
||||
** Garbage Collector
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -27,7 +27,7 @@ typedef struct GCState {
|
||||
GCObject *wk; /* list of traversed key-weak tables (to be cleared) */
|
||||
GCObject *wv; /* list of traversed value-weak tables */
|
||||
GCObject *wkv; /* list of traversed key-value weak tables */
|
||||
global_State *G;
|
||||
global_State *g;
|
||||
} GCState;
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ static void reallymarkobject (GCState *st, GCObject *o) {
|
||||
|
||||
static void marktmu (GCState *st) {
|
||||
GCObject *u;
|
||||
for (u = st->G->tmudata; u; u = u->gch.next) {
|
||||
for (u = st->g->tmudata; u; u = u->gch.next) {
|
||||
unmark(u); /* may be marked, if left from previous GC */
|
||||
reallymarkobject(st, u);
|
||||
}
|
||||
@@ -110,7 +110,7 @@ static void marktmu (GCState *st) {
|
||||
|
||||
|
||||
/* move `dead' udata that need finalization to list `tmudata' */
|
||||
static void separateudata (lua_State *L) {
|
||||
void luaC_separateudata (lua_State *L) {
|
||||
GCObject **p = &G(L)->rootudata;
|
||||
GCObject *curr;
|
||||
GCObject *collected = NULL; /* to collect udata with gc event */
|
||||
@@ -138,9 +138,9 @@ static void separateudata (lua_State *L) {
|
||||
|
||||
|
||||
static void removekey (Node *n) {
|
||||
setnilvalue(val(n)); /* remove corresponding value ... */
|
||||
if (iscollectable(key(n)))
|
||||
setttype(key(n), LUA_TNONE); /* dead key; remove it */
|
||||
setnilvalue(gval(n)); /* remove corresponding value ... */
|
||||
if (iscollectable(gkey(n)))
|
||||
setttype(gkey(n), LUA_TNONE); /* dead key; remove it */
|
||||
}
|
||||
|
||||
|
||||
@@ -150,15 +150,16 @@ static void traversetable (GCState *st, Table *h) {
|
||||
int weakvalue = 0;
|
||||
const TObject *mode;
|
||||
markvalue(st, h->metatable);
|
||||
lua_assert(h->lsizenode || h->node == st->G->dummynode);
|
||||
mode = gfasttm(st->G, h->metatable, TM_MODE);
|
||||
lua_assert(h->lsizenode || h->node == st->g->dummynode);
|
||||
mode = gfasttm(st->g, h->metatable, TM_MODE);
|
||||
if (mode && ttisstring(mode)) { /* is there a weak mode? */
|
||||
weakkey = (strchr(svalue(mode), 'k') != NULL);
|
||||
weakvalue = (strchr(svalue(mode), 'v') != NULL);
|
||||
if (weakkey || weakvalue) { /* is really weak? */
|
||||
GCObject **weaklist;
|
||||
h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */
|
||||
h->marked |= (weakkey << KEYWEAKBIT) | (weakvalue << VALUEWEAKBIT);
|
||||
h->marked |= cast(lu_byte, (weakkey << KEYWEAKBIT) |
|
||||
(weakvalue << VALUEWEAKBIT));
|
||||
weaklist = (weakkey && weakvalue) ? &st->wkv :
|
||||
(weakkey) ? &st->wk :
|
||||
&st->wv;
|
||||
@@ -167,17 +168,17 @@ static void traversetable (GCState *st, Table *h) {
|
||||
}
|
||||
}
|
||||
if (!weakvalue) {
|
||||
i = sizearray(h);
|
||||
i = h->sizearray;
|
||||
while (i--)
|
||||
markobject(st, &h->array[i]);
|
||||
}
|
||||
i = sizenode(h);
|
||||
while (i--) {
|
||||
Node *n = node(h, i);
|
||||
if (!ttisnil(val(n))) {
|
||||
lua_assert(!ttisnil(key(n)));
|
||||
condmarkobject(st, key(n), !weakkey);
|
||||
condmarkobject(st, val(n), !weakvalue);
|
||||
Node *n = gnode(h, i);
|
||||
if (!ttisnil(gval(n))) {
|
||||
lua_assert(!ttisnil(gkey(n)));
|
||||
condmarkobject(st, gkey(n), !weakkey);
|
||||
condmarkobject(st, gval(n), !weakvalue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,11 +187,13 @@ static void traversetable (GCState *st, Table *h) {
|
||||
static void traverseproto (GCState *st, Proto *f) {
|
||||
int i;
|
||||
stringmark(f->source);
|
||||
for (i=0; i<f->sizek; i++) {
|
||||
for (i=0; i<f->sizek; i++) { /* mark literal strings */
|
||||
if (ttisstring(f->k+i))
|
||||
stringmark(tsvalue(f->k+i));
|
||||
}
|
||||
for (i=0; i<f->sizep; i++)
|
||||
for (i=0; i<f->sizeupvalues; i++) /* mark upvalue names */
|
||||
stringmark(f->upvalues[i]);
|
||||
for (i=0; i<f->sizep; i++) /* mark nested protos */
|
||||
markvalue(st, f->p[i]);
|
||||
for (i=0; i<f->sizelocvars; i++) /* mark local-variable names */
|
||||
stringmark(f->locvars[i].varname);
|
||||
@@ -207,7 +210,7 @@ static void traverseclosure (GCState *st, Closure *cl) {
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
lua_assert(cl->l.nupvalues == cl->l.p->nupvalues);
|
||||
lua_assert(cl->l.nupvalues == cl->l.p->nups);
|
||||
markvalue(st, hvalue(&cl->l.g));
|
||||
markvalue(st, cl->l.p);
|
||||
for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */
|
||||
@@ -301,8 +304,8 @@ static void cleartablekeys (GCObject *l) {
|
||||
int i = sizenode(h);
|
||||
lua_assert(h->marked & KEYWEAK);
|
||||
while (i--) {
|
||||
Node *n = node(h, i);
|
||||
if (!valismarked(key(n))) /* key was collected? */
|
||||
Node *n = gnode(h, i);
|
||||
if (!valismarked(gkey(n))) /* key was collected? */
|
||||
removekey(n); /* remove entry from table */
|
||||
}
|
||||
l = h->gclist;
|
||||
@@ -316,7 +319,7 @@ static void cleartablekeys (GCObject *l) {
|
||||
static void cleartablevalues (GCObject *l) {
|
||||
while (l) {
|
||||
Table *h = gcotoh(l);
|
||||
int i = sizearray(h);
|
||||
int i = h->sizearray;
|
||||
lua_assert(h->marked & VALUEWEAK);
|
||||
while (i--) {
|
||||
TObject *o = &h->array[i];
|
||||
@@ -325,8 +328,8 @@ static void cleartablevalues (GCObject *l) {
|
||||
}
|
||||
i = sizenode(h);
|
||||
while (i--) {
|
||||
Node *n = node(h, i);
|
||||
if (!valismarked(val(n))) /* value was collected? */
|
||||
Node *n = gnode(h, i);
|
||||
if (!valismarked(gval(n))) /* value was collected? */
|
||||
removekey(n); /* remove entry from table */
|
||||
}
|
||||
l = h->gclist;
|
||||
@@ -409,7 +412,7 @@ static void do1gcTM (lua_State *L, Udata *udata) {
|
||||
}
|
||||
|
||||
|
||||
static void callGCTM (lua_State *L) {
|
||||
void luaC_callGCTM (lua_State *L) {
|
||||
lu_byte oldah = L->allowhook;
|
||||
L->allowhook = 0; /* stop debug hooks during GC tag methods */
|
||||
L->top++; /* reserve space to keep udata while runs its gc method */
|
||||
@@ -429,12 +432,6 @@ static void callGCTM (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
void luaC_callallgcTM (lua_State *L) {
|
||||
separateudata(L);
|
||||
callGCTM(L); /* call their GC tag methods */
|
||||
}
|
||||
|
||||
|
||||
void luaC_sweep (lua_State *L, int all) {
|
||||
if (all) all = 256; /* larger than any mark */
|
||||
sweeplist(L, &G(L)->rootudata, all);
|
||||
@@ -445,11 +442,11 @@ void luaC_sweep (lua_State *L, int all) {
|
||||
|
||||
/* mark root set */
|
||||
static void markroot (GCState *st, lua_State *L) {
|
||||
global_State *G = st->G;
|
||||
global_State *g = st->g;
|
||||
markobject(st, defaultmeta(L));
|
||||
markobject(st, registry(L));
|
||||
traversestack(st, G->mainthread);
|
||||
if (L != G->mainthread) /* another thread is running? */
|
||||
traversestack(st, g->mainthread);
|
||||
if (L != g->mainthread) /* another thread is running? */
|
||||
markvalue(st, L); /* cannot collect it */
|
||||
}
|
||||
|
||||
@@ -457,7 +454,7 @@ static void markroot (GCState *st, lua_State *L) {
|
||||
static void mark (lua_State *L) {
|
||||
GCState st;
|
||||
GCObject *wkv;
|
||||
st.G = G(L);
|
||||
st.g = G(L);
|
||||
st.tmark = NULL;
|
||||
st.wkv = st.wk = st.wv = NULL;
|
||||
markroot(&st, L);
|
||||
@@ -467,7 +464,7 @@ static void mark (lua_State *L) {
|
||||
wkv = st.wkv; /* keys must be cleared after preserving udata */
|
||||
st.wkv = NULL;
|
||||
st.wv = NULL;
|
||||
separateudata(L); /* separate userdata to be preserved */
|
||||
luaC_separateudata(L); /* separate userdata to be preserved */
|
||||
marktmu(&st); /* mark `preserved' userdata */
|
||||
propagatemarks(&st); /* remark, to propagate `preserveness' */
|
||||
cleartablekeys(wkv);
|
||||
@@ -483,7 +480,7 @@ void luaC_collectgarbage (lua_State *L) {
|
||||
mark(L);
|
||||
luaC_sweep(L, 0);
|
||||
checkSizes(L);
|
||||
callGCTM(L);
|
||||
luaC_callGCTM(L);
|
||||
}
|
||||
|
||||
|
||||
|
||||
9
lgc.h
9
lgc.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lgc.h,v 1.16 2002/08/30 19:09:21 roberto Exp roberto $
|
||||
** $Id: lgc.h,v 1.18 2003/02/10 17:32:50 roberto Exp roberto $
|
||||
** Garbage Collector
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -11,11 +11,12 @@
|
||||
#include "lobject.h"
|
||||
|
||||
|
||||
#define luaC_checkGC(L) if (G(L)->nblocks >= G(L)->GCthreshold) \
|
||||
luaC_collectgarbage(L)
|
||||
#define luaC_checkGC(L) { lua_assert(!(L->ci->state & CI_CALLING)); \
|
||||
if (G(L)->nblocks >= G(L)->GCthreshold) luaC_collectgarbage(L); }
|
||||
|
||||
|
||||
void luaC_callallgcTM (lua_State *L);
|
||||
void luaC_separateudata (lua_State *L);
|
||||
void luaC_callGCTM (lua_State *L);
|
||||
void luaC_sweep (lua_State *L, int all);
|
||||
void luaC_collectgarbage (lua_State *L);
|
||||
void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
|
||||
|
||||
109
liolib.c
109
liolib.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: liolib.c,v 2.27 2002/12/04 15:27:17 roberto Exp roberto $
|
||||
** $Id: liolib.c,v 2.38 2003/03/18 12:25:32 roberto Exp roberto $
|
||||
** Standard I/O (and system) library
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -21,6 +21,36 @@
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** by default, gcc does not get `tmpname'
|
||||
*/
|
||||
#ifndef USE_TMPNAME
|
||||
#ifdef __GNUC__
|
||||
#define USE_TMPNAME 0
|
||||
#else
|
||||
#define USE_TMPNAME 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** by default, posix systems get `popen'
|
||||
*/
|
||||
#ifndef USE_POPEN
|
||||
#ifdef _POSIX_C_SOURCE
|
||||
#if _POSIX_C_SOURCE >= 2
|
||||
#define USE_POPEN 1
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef USE_POPEN
|
||||
#define USE_POPEN 0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** FILE Operations
|
||||
@@ -28,12 +58,12 @@
|
||||
*/
|
||||
|
||||
|
||||
#ifndef USE_POPEN
|
||||
#if !USE_POPEN
|
||||
#define pclose(f) (-1)
|
||||
#endif
|
||||
|
||||
|
||||
#define FILEHANDLE "FileHandle"
|
||||
#define FILEHANDLE "FILE*"
|
||||
|
||||
#define IO_INPUT "_input"
|
||||
#define IO_OUTPUT "_output"
|
||||
@@ -57,21 +87,15 @@ static int pushresult (lua_State *L, int i, const char *filename) {
|
||||
|
||||
|
||||
static FILE **topfile (lua_State *L, int findex) {
|
||||
FILE **f = (FILE **)lua_touserdata(L, findex);
|
||||
if (f == NULL || !lua_getmetatable(L, findex) ||
|
||||
!lua_rawequal(L, -1, lua_upvalueindex(1))) {
|
||||
luaL_argerror(L, findex, "bad file");
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
FILE **f = (FILE **)luaL_checkudata(L, findex, FILEHANDLE);
|
||||
if (f == NULL) luaL_argerror(L, findex, "bad file");
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
static int io_type (lua_State *L) {
|
||||
FILE **f = (FILE **)lua_touserdata(L, 1);
|
||||
if (f == NULL || !lua_getmetatable(L, 1) ||
|
||||
!lua_rawequal(L, -1, lua_upvalueindex(1)))
|
||||
lua_pushnil(L);
|
||||
FILE **f = (FILE **)luaL_checkudata(L, 1, FILEHANDLE);
|
||||
if (f == NULL) lua_pushnil(L);
|
||||
else if (*f == NULL)
|
||||
lua_pushliteral(L, "closed file");
|
||||
else
|
||||
@@ -97,8 +121,7 @@ static FILE *tofile (lua_State *L, int findex) {
|
||||
static FILE **newfile (lua_State *L) {
|
||||
FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
|
||||
*pf = NULL; /* file handle is currently `closed' */
|
||||
lua_pushliteral(L, FILEHANDLE);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
luaL_getmetatable(L, FILEHANDLE);
|
||||
lua_setmetatable(L, -2);
|
||||
return pf;
|
||||
}
|
||||
@@ -173,7 +196,7 @@ static int io_open (lua_State *L) {
|
||||
|
||||
|
||||
static int io_popen (lua_State *L) {
|
||||
#ifndef USE_POPEN
|
||||
#if !USE_POPEN
|
||||
luaL_error(L, "`popen' not supported");
|
||||
return 0;
|
||||
#else
|
||||
@@ -201,12 +224,7 @@ static FILE *getiofile (lua_State *L, const char *name) {
|
||||
|
||||
|
||||
static int g_iofile (lua_State *L, const char *name, const char *mode) {
|
||||
if (lua_isnoneornil(L, 1)) {
|
||||
lua_pushstring(L, name);
|
||||
lua_rawget(L, lua_upvalueindex(1));
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
if (!lua_isnoneornil(L, 1)) {
|
||||
const char *filename = lua_tostring(L, 1);
|
||||
lua_pushstring(L, name);
|
||||
if (filename) {
|
||||
@@ -222,8 +240,11 @@ static int g_iofile (lua_State *L, const char *name, const char *mode) {
|
||||
lua_pushvalue(L, 1);
|
||||
}
|
||||
lua_rawset(L, lua_upvalueindex(1));
|
||||
return 0;
|
||||
}
|
||||
/* return current value */
|
||||
lua_pushstring(L, name);
|
||||
lua_rawget(L, lua_upvalueindex(1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -240,10 +261,10 @@ static int io_output (lua_State *L) {
|
||||
static int io_readline (lua_State *L);
|
||||
|
||||
|
||||
static void aux_lines (lua_State *L, int index, int close) {
|
||||
static void aux_lines (lua_State *L, int idx, int close) {
|
||||
lua_pushliteral(L, FILEHANDLE);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
lua_pushvalue(L, index);
|
||||
lua_pushvalue(L, idx);
|
||||
lua_pushboolean(L, close); /* close/not close file when finished */
|
||||
lua_pushcclosure(L, io_readline, 3);
|
||||
}
|
||||
@@ -356,8 +377,7 @@ static int g_read (lua_State *L, FILE *f, int first) {
|
||||
}
|
||||
else {
|
||||
const char *p = lua_tostring(L, n);
|
||||
if (!p || p[0] != '*')
|
||||
return luaL_error(L, "invalid `read' option");
|
||||
luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
|
||||
switch (p[1]) {
|
||||
case 'n': /* number */
|
||||
success = read_number(L, f);
|
||||
@@ -370,7 +390,7 @@ static int g_read (lua_State *L, FILE *f, int first) {
|
||||
success = 1; /* always success */
|
||||
break;
|
||||
case 'w': /* word */
|
||||
return luaL_error(L, "obsolete option `*w'");
|
||||
return luaL_error(L, "obsolete option `*w' to `read'");
|
||||
default:
|
||||
return luaL_argerror(L, n, "invalid format");
|
||||
}
|
||||
@@ -492,29 +512,19 @@ static const luaL_reg flib[] = {
|
||||
{"seek", f_seek},
|
||||
{"write", f_write},
|
||||
{"close", io_close},
|
||||
{"__gc", io_gc},
|
||||
{"__tostring", io_tostring},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
static void createmeta (lua_State *L) {
|
||||
lua_pushliteral(L, FILEHANDLE);
|
||||
lua_newtable(L); /* push new metatable for file handles */
|
||||
/* close files when collected */
|
||||
lua_pushliteral(L, "__gc");
|
||||
lua_pushvalue(L, -2); /* push metatable (will be upvalue for `gc' method) */
|
||||
lua_pushcclosure(L, io_gc, 1);
|
||||
lua_rawset(L, -3); /* metatable.__gc = io_gc */
|
||||
lua_pushliteral(L, "__tostring");
|
||||
lua_pushvalue(L, -2); /* push metatable */
|
||||
lua_pushcclosure(L, io_tostring, 1);
|
||||
lua_rawset(L, -3);
|
||||
luaL_newmetatable(L, FILEHANDLE); /* create new metatable for file handles */
|
||||
/* file methods */
|
||||
lua_pushliteral(L, "__index");
|
||||
lua_pushvalue(L, -2); /* push metatable */
|
||||
lua_rawset(L, -3); /* metatable.__index = metatable */
|
||||
lua_pushvalue(L, -1); /* push metatable (will be upvalue for library) */
|
||||
luaL_openlib(L, NULL, flib, 1);
|
||||
lua_rawset(L, LUA_REGISTRYINDEX); /* registry.FILEHANDLE = metatable */
|
||||
luaL_openlib(L, NULL, flib, 0);
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
@@ -546,11 +556,16 @@ 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");
|
||||
return luaL_error(L, "unable to generate a unique filename in `tmpname'");
|
||||
lua_pushstring(L, buff);
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -721,17 +736,15 @@ static const luaL_reg syslib[] = {
|
||||
|
||||
|
||||
|
||||
LUALIB_API int lua_iolibopen (lua_State *L) {
|
||||
createmeta(L);
|
||||
LUALIB_API int luaopen_io (lua_State *L) {
|
||||
luaL_openlib(L, LUA_OSLIBNAME, syslib, 0);
|
||||
lua_pushliteral(L, FILEHANDLE);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
createmeta(L);
|
||||
lua_pushvalue(L, -1);
|
||||
luaL_openlib(L, LUA_IOLIBNAME, iolib, 1);
|
||||
/* put predefined file handles into `io' table */
|
||||
registerfile(L, stdin, "stdin", IO_INPUT);
|
||||
registerfile(L, stdout, "stdout", IO_OUTPUT);
|
||||
registerfile(L, stderr, "stderr", NULL);
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
13
llex.c
13
llex.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: llex.c,v 1.116 2002/10/23 19:08:13 roberto Exp roberto $
|
||||
** $Id: llex.c,v 1.118 2003/02/28 17:19:47 roberto Exp roberto $
|
||||
** Lexical Analyzer
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -59,15 +59,20 @@ void luaX_checklimit (LexState *ls, int val, int limit, const char *msg) {
|
||||
}
|
||||
|
||||
|
||||
static void luaX_error (LexState *ls, const char *s, const char *token) {
|
||||
void luaX_errorline (LexState *ls, const char *s, const char *token, int line) {
|
||||
lua_State *L = ls->L;
|
||||
char buff[MAXSRC];
|
||||
luaO_chunkid(buff, getstr(ls->source), MAXSRC);
|
||||
luaO_pushfstring(L, "%s:%d: %s near `%s'", buff, ls->linenumber, s, token);
|
||||
luaO_pushfstring(L, "%s:%d: %s near `%s'", buff, line, s, token);
|
||||
luaD_throw(L, LUA_ERRSYNTAX);
|
||||
}
|
||||
|
||||
|
||||
static void luaX_error (LexState *ls, const char *s, const char *token) {
|
||||
luaX_errorline(ls, s, token, ls->linenumber);
|
||||
}
|
||||
|
||||
|
||||
void luaX_syntaxerror (LexState *ls, const char *msg) {
|
||||
const char *lasttoken;
|
||||
switch (ls->t.token) {
|
||||
@@ -88,7 +93,7 @@ void luaX_syntaxerror (LexState *ls, const char *msg) {
|
||||
|
||||
const char *luaX_token2str (LexState *ls, int token) {
|
||||
if (token < FIRST_RESERVED) {
|
||||
lua_assert(token == (char)token);
|
||||
lua_assert(token == (unsigned char)token);
|
||||
return luaO_pushfstring(ls->L, "%c", token);
|
||||
}
|
||||
else
|
||||
|
||||
3
llex.h
3
llex.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: llex.h,v 1.45 2002/10/08 18:46:08 roberto Exp roberto $
|
||||
** $Id: llex.h,v 1.46 2002/11/22 16:35:20 roberto Exp roberto $
|
||||
** Lexical Analyzer
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -68,6 +68,7 @@ void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source);
|
||||
int luaX_lex (LexState *LS, SemInfo *seminfo);
|
||||
void luaX_checklimit (LexState *ls, int val, int limit, const char *msg);
|
||||
void luaX_syntaxerror (LexState *ls, const char *s);
|
||||
void luaX_errorline (LexState *ls, const char *s, const char *token, int line);
|
||||
const char *luaX_token2str (LexState *ls, int token);
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: llimits.h,v 1.50 2002/11/22 18:01:46 roberto Exp roberto $
|
||||
** $Id: llimits.h,v 1.51 2002/11/25 17:47:13 roberto Exp roberto $
|
||||
** Limits, basic types, and some other `installation-dependent' definitions
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -49,6 +49,9 @@ typedef int ls_hash;
|
||||
/* it should be at least as large as size_t */
|
||||
typedef unsigned long lu_mem;
|
||||
|
||||
#define MAX_LUMEM ULONG_MAX
|
||||
|
||||
|
||||
/* an integer big enough to count the number of strings in use */
|
||||
typedef long ls_nstr;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lmathlib.c,v 1.52 2002/11/14 15:41:38 roberto Exp roberto $
|
||||
** $Id: lmathlib.c,v 1.55 2003/03/11 12:24:34 roberto Exp roberto $
|
||||
** Standard mathematical library
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -233,14 +233,14 @@ static const luaL_reg mathlib[] = {
|
||||
/*
|
||||
** Open math library
|
||||
*/
|
||||
LUALIB_API int lua_mathlibopen (lua_State *L) {
|
||||
LUALIB_API int luaopen_math (lua_State *L) {
|
||||
luaL_openlib(L, LUA_MATHLIBNAME, mathlib, 0);
|
||||
lua_pushliteral(L, "pi");
|
||||
lua_pushnumber(L, PI);
|
||||
lua_settable(L, -3);
|
||||
lua_pushliteral(L, "__pow");
|
||||
lua_pushcfunction(L, math_pow);
|
||||
lua_settable(L, LUA_REGISTRYINDEX);
|
||||
return 0;
|
||||
lua_settable(L, LUA_GLOBALSINDEX);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
205
loadlib.c
Normal file
205
loadlib.c
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
** $Id: loadlib.c,v 1.3 2003/04/02 13:09:14 roberto Exp roberto $
|
||||
** Dynamic library loader for Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*
|
||||
* This Lua library exports a single function, called loadlib, which is
|
||||
* called from Lua as loadlib(lib,init), where lib is the full name of the
|
||||
* library to be loaded (including the complete path) and init is the name
|
||||
* of a function to be called after the library is loaded. Typically, this
|
||||
* function will register other functions, thus making the complete library
|
||||
* available to Lua. The init function is *not* automatically called by
|
||||
* loadlib. Instead, loadlib returns the init function as a Lua function
|
||||
* that the client can call when it thinks is appropriate. In the case of
|
||||
* errors, loadlib returns nil and two strings describing the error.
|
||||
* The first string is supplied by the operating system; it should be
|
||||
* informative and useful for error messages. The second string is "open",
|
||||
* "init", or "absent" to identify the error and is meant to be used for
|
||||
* making decisions without having to look into the first string (whose
|
||||
* format is system-dependent).
|
||||
*
|
||||
* This module contains an implementation of loadlib for Unix systems that
|
||||
* have dlfcn, an implementation for Windows, and a stub for other systems.
|
||||
* See the list at the end of this file for some links to available
|
||||
* implementations of dlfcn and interfaces to other native dynamic loaders
|
||||
* on top of which loadlib could be implemented.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
|
||||
|
||||
#undef LOADLIB
|
||||
|
||||
|
||||
#ifdef USE_DLOPEN
|
||||
#define LOADLIB
|
||||
/*
|
||||
* This is an implementation of loadlib based on the dlfcn interface.
|
||||
* The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
|
||||
* NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
|
||||
* as an emulation layer on top of native functions.
|
||||
*/
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
static int loadlib(lua_State *L)
|
||||
{
|
||||
const char *path=luaL_checkstring(L,1);
|
||||
const char *init=luaL_checkstring(L,2);
|
||||
void *lib=dlopen(path,RTLD_NOW);
|
||||
if (lib!=NULL)
|
||||
{
|
||||
lua_CFunction f=(lua_CFunction) dlsym(lib,init);
|
||||
if (f!=NULL)
|
||||
{
|
||||
lua_pushlightuserdata(L,lib);
|
||||
lua_pushcclosure(L,f,1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/* else return appropriate error messages */
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L,dlerror());
|
||||
lua_pushstring(L,(lib!=NULL) ? "init" : "open");
|
||||
if (lib!=NULL) dlclose(lib);
|
||||
return 3;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** In Windows, default is to use dll; otherwise, default is not to use dll
|
||||
*/
|
||||
#ifndef USE_DLL
|
||||
#ifdef _WIN32
|
||||
#define USE_DLL 1
|
||||
#else
|
||||
#define USE_DLL 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if USE_DLL
|
||||
#define LOADLIB
|
||||
/*
|
||||
* This is an implementation of loadlib for Windows using native functions.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
static void pusherror(lua_State *L)
|
||||
{
|
||||
int error=GetLastError();
|
||||
char buffer[128];
|
||||
if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
0, error, 0, buffer, sizeof(buffer), 0))
|
||||
lua_pushstring(L,buffer);
|
||||
else
|
||||
lua_pushfstring(L,"system error %d\n",error);
|
||||
}
|
||||
|
||||
static int loadlib(lua_State *L)
|
||||
{
|
||||
const char *path=luaL_checkstring(L,1);
|
||||
const char *init=luaL_checkstring(L,2);
|
||||
HINSTANCE lib=LoadLibrary(path);
|
||||
if (lib!=NULL)
|
||||
{
|
||||
lua_CFunction f=(lua_CFunction) GetProcAddress(lib,init);
|
||||
if (f!=NULL)
|
||||
{
|
||||
lua_pushlightuserdata(L,lib);
|
||||
lua_pushcclosure(L,f,1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
lua_pushnil(L);
|
||||
pusherror(L);
|
||||
lua_pushstring(L,(lib!=NULL) ? "init" : "open");
|
||||
if (lib!=NULL) FreeLibrary(lib);
|
||||
return 3;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifndef LOADLIB
|
||||
/* Fallback for other systems */
|
||||
|
||||
/*
|
||||
** Those systems support dlopen, so they should have defined USE_DLOPEN.
|
||||
** The default (no)implementation gives them a special error message.
|
||||
*/
|
||||
#ifdef linux
|
||||
#define LOADLIB
|
||||
#endif
|
||||
|
||||
#ifdef sun
|
||||
#define LOADLIB
|
||||
#endif
|
||||
|
||||
#ifdef sgi
|
||||
#define LOADLIB
|
||||
#endif
|
||||
|
||||
#ifdef BSD
|
||||
#define LOADLIB
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define LOADLIB
|
||||
#endif
|
||||
|
||||
#ifdef LOADLIB
|
||||
#undef LOADLIB
|
||||
#define LOADLIB "`loadlib' not installed (check your Lua configuration)"
|
||||
#else
|
||||
#define LOADLIB "`loadlib' not supported"
|
||||
#endif
|
||||
|
||||
static int loadlib(lua_State *L)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
lua_pushliteral(L,LOADLIB);
|
||||
lua_pushliteral(L,"absent");
|
||||
return 3;
|
||||
}
|
||||
#endif
|
||||
|
||||
LUALIB_API int luaopen_loadlib (lua_State *L)
|
||||
{
|
||||
lua_register(L,"loadlib",loadlib);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Here are some links to available implementations of dlfcn and
|
||||
* interfaces to other native dynamic loaders on top of which loadlib
|
||||
* could be implemented. Please send contributions and corrections to us.
|
||||
*
|
||||
* AIX
|
||||
* Starting with AIX 4.2, dlfcn is included in the base OS.
|
||||
* There is also an emulation package available.
|
||||
* http://www.faqs.org/faqs/aix-faq/part4/section-21.html
|
||||
*
|
||||
* HPUX
|
||||
* HPUX 11 has dlfcn. For HPUX 10 use shl_*.
|
||||
* http://www.geda.seul.org/mailinglist/geda-dev37/msg00094.html
|
||||
* http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html
|
||||
*
|
||||
* Macintosh, Windows
|
||||
* http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html
|
||||
*
|
||||
* Mac OS X/Darwin
|
||||
* http://www.opendarwin.org/projects/dlcompat/
|
||||
*
|
||||
* GLIB has wrapper code for BeOS, OS2, Unix and Windows
|
||||
* http://cvs.gnome.org/lxr/source/glib/gmodule/
|
||||
*
|
||||
*/
|
||||
30
lobject.c
30
lobject.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lobject.c,v 1.93 2002/11/21 15:16:04 roberto Exp roberto $
|
||||
** $Id: lobject.c,v 1.96 2003/02/18 16:02:56 roberto Exp roberto $
|
||||
** Some generic functions over Lua objects
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -30,6 +30,20 @@
|
||||
const TObject luaO_nilobject = {LUA_TNIL, {NULL}};
|
||||
|
||||
|
||||
/*
|
||||
** converts an integer to a "floating point byte", represented as
|
||||
** (mmmmmxxx), where the real value is (xxx) * 2^(mmmmm)
|
||||
*/
|
||||
int luaO_int2fb (unsigned int x) {
|
||||
int m = 0; /* mantissa */
|
||||
while (x >= (1<<3)) {
|
||||
x = (x+1) >> 1;
|
||||
m++;
|
||||
}
|
||||
return (m << 3) | cast(int, x);
|
||||
}
|
||||
|
||||
|
||||
int luaO_log2 (unsigned int x) {
|
||||
static const lu_byte log_8[255] = {
|
||||
0,
|
||||
@@ -59,19 +73,19 @@ int luaO_log2 (unsigned int x) {
|
||||
|
||||
int luaO_rawequalObj (const TObject *t1, const TObject *t2) {
|
||||
if (ttype(t1) != ttype(t2)) return 0;
|
||||
if (iscollectable(t1)) return gcvalue(t1) == gcvalue(t2);
|
||||
else switch (ttype(t1)) {
|
||||
case LUA_TNIL:
|
||||
return 1;
|
||||
case LUA_TNUMBER:
|
||||
return nvalue(t1) == nvalue(t2);
|
||||
case LUA_TBOOLEAN:
|
||||
return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
|
||||
case LUA_TLIGHTUSERDATA:
|
||||
return pvalue(t1) == pvalue(t2);
|
||||
case LUA_TNUMBER:
|
||||
return nvalue(t1) == nvalue(t2);
|
||||
default:
|
||||
lua_assert(iscollectable(t1));
|
||||
return gcvalue(t1) == gcvalue(t2);
|
||||
}
|
||||
lua_assert(0);
|
||||
return 0; /* to avoid warnings */
|
||||
}
|
||||
|
||||
|
||||
@@ -114,11 +128,11 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
|
||||
break;
|
||||
}
|
||||
case 'd':
|
||||
setnvalue(L->top, va_arg(argp, int));
|
||||
setnvalue(L->top, cast(lua_Number, va_arg(argp, int)));
|
||||
incr_top(L);
|
||||
break;
|
||||
case 'f':
|
||||
setnvalue(L->top, va_arg(argp, l_uacNumber));
|
||||
setnvalue(L->top, cast(lua_Number, va_arg(argp, l_uacNumber)));
|
||||
incr_top(L);
|
||||
break;
|
||||
case '%':
|
||||
|
||||
10
lobject.h
10
lobject.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lobject.h,v 1.154 2002/11/14 11:51:50 roberto Exp roberto $
|
||||
** $Id: lobject.h,v 1.158 2003/02/18 16:02:56 roberto Exp roberto $
|
||||
** Type definitions for Lua objects
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -214,7 +214,9 @@ typedef struct Proto {
|
||||
struct Proto **p; /* functions defined inside the function */
|
||||
int *lineinfo; /* map from opcodes to source lines */
|
||||
struct LocVar *locvars; /* information about local variables */
|
||||
TString **upvalues; /* upvalue names */
|
||||
TString *source;
|
||||
int sizeupvalues;
|
||||
int sizek; /* size of `k' */
|
||||
int sizecode;
|
||||
int sizelineinfo;
|
||||
@@ -222,7 +224,7 @@ typedef struct Proto {
|
||||
int sizelocvars;
|
||||
int lineDefined;
|
||||
GCObject *gclist;
|
||||
lu_byte nupvalues;
|
||||
lu_byte nups; /* number of upvalues */
|
||||
lu_byte numparams;
|
||||
lu_byte is_vararg;
|
||||
lu_byte maxstacksize;
|
||||
@@ -314,14 +316,14 @@ typedef struct Table {
|
||||
|
||||
#define twoto(x) (1<<(x))
|
||||
#define sizenode(t) (twoto((t)->lsizenode))
|
||||
#define sizearray(t) ((t)->sizearray)
|
||||
|
||||
|
||||
|
||||
extern const TObject luaO_nilobject;
|
||||
|
||||
int luaO_log2 (unsigned int x);
|
||||
|
||||
int luaO_int2fb (unsigned int x);
|
||||
#define fb2int(x) (((x) & 7) << ((x) >> 3))
|
||||
|
||||
int luaO_rawequalObj (const TObject *t1, const TObject *t2);
|
||||
int luaO_str2d (const char *s, lua_Number *result);
|
||||
|
||||
52
lparser.c
52
lparser.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lparser.c,v 1.201 2002/12/06 17:09:00 roberto Exp roberto $
|
||||
** $Id: lparser.c,v 1.207 2003/02/28 17:19:47 roberto Exp roberto $
|
||||
** Lua Parser
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -179,16 +179,22 @@ static void create_local (LexState *ls, const char *name) {
|
||||
}
|
||||
|
||||
|
||||
static int indexupvalue (FuncState *fs, expdesc *v) {
|
||||
static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
|
||||
int i;
|
||||
for (i=0; i<fs->f->nupvalues; i++) {
|
||||
if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->info)
|
||||
Proto *f = fs->f;
|
||||
for (i=0; i<f->nups; i++) {
|
||||
if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->info) {
|
||||
lua_assert(fs->f->upvalues[i] == name);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
/* new one */
|
||||
luaX_checklimit(fs->ls, fs->f->nupvalues+1, MAXUPVALUES, "upvalues");
|
||||
fs->upvalues[fs->f->nupvalues] = *v;
|
||||
return fs->f->nupvalues++;
|
||||
luaX_checklimit(fs->ls, f->nups + 1, MAXUPVALUES, "upvalues");
|
||||
luaM_growvector(fs->L, fs->f->upvalues, f->nups, fs->f->sizeupvalues,
|
||||
TString *, MAX_INT, "");
|
||||
fs->f->upvalues[f->nups] = name;
|
||||
fs->upvalues[f->nups] = *v;
|
||||
return f->nups++;
|
||||
}
|
||||
|
||||
|
||||
@@ -226,7 +232,7 @@ static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
|
||||
var->info = luaK_stringK(fs, n); /* info points to global name */
|
||||
}
|
||||
else { /* LOCAL or UPVAL */
|
||||
var->info = indexupvalue(fs, var);
|
||||
var->info = indexupvalue(fs, n, var);
|
||||
var->k = VUPVAL; /* upvalue in this level */
|
||||
}
|
||||
}
|
||||
@@ -234,8 +240,10 @@ static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
|
||||
}
|
||||
|
||||
|
||||
static void singlevar (LexState *ls, expdesc *var, int base) {
|
||||
singlevaraux(ls->fs, str_checkname(ls), var, base);
|
||||
static TString *singlevar (LexState *ls, expdesc *var, int base) {
|
||||
TString *varname = str_checkname(ls);
|
||||
singlevaraux(ls->fs, varname, var, base);
|
||||
return varname;
|
||||
}
|
||||
|
||||
|
||||
@@ -302,7 +310,7 @@ static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
|
||||
MAXARG_Bx, "constant table overflow");
|
||||
f->p[fs->np++] = func->f;
|
||||
init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
|
||||
for (i=0; i<func->f->nupvalues; i++) {
|
||||
for (i=0; i<func->f->nups; i++) {
|
||||
OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
|
||||
luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0);
|
||||
}
|
||||
@@ -326,11 +334,8 @@ static void open_func (LexState *ls, FuncState *fs) {
|
||||
fs->nlocvars = 0;
|
||||
fs->nactvar = 0;
|
||||
fs->bl = NULL;
|
||||
f->code = NULL;
|
||||
f->source = ls->source;
|
||||
f->maxstacksize = 2; /* registers 0/1 are always valid */
|
||||
f->numparams = 0; /* default for main chunk */
|
||||
f->is_vararg = 0; /* default for main chunk */
|
||||
}
|
||||
|
||||
|
||||
@@ -350,6 +355,8 @@ static void close_func (LexState *ls) {
|
||||
f->sizep = fs->np;
|
||||
luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
|
||||
f->sizelocvars = fs->nlocvars;
|
||||
luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *);
|
||||
f->sizeupvalues = f->nups;
|
||||
lua_assert(luaG_checkcode(f));
|
||||
lua_assert(fs->bl == NULL);
|
||||
ls->fs = fs->prev;
|
||||
@@ -368,7 +375,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff) {
|
||||
check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected");
|
||||
close_func(&lexstate);
|
||||
lua_assert(funcstate.prev == NULL);
|
||||
lua_assert(funcstate.f->nupvalues == 0);
|
||||
lua_assert(funcstate.f->nups == 0);
|
||||
lua_assert(lexstate.nestlevel == 0);
|
||||
return funcstate.f;
|
||||
}
|
||||
@@ -510,8 +517,7 @@ static void constructor (LexState *ls, expdesc *t) {
|
||||
} while (testnext(ls, ',') || testnext(ls, ';'));
|
||||
check_match(ls, '}', '{', line);
|
||||
lastlistfield(fs, &cc);
|
||||
if (cc.na > 0)
|
||||
SETARG_B(fs->f->code[pc], luaO_log2(cc.na-1)+2); /* set initial table size */
|
||||
SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
|
||||
SETARG_C(fs->f->code[pc], luaO_log2(cc.nh)+1); /* set initial table size */
|
||||
}
|
||||
|
||||
@@ -639,12 +645,18 @@ static void prefixexp (LexState *ls, expdesc *v) {
|
||||
singlevar(ls, v, 1);
|
||||
return;
|
||||
}
|
||||
#ifdef LUA_COMPATUPSYNTAX
|
||||
case '%': { /* for compatibility only */
|
||||
TString *varname;
|
||||
int line = ls->linenumber;
|
||||
next(ls); /* skip `%' */
|
||||
singlevar(ls, v, 1);
|
||||
check_condition(ls, v->k == VUPVAL, "global upvalues are obsolete");
|
||||
varname = singlevar(ls, v, 1);
|
||||
if (v->k != VUPVAL)
|
||||
luaX_errorline(ls, "global upvalues are obsolete",
|
||||
getstr(varname), line);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
luaX_syntaxerror(ls, "unexpected symbol");
|
||||
return;
|
||||
@@ -949,7 +961,7 @@ static void cond (LexState *ls, expdesc *v) {
|
||||
static void whilestat (LexState *ls, int line) {
|
||||
/* whilestat -> WHILE cond DO block END */
|
||||
Instruction codeexp[MAXEXPWHILE + EXTRAEXP];
|
||||
int lineexp = 0;
|
||||
int lineexp;
|
||||
int i;
|
||||
int sizeexp;
|
||||
FuncState *fs = ls->fs;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lparser.h,v 1.44 2002/05/14 17:52:22 roberto Exp roberto $
|
||||
** $Id: lparser.h,v 1.46 2002/12/19 11:11:55 roberto Exp roberto $
|
||||
** Lua Parser
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
29
lstate.c
29
lstate.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lstate.c,v 1.116 2002/11/22 17:16:52 roberto Exp roberto $
|
||||
** $Id: lstate.c,v 1.122 2003/03/18 12:50:04 roberto Exp roberto $
|
||||
** Global State
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -100,21 +100,21 @@ static void f_luaopen (lua_State *L, void *ud) {
|
||||
setnilvalue(defaultmeta(L));
|
||||
setnilvalue(registry(L));
|
||||
luaZ_initbuffer(L, &g->buff);
|
||||
g->panic = &default_panic;
|
||||
g->panic = default_panic;
|
||||
g->rootgc = NULL;
|
||||
g->rootudata = NULL;
|
||||
g->tmudata = NULL;
|
||||
setnilvalue(key(g->dummynode));
|
||||
setnilvalue(val(g->dummynode));
|
||||
setnilvalue(gkey(g->dummynode));
|
||||
setnilvalue(gval(g->dummynode));
|
||||
g->dummynode->next = NULL;
|
||||
g->nblocks = sizeof(lua_State) + sizeof(global_State);
|
||||
stack_init(L, L); /* init stack */
|
||||
/* create default meta table with a dummy table, and then close the loop */
|
||||
defaultmeta(L)->tt = LUA_TTABLE;
|
||||
sethvalue(defaultmeta(L), luaH_new(L, 0, 4));
|
||||
sethvalue(defaultmeta(L), luaH_new(L, 0, 0));
|
||||
hvalue(defaultmeta(L))->metatable = hvalue(defaultmeta(L));
|
||||
sethvalue(gt(L), luaH_new(L, 0, 4)); /* table of globals */
|
||||
sethvalue(registry(L), luaH_new(L, 0, 0)); /* registry */
|
||||
sethvalue(registry(L), luaH_new(L, 4, 4)); /* registry */
|
||||
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
|
||||
luaT_init(L);
|
||||
luaX_init(L);
|
||||
@@ -182,6 +182,8 @@ LUA_API lua_State *lua_open (void) {
|
||||
lua_State *L = mallocstate(NULL);
|
||||
if (L) { /* allocation OK? */
|
||||
L->tt = LUA_TTHREAD;
|
||||
L->marked = 0;
|
||||
L->next = L->gclist = NULL;
|
||||
preinit_state(L);
|
||||
L->l_G = NULL;
|
||||
if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
|
||||
@@ -195,10 +197,23 @@ LUA_API lua_State *lua_open (void) {
|
||||
}
|
||||
|
||||
|
||||
static void callallgcTM (lua_State *L, void *ud) {
|
||||
UNUSED(ud);
|
||||
luaC_callGCTM(L); /* call GC metamethods for all udata */
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_close (lua_State *L) {
|
||||
lua_lock(L);
|
||||
L = G(L)->mainthread; /* only the main thread can be closed */
|
||||
luaC_callallgcTM(L); /* call GC tag methods for all udata */
|
||||
luaF_close(L, L->stack); /* close all upvalues for this thread */
|
||||
luaC_separateudata(L); /* separate udata that have GC metamethods */
|
||||
L->errfunc = 0; /* no error function during GC metamethods */
|
||||
do { /* repeat until no more errors */
|
||||
L->ci = L->base_ci;
|
||||
L->base = L->top = L->ci->base;
|
||||
L->nCcalls = 0;
|
||||
} while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
|
||||
lua_assert(G(L)->tmudata == NULL);
|
||||
close_state(L);
|
||||
}
|
||||
|
||||
3
lstate.h
3
lstate.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lstate.h,v 1.107 2002/11/22 18:01:46 roberto Exp roberto $
|
||||
** $Id: lstate.h,v 1.108 2002/11/25 17:47:13 roberto Exp roberto $
|
||||
** Global State
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -80,6 +80,7 @@ typedef struct CallInfo {
|
||||
struct { /* for Lua functions */
|
||||
const Instruction *savedpc;
|
||||
const Instruction **pc; /* points to `pc' variable in `luaV_execute' */
|
||||
int tailcalls; /* number of tail calls lost under this entry */
|
||||
} l;
|
||||
struct { /* for C functions */
|
||||
int dummy; /* just to avoid an empty struct */
|
||||
|
||||
34
lstrlib.c
34
lstrlib.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lstrlib.c,v 1.91 2002/11/25 17:33:33 roberto Exp roberto $
|
||||
** $Id: lstrlib.c,v 1.97 2003/03/19 21:16:12 roberto Exp roberto $
|
||||
** Standard library for string operations and pattern-matching
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -31,7 +31,7 @@ typedef long sint32; /* a signed version for size_t */
|
||||
static int str_len (lua_State *L) {
|
||||
size_t l;
|
||||
luaL_checklstring(L, 1, &l);
|
||||
lua_pushnumber(L, l);
|
||||
lua_pushnumber(L, (lua_Number)l);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ static int str_sub (lua_State *L) {
|
||||
sint32 start = posrelat(luaL_checklong(L, 2), l);
|
||||
sint32 end = posrelat(luaL_optlong(L, 3, -1), l);
|
||||
if (start < 1) start = 1;
|
||||
if (end > (sint32)l) end = l;
|
||||
if (end > (sint32)l) end = (sint32)l;
|
||||
if (start <= end)
|
||||
lua_pushlstring(L, s+start-1, end-start+1);
|
||||
else lua_pushliteral(L, "");
|
||||
@@ -98,7 +98,8 @@ static int str_byte (lua_State *L) {
|
||||
size_t l;
|
||||
const char *s = luaL_checklstring(L, 1, &l);
|
||||
sint32 pos = posrelat(luaL_optlong(L, 2, 1), l);
|
||||
luaL_argcheck(L, 0 < pos && (size_t)(pos) <= l, 2, "out of range");
|
||||
if (pos <= 0 || (size_t)(pos) > l) /* index out of range? */
|
||||
return 0; /* no answer */
|
||||
lua_pushnumber(L, uchar(s[pos-1]));
|
||||
return 1;
|
||||
}
|
||||
@@ -451,7 +452,7 @@ static void push_onecapture (MatchState *ms, int i) {
|
||||
int l = ms->capture[i].len;
|
||||
if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
|
||||
if (l == CAP_POSITION)
|
||||
lua_pushnumber(ms->L, ms->capture[i].init - ms->src_init + 1);
|
||||
lua_pushnumber(ms->L, (lua_Number)(ms->capture[i].init - ms->src_init + 1));
|
||||
else
|
||||
lua_pushlstring(ms->L, ms->capture[i].init, l);
|
||||
}
|
||||
@@ -477,14 +478,15 @@ static int str_find (lua_State *L) {
|
||||
const char *s = luaL_checklstring(L, 1, &l1);
|
||||
const char *p = luaL_checklstring(L, 2, &l2);
|
||||
sint32 init = posrelat(luaL_optlong(L, 3, 1), l1) - 1;
|
||||
luaL_argcheck(L, 0 <= init && (size_t)(init) <= l1, 3, "out of range");
|
||||
if (init < 0) init = 0;
|
||||
else if ((size_t)(init) > l1) init = (sint32)l1;
|
||||
if (lua_toboolean(L, 4) || /* explicit request? */
|
||||
strpbrk(p, SPECIALS) == NULL) { /* or no special characters? */
|
||||
/* do a plain search */
|
||||
const char *s2 = lmemfind(s+init, l1-init, p, l2);
|
||||
if (s2) {
|
||||
lua_pushnumber(L, s2-s+1);
|
||||
lua_pushnumber(L, s2-s+l2);
|
||||
lua_pushnumber(L, (lua_Number)(s2-s+1));
|
||||
lua_pushnumber(L, (lua_Number)(s2-s+l2));
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
@@ -499,8 +501,8 @@ static int str_find (lua_State *L) {
|
||||
const char *res;
|
||||
ms.level = 0;
|
||||
if ((res=match(&ms, s1, p)) != NULL) {
|
||||
lua_pushnumber(L, s1-s+1); /* start */
|
||||
lua_pushnumber(L, res-s); /* end */
|
||||
lua_pushnumber(L, (lua_Number)(s1-s+1)); /* start */
|
||||
lua_pushnumber(L, (lua_Number)(res-s)); /* end */
|
||||
return push_captures(&ms, NULL, 0) + 2;
|
||||
}
|
||||
} while (s1++<ms.src_end && !anchor);
|
||||
@@ -527,7 +529,7 @@ static int gfind_aux (lua_State *L) {
|
||||
if ((e = match(&ms, src, p)) != NULL) {
|
||||
int newstart = e-s;
|
||||
if (e == src) newstart++; /* empty match? go at least one position */
|
||||
lua_pushnumber(L, newstart);
|
||||
lua_pushnumber(L, (lua_Number)newstart);
|
||||
lua_replace(L, lua_upvalueindex(3));
|
||||
return push_captures(&ms, src, e);
|
||||
}
|
||||
@@ -614,7 +616,7 @@ static int str_gsub (lua_State *L) {
|
||||
}
|
||||
luaL_addlstring(&b, src, ms.src_end-src);
|
||||
luaL_pushresult(&b);
|
||||
lua_pushnumber(L, n); /* number of substitutions */
|
||||
lua_pushnumber(L, (lua_Number)n); /* number of substitutions */
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -693,7 +695,7 @@ static int str_format (lua_State *L) {
|
||||
char buff[MAX_ITEM]; /* to store the formatted item */
|
||||
int hasprecision = 0;
|
||||
if (isdigit(uchar(*strfrmt)) && *(strfrmt+1) == '$')
|
||||
return luaL_error(L, "obsolete `format' option (d$)");
|
||||
return luaL_error(L, "obsolete option (d$) to `format'");
|
||||
arg++;
|
||||
strfrmt = scanformat(L, strfrmt, form, &hasprecision);
|
||||
switch (*strfrmt++) {
|
||||
@@ -730,7 +732,7 @@ static int str_format (lua_State *L) {
|
||||
}
|
||||
}
|
||||
default: { /* also treat cases `pnLlh' */
|
||||
return luaL_error(L, "invalid option in `format'");
|
||||
return luaL_error(L, "invalid option to `format'");
|
||||
}
|
||||
}
|
||||
luaL_addlstring(&b, buff, strlen(buff));
|
||||
@@ -761,8 +763,8 @@ static const luaL_reg strlib[] = {
|
||||
/*
|
||||
** Open string library
|
||||
*/
|
||||
LUALIB_API int lua_strlibopen (lua_State *L) {
|
||||
LUALIB_API int luaopen_string (lua_State *L) {
|
||||
luaL_openlib(L, LUA_STRLIBNAME, strlib, 0);
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
143
ltable.c
143
ltable.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltable.c,v 1.125 2002/12/02 12:06:10 roberto Exp roberto $
|
||||
** $Id: ltable.c,v 1.131 2003/03/24 14:18:42 roberto Exp roberto $
|
||||
** Lua tables (hash)
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -21,6 +21,7 @@
|
||||
** performance penalties.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define ltable_c
|
||||
|
||||
@@ -54,17 +55,41 @@
|
||||
#endif
|
||||
|
||||
|
||||
#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
|
||||
|
||||
#define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
|
||||
#define hashboolean(t,p) hashpow2(t, p)
|
||||
|
||||
#define hashnum(t,n) \
|
||||
(node(t, lmod(cast(lu_hash, cast(ls_hash, n)), sizenode(t))))
|
||||
#define hashstr(t,str) (node(t, lmod((str)->tsv.hash, sizenode(t))))
|
||||
#define hashboolean(t,p) (node(t, lmod(p, sizenode(t))))
|
||||
|
||||
/*
|
||||
** avoid modulus by power of 2 for pointers, as they tend to have many
|
||||
** 2 factors.
|
||||
** for some types, it is better to avoid modulus by power of 2, as
|
||||
** they tend to have many 2 factors.
|
||||
*/
|
||||
#define hashpointer(t,p) (node(t, (IntPoint(p) % ((sizenode(t)-1)|1))))
|
||||
#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
|
||||
|
||||
|
||||
#define hashpointer(t,p) hashmod(t, IntPoint(p))
|
||||
|
||||
|
||||
/*
|
||||
** number of ints inside a lua_Number
|
||||
*/
|
||||
#define numints cast(int, sizeof(lua_Number)/sizeof(int))
|
||||
|
||||
|
||||
/*
|
||||
** hash for lua_Numbers
|
||||
*/
|
||||
static Node *hashnum (const Table *t, lua_Number n) {
|
||||
unsigned int a[numints];
|
||||
int i;
|
||||
n += 1; /* normalize number (avoid -0) */
|
||||
lua_assert(sizeof(a) <= sizeof(n));
|
||||
memcpy(a, &n, sizeof(a));
|
||||
for (i = 1; i < numints; i++) a[0] += a[i];
|
||||
return hashmod(t, cast(lu_hash, a[0]));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
@@ -73,11 +98,8 @@
|
||||
*/
|
||||
Node *luaH_mainposition (const Table *t, const TObject *key) {
|
||||
switch (ttype(key)) {
|
||||
case LUA_TNUMBER: {
|
||||
int ikey;
|
||||
lua_number2int(ikey, nvalue(key));
|
||||
return hashnum(t, ikey);
|
||||
}
|
||||
case LUA_TNUMBER:
|
||||
return hashnum(t, nvalue(key));
|
||||
case LUA_TSTRING:
|
||||
return hashstr(t, tsvalue(key));
|
||||
case LUA_TBOOLEAN:
|
||||
@@ -122,7 +144,7 @@ static int luaH_index (lua_State *L, Table *t, StkId key) {
|
||||
if (v == &luaO_nilobject)
|
||||
luaG_runerror(L, "invalid key for `next'");
|
||||
i = cast(int, (cast(const lu_byte *, v) -
|
||||
cast(const lu_byte *, val(node(t, 0)))) / sizeof(Node));
|
||||
cast(const lu_byte *, gval(gnode(t, 0)))) / sizeof(Node));
|
||||
return i + t->sizearray; /* hash elements are numbered after array ones */
|
||||
}
|
||||
}
|
||||
@@ -132,15 +154,15 @@ int luaH_next (lua_State *L, Table *t, StkId key) {
|
||||
int i = luaH_index(L, t, key); /* find original element */
|
||||
for (i++; i < t->sizearray; i++) { /* try first array part */
|
||||
if (!ttisnil(&t->array[i])) { /* a non-nil value? */
|
||||
setnvalue(key, i+1);
|
||||
setnvalue(key, cast(lua_Number, i+1));
|
||||
setobj2s(key+1, &t->array[i]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */
|
||||
if (!ttisnil(val(node(t, i)))) { /* a non-nil value? */
|
||||
setobj2s(key, key(node(t, i)));
|
||||
setobj2s(key+1, val(node(t, i)));
|
||||
if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
|
||||
setobj2s(key, gkey(gnode(t, i)));
|
||||
setobj2s(key+1, gval(gnode(t, i)));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -160,7 +182,7 @@ static void computesizes (int nums[], int ntotal, int *narray, int *nhash) {
|
||||
int a = nums[0]; /* number of elements smaller than 2^i */
|
||||
int na = a; /* number of elements to go to array part */
|
||||
int n = (na == 0) ? -1 : 0; /* (log of) optimal size for array part */
|
||||
for (i = 1; i <= MAXBITS && *narray >= twoto(i-1); i++) {
|
||||
for (i = 1; a < *narray && *narray >= twoto(i-1); i++) {
|
||||
if (nums[i] > 0) {
|
||||
a += nums[i];
|
||||
if (a >= twoto(i-1)) { /* more than half elements in use? */
|
||||
@@ -178,27 +200,31 @@ static void computesizes (int nums[], int ntotal, int *narray, int *nhash) {
|
||||
|
||||
static void numuse (const Table *t, int *narray, int *nhash) {
|
||||
int nums[MAXBITS+1];
|
||||
int i;
|
||||
int i, lg;
|
||||
int totaluse = 0;
|
||||
for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* init `nums' */
|
||||
/* count elements in array part */
|
||||
i = luaO_log2(t->sizearray) + 1; /* number of `slices' */
|
||||
while (i--) { /* for each slice [2^(i-1) to 2^i) */
|
||||
int to = twoto(i);
|
||||
int from = to/2;
|
||||
if (to > t->sizearray) to = t->sizearray;
|
||||
for (; from < to; from++)
|
||||
if (!ttisnil(&t->array[from])) {
|
||||
nums[i]++;
|
||||
for (i=0, lg=0; lg<=MAXBITS; lg++) { /* for each slice [2^(lg-1) to 2^lg) */
|
||||
int ttlg = twoto(lg); /* 2^lg */
|
||||
if (ttlg > t->sizearray) {
|
||||
ttlg = t->sizearray;
|
||||
if (i >= ttlg) break;
|
||||
}
|
||||
nums[lg] = 0;
|
||||
for (; i<ttlg; i++) {
|
||||
if (!ttisnil(&t->array[i])) {
|
||||
nums[lg]++;
|
||||
totaluse++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (; lg<=MAXBITS; lg++) nums[lg] = 0; /* reset other counts */
|
||||
*narray = totaluse; /* all previous uses were in array part */
|
||||
/* count elements in hash part */
|
||||
i = sizenode(t);
|
||||
while (i--) {
|
||||
if (!ttisnil(val(&t->node[i]))) {
|
||||
int k = arrayindex(key(&t->node[i]));
|
||||
Node *n = &t->node[i];
|
||||
if (!ttisnil(gval(n))) {
|
||||
int k = arrayindex(gkey(n));
|
||||
if (k >= 0) { /* is `key' an appropriate array index? */
|
||||
nums[luaO_log2(k-1)+1]++; /* count as such */
|
||||
(*narray)++;
|
||||
@@ -226,20 +252,20 @@ static void setnodevector (lua_State *L, Table *t, int lsize) {
|
||||
luaG_runerror(L, "table overflow");
|
||||
if (lsize == 0) { /* no elements to hash part? */
|
||||
t->node = G(L)->dummynode; /* use common `dummynode' */
|
||||
lua_assert(ttisnil(key(t->node))); /* assert invariants: */
|
||||
lua_assert(ttisnil(val(t->node)));
|
||||
lua_assert(ttisnil(gkey(t->node))); /* assert invariants: */
|
||||
lua_assert(ttisnil(gval(t->node)));
|
||||
lua_assert(t->node->next == NULL); /* (`dummynode' must be empty) */
|
||||
}
|
||||
else {
|
||||
t->node = luaM_newvector(L, size, Node);
|
||||
for (i=0; i<size; i++) {
|
||||
t->node[i].next = NULL;
|
||||
setnilvalue(key(node(t, i)));
|
||||
setnilvalue(val(node(t, i)));
|
||||
setnilvalue(gkey(gnode(t, i)));
|
||||
setnilvalue(gval(gnode(t, i)));
|
||||
}
|
||||
}
|
||||
t->lsizenode = cast(lu_byte, lsize);
|
||||
t->firstfree = node(t, size-1); /* first free position to be used */
|
||||
t->firstfree = gnode(t, size-1); /* first free position to be used */
|
||||
}
|
||||
|
||||
|
||||
@@ -255,8 +281,8 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
|
||||
lua_assert(t->node == G(L)->dummynode);
|
||||
temp[0] = t->node[0]; /* copy it to `temp' */
|
||||
nold = temp;
|
||||
setnilvalue(key(G(L)->dummynode)); /* restate invariant */
|
||||
setnilvalue(val(G(L)->dummynode));
|
||||
setnilvalue(gkey(G(L)->dummynode)); /* restate invariant */
|
||||
setnilvalue(gval(G(L)->dummynode));
|
||||
lua_assert(G(L)->dummynode->next == NULL);
|
||||
}
|
||||
if (nasize > oldasize) /* array part must grow? */
|
||||
@@ -277,8 +303,8 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
|
||||
/* re-insert elements in hash part */
|
||||
for (i = twoto(oldhsize) - 1; i >= 0; i--) {
|
||||
Node *old = nold+i;
|
||||
if (!ttisnil(val(old)))
|
||||
setobjt2t(luaH_set(L, t, key(old)), val(old));
|
||||
if (!ttisnil(gval(old)))
|
||||
setobjt2t(luaH_set(L, t, gkey(old)), gval(old));
|
||||
}
|
||||
if (oldhsize)
|
||||
luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */
|
||||
@@ -328,7 +354,7 @@ void luaH_free (lua_State *L, Table *t) {
|
||||
** (because gc can call `remove' during a table traversal)
|
||||
*/
|
||||
void luaH_remove (Table *t, Node *e) {
|
||||
Node *mp = luaH_mainposition(t, key(e));
|
||||
Node *mp = luaH_mainposition(t, gkey(e));
|
||||
if (e != mp) { /* element not in its main position? */
|
||||
while (mp->next != e) mp = mp->next; /* find previous */
|
||||
mp->next = e->next; /* remove `e' from its list */
|
||||
@@ -336,8 +362,8 @@ void luaH_remove (Table *t, Node *e) {
|
||||
else {
|
||||
if (e->next != NULL) ??
|
||||
}
|
||||
lua_assert(ttisnil(val(node)));
|
||||
setnilvalue(key(e)); /* clear node `e' */
|
||||
lua_assert(ttisnil(gval(node)));
|
||||
setnilvalue(gkey(e)); /* clear node `e' */
|
||||
e->next = NULL;
|
||||
}
|
||||
#endif
|
||||
@@ -353,8 +379,8 @@ void luaH_remove (Table *t, Node *e) {
|
||||
static TObject *newkey (lua_State *L, Table *t, const TObject *key) {
|
||||
TObject *val;
|
||||
Node *mp = luaH_mainposition(t, key);
|
||||
if (!ttisnil(val(mp))) { /* main position is not free? */
|
||||
Node *othern = luaH_mainposition(t, key(mp)); /* `mp' of colliding node */
|
||||
if (!ttisnil(gval(mp))) { /* main position is not free? */
|
||||
Node *othern = luaH_mainposition(t, gkey(mp)); /* `mp' of colliding node */
|
||||
Node *n = t->firstfree; /* get a free place */
|
||||
if (othern != mp) { /* is colliding node out of its main position? */
|
||||
/* yes; move colliding node into free position */
|
||||
@@ -362,7 +388,7 @@ static TObject *newkey (lua_State *L, Table *t, const TObject *key) {
|
||||
othern->next = n; /* redo the chain with `n' in place of `mp' */
|
||||
*n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
|
||||
mp->next = NULL; /* now `mp' is free */
|
||||
setnilvalue(val(mp));
|
||||
setnilvalue(gval(mp));
|
||||
}
|
||||
else { /* colliding node is in its own main position */
|
||||
/* new node will go into free position */
|
||||
@@ -371,16 +397,16 @@ static TObject *newkey (lua_State *L, Table *t, const TObject *key) {
|
||||
mp = n;
|
||||
}
|
||||
}
|
||||
setobj2t(key(mp), key); /* write barrier */
|
||||
lua_assert(ttisnil(val(mp)));
|
||||
setobj2t(gkey(mp), key); /* write barrier */
|
||||
lua_assert(ttisnil(gval(mp)));
|
||||
for (;;) { /* correct `firstfree' */
|
||||
if (ttisnil(key(t->firstfree)))
|
||||
return val(mp); /* OK; table still has a free place */
|
||||
if (ttisnil(gkey(t->firstfree)))
|
||||
return gval(mp); /* OK; table still has a free place */
|
||||
else if (t->firstfree == t->node) break; /* cannot decrement from here */
|
||||
else (t->firstfree)--;
|
||||
}
|
||||
/* no more free places; must create one */
|
||||
setbvalue(val(mp), 0); /* avoid new key being removed */
|
||||
setbvalue(gval(mp), 0); /* avoid new key being removed */
|
||||
rehash(L, t); /* grow table */
|
||||
val = cast(TObject *, luaH_get(t, key)); /* get new position */
|
||||
lua_assert(ttisboolean(val));
|
||||
@@ -397,7 +423,7 @@ static const TObject *luaH_getany (Table *t, const TObject *key) {
|
||||
else {
|
||||
Node *n = luaH_mainposition(t, key);
|
||||
do { /* check whether `key' is somewhere in the chain */
|
||||
if (luaO_rawequalObj(key(n), key)) return val(n); /* that's it */
|
||||
if (luaO_rawequalObj(gkey(n), key)) return gval(n); /* that's it */
|
||||
else n = n->next;
|
||||
} while (n);
|
||||
return &luaO_nilobject;
|
||||
@@ -412,10 +438,11 @@ const TObject *luaH_getnum (Table *t, int key) {
|
||||
if (1 <= key && key <= t->sizearray)
|
||||
return &t->array[key-1];
|
||||
else {
|
||||
Node *n = hashnum(t, key);
|
||||
lua_Number nk = cast(lua_Number, key);
|
||||
Node *n = hashnum(t, nk);
|
||||
do { /* check whether `key' is somewhere in the chain */
|
||||
if (ttisnumber(key(n)) && nvalue(key(n)) == (lua_Number)key)
|
||||
return val(n); /* that's it */
|
||||
if (ttisnumber(gkey(n)) && nvalue(gkey(n)) == nk)
|
||||
return gval(n); /* that's it */
|
||||
else n = n->next;
|
||||
} while (n);
|
||||
return &luaO_nilobject;
|
||||
@@ -429,8 +456,8 @@ const TObject *luaH_getnum (Table *t, int key) {
|
||||
const TObject *luaH_getstr (Table *t, TString *key) {
|
||||
Node *n = hashstr(t, key);
|
||||
do { /* check whether `key' is somewhere in the chain */
|
||||
if (ttisstring(key(n)) && tsvalue(key(n)) == key)
|
||||
return val(n); /* that's it */
|
||||
if (ttisstring(gkey(n)) && tsvalue(gkey(n)) == key)
|
||||
return gval(n); /* that's it */
|
||||
else n = n->next;
|
||||
} while (n);
|
||||
return &luaO_nilobject;
|
||||
@@ -475,7 +502,7 @@ TObject *luaH_setnum (lua_State *L, Table *t, int key) {
|
||||
return cast(TObject *, p);
|
||||
else {
|
||||
TObject k;
|
||||
setnvalue(&k, key);
|
||||
setnvalue(&k, cast(lua_Number, key));
|
||||
return newkey(L, t, &k);
|
||||
}
|
||||
}
|
||||
|
||||
8
ltable.h
8
ltable.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltable.h,v 1.42 2002/05/27 20:35:40 roberto Exp roberto $
|
||||
** $Id: ltable.h,v 1.43 2002/11/07 16:03:33 roberto Exp roberto $
|
||||
** Lua tables (hash)
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -10,9 +10,9 @@
|
||||
#include "lobject.h"
|
||||
|
||||
|
||||
#define node(t,i) (&(t)->node[i])
|
||||
#define key(n) (&(n)->i_key)
|
||||
#define val(n) (&(n)->i_val)
|
||||
#define gnode(t,i) (&(t)->node[i])
|
||||
#define gkey(n) (&(n)->i_key)
|
||||
#define gval(n) (&(n)->i_val)
|
||||
|
||||
|
||||
const TObject *luaH_getnum (Table *t, int key);
|
||||
|
||||
73
ltablib.c
73
ltablib.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltablib.c,v 1.16 2002/11/14 15:41:38 roberto Exp roberto $
|
||||
** $Id: ltablib.c,v 1.20 2003/03/11 12:24:34 roberto Exp roberto $
|
||||
** Library for Table Manipulation
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -15,52 +15,7 @@
|
||||
#include "lualib.h"
|
||||
|
||||
|
||||
|
||||
static int checkint (lua_State *L) {
|
||||
int n = (int)lua_tonumber(L, -1);
|
||||
if (n == 0 && !lua_isnumber(L, -1)) n = -1;
|
||||
lua_pop(L, 1);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static void aux_setn (lua_State *L, int t, int n) {
|
||||
lua_pushliteral(L, "n");
|
||||
lua_rawget(L, t);
|
||||
if (checkint(L) >= 0) {
|
||||
lua_pushliteral(L, "n"); /* use it */
|
||||
lua_pushnumber(L, n);
|
||||
lua_rawset(L, t);
|
||||
}
|
||||
else { /* use N */
|
||||
lua_pushvalue(L, t);
|
||||
lua_pushnumber(L, n);
|
||||
lua_rawset(L, lua_upvalueindex(1)); /* N[t] = n */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int aux_getn (lua_State *L, int t) {
|
||||
int n;
|
||||
luaL_checktype(L, t, LUA_TTABLE);
|
||||
lua_pushliteral(L, "n"); /* try t.n */
|
||||
lua_rawget(L, t);
|
||||
if ((n = checkint(L)) >= 0) return n;
|
||||
lua_pushvalue(L, t); /* try N[t] */
|
||||
lua_rawget(L, lua_upvalueindex(1));
|
||||
if ((n = checkint(L)) >= 0) return n;
|
||||
else { /* must count elements */
|
||||
n = 0;
|
||||
for (;;) {
|
||||
lua_rawgeti(L, t, ++n);
|
||||
if (lua_isnil(L, -1)) break;
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
aux_setn(L, t, n - 1);
|
||||
return n - 1;
|
||||
}
|
||||
}
|
||||
#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
|
||||
|
||||
|
||||
static int luaB_foreachi (lua_State *L) {
|
||||
@@ -69,7 +24,7 @@ static int luaB_foreachi (lua_State *L) {
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
for (i=1; i<=n; i++) {
|
||||
lua_pushvalue(L, 2); /* function */
|
||||
lua_pushnumber(L, i); /* 1st argument */
|
||||
lua_pushnumber(L, (lua_Number)i); /* 1st argument */
|
||||
lua_rawgeti(L, 1, i); /* 2nd argument */
|
||||
lua_call(L, 2, 1);
|
||||
if (!lua_isnil(L, -1))
|
||||
@@ -99,14 +54,14 @@ static int luaB_foreach (lua_State *L) {
|
||||
|
||||
|
||||
static int luaB_getn (lua_State *L) {
|
||||
lua_pushnumber(L, aux_getn(L, 1));
|
||||
lua_pushnumber(L, (lua_Number)aux_getn(L, 1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_setn (lua_State *L) {
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
aux_setn(L, 1, luaL_checkint(L, 2));
|
||||
luaL_setn(L, 1, luaL_checkint(L, 2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -122,7 +77,7 @@ static int luaB_tinsert (lua_State *L) {
|
||||
if (pos > n) n = pos; /* `grow' array if necessary */
|
||||
v = 3; /* function may be called with more than 3 args */
|
||||
}
|
||||
aux_setn(L, 1, n); /* new size */
|
||||
luaL_setn(L, 1, n); /* new size */
|
||||
while (--n >= pos) { /* move up elements */
|
||||
lua_rawgeti(L, 1, n);
|
||||
lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */
|
||||
@@ -137,7 +92,7 @@ static int luaB_tremove (lua_State *L) {
|
||||
int n = aux_getn(L, 1);
|
||||
int pos = luaL_optint(L, 2, n);
|
||||
if (n <= 0) return 0; /* table is `empty' */
|
||||
aux_setn(L, 1, n-1); /* t.n = n-1 */
|
||||
luaL_setn(L, 1, n-1); /* t.n = n-1 */
|
||||
lua_rawgeti(L, 1, pos); /* result = t[pos] */
|
||||
for ( ;pos<n; pos++) {
|
||||
lua_rawgeti(L, 1, pos+1);
|
||||
@@ -156,7 +111,7 @@ static int str_concat (lua_State *L) {
|
||||
int i = luaL_optint(L, 3, 1);
|
||||
int n = luaL_optint(L, 4, 0);
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
if (n == 0) n = aux_getn(L, 1);
|
||||
if (n == 0) n = luaL_getn(L, 1);
|
||||
luaL_buffinit(L, &b);
|
||||
for (; i <= n; i++) {
|
||||
lua_rawgeti(L, 1, i);
|
||||
@@ -288,14 +243,8 @@ static const luaL_reg tab_funcs[] = {
|
||||
};
|
||||
|
||||
|
||||
LUALIB_API int lua_tablibopen (lua_State *L) {
|
||||
lua_newtable(L); /* create N (table to store num. elements in tables) */
|
||||
lua_pushvalue(L, -1); /* `N' will be its own metatable */
|
||||
lua_setmetatable(L, -2);
|
||||
lua_pushliteral(L, "__mode");
|
||||
lua_pushliteral(L, "k");
|
||||
lua_rawset(L, -3); /* metatable(N).__mode = "k" */
|
||||
luaL_openlib(L, LUA_TABLIBNAME, tab_funcs, 1);
|
||||
return 0;
|
||||
LUALIB_API int luaopen_table (lua_State *L) {
|
||||
luaL_openlib(L, LUA_TABLIBNAME, tab_funcs, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
179
ltests.c
179
ltests.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltests.c,v 1.147 2002/12/04 17:29:05 roberto Exp roberto $
|
||||
** $Id: ltests.c,v 1.157 2003/04/03 13:35:34 roberto Exp roberto $
|
||||
** Internal Module for Debugging of the Lua Implementation
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -36,17 +36,20 @@
|
||||
#ifdef LUA_DEBUG
|
||||
|
||||
|
||||
#define lua_pushintegral(L,i) lua_pushnumber(L, cast(lua_Number, (i)))
|
||||
|
||||
|
||||
static lua_State *lua_state = NULL;
|
||||
|
||||
int islocked = 0;
|
||||
|
||||
|
||||
#define index(L,k) (L->ci->base+(k) - 1)
|
||||
#define func_at(L,k) (L->ci->base+(k) - 1)
|
||||
|
||||
|
||||
static void setnameval (lua_State *L, const char *name, int val) {
|
||||
lua_pushstring(L, name);
|
||||
lua_pushnumber(L, val);
|
||||
lua_pushintegral(L, val);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
|
||||
@@ -190,13 +193,13 @@ static int listcode (lua_State *L) {
|
||||
Proto *p;
|
||||
luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
|
||||
1, "Lua function expected");
|
||||
p = clvalue(index(L, 1))->l.p;
|
||||
p = clvalue(func_at(L, 1))->l.p;
|
||||
lua_newtable(L);
|
||||
setnameval(L, "maxstack", p->maxstacksize);
|
||||
setnameval(L, "numparams", p->numparams);
|
||||
for (pc=0; pc<p->sizecode; pc++) {
|
||||
char buff[100];
|
||||
lua_pushnumber(L, pc+1);
|
||||
lua_pushintegral(L, pc+1);
|
||||
lua_pushstring(L, buildop(p, pc, buff));
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
@@ -209,10 +212,10 @@ static int listk (lua_State *L) {
|
||||
int i;
|
||||
luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
|
||||
1, "Lua function expected");
|
||||
p = clvalue(index(L, 1))->l.p;
|
||||
p = clvalue(func_at(L, 1))->l.p;
|
||||
lua_newtable(L);
|
||||
for (i=0; i<p->sizek; i++) {
|
||||
lua_pushnumber(L, i+1);
|
||||
lua_pushintegral(L, i+1);
|
||||
luaA_pushobject(L, p->k+i);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
@@ -227,7 +230,7 @@ static int listlocals (lua_State *L) {
|
||||
const char *name;
|
||||
luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
|
||||
1, "Lua function expected");
|
||||
p = clvalue(index(L, 1))->l.p;
|
||||
p = clvalue(func_at(L, 1))->l.p;
|
||||
while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
|
||||
lua_pushstring(L, name);
|
||||
return i-1;
|
||||
@@ -252,9 +255,9 @@ static int get_limits (lua_State *L) {
|
||||
|
||||
static int mem_query (lua_State *L) {
|
||||
if (lua_isnone(L, 1)) {
|
||||
lua_pushnumber(L, memdebug_total);
|
||||
lua_pushnumber(L, memdebug_numblocks);
|
||||
lua_pushnumber(L, memdebug_maxmem);
|
||||
lua_pushintegral(L, memdebug_total);
|
||||
lua_pushintegral(L, memdebug_numblocks);
|
||||
lua_pushintegral(L, memdebug_maxmem);
|
||||
return 3;
|
||||
}
|
||||
else {
|
||||
@@ -267,14 +270,14 @@ static int mem_query (lua_State *L) {
|
||||
static int hash_query (lua_State *L) {
|
||||
if (lua_isnone(L, 2)) {
|
||||
luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "string expected");
|
||||
lua_pushnumber(L, tsvalue(index(L, 1))->tsv.hash);
|
||||
lua_pushintegral(L, tsvalue(func_at(L, 1))->tsv.hash);
|
||||
}
|
||||
else {
|
||||
TObject *o = index(L, 1);
|
||||
TObject *o = func_at(L, 1);
|
||||
Table *t;
|
||||
luaL_checktype(L, 2, LUA_TTABLE);
|
||||
t = hvalue(index(L, 2));
|
||||
lua_pushnumber(L, luaH_mainposition(t, o) - t->node);
|
||||
t = hvalue(func_at(L, 2));
|
||||
lua_pushintegral(L, luaH_mainposition(t, o) - t->node);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -282,11 +285,11 @@ static int hash_query (lua_State *L) {
|
||||
|
||||
static int stacklevel (lua_State *L) {
|
||||
unsigned long a = 0;
|
||||
lua_pushnumber(L, (int)(L->top - L->stack));
|
||||
lua_pushnumber(L, (int)(L->stack_last - L->stack));
|
||||
lua_pushnumber(L, (int)(L->ci - L->base_ci));
|
||||
lua_pushnumber(L, (int)(L->end_ci - L->base_ci));
|
||||
lua_pushnumber(L, (unsigned long)&a);
|
||||
lua_pushintegral(L, (int)(L->top - L->stack));
|
||||
lua_pushintegral(L, (int)(L->stack_last - L->stack));
|
||||
lua_pushintegral(L, (int)(L->ci - L->base_ci));
|
||||
lua_pushintegral(L, (int)(L->end_ci - L->base_ci));
|
||||
lua_pushintegral(L, (unsigned long)&a);
|
||||
return 5;
|
||||
}
|
||||
|
||||
@@ -295,28 +298,28 @@ static int table_query (lua_State *L) {
|
||||
const Table *t;
|
||||
int i = luaL_optint(L, 2, -1);
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
t = hvalue(index(L, 1));
|
||||
t = hvalue(func_at(L, 1));
|
||||
if (i == -1) {
|
||||
lua_pushnumber(L, t->sizearray);
|
||||
lua_pushnumber(L, sizenode(t));
|
||||
lua_pushnumber(L, t->firstfree - t->node);
|
||||
lua_pushintegral(L, t->sizearray);
|
||||
lua_pushintegral(L, sizenode(t));
|
||||
lua_pushintegral(L, t->firstfree - t->node);
|
||||
}
|
||||
else if (i < t->sizearray) {
|
||||
lua_pushnumber(L, i);
|
||||
lua_pushintegral(L, i);
|
||||
luaA_pushobject(L, &t->array[i]);
|
||||
lua_pushnil(L);
|
||||
}
|
||||
else if ((i -= t->sizearray) < sizenode(t)) {
|
||||
if (!ttisnil(val(node(t, i))) ||
|
||||
ttisnil(key(node(t, i))) ||
|
||||
ttisnumber(key(node(t, i)))) {
|
||||
luaA_pushobject(L, key(node(t, i)));
|
||||
if (!ttisnil(gval(gnode(t, i))) ||
|
||||
ttisnil(gkey(gnode(t, i))) ||
|
||||
ttisnumber(gkey(gnode(t, i)))) {
|
||||
luaA_pushobject(L, gkey(gnode(t, i)));
|
||||
}
|
||||
else
|
||||
lua_pushstring(L, "<undef>");
|
||||
luaA_pushobject(L, val(&t->node[i]));
|
||||
luaA_pushobject(L, gval(gnode(t, i)));
|
||||
if (t->node[i].next)
|
||||
lua_pushnumber(L, t->node[i].next - t->node);
|
||||
lua_pushintegral(L, t->node[i].next - t->node);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
}
|
||||
@@ -328,8 +331,8 @@ static int string_query (lua_State *L) {
|
||||
stringtable *tb = &G(L)->strt;
|
||||
int s = luaL_optint(L, 2, 0) - 1;
|
||||
if (s==-1) {
|
||||
lua_pushnumber(L ,tb->nuse);
|
||||
lua_pushnumber(L ,tb->size);
|
||||
lua_pushintegral(L ,tb->nuse);
|
||||
lua_pushintegral(L ,tb->size);
|
||||
return 2;
|
||||
}
|
||||
else if (s < tb->size) {
|
||||
@@ -351,7 +354,7 @@ static int tref (lua_State *L) {
|
||||
int lock = luaL_optint(L, 2, 1);
|
||||
luaL_checkany(L, 1);
|
||||
lua_pushvalue(L, 1);
|
||||
lua_pushnumber(L, lua_ref(L, lock));
|
||||
lua_pushintegral(L, lua_ref(L, lock));
|
||||
assert(lua_gettop(L) == level+1); /* +1 for result */
|
||||
return 1;
|
||||
}
|
||||
@@ -384,6 +387,24 @@ static int metatable (lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int upvalue (lua_State *L) {
|
||||
int n = luaL_checkint(L, 2);
|
||||
luaL_checktype(L, 1, LUA_TFUNCTION);
|
||||
if (lua_isnone(L, 3)) {
|
||||
const char *name = lua_getupvalue(L, 1, n);
|
||||
if (name == NULL) return 0;
|
||||
lua_pushstring(L, name);
|
||||
return 2;
|
||||
}
|
||||
else {
|
||||
const char *name = lua_setupvalue(L, 1, n);
|
||||
lua_pushstring(L, name);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int newuserdata (lua_State *L) {
|
||||
size_t size = luaL_checkint(L, 1);
|
||||
char *p = cast(char *, lua_newuserdata(L, size));
|
||||
@@ -399,7 +420,7 @@ static int pushuserdata (lua_State *L) {
|
||||
|
||||
|
||||
static int udataval (lua_State *L) {
|
||||
lua_pushnumber(L, cast(int, lua_touserdata(L, 1)));
|
||||
lua_pushintegral(L, cast(int, lua_touserdata(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -411,7 +432,7 @@ static int doonnewstack (lua_State *L) {
|
||||
int status = luaL_loadbuffer(L1, s, l, s);
|
||||
if (status == 0)
|
||||
status = lua_pcall(L1, 0, 0, 0);
|
||||
lua_pushnumber(L, status);
|
||||
lua_pushintegral(L, status);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -432,20 +453,28 @@ static int newstate (lua_State *L) {
|
||||
lua_State *L1 = lua_open();
|
||||
if (L1) {
|
||||
lua_userstateopen(L1); /* init lock */
|
||||
lua_pushnumber(L, (unsigned long)L1);
|
||||
lua_pushintegral(L, (unsigned long)L1);
|
||||
}
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int loadlib (lua_State *L) {
|
||||
lua_State *L1 = cast(lua_State *, cast(unsigned long, luaL_checknumber(L, 1)));
|
||||
lua_register(L1, "mathlibopen", lua_mathlibopen);
|
||||
lua_register(L1, "strlibopen", lua_strlibopen);
|
||||
lua_register(L1, "iolibopen", lua_iolibopen);
|
||||
lua_register(L1, "dblibopen", lua_dblibopen);
|
||||
lua_register(L1, "baselibopen", lua_baselibopen);
|
||||
static const luaL_reg libs[] = {
|
||||
{"mathlibopen", luaopen_math},
|
||||
{"strlibopen", luaopen_string},
|
||||
{"iolibopen", luaopen_io},
|
||||
{"tablibopen", luaopen_table},
|
||||
{"dblibopen", luaopen_debug},
|
||||
{"baselibopen", luaopen_base},
|
||||
{NULL, NULL}
|
||||
};
|
||||
lua_State *L1 = cast(lua_State *,
|
||||
cast(unsigned long, luaL_checknumber(L, 1)));
|
||||
lua_pushvalue(L1, LUA_GLOBALSINDEX);
|
||||
luaL_openlib(L1, NULL, libs, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -467,8 +496,9 @@ static int doremote (lua_State *L) {
|
||||
status = lua_pcall(L1, 0, LUA_MULTRET, 0);
|
||||
if (status != 0) {
|
||||
lua_pushnil(L);
|
||||
lua_pushnumber(L, status);
|
||||
return 2;
|
||||
lua_pushintegral(L, status);
|
||||
lua_pushstring(L, lua_tostring(L1, -1));
|
||||
return 3;
|
||||
}
|
||||
else {
|
||||
int i = 0;
|
||||
@@ -481,10 +511,17 @@ static int doremote (lua_State *L) {
|
||||
|
||||
|
||||
static int log2_aux (lua_State *L) {
|
||||
lua_pushnumber(L, luaO_log2(luaL_checkint(L, 1)));
|
||||
lua_pushintegral(L, luaO_log2(luaL_checkint(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int int2fb_aux (lua_State *L) {
|
||||
int b = luaO_int2fb(luaL_checkint(L, 1));
|
||||
lua_pushintegral(L, b);
|
||||
lua_pushintegral(L, fb2int(b));
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
static int test_do (lua_State *L) {
|
||||
const char *p = luaL_checkstring(L, 1);
|
||||
@@ -551,31 +588,31 @@ static int testC (lua_State *L) {
|
||||
const char *inst = getname;
|
||||
if EQ("") return 0;
|
||||
else if EQ("isnumber") {
|
||||
lua_pushnumber(L, lua_isnumber(L, getnum));
|
||||
lua_pushintegral(L, lua_isnumber(L, getnum));
|
||||
}
|
||||
else if EQ("isstring") {
|
||||
lua_pushnumber(L, lua_isstring(L, getnum));
|
||||
lua_pushintegral(L, lua_isstring(L, getnum));
|
||||
}
|
||||
else if EQ("istable") {
|
||||
lua_pushnumber(L, lua_istable(L, getnum));
|
||||
lua_pushintegral(L, lua_istable(L, getnum));
|
||||
}
|
||||
else if EQ("iscfunction") {
|
||||
lua_pushnumber(L, lua_iscfunction(L, getnum));
|
||||
lua_pushintegral(L, lua_iscfunction(L, getnum));
|
||||
}
|
||||
else if EQ("isfunction") {
|
||||
lua_pushnumber(L, lua_isfunction(L, getnum));
|
||||
lua_pushintegral(L, lua_isfunction(L, getnum));
|
||||
}
|
||||
else if EQ("isuserdata") {
|
||||
lua_pushnumber(L, lua_isuserdata(L, getnum));
|
||||
lua_pushintegral(L, lua_isuserdata(L, getnum));
|
||||
}
|
||||
else if EQ("isudataval") {
|
||||
lua_pushnumber(L, lua_islightuserdata(L, getnum));
|
||||
lua_pushintegral(L, lua_islightuserdata(L, getnum));
|
||||
}
|
||||
else if EQ("isnil") {
|
||||
lua_pushnumber(L, lua_isnil(L, getnum));
|
||||
lua_pushintegral(L, lua_isnil(L, getnum));
|
||||
}
|
||||
else if EQ("isnull") {
|
||||
lua_pushnumber(L, lua_isnone(L, getnum));
|
||||
lua_pushintegral(L, lua_isnone(L, getnum));
|
||||
}
|
||||
else if EQ("tonumber") {
|
||||
lua_pushnumber(L, lua_tonumber(L, getnum));
|
||||
@@ -584,11 +621,8 @@ static int testC (lua_State *L) {
|
||||
const char *s = lua_tostring(L, getnum);
|
||||
lua_pushstring(L, s);
|
||||
}
|
||||
else if EQ("tonumber") {
|
||||
lua_pushnumber(L, lua_tonumber(L, getnum));
|
||||
}
|
||||
else if EQ("strlen") {
|
||||
lua_pushnumber(L, lua_strlen(L, getnum));
|
||||
lua_pushintegral(L, lua_strlen(L, getnum));
|
||||
}
|
||||
else if EQ("tocfunction") {
|
||||
lua_pushcfunction(L, lua_tocfunction(L, getnum));
|
||||
@@ -597,7 +631,7 @@ static int testC (lua_State *L) {
|
||||
return getnum;
|
||||
}
|
||||
else if EQ("gettop") {
|
||||
lua_pushnumber(L, lua_gettop(L));
|
||||
lua_pushintegral(L, lua_gettop(L));
|
||||
}
|
||||
else if EQ("settop") {
|
||||
lua_settop(L, getnum);
|
||||
@@ -606,7 +640,7 @@ static int testC (lua_State *L) {
|
||||
lua_pop(L, getnum);
|
||||
}
|
||||
else if EQ("pushnum") {
|
||||
lua_pushnumber(L, getnum);
|
||||
lua_pushintegral(L, getnum);
|
||||
}
|
||||
else if EQ("pushnil") {
|
||||
lua_pushnil(L);
|
||||
@@ -615,7 +649,7 @@ static int testC (lua_State *L) {
|
||||
lua_pushboolean(L, getnum);
|
||||
}
|
||||
else if EQ("tobool") {
|
||||
lua_pushnumber(L, lua_toboolean(L, getnum));
|
||||
lua_pushintegral(L, lua_toboolean(L, getnum));
|
||||
}
|
||||
else if EQ("pushvalue") {
|
||||
lua_pushvalue(L, getnum);
|
||||
@@ -683,6 +717,16 @@ static int testC (lua_State *L) {
|
||||
else if EQ("type") {
|
||||
lua_pushstring(L, lua_typename(L, lua_type(L, getnum)));
|
||||
}
|
||||
else if EQ("getn") {
|
||||
int i = getnum;
|
||||
lua_pushintegral(L, luaL_getn(L, i));
|
||||
}
|
||||
else if EQ("setn") {
|
||||
int i = getnum;
|
||||
int n = cast(int, lua_tonumber(L, -1));
|
||||
luaL_setn(L, i, n);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
else luaL_error(L, "unknown instruction %s", buff);
|
||||
}
|
||||
return 0;
|
||||
@@ -754,6 +798,7 @@ static const struct luaL_reg tests_funcs[] = {
|
||||
{"d2s", d2s},
|
||||
{"s2d", s2d},
|
||||
{"metatable", metatable},
|
||||
{"upvalue", upvalue},
|
||||
{"newuserdata", newuserdata},
|
||||
{"pushuserdata", pushuserdata},
|
||||
{"udataval", udataval},
|
||||
@@ -762,6 +807,7 @@ static const struct luaL_reg tests_funcs[] = {
|
||||
{"closestate", closestate},
|
||||
{"doremote", doremote},
|
||||
{"log2", log2_aux},
|
||||
{"int2fb", int2fb_aux},
|
||||
{"totalmem", mem_query},
|
||||
{"resume", coresume},
|
||||
{"setyhook", setyhook},
|
||||
@@ -777,7 +823,15 @@ static void fim (void) {
|
||||
}
|
||||
|
||||
|
||||
static int l_panic (lua_State *L) {
|
||||
UNUSED(L);
|
||||
fprintf(stderr, "unable to recover; exiting\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int luaB_opentests (lua_State *L) {
|
||||
lua_atpanic(L, l_panic);
|
||||
lua_userstateopen(L); /* init lock */
|
||||
lua_state = L; /* keep first state to be opened */
|
||||
luaL_openlib(L, "T", tests_funcs, 0);
|
||||
@@ -792,6 +846,7 @@ int main (int argc, char *argv[]) {
|
||||
if (limit)
|
||||
memdebug_memlimit = strtoul(limit, NULL, 10);
|
||||
l_main(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
4
ltm.c
4
ltm.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltm.c,v 1.104 2002/11/14 11:51:50 roberto Exp roberto $
|
||||
** $Id: ltm.c,v 1.105 2002/12/04 17:38:31 roberto Exp roberto $
|
||||
** Tag methods
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -49,7 +49,7 @@ const TObject *luaT_gettm (Table *events, TMS event, TString *ename) {
|
||||
const TObject *tm = luaH_getstr(events, ename);
|
||||
lua_assert(event <= TM_EQ);
|
||||
if (ttisnil(tm)) { /* no tag method? */
|
||||
events->flags |= (1u<<event); /* cache this fact */
|
||||
events->flags |= cast(lu_byte, 1u<<event); /* cache this fact */
|
||||
return NULL;
|
||||
}
|
||||
else return tm;
|
||||
|
||||
59
lua.c
59
lua.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lua.c,v 1.112 2002/12/04 17:28:27 roberto Exp roberto $
|
||||
** $Id: lua.c,v 1.121 2003/03/24 12:40:01 roberto Exp roberto $
|
||||
** Lua stand-alone interpreter
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -26,10 +26,14 @@
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _POSIX_SOURCE
|
||||
/*
|
||||
** definition of `isatty'
|
||||
*/
|
||||
#ifdef _POSIX_C_SOURCE
|
||||
#include <unistd.h>
|
||||
#define stdin_is_tty() isatty(0)
|
||||
#else
|
||||
static int isatty (int x) { return x==0; } /* assume stdin is a tty */
|
||||
#define stdin_is_tty() 1 /* assume stdin is a tty */
|
||||
#endif
|
||||
|
||||
|
||||
@@ -43,6 +47,9 @@ static int isatty (int x) { return x==0; } /* assume stdin is a tty */
|
||||
#define PROMPT2 ">> "
|
||||
#endif
|
||||
|
||||
#ifndef PROGNAME
|
||||
#define PROGNAME "lua"
|
||||
#endif
|
||||
|
||||
#ifndef lua_userinit
|
||||
#define lua_userinit(L) openstdlibs(L)
|
||||
@@ -56,17 +63,18 @@ static int isatty (int x) { return x==0; } /* assume stdin is a tty */
|
||||
|
||||
static lua_State *L = NULL;
|
||||
|
||||
static const char *progname;
|
||||
static const char *progname = PROGNAME;
|
||||
|
||||
|
||||
|
||||
static const luaL_reg lualibs[] = {
|
||||
{"baselib", lua_baselibopen},
|
||||
{"tablib", lua_tablibopen},
|
||||
{"iolib", lua_iolibopen},
|
||||
{"strlib", lua_strlibopen},
|
||||
{"mathlib", lua_mathlibopen},
|
||||
{"dblib", lua_dblibopen},
|
||||
{"base", luaopen_base},
|
||||
{"table", luaopen_table},
|
||||
{"io", luaopen_io},
|
||||
{"string", luaopen_string},
|
||||
{"math", luaopen_math},
|
||||
{"debug", luaopen_debug},
|
||||
{"loadlib", luaopen_loadlib},
|
||||
/* add your libraries here */
|
||||
LUA_EXTRALIBS
|
||||
{NULL, NULL}
|
||||
@@ -134,13 +142,6 @@ static int lcall (int narg, int clear) {
|
||||
}
|
||||
|
||||
|
||||
static int l_panic (lua_State *l) {
|
||||
(void)l;
|
||||
l_message(progname, "unable to recover; exiting");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void print_version (void) {
|
||||
l_message(NULL, LUA_VERSION " " LUA_COPYRIGHT);
|
||||
}
|
||||
@@ -285,7 +286,8 @@ static void manual_input (void) {
|
||||
lua_getglobal(L, "print");
|
||||
lua_insert(L, 1);
|
||||
if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
|
||||
l_message(progname, "error calling `print'");
|
||||
l_message(progname, lua_pushfstring(L, "error calling `print' (%s)",
|
||||
lua_tostring(L, -1)));
|
||||
}
|
||||
}
|
||||
lua_settop(L, 0); /* clear stack */
|
||||
@@ -296,7 +298,7 @@ static void manual_input (void) {
|
||||
|
||||
static int handle_argv (char *argv[], int *interactive) {
|
||||
if (argv[1] == NULL) { /* no more arguments? */
|
||||
if (isatty(0)) {
|
||||
if (stdin_is_tty()) {
|
||||
print_version();
|
||||
manual_input();
|
||||
}
|
||||
@@ -309,6 +311,10 @@ static int handle_argv (char *argv[], int *interactive) {
|
||||
if (argv[i][0] != '-') break; /* not an option? */
|
||||
switch (argv[i][1]) { /* option */
|
||||
case '-': { /* `--' */
|
||||
if (argv[i][2] != '\0') {
|
||||
print_usage();
|
||||
return 1;
|
||||
}
|
||||
i++; /* skip this argument */
|
||||
goto endloop; /* stop handling arguments */
|
||||
}
|
||||
@@ -329,10 +335,10 @@ static int handle_argv (char *argv[], int *interactive) {
|
||||
if (*chunk == '\0') chunk = argv[++i];
|
||||
if (chunk == NULL) {
|
||||
print_usage();
|
||||
return EXIT_FAILURE;
|
||||
return 1;
|
||||
}
|
||||
if (dostring(chunk, "=<command line>") != 0)
|
||||
return EXIT_FAILURE;
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
case 'l': {
|
||||
@@ -340,10 +346,10 @@ static int handle_argv (char *argv[], int *interactive) {
|
||||
if (*filename == '\0') filename = argv[++i];
|
||||
if (filename == NULL) {
|
||||
print_usage();
|
||||
return EXIT_FAILURE;
|
||||
return 1;
|
||||
}
|
||||
if (load_file(filename))
|
||||
return EXIT_FAILURE; /* stop if file fails */
|
||||
return 1; /* stop if file fails */
|
||||
break;
|
||||
}
|
||||
case 'c': {
|
||||
@@ -356,7 +362,7 @@ static int handle_argv (char *argv[], int *interactive) {
|
||||
}
|
||||
default: {
|
||||
print_usage();
|
||||
return EXIT_FAILURE;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} endloop:
|
||||
@@ -373,7 +379,7 @@ static int handle_argv (char *argv[], int *interactive) {
|
||||
|
||||
static void openstdlibs (lua_State *l) {
|
||||
const luaL_reg *lib = lualibs;
|
||||
for (; lib->name; lib++) {
|
||||
for (; lib->func; lib++) {
|
||||
lib->func(l); /* open library */
|
||||
lua_settop(l, 0); /* discard any results */
|
||||
}
|
||||
@@ -401,7 +407,7 @@ static int pmain (lua_State *l) {
|
||||
struct Smain *s = (struct Smain *)lua_touserdata(l, 1);
|
||||
int status;
|
||||
int interactive = 0;
|
||||
progname = s->argv[0];
|
||||
if (s->argv[0] && s->argv[0][0]) progname = s->argv[0];
|
||||
L = l;
|
||||
lua_userinit(l); /* open libraries */
|
||||
status = handle_luainit();
|
||||
@@ -424,7 +430,6 @@ int main (int argc, char *argv[]) {
|
||||
}
|
||||
s.argc = argc;
|
||||
s.argv = argv;
|
||||
lua_atpanic(l, l_panic);
|
||||
status = lua_cpcall(l, &pmain, &s);
|
||||
report(status);
|
||||
lua_close(l);
|
||||
|
||||
20
lua.h
20
lua.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lua.h,v 1.168 2002/11/26 12:53:29 roberto Exp roberto $
|
||||
** $Id: lua.h,v 1.174 2003/02/27 11:52:30 roberto Exp roberto $
|
||||
** Lua - An Extensible Extension Language
|
||||
** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
|
||||
** http://www.lua.org mailto:info@lua.org
|
||||
@@ -14,8 +14,8 @@
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
#define LUA_VERSION "Lua 5.0 (beta)"
|
||||
#define LUA_COPYRIGHT "Copyright (C) 1994-2002 Tecgraf, PUC-Rio"
|
||||
#define LUA_VERSION "Lua 5.0"
|
||||
#define LUA_COPYRIGHT "Copyright (C) 1994-2003 Tecgraf, PUC-Rio"
|
||||
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
|
||||
|
||||
|
||||
@@ -167,8 +167,9 @@ LUA_API void lua_gettable (lua_State *L, int idx);
|
||||
LUA_API void lua_rawget (lua_State *L, int idx);
|
||||
LUA_API void lua_rawgeti (lua_State *L, int idx, int n);
|
||||
LUA_API void lua_newtable (lua_State *L);
|
||||
LUA_API void *lua_newuserdata (lua_State *L, size_t sz);
|
||||
LUA_API int lua_getmetatable (lua_State *L, int objindex);
|
||||
LUA_API void lua_getglobals (lua_State *L, int idx);
|
||||
LUA_API void lua_getfenv (lua_State *L, int idx);
|
||||
|
||||
|
||||
/*
|
||||
@@ -178,7 +179,7 @@ LUA_API void lua_settable (lua_State *L, int idx);
|
||||
LUA_API void lua_rawset (lua_State *L, int idx);
|
||||
LUA_API void lua_rawseti (lua_State *L, int idx, int n);
|
||||
LUA_API int lua_setmetatable (lua_State *L, int objindex);
|
||||
LUA_API int lua_setglobals (lua_State *L, int idx);
|
||||
LUA_API int lua_setfenv (lua_State *L, int idx);
|
||||
|
||||
|
||||
/*
|
||||
@@ -218,8 +219,6 @@ LUA_API int lua_next (lua_State *L, int idx);
|
||||
|
||||
LUA_API void lua_concat (lua_State *L, int n);
|
||||
|
||||
LUA_API void *lua_newuserdata (lua_State *L, size_t sz);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
@@ -317,6 +316,7 @@ LUA_API int lua_pushupvalues (lua_State *L);
|
||||
#define LUA_HOOKRET 1
|
||||
#define LUA_HOOKLINE 2
|
||||
#define LUA_HOOKCOUNT 3
|
||||
#define LUA_HOOKTAILRET 4
|
||||
|
||||
|
||||
/*
|
||||
@@ -336,6 +336,8 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar);
|
||||
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
|
||||
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
|
||||
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
|
||||
LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n);
|
||||
LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n);
|
||||
|
||||
LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);
|
||||
LUA_API lua_Hook lua_gethook (lua_State *L);
|
||||
@@ -349,7 +351,7 @@ struct lua_Debug {
|
||||
int event;
|
||||
const char *name; /* (n) */
|
||||
const char *namewhat; /* (n) `global', `local', `field', `method' */
|
||||
const char *what; /* (S) `Lua' function, `C' function, Lua `main' */
|
||||
const char *what; /* (S) `Lua', `C', `main', `tail' */
|
||||
const char *source; /* (S) */
|
||||
int currentline; /* (l) */
|
||||
int nups; /* (u) number of upvalues */
|
||||
@@ -363,7 +365,7 @@ struct lua_Debug {
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 Tecgraf, PUC-Rio. All rights reserved.
|
||||
* Copyright (C) 1994-2003 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
|
||||
|
||||
28
lualib.h
28
lualib.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lualib.h,v 1.24 2002/06/18 17:42:52 roberto Exp roberto $
|
||||
** $Id: lualib.h,v 1.27 2003/03/17 13:04:58 roberto Exp roberto $
|
||||
** Lua standard libraries
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -12,28 +12,31 @@
|
||||
|
||||
|
||||
#ifndef LUALIB_API
|
||||
#define LUALIB_API extern
|
||||
#define LUALIB_API LUA_API
|
||||
#endif
|
||||
|
||||
|
||||
#define LUA_COLIBNAME "coroutine"
|
||||
LUALIB_API int lua_baselibopen (lua_State *L);
|
||||
LUALIB_API int luaopen_base (lua_State *L);
|
||||
|
||||
#define LUA_TABLIBNAME "table"
|
||||
LUALIB_API int lua_tablibopen (lua_State *L);
|
||||
LUALIB_API int luaopen_table (lua_State *L);
|
||||
|
||||
#define LUA_IOLIBNAME "io"
|
||||
#define LUA_OSLIBNAME "os"
|
||||
LUALIB_API int lua_iolibopen (lua_State *L);
|
||||
LUALIB_API int luaopen_io (lua_State *L);
|
||||
|
||||
#define LUA_STRLIBNAME "string"
|
||||
LUALIB_API int lua_strlibopen (lua_State *L);
|
||||
LUALIB_API int luaopen_string (lua_State *L);
|
||||
|
||||
#define LUA_MATHLIBNAME "math"
|
||||
LUALIB_API int lua_mathlibopen (lua_State *L);
|
||||
LUALIB_API int luaopen_math (lua_State *L);
|
||||
|
||||
#define LUA_DBLIBNAME "debug"
|
||||
LUALIB_API int lua_dblibopen (lua_State *L);
|
||||
LUALIB_API int luaopen_debug (lua_State *L);
|
||||
|
||||
|
||||
LUALIB_API int luaopen_loadlib (lua_State *L);
|
||||
|
||||
|
||||
/* to help testing the libraries */
|
||||
@@ -41,4 +44,13 @@ LUALIB_API int lua_dblibopen (lua_State *L);
|
||||
#define lua_assert(c) /* empty */
|
||||
#endif
|
||||
|
||||
|
||||
/* compatibility code */
|
||||
#define lua_baselibopen luaopen_base
|
||||
#define lua_tablibopen luaopen_table
|
||||
#define lua_iolibopen luaopen_io
|
||||
#define lua_strlibopen luaopen_string
|
||||
#define lua_mathlibopen luaopen_math
|
||||
#define lua_dblibopen luaopen_debug
|
||||
|
||||
#endif
|
||||
|
||||
25
lundump.c
25
lundump.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lundump.c,v 1.57 2002/11/14 16:15:53 roberto Exp roberto $
|
||||
** $Id: lundump.c,v 1.49 2003/04/07 20:34:20 lhf Exp $
|
||||
** load pre-compiled Lua chunks
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -104,7 +104,7 @@ static TString* LoadString (LoadState* S)
|
||||
{
|
||||
char* s=luaZ_openspace(S->L,S->b,size);
|
||||
ezread(S,s,size);
|
||||
return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
|
||||
return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,6 +138,18 @@ static void LoadLines (LoadState* S, Proto* f)
|
||||
LoadVector(S,f->lineinfo,size,sizeof(*f->lineinfo));
|
||||
}
|
||||
|
||||
static void LoadUpvalues (LoadState* S, Proto* f)
|
||||
{
|
||||
int i,n;
|
||||
n=LoadInt(S);
|
||||
if (n!=0 && n!=f->nups)
|
||||
luaG_runerror(S->L,"bad nupvalues in %s: read %d; expected %d",
|
||||
S->name,n,f->nups);
|
||||
f->upvalues=luaM_newvector(S->L,n,TString*);
|
||||
f->sizeupvalues=n;
|
||||
for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
|
||||
}
|
||||
|
||||
static Proto* LoadFunction (LoadState* S, TString* p);
|
||||
|
||||
static void LoadConstants (LoadState* S, Proto* f)
|
||||
@@ -177,12 +189,13 @@ static Proto* LoadFunction (LoadState* S, TString* p)
|
||||
Proto* f=luaF_newproto(S->L);
|
||||
f->source=LoadString(S); if (f->source==NULL) f->source=p;
|
||||
f->lineDefined=LoadInt(S);
|
||||
f->nupvalues=LoadByte(S);
|
||||
f->nups=LoadByte(S);
|
||||
f->numparams=LoadByte(S);
|
||||
f->is_vararg=LoadByte(S);
|
||||
f->maxstacksize=LoadByte(S);
|
||||
LoadLocals(S,f);
|
||||
LoadLines(S,f);
|
||||
LoadLocals(S,f);
|
||||
LoadUpvalues(S,f);
|
||||
LoadConstants(S,f);
|
||||
LoadCode(S,f);
|
||||
#ifndef TRUST_BINARIES
|
||||
@@ -213,14 +226,14 @@ static void TestSize (LoadState* S, int s, const char* what)
|
||||
static void LoadHeader (LoadState* S)
|
||||
{
|
||||
int version;
|
||||
lua_Number x=0,tx=TEST_NUMBER;
|
||||
lua_Number x,tx=TEST_NUMBER;
|
||||
LoadSignature(S);
|
||||
version=LoadByte(S);
|
||||
if (version>VERSION)
|
||||
luaG_runerror(S->L,"%s too new: "
|
||||
"read version %d.%d; expected at most %d.%d",
|
||||
S->name,V(version),V(VERSION));
|
||||
if (version<VERSION0) /* check last major change */
|
||||
if (version<VERSION0) /* check last major change */
|
||||
luaG_runerror(S->L,"%s too old: "
|
||||
"read version %d.%d; expected at least %d.%d",
|
||||
S->name,V(version),V(VERSION0));
|
||||
|
||||
14
lundump.h
14
lundump.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lundump.h,v 1.28 2002/10/09 13:42:01 roberto Exp roberto $
|
||||
** $Id: lundump.h,v 1.30 2003/04/07 20:34:20 lhf Exp $
|
||||
** load pre-compiled Lua chunks
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -11,24 +11,24 @@
|
||||
#include "lzio.h"
|
||||
|
||||
/* load one chunk; from lundump.c */
|
||||
Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer *buff);
|
||||
Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff);
|
||||
|
||||
/* find byte order; from lundump.c */
|
||||
int luaU_endianness (void);
|
||||
|
||||
/* dump one chunk; from dump.c */
|
||||
void luaU_dump (lua_State *L, const Proto* Main, lua_Chunkwriter w, void* data);
|
||||
/* dump one chunk; from ldump.c */
|
||||
void luaU_dump (lua_State* L, const Proto* Main, lua_Chunkwriter w, void* data);
|
||||
|
||||
/* print one chunk; from print.c */
|
||||
void luaU_print (const Proto* Main);
|
||||
|
||||
/* definitions for headers of binary files */
|
||||
#define LUA_SIGNATURE "\033Lua" /* binary files start with <esc>Lua */
|
||||
#define LUA_SIGNATURE "\033Lua" /* binary files start with "<esc>Lua" */
|
||||
#define VERSION 0x50 /* last format change was in 5.0 */
|
||||
#define VERSION0 0x50 /* last major change was in 5.0 */
|
||||
|
||||
/* a multiple of PI for testing native format */
|
||||
/* multiplying by 1E8 gives non-trivial integer values */
|
||||
#define TEST_NUMBER 3.14159265358979323846E8
|
||||
/* multiplying by 1E7 gives non-trivial integer values */
|
||||
#define TEST_NUMBER ((lua_Number)3.14159265358979323846E7)
|
||||
|
||||
#endif
|
||||
|
||||
94
lvm.c
94
lvm.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lvm.c,v 1.272 2002/12/06 17:09:00 roberto Exp roberto $
|
||||
** $Id: lvm.c,v 1.283 2003/03/31 13:00:25 roberto Exp roberto $
|
||||
** Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -9,6 +9,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* needed only when `lua_number2str' uses `sprintf' */
|
||||
#include <stdio.h>
|
||||
|
||||
#define lvm_c
|
||||
|
||||
#include "lua.h"
|
||||
@@ -29,7 +32,6 @@
|
||||
|
||||
/* function to convert a lua_Number to a string */
|
||||
#ifndef lua_number2str
|
||||
#include <stdio.h>
|
||||
#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
|
||||
#endif
|
||||
|
||||
@@ -204,6 +206,33 @@ static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2,
|
||||
}
|
||||
|
||||
|
||||
static const TObject *get_compTM (lua_State *L, Table *mt1, Table *mt2,
|
||||
TMS event) {
|
||||
const TObject *tm1 = fasttm(L, mt1, event);
|
||||
const TObject *tm2;
|
||||
if (tm1 == NULL) return NULL; /* no metamethod */
|
||||
if (mt1 == mt2) return tm1; /* same metatables => same metamethods */
|
||||
tm2 = fasttm(L, mt2, event);
|
||||
if (tm2 == NULL) return NULL; /* no metamethod */
|
||||
if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */
|
||||
return tm1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static int call_orderTM (lua_State *L, const TObject *p1, const TObject *p2,
|
||||
TMS event) {
|
||||
const TObject *tm1 = luaT_gettmbyobj(L, p1, event);
|
||||
const TObject *tm2;
|
||||
if (ttisnil(tm1)) return -1; /* no metamethod? */
|
||||
tm2 = luaT_gettmbyobj(L, p2, event);
|
||||
if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */
|
||||
return -1;
|
||||
callTMres(L, tm1, p1, p2);
|
||||
return !l_isfalse(L->top);
|
||||
}
|
||||
|
||||
|
||||
static int luaV_strcmp (const TString *ls, const TString *rs) {
|
||||
const char *l = getstr(ls);
|
||||
size_t ll = ls->tsv.len;
|
||||
@@ -227,35 +256,37 @@ static int luaV_strcmp (const TString *ls, const TString *rs) {
|
||||
|
||||
|
||||
int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r) {
|
||||
int res;
|
||||
if (ttype(l) != ttype(r))
|
||||
return luaG_ordererror(L, l, r);
|
||||
else if (ttisnumber(l))
|
||||
return nvalue(l) < nvalue(r);
|
||||
else if (ttisstring(l))
|
||||
return luaV_strcmp(tsvalue(l), tsvalue(r)) < 0;
|
||||
else if (call_binTM(L, l, r, L->top, TM_LT))
|
||||
return !l_isfalse(L->top);
|
||||
else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
|
||||
return res;
|
||||
return luaG_ordererror(L, l, r);
|
||||
}
|
||||
|
||||
|
||||
static int luaV_lessequal (lua_State *L, const TObject *l, const TObject *r) {
|
||||
int res;
|
||||
if (ttype(l) != ttype(r))
|
||||
return luaG_ordererror(L, l, r);
|
||||
else if (ttisnumber(l))
|
||||
return nvalue(l) <= nvalue(r);
|
||||
else if (ttisstring(l))
|
||||
return luaV_strcmp(tsvalue(l), tsvalue(r)) <= 0;
|
||||
else if (call_binTM(L, l, r, L->top, TM_LE)) /* first try `le' */
|
||||
return !l_isfalse(L->top);
|
||||
else if (call_binTM(L, r, l, L->top, TM_LT)) /* else try `lt' */
|
||||
return l_isfalse(L->top);
|
||||
else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
|
||||
return res;
|
||||
else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */
|
||||
return !res;
|
||||
return luaG_ordererror(L, l, r);
|
||||
}
|
||||
|
||||
|
||||
int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2) {
|
||||
const TObject *tm = NULL;
|
||||
const TObject *tm;
|
||||
lua_assert(ttype(t1) == ttype(t2));
|
||||
switch (ttype(t1)) {
|
||||
case LUA_TNIL: return 1;
|
||||
@@ -264,20 +295,18 @@ int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2) {
|
||||
case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
|
||||
case LUA_TUSERDATA: {
|
||||
if (uvalue(t1) == uvalue(t2)) return 1;
|
||||
else if ((tm = fasttm(L, uvalue(t1)->uv.metatable, TM_EQ)) == NULL &&
|
||||
(tm = fasttm(L, uvalue(t2)->uv.metatable, TM_EQ)) == NULL)
|
||||
return 0; /* no TM */
|
||||
else break; /* will try TM */
|
||||
tm = get_compTM(L, uvalue(t1)->uv.metatable, uvalue(t2)->uv.metatable,
|
||||
TM_EQ);
|
||||
break; /* will try TM */
|
||||
}
|
||||
case LUA_TTABLE: {
|
||||
if (hvalue(t1) == hvalue(t2)) return 1;
|
||||
else if ((tm = fasttm(L, hvalue(t1)->metatable, TM_EQ)) == NULL &&
|
||||
(tm = fasttm(L, hvalue(t2)->metatable, TM_EQ)) == NULL)
|
||||
return 0; /* no TM */
|
||||
else break; /* will try TM */
|
||||
tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
|
||||
break; /* will try TM */
|
||||
}
|
||||
default: return gcvalue(t1) == gcvalue(t2);
|
||||
}
|
||||
if (tm == NULL) return 0; /* no TM? */
|
||||
callTMres(L, tm, t1, t2); /* call TM */
|
||||
return !l_isfalse(L->top);
|
||||
}
|
||||
@@ -328,11 +357,10 @@ static void Arith (lua_State *L, StkId ra,
|
||||
case TM_MUL: setnvalue(ra, nvalue(b) * nvalue(c)); break;
|
||||
case TM_DIV: setnvalue(ra, nvalue(b) / nvalue(c)); break;
|
||||
case TM_POW: {
|
||||
const TObject *f = luaH_getstr(hvalue(registry(L)),
|
||||
G(L)->tmname[TM_POW]);
|
||||
const TObject *f = luaH_getstr(hvalue(gt(L)), G(L)->tmname[TM_POW]);
|
||||
ptrdiff_t res = savestack(L, ra);
|
||||
if (!ttisfunction(f))
|
||||
luaG_runerror(L, "`pow' (for `^' operator) is not a function");
|
||||
luaG_runerror(L, "`__pow' (`^' operator) is not a function");
|
||||
callTMres(L, f, b, c);
|
||||
ra = restorestack(L, res); /* previous call may change stack */
|
||||
setobjs2s(ra, L->top);
|
||||
@@ -468,7 +496,7 @@ StkId luaV_execute (lua_State *L) {
|
||||
}
|
||||
case OP_NEWTABLE: {
|
||||
int b = GETARG_B(i);
|
||||
if (b > 0) b = twoto(b-1);
|
||||
b = fb2int(b);
|
||||
sethvalue(ra, luaH_new(L, b, GETARG_C(i)));
|
||||
luaC_checkGC(L);
|
||||
break;
|
||||
@@ -621,6 +649,7 @@ StkId luaV_execute (lua_State *L) {
|
||||
(L->ci - 1)->top = L->top = base+aux; /* correct top */
|
||||
lua_assert(L->ci->state & CI_SAVEDPC);
|
||||
(L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc;
|
||||
(L->ci - 1)->u.l.tailcalls++; /* one more call lost */
|
||||
(L->ci - 1)->state = CI_SAVEDPC;
|
||||
L->ci--; /* remove new frame */
|
||||
L->base = L->ci->base;
|
||||
@@ -630,7 +659,7 @@ StkId luaV_execute (lua_State *L) {
|
||||
break;
|
||||
}
|
||||
case OP_RETURN: {
|
||||
CallInfo *ci = L->ci - 1;
|
||||
CallInfo *ci = L->ci - 1; /* previous function frame */
|
||||
int b = GETARG_B(i);
|
||||
if (b != 0) L->top = ra+b-1;
|
||||
lua_assert(L->ci->state & CI_HASFRAME);
|
||||
@@ -638,12 +667,15 @@ StkId luaV_execute (lua_State *L) {
|
||||
L->ci->state = CI_SAVEDPC; /* deactivate current function */
|
||||
L->ci->u.l.savedpc = pc;
|
||||
/* previous function was running `here'? */
|
||||
if (!(ci->state & CI_CALLING))
|
||||
if (!(ci->state & CI_CALLING)) {
|
||||
lua_assert((ci->state & CI_C) || ci->u.l.pc != &pc);
|
||||
return ra; /* no: return */
|
||||
else { /* yes: continue its execution (go through) */
|
||||
}
|
||||
else { /* yes: continue its execution */
|
||||
int nresults;
|
||||
lua_assert(ttisfunction(ci->base - 1));
|
||||
lua_assert(ci->state & CI_SAVEDPC);
|
||||
lua_assert(ci->u.l.pc == &pc &&
|
||||
ttisfunction(ci->base - 1) &&
|
||||
(ci->state & CI_SAVEDPC));
|
||||
lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL);
|
||||
nresults = GETARG_C(*(ci->u.l.savedpc - 1)) - 1;
|
||||
luaD_poscall(L, nresults, ra);
|
||||
@@ -652,7 +684,7 @@ StkId luaV_execute (lua_State *L) {
|
||||
}
|
||||
}
|
||||
case OP_FORLOOP: {
|
||||
lua_Number step, index, limit;
|
||||
lua_Number step, idx, limit;
|
||||
const TObject *plimit = ra+1;
|
||||
const TObject *pstep = ra+2;
|
||||
if (!ttisnumber(ra))
|
||||
@@ -662,11 +694,11 @@ StkId luaV_execute (lua_State *L) {
|
||||
if (!tonumber(pstep, ra+2))
|
||||
luaG_runerror(L, "`for' step must be a number");
|
||||
step = nvalue(pstep);
|
||||
index = nvalue(ra) + step; /* increment index */
|
||||
idx = nvalue(ra) + step; /* increment index */
|
||||
limit = nvalue(plimit);
|
||||
if (step > 0 ? index <= limit : index >= limit) {
|
||||
if (step > 0 ? idx <= limit : idx >= limit) {
|
||||
dojump(pc, GETARG_sBx(i)); /* jump back */
|
||||
chgnvalue(ra, index); /* update index */
|
||||
chgnvalue(ra, idx); /* update index */
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -727,7 +759,7 @@ StkId luaV_execute (lua_State *L) {
|
||||
Closure *ncl;
|
||||
int nup, j;
|
||||
p = cl->p->p[GETARG_Bx(i)];
|
||||
nup = p->nupvalues;
|
||||
nup = p->nups;
|
||||
ncl = luaF_newLclosure(L, nup, &cl->g);
|
||||
ncl->l.p = p;
|
||||
for (j=0; j<nup; j++, pc++) {
|
||||
|
||||
6
lzio.c
6
lzio.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lzio.c,v 1.22 2002/10/08 18:46:08 roberto Exp roberto $
|
||||
** $Id: lzio.c,v 1.23 2002/12/04 17:38:31 roberto Exp roberto $
|
||||
** a generic input stream interface
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -22,7 +22,7 @@ int luaZ_fill (ZIO *z) {
|
||||
if (buff == NULL || size == 0) return EOZ;
|
||||
z->n = size - 1;
|
||||
z->p = buff;
|
||||
return *(z->p++);
|
||||
return char2int(*(z->p++));
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ int luaZ_lookahead (ZIO *z) {
|
||||
z->n++;
|
||||
z->p--;
|
||||
}
|
||||
return *z->p;
|
||||
return char2int(*z->p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
9
lzio.h
9
lzio.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lzio.h,v 1.13 2002/08/05 18:45:02 roberto Exp roberto $
|
||||
** $Id: lzio.h,v 1.14 2002/10/08 18:46:08 roberto Exp roberto $
|
||||
** Buffered streams
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -15,9 +15,10 @@
|
||||
|
||||
typedef struct Zio ZIO;
|
||||
|
||||
#define zgetc(z) (((z)->n--)>0 ? \
|
||||
cast(int, cast(unsigned char, *(z)->p++)) : \
|
||||
luaZ_fill(z))
|
||||
|
||||
#define char2int(c) cast(int, cast(unsigned char, (c)))
|
||||
|
||||
#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z))
|
||||
|
||||
#define zname(z) ((z)->name)
|
||||
|
||||
|
||||
28
makefile
28
makefile
@@ -1,5 +1,5 @@
|
||||
#
|
||||
## $Id: makefile,v 1.38 2002/10/25 21:38:17 roberto Exp $
|
||||
## $Id: makefile,v 1.40 2003/03/19 21:27:30 roberto Exp roberto $
|
||||
## Makefile
|
||||
## See Copyright Notice in lua.h
|
||||
#
|
||||
@@ -7,22 +7,14 @@
|
||||
|
||||
#CONFIGURATION
|
||||
|
||||
# define (undefine) USE_POPEN if your system (does not) support piped I/O
|
||||
#
|
||||
# define (undefine) _POSIX_SOURCE if your system is (not) POSIX compliant
|
||||
#
|
||||
# define LUA_NUM_TYPE if you need numbers to be different from double
|
||||
# (for instance, -DLUA_NUM_TYPE=float)
|
||||
# you may need to adapat the code, too.
|
||||
|
||||
|
||||
# DEBUG = -g -DLUA_USER_H='"ltests.h"' # -DHARDSTACKTESTS -DEXTERNMEMCHECK
|
||||
# -DEXTERNMEMCHECK -DHARDSTACKTESTS
|
||||
# DEBUG = -g -DLUA_USER_H='"ltests.h"'
|
||||
OPTIMIZE = -O2 \
|
||||
# -D'lua_number2int(i,d)=__asm__("fldl %1\nfistpl %0":"=m"(i):"m"(d))' \
|
||||
# -fomit-frame-pointer
|
||||
-D'lua_number2int(i,d)=__asm__("fldl %1\nfistpl %0":"=m"(i):"m"(d))' \
|
||||
# -fomit-frame-pointer
|
||||
|
||||
|
||||
CONFIG = -D_POSIX_SOURCE $(DEBUG) $(OPTIMIZE) # -DUSE_POPEN
|
||||
CONFIG = $(DEBUG) $(OPTIMIZE) -DLUA_COMPATUPSYNTAX -DUSE_TMPNAME -DUSE_DLOPEN
|
||||
|
||||
|
||||
# Compilation parameters
|
||||
@@ -39,7 +31,7 @@ CWARNS = -Wall -pedantic \
|
||||
# -Wtraditional \
|
||||
# -Wcast-qual
|
||||
|
||||
CFLAGS = $(CONFIG) $(CWARNS) -ansi
|
||||
CFLAGS = $(CONFIG) $(CWARNS) # -ansi
|
||||
|
||||
|
||||
# To make early versions
|
||||
@@ -80,11 +72,12 @@ LIBOBJS = \
|
||||
lmathlib.o \
|
||||
liolib.o \
|
||||
lstrlib.o \
|
||||
ldblib.o
|
||||
ldblib.o \
|
||||
loadlib.o
|
||||
|
||||
|
||||
lua : lua.o liblua.a liblualib.a
|
||||
$(CC) $(CFLAGS) -o $@ lua.o -L. -llua -llualib -lm
|
||||
$(CC) $(CFLAGS) -o $@ lua.o -Wl,-E -L. -llua -llualib -lm -ldl
|
||||
|
||||
liblua.a : $(LUAOBJS)
|
||||
$(AR) $(ARFLAGS) $@ $?
|
||||
@@ -137,6 +130,7 @@ lmem.o: lmem.c lua.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h \
|
||||
ldo.h lmem.h
|
||||
lobject.o: lobject.c lua.h ldo.h lobject.h llimits.h lstate.h ltm.h \
|
||||
lzio.h lmem.h lstring.h lvm.h
|
||||
loadlib.o: loadlib.c lua.h lauxlib.h lualib.h
|
||||
lopcodes.o: lopcodes.c lua.h lobject.h llimits.h lopcodes.h
|
||||
lparser.o: lparser.c lua.h lcode.h llex.h lobject.h llimits.h lzio.h \
|
||||
lopcodes.h lparser.h ltable.h ldebug.h lstate.h ltm.h lfunc.h lmem.h \
|
||||
|
||||
4487
manual.tex
4487
manual.tex
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user