aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-08-07 16:22:39 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-08-07 16:22:39 -0300
commit5016f43aa439662ca35a5d78e820c617c517f60a (patch)
tree167aabeccb5a2307c3de7d20542ecf7d99769d3c
parentc1c100a0c04bc77623b32269f37df49e7a2457d2 (diff)
downloadlua-5016f43aa439662ca35a5d78e820c617c517f60a.tar.gz
lua-5016f43aa439662ca35a5d78e820c617c517f60a.tar.bz2
lua-5016f43aa439662ca35a5d78e820c617c517f60a.zip
(much) cleaner way to control function states
-rw-r--r--ldebug.c14
-rw-r--r--ldo.c16
-rw-r--r--lstate.c4
-rw-r--r--lstate.h16
-rw-r--r--lvm.c37
-rw-r--r--lvm.h9
6 files changed, 54 insertions, 42 deletions
diff --git a/ldebug.c b/ldebug.c
index 82f82612..bd123234 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 1.128 2002/08/06 18:01:50 roberto Exp roberto $ 2** $Id: ldebug.c,v 1.129 2002/08/07 14:35: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*/
@@ -28,14 +28,16 @@
28static const char *getfuncname (CallInfo *ci, const char **name); 28static const char *getfuncname (CallInfo *ci, const char **name);
29 29
30 30
31static int isLua (CallInfo *ci) { 31#define isLua(ci) (!((ci)->state & CI_C))
32 return isLfunction (ci->base - 1); 32
33}
34 33
35static int currentpc (CallInfo *ci) { 34static int currentpc (CallInfo *ci) {
36 if (!isLua(ci)) return -1; /* function is not a Lua function? */ 35 if (!isLua(ci)) return -1; /* function is not a Lua function? */
37 if (ci->pc != &luaV_callingmark) /* is not calling another Lua function? */ 36 if (!(ci->state & CI_SAVEDPC)) { /* savedpc outdated? */
38 ci->u.l.savedpc = *ci->pc; /* `pc' may not be saved; save it */ 37 lua_assert(ci->state & CI_HASFRAME);
38 ci->u.l.savedpc = *ci->u.l.pc;
39 ci->state |= CI_SAVEDPC;
40 }
39 /* function's pc is saved */ 41 /* function's pc is saved */
40 return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p); 42 return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p);
41} 43}
diff --git a/ldo.c b/ldo.c
index 85561e06..8f125372 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.189 2002/08/05 17:36:24 roberto Exp roberto $ 2** $Id: ldo.c,v 1.190 2002/08/06 15:32:22 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*/
@@ -108,7 +108,7 @@ static void correctstack (lua_State *L, TObject *oldstack) {
108 for (ci = L->base_ci; ci <= L->ci; ci++) { 108 for (ci = L->base_ci; ci <= L->ci; ci++) {
109 ci->base = (ci->base - oldstack) + L->stack; 109 ci->base = (ci->base - oldstack) + L->stack;
110 ci->top = (ci->top - oldstack) + L->stack; 110 ci->top = (ci->top - oldstack) + L->stack;
111 if (ci->pc && ci->pc != &luaV_callingmark) /* function has a frame? */ 111 if (ci->state & CI_HASFRAME) /* Lua function with active frame? */
112 *ci->u.l.pb = (*ci->u.l.pb - oldstack) + L->stack; /* correct frame */ 112 *ci->u.l.pb = (*ci->u.l.pb - oldstack) + L->stack; /* correct frame */
113 } 113 }
114} 114}
@@ -229,6 +229,7 @@ StkId luaD_precall (lua_State *L, StkId func) {
229 ci->base = restorestack(L, funcr) + 1; 229 ci->base = restorestack(L, funcr) + 1;
230 ci->top = ci->base + p->maxstacksize; 230 ci->top = ci->base + p->maxstacksize;
231 ci->u.l.savedpc = p->code; /* starting point */ 231 ci->u.l.savedpc = p->code; /* starting point */
232 ci->state = CI_SAVEDPC;
232 while (L->top < ci->top) 233 while (L->top < ci->top)
233 setnilvalue(L->top++); 234 setnilvalue(L->top++);
234 L->top = ci->top; 235 L->top = ci->top;
@@ -241,7 +242,7 @@ StkId luaD_precall (lua_State *L, StkId func) {
241 ci = ++L->ci; /* now `enter' new function */ 242 ci = ++L->ci; /* now `enter' new function */
242 ci->base = restorestack(L, funcr) + 1; 243 ci->base = restorestack(L, funcr) + 1;
243 ci->top = L->top + LUA_MINSTACK; 244 ci->top = L->top + LUA_MINSTACK;
244 ci->pc = NULL; /* not a Lua function */ 245 ci->state = CI_C; /* a C function */
245 if (L->hookmask & LUA_MASKCALL) { 246 if (L->hookmask & LUA_MASKCALL) {
246 luaD_callhook(L, LUA_HOOKCALL, -1); 247 luaD_callhook(L, LUA_HOOKCALL, -1);
247 ci = L->ci; /* previous call may realocate `ci' */ 248 ci = L->ci; /* previous call may realocate `ci' */
@@ -300,7 +301,6 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
300LUA_API void lua_cobegin (lua_State *L, int nargs) { 301LUA_API void lua_cobegin (lua_State *L, int nargs) {
301 lua_lock(L); 302 lua_lock(L);
302 luaD_precall(L, L->top - (nargs+1)); 303 luaD_precall(L, L->top - (nargs+1));
303 L->ci->pc = &luaV_callingmark; /* function is not active (yet) */
304 lua_unlock(L); 304 lua_unlock(L);
305} 305}
306 306
@@ -317,10 +317,10 @@ static void move_results (lua_State *L, TObject *from, TObject *to) {
317static void resume (lua_State *L, void *ud) { 317static void resume (lua_State *L, void *ud) {
318 StkId firstResult; 318 StkId firstResult;
319 CallInfo *ci = L->ci; 319 CallInfo *ci = L->ci;
320 if (ci->pc == NULL) { /* not first time? */ 320 if (ci->state & CI_C) { /* not first time (i.e. inside a yield)? */
321 /* finish interrupted execution of `OP_CALL' */ 321 /* finish interrupted execution of `OP_CALL' */
322 int nresults; 322 int nresults;
323 lua_assert((ci - 1)->pc == &luaV_callingmark); 323 lua_assert((ci-1)->state & CI_SAVEDPC);
324 lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL || 324 lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL ||
325 GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL); 325 GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL);
326 nresults = GETARG_C(*((ci-1)->u.l.savedpc - 1)) - 1; 326 nresults = GETARG_C(*((ci-1)->u.l.savedpc - 1)) - 1;
@@ -363,9 +363,9 @@ LUA_API int lua_yield (lua_State *L, int nresults) {
363 CallInfo *ci; 363 CallInfo *ci;
364 lua_lock(L); 364 lua_lock(L);
365 ci = L->ci; 365 ci = L->ci;
366 if ((ci-1)->pc == NULL) 366 if ((ci-1)->state & CI_C)
367 luaG_runerror(L, "cannot yield a C function"); 367 luaG_runerror(L, "cannot yield a C function");
368 lua_assert(ci->pc == NULL); /* current function is not Lua */ 368 lua_assert(ci->state & CI_C); /* current function is not Lua */
369 ci->u.c.yield_results = nresults; 369 ci->u.c.yield_results = nresults;
370 lua_unlock(L); 370 lua_unlock(L);
371 return -1; 371 return -1;
diff --git a/lstate.c b/lstate.c
index 4e281977..ab2b7bb5 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 1.101 2002/08/05 18:45:45 roberto Exp roberto $ 2** $Id: lstate.c,v 1.102 2002/08/06 15:32:22 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,7 +41,7 @@ static void stack_init (lua_State *L, lua_State *OL) {
41 L->stack_last = L->stack+(L->stacksize - EXTRA_STACK)-1; 41 L->stack_last = L->stack+(L->stacksize - 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->pc = NULL; /* not a Lua function */ 44 L->ci->state = CI_C; /* not a Lua function */
45 setnilvalue(L->top++); /* `function' entry for this `ci' */ 45 setnilvalue(L->top++); /* `function' entry for this `ci' */
46 L->ci->base = L->top; 46 L->ci->base = L->top;
47 L->ci->top = L->top + LUA_MINSTACK; 47 L->ci->top = L->top + LUA_MINSTACK;
diff --git a/lstate.h b/lstate.h
index bcd411a6..c5001f7b 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 1.91 2002/08/06 15:32:22 roberto Exp roberto $ 2** $Id: lstate.h,v 1.92 2002/08/06 18:01: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*/
@@ -87,10 +87,11 @@ typedef struct stringtable {
87typedef struct CallInfo { 87typedef struct CallInfo {
88 StkId base; /* base for called function */ 88 StkId base; /* base for called function */
89 StkId top; /* top for this function */ 89 StkId top; /* top for this function */
90 const Instruction **pc; /* points to `pc' variable in `luaV_execute' */ 90 int state; /* bit fields; see below */
91 union { 91 union {
92 struct { /* for Lua functions */ 92 struct { /* for Lua functions */
93 const Instruction *savedpc; 93 const Instruction *savedpc;
94 const Instruction **pc; /* points to `pc' variable in `luaV_execute' */
94 StkId *pb; /* points to `base' variable in `luaV_execute' */ 95 StkId *pb; /* points to `base' variable in `luaV_execute' */
95 } l; 96 } l;
96 struct { /* for C functions */ 97 struct { /* for C functions */
@@ -100,6 +101,17 @@ typedef struct CallInfo {
100} CallInfo; 101} CallInfo;
101 102
102 103
104/*
105** bit fields for `CallInfo.state'
106*/
107#define CI_C 1 /* 1 if function is a C function */
108/* 1 if (Lua) function has an active `luaV_execute' running it */
109#define CI_HASFRAME 2
110/* 1 if Lua function is calling another Lua function (and therefore its
111 `pc' is being used by the other, and therefore CI_SAVEDPC is 1 too) */
112#define CI_CALLING 4
113#define CI_SAVEDPC 8 /* 1 if `savedpc' is updated */
114
103 115
104#define ci_func(ci) (clvalue((ci)->base - 1)) 116#define ci_func(ci) (clvalue((ci)->base - 1))
105 117
diff --git a/lvm.c b/lvm.c
index 3eeb2ff8..c61d4a3c 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.249 2002/08/05 17:36:24 roberto Exp roberto $ 2** $Id: lvm.c,v 1.250 2002/08/07 14:24:24 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*/
@@ -24,8 +24,6 @@
24#include "lvm.h" 24#include "lvm.h"
25 25
26 26
27Instruction const *luaV_callingmark = NULL;
28
29 27
30/* function to convert a lua_Number to a string */ 28/* function to convert a lua_Number to a string */
31#ifndef lua_number2str 29#ifndef lua_number2str
@@ -83,16 +81,18 @@ static void traceexec (lua_State *L) {
83 if (mask & LUA_MASKLINE) { 81 if (mask & LUA_MASKLINE) {
84 CallInfo *ci = L->ci; 82 CallInfo *ci = L->ci;
85 Proto *p = ci_func(ci)->l.p; 83 Proto *p = ci_func(ci)->l.p;
86 int newline = getline(p, pcRel(*ci->pc, p)); 84 int newline = getline(p, pcRel(*ci->u.l.pc, p));
87 if (pcRel(*ci->pc, p) == 0) /* tracing may be starting now? */ 85 lua_assert(ci->state & CI_HASFRAME);
88 ci->u.l.savedpc = *ci->pc; /* initialize `savedpc' */ 86 if (pcRel(*ci->u.l.pc, p) == 0) /* tracing may be starting now? */
87 ci->u.l.savedpc = *ci->u.l.pc; /* initialize `savedpc' */
89 /* calls linehook when enters a new line or jumps back (loop) */ 88 /* calls linehook when enters a new line or jumps back (loop) */
90 if (*ci->pc <= ci->u.l.savedpc || 89 if (*ci->u.l.pc <= ci->u.l.savedpc ||
91 newline != getline(p, pcRel(ci->u.l.savedpc, p))) { 90 newline != getline(p, pcRel(ci->u.l.savedpc, p))) {
92 luaD_callhook(L, LUA_HOOKLINE, newline); 91 luaD_callhook(L, LUA_HOOKLINE, newline);
93 ci = L->ci; /* previous call may reallocate `ci' */ 92 ci = L->ci; /* previous call may reallocate `ci' */
94 } 93 }
95 ci->u.l.savedpc = *ci->pc; 94 ci->u.l.savedpc = *ci->u.l.pc;
95 ci->state |= CI_SAVEDPC; /* `savedpc' is updated */
96 } 96 }
97} 97}
98 98
@@ -374,11 +374,13 @@ StkId luaV_execute (lua_State *L) {
374 const Instruction *pc; 374 const Instruction *pc;
375 callentry: /* entry point when calling new functions */ 375 callentry: /* entry point when calling new functions */
376 L->ci->u.l.pb = &base; 376 L->ci->u.l.pb = &base;
377 L->ci->pc = &pc; 377 L->ci->u.l.pc = &pc;
378 pc = L->ci->u.l.savedpc;
379 if (L->hookmask & LUA_MASKCALL) 378 if (L->hookmask & LUA_MASKCALL)
380 luaD_callhook(L, LUA_HOOKCALL, -1); 379 luaD_callhook(L, LUA_HOOKCALL, -1);
381 retentry: /* entry point when returning to old functions */ 380 retentry: /* entry point when returning to old functions */
381 lua_assert(L->ci->state & CI_SAVEDPC);
382 L->ci->state = CI_HASFRAME; /* activate frame */
383 pc = L->ci->u.l.savedpc;
382 base = L->ci->base; 384 base = L->ci->base;
383 cl = &clvalue(base - 1)->l; 385 cl = &clvalue(base - 1)->l;
384 k = cl->p->k; 386 k = cl->p->k;
@@ -599,7 +601,7 @@ StkId luaV_execute (lua_State *L) {
599 if (firstResult) { 601 if (firstResult) {
600 if (firstResult > L->top) { /* yield? */ 602 if (firstResult > L->top) { /* yield? */
601 (L->ci - 1)->u.l.savedpc = pc; 603 (L->ci - 1)->u.l.savedpc = pc;
602 (L->ci - 1)->pc = &luaV_callingmark; 604 (L->ci - 1)->state = CI_SAVEDPC;
603 return NULL; 605 return NULL;
604 } 606 }
605 /* it was a C function (`precall' called it); adjust results */ 607 /* it was a C function (`precall' called it); adjust results */
@@ -609,7 +611,7 @@ StkId luaV_execute (lua_State *L) {
609 else { /* it is a Lua function */ 611 else { /* it is a Lua function */
610 if (GET_OPCODE(i) == OP_CALL) { /* regular call? */ 612 if (GET_OPCODE(i) == OP_CALL) { /* regular call? */
611 (L->ci-1)->u.l.savedpc = pc; /* save `pc' to return later */ 613 (L->ci-1)->u.l.savedpc = pc; /* save `pc' to return later */
612 (L->ci-1)->pc = &luaV_callingmark; /* function is calling */ 614 (L->ci-1)->state = (CI_SAVEDPC | CI_CALLING);
613 } 615 }
614 else { /* tail call: put new frame in place of previous one */ 616 else { /* tail call: put new frame in place of previous one */
615 int aux; 617 int aux;
@@ -618,7 +620,9 @@ StkId luaV_execute (lua_State *L) {
618 for (aux = 0; ra1+aux < L->top; aux++) /* move frame down */ 620 for (aux = 0; ra1+aux < L->top; aux++) /* move frame down */
619 setobj(base+aux-1, ra1+aux); 621 setobj(base+aux-1, ra1+aux);
620 (L->ci - 1)->top = L->top = base+aux; /* correct top */ 622 (L->ci - 1)->top = L->top = base+aux; /* correct top */
623 lua_assert(L->ci->state & CI_SAVEDPC);
621 (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc; 624 (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc;
625 (L->ci - 1)->state = CI_SAVEDPC;
622 L->ci--; /* remove previous frame */ 626 L->ci--; /* remove previous frame */
623 } 627 }
624 goto callentry; 628 goto callentry;
@@ -629,20 +633,21 @@ StkId luaV_execute (lua_State *L) {
629 CallInfo *ci = L->ci - 1; 633 CallInfo *ci = L->ci - 1;
630 int b = GETARG_B(i); 634 int b = GETARG_B(i);
631 if (b != 0) L->top = ra+b-1; 635 if (b != 0) L->top = ra+b-1;
632 lua_assert(L->ci->pc == &pc); 636 lua_assert(L->ci->state & CI_HASFRAME);
633 if (L->openupval) luaF_close(L, base); 637 if (L->openupval) luaF_close(L, base);
638 L->ci->state = CI_SAVEDPC; /* deactivate current function */
639 L->ci->u.l.savedpc = pc;
634 /* previous function was running `here'? */ 640 /* previous function was running `here'? */
635 if (ci->pc != &luaV_callingmark) 641 if (!(ci->state & CI_CALLING))
636 return ra; /* no: return */ 642 return ra; /* no: return */
637 else { /* yes: continue its execution (go through) */ 643 else { /* yes: continue its execution (go through) */
638 int nresults; 644 int nresults;
639 lua_assert(ttisfunction(ci->base - 1)); 645 lua_assert(ttisfunction(ci->base - 1));
646 lua_assert(ci->state & CI_SAVEDPC);
640 lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL); 647 lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL);
641 nresults = GETARG_C(*(ci->u.l.savedpc - 1)) - 1; 648 nresults = GETARG_C(*(ci->u.l.savedpc - 1)) - 1;
642 luaD_poscall(L, nresults, ra); 649 luaD_poscall(L, nresults, ra);
643 if (nresults >= 0) L->top = L->ci->top; 650 if (nresults >= 0) L->top = L->ci->top;
644 L->ci->pc = &pc; /* function is active again */
645 pc = L->ci->u.l.savedpc;
646 goto retentry; 651 goto retentry;
647 } 652 }
648 } 653 }
diff --git a/lvm.h b/lvm.h
index c1b2c312..17cbfb8c 100644
--- a/lvm.h
+++ b/lvm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.h,v 1.44 2002/07/05 18:27:39 roberto Exp $ 2** $Id: lvm.h,v 1.45 2002/08/05 17:36:24 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*/
@@ -22,13 +22,6 @@
22 (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) 22 (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
23 23
24 24
25/*
26** dummy addrees, to mark Lua functions calling other Lua functions (and
27** therefore without a valid `pc'
28*/
29extern Instruction const *luaV_callingmark;
30
31
32int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r); 25int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r);
33int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2); 26int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2);
34const TObject *luaV_tonumber (const TObject *obj, TObject *n); 27const TObject *luaV_tonumber (const TObject *obj, TObject *n);