aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-05-14 16:25:09 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-05-14 16:25:09 -0300
commit0bda88e6cd960d3b1ad1d46826bfdef179098d2a (patch)
treed3b237faef502dba76747a5563be9ccc4c404754
parent7966a4acaea50230e30acc8fd6997bce22307f24 (diff)
downloadlua-0bda88e6cd960d3b1ad1d46826bfdef179098d2a.tar.gz
lua-0bda88e6cd960d3b1ad1d46826bfdef179098d2a.tar.bz2
lua-0bda88e6cd960d3b1ad1d46826bfdef179098d2a.zip
small steps towards yields in iterators and tag methods
-rw-r--r--lapi.c10
-rw-r--r--ldo.c30
-rw-r--r--ldo.h10
-rw-r--r--lstate.h5
-rw-r--r--lvm.c127
-rw-r--r--lvm.h8
6 files changed, 111 insertions, 79 deletions
diff --git a/lapi.c b/lapi.c
index bb436ebd..7a1a72d3 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.7 2004/04/30 20:13:38 roberto Exp roberto $ 2** $Id: lapi.c,v 2.8 2004/05/11 16:52:08 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*/
@@ -488,7 +488,7 @@ LUA_API void lua_gettable (lua_State *L, int idx) {
488 lua_lock(L); 488 lua_lock(L);
489 t = luaA_index(L, idx); 489 t = luaA_index(L, idx);
490 api_checkvalidindex(L, t); 490 api_checkvalidindex(L, t);
491 luaV_gettable(L, t, L->top - 1, L->top - 1); 491 luaV_gettable(L, t, L->top - 1, L->top - 1, NULL);
492 lua_unlock(L); 492 lua_unlock(L);
493} 493}
494 494
@@ -500,7 +500,7 @@ LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
500 t = luaA_index(L, idx); 500 t = luaA_index(L, idx);
501 api_checkvalidindex(L, t); 501 api_checkvalidindex(L, t);
502 setsvalue(L, &key, luaS_new(L, k)); 502 setsvalue(L, &key, luaS_new(L, k));
503 luaV_gettable(L, t, &key, L->top); 503 luaV_gettable(L, t, &key, L->top, NULL);
504 api_incr_top(L); 504 api_incr_top(L);
505 lua_unlock(L); 505 lua_unlock(L);
506} 506}
@@ -584,7 +584,7 @@ LUA_API void lua_settable (lua_State *L, int idx) {
584 api_checknelems(L, 2); 584 api_checknelems(L, 2);
585 t = luaA_index(L, idx); 585 t = luaA_index(L, idx);
586 api_checkvalidindex(L, t); 586 api_checkvalidindex(L, t);
587 luaV_settable(L, t, L->top - 2, L->top - 1); 587 luaV_settable(L, t, L->top - 2, L->top - 1, NULL);
588 L->top -= 2; /* pop index and value */ 588 L->top -= 2; /* pop index and value */
589 lua_unlock(L); 589 lua_unlock(L);
590} 590}
@@ -598,7 +598,7 @@ LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
598 t = luaA_index(L, idx); 598 t = luaA_index(L, idx);
599 api_checkvalidindex(L, t); 599 api_checkvalidindex(L, t);
600 setsvalue(L, &key, luaS_new(L, k)); 600 setsvalue(L, &key, luaS_new(L, k));
601 luaV_settable(L, t, &key, L->top - 1); 601 luaV_settable(L, t, &key, L->top - 1, NULL);
602 L->top--; /* pop value */ 602 L->top--; /* pop value */
603 lua_unlock(L); 603 lua_unlock(L);
604} 604}
diff --git a/ldo.c b/ldo.c
index f2682670..fc1caa7f 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.3 2004/04/30 20:13:38 roberto Exp roberto $ 2** $Id: ldo.c,v 2.4 2004/05/10 17:50:51 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*/
@@ -219,7 +219,7 @@ static StkId tryfuncTM (lua_State *L, StkId func) {
219} 219}
220 220
221 221
222StkId luaD_precall (lua_State *L, StkId func) { 222int luaD_precall (lua_State *L, StkId func, int nresults) {
223 LClosure *cl; 223 LClosure *cl;
224 ptrdiff_t funcr = savestack(L, func); 224 ptrdiff_t funcr = savestack(L, func);
225 if (!ttisfunction(func)) /* `func' is not a function? */ 225 if (!ttisfunction(func)) /* `func' is not a function? */
@@ -239,10 +239,11 @@ StkId luaD_precall (lua_State *L, StkId func) {
239 ci->top = L->base + p->maxstacksize; 239 ci->top = L->base + p->maxstacksize;
240 ci->u.l.savedpc = p->code; /* starting point */ 240 ci->u.l.savedpc = p->code; /* starting point */
241 ci->u.l.tailcalls = 0; 241 ci->u.l.tailcalls = 0;
242 ci->nresults = nresults;
242 for (st = L->top; st < ci->top; st++) 243 for (st = L->top; st < ci->top; st++)
243 setnilvalue(st); 244 setnilvalue(st);
244 L->top = ci->top; 245 L->top = ci->top;
245 return NULL; 246 return PCRLUA;
246 } 247 }
247 else { /* if is a C function, call it */ 248 else { /* if is a C function, call it */
248 CallInfo *ci; 249 CallInfo *ci;
@@ -256,7 +257,14 @@ StkId luaD_precall (lua_State *L, StkId func) {
256 lua_unlock(L); 257 lua_unlock(L);
257 n = (*curr_func(L)->c.f)(L); /* do the actual call */ 258 n = (*curr_func(L)->c.f)(L); /* do the actual call */
258 lua_lock(L); 259 lua_lock(L);
259 return L->top - n; 260 if (n >= 0) { /* no yielding? */
261 luaD_poscall(L, nresults, L->top - n);
262 return PCRC;
263 }
264 else {
265 ci->nresults = nresults;
266 return PCRYIELD;
267 }
260 } 268 }
261} 269}
262 270
@@ -297,17 +305,16 @@ void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
297** function position. 305** function position.
298*/ 306*/
299void luaD_call (lua_State *L, StkId func, int nResults) { 307void luaD_call (lua_State *L, StkId func, int nResults) {
300 StkId firstResult;
301 if (++L->nCcalls >= LUA_MAXCCALLS) { 308 if (++L->nCcalls >= LUA_MAXCCALLS) {
302 if (L->nCcalls == LUA_MAXCCALLS) 309 if (L->nCcalls == LUA_MAXCCALLS)
303 luaG_runerror(L, "C stack overflow"); 310 luaG_runerror(L, "C stack overflow");
304 else if (L->nCcalls >= (LUA_MAXCCALLS + (LUA_MAXCCALLS>>3))) 311 else if (L->nCcalls >= (LUA_MAXCCALLS + (LUA_MAXCCALLS>>3)))
305 luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ 312 luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
306 } 313 }
307 firstResult = luaD_precall(L, func); 314 if (luaD_precall(L, func, nResults) == PCRLUA) { /* is a Lua function? */
308 if (firstResult == NULL) /* is a Lua function? */ 315 StkId firstResult = luaV_execute(L, 1); /* call it */
309 firstResult = luaV_execute(L, 1); /* call it */ 316 luaD_poscall(L, nResults, firstResult);
310 luaD_poscall(L, nResults, firstResult); 317 }
311 L->nCcalls--; 318 L->nCcalls--;
312 luaC_checkGC(L); 319 luaC_checkGC(L);
313} 320}
@@ -319,15 +326,14 @@ static void resume (lua_State *L, void *ud) {
319 CallInfo *ci = L->ci; 326 CallInfo *ci = L->ci;
320 if (!L->isSuspended) { 327 if (!L->isSuspended) {
321 lua_assert(ci == L->base_ci && nargs < L->top - L->base); 328 lua_assert(ci == L->base_ci && nargs < L->top - L->base);
322 luaD_precall(L, L->top - (nargs + 1)); /* start coroutine */ 329 luaD_precall(L, L->top - (nargs + 1), LUA_MULTRET); /* start coroutine */
323 } 330 }
324 else { /* resuming from previous yield */ 331 else { /* resuming from previous yield */
325 if (!f_isLua(ci)) { /* `common' yield? */ 332 if (!f_isLua(ci)) { /* `common' yield? */
326 /* finish interrupted execution of `OP_CALL' */ 333 /* finish interrupted execution of `OP_CALL' */
327 int nresults; 334 int nresults = ci->nresults;
328 lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL || 335 lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL ||
329 GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL); 336 GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL);
330 nresults = GETARG_C(*((ci-1)->u.l.savedpc - 1)) - 1;
331 luaD_poscall(L, nresults, L->top - nargs); /* complete it */ 337 luaD_poscall(L, nresults, L->top - nargs); /* complete it */
332 if (nresults >= 0) L->top = L->ci->top; 338 if (nresults >= 0) L->top = L->ci->top;
333 } /* else yielded inside a hook: just continue its execution */ 339 } /* else yielded inside a hook: just continue its execution */
diff --git a/ldo.h b/ldo.h
index fc13692c..8e2e026b 100644
--- a/ldo.h
+++ b/ldo.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.h,v 1.58 2003/08/27 21:01:44 roberto Exp roberto $ 2** $Id: ldo.h,v 2.1 2003/12/10 12:13:36 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*/
@@ -38,13 +38,19 @@
38#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n))) 38#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n)))
39 39
40 40
41/* results from luaD_precall */
42#define PCRLUA 0 /* initiated a call to a Lua function */
43#define PCRC 1 /* did a call to a C function */
44#define PCRYIELD 2 /* C funtion yielded */
45
46
41/* type of protected functions, to be ran by `runprotected' */ 47/* type of protected functions, to be ran by `runprotected' */
42typedef void (*Pfunc) (lua_State *L, void *ud); 48typedef void (*Pfunc) (lua_State *L, void *ud);
43 49
44void luaD_resetprotection (lua_State *L); 50void luaD_resetprotection (lua_State *L);
45int luaD_protectedparser (lua_State *L, ZIO *z, const char *name); 51int luaD_protectedparser (lua_State *L, ZIO *z, const char *name);
46void luaD_callhook (lua_State *L, int event, int line); 52void luaD_callhook (lua_State *L, int event, int line);
47StkId luaD_precall (lua_State *L, StkId func); 53int luaD_precall (lua_State *L, StkId func, int nresults);
48void luaD_call (lua_State *L, StkId func, int nResults); 54void luaD_call (lua_State *L, StkId func, int nResults);
49int luaD_pcall (lua_State *L, Pfunc func, void *u, 55int luaD_pcall (lua_State *L, Pfunc func, void *u,
50 ptrdiff_t oldtop, ptrdiff_t ef); 56 ptrdiff_t oldtop, ptrdiff_t ef);
diff --git a/lstate.h b/lstate.h
index 19ff1bd9..3a1eb329 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 2.1 2003/12/10 12:13:36 roberto Exp roberto $ 2** $Id: lstate.h,v 2.2 2004/03/23 17:02:58 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*/
@@ -70,8 +70,9 @@ typedef struct stringtable {
70** informations about a call 70** informations about a call
71*/ 71*/
72typedef struct CallInfo { 72typedef struct CallInfo {
73 StkId base; /* base for called function */ 73 StkId base; /* base for this function */
74 StkId top; /* top for this function */ 74 StkId top; /* top for this function */
75 int nresults; /* expected number of results from this function */
75 union { 76 union {
76 struct { /* for Lua functions */ 77 struct { /* for Lua functions */
77 const Instruction *savedpc; 78 const Instruction *savedpc;
diff --git a/lvm.c b/lvm.c
index a7a4b3b3..4c5a7ec7 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.4 2004/04/30 20:13:38 roberto Exp roberto $ 2** $Id: lvm.c,v 2.5 2004/05/10 17:50:51 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*/
@@ -106,7 +106,8 @@ static void callTM (lua_State *L) {
106} 106}
107 107
108 108
109void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { 109StkId luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val,
110 const Instruction *pc) {
110 int loop; 111 int loop;
111 for (loop = 0; loop < MAXTAGLOOP; loop++) { 112 for (loop = 0; loop < MAXTAGLOOP; loop++) {
112 const TValue *tm; 113 const TValue *tm;
@@ -116,24 +117,30 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
116 if (!ttisnil(res) || /* result is no nil? */ 117 if (!ttisnil(res) || /* result is no nil? */
117 (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ 118 (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
118 setobj2s(L, val, res); 119 setobj2s(L, val, res);
119 return; 120 return L->base;
120 } 121 }
121 /* else will try the tag method */ 122 /* else will try the tag method */
122 } 123 }
123 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) 124 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) {
125 if (pc) L->ci->u.l.savedpc = pc;
124 luaG_typeerror(L, t, "index"); 126 luaG_typeerror(L, t, "index");
127 }
125 if (ttisfunction(tm)) { 128 if (ttisfunction(tm)) {
129 if (pc) L->ci->u.l.savedpc = pc;
126 prepTMcall(L, tm, t, key); 130 prepTMcall(L, tm, t, key);
127 callTMres(L, val); 131 callTMres(L, val);
128 return; 132 return L->base;
129 } 133 }
130 t = tm; /* else repeat with `tm' */ 134 t = tm; /* else repeat with `tm' */
131 } 135 }
136 if (pc) L->ci->u.l.savedpc = pc;
132 luaG_runerror(L, "loop in gettable"); 137 luaG_runerror(L, "loop in gettable");
138 return NULL; /* to avoid warnings */
133} 139}
134 140
135 141
136void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { 142StkId luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val,
143 const Instruction *pc) {
137 int loop; 144 int loop;
138 for (loop = 0; loop < MAXTAGLOOP; loop++) { 145 for (loop = 0; loop < MAXTAGLOOP; loop++) {
139 const TValue *tm; 146 const TValue *tm;
@@ -144,21 +151,26 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
144 (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ 151 (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
145 setobj2t(L, oldval, val); 152 setobj2t(L, oldval, val);
146 luaC_barrier(L, h, val); 153 luaC_barrier(L, h, val);
147 return; 154 return L->base;
148 } 155 }
149 /* else will try the tag method */ 156 /* else will try the tag method */
150 } 157 }
151 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) 158 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) {
159 if (pc) L->ci->u.l.savedpc = pc;
152 luaG_typeerror(L, t, "index"); 160 luaG_typeerror(L, t, "index");
161 }
153 if (ttisfunction(tm)) { 162 if (ttisfunction(tm)) {
163 if (pc) L->ci->u.l.savedpc = pc;
154 prepTMcall(L, tm, t, key); 164 prepTMcall(L, tm, t, key);
155 setobj2s(L, L->top+3, val); /* 3th argument */ 165 setobj2s(L, L->top+3, val); /* 3th argument */
156 callTM(L); 166 callTM(L);
157 return; 167 return L->base;
158 } 168 }
159 t = tm; /* else repeat with `tm' */ 169 t = tm; /* else repeat with `tm' */
160 } 170 }
171 if (pc) L->ci->u.l.savedpc = pc;
161 luaG_runerror(L, "loop in settable"); 172 luaG_runerror(L, "loop in settable");
173 return NULL; /* to avoid warnings */
162} 174}
163 175
164 176
@@ -427,22 +439,16 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
427 case OP_GETGLOBAL: { 439 case OP_GETGLOBAL: {
428 TValue *rb = KBx(i); 440 TValue *rb = KBx(i);
429 lua_assert(ttisstring(rb) && ttistable(&cl->g)); 441 lua_assert(ttisstring(rb) && ttistable(&cl->g));
430 L->ci->u.l.savedpc = pc; 442 base = luaV_gettable(L, &cl->g, rb, ra, pc); /***/
431 luaV_gettable(L, &cl->g, rb, ra); /***/
432 base = L->base;
433 break; 443 break;
434 } 444 }
435 case OP_GETTABLE: { 445 case OP_GETTABLE: {
436 L->ci->u.l.savedpc = pc; 446 base = luaV_gettable(L, RB(i), RKC(i), ra, pc); /***/
437 luaV_gettable(L, RB(i), RKC(i), ra); /***/
438 base = L->base;
439 break; 447 break;
440 } 448 }
441 case OP_SETGLOBAL: { 449 case OP_SETGLOBAL: {
442 lua_assert(ttisstring(KBx(i)) && ttistable(&cl->g)); 450 lua_assert(ttisstring(KBx(i)) && ttistable(&cl->g));
443 L->ci->u.l.savedpc = pc; 451 base = luaV_settable(L, &cl->g, KBx(i), ra, pc); /***/
444 luaV_settable(L, &cl->g, KBx(i), ra); /***/
445 base = L->base;
446 break; 452 break;
447 } 453 }
448 case OP_SETUPVAL: { 454 case OP_SETUPVAL: {
@@ -452,9 +458,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
452 break; 458 break;
453 } 459 }
454 case OP_SETTABLE: { 460 case OP_SETTABLE: {
455 L->ci->u.l.savedpc = pc; 461 base = luaV_settable(L, ra, RKB(i), RKC(i), pc); /***/
456 luaV_settable(L, ra, RKB(i), RKC(i)); /***/
457 base = L->base;
458 break; 462 break;
459 } 463 }
460 case OP_NEWTABLE: { 464 case OP_NEWTABLE: {
@@ -469,9 +473,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
469 case OP_SELF: { 473 case OP_SELF: {
470 StkId rb = RB(i); 474 StkId rb = RB(i);
471 setobjs2s(L, ra+1, rb); 475 setobjs2s(L, ra+1, rb);
472 L->ci->u.l.savedpc = pc; 476 base = luaV_gettable(L, rb, RKC(i), ra, pc); /***/
473 luaV_gettable(L, rb, RKC(i), ra); /***/
474 base = L->base;
475 break; 477 break;
476 } 478 }
477 case OP_ADD: { 479 case OP_ADD: {
@@ -582,43 +584,59 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
582 } 584 }
583 break; 585 break;
584 } 586 }
585 case OP_CALL: 587 case OP_CALL: { /***/
586 case OP_TAILCALL: { /***/ 588 int pcr;
587 StkId firstResult;
588 int b = GETARG_B(i); 589 int b = GETARG_B(i);
590 int nresults = GETARG_C(i) - 1;
589 if (b != 0) L->top = ra+b; /* else previous instruction set top */ 591 if (b != 0) L->top = ra+b; /* else previous instruction set top */
590 L->ci->u.l.savedpc = pc; 592 L->ci->u.l.savedpc = pc;
591 firstResult = luaD_precall(L, ra); 593 pcr = luaD_precall(L, ra, nresults);
592 if (firstResult) { 594 if (pcr == PCRLUA) {
593 int nresults = GETARG_C(i) - 1; 595 nexeccalls++;
594 if (firstResult > L->top) { /* yield? */ 596 goto callentry; /* restart luaV_execute over new Lua function */
595 (L->ci - 1)->u.l.savedpc = pc; 597 }
596 return NULL; 598 else if (pcr == PCRC) {
597 }
598 /* it was a C function (`precall' called it); adjust results */ 599 /* it was a C function (`precall' called it); adjust results */
599 luaD_poscall(L, nresults, firstResult);
600 if (nresults >= 0) L->top = L->ci->top; 600 if (nresults >= 0) L->top = L->ci->top;
601 base = L->base;
602 break;
601 } 603 }
602 else { /* it is a Lua function */ 604 else {
603 if (GET_OPCODE(i) == OP_CALL) /* regular call? */ 605 lua_assert(pcr == PCRYIELD);
604 nexeccalls++; 606 return NULL;
605 else { /* tail call: put new frame in place of previous one */ 607 }
606 int aux; 608 }
607 base = (L->ci - 1)->base; /* `luaD_precall' may change the stack */ 609 case OP_TAILCALL: { /***/
608 ra = RA(i); 610 int pcr;
609 if (L->openupval) luaF_close(L, base); 611 int b = GETARG_B(i);
610 for (aux = 0; ra+aux < L->top; aux++) /* move frame down */ 612 if (b != 0) L->top = ra+b; /* else previous instruction set top */
611 setobjs2s(L, base+aux-1, ra+aux); 613 L->ci->u.l.savedpc = pc;
612 (L->ci - 1)->top = L->top = base+aux; /* correct top */ 614 lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
613 (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc; 615 pcr = luaD_precall(L, ra, LUA_MULTRET);
614 (L->ci - 1)->u.l.tailcalls++; /* one more call lost */ 616 if (pcr == PCRLUA) {
615 L->ci--; /* remove new frame */ 617 /* tail call: put new frame in place of previous one */
616 L->base = L->ci->base; 618 int aux;
617 } 619 base = (L->ci - 1)->base; /* `luaD_precall' may change the stack */
620 ra = RA(i);
621 if (L->openupval) luaF_close(L, base);
622 for (aux = 0; ra+aux < L->top; aux++) /* move frame down */
623 setobjs2s(L, base+aux-1, ra+aux);
624 (L->ci - 1)->top = L->top = base+aux; /* correct top */
625 (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc;
626 (L->ci - 1)->u.l.tailcalls++; /* one more call lost */
627 L->ci--; /* remove new frame */
628 L->base = L->ci->base;
618 goto callentry; 629 goto callentry;
619 } 630 }
620 base = L->base; 631 else if (pcr == PCRC) {
621 break; 632 /* it was a C function (`precall' called it) */
633 base = L->base;
634 break;
635 }
636 else {
637 lua_assert(pcr == PCRYIELD);
638 return NULL;
639 }
622 } 640 }
623 case OP_RETURN: { 641 case OP_RETURN: {
624 CallInfo *ci = L->ci - 1; /* previous function frame */ 642 CallInfo *ci = L->ci - 1; /* previous function frame */
@@ -629,10 +647,9 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
629 if (--nexeccalls == 0) /* was previous function running `here'? */ 647 if (--nexeccalls == 0) /* was previous function running `here'? */
630 return ra; /* no: return */ 648 return ra; /* no: return */
631 else { /* yes: continue its execution */ 649 else { /* yes: continue its execution */
632 int nresults; 650 int nresults = (ci+1)->nresults;
633 lua_assert(isLua(ci)); 651 lua_assert(isLua(ci));
634 lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL); 652 lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL);
635 nresults = GETARG_C(*(ci->u.l.savedpc - 1)) - 1;
636 luaD_poscall(L, nresults, ra); 653 luaD_poscall(L, nresults, ra);
637 if (nresults >= 0) L->top = L->ci->top; 654 if (nresults >= 0) L->top = L->ci->top;
638 goto retentry; 655 goto retentry;
diff --git a/lvm.h b/lvm.h
index defe611f..0cae36c9 100644
--- a/lvm.h
+++ b/lvm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.h,v 1.49 2003/07/16 20:49:02 roberto Exp roberto $ 2** $Id: lvm.h,v 2.1 2003/12/10 12:13:36 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*/
@@ -26,8 +26,10 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
26int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2); 26int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
27const TValue *luaV_tonumber (const TValue *obj, TValue *n); 27const TValue *luaV_tonumber (const TValue *obj, TValue *n);
28int luaV_tostring (lua_State *L, StkId obj); 28int luaV_tostring (lua_State *L, StkId obj);
29void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val); 29StkId luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val,
30void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val); 30 const Instruction *pc);
31StkId luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val,
32 const Instruction *pc);
31StkId luaV_execute (lua_State *L, int nexeccalls); 33StkId luaV_execute (lua_State *L, int nexeccalls);
32void luaV_concat (lua_State *L, int total, int last); 34void luaV_concat (lua_State *L, int total, int last);
33 35