|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
-** $Id: lapi.c,v 2.119 2010/04/02 15:19:19 roberto Exp roberto $
|
|
|
+** $Id: lapi.c,v 2.120 2010/04/05 14:21:38 roberto Exp roberto $
|
|
|
** Lua API
|
|
|
** See Copyright Notice in lua.h
|
|
|
*/
|
|
@@ -54,12 +54,16 @@ static TValue *index2addr (lua_State *L, int idx) {
|
|
|
else if (idx == LUA_REGISTRYINDEX)
|
|
|
return &G(L)->l_registry;
|
|
|
else { /* upvalues */
|
|
|
- Closure *func = curr_func(L);
|
|
|
idx = LUA_REGISTRYINDEX - idx;
|
|
|
api_check(L, idx <= UCHAR_MAX + 1, "upvalue index too large");
|
|
|
- return (idx <= func->c.nupvalues)
|
|
|
- ? &func->c.upvalue[idx-1]
|
|
|
- : cast(TValue *, luaO_nilobject);
|
|
|
+ if (ttiscfp(ci->func)) /* C-function pointer? */
|
|
|
+ return cast(TValue *, luaO_nilobject); /* it has no upvalues */
|
|
|
+ else {
|
|
|
+ Closure *func = clvalue(ci->func);
|
|
|
+ return (idx <= func->c.nupvalues)
|
|
|
+ ? &func->c.upvalue[idx-1]
|
|
|
+ : cast(TValue *, luaO_nilobject);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -181,8 +185,10 @@ static void moveto (lua_State *L, TValue *fr, int idx) {
|
|
|
TValue *to = index2addr(L, idx);
|
|
|
api_checkvalidindex(L, to);
|
|
|
setobj(L, to, fr);
|
|
|
- if (idx < LUA_REGISTRYINDEX) /* function upvalue? */
|
|
|
- luaC_barrier(L, curr_func(L), fr);
|
|
|
+ if (idx < LUA_REGISTRYINDEX) { /* function upvalue? */
|
|
|
+ lua_assert(ttisclosure(L->ci->func));
|
|
|
+ luaC_barrier(L, clvalue(L->ci->func), fr);
|
|
|
+ }
|
|
|
/* LUA_REGISTRYINDEX does not need gc barrier
|
|
|
(collector revisits it before finishing collection) */
|
|
|
}
|
|
@@ -223,19 +229,19 @@ LUA_API void lua_pushvalue (lua_State *L, int idx) {
|
|
|
|
|
|
LUA_API int lua_type (lua_State *L, int idx) {
|
|
|
StkId o = index2addr(L, idx);
|
|
|
- return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
|
|
|
+ return (o == luaO_nilobject) ? LUA_TNONE : ttypenv(o);
|
|
|
}
|
|
|
|
|
|
|
|
|
LUA_API const char *lua_typename (lua_State *L, int t) {
|
|
|
UNUSED(L);
|
|
|
- return typename(t);
|
|
|
+ return ttypename(t);
|
|
|
}
|
|
|
|
|
|
|
|
|
LUA_API int lua_iscfunction (lua_State *L, int idx) {
|
|
|
StkId o = index2addr(L, idx);
|
|
|
- return iscfunction(o);
|
|
|
+ return (ttiscfp(o) || (ttisclosure(o) && clvalue(o)->c.isC));
|
|
|
}
|
|
|
|
|
|
|
|
@@ -361,7 +367,10 @@ LUA_API size_t lua_rawlen (lua_State *L, int idx) {
|
|
|
|
|
|
LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
|
|
|
StkId o = index2addr(L, idx);
|
|
|
- return (!iscfunction(o)) ? NULL : clvalue(o)->c.f;
|
|
|
+ if (ttiscfp(o)) return fvalue(o);
|
|
|
+ else if (ttisclosure(o) && clvalue(o)->c.isC)
|
|
|
+ return clvalue(o)->c.f;
|
|
|
+ else return NULL; /* not a C function */
|
|
|
}
|
|
|
|
|
|
|
|
@@ -386,6 +395,7 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) {
|
|
|
switch (ttype(o)) {
|
|
|
case LUA_TTABLE: return hvalue(o);
|
|
|
case LUA_TFUNCTION: return clvalue(o);
|
|
|
+ case LUA_TCFP: return cast(void *, cast(size_t, fvalue(o)));
|
|
|
case LUA_TTHREAD: return thvalue(o);
|
|
|
case LUA_TUSERDATA:
|
|
|
case LUA_TLIGHTUSERDATA:
|
|
@@ -480,18 +490,22 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
|
|
|
|
|
|
|
|
|
LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
|
|
|
- Closure *cl;
|
|
|
lua_lock(L);
|
|
|
- api_checknelems(L, n);
|
|
|
- api_check(L, n <= UCHAR_MAX, "upvalue index too large");
|
|
|
- luaC_checkGC(L);
|
|
|
- cl = luaF_newCclosure(L, n);
|
|
|
- cl->c.f = fn;
|
|
|
- L->top -= n;
|
|
|
- while (n--)
|
|
|
- setobj2n(L, &cl->c.upvalue[n], L->top+n);
|
|
|
- setclvalue(L, L->top, cl);
|
|
|
- lua_assert(iswhite(obj2gco(cl)));
|
|
|
+ if (n == 0) {
|
|
|
+ setfvalue(L->top, fn);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ Closure *cl;
|
|
|
+ api_checknelems(L, n);
|
|
|
+ api_check(L, n <= UCHAR_MAX, "upvalue index too large");
|
|
|
+ luaC_checkGC(L);
|
|
|
+ cl = luaF_newCclosure(L, n);
|
|
|
+ cl->c.f = fn;
|
|
|
+ L->top -= n;
|
|
|
+ while (n--)
|
|
|
+ setobj2n(L, &cl->c.upvalue[n], L->top + n);
|
|
|
+ setclvalue(L, L->top, cl);
|
|
|
+ }
|
|
|
api_incr_top(L);
|
|
|
lua_unlock(L);
|
|
|
}
|
|
@@ -598,7 +612,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
|
|
|
mt = uvalue(obj)->metatable;
|
|
|
break;
|
|
|
default:
|
|
|
- mt = G(L)->mt[ttype(obj)];
|
|
|
+ mt = G(L)->mt[ttypenv(obj)];
|
|
|
break;
|
|
|
}
|
|
|
if (mt == NULL)
|
|
@@ -713,7 +727,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
|
|
|
break;
|
|
|
}
|
|
|
default: {
|
|
|
- G(L)->mt[ttype(obj)] = mt;
|
|
|
+ G(L)->mt[ttypenv(obj)] = mt;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
@@ -1063,7 +1077,7 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
|
|
|
|
|
|
static const char *aux_upvalue (StkId fi, int n, TValue **val) {
|
|
|
Closure *f;
|
|
|
- if (!ttisfunction(fi)) return NULL;
|
|
|
+ if (!ttisclosure(fi)) return NULL;
|
|
|
f = clvalue(fi);
|
|
|
if (f->c.isC) {
|
|
|
if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
|
|
@@ -1115,7 +1129,7 @@ static UpVal **getupvalref (lua_State *L, int fidx, int n, Closure **pf) {
|
|
|
Closure *f;
|
|
|
Proto *p;
|
|
|
StkId fi = index2addr(L, fidx);
|
|
|
- api_check(L, ttisfunction(fi), "function expected");
|
|
|
+ api_check(L, ttisclosure(fi), "Lua function expected");
|
|
|
f = clvalue(fi);
|
|
|
api_check(L, !f->c.isC, "Lua function expected");
|
|
|
p = f->l.p;
|
|
@@ -1128,7 +1142,7 @@ static UpVal **getupvalref (lua_State *L, int fidx, int n, Closure **pf) {
|
|
|
LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
|
|
|
Closure *f;
|
|
|
StkId fi = index2addr(L, fidx);
|
|
|
- api_check(L, ttisfunction(fi), "function expected");
|
|
|
+ api_check(L, ttisclosure(fi), "function expected");
|
|
|
f = clvalue(fi);
|
|
|
if (f->c.isC) {
|
|
|
api_check(L, 1 <= n && n <= f->c.nupvalues, "invalid upvalue index");
|