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"); |