aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c47
1 files changed, 21 insertions, 26 deletions
diff --git a/ldo.c b/ldo.c
index 93e2aa0a..f462353f 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.218 2003/05/13 19:22:19 roberto Exp roberto $ 2** $Id: ldo.c,v 1.219 2003/05/14 21:02:39 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*/
@@ -243,6 +243,7 @@ StkId luaD_precall (lua_State *L, StkId func) {
243 cl = &clvalue(func)->l; 243 cl = &clvalue(func)->l;
244 if (!cl->isC) { /* Lua function? prepare its call */ 244 if (!cl->isC) { /* Lua function? prepare its call */
245 CallInfo *ci; 245 CallInfo *ci;
246 StkId st;
246 Proto *p = cl->p; 247 Proto *p = cl->p;
247 if (p->is_vararg) /* varargs? */ 248 if (p->is_vararg) /* varargs? */
248 adjust_varargs(L, p->numparams, func+1); 249 adjust_varargs(L, p->numparams, func+1);
@@ -252,9 +253,8 @@ StkId luaD_precall (lua_State *L, StkId func) {
252 ci->top = L->base + p->maxstacksize; 253 ci->top = L->base + p->maxstacksize;
253 ci->u.l.savedpc = p->code; /* starting point */ 254 ci->u.l.savedpc = p->code; /* starting point */
254 ci->u.l.tailcalls = 0; 255 ci->u.l.tailcalls = 0;
255 ci->state = CI_SAVEDPC; 256 for (st = L->top; st < ci->top; st++)
256 while (L->top < ci->top) 257 setnilvalue(st);
257 setnilvalue(L->top++);
258 L->top = ci->top; 258 L->top = ci->top;
259 return NULL; 259 return NULL;
260 } 260 }
@@ -265,7 +265,6 @@ StkId luaD_precall (lua_State *L, StkId func) {
265 ci = ++L->ci; /* now `enter' new function */ 265 ci = ++L->ci; /* now `enter' new function */
266 L->base = L->ci->base = restorestack(L, funcr) + 1; 266 L->base = L->ci->base = restorestack(L, funcr) + 1;
267 ci->top = L->top + LUA_MINSTACK; 267 ci->top = L->top + LUA_MINSTACK;
268 ci->state = CI_C; /* a C function */
269 if (L->hookmask & LUA_MASKCALL) 268 if (L->hookmask & LUA_MASKCALL)
270 luaD_callhook(L, LUA_HOOKCALL, -1); 269 luaD_callhook(L, LUA_HOOKCALL, -1);
271 lua_unlock(L); 270 lua_unlock(L);
@@ -279,7 +278,7 @@ StkId luaD_precall (lua_State *L, StkId func) {
279static StkId callrethooks (lua_State *L, StkId firstResult) { 278static StkId callrethooks (lua_State *L, StkId firstResult) {
280 ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ 279 ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
281 luaD_callhook(L, LUA_HOOKRET, -1); 280 luaD_callhook(L, LUA_HOOKRET, -1);
282 if (!(L->ci->state & CI_C)) { /* Lua function? */ 281 if (f_isLua(L->ci)) { /* Lua function? */
283 while (L->ci->u.l.tailcalls--) /* call hook for eventual tail calls */ 282 while (L->ci->u.l.tailcalls--) /* call hook for eventual tail calls */
284 luaD_callhook(L, LUA_HOOKTAILRET, -1); 283 luaD_callhook(L, LUA_HOOKTAILRET, -1);
285 } 284 }
@@ -313,7 +312,6 @@ void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
313*/ 312*/
314void luaD_call (lua_State *L, StkId func, int nResults) { 313void luaD_call (lua_State *L, StkId func, int nResults) {
315 StkId firstResult; 314 StkId firstResult;
316 lua_assert(!(L->ci->state & CI_CALLING));
317 if (++L->nCcalls >= LUA_MAXCCALLS) { 315 if (++L->nCcalls >= LUA_MAXCCALLS) {
318 if (L->nCcalls == LUA_MAXCCALLS) 316 if (L->nCcalls == LUA_MAXCCALLS)
319 luaG_runerror(L, "C stack overflow"); 317 luaG_runerror(L, "C stack overflow");
@@ -322,7 +320,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
322 } 320 }
323 firstResult = luaD_precall(L, func); 321 firstResult = luaD_precall(L, func);
324 if (firstResult == NULL) /* is a Lua function? */ 322 if (firstResult == NULL) /* is a Lua function? */
325 firstResult = luaV_execute(L); /* call it */ 323 firstResult = luaV_execute(L, 1); /* call it */
326 luaD_poscall(L, nResults, firstResult); 324 luaD_poscall(L, nResults, firstResult);
327 L->nCcalls--; 325 L->nCcalls--;
328 luaC_checkGC(L); 326 luaC_checkGC(L);
@@ -333,29 +331,28 @@ static void resume (lua_State *L, void *ud) {
333 StkId firstResult; 331 StkId firstResult;
334 int nargs = *cast(int *, ud); 332 int nargs = *cast(int *, ud);
335 CallInfo *ci = L->ci; 333 CallInfo *ci = L->ci;
336 if (ci == L->base_ci) { /* no activation record? */ 334 if (!L->isSuspended) {
337 if (nargs >= L->top - L->base) 335 if (ci == L->base_ci) { /* no activation record? */
338 luaG_runerror(L, "cannot resume dead coroutine"); 336 if (nargs >= L->top - L->base)
339 luaD_precall(L, L->top - (nargs + 1)); /* start coroutine */ 337 luaG_runerror(L, "cannot resume dead coroutine");
338 luaD_precall(L, L->top - (nargs + 1)); /* start coroutine */
339 }
340 else
341 luaG_runerror(L, "cannot resume non-suspended coroutine");
340 } 342 }
341 else if (ci->state & CI_YIELD) { /* inside a yield? */ 343 else { /* resumming from previous yield */
342 if (ci->state & CI_C) { /* `common' yield? */ 344 if (!f_isLua(ci)) { /* `common' yield? */
343 /* finish interrupted execution of `OP_CALL' */ 345 /* finish interrupted execution of `OP_CALL' */
344 int nresults; 346 int nresults;
345 lua_assert((ci-1)->state & CI_SAVEDPC);
346 lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL || 347 lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL ||
347 GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL); 348 GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL);
348 nresults = GETARG_C(*((ci-1)->u.l.savedpc - 1)) - 1; 349 nresults = GETARG_C(*((ci-1)->u.l.savedpc - 1)) - 1;
349 luaD_poscall(L, nresults, L->top - nargs); /* complete it */ 350 luaD_poscall(L, nresults, L->top - nargs); /* complete it */
350 if (nresults >= 0) L->top = L->ci->top; 351 if (nresults >= 0) L->top = L->ci->top;
351 } 352 } /* else yielded inside a hook: just continue its execution */
352 else { /* yielded inside a hook: just continue its execution */
353 ci->state &= ~CI_YIELD;
354 }
355 } 353 }
356 else 354 L->isSuspended = 0;
357 luaG_runerror(L, "cannot resume non-suspended coroutine"); 355 firstResult = luaV_execute(L, L->ci - L->base_ci);
358 firstResult = luaV_execute(L);
359 if (firstResult != NULL) /* return? */ 356 if (firstResult != NULL) /* return? */
360 luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */ 357 luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */
361} 358}
@@ -388,9 +385,7 @@ LUA_API int lua_yield (lua_State *L, int nresults) {
388 ci = L->ci; 385 ci = L->ci;
389 if (L->nCcalls > 0) 386 if (L->nCcalls > 0)
390 luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); 387 luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
391 if (ci->state & CI_C) { /* usual yield */ 388 if (!f_isLua(ci)) { /* usual yield */
392 if ((ci-1)->state & CI_C)
393 luaG_runerror(L, "cannot yield a C function");
394 if (L->top - nresults > L->base) { /* is there garbage in the stack? */ 389 if (L->top - nresults > L->base) { /* is there garbage in the stack? */
395 int i; 390 int i;
396 for (i=0; i<nresults; i++) /* move down results */ 391 for (i=0; i<nresults; i++) /* move down results */
@@ -398,7 +393,7 @@ LUA_API int lua_yield (lua_State *L, int nresults) {
398 L->top = L->base + nresults; 393 L->top = L->base + nresults;
399 } 394 }
400 } /* else it's an yield inside a hook: nothing to do */ 395 } /* else it's an yield inside a hook: nothing to do */
401 ci->state |= CI_YIELD; 396 L->isSuspended = 1;
402 lua_unlock(L); 397 lua_unlock(L);
403 return -1; 398 return -1;
404} 399}