first implementation of light C functions
This commit is contained in:
68
lapi.c
68
lapi.c
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user