aboutsummaryrefslogtreecommitdiff
path: root/lapi.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-04-14 12:13:48 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-04-14 12:13:48 -0300
commit7dfa4cd655118faf164427356609fec31906dac2 (patch)
treed39fac9afba1dc0ab01dd5d174824120650c9eab /lapi.c
parentfc6203ee4308173283f9ad9de6694d47f0908c4d (diff)
downloadlua-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.c68
1 files changed, 41 insertions, 27 deletions
diff --git a/lapi.c b/lapi.c
index 0ed2734d..805eedef 100644
--- a/lapi.c
+++ b/lapi.c
@@ -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
224LUA_API int lua_type (lua_State *L, int idx) { 230LUA_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
230LUA_API const char *lua_typename (lua_State *L, int t) { 236LUA_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
236LUA_API int lua_iscfunction (lua_State *L, int idx) { 242LUA_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
362LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { 368LUA_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
482LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { 492LUA_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
1064static const char *aux_upvalue (StkId fi, int n, TValue **val) { 1078static 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) {
1128LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { 1142LUA_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");