macros LUA_ENTRY/LUA_EXIT to control exclusive access to Lua core

This commit is contained in:
Roberto Ierusalimschy
2001-01-24 13:45:33 -02:00
parent 6fda6a5302
commit 71ae4801d6
11 changed files with 420 additions and 149 deletions

321
lapi.c
View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lapi.c,v 1.117 2001/01/18 15:59:09 roberto Exp roberto $ ** $Id: lapi.c,v 1.118 2001/01/19 13:20:30 roberto Exp roberto $
** Lua API ** Lua API
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -54,7 +54,11 @@ void luaA_pushobject (lua_State *L, const TObject *o) {
} }
LUA_API int lua_stackspace (lua_State *L) { LUA_API int lua_stackspace (lua_State *L) {
return (L->stack_last - L->top); int i;
LUA_ENTRY;
i = (L->stack_last - L->top);
LUA_EXIT;
return i;
} }
@@ -65,36 +69,50 @@ LUA_API int lua_stackspace (lua_State *L) {
LUA_API int lua_gettop (lua_State *L) { LUA_API int lua_gettop (lua_State *L) {
return (L->top - L->Cbase); int i;
LUA_ENTRY;
i = (L->top - L->Cbase);
LUA_EXIT;
return i;
} }
LUA_API void lua_settop (lua_State *L, int index) { LUA_API void lua_settop (lua_State *L, int index) {
LUA_ENTRY;
if (index >= 0) if (index >= 0)
luaD_adjusttop(L, L->Cbase, index); luaD_adjusttop(L, L->Cbase, index);
else else
L->top = L->top+index+1; /* index is negative */ L->top = L->top+index+1; /* index is negative */
LUA_EXIT;
} }
LUA_API void lua_remove (lua_State *L, int index) { LUA_API void lua_remove (lua_State *L, int index) {
StkId p = luaA_index(L, index); StkId p;
LUA_ENTRY;
p = luaA_index(L, index);
while (++p < L->top) setobj(p-1, p); while (++p < L->top) setobj(p-1, p);
L->top--; L->top--;
LUA_EXIT;
} }
LUA_API void lua_insert (lua_State *L, int index) { LUA_API void lua_insert (lua_State *L, int index) {
StkId p = luaA_index(L, index); StkId p;
StkId q; StkId q;
LUA_ENTRY;
p = luaA_index(L, index);
for (q = L->top; q>p; q--) setobj(q, q-1); for (q = L->top; q>p; q--) setobj(q, q-1);
setobj(p, L->top); setobj(p, L->top);
LUA_EXIT;
} }
LUA_API void lua_pushvalue (lua_State *L, int index) { LUA_API void lua_pushvalue (lua_State *L, int index) {
LUA_ENTRY;
setobj(L->top, luaA_index(L, index)); setobj(L->top, luaA_index(L, index));
api_incr_top(L); api_incr_top(L);
LUA_EXIT;
} }
@@ -105,24 +123,43 @@ LUA_API void lua_pushvalue (lua_State *L, int index) {
LUA_API int lua_type (lua_State *L, int index) { LUA_API int lua_type (lua_State *L, int index) {
StkId o = luaA_indexAcceptable(L, index); StkId o;
return (o == NULL) ? LUA_TNONE : ttype(o); int i;
LUA_ENTRY;
o = luaA_indexAcceptable(L, index);
i = (o == NULL) ? LUA_TNONE : ttype(o);
LUA_EXIT;
return i;
} }
LUA_API const char *lua_typename (lua_State *L, int t) { LUA_API const char *lua_typename (lua_State *L, int t) {
const char *s;
LUA_ENTRY;
UNUSED(L); UNUSED(L);
return (t == LUA_TNONE) ? "no value" : luaO_typenames[t]; s = (t == LUA_TNONE) ? "no value" : luaO_typenames[t];
LUA_EXIT;
return s;
} }
LUA_API int lua_iscfunction (lua_State *L, int index) { LUA_API int lua_iscfunction (lua_State *L, int index) {
StkId o = luaA_indexAcceptable(L, index); StkId o;
return (o == NULL) ? 0 : iscfunction(o); int i;
LUA_ENTRY;
o = luaA_indexAcceptable(L, index);
i = (o == NULL) ? 0 : iscfunction(o);
LUA_EXIT;
return i;
} }
LUA_API int lua_isnumber (lua_State *L, int index) { LUA_API int lua_isnumber (lua_State *L, int index) {
TObject *o = luaA_indexAcceptable(L, index); TObject *o;
return (o == NULL) ? 0 : (tonumber(o) == 0); int i;
LUA_ENTRY;
o = luaA_indexAcceptable(L, index);
i = (o == NULL) ? 0 : (tonumber(o) == 0);
LUA_EXIT;
return i;
} }
LUA_API int lua_isstring (lua_State *L, int index) { LUA_API int lua_isstring (lua_State *L, int index) {
@@ -132,62 +169,113 @@ LUA_API int lua_isstring (lua_State *L, int index) {
LUA_API int lua_tag (lua_State *L, int index) { LUA_API int lua_tag (lua_State *L, int index) {
StkId o = luaA_indexAcceptable(L, index); StkId o;
return (o == NULL) ? LUA_NOTAG : luaT_tag(o); int i;
LUA_ENTRY;
o = luaA_indexAcceptable(L, index);
i = (o == NULL) ? LUA_NOTAG : luaT_tag(o);
LUA_EXIT;
return i;
} }
LUA_API int lua_equal (lua_State *L, int index1, int index2) { LUA_API int lua_equal (lua_State *L, int index1, int index2) {
StkId o1 = luaA_indexAcceptable(L, index1); StkId o1, o2;
StkId o2 = luaA_indexAcceptable(L, index2); int i;
if (o1 == NULL || o2 == NULL) return 0; /* index out-of-range */ LUA_ENTRY;
else return luaO_equalObj(o1, o2); o1 = luaA_indexAcceptable(L, index1);
o2 = luaA_indexAcceptable(L, index2);
i = (o1 == NULL || o2 == NULL) ? 0 /* index out-of-range */
: luaO_equalObj(o1, o2);
LUA_EXIT;
return i;
} }
LUA_API int lua_lessthan (lua_State *L, int index1, int index2) { LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
StkId o1 = luaA_indexAcceptable(L, index1); StkId o1, o2;
StkId o2 = luaA_indexAcceptable(L, index2); int i;
if (o1 == NULL || o2 == NULL) return 0; /* index out-of-range */ LUA_ENTRY;
else return luaV_lessthan(L, o1, o2, L->top); o1 = luaA_indexAcceptable(L, index1);
o2 = luaA_indexAcceptable(L, index2);
i = (o1 == NULL || o2 == NULL) ? 0 /* index out-of-range */
: luaV_lessthan(L, o1, o2, L->top);
LUA_EXIT;
return i;
} }
LUA_API lua_Number lua_tonumber (lua_State *L, int index) { LUA_API lua_Number lua_tonumber (lua_State *L, int index) {
StkId o = luaA_indexAcceptable(L, index); StkId o;
return (o == NULL || tonumber(o)) ? 0 : nvalue(o); lua_Number n;
LUA_ENTRY;
o = luaA_indexAcceptable(L, index);
n = (o == NULL || tonumber(o)) ? 0 : nvalue(o);
LUA_EXIT;
return n;
} }
LUA_API const char *lua_tostring (lua_State *L, int index) { LUA_API const char *lua_tostring (lua_State *L, int index) {
StkId o = luaA_indexAcceptable(L, index); StkId o;
return (o == NULL || tostring(L, o)) ? NULL : svalue(o); const char *s;
LUA_ENTRY;
o = luaA_indexAcceptable(L, index);
s = (o == NULL || tostring(L, o)) ? NULL : svalue(o);
LUA_EXIT;
return s;
} }
LUA_API size_t lua_strlen (lua_State *L, int index) { LUA_API size_t lua_strlen (lua_State *L, int index) {
StkId o = luaA_indexAcceptable(L, index); StkId o;
return (o == NULL || tostring(L, o)) ? 0 : tsvalue(o)->len; size_t l;
LUA_ENTRY;
o = luaA_indexAcceptable(L, index);
l = (o == NULL || tostring(L, o)) ? 0 : tsvalue(o)->len;
LUA_EXIT;
return l;
} }
LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index) { LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index) {
StkId o = luaA_indexAcceptable(L, index); StkId o;
return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->f.c; lua_CFunction f;
LUA_ENTRY;
o = luaA_indexAcceptable(L, index);
f = (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->f.c;
LUA_EXIT;
return f;
} }
LUA_API void *lua_touserdata (lua_State *L, int index) { LUA_API void *lua_touserdata (lua_State *L, int index) {
StkId o = luaA_indexAcceptable(L, index); StkId o;
return (o == NULL || ttype(o) != LUA_TUSERDATA) ? NULL : void *p;
LUA_ENTRY;
o = luaA_indexAcceptable(L, index);
p = (o == NULL || ttype(o) != LUA_TUSERDATA) ? NULL :
tsvalue(o)->u.d.value; tsvalue(o)->u.d.value;
LUA_EXIT;
return p;
} }
LUA_API const void *lua_topointer (lua_State *L, int index) { LUA_API const void *lua_topointer (lua_State *L, int index) {
StkId o = luaA_indexAcceptable(L, index); StkId o;
if (o == NULL) return NULL; const void *p;
switch (ttype(o)) { LUA_ENTRY;
case LUA_TTABLE: o = luaA_indexAcceptable(L, index);
return hvalue(o); if (o == NULL) p = NULL;
case LUA_TFUNCTION: else {
return clvalue(o); switch (ttype(o)) {
default: return NULL; case LUA_TTABLE:
p = hvalue(o);
break;
case LUA_TFUNCTION:
p = clvalue(o);
break;
default:
p = NULL;
break;
}
} }
LUA_EXIT;
return p;
} }
@@ -198,20 +286,26 @@ LUA_API const void *lua_topointer (lua_State *L, int index) {
LUA_API void lua_pushnil (lua_State *L) { LUA_API void lua_pushnil (lua_State *L) {
LUA_ENTRY;
setnilvalue(L->top); setnilvalue(L->top);
api_incr_top(L); api_incr_top(L);
LUA_EXIT;
} }
LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
LUA_ENTRY;
setnvalue(L->top, n); setnvalue(L->top, n);
api_incr_top(L); api_incr_top(L);
LUA_EXIT;
} }
LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) { LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
LUA_ENTRY;
setsvalue(L->top, luaS_newlstr(L, s, len)); setsvalue(L->top, luaS_newlstr(L, s, len));
api_incr_top(L); api_incr_top(L);
LUA_EXIT;
} }
@@ -224,16 +318,20 @@ LUA_API void lua_pushstring (lua_State *L, const char *s) {
LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
LUA_ENTRY;
luaV_Cclosure(L, fn, n); luaV_Cclosure(L, fn, n);
LUA_EXIT;
} }
LUA_API void lua_pushusertag (lua_State *L, void *u, int tag) { LUA_API void lua_pushusertag (lua_State *L, void *u, int tag) {
LUA_ENTRY;
/* ORDER LUA_T */ /* ORDER LUA_T */
if (!(tag == LUA_ANYTAG || tag == LUA_TUSERDATA || validtag(G(L), tag))) if (!(tag == LUA_ANYTAG || tag == LUA_TUSERDATA || validtag(G(L), tag)))
luaO_verror(L, "invalid tag for a userdata (%d)", tag); luaO_verror(L, "invalid tag for a userdata (%d)", tag);
setuvalue(L->top, luaS_createudata(L, u, tag)); setuvalue(L->top, luaS_createudata(L, u, tag));
api_incr_top(L); api_incr_top(L);
LUA_EXIT;
} }
@@ -244,60 +342,80 @@ LUA_API void lua_pushusertag (lua_State *L, void *u, int tag) {
LUA_API void lua_getglobal (lua_State *L, const char *name) { LUA_API void lua_getglobal (lua_State *L, const char *name) {
StkId top = L->top; StkId top;
LUA_ENTRY;
top = L->top;
setobj(top, luaV_getglobal(L, luaS_new(L, name))); setobj(top, luaV_getglobal(L, luaS_new(L, name)));
L->top = top; L->top = top;
api_incr_top(L); api_incr_top(L);
LUA_EXIT;
} }
LUA_API void lua_gettable (lua_State *L, int index) { LUA_API void lua_gettable (lua_State *L, int index) {
StkId t = Index(L, index); StkId t, top;
StkId top = L->top; LUA_ENTRY;
t = Index(L, index);
top = L->top;
setobj(top-1, luaV_gettable(L, t)); setobj(top-1, luaV_gettable(L, t));
L->top = top; /* tag method may change top */ L->top = top; /* tag method may change top */
LUA_EXIT;
} }
LUA_API void lua_rawget (lua_State *L, int index) { LUA_API void lua_rawget (lua_State *L, int index) {
StkId t = Index(L, index); StkId t;
LUA_ENTRY;
t = Index(L, index);
lua_assert(ttype(t) == LUA_TTABLE); lua_assert(ttype(t) == LUA_TTABLE);
setobj(L->top - 1, luaH_get(hvalue(t), L->top - 1)); setobj(L->top - 1, luaH_get(hvalue(t), L->top - 1));
LUA_EXIT;
} }
LUA_API void lua_rawgeti (lua_State *L, int index, int n) { LUA_API void lua_rawgeti (lua_State *L, int index, int n) {
StkId o = Index(L, index); StkId o;
LUA_ENTRY;
o = Index(L, index);
lua_assert(ttype(o) == LUA_TTABLE); lua_assert(ttype(o) == LUA_TTABLE);
setobj(L->top, luaH_getnum(hvalue(o), n)); setobj(L->top, luaH_getnum(hvalue(o), n));
api_incr_top(L); api_incr_top(L);
LUA_EXIT;
} }
LUA_API void lua_getglobals (lua_State *L) { LUA_API void lua_getglobals (lua_State *L) {
LUA_ENTRY;
sethvalue(L->top, L->gt); sethvalue(L->top, L->gt);
api_incr_top(L); api_incr_top(L);
LUA_EXIT;
} }
LUA_API int lua_getref (lua_State *L, int ref) { LUA_API int lua_getref (lua_State *L, int ref) {
int status = 1;
LUA_ENTRY;
if (ref == LUA_REFNIL) { if (ref == LUA_REFNIL) {
setnilvalue(L->top); setnilvalue(L->top);
api_incr_top(L);
} }
else if (0 <= ref && ref < G(L)->nref && else if (0 <= ref && ref < G(L)->nref &&
(G(L)->refArray[ref].st == LOCK || G(L)->refArray[ref].st == HOLD)) { (G(L)->refArray[ref].st == LOCK || G(L)->refArray[ref].st == HOLD)) {
setobj(L->top, &G(L)->refArray[ref].o); setobj(L->top, &G(L)->refArray[ref].o);
api_incr_top(L);
} }
else else
return 0; status = 0;
api_incr_top(L); LUA_EXIT;
return 1; return status;
} }
LUA_API void lua_newtable (lua_State *L) { LUA_API void lua_newtable (lua_State *L) {
LUA_ENTRY;
sethvalue(L->top, luaH_new(L, 0)); sethvalue(L->top, luaH_new(L, 0));
api_incr_top(L); api_incr_top(L);
LUA_EXIT;
} }
@@ -308,45 +426,61 @@ LUA_API void lua_newtable (lua_State *L) {
LUA_API void lua_setglobal (lua_State *L, const char *name) { LUA_API void lua_setglobal (lua_State *L, const char *name) {
StkId top = L->top; StkId top;
LUA_ENTRY;
top = L->top;
luaV_setglobal(L, luaS_new(L, name)); luaV_setglobal(L, luaS_new(L, name));
L->top = top-1; /* remove element from the top */ L->top = top-1; /* remove element from the top */
LUA_EXIT;
} }
LUA_API void lua_settable (lua_State *L, int index) { LUA_API void lua_settable (lua_State *L, int index) {
StkId t = Index(L, index); StkId t, top;
StkId top = L->top; LUA_ENTRY;
t = Index(L, index);
top = L->top;
luaV_settable(L, t, top-2); luaV_settable(L, t, top-2);
L->top = top-2; /* pop index and value */ L->top = top-2; /* pop index and value */
LUA_EXIT;
} }
LUA_API void lua_rawset (lua_State *L, int index) { LUA_API void lua_rawset (lua_State *L, int index) {
StkId t = Index(L, index); StkId t;
LUA_ENTRY;
t = Index(L, index);
lua_assert(ttype(t) == LUA_TTABLE); lua_assert(ttype(t) == LUA_TTABLE);
setobj(luaH_set(L, hvalue(t), L->top-2), (L->top-1)); setobj(luaH_set(L, hvalue(t), L->top-2), (L->top-1));
L->top -= 2; L->top -= 2;
LUA_EXIT;
} }
LUA_API void lua_rawseti (lua_State *L, int index, int n) { LUA_API void lua_rawseti (lua_State *L, int index, int n) {
StkId o = Index(L, index); StkId o;
LUA_ENTRY;
o = Index(L, index);
lua_assert(ttype(o) == LUA_TTABLE); lua_assert(ttype(o) == LUA_TTABLE);
setobj(luaH_setnum(L, hvalue(o), n), (L->top-1)); setobj(luaH_setnum(L, hvalue(o), n), (L->top-1));
L->top--; L->top--;
LUA_EXIT;
} }
LUA_API void lua_setglobals (lua_State *L) { LUA_API void lua_setglobals (lua_State *L) {
StkId newtable = --L->top; StkId newtable;
LUA_ENTRY;
newtable = --L->top;
lua_assert(ttype(newtable) == LUA_TTABLE); lua_assert(ttype(newtable) == LUA_TTABLE);
L->gt = hvalue(newtable); L->gt = hvalue(newtable);
LUA_EXIT;
} }
LUA_API int lua_ref (lua_State *L, int lock) { LUA_API int lua_ref (lua_State *L, int lock) {
int ref; int ref;
LUA_ENTRY;
if (ttype(L->top-1) == LUA_TNIL) if (ttype(L->top-1) == LUA_TNIL)
ref = LUA_REFNIL; ref = LUA_REFNIL;
else { else {
@@ -363,6 +497,7 @@ LUA_API int lua_ref (lua_State *L, int lock) {
G(L)->refArray[ref].st = lock ? LOCK : HOLD; G(L)->refArray[ref].st = lock ? LOCK : HOLD;
} }
L->top--; L->top--;
LUA_EXIT;
return ref; return ref;
} }
@@ -373,7 +508,9 @@ LUA_API int lua_ref (lua_State *L, int lock) {
*/ */
LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults) { LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults) {
LUA_ENTRY;
luaD_call(L, L->top-(nargs+1), nresults); luaD_call(L, L->top-(nargs+1), nresults);
LUA_EXIT;
} }
@@ -386,19 +523,29 @@ LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults) {
#define GCunscale(x) ((mem_int)(x)<<10) #define GCunscale(x) ((mem_int)(x)<<10)
LUA_API int lua_getgcthreshold (lua_State *L) { LUA_API int lua_getgcthreshold (lua_State *L) {
return GCscale(G(L)->GCthreshold); int threshold;
LUA_ENTRY;
threshold = GCscale(G(L)->GCthreshold);
LUA_EXIT;
return threshold;
} }
LUA_API int lua_getgccount (lua_State *L) { LUA_API int lua_getgccount (lua_State *L) {
return GCscale(G(L)->nblocks); int count;
LUA_ENTRY;
count = GCscale(G(L)->nblocks);
LUA_EXIT;
return count;
} }
LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) { LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
LUA_ENTRY;
if (newthreshold > GCscale(ULONG_MAX)) if (newthreshold > GCscale(ULONG_MAX))
G(L)->GCthreshold = ULONG_MAX; G(L)->GCthreshold = ULONG_MAX;
else else
G(L)->GCthreshold = GCunscale(newthreshold); G(L)->GCthreshold = GCunscale(newthreshold);
luaC_checkGC(L); luaC_checkGC(L);
LUA_EXIT;
} }
@@ -407,6 +554,7 @@ LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
*/ */
LUA_API void lua_settag (lua_State *L, int tag) { LUA_API void lua_settag (lua_State *L, int tag) {
LUA_ENTRY;
luaT_realtag(L, tag); luaT_realtag(L, tag);
switch (ttype(L->top-1)) { switch (ttype(L->top-1)) {
case LUA_TTABLE: case LUA_TTABLE:
@@ -419,69 +567,98 @@ LUA_API void lua_settag (lua_State *L, int tag) {
luaO_verror(L, "cannot change the tag of a %.20s", luaO_verror(L, "cannot change the tag of a %.20s",
luaO_typename(L->top-1)); luaO_typename(L->top-1));
} }
LUA_EXIT;
}
LUA_API void lua_error (lua_State *L, const char *s) {
LUA_ENTRY;
luaD_error(L, s);
LUA_EXIT;
} }
LUA_API void lua_unref (lua_State *L, int ref) { LUA_API void lua_unref (lua_State *L, int ref) {
LUA_ENTRY;
if (ref >= 0) { if (ref >= 0) {
lua_assert(ref < G(L)->nref && G(L)->refArray[ref].st < 0); lua_assert(ref < G(L)->nref && G(L)->refArray[ref].st < 0);
G(L)->refArray[ref].st = G(L)->refFree; G(L)->refArray[ref].st = G(L)->refFree;
G(L)->refFree = ref; G(L)->refFree = ref;
} }
LUA_EXIT;
} }
LUA_API int lua_next (lua_State *L, int index) { LUA_API int lua_next (lua_State *L, int index) {
StkId t = luaA_index(L, index); StkId t;
Node *n; Node *n;
int more;
LUA_ENTRY;
t = luaA_index(L, index);
lua_assert(ttype(t) == LUA_TTABLE); lua_assert(ttype(t) == LUA_TTABLE);
n = luaH_next(L, hvalue(t), luaA_index(L, -1)); n = luaH_next(L, hvalue(t), luaA_index(L, -1));
if (n) { if (n) {
setobj(L->top-1, key(n)); setobj(L->top-1, key(n));
setobj(L->top, val(n)); setobj(L->top, val(n));
api_incr_top(L); api_incr_top(L);
return 1; more = 1;
} }
else { /* no more elements */ else { /* no more elements */
L->top -= 1; /* remove key */ L->top -= 1; /* remove key */
return 0; more = 0;
} }
LUA_EXIT;
return more;
} }
LUA_API int lua_getn (lua_State *L, int index) { LUA_API int lua_getn (lua_State *L, int index) {
Hash *h = hvalue(luaA_index(L, index)); Hash *h;
const TObject *value = luaH_getstr(h, luaS_newliteral(L, "n")); /* = h.n */ const TObject *value;
int n;
LUA_ENTRY;
h = hvalue(luaA_index(L, index));
value = luaH_getstr(h, luaS_newliteral(L, "n")); /* = h.n */
if (ttype(value) == LUA_TNUMBER) if (ttype(value) == LUA_TNUMBER)
return (int)nvalue(value); n = (int)nvalue(value);
else { else {
lua_Number max = 0; lua_Number max = 0;
int i = h->size; int i = h->size;
Node *n = h->node; Node *nd = h->node;
while (i--) { while (i--) {
if (ttype(key(n)) == LUA_TNUMBER && if (ttype(key(nd)) == LUA_TNUMBER &&
ttype(val(n)) != LUA_TNIL && ttype(val(nd)) != LUA_TNIL &&
nvalue(key(n)) > max) nvalue(key(nd)) > max)
max = nvalue(key(n)); max = nvalue(key(nd));
n++; nd++;
} }
return (int)max; n = (int)max;
} }
LUA_EXIT;
return n;
} }
LUA_API void lua_concat (lua_State *L, int n) { LUA_API void lua_concat (lua_State *L, int n) {
StkId top = L->top; StkId top;
LUA_ENTRY;
top = L->top;
luaV_strconc(L, n, top); luaV_strconc(L, n, top);
L->top = top-(n-1); L->top = top-(n-1);
luaC_checkGC(L); luaC_checkGC(L);
LUA_EXIT;
} }
LUA_API void *lua_newuserdata (lua_State *L, size_t size) { LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
TString *ts = luaS_newudata(L, size, NULL); TString *ts;
void *p;
LUA_ENTRY;
ts = luaS_newudata(L, size, NULL);
setuvalue(L->top, ts); setuvalue(L->top, ts);
api_incr_top(L); api_incr_top(L);
return ts->u.d.value; p = ts->u.d.value;
LUA_EXIT;
return p;
} }

