diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-04-14 12:13:48 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-04-14 12:13:48 -0300 |
| commit | 7dfa4cd655118faf164427356609fec31906dac2 (patch) | |
| tree | d39fac9afba1dc0ab01dd5d174824120650c9eab /lapi.c | |
| parent | fc6203ee4308173283f9ad9de6694d47f0908c4d (diff) | |
| download | lua-7dfa4cd655118faf164427356609fec31906dac2.tar.gz lua-7dfa4cd655118faf164427356609fec31906dac2.tar.bz2 lua-7dfa4cd655118faf164427356609fec31906dac2.zip | |
first implementation of light C functions
Diffstat (limited to 'lapi.c')
| -rw-r--r-- | lapi.c | 68 |
1 files changed, 41 insertions, 27 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lapi.c,v 2.119 2010/04/02 15:19:19 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 2.120 2010/04/05 14:21:38 roberto Exp roberto $ |
| 3 | ** Lua API | 3 | ** Lua API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -54,12 +54,16 @@ static TValue *index2addr (lua_State *L, int idx) { | |||
| 54 | else if (idx == LUA_REGISTRYINDEX) | 54 | else if (idx == LUA_REGISTRYINDEX) |
| 55 | return &G(L)->l_registry; | 55 | return &G(L)->l_registry; |
| 56 | else { /* upvalues */ | 56 | else { /* upvalues */ |
| 57 | Closure *func = curr_func(L); | ||
| 58 | idx = LUA_REGISTRYINDEX - idx; | 57 | idx = LUA_REGISTRYINDEX - idx; |
| 59 | api_check(L, idx <= UCHAR_MAX + 1, "upvalue index too large"); | 58 | api_check(L, idx <= UCHAR_MAX + 1, "upvalue index too large"); |
| 60 | return (idx <= func->c.nupvalues) | 59 | if (ttiscfp(ci->func)) /* C-function pointer? */ |
| 61 | ? &func->c.upvalue[idx-1] | 60 | return cast(TValue *, luaO_nilobject); /* it has no upvalues */ |
| 62 | : cast(TValue *, luaO_nilobject); | 61 | else { |
| 62 | Closure *func = clvalue(ci->func); | ||
| 63 | return (idx <= func->c.nupvalues) | ||
| 64 | ? &func->c.upvalue[idx-1] | ||
| 65 | : cast(TValue *, luaO_nilobject); | ||
| 66 | } | ||
| 63 | } | 67 | } |
| 64 | } | 68 | } |
| 65 | 69 | ||
| @@ -181,8 +185,10 @@ static void moveto (lua_State *L, TValue *fr, int idx) { | |||
| 181 | TValue *to = index2addr(L, idx); | 185 | TValue *to = index2addr(L, idx); |
| 182 | api_checkvalidindex(L, to); | 186 | api_checkvalidindex(L, to); |
| 183 | setobj(L, to, fr); | 187 | setobj(L, to, fr); |
| 184 | if (idx < LUA_REGISTRYINDEX) /* function upvalue? */ | 188 | if (idx < LUA_REGISTRYINDEX) { /* function upvalue? */ |
| 185 | luaC_barrier(L, curr_func(L), fr); | 189 | lua_assert(ttisclosure(L->ci->func)); |
| 190 | luaC_barrier(L, clvalue(L->ci->func), fr); | ||
| 191 | } | ||
| 186 | /* LUA_REGISTRYINDEX does not need gc barrier | 192 | /* LUA_REGISTRYINDEX does not need gc barrier |
| 187 | (collector revisits it before finishing collection) */ | 193 | (collector revisits it before finishing collection) */ |
| 188 | } | 194 | } |
| @@ -223,19 +229,19 @@ LUA_API void lua_pushvalue (lua_State *L, int idx) { | |||
| 223 | 229 | ||
| 224 | LUA_API int lua_type (lua_State *L, int idx) { | 230 | LUA_API int lua_type (lua_State *L, int idx) { |
| 225 | StkId o = index2addr(L, idx); | 231 | StkId o = index2addr(L, idx); |
| 226 | return (o == luaO_nilobject) ? LUA_TNONE : ttype(o); | 232 | return (o == luaO_nilobject) ? LUA_TNONE : ttypenv(o); |
| 227 | } | 233 | } |
| 228 | 234 | ||
| 229 | 235 | ||
| 230 | LUA_API const char *lua_typename (lua_State *L, int t) { | 236 | LUA_API const char *lua_typename (lua_State *L, int t) { |
| 231 | UNUSED(L); | 237 | UNUSED(L); |
| 232 | return typename(t); | 238 | return ttypename(t); |
| 233 | } | 239 | } |
| 234 | 240 | ||
| 235 | 241 | ||
| 236 | LUA_API int lua_iscfunction (lua_State *L, int idx) { | 242 | LUA_API int lua_iscfunction (lua_State *L, int idx) { |
| 237 | StkId o = index2addr(L, idx); | 243 | StkId o = index2addr(L, idx); |
| 238 | return iscfunction(o); | 244 | return (ttiscfp(o) || (ttisclosure(o) && clvalue(o)->c.isC)); |
| 239 | } | 245 | } |
| 240 | 246 | ||
| 241 | 247 | ||
| @@ -361,7 +367,10 @@ LUA_API size_t lua_rawlen (lua_State *L, int idx) { | |||
| 361 | 367 | ||
| 362 | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { | 368 | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { |
| 363 | StkId o = index2addr(L, idx); | 369 | StkId o = index2addr(L, idx); |
| 364 | return (!iscfunction(o)) ? NULL : clvalue(o)->c.f; | 370 | if (ttiscfp(o)) return fvalue(o); |
| 371 | else if (ttisclosure(o) && clvalue(o)->c.isC) | ||
| 372 | return clvalue(o)->c.f; | ||
| 373 | else return NULL; /* not a C function */ | ||
| 365 | } | 374 | } |
| 366 | 375 | ||
| 367 | 376 | ||
| @@ -386,6 +395,7 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) { | |||
| 386 | switch (ttype(o)) { | 395 | switch (ttype(o)) { |
| 387 | case LUA_TTABLE: return hvalue(o); | 396 | case LUA_TTABLE: return hvalue(o); |
| 388 | case LUA_TFUNCTION: return clvalue(o); | 397 | case LUA_TFUNCTION: return clvalue(o); |
| 398 | case LUA_TCFP: return cast(void *, cast(size_t, fvalue(o))); | ||
| 389 | case LUA_TTHREAD: return thvalue(o); | 399 | case LUA_TTHREAD: return thvalue(o); |
| 390 | case LUA_TUSERDATA: | 400 | case LUA_TUSERDATA: |
| 391 | case LUA_TLIGHTUSERDATA: | 401 | case LUA_TLIGHTUSERDATA: |
| @@ -480,18 +490,22 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { | |||
| 480 | 490 | ||
| 481 | 491 | ||
| 482 | LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { | 492 | LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { |
| 483 | Closure *cl; | ||
| 484 | lua_lock(L); | 493 | lua_lock(L); |
| 485 | api_checknelems(L, n); | 494 | if (n == 0) { |
| 486 | api_check(L, n <= UCHAR_MAX, "upvalue index too large"); | 495 | setfvalue(L->top, fn); |
| 487 | luaC_checkGC(L); | 496 | } |
| 488 | cl = luaF_newCclosure(L, n); | 497 | else { |
| 489 | cl->c.f = fn; | 498 | Closure *cl; |
| 490 | L->top -= n; | 499 | api_checknelems(L, n); |
| 491 | while (n--) | 500 | api_check(L, n <= UCHAR_MAX, "upvalue index too large"); |
| 492 | setobj2n(L, &cl->c.upvalue[n], L->top+n); | 501 | luaC_checkGC(L); |
| 493 | setclvalue(L, L->top, cl); | 502 | cl = luaF_newCclosure(L, n); |
| 494 | lua_assert(iswhite(obj2gco(cl))); | 503 | cl->c.f = fn; |
| 504 | L->top -= n; | ||
| 505 | while (n--) | ||
| 506 | setobj2n(L, &cl->c.upvalue[n], L->top + n); | ||
| 507 | setclvalue(L, L->top, cl); | ||
| 508 | } | ||
| 495 | api_incr_top(L); | 509 | api_incr_top(L); |
| 496 | lua_unlock(L); | 510 | lua_unlock(L); |
| 497 | } | 511 | } |
| @@ -598,7 +612,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) { | |||
| 598 | mt = uvalue(obj)->metatable; | 612 | mt = uvalue(obj)->metatable; |
| 599 | break; | 613 | break; |
| 600 | default: | 614 | default: |
| 601 | mt = G(L)->mt[ttype(obj)]; | 615 | mt = G(L)->mt[ttypenv(obj)]; |
| 602 | break; | 616 | break; |
| 603 | } | 617 | } |
| 604 | if (mt == NULL) | 618 | if (mt == NULL) |
| @@ -713,7 +727,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { | |||
| 713 | break; | 727 | break; |
| 714 | } | 728 | } |
| 715 | default: { | 729 | default: { |
| 716 | G(L)->mt[ttype(obj)] = mt; | 730 | G(L)->mt[ttypenv(obj)] = mt; |
| 717 | break; | 731 | break; |
| 718 | } | 732 | } |
| 719 | } | 733 | } |
| @@ -1063,7 +1077,7 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) { | |||
| 1063 | 1077 | ||
| 1064 | static const char *aux_upvalue (StkId fi, int n, TValue **val) { | 1078 | static const char *aux_upvalue (StkId fi, int n, TValue **val) { |
| 1065 | Closure *f; | 1079 | Closure *f; |
| 1066 | if (!ttisfunction(fi)) return NULL; | 1080 | if (!ttisclosure(fi)) return NULL; |
| 1067 | f = clvalue(fi); | 1081 | f = clvalue(fi); |
| 1068 | if (f->c.isC) { | 1082 | if (f->c.isC) { |
| 1069 | if (!(1 <= n && n <= f->c.nupvalues)) return NULL; | 1083 | 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) { | |||
| 1115 | Closure *f; | 1129 | Closure *f; |
| 1116 | Proto *p; | 1130 | Proto *p; |
| 1117 | StkId fi = index2addr(L, fidx); | 1131 | StkId fi = index2addr(L, fidx); |
| 1118 | api_check(L, ttisfunction(fi), "function expected"); | 1132 | api_check(L, ttisclosure(fi), "Lua function expected"); |
| 1119 | f = clvalue(fi); | 1133 | f = clvalue(fi); |
| 1120 | api_check(L, !f->c.isC, "Lua function expected"); | 1134 | api_check(L, !f->c.isC, "Lua function expected"); |
| 1121 | p = f->l.p; | 1135 | p = f->l.p; |
| @@ -1128,7 +1142,7 @@ static UpVal **getupvalref (lua_State *L, int fidx, int n, Closure **pf) { | |||
| 1128 | LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { | 1142 | LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { |
| 1129 | Closure *f; | 1143 | Closure *f; |
| 1130 | StkId fi = index2addr(L, fidx); | 1144 | StkId fi = index2addr(L, fidx); |
| 1131 | api_check(L, ttisfunction(fi), "function expected"); | 1145 | api_check(L, ttisclosure(fi), "function expected"); |
| 1132 | f = clvalue(fi); | 1146 | f = clvalue(fi); |
| 1133 | if (f->c.isC) { | 1147 | if (f->c.isC) { |
| 1134 | api_check(L, 1 <= n && n <= f->c.nupvalues, "invalid upvalue index"); | 1148 | api_check(L, 1 <= n && n <= f->c.nupvalues, "invalid upvalue index"); |
