diff options
| -rw-r--r-- | lapi.c | 19 | ||||
| -rw-r--r-- | lbaselib.c | 40 | ||||
| -rw-r--r-- | ldo.c | 32 | ||||
| -rw-r--r-- | lstate.c | 4 | ||||
| -rw-r--r-- | lstate.h | 4 | ||||
| -rw-r--r-- | lua.h | 15 | ||||
| -rw-r--r-- | lvm.c | 4 |
7 files changed, 79 insertions, 39 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lapi.c,v 2.17 2004/08/17 17:45:45 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 2.18 2004/08/30 13:44:44 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 | */ |
| @@ -97,6 +97,7 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { | |||
| 97 | if (from == to) return; | 97 | if (from == to) return; |
| 98 | lua_lock(to); | 98 | lua_lock(to); |
| 99 | api_checknelems(from, n); | 99 | api_checknelems(from, n); |
| 100 | api_check(L, G(from) == G(to)); | ||
| 100 | from->top -= n; | 101 | from->top -= n; |
| 101 | for (i = 0; i < n; i++) { | 102 | for (i = 0; i < n; i++) { |
| 102 | setobj2s(to, to->top, from->top + i); | 103 | setobj2s(to, to->top, from->top + i); |
| @@ -479,6 +480,15 @@ LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { | |||
| 479 | } | 480 | } |
| 480 | 481 | ||
| 481 | 482 | ||
| 483 | LUA_API int lua_pushthread (lua_State *L) { | ||
| 484 | lua_lock(L); | ||
| 485 | setthvalue(L, L->top, L); | ||
| 486 | api_incr_top(L); | ||
| 487 | lua_unlock(L); | ||
| 488 | return (G(L)->mainthread == L); | ||
| 489 | } | ||
| 490 | |||
| 491 | |||
| 482 | 492 | ||
| 483 | /* | 493 | /* |
| 484 | ** get functions (Lua -> stack) | 494 | ** get functions (Lua -> stack) |
| @@ -650,7 +660,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { | |||
| 650 | case LUA_TTABLE: { | 660 | case LUA_TTABLE: { |
| 651 | hvalue(obj)->metatable = mt; | 661 | hvalue(obj)->metatable = mt; |
| 652 | if (mt) | 662 | if (mt) |
| 653 | luaC_objbarrier(L, hvalue(obj), mt); | 663 | luaC_objbarriert(L, hvalue(obj), mt); |
| 654 | break; | 664 | break; |
| 655 | } | 665 | } |
| 656 | case LUA_TUSERDATA: { | 666 | case LUA_TUSERDATA: { |
| @@ -816,6 +826,11 @@ LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data) { | |||
| 816 | } | 826 | } |
| 817 | 827 | ||
| 818 | 828 | ||
| 829 | LUA_API int lua_threadstatus (lua_State *L) { | ||
| 830 | return L->status; | ||
| 831 | } | ||
| 832 | |||
| 833 | |||
| 819 | /* | 834 | /* |
| 820 | ** Garbage-collection function | 835 | ** Garbage-collection function |
| 821 | */ | 836 | */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbaselib.c,v 1.156 2004/08/30 18:35:14 roberto Exp roberto $ | 2 | ** $Id: lbaselib.c,v 1.157 2004/09/03 13:16:48 roberto Exp roberto $ |
| 3 | ** Basic library | 3 | ** Basic library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -523,9 +523,13 @@ static int auxresume (lua_State *L, lua_State *co, int narg) { | |||
| 523 | int status; | 523 | int status; |
| 524 | if (!lua_checkstack(co, narg)) | 524 | if (!lua_checkstack(co, narg)) |
| 525 | luaL_error(L, "too many arguments to resume"); | 525 | luaL_error(L, "too many arguments to resume"); |
| 526 | if (lua_threadstatus(co) == 0 && lua_gettop(co) == 0) { | ||
| 527 | lua_pushliteral(L, "cannot resume dead coroutine"); | ||
| 528 | return -1; /* error flag */ | ||
| 529 | } | ||
| 526 | lua_xmove(L, co, narg); | 530 | lua_xmove(L, co, narg); |
| 527 | status = lua_resume(co, narg); | 531 | status = lua_resume(co, narg); |
| 528 | if (status == 0) { | 532 | if (status == 0 || status == LUA_YIELD) { |
| 529 | int nres = lua_gettop(co); | 533 | int nres = lua_gettop(co); |
| 530 | if (!lua_checkstack(L, nres)) | 534 | if (!lua_checkstack(L, nres)) |
| 531 | luaL_error(L, "too many results to resume"); | 535 | luaL_error(L, "too many results to resume"); |
| @@ -599,22 +603,44 @@ static int luaB_costatus (lua_State *L) { | |||
| 599 | luaL_argcheck(L, co, 1, "coroutine expected"); | 603 | luaL_argcheck(L, co, 1, "coroutine expected"); |
| 600 | if (L == co) lua_pushliteral(L, "running"); | 604 | if (L == co) lua_pushliteral(L, "running"); |
| 601 | else { | 605 | else { |
| 602 | lua_Debug ar; | 606 | switch (lua_threadstatus(co)) { |
| 603 | if (lua_getstack(co, 0, &ar) == 0 && lua_gettop(co) == 0) | 607 | case LUA_YIELD: |
| 604 | lua_pushliteral(L, "dead"); | 608 | lua_pushliteral(L, "suspended"); |
| 605 | else | 609 | break; |
| 606 | lua_pushliteral(L, "suspended"); | 610 | case 0: { |
| 611 | lua_Debug ar; | ||
| 612 | if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ | ||
| 613 | lua_pushliteral(L, "normal"); /* it is running */ | ||
| 614 | else if (lua_gettop(co) == 0) | ||
| 615 | lua_pushliteral(L, "dead"); | ||
| 616 | else | ||
| 617 | lua_pushliteral(L, "suspended"); /* initial state */ | ||
| 618 | break; | ||
| 619 | } | ||
| 620 | default: /* some error occured */ | ||
| 621 | lua_pushliteral(L, "dead"); | ||
| 622 | break; | ||
| 623 | } | ||
| 607 | } | 624 | } |
| 608 | return 1; | 625 | return 1; |
| 609 | } | 626 | } |
| 610 | 627 | ||
| 611 | 628 | ||
| 629 | static int luaB_cocurrent (lua_State *L) { | ||
| 630 | if (lua_pushthread(L)) | ||
| 631 | return 0; /* main thread is not a coroutine */ | ||
| 632 | else | ||
| 633 | return 1; | ||
| 634 | } | ||
| 635 | |||
| 636 | |||
| 612 | static const luaL_reg co_funcs[] = { | 637 | static const luaL_reg co_funcs[] = { |
| 613 | {"create", luaB_cocreate}, | 638 | {"create", luaB_cocreate}, |
| 614 | {"wrap", luaB_cowrap}, | 639 | {"wrap", luaB_cowrap}, |
| 615 | {"resume", luaB_coresume}, | 640 | {"resume", luaB_coresume}, |
| 616 | {"yield", luaB_yield}, | 641 | {"yield", luaB_yield}, |
| 617 | {"status", luaB_costatus}, | 642 | {"status", luaB_costatus}, |
| 643 | {"current", luaB_cocurrent}, | ||
| 618 | {NULL, NULL} | 644 | {NULL, NULL} |
| 619 | }; | 645 | }; |
| 620 | 646 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.c,v 2.8 2004/09/03 15:48:56 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.9 2004/09/08 14:23:09 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 | */ |
| @@ -358,7 +358,7 @@ static void resume (lua_State *L, void *ud) { | |||
| 358 | StkId firstResult; | 358 | StkId firstResult; |
| 359 | int nargs = *cast(int *, ud); | 359 | int nargs = *cast(int *, ud); |
| 360 | CallInfo *ci = L->ci; | 360 | CallInfo *ci = L->ci; |
| 361 | if (!L->isSuspended) { | 361 | if (L->status != LUA_YIELD) { |
| 362 | lua_assert(ci == L->base_ci && nargs < L->top - L->base); | 362 | lua_assert(ci == L->base_ci && nargs < L->top - L->base); |
| 363 | luaD_precall(L, L->top - (nargs + 1), LUA_MULTRET); /* start coroutine */ | 363 | luaD_precall(L, L->top - (nargs + 1), LUA_MULTRET); /* start coroutine */ |
| 364 | } | 364 | } |
| @@ -372,10 +372,11 @@ static void resume (lua_State *L, void *ud) { | |||
| 372 | if (nresults >= 0) L->top = L->ci->top; | 372 | if (nresults >= 0) L->top = L->ci->top; |
| 373 | } /* else yielded inside a hook: just continue its execution */ | 373 | } /* else yielded inside a hook: just continue its execution */ |
| 374 | } | 374 | } |
| 375 | L->isSuspended = 0; | 375 | L->status = 0; |
| 376 | firstResult = luaV_execute(L, L->ci - L->base_ci); | 376 | firstResult = luaV_execute(L, L->ci - L->base_ci); |
| 377 | if (firstResult != NULL) /* return? */ | 377 | if (firstResult != NULL) { /* return? */ |
| 378 | luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */ | 378 | luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */ |
| 379 | } | ||
| 379 | } | 380 | } |
| 380 | 381 | ||
| 381 | 382 | ||
| @@ -393,25 +394,20 @@ LUA_API int lua_resume (lua_State *L, int nargs) { | |||
| 393 | lu_byte old_allowhooks; | 394 | lu_byte old_allowhooks; |
| 394 | lua_lock(L); | 395 | lua_lock(L); |
| 395 | lua_assert(L->errfunc == 0 && L->nCcalls == 0); | 396 | lua_assert(L->errfunc == 0 && L->nCcalls == 0); |
| 396 | if (!L->isSuspended) { | 397 | if (L->status != LUA_YIELD) { |
| 397 | if (L->ci == L->base_ci) { /* no activation record? */ | 398 | if (L->status != 0) |
| 398 | if (nargs >= L->top - L->base) | 399 | return resume_error(L, "cannot resume dead coroutine"); |
| 399 | return resume_error(L, "cannot resume dead coroutine"); | 400 | else if (L->ci != L->base_ci) |
| 400 | } | ||
| 401 | else | ||
| 402 | return resume_error(L, "cannot resume non-suspended coroutine"); | 401 | return resume_error(L, "cannot resume non-suspended coroutine"); |
| 403 | } | 402 | } |
| 404 | old_allowhooks = L->allowhook; | 403 | old_allowhooks = L->allowhook; |
| 405 | status = luaD_rawrunprotected(L, resume, &nargs); | 404 | status = luaD_rawrunprotected(L, resume, &nargs); |
| 406 | if (status != 0) { /* error? */ | 405 | if (status != 0) { /* error? */ |
| 407 | L->ci = L->base_ci; /* go back to initial level */ | 406 | L->status = status; /* mark thread as `dead' */ |
| 408 | L->base = L->ci->base; | 407 | seterrorobj(L, status, L->top); |
| 409 | L->nCcalls = 0; | ||
| 410 | luaF_close(L, L->base); /* close eventual pending closures */ | ||
| 411 | seterrorobj(L, status, L->base); | ||
| 412 | L->allowhook = old_allowhooks; | ||
| 413 | restore_stack_limit(L); | ||
| 414 | } | 408 | } |
| 409 | else | ||
| 410 | status = L->status; | ||
| 415 | lua_unlock(L); | 411 | lua_unlock(L); |
| 416 | return status; | 412 | return status; |
| 417 | } | 413 | } |
| @@ -431,7 +427,7 @@ LUA_API int lua_yield (lua_State *L, int nresults) { | |||
| 431 | L->top = L->base + nresults; | 427 | L->top = L->base + nresults; |
| 432 | } | 428 | } |
| 433 | } /* else it's an yield inside a hook: nothing to do */ | 429 | } /* else it's an yield inside a hook: nothing to do */ |
| 434 | L->isSuspended = 1; | 430 | L->status = LUA_YIELD; |
| 435 | lua_unlock(L); | 431 | lua_unlock(L); |
| 436 | return -1; | 432 | return -1; |
| 437 | } | 433 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.c,v 2.12 2004/08/30 13:44:44 roberto Exp $ | 2 | ** $Id: lstate.c,v 2.13 2004/09/08 14:23:09 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 | */ |
| @@ -114,7 +114,7 @@ static void preinit_state (lua_State *L, global_State *g) { | |||
| 114 | L->openupval = NULL; | 114 | L->openupval = NULL; |
| 115 | L->size_ci = 0; | 115 | L->size_ci = 0; |
| 116 | L->nCcalls = 0; | 116 | L->nCcalls = 0; |
| 117 | L->isSuspended = 0; | 117 | L->status = 0; |
| 118 | L->base_ci = L->ci = NULL; | 118 | L->base_ci = L->ci = NULL; |
| 119 | L->errfunc = 0; | 119 | L->errfunc = 0; |
| 120 | setnilvalue(gt(L)); | 120 | setnilvalue(gt(L)); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.h,v 2.6 2004/08/24 20:12:06 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 2.7 2004/08/30 13:44:44 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 | */ |
| @@ -111,7 +111,7 @@ struct lua_State { | |||
| 111 | unsigned short nCcalls; /* number of nested C calls */ | 111 | unsigned short nCcalls; /* number of nested C calls */ |
| 112 | lu_byte hookmask; | 112 | lu_byte hookmask; |
| 113 | lu_byte allowhook; | 113 | lu_byte allowhook; |
| 114 | lu_byte isSuspended; | 114 | lu_byte status; |
| 115 | int basehookcount; | 115 | int basehookcount; |
| 116 | int hookcount; | 116 | int hookcount; |
| 117 | lua_Hook hook; | 117 | lua_Hook hook; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lua.h,v 1.191 2004/06/02 17:37:03 roberto Exp roberto $ | 2 | ** $Id: lua.h,v 1.192 2004/06/04 15:30:53 roberto Exp roberto $ |
| 3 | ** Lua - An Extensible Extension Language | 3 | ** Lua - An Extensible Extension Language |
| 4 | ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil | 4 | ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil |
| 5 | ** http://www.lua.org mailto:info@lua.org | 5 | ** http://www.lua.org mailto:info@lua.org |
| @@ -37,11 +37,12 @@ | |||
| 37 | #define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) | 37 | #define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) |
| 38 | 38 | ||
| 39 | 39 | ||
| 40 | /* error codes for `lua_pcall' */ | 40 | /* return codes for `lua_pcall', `lua_resume', and `lua_threadstatus' */ |
| 41 | #define LUA_ERRRUN 1 | 41 | #define LUA_YIELD 1 |
| 42 | #define LUA_ERRSYNTAX 2 | 42 | #define LUA_ERRRUN 2 |
| 43 | #define LUA_ERRMEM 3 | 43 | #define LUA_ERRSYNTAX 3 |
| 44 | #define LUA_ERRERR 4 | 44 | #define LUA_ERRMEM 4 |
| 45 | #define LUA_ERRERR 5 | ||
| 45 | 46 | ||
| 46 | 47 | ||
| 47 | typedef struct lua_State lua_State; | 48 | typedef struct lua_State lua_State; |
| @@ -165,6 +166,7 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...); | |||
| 165 | LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n); | 166 | LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n); |
| 166 | LUA_API void lua_pushboolean (lua_State *L, int b); | 167 | LUA_API void lua_pushboolean (lua_State *L, int b); |
| 167 | LUA_API void lua_pushlightuserdata (lua_State *L, void *p); | 168 | LUA_API void lua_pushlightuserdata (lua_State *L, void *p); |
| 169 | LUA_API int lua_pushthread (lua_State *L); | ||
| 168 | 170 | ||
| 169 | 171 | ||
| 170 | /* | 172 | /* |
| @@ -208,6 +210,7 @@ LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data); | |||
| 208 | */ | 210 | */ |
| 209 | LUA_API int lua_yield (lua_State *L, int nresults); | 211 | LUA_API int lua_yield (lua_State *L, int nresults); |
| 210 | LUA_API int lua_resume (lua_State *L, int narg); | 212 | LUA_API int lua_resume (lua_State *L, int narg); |
| 213 | LUA_API int lua_threadstatus (lua_State *L); | ||
| 211 | 214 | ||
| 212 | /* | 215 | /* |
| 213 | ** garbage-collection function and options | 216 | ** garbage-collection function and options |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 2.12 2004/08/10 19:17:23 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.13 2004/08/12 14:19: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 | */ |
| @@ -398,7 +398,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { | |||
| 398 | if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && | 398 | if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && |
| 399 | (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { | 399 | (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { |
| 400 | traceexec(L, pc); /***/ | 400 | traceexec(L, pc); /***/ |
| 401 | if (L->isSuspended) { /* did hook yield? */ | 401 | if (L->status == LUA_YIELD) { /* did hook yield? */ |
| 402 | L->ci->savedpc = pc - 1; | 402 | L->ci->savedpc = pc - 1; |
| 403 | return NULL; | 403 | return NULL; |
| 404 | } | 404 | } |
