aboutsummaryrefslogtreecommitdiff
path: root/lapi.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2011-06-02 16:31:40 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2011-06-02 16:31:40 -0300
commit3b44821334a1aa387c13eaf3cd23a2344091cbc7 (patch)
tree7070ed226b6db26ae82f99d94138465a95b0d7fc /lapi.c
parent0214dab989396de05567f293e6aa909ee2ffbac1 (diff)
downloadlua-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.c117
1 files changed, 61 insertions, 56 deletions
diff --git a/lapi.c b/lapi.c
index 3e1c50d6..8fd9ba86 100644
--- a/lapi.c
+++ b/lapi.c
@@ -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
252LUA_API int lua_iscfunction (lua_State *L, int idx) { 250LUA_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
399LUA_API size_t lua_rawlen (lua_State *L, int idx) { 397LUA_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) {
410LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { 408LUA_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
419LUA_API void *lua_touserdata (lua_State *L, int idx) { 417LUA_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
1132static const char *aux_upvalue (StkId fi, int n, TValue **val, 1130static 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
1190static UpVal **getupvalref (lua_State *L, int fidx, int n, Closure **pf) { 1190static 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
1202LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { 1201LUA_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
1215LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, 1220LUA_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;