aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c19
-rw-r--r--lbaselib.c40
-rw-r--r--ldo.c32
-rw-r--r--lstate.c4
-rw-r--r--lstate.h4
-rw-r--r--lua.h15
-rw-r--r--lvm.c4
7 files changed, 79 insertions, 39 deletions
diff --git a/lapi.c b/lapi.c
index c8cf819b..26b2c3b5 100644
--- a/lapi.c
+++ b/lapi.c
@@ -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
483LUA_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
829LUA_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*/
diff --git a/lbaselib.c b/lbaselib.c
index 762593a6..4c54a649 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -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
629static 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
612static const luaL_reg co_funcs[] = { 637static 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
diff --git a/ldo.c b/ldo.c
index 19c57153..a016f71a 100644
--- a/ldo.c
+++ b/ldo.c
@@ -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}
diff --git a/lstate.c b/lstate.c
index 0a2eaefb..2b34cdbd 100644
--- a/lstate.c
+++ b/lstate.c
@@ -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));
diff --git a/lstate.h b/lstate.h
index d8bda576..836e3df5 100644
--- a/lstate.h
+++ b/lstate.h
@@ -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;
diff --git a/lua.h b/lua.h
index 0b5347d6..66095219 100644
--- a/lua.h
+++ b/lua.h
@@ -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
47typedef struct lua_State lua_State; 48typedef struct lua_State lua_State;
@@ -165,6 +166,7 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
165LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n); 166LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
166LUA_API void lua_pushboolean (lua_State *L, int b); 167LUA_API void lua_pushboolean (lua_State *L, int b);
167LUA_API void lua_pushlightuserdata (lua_State *L, void *p); 168LUA_API void lua_pushlightuserdata (lua_State *L, void *p);
169LUA_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*/
209LUA_API int lua_yield (lua_State *L, int nresults); 211LUA_API int lua_yield (lua_State *L, int nresults);
210LUA_API int lua_resume (lua_State *L, int narg); 212LUA_API int lua_resume (lua_State *L, int narg);
213LUA_API int lua_threadstatus (lua_State *L);
211 214
212/* 215/*
213** garbage-collection function and options 216** garbage-collection function and options
diff --git a/lvm.c b/lvm.c
index 27a5bb34..b8483512 100644
--- a/lvm.c
+++ b/lvm.c
@@ -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 }