aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldebug.c22
-rw-r--r--ldo.c63
-rw-r--r--lstate.c4
-rw-r--r--lstate.h21
-rw-r--r--lvm.c23
5 files changed, 71 insertions, 62 deletions
diff --git a/ldebug.c b/ldebug.c
index 73029a5d..413bab69 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 1.123 2002/06/24 15:07:21 roberto Exp roberto $ 2** $Id: ldebug.c,v 1.124 2002/07/08 18:21:33 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*/
@@ -30,15 +30,11 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
30 30
31 31
32 32
33static int isLmark (CallInfo *ci) {
34 return (ttype(ci->base - 1) == LUA_TFUNCTION && !ci_func(ci)->c.isC);
35}
36
37
38static int currentpc (lua_State *L, CallInfo *ci) { 33static int currentpc (lua_State *L, CallInfo *ci) {
39 if (ci->pc == NULL) return -1; /* function is not an active Lua function */ 34 if (!isLua(ci)) return -1; /* function is not a Lua function? */
40 if (ci == L->ci || ci->pc != (ci+1)->pc) /* no other function using `pc'? */ 35 /* next function is not using the same `pc'? (not a Lua->Lua call?) */
41 ci->savedpc = *ci->pc; /* may not be saved; save it */ 36 if (ci == L->ci || !isLua(ci+1) || ci->u.l.pc != (ci+1)->u.l.pc)
37 ci->savedpc = *ci->u.l.pc; /* may not be saved; save it */
42 /* function's pc is saved */ 38 /* function's pc is saved */
43 return pcRel(ci->savedpc, ci_func(ci)->l.p); 39 return pcRel(ci->savedpc, ci_func(ci)->l.p);
44} 40}
@@ -95,7 +91,7 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
95 91
96 92
97static Proto *getluaproto (CallInfo *ci) { 93static Proto *getluaproto (CallInfo *ci) {
98 return (isLmark(ci) ? ci_func(ci)->l.p : NULL); 94 return (isLua(ci) ? ci_func(ci)->l.p : NULL);
99} 95}
100 96
101 97
@@ -424,7 +420,7 @@ static const char *kname (Proto *p, int c) {
424 420
425static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos, 421static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
426 const char **name) { 422 const char **name) {
427 if (isLmark(ci)) { /* an active Lua function? */ 423 if (isLua(ci)) { /* an active Lua function? */
428 Proto *p = ci_func(ci)->l.p; 424 Proto *p = ci_func(ci)->l.p;
429 int pc = currentpc(L, ci); 425 int pc = currentpc(L, ci);
430 Instruction i; 426 Instruction i;
@@ -462,7 +458,7 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
462 458
463 459
464static Instruction getcurrentinstr (lua_State *L, CallInfo *ci) { 460static Instruction getcurrentinstr (lua_State *L, CallInfo *ci) {
465 if (ci == L->base_ci || !isLmark(ci)) 461 if (ci == L->base_ci || !isLua(ci))
466 return (Instruction)(-1); /* not an active Lua function */ 462 return (Instruction)(-1); /* not an active Lua function */
467 else 463 else
468 return ci_func(ci)->l.p->code[currentpc(L, ci)]; 464 return ci_func(ci)->l.p->code[currentpc(L, ci)];
@@ -531,7 +527,7 @@ static void addinfo (lua_State *L, int internal) {
531 CallInfo *ci = L->ci; 527 CallInfo *ci = L->ci;
532 if (!internal && ci > L->base_ci) ci--; 528 if (!internal && ci > L->base_ci) ci--;
533 if (strchr(msg, '\n')) return; /* message already `formatted' */ 529 if (strchr(msg, '\n')) return; /* message already `formatted' */
534 if (!isLmark(ci)) { /* no Lua code? */ 530 if (!isLua(ci)) { /* no Lua code? */
535 luaO_pushfstring(L, "%s\n", msg); /* no extra info */ 531 luaO_pushfstring(L, "%s\n", msg); /* no extra info */
536 } 532 }
537 else { /* add file:line information */ 533 else { /* add file:line information */
diff --git a/ldo.c b/ldo.c
index e2511bde..55f7958f 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.186 2002/07/08 18:21:33 roberto Exp roberto $ 2** $Id: ldo.c,v 1.187 2002/07/09 18:19:19 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*/
@@ -60,10 +60,10 @@ static void correctstack (lua_State *L, TObject *oldstack) {
60 for (ci = L->base_ci; ci <= L->ci; ci++) { 60 for (ci = L->base_ci; ci <= L->ci; ci++) {
61 ci->base = (ci->base - oldstack) + L->stack; 61 ci->base = (ci->base - oldstack) + L->stack;
62 ci->top = (ci->top - oldstack) + L->stack; 62 ci->top = (ci->top - oldstack) + L->stack;
63 if (ci->pc) { /* entry is of an active Lua function? */ 63 if (isLua(ci) && /* is a Lua function... */
64 if (ci->pc != (ci-1)->pc) 64 !(isLua(ci-1) && /* and next is not a Lua function... */
65 *ci->pb = (*ci->pb - oldstack) + L->stack; 65 ci->u.l.pc == (ci-1)->u.l.pc)) /* sharing the same C frame? */
66 } 66 *ci->u.l.pb = (*ci->u.l.pb - oldstack) + L->stack; /* correct frame */
67 } 67 }
68} 68}
69 69
@@ -134,10 +134,6 @@ void luaD_callhook (lua_State *L, lua_Hookevent event, int line) {
134 ar.event = event; 134 ar.event = event;
135 ar.currentline = line; 135 ar.currentline = line;
136 ar.i_ci = L->ci - L->base_ci; 136 ar.i_ci = L->ci - L->base_ci;
137 if (event <= LUA_HOOKRET) { /* `call' or `return' event? */
138 L->ci->pc = NULL; /* function is not active */
139 L->ci->top = L->ci->base; /* `top' may not have a valid value yet */
140 }
141 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 137 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
142 L->ci->top = L->top + LUA_MINSTACK; 138 L->ci->top = L->top + LUA_MINSTACK;
143 setallowhook(L, 0); /* cannot call hooks inside a hook */ 139 setallowhook(L, 0); /* cannot call hooks inside a hook */
@@ -152,11 +148,11 @@ void luaD_callhook (lua_State *L, lua_Hookevent event, int line) {
152} 148}
153 149
154 150
155static void adjust_varargs (lua_State *L, int nfixargs) { 151static void adjust_varargs (lua_State *L, int nfixargs, StkId base) {
156 int i; 152 int i;
157 Table *htab; 153 Table *htab;
158 TObject nname; 154 TObject nname;
159 int actual = L->top - L->ci->base; /* actual number of arguments */ 155 int actual = L->top - base; /* actual number of arguments */
160 if (actual < nfixargs) { 156 if (actual < nfixargs) {
161 luaD_checkstack(L, nfixargs - actual); 157 luaD_checkstack(L, nfixargs - actual);
162 for (; actual < nfixargs; ++actual) 158 for (; actual < nfixargs; ++actual)
@@ -178,49 +174,52 @@ static void adjust_varargs (lua_State *L, int nfixargs) {
178static StkId tryfuncTM (lua_State *L, StkId func) { 174static StkId tryfuncTM (lua_State *L, StkId func) {
179 const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL); 175 const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL);
180 StkId p; 176 StkId p;
181 if (ttype(tm) != LUA_TFUNCTION) { 177 ptrdiff_t funcr = savestack(L, func);
182 L->ci--; /* undo increment (no function here) */ 178 if (ttype(tm) != LUA_TFUNCTION)
183 luaG_typeerror(L, func, "call"); 179 luaG_typeerror(L, func, "call");
184 }
185 /* Open a hole inside the stack at `func' */ 180 /* Open a hole inside the stack at `func' */
186 for (p = L->top; p > func; p--) setobj(p, p-1); 181 for (p = L->top; p > func; p--) setobj(p, p-1);
187 incr_top(L); 182 incr_top(L);
188 func = L->ci->base - 1; /* previous call may change stack */ 183 func = restorestack(L, funcr); /* previous call may change stack */
189 setobj(func, tm); /* tag method is the new function to be called */ 184 setobj(func, tm); /* tag method is the new function to be called */
190 return func; 185 return func;
191} 186}
192 187
193 188
194StkId luaD_precall (lua_State *L, StkId func) { 189StkId luaD_precall (lua_State *L, StkId func) {
195 CallInfo *ci;
196 LClosure *cl; 190 LClosure *cl;
197 if (++L->ci == L->end_ci) luaD_growCI(L); 191 ptrdiff_t funcr = savestack(L, func);
198 ci = L->ci;
199 ci->base = func+1;
200 ci->pc = NULL;
201 if (ttype(func) != LUA_TFUNCTION) /* `func' is not a function? */ 192 if (ttype(func) != LUA_TFUNCTION) /* `func' is not a function? */
202 func = tryfuncTM(L, func); /* check the `function' tag method */ 193 func = tryfuncTM(L, func); /* check the `function' tag method */
194 if (L->ci + 1 == L->end_ci) luaD_growCI(L);
203 cl = &clvalue(func)->l; 195 cl = &clvalue(func)->l;
204 if (L->hookmask & LUA_MASKCALL) {
205 luaD_callhook(L, LUA_HOOKCALL, -1);
206 ci = L->ci; /* previous call may realocate `ci' */
207 }
208 if (!cl->isC) { /* Lua function? prepare its call */ 196 if (!cl->isC) { /* Lua function? prepare its call */
197 CallInfo *ci;
209 Proto *p = cl->p; 198 Proto *p = cl->p;
210 ci->savedpc = p->code; /* starting point */
211 if (p->is_vararg) /* varargs? */ 199 if (p->is_vararg) /* varargs? */
212 adjust_varargs(L, p->numparams); 200 adjust_varargs(L, p->numparams, func+1);
213 luaD_checkstack(L, p->maxstacksize); 201 luaD_checkstack(L, p->maxstacksize);
202 ci = ++L->ci; /* now `enter' new function */
203 ci->base = restorestack(L, funcr) + 1;
214 ci->top = ci->base + p->maxstacksize; 204 ci->top = ci->base + p->maxstacksize;
205 ci->savedpc = p->code; /* starting point */
215 while (L->top < ci->top) 206 while (L->top < ci->top)
216 setnilvalue(L->top++); 207 setnilvalue(L->top++);
217 L->top = ci->top; 208 L->top = ci->top;
218 return NULL; 209 return NULL;
219 } 210 }
220 else { /* if is a C function, call it */ 211 else { /* if is a C function, call it */
212 CallInfo *ci;
221 int n; 213 int n;
222 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 214 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
215 ci = ++L->ci; /* now `enter' new function */
216 ci->base = restorestack(L, funcr) + 1;
223 ci->top = L->top + LUA_MINSTACK; 217 ci->top = L->top + LUA_MINSTACK;
218 ci->savedpc = NULL; /* not a Lua function */
219 if (L->hookmask & LUA_MASKCALL) {
220 luaD_callhook(L, LUA_HOOKCALL, -1);
221 ci = L->ci; /* previous call may realocate `ci' */
222 }
224 lua_unlock(L); 223 lua_unlock(L);
225#if LUA_COMPATUPVALUES 224#if LUA_COMPATUPVALUES
226 lua_pushupvalues(L); 225 lua_pushupvalues(L);
@@ -296,9 +295,10 @@ struct ResS {
296static void resume (lua_State *L, void *ud) { 295static void resume (lua_State *L, void *ud) {
297 StkId firstResult; 296 StkId firstResult;
298 CallInfo *ci = L->ci; 297 CallInfo *ci = L->ci;
299 if (ci->savedpc != ci_func(ci)->l.p->code) { /* not first time? */ 298 if (!isLua(ci)) { /* not first time? */
300 /* finish interupted execution of `OP_CALL' */ 299 /* finish interrupted execution of `OP_CALL' */
301 int nresults; 300 int nresults;
301 lua_assert(isLua(ci - 1));
302 lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL); 302 lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL);
303 nresults = GETARG_C(*((ci-1)->savedpc - 1)) - 1; 303 nresults = GETARG_C(*((ci-1)->savedpc - 1)) - 1;
304 luaD_poscall(L, nresults, L->top); /* complete it */ 304 luaD_poscall(L, nresults, L->top); /* complete it */
@@ -306,7 +306,7 @@ static void resume (lua_State *L, void *ud) {
306 } 306 }
307 firstResult = luaV_execute(L); 307 firstResult = luaV_execute(L);
308 if (firstResult == NULL) /* yield? */ 308 if (firstResult == NULL) /* yield? */
309 cast(struct ResS *, ud)->numres = L->ci->yield_results; 309 cast(struct ResS *, ud)->numres = L->ci->u.c.yield_results;
310 else { /* return */ 310 else { /* return */
311 cast(struct ResS *, ud)->numres = L->top - firstResult; 311 cast(struct ResS *, ud)->numres = L->top - firstResult;
312 luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */ 312 luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */
@@ -338,9 +338,10 @@ LUA_API int lua_yield (lua_State *L, int nresults) {
338 CallInfo *ci; 338 CallInfo *ci;
339 lua_lock(L); 339 lua_lock(L);
340 ci = L->ci; 340 ci = L->ci;
341 if (ci_func(ci-1)->c.isC) 341 if (!isLua(ci-1))
342 luaG_runerror(L, "cannot yield a C function"); 342 luaG_runerror(L, "cannot yield a C function");
343 ci->yield_results = nresults; 343 lua_assert(!isLua(ci));
344 ci->u.c.yield_results = nresults;
344 lua_unlock(L); 345 lua_unlock(L);
345 return -1; 346 return -1;
346} 347}
diff --git a/lstate.c b/lstate.c
index 241c177b..1edb93f4 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 1.97 2002/06/18 15:19:27 roberto Exp roberto $ 2** $Id: lstate.c,v 1.98 2002/07/08 18:21:33 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*/
@@ -41,9 +41,9 @@ static void stack_init (lua_State *L, lua_State *OL) {
41 L->stack_last = L->stack+(BASIC_STACK_SIZE-EXTRA_STACK)-1; 41 L->stack_last = L->stack+(BASIC_STACK_SIZE-EXTRA_STACK)-1;
42 L->base_ci = luaM_newvector(OL, BASIC_CI_SIZE, CallInfo); 42 L->base_ci = luaM_newvector(OL, BASIC_CI_SIZE, CallInfo);
43 L->ci = L->base_ci; 43 L->ci = L->base_ci;
44 L->ci->savedpc = NULL;
44 L->ci->base = L->top; 45 L->ci->base = L->top;
45 L->ci->top = L->top + LUA_MINSTACK; 46 L->ci->top = L->top + LUA_MINSTACK;
46 L->ci->pc = NULL;
47 L->size_ci = BASIC_CI_SIZE; 47 L->size_ci = BASIC_CI_SIZE;
48 L->end_ci = L->base_ci + L->size_ci; 48 L->end_ci = L->base_ci + L->size_ci;
49} 49}
diff --git a/lstate.h b/lstate.h
index ef47de36..5db528ff 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 1.87 2002/07/08 18:21:33 roberto Exp roberto $ 2** $Id: lstate.h,v 1.88 2002/07/08 20:22:08 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*/
@@ -87,13 +87,22 @@ typedef struct stringtable {
87*/ 87*/
88typedef struct CallInfo { 88typedef struct CallInfo {
89 StkId base; /* base for called function */ 89 StkId base; /* base for called function */
90 const Instruction *savedpc; 90 StkId top; /* top for this function */
91 StkId top; /* top for this function (when it's a Lua function) */ 91 const Instruction *savedpc; /* NULL means not a Lua function */
92 const Instruction **pc; /* points to `pc' variable in `luaV_execute' */ 92 union {
93 StkId *pb; /* points to `base' variable in `luaV_execute' */ 93 struct { /* for Lua functions */
94 int yield_results; 94 const Instruction **pc; /* points to `pc' variable in `luaV_execute' */
95 StkId *pb; /* points to `base' variable in `luaV_execute' */
96 } l;
97 struct { /* for C functions */
98 int yield_results;
99 } c;
100 } u;
95} CallInfo; 101} CallInfo;
96 102
103
104#define isLua(ci) ((ci)->savedpc != NULL)
105
97#define ci_func(ci) (clvalue((ci)->base - 1)) 106#define ci_func(ci) (clvalue((ci)->base - 1))
98 107
99 108
diff --git a/lvm.c b/lvm.c
index ced4d7f1..8dcd83eb 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.245 2002/07/08 18:21:33 roberto Exp roberto $ 2** $Id: lvm.c,v 1.246 2002/07/08 20:22:08 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*/
@@ -80,16 +80,16 @@ static void traceexec (lua_State *L) {
80 if (mask & LUA_MASKLINE) { 80 if (mask & LUA_MASKLINE) {
81 CallInfo *ci = L->ci; 81 CallInfo *ci = L->ci;
82 Proto *p = ci_func(ci)->l.p; 82 Proto *p = ci_func(ci)->l.p;
83 int newline = getline(p, pcRel(*ci->pc, p)); 83 int newline = getline(p, pcRel(*ci->u.l.pc, p));
84 if (pcRel(*ci->pc, p) == 0) /* tracing may be starting now? */ 84 if (pcRel(*ci->u.l.pc, p) == 0) /* tracing may be starting now? */
85 ci->savedpc = *ci->pc; /* initialize `savedpc' */ 85 ci->savedpc = *ci->u.l.pc; /* initialize `savedpc' */
86 /* calls linehook when enters a new line or jumps back (loop) */ 86 /* calls linehook when enters a new line or jumps back (loop) */
87 if (*ci->pc <= ci->savedpc || 87 if (*ci->u.l.pc <= ci->savedpc ||
88 newline != getline(p, pcRel(ci->savedpc, p))) { 88 newline != getline(p, pcRel(ci->savedpc, p))) {
89 luaD_callhook(L, LUA_HOOKLINE, newline); 89 luaD_callhook(L, LUA_HOOKLINE, newline);
90 ci = L->ci; /* previous call may reallocate `ci' */ 90 ci = L->ci; /* previous call may reallocate `ci' */
91 } 91 }
92 ci->savedpc = *ci->pc; 92 ci->savedpc = *ci->u.l.pc;
93 } 93 }
94} 94}
95 95
@@ -370,9 +370,11 @@ StkId luaV_execute (lua_State *L) {
370 TObject *k; 370 TObject *k;
371 const Instruction *pc; 371 const Instruction *pc;
372 callentry: /* entry point when calling new functions */ 372 callentry: /* entry point when calling new functions */
373 L->ci->pc = &pc; 373 L->ci->u.l.pc = &pc;
374 L->ci->pb = &base; 374 L->ci->u.l.pb = &base;
375 pc = L->ci->savedpc; 375 pc = L->ci->savedpc;
376 if (L->hookmask & LUA_MASKCALL)
377 luaD_callhook(L, LUA_HOOKCALL, -1);
376 retentry: /* entry point when returning to old functions */ 378 retentry: /* entry point when returning to old functions */
377 base = L->ci->base; 379 base = L->ci->base;
378 cl = &clvalue(base - 1)->l; 380 cl = &clvalue(base - 1)->l;
@@ -619,12 +621,13 @@ StkId luaV_execute (lua_State *L) {
619 if (L->openupval) luaF_close(L, base); 621 if (L->openupval) luaF_close(L, base);
620 b = GETARG_B(i); 622 b = GETARG_B(i);
621 if (b != 0) L->top = ra+b-1; 623 if (b != 0) L->top = ra+b-1;
622 lua_assert(L->ci->pc == &pc); 624 lua_assert(L->ci->u.l.pc == &pc);
623 } 625 }
624 ret: { 626 ret: {
625 CallInfo *ci; 627 CallInfo *ci;
626 ci = L->ci - 1; 628 ci = L->ci - 1;
627 if (ci->pc != &pc) /* previous function was running `here'? */ 629 /* previous function was running `here'? */
630 if (!isLua(ci) || ci->u.l.pc != &pc)
628 return ra; /* no: return */ 631 return ra; /* no: return */
629 else { /* yes: continue its execution */ 632 else { /* yes: continue its execution */
630 int nresults; 633 int nresults;