diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-06-02 16:31:40 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-06-02 16:31:40 -0300 |
commit | 3b44821334a1aa387c13eaf3cd23a2344091cbc7 (patch) | |
tree | 7070ed226b6db26ae82f99d94138465a95b0d7fc /lapi.c | |
parent | 0214dab989396de05567f293e6aa909ee2ffbac1 (diff) | |
download | lua-3b44821334a1aa387c13eaf3cd23a2344091cbc7.tar.gz lua-3b44821334a1aa387c13eaf3cd23a2344091cbc7.tar.bz2 lua-3b44821334a1aa387c13eaf3cd23a2344091cbc7.zip |
stricter control (using tag variants) over closure kinds (Lua x C)
Diffstat (limited to 'lapi.c')
-rw-r--r-- | lapi.c | 117 |
1 files changed, 61 insertions, 56 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lapi.c,v 2.146 2011/05/31 18:24:36 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 2.147 2011/05/31 18:27:56 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 | */ |
@@ -59,9 +59,9 @@ static TValue *index2addr (lua_State *L, int idx) { | |||
59 | if (ttislcf(ci->func)) /* light C function? */ | 59 | if (ttislcf(ci->func)) /* light C function? */ |
60 | return cast(TValue *, luaO_nilobject); /* it has no upvalues */ | 60 | return cast(TValue *, luaO_nilobject); /* it has no upvalues */ |
61 | else { | 61 | else { |
62 | Closure *func = clvalue(ci->func); | 62 | CClosure *func = clCvalue(ci->func); |
63 | return (idx <= func->c.nupvalues) | 63 | return (idx <= func->nupvalues) |
64 | ? &func->c.upvalue[idx-1] | 64 | ? &func->upvalue[idx-1] |
65 | : cast(TValue *, luaO_nilobject); | 65 | : cast(TValue *, luaO_nilobject); |
66 | } | 66 | } |
67 | } | 67 | } |
@@ -195,10 +195,8 @@ static void moveto (lua_State *L, TValue *fr, int idx) { | |||
195 | TValue *to = index2addr(L, idx); | 195 | TValue *to = index2addr(L, idx); |
196 | api_checkvalidindex(L, to); | 196 | api_checkvalidindex(L, to); |
197 | setobj(L, to, fr); | 197 | setobj(L, to, fr); |
198 | if (idx < LUA_REGISTRYINDEX) { /* function upvalue? */ | 198 | if (idx < LUA_REGISTRYINDEX) /* function upvalue? */ |
199 | lua_assert(ttisclosure(L->ci->func)); | 199 | luaC_barrier(L, clCvalue(L->ci->func), fr); |
200 | luaC_barrier(L, clvalue(L->ci->func), fr); | ||
201 | } | ||
202 | /* LUA_REGISTRYINDEX does not need gc barrier | 200 | /* LUA_REGISTRYINDEX does not need gc barrier |
203 | (collector revisits it before finishing collection) */ | 201 | (collector revisits it before finishing collection) */ |
204 | } | 202 | } |
@@ -251,7 +249,7 @@ LUA_API const char *lua_typename (lua_State *L, int t) { | |||
251 | 249 | ||
252 | LUA_API int lua_iscfunction (lua_State *L, int idx) { | 250 | LUA_API int lua_iscfunction (lua_State *L, int idx) { |
253 | StkId o = index2addr(L, idx); | 251 | StkId o = index2addr(L, idx); |
254 | return (ttislcf(o) || (ttisclosure(o) && clvalue(o)->c.isC)); | 252 | return (ttislcf(o) || (ttisCclosure(o))); |
255 | } | 253 | } |
256 | 254 | ||
257 | 255 | ||
@@ -398,7 +396,7 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { | |||
398 | 396 | ||
399 | LUA_API size_t lua_rawlen (lua_State *L, int idx) { | 397 | LUA_API size_t lua_rawlen (lua_State *L, int idx) { |
400 | StkId o = index2addr(L, idx); | 398 | StkId o = index2addr(L, idx); |
401 | switch (ttype(o)) { | 399 | switch (ttypenv(o)) { |
402 | case LUA_TSTRING: return tsvalue(o)->len; | 400 | case LUA_TSTRING: return tsvalue(o)->len; |
403 | case LUA_TUSERDATA: return uvalue(o)->len; | 401 | case LUA_TUSERDATA: return uvalue(o)->len; |
404 | case LUA_TTABLE: return luaH_getn(hvalue(o)); | 402 | case LUA_TTABLE: return luaH_getn(hvalue(o)); |
@@ -410,15 +408,15 @@ LUA_API size_t lua_rawlen (lua_State *L, int idx) { | |||
410 | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { | 408 | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { |
411 | StkId o = index2addr(L, idx); | 409 | StkId o = index2addr(L, idx); |
412 | if (ttislcf(o)) return fvalue(o); | 410 | if (ttislcf(o)) return fvalue(o); |
413 | else if (ttisclosure(o) && clvalue(o)->c.isC) | 411 | else if (ttisCclosure(o)) |
414 | return clvalue(o)->c.f; | 412 | return clCvalue(o)->f; |
415 | else return NULL; /* not a C function */ | 413 | else return NULL; /* not a C function */ |
416 | } | 414 | } |
417 | 415 | ||
418 | 416 | ||
419 | LUA_API void *lua_touserdata (lua_State *L, int idx) { | 417 | LUA_API void *lua_touserdata (lua_State *L, int idx) { |
420 | StkId o = index2addr(L, idx); | 418 | StkId o = index2addr(L, idx); |
421 | switch (ttype(o)) { | 419 | switch (ttypenv(o)) { |
422 | case LUA_TUSERDATA: return (rawuvalue(o) + 1); | 420 | case LUA_TUSERDATA: return (rawuvalue(o) + 1); |
423 | case LUA_TLIGHTUSERDATA: return pvalue(o); | 421 | case LUA_TLIGHTUSERDATA: return pvalue(o); |
424 | default: return NULL; | 422 | default: return NULL; |
@@ -436,7 +434,8 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) { | |||
436 | StkId o = index2addr(L, idx); | 434 | StkId o = index2addr(L, idx); |
437 | switch (ttype(o)) { | 435 | switch (ttype(o)) { |
438 | case LUA_TTABLE: return hvalue(o); | 436 | case LUA_TTABLE: return hvalue(o); |
439 | case LUA_TFUNCTION: return clvalue(o); | 437 | case LUA_TLCL: return clLvalue(o); |
438 | case LUA_TCCL: return clCvalue(o); | ||
440 | case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o))); | 439 | case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o))); |
441 | case LUA_TTHREAD: return thvalue(o); | 440 | case LUA_TTHREAD: return thvalue(o); |
442 | case LUA_TUSERDATA: | 441 | case LUA_TUSERDATA: |
@@ -556,7 +555,7 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { | |||
556 | L->top -= n; | 555 | L->top -= n; |
557 | while (n--) | 556 | while (n--) |
558 | setobj2n(L, &cl->c.upvalue[n], L->top + n); | 557 | setobj2n(L, &cl->c.upvalue[n], L->top + n); |
559 | setclvalue(L, L->top, cl); | 558 | setclCvalue(L, L->top, cl); |
560 | } | 559 | } |
561 | api_incr_top(L); | 560 | api_incr_top(L); |
562 | lua_unlock(L); | 561 | lua_unlock(L); |
@@ -656,7 +655,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) { | |||
656 | int res; | 655 | int res; |
657 | lua_lock(L); | 656 | lua_lock(L); |
658 | obj = index2addr(L, objindex); | 657 | obj = index2addr(L, objindex); |
659 | switch (ttype(obj)) { | 658 | switch (ttypenv(obj)) { |
660 | case LUA_TTABLE: | 659 | case LUA_TTABLE: |
661 | mt = hvalue(obj)->metatable; | 660 | mt = hvalue(obj)->metatable; |
662 | break; | 661 | break; |
@@ -763,7 +762,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { | |||
763 | api_check(L, ttistable(L->top - 1), "table expected"); | 762 | api_check(L, ttistable(L->top - 1), "table expected"); |
764 | mt = hvalue(L->top - 1); | 763 | mt = hvalue(L->top - 1); |
765 | } | 764 | } |
766 | switch (ttype(obj)) { | 765 | switch (ttypenv(obj)) { |
767 | case LUA_TTABLE: { | 766 | case LUA_TTABLE: { |
768 | hvalue(obj)->metatable = mt; | 767 | hvalue(obj)->metatable = mt; |
769 | if (mt) | 768 | if (mt) |
@@ -921,15 +920,14 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, | |||
921 | luaZ_init(L, &z, reader, data); | 920 | luaZ_init(L, &z, reader, data); |
922 | status = luaD_protectedparser(L, &z, chunkname); | 921 | status = luaD_protectedparser(L, &z, chunkname); |
923 | if (status == LUA_OK) { /* no errors? */ | 922 | if (status == LUA_OK) { /* no errors? */ |
924 | Closure *f = clvalue(L->top - 1); /* get newly created function */ | 923 | LClosure *f = clLvalue(L->top - 1); /* get newly created function */ |
925 | lua_assert(!f->c.isC); | 924 | if (f->nupvalues == 1) { /* does it have one upvalue? */ |
926 | if (f->l.nupvalues == 1) { /* does it have one upvalue? */ | ||
927 | /* get global table from registry */ | 925 | /* get global table from registry */ |
928 | Table *reg = hvalue(&G(L)->l_registry); | 926 | Table *reg = hvalue(&G(L)->l_registry); |
929 | const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS); | 927 | const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS); |
930 | /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ | 928 | /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ |
931 | setobj(L, f->l.upvals[0]->v, gt); | 929 | setobj(L, f->upvals[0]->v, gt); |
932 | luaC_barrier(L, f->l.upvals[0], gt); | 930 | luaC_barrier(L, f->upvals[0], gt); |
933 | } | 931 | } |
934 | } | 932 | } |
935 | lua_unlock(L); | 933 | lua_unlock(L); |
@@ -1131,25 +1129,27 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) { | |||
1131 | 1129 | ||
1132 | static const char *aux_upvalue (StkId fi, int n, TValue **val, | 1130 | static const char *aux_upvalue (StkId fi, int n, TValue **val, |
1133 | GCObject **owner) { | 1131 | GCObject **owner) { |
1134 | Closure *f; | 1132 | switch (ttype(fi)) { |
1135 | if (!ttisclosure(fi)) return NULL; | 1133 | case LUA_TCCL: { /* C closure */ |
1136 | f = clvalue(fi); | 1134 | CClosure *f = clCvalue(fi); |
1137 | if (f->c.isC) { | 1135 | if (!(1 <= n && n <= f->nupvalues)) return NULL; |
1138 | if (!(1 <= n && n <= f->c.nupvalues)) return NULL; | 1136 | *val = &f->upvalue[n-1]; |
1139 | *val = &f->c.upvalue[n-1]; | 1137 | if (owner) *owner = obj2gco(f); |
1140 | if (owner) *owner = obj2gco(f); | 1138 | return ""; |
1141 | return ""; | 1139 | } |
1142 | } | 1140 | case LUA_TLCL: { /* Lua closure */ |
1143 | else { | 1141 | LClosure *f = clLvalue(fi); |
1144 | const char *name; | 1142 | const char *name; |
1145 | Proto *p = f->l.p; | 1143 | Proto *p = f->p; |
1146 | if (!(1 <= n && n <= p->sizeupvalues)) return NULL; | 1144 | if (!(1 <= n && n <= p->sizeupvalues)) return NULL; |
1147 | *val = f->l.upvals[n-1]->v; | 1145 | *val = f->upvals[n-1]->v; |
1148 | if (owner) *owner = obj2gco(f->l.upvals[n - 1]); | 1146 | if (owner) *owner = obj2gco(f->upvals[n - 1]); |
1149 | name = getstr(p->upvalues[n-1].name); | 1147 | name = getstr(p->upvalues[n-1].name); |
1150 | if (name == NULL) /* no debug information? */ | 1148 | if (name == NULL) /* no debug information? */ |
1151 | name = ""; | 1149 | name = ""; |
1152 | return name; | 1150 | return name; |
1151 | } | ||
1152 | default: return NULL; /* not a closure */ | ||
1153 | } | 1153 | } |
1154 | } | 1154 | } |
1155 | 1155 | ||
@@ -1187,34 +1187,39 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { | |||
1187 | } | 1187 | } |
1188 | 1188 | ||
1189 | 1189 | ||
1190 | static UpVal **getupvalref (lua_State *L, int fidx, int n, Closure **pf) { | 1190 | static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) { |
1191 | Closure *f; | 1191 | LClosure *f; |
1192 | StkId fi = index2addr(L, fidx); | 1192 | StkId fi = index2addr(L, fidx); |
1193 | api_check(L, ttisclosure(fi), "Lua function expected"); | 1193 | api_check(L, ttisLclosure(fi), "Lua function expected"); |
1194 | f = clvalue(fi); | 1194 | f = clLvalue(fi); |
1195 | api_check(L, !f->c.isC, "Lua function expected"); | 1195 | api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); |
1196 | api_check(L, (1 <= n && n <= f->l.p->sizeupvalues), "invalid upvalue index"); | ||
1197 | if (pf) *pf = f; | 1196 | if (pf) *pf = f; |
1198 | return &f->l.upvals[n - 1]; /* get its upvalue pointer */ | 1197 | return &f->upvals[n - 1]; /* get its upvalue pointer */ |
1199 | } | 1198 | } |
1200 | 1199 | ||
1201 | 1200 | ||
1202 | LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { | 1201 | LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { |
1203 | Closure *f; | ||
1204 | StkId fi = index2addr(L, fidx); | 1202 | StkId fi = index2addr(L, fidx); |
1205 | api_check(L, ttisclosure(fi), "function expected"); | 1203 | switch (ttype(fi)) { |
1206 | f = clvalue(fi); | 1204 | case LUA_TLCL: { /* lua closure */ |
1207 | if (f->c.isC) { | 1205 | return *getupvalref(L, fidx, n, NULL); |
1208 | api_check(L, 1 <= n && n <= f->c.nupvalues, "invalid upvalue index"); | 1206 | } |
1209 | return &f->c.upvalue[n - 1]; | 1207 | case LUA_TCCL: { /* C closure */ |
1208 | CClosure *f = clCvalue(fi); | ||
1209 | api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index"); | ||
1210 | return &f->upvalue[n - 1]; | ||
1211 | } | ||
1212 | default: { | ||
1213 | api_check(L, 0, "closure expected"); | ||
1214 | return NULL; | ||
1215 | } | ||
1210 | } | 1216 | } |
1211 | else return *getupvalref(L, fidx, n, NULL); | ||
1212 | } | 1217 | } |
1213 | 1218 | ||
1214 | 1219 | ||
1215 | LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, | 1220 | LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, |
1216 | int fidx2, int n2) { | 1221 | int fidx2, int n2) { |
1217 | Closure *f1; | 1222 | LClosure *f1; |
1218 | UpVal **up1 = getupvalref(L, fidx1, n1, &f1); | 1223 | UpVal **up1 = getupvalref(L, fidx1, n1, &f1); |
1219 | UpVal **up2 = getupvalref(L, fidx2, n2, NULL); | 1224 | UpVal **up2 = getupvalref(L, fidx2, n2, NULL); |
1220 | *up1 = *up2; | 1225 | *up1 = *up2; |