aboutsummaryrefslogtreecommitdiff
path: root/lbaselib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-06-10 18:30:26 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-06-10 18:30:26 -0300
commitbd262d591f56a4c14be58c14c54aa929d0d3bf64 (patch)
tree753b3b57a04c2bdd2fcae53447e6b54bcb2ae23e /lbaselib.c
parent0d116c3adab7bf831ecb8adec0cedfe9a807476e (diff)
downloadlua-bd262d591f56a4c14be58c14c54aa929d0d3bf64.tar.gz
lua-bd262d591f56a4c14be58c14c54aa929d0d3bf64.tar.bz2
lua-bd262d591f56a4c14be58c14c54aa929d0d3bf64.zip
'coroutine' library separated from 'baselib'
Diffstat (limited to 'lbaselib.c')
-rw-r--r--lbaselib.c149
1 files changed, 3 insertions, 146 deletions
diff --git a/lbaselib.c b/lbaselib.c
index d9669dfc..d28708af 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbaselib.c,v 1.242 2010/04/19 16:36:06 roberto Exp roberto $ 2** $Id: lbaselib.c,v 1.243 2010/04/19 17:02:02 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*/
@@ -500,144 +500,7 @@ static const luaL_Reg base_funcs[] = {
500}; 500};
501 501
502 502
503/* 503LUAMOD_API int luaopen_base (lua_State *L) {
504** {======================================================
505** Coroutine library
506** =======================================================
507*/
508
509static int auxresume (lua_State *L, lua_State *co, int narg) {
510 int status;
511 if (!lua_checkstack(co, narg)) {
512 lua_pushliteral(L, "too many arguments to resume");
513 return -1; /* error flag */
514 }
515 if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) {
516 lua_pushliteral(L, "cannot resume dead coroutine");
517 return -1; /* error flag */
518 }
519 lua_xmove(L, co, narg);
520 status = lua_resume(co, narg);
521 if (status == LUA_OK || status == LUA_YIELD) {
522 int nres = lua_gettop(co);
523 if (!lua_checkstack(L, nres + 1)) {
524 lua_pop(co, nres); /* remove results anyway */
525 lua_pushliteral(L, "too many results to resume");
526 return -1; /* error flag */
527 }
528 lua_xmove(co, L, nres); /* move yielded values */
529 return nres;
530 }
531 else {
532 lua_xmove(co, L, 1); /* move error message */
533 return -1; /* error flag */
534 }
535}
536
537
538static int luaB_coresume (lua_State *L) {
539 lua_State *co = lua_tothread(L, 1);
540 int r;
541 luaL_argcheck(L, co, 1, "coroutine expected");
542 r = auxresume(L, co, lua_gettop(L) - 1);
543 if (r < 0) {
544 lua_pushboolean(L, 0);
545 lua_insert(L, -2);
546 return 2; /* return false + error message */
547 }
548 else {
549 lua_pushboolean(L, 1);
550 lua_insert(L, -(r + 1));
551 return r + 1; /* return true + `resume' returns */
552 }
553}
554
555
556static int luaB_auxwrap (lua_State *L) {
557 lua_State *co = lua_tothread(L, lua_upvalueindex(1));
558 int r = auxresume(L, co, lua_gettop(L));
559 if (r < 0) {
560 if (lua_isstring(L, -1)) { /* error object is a string? */
561 luaL_where(L, 1); /* add extra info */
562 lua_insert(L, -2);
563 lua_concat(L, 2);
564 }
565 lua_error(L); /* propagate error */
566 }
567 return r;
568}
569
570
571static int luaB_cocreate (lua_State *L) {
572 lua_State *NL = lua_newthread(L);
573 luaL_checktype(L, 1, LUA_TFUNCTION);
574 lua_pushvalue(L, 1); /* move function to top */
575 lua_xmove(L, NL, 1); /* move function from L to NL */
576 return 1;
577}
578
579
580static int luaB_cowrap (lua_State *L) {
581 luaB_cocreate(L);
582 lua_pushcclosure(L, luaB_auxwrap, 1);
583 return 1;
584}
585
586
587static int luaB_yield (lua_State *L) {
588 return lua_yield(L, lua_gettop(L));
589}
590
591
592static int luaB_costatus (lua_State *L) {
593 lua_State *co = lua_tothread(L, 1);
594 luaL_argcheck(L, co, 1, "coroutine expected");
595 if (L == co) lua_pushliteral(L, "running");
596 else {
597 switch (lua_status(co)) {
598 case LUA_YIELD:
599 lua_pushliteral(L, "suspended");
600 break;
601 case LUA_OK: {
602 lua_Debug ar;
603 if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */
604 lua_pushliteral(L, "normal"); /* it is running */
605 else if (lua_gettop(co) == 0)
606 lua_pushliteral(L, "dead");
607 else
608 lua_pushliteral(L, "suspended"); /* initial state */
609 break;
610 }
611 default: /* some error occurred */
612 lua_pushliteral(L, "dead");
613 break;
614 }
615 }
616 return 1;
617}
618
619
620static int luaB_corunning (lua_State *L) {
621 int ismain = lua_pushthread(L);
622 lua_pushboolean(L, ismain);
623 return 2;
624}
625
626
627static const luaL_Reg co_funcs[] = {
628 {"create", luaB_cocreate},
629 {"resume", luaB_coresume},
630 {"running", luaB_corunning},
631 {"status", luaB_costatus},
632 {"wrap", luaB_cowrap},
633 {"yield", luaB_yield},
634 {NULL, NULL}
635};
636
637/* }====================================================== */
638
639
640static void base_open (lua_State *L) {
641 /* set global _G */ 504 /* set global _G */
642 lua_pushglobaltable(L); 505 lua_pushglobaltable(L);
643 lua_pushglobaltable(L); 506 lua_pushglobaltable(L);
@@ -654,12 +517,6 @@ static void base_open (lua_State *L) {
654 lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ 517 lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */
655 lua_pushcclosure(L, luaB_newproxy, 1); 518 lua_pushcclosure(L, luaB_newproxy, 1);
656 lua_setfield(L, -2, "newproxy"); /* set global `newproxy' */ 519 lua_setfield(L, -2, "newproxy"); /* set global `newproxy' */
657} 520 return 1;
658
659
660LUAMOD_API int luaopen_base (lua_State *L) {
661 base_open(L);
662 luaL_register(L, LUA_COLIBNAME, co_funcs);
663 return 2;
664} 521}
665 522