aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c30
1 files changed, 18 insertions, 12 deletions
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 */