diff options
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 52 |
1 files changed, 24 insertions, 28 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 2.28 2005/07/11 14:00:31 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.29 2005/08/09 19:49:04 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 | */ |
@@ -134,7 +134,7 @@ static void correctstack (lua_State *L, TValue *oldstack) { | |||
134 | ci->base = (ci->base - oldstack) + L->stack; | 134 | ci->base = (ci->base - oldstack) + L->stack; |
135 | ci->func = (ci->func - oldstack) + L->stack; | 135 | ci->func = (ci->func - oldstack) + L->stack; |
136 | } | 136 | } |
137 | L->base = L->ci->base; | 137 | L->base = (L->base - oldstack) + L->stack; |
138 | } | 138 | } |
139 | 139 | ||
140 | 140 | ||
@@ -314,13 +314,14 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
314 | L->base = ci->base = ci->func + 1; | 314 | L->base = ci->base = ci->func + 1; |
315 | ci->top = L->top + LUA_MINSTACK; | 315 | ci->top = L->top + LUA_MINSTACK; |
316 | lua_assert(ci->top <= L->stack_last); | 316 | lua_assert(ci->top <= L->stack_last); |
317 | ci->nresults = nresults; | ||
317 | if (L->hookmask & LUA_MASKCALL) | 318 | if (L->hookmask & LUA_MASKCALL) |
318 | luaD_callhook(L, LUA_HOOKCALL, -1); | 319 | luaD_callhook(L, LUA_HOOKCALL, -1); |
319 | lua_unlock(L); | 320 | lua_unlock(L); |
320 | n = (*curr_func(L)->c.f)(L); /* do the actual call */ | 321 | n = (*curr_func(L)->c.f)(L); /* do the actual call */ |
321 | lua_lock(L); | 322 | lua_lock(L); |
322 | if (n >= 0) { /* no yielding? */ | 323 | if (n >= 0) { /* no yielding? */ |
323 | luaD_poscall(L, nresults, L->top - n); | 324 | luaD_poscall(L, L->top - n); |
324 | return PCRC; | 325 | return PCRC; |
325 | } | 326 | } |
326 | else { | 327 | else { |
@@ -342,22 +343,24 @@ static StkId callrethooks (lua_State *L, StkId firstResult) { | |||
342 | } | 343 | } |
343 | 344 | ||
344 | 345 | ||
345 | void luaD_poscall (lua_State *L, int wanted, StkId firstResult) { | 346 | int luaD_poscall (lua_State *L, StkId firstResult) { |
346 | StkId res; | 347 | StkId res; |
348 | int wanted, i; | ||
349 | CallInfo *ci; | ||
347 | if (L->hookmask & LUA_MASKRET) | 350 | if (L->hookmask & LUA_MASKRET) |
348 | firstResult = callrethooks(L, firstResult); | 351 | firstResult = callrethooks(L, firstResult); |
349 | res = L->ci->func; /* res == final position of 1st result */ | 352 | ci = L->ci--; |
350 | L->ci--; | 353 | res = ci->func; /* res == final position of 1st result */ |
351 | L->base = L->ci->base; /* restore base */ | 354 | wanted = ci->nresults; |
352 | L->savedpc = L->ci->savedpc; /* restore savedpc */ | 355 | L->base = (ci - 1)->base; /* restore base */ |
356 | L->savedpc = (ci - 1)->savedpc; /* restore savedpc */ | ||
353 | /* move results to correct place */ | 357 | /* move results to correct place */ |
354 | while (wanted != 0 && firstResult < L->top) { | 358 | for (i = wanted; i != 0 && firstResult < L->top; i--) |
355 | setobjs2s(L, res++, firstResult++); | 359 | setobjs2s(L, res++, firstResult++); |
356 | wanted--; | 360 | while (i-- > 0) |
357 | } | ||
358 | while (wanted-- > 0) | ||
359 | setnilvalue(res++); | 361 | setnilvalue(res++); |
360 | L->top = res; | 362 | L->top = res; |
363 | return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */ | ||
361 | } | 364 | } |
362 | 365 | ||
363 | 366 | ||
@@ -374,41 +377,34 @@ void luaD_call (lua_State *L, StkId func, int nResults) { | |||
374 | else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) | 377 | else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) |
375 | luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ | 378 | luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ |
376 | } | 379 | } |
377 | if (luaD_precall(L, func, nResults) == PCRLUA) { /* is a Lua function? */ | 380 | if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */ |
378 | StkId firstResult = luaV_execute(L, 1); /* call it */ | 381 | luaV_execute(L, 1); /* call it */ |
379 | luaD_poscall(L, nResults, firstResult); | ||
380 | } | ||
381 | L->nCcalls--; | 382 | L->nCcalls--; |
382 | luaC_checkGC(L); | 383 | luaC_checkGC(L); |
383 | } | 384 | } |
384 | 385 | ||
385 | 386 | ||
386 | static void resume (lua_State *L, void *ud) { | 387 | static void resume (lua_State *L, void *ud) { |
387 | StkId firstResult; | ||
388 | StkId firstArg = cast(StkId, ud); | 388 | StkId firstArg = cast(StkId, ud); |
389 | CallInfo *ci = L->ci; | 389 | CallInfo *ci = L->ci; |
390 | if (L->status != LUA_YIELD) { | 390 | if (L->status != LUA_YIELD) { /* start coroutine */ |
391 | lua_assert(ci == L->base_ci && firstArg > L->base); | 391 | lua_assert(ci == L->base_ci && firstArg > L->base); |
392 | luaD_precall(L, firstArg - 1, LUA_MULTRET); /* start coroutine */ | 392 | if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA) |
393 | return; | ||
393 | } | 394 | } |
394 | else { /* resuming from previous yield */ | 395 | else { /* resuming from previous yield */ |
395 | if (!f_isLua(ci)) { /* `common' yield? */ | 396 | if (!f_isLua(ci)) { /* `common' yield? */ |
396 | /* finish interrupted execution of `OP_CALL' */ | 397 | /* finish interrupted execution of `OP_CALL' */ |
397 | int nresults = ci->nresults; | ||
398 | lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL || | 398 | lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL || |
399 | GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL); | 399 | GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL); |
400 | luaD_poscall(L, nresults, firstArg); /* complete it */ | 400 | if (luaD_poscall(L, firstArg)) /* complete it... */ |
401 | if (nresults >= 0) L->top = L->ci->top; | 401 | L->top = L->ci->top; /* and correct top if not multiple results */ |
402 | } | 402 | } |
403 | else { /* yielded inside a hook: just continue its execution */ | 403 | else /* yielded inside a hook: just continue its execution */ |
404 | L->base = L->ci->base; | 404 | L->base = L->ci->base; |
405 | } | ||
406 | } | 405 | } |
407 | L->status = 0; | 406 | L->status = 0; |
408 | firstResult = luaV_execute(L, cast(int, L->ci - L->base_ci)); | 407 | luaV_execute(L, cast(int, L->ci - L->base_ci)); |
409 | if (firstResult != NULL) { /* return? */ | ||
410 | luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */ | ||
411 | } | ||
412 | } | 408 | } |
413 | 409 | ||
414 | 410 | ||