aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-03-07 15:09:25 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-03-07 15:09:25 -0300
commit6048c4f74d7d63d6c2f5a53cd8e4ee01f6702be9 (patch)
tree1f8fd00995288958a32ebd8f97863c5f1cb8f776
parent5e870f86a255988ca85eda795adc31063ec1ac70 (diff)
downloadlua-6048c4f74d7d63d6c2f5a53cd8e4ee01f6702be9.tar.gz
lua-6048c4f74d7d63d6c2f5a53cd8e4ee01f6702be9.tar.bz2
lua-6048c4f74d7d63d6c2f5a53cd8e4ee01f6702be9.zip
better way to link callinfo's and stack
-rw-r--r--lapi.c22
-rw-r--r--ldblib.c4
-rw-r--r--ldebug.c174
-rw-r--r--ldo.c47
-rw-r--r--ldo.h4
-rw-r--r--lgc.c9
-rw-r--r--lobject.h22
-rw-r--r--lstate.c4
-rw-r--r--lstate.h11
-rw-r--r--luadebug.h4
-rw-r--r--lvm.c16
11 files changed, 138 insertions, 179 deletions
diff --git a/lapi.c b/lapi.c
index 87131794..aa628469 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 1.134 2001/02/23 17:28:12 roberto Exp roberto $ 2** $Id: lapi.c,v 1.135 2001/03/02 17:27:50 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*/
@@ -31,7 +31,7 @@ const l_char lua_ident[] = l_s("$Lua: ") LUA_VERSION l_s(" ")
31#define api_check(L, o) /* nothing */ 31#define api_check(L, o) /* nothing */
32#endif 32#endif
33 33
34#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->Cbase)) 34#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->ci->base))
35 35
36#define api_incr_top(L) incr_top 36#define api_incr_top(L) incr_top
37 37
@@ -39,11 +39,11 @@ const l_char lua_ident[] = l_s("$Lua: ") LUA_VERSION l_s(" ")
39 39
40TObject *luaA_index (lua_State *L, int index) { 40TObject *luaA_index (lua_State *L, int index) {
41 if (index > 0) { 41 if (index > 0) {
42 api_check(L, index <= L->top - L->Cbase); 42 api_check(L, index <= L->top - L->ci->base);
43 return L->Cbase+index-1; 43 return L->ci->base+index-1;
44 } 44 }
45 else { 45 else {
46 api_check(L, index != 0 && -index <= L->top - L->Cbase); 46 api_check(L, index != 0 && -index <= L->top - L->ci->base);
47 return L->top+index; 47 return L->top+index;
48 } 48 }
49} 49}
@@ -51,13 +51,13 @@ TObject *luaA_index (lua_State *L, int index) {
51 51
52static TObject *luaA_indexAcceptable (lua_State *L, int index) { 52static TObject *luaA_indexAcceptable (lua_State *L, int index) {
53 if (index > 0) { 53 if (index > 0) {
54 TObject *o = L->Cbase+(index-1); 54 TObject *o = L->ci->base+(index-1);
55 api_check(L, index <= L->stack_last - L->Cbase); 55 api_check(L, index <= L->stack_last - L->ci->base);
56 if (o >= L->top) return NULL; 56 if (o >= L->top) return NULL;
57 else return o; 57 else return o;
58 } 58 }
59 else { 59 else {
60 api_check(L, index != 0 && -index <= L->top - L->Cbase); 60 api_check(L, index != 0 && -index <= L->top - L->ci->base);
61 return L->top+index; 61 return L->top+index;
62 } 62 }
63} 63}
@@ -86,7 +86,7 @@ LUA_API int lua_stackspace (lua_State *L) {
86LUA_API int lua_gettop (lua_State *L) { 86LUA_API int lua_gettop (lua_State *L) {
87 int i; 87 int i;
88 lua_lock(L); 88 lua_lock(L);
89 i = (L->top - L->Cbase); 89 i = (L->top - L->ci->base);
90 lua_unlock(L); 90 lua_unlock(L);
91 return i; 91 return i;
92} 92}
@@ -95,9 +95,9 @@ LUA_API int lua_gettop (lua_State *L) {
95LUA_API void lua_settop (lua_State *L, int index) { 95LUA_API void lua_settop (lua_State *L, int index) {
96 lua_lock(L); 96 lua_lock(L);
97 if (index >= 0) 97 if (index >= 0)
98 luaD_adjusttop(L, L->Cbase, index); 98 luaD_adjusttop(L, L->ci->base, index);
99 else { 99 else {
100 api_check(L, -(index+1) <= (L->top - L->Cbase)); 100 api_check(L, -(index+1) <= (L->top - L->ci->base));
101 L->top = L->top+index+1; /* index is negative */ 101 L->top = L->top+index+1; /* index is negative */
102 } 102 }
103 lua_unlock(L); 103 lua_unlock(L);
diff --git a/ldblib.c b/ldblib.c
index 9bdbe5d2..98faf5a7 100644
--- a/ldblib.c
+++ b/ldblib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldblib.c,v 1.33 2001/02/23 17:17:25 roberto Exp roberto $ 2** $Id: ldblib.c,v 1.34 2001/03/06 20:09:38 roberto Exp roberto $
3** Interface from Lua to its debug API 3** Interface from Lua to its debug API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -121,7 +121,7 @@ static void hookf (lua_State *L, void *key) {
121 lua_pushuserdata(L, key); 121 lua_pushuserdata(L, key);
122 lua_gettable(L, -2); 122 lua_gettable(L, -2);
123 if (lua_isfunction(L, -1)) { 123 if (lua_isfunction(L, -1)) {
124 lua_pushvalue(L, 1); 124 lua_pushvalue(L, -3); /* original argument (below table and function) */
125 lua_rawcall(L, 1, 0); 125 lua_rawcall(L, 1, 0);
126 } 126 }
127 else 127 else
diff --git a/ldebug.c b/ldebug.c
index ea11cefd..c3bf8756 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 1.72 2001/03/06 14:46:54 roberto Exp roberto $ 2** $Id: ldebug.c,v 1.73 2001/03/07 13:22:55 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*/
@@ -24,19 +24,14 @@
24 24
25 25
26 26
27static const l_char *getfuncname (lua_State *L, StkId f, const l_char **name); 27static const l_char *getfuncname (lua_State *L, CallInfo *ci,
28 const l_char **name);
28 29
29 30
30static void setnormalized (TObject *d, const TObject *s) {
31 if (ttype(s) == LUA_TMARK) {
32 setclvalue(d, infovalue(s)->func);
33 }
34 else setobj(d, s);
35}
36
37 31
38static int isLmark (StkId o) { 32static int isLmark (CallInfo *ci) {
39 return (o && ttype(o) == LUA_TMARK && !infovalue(o)->func->isC); 33 lua_assert(ci == NULL || ttype(ci->base - 1) == LUA_TFUNCTION);
34 return (ci && ci->prev && !ci_func(ci)->isC);
40} 35}
41 36
42 37
@@ -60,27 +55,25 @@ LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func) {
60} 55}
61 56
62 57
63static StkId aux_stackedfunction (lua_State *L, int level, StkId top) { 58static CallInfo *ci_stack (lua_State *L, StkId obj) {
64 int i; 59 CallInfo *ci = L->ci;
65 for (i = (top-1) - L->stack; i>=0; i--) { 60 while (ci->base > obj) ci = ci->prev;
66 if (is_T_MARK(&L->stack[i])) { 61 return (ci != &L->basefunc) ? ci : NULL;
67 if (level == 0)
68 return L->stack+i;
69 level--;
70 }
71 }
72 return NULL;
73} 62}
74 63
75 64
76LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { 65LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
77 StkId f; 66 CallInfo *ci;
78 int status; 67 int status;
79 lua_lock(L); 68 lua_lock(L);
80 f = aux_stackedfunction(L, level, L->top); 69 ci = L->ci;
81 if (f == NULL) status = 0; /* there is no such level */ 70 while (level-- && ci != &L->basefunc) {
71 lua_assert(ci->base > ci->prev->base);
72 ci = ci->prev;
73 }
74 if (ci == &L->basefunc) status = 0; /* there is no such level */
82 else { 75 else {
83 ar->_func = f; 76 ar->_ci = ci;
84 status = 1; 77 status = 1;
85 } 78 }
86 lua_unlock(L); 79 lua_unlock(L);
@@ -88,18 +81,6 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
88} 81}
89 82
90 83
91static int nups (StkId f) {
92 switch (ttype(f)) {
93 case LUA_TFUNCTION:
94 return clvalue(f)->nupvalues;
95 case LUA_TMARK:
96 return infovalue(f)->func->nupvalues;
97 default:
98 return 0;
99 }
100}
101
102
103int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) { 84int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) {
104 int refi; 85 int refi;
105 if (lineinfo == NULL || pc == -1) 86 if (lineinfo == NULL || pc == -1)
@@ -131,45 +112,43 @@ int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) {
131} 112}
132 113
133 114
134static int currentpc (StkId f) { 115static int currentpc (CallInfo *ci) {
135 CallInfo *ci = infovalue(f); 116 lua_assert(isLmark(ci));
136 lua_assert(isLmark(f));
137 if (ci->pc) 117 if (ci->pc)
138 return (*ci->pc - ci->func->f.l->code) - 1; 118 return (*ci->pc - ci_func(ci)->f.l->code) - 1;
139 else 119 else
140 return -1; /* function is not active */ 120 return -1; /* function is not active */
141} 121}
142 122
143 123
144static int currentline (StkId f) { 124static int currentline (CallInfo *ci) {
145 if (!isLmark(f)) 125 if (!isLmark(ci))
146 return -1; /* only active lua functions have current-line information */ 126 return -1; /* only active lua functions have current-line information */
147 else { 127 else {
148 CallInfo *ci = infovalue(f); 128 int *lineinfo = ci_func(ci)->f.l->lineinfo;
149 int *lineinfo = ci->func->f.l->lineinfo; 129 return luaG_getline(lineinfo, currentpc(ci), 1, NULL);
150 return luaG_getline(lineinfo, currentpc(f), 1, NULL);
151 } 130 }
152} 131}
153 132
154 133
155 134
156static Proto *getluaproto (StkId f) { 135static Proto *getluaproto (CallInfo *ci) {
157 return (isLmark(f) ? infovalue(f)->func->f.l : NULL); 136 return (isLmark(ci) ? ci_func(ci)->f.l : NULL);
158} 137}
159 138
160 139
161LUA_API const l_char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { 140LUA_API const l_char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
162 const l_char *name; 141 const l_char *name;
163 StkId f; 142 CallInfo *ci;
164 Proto *fp; 143 Proto *fp;
165 lua_lock(L); 144 lua_lock(L);
166 name = NULL; 145 name = NULL;
167 f = ar->_func; 146 ci = ar->_ci;
168 fp = getluaproto(f); 147 fp = getluaproto(ci);
169 if (fp) { /* `f' is a Lua function? */ 148 if (fp) { /* is a Lua function? */
170 name = luaF_getlocalname(fp, n, currentpc(f)); 149 name = luaF_getlocalname(fp, n, currentpc(ci));
171 if (name) 150 if (name)
172 luaA_pushobject(L, (f+1)+(n-1)); /* push value */ 151 luaA_pushobject(L, ci->base+(n-1)); /* push value */
173 } 152 }
174 lua_unlock(L); 153 lua_unlock(L);
175 return name; 154 return name;
@@ -178,19 +157,19 @@ LUA_API const l_char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
178 157
179LUA_API const l_char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { 158LUA_API const l_char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
180 const l_char *name; 159 const l_char *name;
181 StkId f; 160 CallInfo *ci;
182 Proto *fp; 161 Proto *fp;
183 lua_lock(L); 162 lua_lock(L);
184 name = NULL; 163 name = NULL;
185 f = ar->_func; 164 ci = ar->_ci;
186 fp = getluaproto(f); 165 fp = getluaproto(ci);
187 L->top--; /* pop new value */ 166 L->top--; /* pop new value */
188 if (fp) { /* `f' is a Lua function? */ 167 if (fp) { /* is a Lua function? */
189 name = luaF_getlocalname(fp, n, currentpc(f)); 168 name = luaF_getlocalname(fp, n, currentpc(ci));
190 if (!name || name[0] == l_c('(')) /* `(' starts private locals */ 169 if (!name || name[0] == l_c('(')) /* `(' starts private locals */
191 name = NULL; 170 name = NULL;
192 else 171 else
193 setobj((f+1)+(n-1), L->top); 172 setobj(ci->base+(n-1), L->top);
194 } 173 }
195 lua_unlock(L); 174 lua_unlock(L);
196 return name; 175 return name;
@@ -205,16 +184,12 @@ static void infoLproto (lua_Debug *ar, Proto *f) {
205 184
206 185
207static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) { 186static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) {
208 Closure *cl = NULL; 187 Closure *cl;
209 switch (ttype(func)) { 188 if (ttype(func) == LUA_TFUNCTION)
210 case LUA_TFUNCTION: 189 cl = clvalue(func);
211 cl = clvalue(func); 190 else {
212 break; 191 luaD_error(L, l_s("value for `lua_getinfo' is not a function"));
213 case LUA_TMARK: 192 cl = NULL; /* to avoid warnings */
214 cl = infovalue(func)->func;
215 break;
216 default:
217 luaD_error(L, l_s("value for `lua_getinfo' is not a function"));
218 } 193 }
219 if (cl->isC) { 194 if (cl->isC) {
220 ar->source = l_s("=C"); 195 ar->source = l_s("=C");
@@ -255,60 +230,60 @@ static const l_char *travglobals (lua_State *L, const TObject *o) {
255} 230}
256 231
257 232
258static void getname (lua_State *L, StkId f, lua_Debug *ar) { 233static void getname (lua_State *L, const TObject *f, lua_Debug *ar) {
259 TObject o;
260 setnormalized(&o, f);
261 /* try to find a name for given function */ 234 /* try to find a name for given function */
262 if ((ar->name = travglobals(L, &o)) != NULL) 235 if ((ar->name = travglobals(L, f)) != NULL)
263 ar->namewhat = l_s("global"); 236 ar->namewhat = l_s("global");
264 /* not found: try tag methods */ 237 /* not found: try tag methods */
265 else if ((ar->name = travtagmethods(G(L), &o)) != NULL) 238 else if ((ar->name = travtagmethods(G(L), f)) != NULL)
266 ar->namewhat = l_s("tag-method"); 239 ar->namewhat = l_s("tag-method");
267 else ar->namewhat = l_s(""); /* not found at all */ 240 else ar->namewhat = l_s(""); /* not found at all */
268} 241}
269 242
270 243
271LUA_API int lua_getinfo (lua_State *L, const l_char *what, lua_Debug *ar) { 244LUA_API int lua_getinfo (lua_State *L, const l_char *what, lua_Debug *ar) {
272 StkId func; 245 StkId f;
273 int isactive; 246 CallInfo *ci;
274 int status = 1; 247 int status = 1;
275 lua_lock(L); 248 lua_lock(L);
276 isactive = (*what != l_c('>')); 249 if (*what != l_c('>')) { /* function is active? */
277 if (isactive) 250 ci = ar->_ci;
278 func = ar->_func; 251 f = ci->base - 1;
252 }
279 else { 253 else {
280 what++; /* skip the `>' */ 254 what++; /* skip the `>' */
281 func = L->top - 1; 255 ci = NULL;
256 f = L->top - 1;
282 } 257 }
283 for (; *what; what++) { 258 for (; *what; what++) {
284 switch (*what) { 259 switch (*what) {
285 case l_c('S'): { 260 case l_c('S'): {
286 funcinfo(L, ar, func); 261 funcinfo(L, ar, f);
287 break; 262 break;
288 } 263 }
289 case l_c('l'): { 264 case l_c('l'): {
290 ar->currentline = currentline(func); 265 ar->currentline = currentline(ci);
291 break; 266 break;
292 } 267 }
293 case l_c('u'): { 268 case l_c('u'): {
294 ar->nups = nups(func); 269 ar->nups = (ttype(f) == LUA_TFUNCTION) ? clvalue(f)->nupvalues : 0;
295 break; 270 break;
296 } 271 }
297 case l_c('n'): { 272 case l_c('n'): {
298 ar->namewhat = (isactive) ? getfuncname(L, func, &ar->name) : NULL; 273 ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL;
299 if (ar->namewhat == NULL) 274 if (ar->namewhat == NULL)
300 getname(L, func, ar); 275 getname(L, f, ar);
301 break; 276 break;
302 } 277 }
303 case l_c('f'): { 278 case l_c('f'): {
304 setnormalized(L->top, func); 279 setobj(L->top, f);
305 incr_top; /* push function */ 280 incr_top; /* push function */
306 break; 281 break;
307 } 282 }
308 default: status = 0; /* invalid option */ 283 default: status = 0; /* invalid option */
309 } 284 }
310 } 285 }
311 if (!isactive) L->top--; /* pop function */ 286 if (!ci) L->top--; /* pop function */
312 lua_unlock(L); 287 lua_unlock(L);
313 return status; 288 return status;
314} 289}
@@ -539,13 +514,13 @@ int luaG_checkcode (lua_State *L, const Proto *pt) {
539 514
540 515
541static const l_char *getobjname (lua_State *L, StkId obj, const l_char **name) { 516static const l_char *getobjname (lua_State *L, StkId obj, const l_char **name) {
542 StkId func = aux_stackedfunction(L, 0, obj); 517 CallInfo *ci = ci_stack(L, obj);
543 if (!isLmark(func)) 518 if (!isLmark(ci))
544 return NULL; /* not an active Lua function */ 519 return NULL; /* not an active Lua function */
545 else { 520 else {
546 Proto *p = infovalue(func)->func->f.l; 521 Proto *p = ci_func(ci)->f.l;
547 int pc = currentpc(func); 522 int pc = currentpc(ci);
548 int stackpos = obj - (func+1); /* func+1 == function base */ 523 int stackpos = obj - ci->base;
549 Instruction i = luaG_symbexec(L, p, pc, stackpos); 524 Instruction i = luaG_symbexec(L, p, pc, stackpos);
550 lua_assert(pc != -1); 525 lua_assert(pc != -1);
551 switch (GET_OPCODE(i)) { 526 switch (GET_OPCODE(i)) {
@@ -570,18 +545,19 @@ static const l_char *getobjname (lua_State *L, StkId obj, const l_char **name) {
570} 545}
571 546
572 547
573static const l_char *getfuncname (lua_State *L, StkId f, const l_char **name) { 548static const l_char *getfuncname (lua_State *L, CallInfo *ci,
574 StkId func = aux_stackedfunction(L, 0, f); /* calling function */ 549 const l_char **name) {
575 if (!isLmark(func)) 550 ci = ci->prev; /* calling function */
551 if (ci == &L->basefunc || !isLmark(ci))
576 return NULL; /* not an active Lua function */ 552 return NULL; /* not an active Lua function */
577 else { 553 else {
578 Proto *p = infovalue(func)->func->f.l; 554 Proto *p = ci_func(ci)->f.l;
579 int pc = currentpc(func); 555 int pc = currentpc(ci);
580 Instruction i; 556 Instruction i;
581 if (pc == -1) return NULL; /* function is not activated */ 557 if (pc == -1) return NULL; /* function is not activated */
582 i = p->code[pc]; 558 i = p->code[pc];
583 return (GET_OPCODE(i) == OP_CALL 559 return (GET_OPCODE(i) == OP_CALL
584 ? getobjname(L, (func+1)+GETARG_A(i), name) 560 ? getobjname(L, ci->base+GETARG_A(i), name)
585 : NULL); /* no useful name found */ 561 : NULL); /* no useful name found */
586 } 562 }
587} 563}
diff --git a/ldo.c b/ldo.c
index fb6233be..95db67a3 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.129 2001/02/23 17:28:12 roberto Exp roberto $ 2** $Id: ldo.c,v 1.130 2001/03/02 17:27:50 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*/
@@ -42,7 +42,7 @@ void luaD_init (lua_State *L, int stacksize) {
42 stacksize += EXTRA_STACK; 42 stacksize += EXTRA_STACK;
43 L->stack = luaM_newvector(L, stacksize, TObject); 43 L->stack = luaM_newvector(L, stacksize, TObject);
44 L->stacksize = stacksize; 44 L->stacksize = stacksize;
45 L->Cbase = L->top = L->stack; 45 L->basefunc.base = L->top = L->stack;
46 restore_stack_limit(L); 46 restore_stack_limit(L);
47} 47}
48 48
@@ -90,8 +90,7 @@ static void luaD_openstack (lua_State *L, StkId pos) {
90 90
91 91
92static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) { 92static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) {
93 StkId old_Cbase = L->Cbase; 93 StkId old_top = L->top;
94 StkId old_top = L->Cbase = L->top;
95 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 94 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
96 L->allowhooks = 0; /* cannot call hooks inside a hook */ 95 L->allowhooks = 0; /* cannot call hooks inside a hook */
97 lua_unlock(L); 96 lua_unlock(L);
@@ -100,45 +99,41 @@ static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) {
100 lua_assert(L->allowhooks == 0); 99 lua_assert(L->allowhooks == 0);
101 L->allowhooks = 1; 100 L->allowhooks = 1;
102 L->top = old_top; 101 L->top = old_top;
103 L->Cbase = old_Cbase;
104} 102}
105 103
106 104
107void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook) { 105void luaD_lineHook (lua_State *L, int line, lua_Hook linehook) {
108 if (L->allowhooks) { 106 if (L->allowhooks) {
109 lua_Debug ar; 107 lua_Debug ar;
110 ar._func = func;
111 ar.event = l_s("line"); 108 ar.event = l_s("line");
109 ar._ci = L->ci;
112 ar.currentline = line; 110 ar.currentline = line;
113 dohook(L, &ar, linehook); 111 dohook(L, &ar, linehook);
114 } 112 }
115} 113}
116 114
117 115
118static void luaD_callHook (lua_State *L, StkId func, lua_Hook callhook, 116static void luaD_callHook (lua_State *L, lua_Hook callhook,
119 const l_char *event) { 117 const l_char *event) {
120 if (L->allowhooks) { 118 if (L->allowhooks) {
121 lua_Debug ar; 119 lua_Debug ar;
122 ar._func = func;
123 ar.event = event; 120 ar.event = event;
124 infovalue(func)->pc = NULL; /* function is not active */ 121 ar._ci = L->ci;
122 L->ci->pc = NULL; /* function is not active */
125 dohook(L, &ar, callhook); 123 dohook(L, &ar, callhook);
126 } 124 }
127} 125}
128 126
129 127
130static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) { 128static StkId callCclosure (lua_State *L, const struct Closure *cl) {
131 int nup = cl->nupvalues; /* number of upvalues */ 129 int nup = cl->nupvalues; /* number of upvalues */
132 StkId old_Cbase = L->Cbase;
133 int n; 130 int n;
134 L->Cbase = base; /* new base for C function */
135 luaD_checkstack(L, nup+LUA_MINSTACK); /* ensure minimum stack size */ 131 luaD_checkstack(L, nup+LUA_MINSTACK); /* ensure minimum stack size */
136 for (n=0; n<nup; n++) /* copy upvalues as extra arguments */ 132 for (n=0; n<nup; n++) /* copy upvalues as extra arguments */
137 setobj(L->top++, &cl->upvalue[n]); 133 setobj(L->top++, &cl->upvalue[n]);
138 lua_unlock(L); 134 lua_unlock(L);
139 n = (*cl->f.c)(L); /* do the actual call */ 135 n = (*cl->f.c)(L); /* do the actual call */
140 lua_lock(L); 136 lua_lock(L);
141 L->Cbase = old_Cbase; /* restore old C base */
142 return L->top - n; /* return index of first result */ 137 return L->top - n; /* return index of first result */
143} 138}
144 139
@@ -154,7 +149,6 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
154 lua_Hook callhook; 149 lua_Hook callhook;
155 StkId firstResult; 150 StkId firstResult;
156 CallInfo ci; 151 CallInfo ci;
157 Closure *cl;
158 if (ttype(func) != LUA_TFUNCTION) { 152 if (ttype(func) != LUA_TFUNCTION) {
159 /* `func' is not a function; check the `function' tag method */ 153 /* `func' is not a function; check the `function' tag method */
160 Closure *tm = luaT_gettmbyObj(G(L), func, TM_FUNCTION); 154 Closure *tm = luaT_gettmbyObj(G(L), func, TM_FUNCTION);
@@ -163,18 +157,17 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
163 luaD_openstack(L, func); 157 luaD_openstack(L, func);
164 setclvalue(func, tm); /* tag method is the new function to be called */ 158 setclvalue(func, tm); /* tag method is the new function to be called */
165 } 159 }
166 cl = clvalue(func); 160 ci.prev = L->ci; /* chain new callinfo */
167 ci.func = cl; 161 L->ci = &ci;
168 setivalue(func, &ci); 162 ci.base = func+1;
169 callhook = L->callhook; 163 callhook = L->callhook;
170 if (callhook) 164 if (callhook)
171 luaD_callHook(L, func, callhook, l_s("call")); 165 luaD_callHook(L, callhook, l_s("call"));
172 firstResult = (cl->isC ? callCclosure(L, cl, func+1) : 166 firstResult = (clvalue(func)->isC ? callCclosure(L, clvalue(func)) :
173 luaV_execute(L, cl, func+1)); 167 luaV_execute(L, clvalue(func), func+1));
174 if (callhook) /* same hook that was active at entry */ 168 if (callhook) /* same hook that was active at entry */
175 luaD_callHook(L, func, callhook, l_s("return")); 169 luaD_callHook(L, callhook, l_s("return"));
176 lua_assert(ttype(func) == LUA_TMARK); 170 L->ci = ci.prev; /* unchain callinfo */
177 setnilvalue(func); /* remove callinfo from the stack */
178 /* move results to `func' (to erase parameters and function) */ 171 /* move results to `func' (to erase parameters and function) */
179 if (nResults == LUA_MULTRET) { 172 if (nResults == LUA_MULTRET) {
180 while (firstResult < L->top) /* copy all results */ 173 while (firstResult < L->top) /* copy all results */
@@ -368,7 +361,7 @@ void luaD_breakrun (lua_State *L, int errcode) {
368 361
369 362
370int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) { 363int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) {
371 StkId oldCbase = L->Cbase; 364 CallInfo *oldci = L->ci;
372 StkId oldtop = L->top; 365 StkId oldtop = L->top;
373 struct lua_longjmp lj; 366 struct lua_longjmp lj;
374 int allowhooks = L->allowhooks; 367 int allowhooks = L->allowhooks;
@@ -379,7 +372,7 @@ int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) {
379 (*f)(L, ud); 372 (*f)(L, ud);
380 else { /* an error occurred: restore the state */ 373 else { /* an error occurred: restore the state */
381 L->allowhooks = allowhooks; 374 L->allowhooks = allowhooks;
382 L->Cbase = oldCbase; 375 L->ci = oldci;
383 L->top = oldtop; 376 L->top = oldtop;
384 restore_stack_limit(L); 377 restore_stack_limit(L);
385 } 378 }
diff --git a/ldo.h b/ldo.h
index b4bc94c5..bf8bbe7f 100644
--- a/ldo.h
+++ b/ldo.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.h,v 1.30 2001/02/07 18:13:49 roberto Exp roberto $ 2** $Id: ldo.h,v 1.31 2001/02/23 17:17:25 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*/
@@ -21,7 +21,7 @@
21 21
22void luaD_init (lua_State *L, int stacksize); 22void luaD_init (lua_State *L, int stacksize);
23void luaD_adjusttop (lua_State *L, StkId base, int extra); 23void luaD_adjusttop (lua_State *L, StkId base, int extra);
24void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook); 24void luaD_lineHook (lua_State *L, int line, lua_Hook linehook);
25void luaD_call (lua_State *L, StkId func, int nResults); 25void luaD_call (lua_State *L, StkId func, int nResults);
26void luaD_checkstack (lua_State *L, int n); 26void luaD_checkstack (lua_State *L, int n);
27 27
diff --git a/lgc.c b/lgc.c
index ff4ccaf0..26aa51ff 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.92 2001/02/23 17:17:25 roberto Exp roberto $ 2** $Id: lgc.c,v 1.93 2001/03/02 17:27:50 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -85,9 +85,6 @@ static void markobject (GCState *st, TObject *o) {
85 case LUA_TUSERDATA: case LUA_TSTRING: 85 case LUA_TUSERDATA: case LUA_TSTRING:
86 strmark(tsvalue(o)); 86 strmark(tsvalue(o));
87 break; 87 break;
88 case LUA_TMARK:
89 markclosure(st, infovalue(o)->func);
90 break;
91 case LUA_TFUNCTION: 88 case LUA_TFUNCTION:
92 markclosure(st, clvalue(o)); 89 markclosure(st, clvalue(o));
93 break; 90 break;
@@ -107,8 +104,8 @@ static void markstacks (lua_State *L, GCState *st) {
107 marktable(st, L1->gt); /* mark table of globals */ 104 marktable(st, L1->gt); /* mark table of globals */
108 for (o=L1->stack; o<L1->top; o++) 105 for (o=L1->stack; o<L1->top; o++)
109 markobject(st, o); 106 markobject(st, o);
110 lim = (L1->stack_last - L1->top > MAXSTACK) ? L1->top+MAXSTACK 107 lim = (L1->stack_last - L1->ci->base > MAXSTACK) ? L1->ci->base+MAXSTACK
111 : L1->stack_last; 108 : L1->stack_last;
112 for (; o<=lim; o++) setnilvalue(o); 109 for (; o<=lim; o++) setnilvalue(o);
113 lua_assert(L1->previous->next == L1 && L1->next->previous == L1); 110 lua_assert(L1->previous->next == L1 && L1->next->previous == L1);
114 L1 = L1->next; 111 L1 = L1->next;
diff --git a/lobject.h b/lobject.h
index 16c3f53e..23ca0d03 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 1.99 2001/02/23 20:32:32 roberto Exp roberto $ 2** $Id: lobject.h,v 1.100 2001/03/02 17:27:50 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*/
@@ -22,24 +22,15 @@
22#endif 22#endif
23 23
24 24
25/* ttype for closures active in the stack */
26#define LUA_TMARK 6
27
28 25
29/* tags for values visible from Lua == first user-created tag */ 26/* tags for values visible from Lua == first user-created tag */
30#define NUM_TAGS 6 27#define NUM_TAGS 6
31 28
32 29
33/* check whether `t' is a mark */
34#define is_T_MARK(t) (ttype(t) == LUA_TMARK)
35
36
37
38typedef union { 30typedef union {
39 struct TString *ts; 31 struct TString *ts;
40 struct Closure *cl; 32 struct Closure *cl;
41 struct Hash *h; 33 struct Hash *h;
42 struct CallInfo *info;
43 lua_Number n; /* LUA_TNUMBER */ 34 lua_Number n; /* LUA_TNUMBER */
44} Value; 35} Value;
45 36
@@ -56,7 +47,6 @@ typedef struct lua_TObject {
56#define tsvalue(o) ((o)->value.ts) 47#define tsvalue(o) ((o)->value.ts)
57#define clvalue(o) ((o)->value.cl) 48#define clvalue(o) ((o)->value.cl)
58#define hvalue(o) ((o)->value.h) 49#define hvalue(o) ((o)->value.h)
59#define infovalue(o) ((o)->value.info)
60 50
61 51
62/* Macros to set values */ 52/* Macros to set values */
@@ -75,9 +65,6 @@ typedef struct lua_TObject {
75#define sethvalue(obj,x) \ 65#define sethvalue(obj,x) \
76 { TObject *_o=(obj); _o->tt=LUA_TTABLE; _o->value.h=(x); } 66 { TObject *_o=(obj); _o->tt=LUA_TTABLE; _o->value.h=(x); }
77 67
78#define setivalue(obj,x) \
79 { TObject *_o=(obj); _o->tt=LUA_TMARK; _o->value.info=(x); }
80
81#define setnilvalue(obj) ((obj)->tt=LUA_TNIL) 68#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
82 69
83#define setobj(obj1,obj2) \ 70#define setobj(obj1,obj2) \
@@ -85,6 +72,8 @@ typedef struct lua_TObject {
85 o1->tt=o2->tt; o1->value = o2->value; } 72 o1->tt=o2->tt; o1->value = o2->value; }
86 73
87 74
75typedef TObject *StkId; /* index to stack elements */
76
88 77
89/* 78/*
90** String headers for string table 79** String headers for string table
@@ -209,13 +198,16 @@ typedef struct Hash {
209** informations about a call (for debugging) 198** informations about a call (for debugging)
210*/ 199*/
211typedef struct CallInfo { 200typedef struct CallInfo {
212 struct Closure *func; /* function being called */ 201 struct CallInfo *prev; /* linked list */
202 StkId base; /* base for called function */
213 const Instruction **pc; /* current pc of called function */ 203 const Instruction **pc; /* current pc of called function */
214 int lastpc; /* last pc traced */ 204 int lastpc; /* last pc traced */
215 int line; /* current line */ 205 int line; /* current line */
216 int refi; /* current index in `lineinfo' */ 206 int refi; /* current index in `lineinfo' */
217} CallInfo; 207} CallInfo;
218 208
209#define ci_func(ci) (clvalue((ci)->base - 1))
210
219 211
220extern const TObject luaO_nilobject; 212extern const TObject luaO_nilobject;
221 213
diff --git a/lstate.c b/lstate.c
index 2b16a4eb..f48f59e3 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 1.57 2001/02/23 17:17:25 roberto Exp roberto $ 2** $Id: lstate.c,v 1.58 2001/03/02 17:27:50 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*/
@@ -99,6 +99,8 @@ LUA_API lua_State *lua_open (lua_State *OL, int stacksize) {
99 L->G = NULL; 99 L->G = NULL;
100 L->stack = NULL; 100 L->stack = NULL;
101 L->stacksize = 0; 101 L->stacksize = 0;
102 L->ci = &L->basefunc;
103 L->basefunc.prev = NULL;
102 L->errorJmp = NULL; 104 L->errorJmp = NULL;
103 L->callhook = NULL; 105 L->callhook = NULL;
104 L->linehook = NULL; 106 L->linehook = NULL;
diff --git a/lstate.h b/lstate.h
index 21348211..69fd02ad 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 1.53 2001/02/23 20:30:01 roberto Exp roberto $ 2** $Id: lstate.h,v 1.54 2001/03/02 17:27:50 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*/
@@ -31,8 +31,6 @@
31#define LUA_USERSTATE 31#define LUA_USERSTATE
32#endif 32#endif
33 33
34typedef TObject *StkId; /* index to stack elements */
35
36 34
37/* 35/*
38** marks for Reference array 36** marks for Reference array
@@ -90,18 +88,19 @@ typedef struct global_State {
90struct lua_State { 88struct lua_State {
91 LUA_USERSTATE 89 LUA_USERSTATE
92 StkId top; /* first free slot in the stack */ 90 StkId top; /* first free slot in the stack */
93 StkId stack; /* stack base */ 91 CallInfo *ci; /* call info for current function */
94 StkId stack_last; /* last free slot in the stack */ 92 StkId stack_last; /* last free slot in the stack */
95 int stacksize;
96 StkId Cbase; /* base for current C function */
97 Hash *gt; /* table for globals */ 93 Hash *gt; /* table for globals */
98 global_State *G; 94 global_State *G;
95 StkId stack; /* stack base */
96 int stacksize;
99 lua_Hook callhook; 97 lua_Hook callhook;
100 lua_Hook linehook; 98 lua_Hook linehook;
101 int allowhooks; 99 int allowhooks;
102 struct lua_longjmp *errorJmp; /* current error recover point */ 100 struct lua_longjmp *errorJmp; /* current error recover point */
103 lua_State *next; /* circular double linked list of states */ 101 lua_State *next; /* circular double linked list of states */
104 lua_State *previous; 102 lua_State *previous;
103 CallInfo basefunc;
105}; 104};
106 105
107 106
diff --git a/luadebug.h b/luadebug.h
index 5ffdbe03..f23216c5 100644
--- a/luadebug.h
+++ b/luadebug.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: luadebug.h,v 1.17 2000/10/30 12:38:50 roberto Exp roberto $ 2** $Id: luadebug.h,v 1.18 2001/02/23 17:17:25 roberto Exp roberto $
3** Debugging API 3** Debugging API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -39,7 +39,7 @@ struct lua_Debug {
39 const l_char *source; /* (S) */ 39 const l_char *source; /* (S) */
40 l_char short_src[LUA_IDSIZE]; /* (S) */ 40 l_char short_src[LUA_IDSIZE]; /* (S) */
41 /* private part */ 41 /* private part */
42 struct lua_TObject *_func; /* active function */ 42 struct CallInfo *_ci; /* active function */
43}; 43};
44 44
45 45
diff --git a/lvm.c b/lvm.c
index 99405763..a8f0dc9f 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.173 2001/02/23 20:30:52 roberto Exp roberto $ 2** $Id: lvm.c,v 1.174 2001/03/07 13:22:55 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*/
@@ -51,10 +51,10 @@ int luaV_tostring (lua_State *L, TObject *obj) { /* LUA_NUMBER */
51} 51}
52 52
53 53
54static void traceexec (lua_State *L, StkId base, lua_Hook linehook) { 54static void traceexec (lua_State *L, lua_Hook linehook) {
55 CallInfo *ci = infovalue(base-1); 55 CallInfo *ci = L->ci;
56 int *lineinfo = ci->func->f.l->lineinfo; 56 int *lineinfo = ci_func(ci)->f.l->lineinfo;
57 int pc = (*ci->pc - ci->func->f.l->code) - 1; 57 int pc = (*ci->pc - ci_func(ci)->f.l->code) - 1;
58 int newline; 58 int newline;
59 if (pc == 0) { /* may be first time? */ 59 if (pc == 0) { /* may be first time? */
60 ci->line = 1; 60 ci->line = 1;
@@ -65,7 +65,7 @@ static void traceexec (lua_State *L, StkId base, lua_Hook linehook) {
65 /* calls linehook when enters a new line or jumps back (loop) */ 65 /* calls linehook when enters a new line or jumps back (loop) */
66 if (newline != ci->line || pc <= ci->lastpc) { 66 if (newline != ci->line || pc <= ci->lastpc) {
67 ci->line = newline; 67 ci->line = newline;
68 luaD_lineHook(L, base-2, newline, linehook); 68 luaD_lineHook(L, newline, linehook);
69 } 69 }
70 ci->lastpc = pc; 70 ci->lastpc = pc;
71} 71}
@@ -332,7 +332,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
332 const Instruction *pc = tf->code; 332 const Instruction *pc = tf->code;
333 TString **const kstr = tf->kstr; 333 TString **const kstr = tf->kstr;
334 const lua_Hook linehook = L->linehook; 334 const lua_Hook linehook = L->linehook;
335 infovalue(base-1)->pc = &pc; 335 L->ci->pc = &pc;
336 if (tf->is_vararg) /* varargs? */ 336 if (tf->is_vararg) /* varargs? */
337 adjust_varargs(L, base, tf->numparams); 337 adjust_varargs(L, base, tf->numparams);
338 luaD_adjusttop(L, base, tf->maxstacksize); 338 luaD_adjusttop(L, base, tf->maxstacksize);
@@ -342,7 +342,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
342 const Instruction i = *pc++; 342 const Instruction i = *pc++;
343 lua_assert(L->top == base+tf->maxstacksize); 343 lua_assert(L->top == base+tf->maxstacksize);
344 if (linehook) 344 if (linehook)
345 traceexec(L, base, linehook); 345 traceexec(L, linehook);
346 switch (GET_OPCODE(i)) { 346 switch (GET_OPCODE(i)) {
347 case OP_RETURN: { 347 case OP_RETURN: {
348 L->top = top; 348 L->top = top;