View File

@@ -1,5 +1,5 @@
/* /*
** $Id: ldebug.c,v 1.53 2001/01/18 15:59:09 roberto Exp roberto $ ** $Id: ldebug.c,v 1.54 2001/01/19 13:20:30 roberto Exp roberto $
** Debug Interface ** Debug Interface
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -41,15 +41,21 @@ static int isLmark (StkId o) {
LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func) { LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func) {
lua_Hook oldhook = L->callhook; lua_Hook oldhook;
LUA_ENTRY;
oldhook = L->callhook;
L->callhook = func; L->callhook = func;
LUA_EXIT;
return oldhook; return oldhook;
} }
LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func) { LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func) {
lua_Hook oldhook = L->linehook; lua_Hook oldhook;
LUA_ENTRY;
oldhook = L->linehook;
L->linehook = func; L->linehook = func;
LUA_EXIT;
return oldhook; return oldhook;
} }
@@ -68,12 +74,17 @@ static StkId aux_stackedfunction (lua_State *L, int level, StkId top) {
LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
StkId f = aux_stackedfunction(L, level, L->top); StkId f;
if (f == NULL) return 0; /* there is no such level */ int status;
LUA_ENTRY;
f = aux_stackedfunction(L, level, L->top);
if (f == NULL) status = 0; /* there is no such level */
else { else {
ar->_func = f; ar->_func = f;
return 1; status = 1;
} }
LUA_EXIT;
return status;
} }
@@ -149,25 +160,39 @@ static Proto *getluaproto (StkId f) {
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
const char *name; const char *name;
StkId f = ar->_func; StkId f;
Proto *fp = getluaproto(f); Proto *fp;
if (!fp) return NULL; /* `f' is not a Lua function? */ LUA_ENTRY;
name = luaF_getlocalname(fp, n, currentpc(f)); name = NULL;
if (!name) return NULL; f = ar->_func;
luaA_pushobject(L, (f+1)+(n-1)); /* push value */ fp = getluaproto(f);
if (fp) { /* `f' is a Lua function? */
name = luaF_getlocalname(fp, n, currentpc(f));
if (name)
luaA_pushobject(L, (f+1)+(n-1)); /* push value */
}
LUA_EXIT;
return name; return name;
} }
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
const char *name; const char *name;
StkId f = ar->_func; StkId f;
Proto *fp = getluaproto(f); Proto *fp;
LUA_ENTRY;
name = NULL;
f = ar->_func;
fp = getluaproto(f);
L->top--; /* pop new value */ L->top--; /* pop new value */
if (!fp) return NULL; /* `f' is not a Lua function? */ if (fp) { /* `f' is a Lua function? */
name = luaF_getlocalname(fp, n, currentpc(f)); name = luaF_getlocalname(fp, n, currentpc(f));
if (!name || name[0] == '(') return NULL; /* `(' starts private locals */ if (!name || name[0] == '(') /* `(' starts private locals */
setobj((f+1)+(n-1), L->top); name = NULL;
else
setobj((f+1)+(n-1), L->top);
}
LUA_EXIT;
return name; return name;
} }
@@ -189,7 +214,7 @@ static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) {
cl = infovalue(func)->func; cl = infovalue(func)->func;
break; break;
default: default:
lua_error(L, "value for `lua_getinfo' is not a function"); luaD_error(L, "value for `lua_getinfo' is not a function");
} }
if (cl->isC) { if (cl->isC) {
ar->source = "=C"; ar->source = "=C";
@@ -245,7 +270,10 @@ static void getname (lua_State *L, StkId f, lua_Debug *ar) {
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
StkId func; StkId func;
int isactive = (*what != '>'); int isactive;
int status = 1;
LUA_ENTRY;
isactive = (*what != '>');
if (isactive) if (isactive)
func = ar->_func; func = ar->_func;
else { else {
@@ -277,11 +305,12 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
incr_top; /* push function */ incr_top; /* push function */
break; break;
} }
default: return 0; /* invalid option */ default: status = 0; /* invalid option */
} }
} }
if (!isactive) L->top--; /* pop function */ if (!isactive) L->top--; /* pop function */
return 1; LUA_EXIT;
return status;
} }

