summaryrefslogtreecommitdiff
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
parent0214dab989396de05567f293e6aa909ee2ffbac1 (diff)
downloadlua-3b44821334a1aa387c13eaf3cd23a2344091cbc7.tar.gz
lua-3b44821334a1aa387c13eaf3cd23a2344091cbc7.tar.bz2
lua-3b44821334a1aa387c13eaf3cd23a2344091cbc7.zip
stricter control (using tag variants) over closure kinds (Lua x C)
-rw-r--r--lapi.c117
-rw-r--r--ldebug.c24
-rw-r--r--ldebug.h5
-rw-r--r--ldo.c108
-rw-r--r--lobject.h47
-rw-r--r--lstate.h3
-rw-r--r--ltable.c4
-rw-r--r--ltests.c4
-rw-r--r--ltm.c4
-rw-r--r--lvm.c13
10 files changed, 176 insertions, 153 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;
diff --git a/ldebug.c b/ldebug.c
index 1576aebf..9a0242b6 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 2.80 2011/04/19 16:22:13 roberto Exp roberto $ 2** $Id: ldebug.c,v 2.81 2011/04/28 14:00:11 roberto Exp roberto $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -35,12 +35,12 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
35 35
36static int currentpc (CallInfo *ci) { 36static int currentpc (CallInfo *ci) {
37 lua_assert(isLua(ci)); 37 lua_assert(isLua(ci));
38 return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p); 38 return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
39} 39}
40 40
41 41
42static int currentline (CallInfo *ci) { 42static int currentline (CallInfo *ci) {
43 return getfuncline(ci_func(ci)->l.p, currentpc(ci)); 43 return getfuncline(ci_func(ci)->p, currentpc(ci));
44} 44}
45 45
46 46
@@ -95,7 +95,7 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
95 95
96 96
97static const char *findvararg (CallInfo *ci, int n, StkId *pos) { 97static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
98 int nparams = clvalue(ci->func)->l.p->numparams; 98 int nparams = clLvalue(ci->func)->p->numparams;
99 if (n >= ci->u.l.base - ci->func - nparams) 99 if (n >= ci->u.l.base - ci->func - nparams)
100 return NULL; /* no such vararg */ 100 return NULL; /* no such vararg */
101 else { 101 else {
@@ -114,7 +114,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n,
114 return findvararg(ci, -n, pos); 114 return findvararg(ci, -n, pos);
115 else { 115 else {
116 base = ci->u.l.base; 116 base = ci->u.l.base;
117 name = luaF_getlocalname(ci_func(ci)->l.p, n, currentpc(ci)); 117 name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
118 } 118 }
119 } 119 }
120 else 120 else
@@ -138,7 +138,7 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
138 if (!isLfunction(L->top - 1)) /* not a Lua function? */ 138 if (!isLfunction(L->top - 1)) /* not a Lua function? */
139 name = NULL; 139 name = NULL;
140 else /* consider live variables at function start (parameters) */ 140 else /* consider live variables at function start (parameters) */
141 name = luaF_getlocalname(clvalue(L->top - 1)->l.p, n, 0); 141 name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
142 } 142 }
143 else { /* active function; get information through 'ar' */ 143 else { /* active function; get information through 'ar' */
144 StkId pos = 0; /* to avoid warnings */ 144 StkId pos = 0; /* to avoid warnings */
@@ -294,7 +294,7 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
294static void kname (lua_State *L, CallInfo *ci, int c, int oreg, 294static void kname (lua_State *L, CallInfo *ci, int c, int oreg,
295 const char *what, const char **name) { 295 const char *what, const char **name) {
296 if (ISK(c)) { /* is 'c' a constant? */ 296 if (ISK(c)) { /* is 'c' a constant? */
297 TValue *kvalue = &ci_func(ci)->l.p->k[INDEXK(c)]; 297 TValue *kvalue = &ci_func(ci)->p->k[INDEXK(c)];
298 if (ttisstring(kvalue)) { /* literal constant? */ 298 if (ttisstring(kvalue)) { /* literal constant? */
299 *name = svalue(kvalue); /* it is its own name */ 299 *name = svalue(kvalue); /* it is its own name */
300 return; 300 return;
@@ -315,7 +315,7 @@ static void kname (lua_State *L, CallInfo *ci, int c, int oreg,
315 315
316static const char *getobjname (lua_State *L, CallInfo *ci, int reg, 316static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
317 const char **name) { 317 const char **name) {
318 Proto *p = ci_func(ci)->l.p; 318 Proto *p = ci_func(ci)->p;
319 const char *what = NULL; 319 const char *what = NULL;
320 int lastpc = currentpc(ci); 320 int lastpc = currentpc(ci);
321 int pc; 321 int pc;
@@ -421,9 +421,9 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
421 if ((ci->callstatus & CIST_TAIL) || !isLua(ci->previous)) 421 if ((ci->callstatus & CIST_TAIL) || !isLua(ci->previous))
422 return NULL; /* calling function is not Lua (or is unknown) */ 422 return NULL; /* calling function is not Lua (or is unknown) */
423 ci = ci->previous; /* calling function */ 423 ci = ci->previous; /* calling function */
424 i = ci_func(ci)->l.p->code[currentpc(ci)]; 424 i = ci_func(ci)->p->code[currentpc(ci)];
425 if (GET_OPCODE(i) == OP_EXTRAARG) /* extra argument? */ 425 if (GET_OPCODE(i) == OP_EXTRAARG) /* extra argument? */
426 i = ci_func(ci)->l.p->code[currentpc(ci) - 1]; /* get 'real' instruction */ 426 i = ci_func(ci)->p->code[currentpc(ci) - 1]; /* get 'real' instruction */
427 switch (GET_OPCODE(i)) { 427 switch (GET_OPCODE(i)) {
428 case OP_CALL: 428 case OP_CALL:
429 case OP_TAILCALL: 429 case OP_TAILCALL:
@@ -474,7 +474,7 @@ static int isinstack (CallInfo *ci, const TValue *o) {
474 474
475static const char *getupvalname (CallInfo *ci, const TValue *o, 475static const char *getupvalname (CallInfo *ci, const TValue *o,
476 const char **name) { 476 const char **name) {
477 LClosure *c = &ci_func(ci)->l; 477 LClosure *c = ci_func(ci);
478 int i; 478 int i;
479 for (i = 0; i < c->nupvalues; i++) { 479 for (i = 0; i < c->nupvalues; i++) {
480 if (c->upvals[i]->v == o) { 480 if (c->upvals[i]->v == o) {
@@ -535,7 +535,7 @@ static void addinfo (lua_State *L, const char *msg) {
535 if (isLua(ci)) { /* is Lua code? */ 535 if (isLua(ci)) { /* is Lua code? */
536 char buff[LUA_IDSIZE]; /* add file:line information */ 536 char buff[LUA_IDSIZE]; /* add file:line information */
537 int line = currentline(ci); 537 int line = currentline(ci);
538 TString *src = ci_func(ci)->l.p->source; 538 TString *src = ci_func(ci)->p->source;
539 if (src) 539 if (src)
540 luaO_chunkid(buff, getstr(src), LUA_IDSIZE); 540 luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
541 else { /* no source available; use "?" instead */ 541 else { /* no source available; use "?" instead */
diff --git a/ldebug.h b/ldebug.h
index c37c9403..5f865ee8 100644
--- a/ldebug.h
+++ b/ldebug.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.h,v 2.4 2009/04/30 17:42:21 roberto Exp roberto $ 2** $Id: ldebug.h,v 2.5 2009/06/10 16:57:53 roberto Exp roberto $
3** Auxiliary functions from Debug Interface module 3** Auxiliary functions from Debug Interface module
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -17,6 +17,9 @@
17 17
18#define resethookcount(L) (L->hookcount = L->basehookcount) 18#define resethookcount(L) (L->hookcount = L->basehookcount)
19 19
20/* Active Lua function (given call info) */
21#define ci_func(ci) (clLvalue((ci)->func))
22
20 23
21LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o, 24LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o,
22 const char *opname); 25 const char *opname);
diff --git a/ldo.c b/ldo.c
index 63f5fb89..88722dda 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.93 2011/02/23 13:13:10 roberto Exp roberto $ 2** $Id: ldo.c,v 2.94 2011/05/30 16:36:38 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -293,59 +293,59 @@ static StkId tryfuncTM (lua_State *L, StkId func) {
293** returns true if function has been executed (C function) 293** returns true if function has been executed (C function)
294*/ 294*/
295int luaD_precall (lua_State *L, StkId func, int nresults) { 295int luaD_precall (lua_State *L, StkId func, int nresults) {
296 Closure *cl;
297 lua_CFunction f; 296 lua_CFunction f;
298 ptrdiff_t funcr; 297 CallInfo *ci;
299 if (!ttisfunction(func)) /* `func' is not a function? */ 298 int n; /* number of arguments (Lua) or returns (C) */
300 func = tryfuncTM(L, func); /* check the `function' tag method */ 299 ptrdiff_t funcr = savestack(L, func);
301 funcr = savestack(L, func); 300 switch (ttype(func)) {
302 if (ttislcf(func) || (cl = clvalue(func), cl->c.isC)) { /* C function? */ 301 case LUA_TLCF: /* light C function */
303 CallInfo *ci; 302 f = fvalue(func);
304 int n; 303 goto Cfunc;
305 f = (ttislcf(func) ? fvalue(func) : cl->c.f); 304 case LUA_TCCL: { /* C closure */
306 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 305 f = clCvalue(func)->f;
307 ci = next_ci(L); /* now 'enter' new function */ 306 Cfunc:
308 ci->nresults = nresults; 307 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
309 ci->func = restorestack(L, funcr); 308 ci = next_ci(L); /* now 'enter' new function */
310 ci->top = L->top + LUA_MINSTACK; 309 ci->nresults = nresults;
311 lua_assert(ci->top <= L->stack_last); 310 ci->func = restorestack(L, funcr);
312 ci->callstatus = 0; 311 ci->top = L->top + LUA_MINSTACK;
313 if (L->hookmask & LUA_MASKCALL) 312 lua_assert(ci->top <= L->stack_last);
314 luaD_hook(L, LUA_HOOKCALL, -1); 313 ci->callstatus = 0;
315 lua_unlock(L); 314 if (L->hookmask & LUA_MASKCALL)
316 n = (*f)(L); /* do the actual call */ 315 luaD_hook(L, LUA_HOOKCALL, -1);
317 lua_lock(L); 316 lua_unlock(L);
318 api_checknelems(L, n); 317 n = (*f)(L); /* do the actual call */
319 luaD_poscall(L, L->top - n); 318 lua_lock(L);
320 return 1; 319 api_checknelems(L, n);
321 } 320 luaD_poscall(L, L->top - n);
322 else { /* Lua function: prepare its call */ 321 return 1;
323 CallInfo *ci; 322 }
324 int nparams, nargs; 323 case LUA_TLCL: { /* Lua function: prepare its call */
325 StkId base; 324 StkId base;
326 Proto *p = cl->l.p; 325 Proto *p = clLvalue(func)->p;
327 luaD_checkstack(L, p->maxstacksize); 326 luaD_checkstack(L, p->maxstacksize);
328 func = restorestack(L, funcr); 327 func = restorestack(L, funcr);
329 nargs = cast_int(L->top - func) - 1; /* number of real arguments */ 328 n = cast_int(L->top - func) - 1; /* number of real arguments */
330 nparams = p->numparams; /* number of expected parameters */ 329 for (; n < p->numparams; n++)
331 for (; nargs < nparams; nargs++) 330 setnilvalue(L->top++); /* complete missing arguments */
332 setnilvalue(L->top++); /* complete missing arguments */ 331 base = (!p->is_vararg) ? func + 1 : adjust_varargs(L, p, n);
333 if (!p->is_vararg) /* no varargs? */ 332 ci = next_ci(L); /* now 'enter' new function */
334 base = func + 1; 333 ci->nresults = nresults;
335 else /* vararg function */ 334 ci->func = func;
336 base = adjust_varargs(L, p, nargs); 335 ci->u.l.base = base;
337 ci = next_ci(L); /* now 'enter' new function */ 336 ci->top = base + p->maxstacksize;
338 ci->nresults = nresults; 337 lua_assert(ci->top <= L->stack_last);
339 ci->func = func; 338 ci->u.l.savedpc = p->code; /* starting point */
340 ci->u.l.base = base; 339 ci->callstatus = CIST_LUA;
341 ci->top = base + p->maxstacksize; 340 L->top = ci->top;
342 lua_assert(ci->top <= L->stack_last); 341 if (L->hookmask & LUA_MASKCALL)
343 ci->u.l.savedpc = p->code; /* starting point */ 342 callhook(L, ci);
344 ci->callstatus = CIST_LUA; 343 return 0;
345 L->top = ci->top; 344 }
346 if (L->hookmask & LUA_MASKCALL) 345 default: { /* not a function */
347 callhook(L, ci); 346 func = tryfuncTM(L, func); /* retry with 'function' tag method */
348 return 0; 347 return luaD_precall(L, func, nresults);
348 }
349 } 349 }
350} 350}
351 351
@@ -626,7 +626,7 @@ static void f_parser (lua_State *L, void *ud) {
626 setptvalue2s(L, L->top, tf); 626 setptvalue2s(L, L->top, tf);
627 incr_top(L); 627 incr_top(L);
628 cl = luaF_newLclosure(L, tf); 628 cl = luaF_newLclosure(L, tf);
629 setclvalue(L, L->top - 1, cl); 629 setclLvalue(L, L->top - 1, cl);
630 for (i = 0; i < tf->sizeupvalues; i++) /* initialize upvalues */ 630 for (i = 0; i < tf->sizeupvalues; i++) /* initialize upvalues */
631 cl->l.upvals[i] = luaF_newupval(L); 631 cl->l.upvals[i] = luaF_newupval(L);
632} 632}
diff --git a/lobject.h b/lobject.h
index f5941839..daa46472 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 2.55 2011/05/31 18:24:36 roberto Exp roberto $ 2** $Id: lobject.h,v 2.56 2011/05/31 19:15:01 roberto Exp roberto $
3** Type definitions for Lua objects 3** Type definitions for Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -32,17 +32,25 @@
32/* 32/*
33** tags for Tagged Values have the following use of bits: 33** tags for Tagged Values have the following use of bits:
34** bits 0-3: actual tag (a LUA_T* value) 34** bits 0-3: actual tag (a LUA_T* value)
35** bit 4: variant bit (for functions, means a light C function) 35** bits 4-5: variant bits
36** bit 5: whether value is collectable 36** bit 6: whether value is collectable
37*/ 37*/
38 38
39/* Variant tag for light C functions */ 39/*
40#define BIT_ISVARIANT (1 << 4) 40** LUA_TFUNCTION variants:
41#define LUA_TLCF (LUA_TFUNCTION | BIT_ISVARIANT) 41** 0 - Lua function
42** 1 - light C function
43** 2 - regular C function (closure)
44*/
45
46/* Variant tags for functions */
47#define LUA_TLCL (LUA_TFUNCTION | (0 << 4)) /* Lua closure */
48#define LUA_TLCF (LUA_TFUNCTION | (1 << 4)) /* light C function */
49#define LUA_TCCL (LUA_TFUNCTION | (2 << 4)) /* C closure */
42 50
43 51
44/* Bit mark for collectable types */ 52/* Bit mark for collectable types */
45#define BIT_ISCOLLECTABLE (1 << 5) 53#define BIT_ISCOLLECTABLE (1 << 6)
46 54
47/* mark a tag as collectable */ 55/* mark a tag as collectable */
48#define ctb(t) ((t) | BIT_ISCOLLECTABLE) 56#define ctb(t) ((t) | BIT_ISCOLLECTABLE)
@@ -106,8 +114,8 @@ typedef struct lua_TValue {
106/* raw type tag of a TValue */ 114/* raw type tag of a TValue */
107#define rttype(o) ((o)->tt_) 115#define rttype(o) ((o)->tt_)
108 116
109/* type tag of a TValue (bits 0-3 for tags + variant bit) */ 117/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
110#define ttype(o) (rttype(o) & 0x1F) 118#define ttype(o) (rttype(o) & 0x3F)
111 119
112 120
113/* type tag of a TValue with no variants (bits 0-3) */ 121/* type tag of a TValue with no variants (bits 0-3) */
@@ -123,7 +131,9 @@ typedef struct lua_TValue {
123#define ttisstring(o) checktag((o), ctb(LUA_TSTRING)) 131#define ttisstring(o) checktag((o), ctb(LUA_TSTRING))
124#define ttistable(o) checktag((o), ctb(LUA_TTABLE)) 132#define ttistable(o) checktag((o), ctb(LUA_TTABLE))
125#define ttisfunction(o) (ttypenv(o) == LUA_TFUNCTION) 133#define ttisfunction(o) (ttypenv(o) == LUA_TFUNCTION)
126#define ttisclosure(o) checktag((o), ctb(LUA_TFUNCTION)) 134#define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION)
135#define ttisCclosure(o) checktag((o), ctb(LUA_TCCL))
136#define ttisLclosure(o) checktag((o), ctb(LUA_TLCL))
127#define ttislcf(o) checktag((o), LUA_TLCF) 137#define ttislcf(o) checktag((o), LUA_TLCF)
128#define ttisuserdata(o) checktag((o), ctb(LUA_TUSERDATA)) 138#define ttisuserdata(o) checktag((o), ctb(LUA_TUSERDATA))
129#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD)) 139#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD))
@@ -140,6 +150,8 @@ typedef struct lua_TValue {
140#define rawuvalue(o) check_exp(ttisuserdata(o), &val_(o).gc->u) 150#define rawuvalue(o) check_exp(ttisuserdata(o), &val_(o).gc->u)
141#define uvalue(o) (&rawuvalue(o)->uv) 151#define uvalue(o) (&rawuvalue(o)->uv)
142#define clvalue(o) check_exp(ttisclosure(o), &val_(o).gc->cl) 152#define clvalue(o) check_exp(ttisclosure(o), &val_(o).gc->cl)
153#define clLvalue(o) check_exp(ttisLclosure(o), &val_(o).gc->cl.l)
154#define clCvalue(o) check_exp(ttisCclosure(o), &val_(o).gc->cl.c)
143#define fvalue(o) check_exp(ttislcf(o), val_(o).f) 155#define fvalue(o) check_exp(ttislcf(o), val_(o).f)
144#define hvalue(o) check_exp(ttistable(o), &val_(o).gc->h) 156#define hvalue(o) check_exp(ttistable(o), &val_(o).gc->h)
145#define bvalue(o) check_exp(ttisboolean(o), val_(o).b) 157#define bvalue(o) check_exp(ttisboolean(o), val_(o).b)
@@ -152,7 +164,7 @@ typedef struct lua_TValue {
152 164
153 165
154/* Macros for internal tests */ 166/* Macros for internal tests */
155#define righttt(obj) (ttype(obj) == gcvalue(obj)->gch.tt) 167#define righttt(obj) (ttypenv(obj) == gcvalue(obj)->gch.tt)
156 168
157#define checkliveness(g,obj) \ 169#define checkliveness(g,obj) \
158 lua_longassert(!iscollectable(obj) || \ 170 lua_longassert(!iscollectable(obj) || \
@@ -197,9 +209,14 @@ typedef struct lua_TValue {
197 val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTHREAD)); \ 209 val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTHREAD)); \
198 checkliveness(G(L),io); } 210 checkliveness(G(L),io); }
199 211
200#define setclvalue(L,obj,x) \ 212#define setclLvalue(L,obj,x) \
213 { TValue *io=(obj); \
214 val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TLCL)); \
215 checkliveness(G(L),io); }
216
217#define setclCvalue(L,obj,x) \
201 { TValue *io=(obj); \ 218 { TValue *io=(obj); \
202 val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TFUNCTION)); \ 219 val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TCCL)); \
203 checkliveness(G(L),io); } 220 checkliveness(G(L),io); }
204 221
205#define sethvalue(L,obj,x) \ 222#define sethvalue(L,obj,x) \
@@ -375,9 +392,9 @@ typedef union Closure {
375} Closure; 392} Closure;
376 393
377 394
378#define isLfunction(o) (ttisclosure(o) && !clvalue(o)->c.isC) 395#define isLfunction(o) ttisLclosure(o)
379 396
380#define getproto(o) (clvalue(o)->l.p) 397#define getproto(o) (clLvalue(o)->p)
381 398
382 399
383/* 400/*
diff --git a/lstate.h b/lstate.h
index 6bf691b2..606bb669 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 2.70 2010/12/20 18:17:46 roberto Exp roberto $ 2** $Id: lstate.h,v 2.71 2010/12/20 19:40:07 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -104,7 +104,6 @@ typedef struct CallInfo {
104#define CIST_TAIL (1<<6) /* call was tail called */ 104#define CIST_TAIL (1<<6) /* call was tail called */
105 105
106 106
107#define ci_func(ci) (clvalue((ci)->func))
108#define isLua(ci) ((ci)->callstatus & CIST_LUA) 107#define isLua(ci) ((ci)->callstatus & CIST_LUA)
109 108
110 109
diff --git a/ltable.c b/ltable.c
index 410411f1..e4ff8dd5 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 2.56 2011/05/31 18:24:36 roberto Exp roberto $ 2** $Id: ltable.c,v 2.57 2011/05/31 18:27:56 roberto Exp roberto $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -468,7 +468,7 @@ const TValue *luaH_getstr (Table *t, TString *key) {
468** main search function 468** main search function
469*/ 469*/
470const TValue *luaH_get (Table *t, const TValue *key) { 470const TValue *luaH_get (Table *t, const TValue *key) {
471 switch (ttype(key)) { 471 switch (ttypenv(key)) {
472 case LUA_TNIL: return luaO_nilobject; 472 case LUA_TNIL: return luaO_nilobject;
473 case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key)); 473 case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
474 case LUA_TNUMBER: { 474 case LUA_TNUMBER: {
diff --git a/ltests.c b/ltests.c
index ec30724c..52071bf1 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 2.117 2011/05/05 16:18:53 roberto Exp roberto $ 2** $Id: ltests.c,v 2.118 2011/05/25 14:12:28 roberto Exp roberto $
3** Internal Module for Debugging of the Lua Implementation 3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -291,7 +291,7 @@ static void checkclosure (global_State *g, Closure *cl) {
291static int lua_checkpc (pCallInfo ci) { 291static int lua_checkpc (pCallInfo ci) {
292 if (!isLua(ci)) return 1; 292 if (!isLua(ci)) return 1;
293 else { 293 else {
294 Proto *p = ci_func(ci)->l.p; 294 Proto *p = ci_func(ci)->p;
295 return p->code <= ci->u.l.savedpc && 295 return p->code <= ci->u.l.savedpc &&
296 ci->u.l.savedpc <= p->code + p->sizecode; 296 ci->u.l.savedpc <= p->code + p->sizecode;
297 } 297 }
diff --git a/ltm.c b/ltm.c
index e411606d..35934058 100644
--- a/ltm.c
+++ b/ltm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.c,v 2.12 2010/04/13 20:48:12 roberto Exp roberto $ 2** $Id: ltm.c,v 2.13 2011/02/28 17:32:10 roberto Exp roberto $
3** Tag methods 3** Tag methods
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -62,7 +62,7 @@ const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
62 62
63const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) { 63const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
64 Table *mt; 64 Table *mt;
65 switch (ttype(o)) { 65 switch (ttypenv(o)) {
66 case LUA_TTABLE: 66 case LUA_TTABLE:
67 mt = hvalue(o)->metatable; 67 mt = hvalue(o)->metatable;
68 break; 68 break;
diff --git a/lvm.c b/lvm.c
index 357aba17..8929dfb3 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.138 2011/05/31 18:24:36 roberto Exp roberto $ 2** $Id: lvm.c,v 2.139 2011/05/31 18:27:56 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -65,7 +65,7 @@ static void traceexec (lua_State *L) {
65 luaD_hook(L, LUA_HOOKCOUNT, -1); 65 luaD_hook(L, LUA_HOOKCOUNT, -1);
66 } 66 }
67 if (mask & LUA_MASKLINE) { 67 if (mask & LUA_MASKLINE) {
68 Proto *p = ci_func(ci)->l.p; 68 Proto *p = ci_func(ci)->p;
69 int npc = pcRel(ci->u.l.savedpc, p); 69 int npc = pcRel(ci->u.l.savedpc, p);
70 int newline = getfuncline(p, npc); 70 int newline = getfuncline(p, npc);
71 if (npc == 0 || /* call linehook when enter a new function, */ 71 if (npc == 0 || /* call linehook when enter a new function, */
@@ -315,7 +315,7 @@ void luaV_concat (lua_State *L, int total) {
315 315
316void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { 316void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
317 const TValue *tm; 317 const TValue *tm;
318 switch (ttype(rb)) { 318 switch (ttypenv(rb)) {
319 case LUA_TTABLE: { 319 case LUA_TTABLE: {
320 Table *h = hvalue(rb); 320 Table *h = hvalue(rb);
321 tm = fasttm(L, h->metatable, TM_LEN); 321 tm = fasttm(L, h->metatable, TM_LEN);
@@ -385,7 +385,7 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
385 Upvaldesc *uv = p->upvalues; 385 Upvaldesc *uv = p->upvalues;
386 int i; 386 int i;
387 Closure *ncl = luaF_newLclosure(L, p); 387 Closure *ncl = luaF_newLclosure(L, p);
388 setclvalue(L, ra, ncl); /* anchor new closure in stack */ 388 setclLvalue(L, ra, ncl); /* anchor new closure in stack */
389 for (i = 0; i < nup; i++) { /* fill in its upvalues */ 389 for (i = 0; i < nup; i++) { /* fill in its upvalues */
390 if (uv[i].instack) /* upvalue refers to local variable? */ 390 if (uv[i].instack) /* upvalue refers to local variable? */
391 ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx); 391 ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx);
@@ -512,9 +512,8 @@ void luaV_execute (lua_State *L) {
512 TValue *k; 512 TValue *k;
513 StkId base; 513 StkId base;
514 newframe: /* reentry point when frame changes (call/return) */ 514 newframe: /* reentry point when frame changes (call/return) */
515 lua_assert(isLua(ci));
516 lua_assert(ci == L->ci); 515 lua_assert(ci == L->ci);
517 cl = &clvalue(ci->func)->l; 516 cl = clLvalue(ci->func);
518 k = cl->p->k; 517 k = cl->p->k;
519 base = ci->u.l.base; 518 base = ci->u.l.base;
520 /* main loop of interpreter */ 519 /* main loop of interpreter */
@@ -819,7 +818,7 @@ void luaV_execute (lua_State *L) {
819 if (ncl == NULL) /* no match? */ 818 if (ncl == NULL) /* no match? */
820 pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ 819 pushclosure(L, p, cl->upvals, base, ra); /* create a new one */
821 else 820 else
822 setclvalue(L, ra, ncl); /* push cashed closure */ 821 setclLvalue(L, ra, ncl); /* push cashed closure */
823 checkGC(L, 822 checkGC(L,
824 L->top = ra + 1; /* limit of live values */ 823 L->top = ra + 1; /* limit of live values */
825 luaC_step(L); 824 luaC_step(L);