From 7dfa4cd655118faf164427356609fec31906dac2 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy <roberto@inf.puc-rio.br> Date: Wed, 14 Apr 2010 12:13:48 -0300 Subject: first implementation of light C functions --- lapi.c | 68 ++++++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 27 deletions(-) (limited to 'lapi.c') diff --git a/lapi.c b/lapi.c index 0ed2734d..805eedef 100644 --- a/lapi.c +++ b/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"); -- cgit v1.2.3-55-g6feb