32
ldo.c
View File

@@ -1,5 +1,5 @@
/* /*
** $Id: ldo.c,v 1.114 2001/01/18 15:59:09 roberto Exp roberto $ ** $Id: ldo.c,v 1.115 2001/01/19 13:20:30 roberto Exp roberto $
** Stack and Call structure of Lua ** Stack and Call structure of Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -56,7 +56,7 @@ void luaD_checkstack (lua_State *L, int n) {
else { else {
L->stack_last += EXTRA_STACK; /* to be used by error message */ L->stack_last += EXTRA_STACK; /* to be used by error message */
lua_assert(L->stack_last == L->stack+L->stacksize-1); lua_assert(L->stack_last == L->stack+L->stacksize-1);
lua_error(L, "stack overflow"); luaD_error(L, "stack overflow");
} }
} }
} }
@@ -94,7 +94,9 @@ static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) {
StkId old_top = L->Cbase = L->top; StkId old_top = L->Cbase = L->top;
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
L->allowhooks = 0; /* cannot call hooks inside a hook */ L->allowhooks = 0; /* cannot call hooks inside a hook */
LUA_EXIT;
(*hook)(L, ar); (*hook)(L, ar);
LUA_ENTRY;
lua_assert(L->allowhooks == 0); lua_assert(L->allowhooks == 0);
L->allowhooks = 1; L->allowhooks = 1;
L->top = old_top; L->top = old_top;
@@ -133,7 +135,9 @@ static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) {
luaD_checkstack(L, nup+LUA_MINSTACK); /* ensure minimum stack size */ luaD_checkstack(L, nup+LUA_MINSTACK); /* ensure minimum stack size */
for (n=0; n<nup; n++) /* copy upvalues as extra arguments */ for (n=0; n<nup; n++) /* copy upvalues as extra arguments */
setobj(L->top++, &cl->upvalue[n]); setobj(L->top++, &cl->upvalue[n]);
LUA_EXIT;
n = (*cl->f.c)(L); /* do the actual call */ n = (*cl->f.c)(L); /* do the actual call */
LUA_ENTRY;
L->Cbase = old_Cbase; /* restore old C base */ L->Cbase = old_Cbase; /* restore old C base */
return L->top - n; /* return index of first result */ return L->top - n; /* return index of first result */
} }
@@ -212,13 +216,16 @@ static void f_call (lua_State *L, void *ud) {
LUA_API int lua_call (lua_State *L, int nargs, int nresults) { LUA_API int lua_call (lua_State *L, int nargs, int nresults) {
StkId func = L->top - (nargs+1); /* function to be called */ StkId func;
struct CallS c; struct CallS c;
int status; int status;
LUA_ENTRY;
func = L->top - (nargs+1); /* function to be called */
c.func = func; c.nresults = nresults; c.func = func; c.nresults = nresults;
status = luaD_runprotected(L, f_call, &c); status = luaD_runprotected(L, f_call, &c);
if (status != 0) /* an error occurred? */ if (status != 0) /* an error occurred? */
L->top = func; /* remove parameters from the stack */ L->top = func; /* remove parameters from the stack */
LUA_EXIT;
return status; return status;
} }
@@ -242,6 +249,7 @@ static int protectedparser (lua_State *L, ZIO *z, int bin) {
struct ParserS p; struct ParserS p;
mem_int old_blocks; mem_int old_blocks;
int status; int status;
LUA_ENTRY;
p.z = z; p.bin = bin; p.z = z; p.bin = bin;
luaC_checkGC(L); luaC_checkGC(L);
old_blocks = G(L)->nblocks; old_blocks = G(L)->nblocks;
@@ -253,6 +261,7 @@ static int protectedparser (lua_State *L, ZIO *z, int bin) {
} }
else if (status == LUA_ERRRUN) /* an error occurred: correct error code */ else if (status == LUA_ERRRUN) /* an error occurred: correct error code */
status = LUA_ERRSYNTAX; status = LUA_ERRSYNTAX;
LUA_EXIT;
return status; return status;
} }
@@ -275,9 +284,9 @@ static int parse_file (lua_State *L, const char *filename) {
lua_pushstring(L, (filename == NULL) ? "(stdin)" : filename); lua_pushstring(L, (filename == NULL) ? "(stdin)" : filename);
lua_concat(L, 2); lua_concat(L, 2);
filename = lua_tostring(L, -1); /* filename = '@'..filename */ filename = lua_tostring(L, -1); /* filename = '@'..filename */
lua_pop(L, 1); /* OK: there is no GC during parser */
luaZ_Fopen(&z, f, filename); luaZ_Fopen(&z, f, filename);
status = protectedparser(L, &z, bin); status = protectedparser(L, &z, bin);
lua_remove(L, -2); /* remove filename */
if (f != stdin) if (f != stdin)
fclose(f); fclose(f);
return status; return status;
@@ -285,7 +294,8 @@ static int parse_file (lua_State *L, const char *filename) {
LUA_API int lua_dofile (lua_State *L, const char *filename) { LUA_API int lua_dofile (lua_State *L, const char *filename) {
int status = parse_file(L, filename); int status;
status = parse_file(L, filename);
if (status == 0) /* parse OK? */ if (status == 0) /* parse OK? */
status = lua_call(L, 0, LUA_MULTRET); /* call main */ status = lua_call(L, 0, LUA_MULTRET); /* call main */
return status; return status;
@@ -295,14 +305,17 @@ LUA_API int lua_dofile (lua_State *L, const char *filename) {
static int parse_buffer (lua_State *L, const char *buff, size_t size, static int parse_buffer (lua_State *L, const char *buff, size_t size,
const char *name) { const char *name) {
ZIO z; ZIO z;
int status;
if (!name) name = "?"; if (!name) name = "?";
luaZ_mopen(&z, buff, size, name); luaZ_mopen(&z, buff, size, name);
return protectedparser(L, &z, buff[0]==ID_CHUNK); status = protectedparser(L, &z, buff[0]==ID_CHUNK);
return status;
} }
LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, const char *name) { LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, const char *name) {
int status = parse_buffer(L, buff, size, name); int status;
status = parse_buffer(L, buff, size, name);
if (status == 0) /* parse OK? */ if (status == 0) /* parse OK? */
status = lua_call(L, 0, LUA_MULTRET); /* call main */ status = lua_call(L, 0, LUA_MULTRET); /* call main */
return status; return status;
@@ -333,7 +346,8 @@ static void message (lua_State *L, const char *s) {
if (ttype(em) == LUA_TFUNCTION) { if (ttype(em) == LUA_TFUNCTION) {
setobj(L->top, em); setobj(L->top, em);
incr_top; incr_top;
lua_pushstring(L, s); setsvalue(L->top, luaS_new(L, s));
incr_top;
luaD_call(L, L->top-2, 0); luaD_call(L, L->top-2, 0);
} }
} }
@@ -342,7 +356,7 @@ static void message (lua_State *L, const char *s) {
/* /*
** Reports an error, and jumps up to the available recovery label ** Reports an error, and jumps up to the available recovery label
*/ */
LUA_API void lua_error (lua_State *L, const char *s) { void luaD_error (lua_State *L, const char *s) {
if (s) message(L, s); if (s) message(L, s);
luaD_breakrun(L, LUA_ERRRUN); luaD_breakrun(L, LUA_ERRRUN);
} }

3
ldo.h
View File

@@ -1,5 +1,5 @@
/* /*
** $Id: ldo.h,v 1.27 2000/10/05 13:00:17 roberto Exp roberto $ ** $Id: ldo.h,v 1.28 2000/10/06 12:45:25 roberto Exp roberto $
** Stack and Call structure of Lua ** Stack and Call structure of Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -26,6 +26,7 @@ void luaD_call (lua_State *L, StkId func, int nResults);
void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults); void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults);
void luaD_checkstack (lua_State *L, int n); void luaD_checkstack (lua_State *L, int n);
void luaD_error (lua_State *L, const char *s);
void luaD_breakrun (lua_State *L, int errcode); void luaD_breakrun (lua_State *L, int errcode);
int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud); int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud);

6
lmem.c
View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lmem.c,v 1.42 2000/12/28 12:55:41 roberto Exp roberto $ ** $Id: lmem.c,v 1.43 2001/01/19 13:20:30 roberto Exp roberto $
** Interface to Memory Manager ** Interface to Memory Manager
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -134,7 +134,7 @@ void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems,
else if (*size >= limit/2) { /* cannot double it? */ else if (*size >= limit/2) { /* cannot double it? */
if (*size < limit - MINPOWER2) /* try something smaller... */ if (*size < limit - MINPOWER2) /* try something smaller... */
newsize = limit; /* still have at least MINPOWER2 free places */ newsize = limit; /* still have at least MINPOWER2 free places */
else lua_error(L, errormsg); else luaD_error(L, errormsg);
} }
newblock = luaM_realloc(L, block, (luint32)(*size)*(luint32)size_elems, newblock = luaM_realloc(L, block, (luint32)(*size)*(luint32)size_elems,
(luint32)newsize*(luint32)size_elems); (luint32)newsize*(luint32)size_elems);
@@ -152,7 +152,7 @@ void *luaM_realloc (lua_State *L, void *block, luint32 oldsize, luint32 size) {
block = NULL; block = NULL;
} }
else if (size >= MAX_SIZET) else if (size >= MAX_SIZET)
lua_error(L, "memory allocation error: block too big"); luaD_error(L, "memory allocation error: block too big");
else { else {
block = basicrealloc(block, oldsize, size); block = basicrealloc(block, oldsize, size);
if (block == NULL) { if (block == NULL) {

View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lobject.c,v 1.58 2000/12/28 12:55:41 roberto Exp roberto $ ** $Id: lobject.c,v 1.59 2001/01/19 13:20:30 roberto Exp roberto $
** Some generic functions over Lua objects ** Some generic functions over Lua objects
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -12,6 +12,7 @@
#include "lua.h" #include "lua.h"
#include "ldo.h"
#include "lmem.h" #include "lmem.h"
#include "lobject.h" #include "lobject.h"
#include "lstate.h" #include "lstate.h"
@@ -85,7 +86,7 @@ void luaO_verror (lua_State *L, const char *fmt, ...) {
va_start(argp, fmt); va_start(argp, fmt);
vsprintf(buff, fmt, argp); vsprintf(buff, fmt, argp);
va_end(argp); va_end(argp);
lua_error(L, buff); luaD_error(L, buff);
} }

View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lstate.c,v 1.51 2001/01/19 13:20:30 roberto Exp roberto $ ** $Id: lstate.c,v 1.52 2001/01/22 18:01:38 roberto Exp roberto $
** Global State ** Global State
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -22,6 +22,7 @@
#ifdef LUA_DEBUG #ifdef LUA_DEBUG
static lua_State *lua_state = NULL; static lua_State *lua_state = NULL;
void luaB_opentests (lua_State *L); void luaB_opentests (lua_State *L);
int islocked = 0;
#endif #endif
@@ -44,6 +45,9 @@ struct Sopen {
}; };
static void close_state (lua_State *L);
/* /*
** open parts that may cause memory-allocation errors ** open parts that may cause memory-allocation errors
*/ */
@@ -80,12 +84,13 @@ static void f_luaopen (lua_State *L, void *ud) {
G(L)->sizeref = 0; G(L)->sizeref = 0;
G(L)->refFree = NONEXT; G(L)->refFree = NONEXT;
G(L)->nblocks = sizeof(lua_State) + sizeof(global_State); G(L)->nblocks = sizeof(lua_State) + sizeof(global_State);
G(L)->GCthreshold = MAX_INT; /* to avoid GC during pre-definitions */
luaD_init(L, so->stacksize); /* init stack */ luaD_init(L, so->stacksize); /* init stack */
L->gt = luaH_new(L, 10); /* table of globals */ L->gt = luaH_new(L, 10); /* table of globals */
luaS_init(L); luaS_init(L);
luaX_init(L); luaX_init(L);
luaT_init(L); luaT_init(L);
G(L)->GCthreshold = 4*G(L)->nblocks;
LUA_EXIT; /* temporary exit to use the API */
lua_newtable(L); lua_newtable(L);
lua_ref(L, 1); /* create registry */ lua_ref(L, 1); /* create registry */
lua_register(L, LUA_ERRORMESSAGE, errormessage); lua_register(L, LUA_ERRORMESSAGE, errormessage);
@@ -94,37 +99,41 @@ static void f_luaopen (lua_State *L, void *ud) {
if (lua_state == NULL) lua_state = L; /* keep first state to be opened */ if (lua_state == NULL) lua_state = L; /* keep first state to be opened */
lua_assert(lua_gettop(L) == 0); lua_assert(lua_gettop(L) == 0);
#endif #endif
G(L)->GCthreshold = 2*G(L)->nblocks; LUA_ENTRY; /* go back inside */
} }
} }
LUA_API lua_State *lua_open (lua_State *OL, int stacksize) { LUA_API lua_State *lua_open (lua_State *OL, int stacksize) {
struct Sopen so; struct Sopen so;
lua_State *L = luaM_new(OL, lua_State); lua_State *L;
if (L == NULL) return NULL; /* memory allocation error */ LUA_ENTRY;
L->G = NULL; L = luaM_new(OL, lua_State);
L->stack = NULL; if (L) { /* allocation OK? */
L->stacksize = 0; L->G = NULL;
L->errorJmp = NULL; L->stack = NULL;
L->callhook = NULL; L->stacksize = 0;
L->linehook = NULL; L->errorJmp = NULL;
L->allowhooks = 1; L->callhook = NULL;
L->next = L->previous = L; L->linehook = NULL;
so.stacksize = stacksize; L->allowhooks = 1;
so.L = OL; L->next = L->previous = L;
if (luaD_runprotected(L, f_luaopen, &so) != 0) { so.stacksize = stacksize;
/* memory allocation error: free partial state */ so.L = OL;
lua_close(L); if (luaD_runprotected(L, f_luaopen, &so) != 0) {
return NULL; /* memory allocation error: free partial state */
close_state(L);
L = NULL;
}
} }
LUA_EXIT;
return L; return L;
} }
LUA_API void lua_close (lua_State *L) { static void close_state (lua_State *L) {
lua_State *L1 = L->next; /* any surviving thread (if there is one) */ lua_State *L1;
lua_assert(L != lua_state || lua_gettop(L) == 0); L1 = L->next; /* any surviving thread (if there is one) */
if (L1 == L) L1 = NULL; /* no surviving threads */ if (L1 == L) L1 = NULL; /* no surviving threads */
if (L1 != NULL) { /* are there other threads? */ if (L1 != NULL) { /* are there other threads? */
lua_assert(L->previous != L); lua_assert(L->previous != L);
@@ -144,6 +153,13 @@ LUA_API void lua_close (lua_State *L) {
} }
luaM_freearray(L1, L->stack, L->stacksize, TObject); luaM_freearray(L1, L->stack, L->stacksize, TObject);
luaM_freelem(L1, L, lua_State); luaM_freelem(L1, L, lua_State);
}
LUA_API void lua_close (lua_State *L) {
lua_assert(L != lua_state || lua_gettop(L) == 0);
LUA_ENTRY;
close_state(L);
LUA_EXIT;
lua_assert(L != lua_state || memdebug_numblocks == 0); lua_assert(L != lua_state || memdebug_numblocks == 0);
lua_assert(L != lua_state || memdebug_total == 0); lua_assert(L != lua_state || memdebug_total == 0);
} }

View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lstate.h,v 1.44 2001/01/19 13:20:30 roberto Exp roberto $ ** $Id: lstate.h,v 1.45 2001/01/22 18:01:38 roberto Exp roberto $
** Global State ** Global State
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -13,6 +13,26 @@
#ifdef LUA_DEBUG
extern int islocked;
#define LUA_ENTRY lua_assert(islocked++ == 0)
#define LUA_EXIT lua_assert(--islocked == 0)
#endif
/*
** macros that control all entries and exits from Lua core machine
** (mainly for thread syncronization)
*/
#ifndef LUA_ENTRY
#define LUA_ENTRY
#endif
#ifndef LUA_EXIT
#define LUA_EXIT
#endif
typedef TObject *StkId; /* index to stack elements */ typedef TObject *StkId; /* index to stack elements */

View File

@@ -1,5 +1,5 @@
/* /*
** $Id: ltable.c,v 1.64 2001/01/18 15:59:09 roberto Exp roberto $ ** $Id: ltable.c,v 1.65 2001/01/19 13:20:30 roberto Exp roberto $
** Lua tables (hash) ** Lua tables (hash)
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -20,6 +20,7 @@
#include "lua.h" #include "lua.h"
#include "ldo.h"
#include "lmem.h" #include "lmem.h"
#include "lobject.h" #include "lobject.h"
#include "lstate.h" #include "lstate.h"
@@ -112,7 +113,7 @@ Node *luaH_next (lua_State *L, const Hash *t, const TObject *key) {
else { else {
const TObject *v = luaH_get(t, key); const TObject *v = luaH_get(t, key);
if (v == &luaO_nilobject) if (v == &luaO_nilobject)
lua_error(L, "invalid key for `next'"); luaD_error(L, "invalid key for `next'");
i = (int)(((const char *)v - i = (int)(((const char *)v -
(const char *)(&t->node[0].val)) / sizeof(Node)) + 1; (const char *)(&t->node[0].val)) / sizeof(Node)) + 1;
} }
@@ -152,7 +153,7 @@ void luaH_remove (Hash *t, TObject *key) {
static void setnodevector (lua_State *L, Hash *t, luint32 size) { static void setnodevector (lua_State *L, Hash *t, luint32 size) {
int i; int i;
if (size > MAX_INT) if (size > MAX_INT)
lua_error(L, "table overflow"); luaD_error(L, "table overflow");
t->node = luaM_newvector(L, size, Node); t->node = luaM_newvector(L, size, Node);
for (i=0; i<(int)size; i++) { for (i=0; i<(int)size; i++) {
setnilvalue(&t->node[i].key); setnilvalue(&t->node[i].key);
@@ -259,7 +260,7 @@ static TObject *luaH_setany (lua_State *L, Hash *t, const TObject *key) {
Node *mp = luaH_mainposition(t, key); Node *mp = luaH_mainposition(t, key);
Node *n = mp; Node *n = mp;
if (!mp) if (!mp)
lua_error(L, "table index is nil"); luaD_error(L, "table index is nil");
do { /* check whether `key' is somewhere in the chain */ do { /* check whether `key' is somewhere in the chain */
if (luaO_equalObj(key, &n->key)) if (luaO_equalObj(key, &n->key))
return &n->val; /* that's all */ return &n->val; /* that's all */

19
ltm.c
View File

@@ -1,5 +1,5 @@
/* /*
** $Id: ltm.c,v 1.60 2001/01/18 15:59:09 roberto Exp roberto $ ** $Id: ltm.c,v 1.61 2001/01/19 13:20:30 roberto Exp roberto $
** Tag methods ** Tag methods
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -84,10 +84,14 @@ void luaT_init (lua_State *L) {
LUA_API int lua_newtag (lua_State *L) { LUA_API int lua_newtag (lua_State *L) {
int tag;
LUA_ENTRY;
luaM_growvector(L, G(L)->TMtable, G(L)->ntag, G(L)->sizeTM, struct TM, luaM_growvector(L, G(L)->TMtable, G(L)->ntag, G(L)->sizeTM, struct TM,
MAX_INT, "tag table overflow"); MAX_INT, "tag table overflow");
init_entry(L, G(L)->ntag); init_entry(L, G(L)->ntag);
return G(L)->ntag++; tag = G(L)->ntag++;
LUA_EXIT;
return tag;
} }
@@ -104,12 +108,14 @@ void luaT_realtag (lua_State *L, int tag) {
LUA_API int lua_copytagmethods (lua_State *L, int tagto, int tagfrom) { LUA_API int lua_copytagmethods (lua_State *L, int tagto, int tagfrom) {
int e; int e;
LUA_ENTRY;
checktag(L, tagto); checktag(L, tagto);
checktag(L, tagfrom); checktag(L, tagfrom);
for (e=0; e<TM_N; e++) { for (e=0; e<TM_N; e++) {
if (luaT_validevent(tagto, e)) if (luaT_validevent(tagto, e))
luaT_gettm(G(L), tagto, e) = luaT_gettm(G(L), tagfrom, e); luaT_gettm(G(L), tagto, e) = luaT_gettm(G(L), tagfrom, e);
} }
LUA_EXIT;
return tagto; return tagto;
} }
@@ -126,6 +132,7 @@ int luaT_tag (const TObject *o) {
LUA_API void lua_gettagmethod (lua_State *L, int t, const char *event) { LUA_API void lua_gettagmethod (lua_State *L, int t, const char *event) {
int e; int e;
LUA_ENTRY;
e = luaI_checkevent(L, event, t); e = luaI_checkevent(L, event, t);
checktag(L, t); checktag(L, t);
if (luaT_validevent(t, e) && luaT_gettm(G(L), t, e)) { if (luaT_validevent(t, e) && luaT_gettm(G(L), t, e)) {
@@ -134,11 +141,14 @@ LUA_API void lua_gettagmethod (lua_State *L, int t, const char *event) {
else else
setnilvalue(L->top); setnilvalue(L->top);
incr_top; incr_top;
LUA_EXIT;
} }
LUA_API void lua_settagmethod (lua_State *L, int t, const char *event) { LUA_API void lua_settagmethod (lua_State *L, int t, const char *event) {
int e = luaI_checkevent(L, event, t); int e;
LUA_ENTRY;
e = luaI_checkevent(L, event, t);
checktag(L, t); checktag(L, t);
if (!luaT_validevent(t, e)) if (!luaT_validevent(t, e))
luaO_verror(L, "cannot change `%.20s' tag method for type `%.20s'%.20s", luaO_verror(L, "cannot change `%.20s' tag method for type `%.20s'%.20s",
@@ -153,8 +163,9 @@ LUA_API void lua_settagmethod (lua_State *L, int t, const char *event) {
luaT_gettm(G(L), t, e) = clvalue(L->top - 1); luaT_gettm(G(L), t, e) = clvalue(L->top - 1);
break; break;
default: default:
lua_error(L, "tag method must be a function (or nil)"); luaD_error(L, "tag method must be a function (or nil)");
} }
L->top--; L->top--;
LUA_EXIT;
} }

19
lvm.c
View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lvm.c,v 1.154 2001/01/18 15:59:09 roberto Exp roberto $ ** $Id: lvm.c,v 1.155 2001/01/19 13:20:30 roberto Exp roberto $
** Lua virtual machine ** Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -219,7 +219,8 @@ static int call_binTM (lua_State *L, StkId top, TMS event) {
return 0; /* error */ return 0; /* error */
} }
} }
lua_pushstring(L, luaT_eventname[event]); setsvalue(L->top, luaS_new(L, luaT_eventname[event]));
incr_top;
luaD_callTM(L, tm, 3, 1); luaD_callTM(L, tm, 3, 1);
return 1; return 1;
} }
@@ -287,7 +288,7 @@ void luaV_strconc (lua_State *L, int total, StkId top) {
tl += tsvalue(top-n-1)->len; tl += tsvalue(top-n-1)->len;
n++; n++;
} }
if (tl > MAX_SIZET) lua_error(L, "string size overflow"); if (tl > MAX_SIZET) luaD_error(L, "string size overflow");
buffer = luaO_openspace(L, tl); buffer = luaO_openspace(L, tl);
tl = 0; tl = 0;
for (i=n; i>0; i--) { /* concat all strings */ for (i=n; i>0; i--) { /* concat all strings */
@@ -520,7 +521,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
} }
case OP_POW: { case OP_POW: {
if (!call_binTM(L, top, TM_POW)) if (!call_binTM(L, top, TM_POW))
lua_error(L, "undefined operation"); luaD_error(L, "undefined operation");
top--; top--;
break; break;
} }
@@ -606,11 +607,11 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
} }
case OP_FORPREP: { case OP_FORPREP: {
if (tonumber(top-1)) if (tonumber(top-1))
lua_error(L, "`for' step must be a number"); luaD_error(L, "`for' step must be a number");
if (tonumber(top-2)) if (tonumber(top-2))
lua_error(L, "`for' limit must be a number"); luaD_error(L, "`for' limit must be a number");
if (tonumber(top-3)) if (tonumber(top-3))
lua_error(L, "`for' initial value must be a number"); luaD_error(L, "`for' initial value must be a number");
if (nvalue(top-1) > 0 ? if (nvalue(top-1) > 0 ?
nvalue(top-3) > nvalue(top-2) : nvalue(top-3) > nvalue(top-2) :
nvalue(top-3) < nvalue(top-2)) { /* `empty' loop? */ nvalue(top-3) < nvalue(top-2)) { /* `empty' loop? */
@@ -623,7 +624,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
lua_assert(ttype(top-1) == LUA_TNUMBER); lua_assert(ttype(top-1) == LUA_TNUMBER);
lua_assert(ttype(top-2) == LUA_TNUMBER); lua_assert(ttype(top-2) == LUA_TNUMBER);
if (ttype(top-3) != LUA_TNUMBER) if (ttype(top-3) != LUA_TNUMBER)
lua_error(L, "`for' index must be a number"); luaD_error(L, "`for' index must be a number");
nvalue(top-3) += nvalue(top-1); /* increment index */ nvalue(top-3) += nvalue(top-1); /* increment index */
if (nvalue(top-1) > 0 ? if (nvalue(top-1) > 0 ?
nvalue(top-3) > nvalue(top-2) : nvalue(top-3) > nvalue(top-2) :
@@ -636,7 +637,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
case OP_LFORPREP: { case OP_LFORPREP: {
Node *node; Node *node;
if (ttype(top-1) != LUA_TTABLE) if (ttype(top-1) != LUA_TTABLE)
lua_error(L, "`for' table must be a table"); luaD_error(L, "`for' table must be a table");
node = luaH_next(L, hvalue(top-1), &luaO_nilobject); node = luaH_next(L, hvalue(top-1), &luaO_nilobject);
if (node == NULL) { /* `empty' loop? */ if (node == NULL) { /* `empty' loop? */
top--; /* remove table */ top--; /* remove table */