?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

  1. /*
  2. ** $Id: lcorolib.c,v 1.5.1.1 2013/04/12 18:48:47 roberto Exp $
  3. ** Coroutine Library
  4. ** See Copyright Notice in lua.h
  5. */
  6.  
  7.  
  8. #include <stdlib.h>
  9.  
  10.  
  11. #define lcorolib_c
  12. #define LUA_LIB
  13.  
  14. #include "lua.h"
  15.  
  16. #include "lauxlib.h"
  17. #include "lualib.h"
  18.  
  19.  
  20. static int auxresume (lua_State *L, lua_State *co, int narg) {
  21.   int status;
  22.   if (!lua_checkstack(co, narg)) {
  23.     lua_pushliteral(L, "too many arguments to resume");
  24.     return -1;  /* error flag */
  25.   }
  26.   if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) {
  27.     lua_pushliteral(L, "cannot resume dead coroutine");
  28.     return -1;  /* error flag */
  29.   }
  30.   lua_xmove(L, co, narg);
  31.   status = lua_resume(co, L, narg);
  32.   if (status == LUA_OK || status == LUA_YIELD) {
  33.     int nres = lua_gettop(co);
  34.     if (!lua_checkstack(L, nres + 1)) {
  35.       lua_pop(co, nres);  /* remove results anyway */
  36.       lua_pushliteral(L, "too many results to resume");
  37.       return -1;  /* error flag */
  38.     }
  39.     lua_xmove(co, L, nres);  /* move yielded values */
  40.     return nres;
  41.   }
  42.   else {
  43.     lua_xmove(co, L, 1);  /* move error message */
  44.     return -1;  /* error flag */
  45.   }
  46. }
  47.  
  48.  
  49. static int luaB_coresume (lua_State *L) {
  50.   lua_State *co = lua_tothread(L, 1);
  51.   int r;
  52.   luaL_argcheck(L, co, 1, "coroutine expected");
  53.   r = auxresume(L, co, lua_gettop(L) - 1);
  54.   if (r < 0) {
  55.     lua_pushboolean(L, 0);
  56.     lua_insert(L, -2);
  57.     return 2;  /* return false + error message */
  58.   }
  59.   else {
  60.     lua_pushboolean(L, 1);
  61.     lua_insert(L, -(r + 1));
  62.     return r + 1;  /* return true + `resume' returns */
  63.   }
  64. }
  65.  
  66.  
  67. static int luaB_auxwrap (lua_State *L) {
  68.   lua_State *co = lua_tothread(L, lua_upvalueindex(1));
  69.   int r = auxresume(L, co, lua_gettop(L));
  70.   if (r < 0) {
  71.     if (lua_isstring(L, -1)) {  /* error object is a string? */
  72.       luaL_where(L, 1);  /* add extra info */
  73.       lua_insert(L, -2);
  74.       lua_concat(L, 2);
  75.     }
  76.     return lua_error(L);  /* propagate error */
  77.   }
  78.   return r;
  79. }
  80.  
  81.  
  82. static int luaB_cocreate (lua_State *L) {
  83.   lua_State *NL;
  84.   luaL_checktype(L, 1, LUA_TFUNCTION);
  85.   NL = lua_newthread(L);
  86.   lua_pushvalue(L, 1);  /* move function to top */
  87.   lua_xmove(L, NL, 1);  /* move function from L to NL */
  88.   return 1;
  89. }
  90.  
  91.  
  92. static int luaB_cowrap (lua_State *L) {
  93.   luaB_cocreate(L);
  94.   lua_pushcclosure(L, luaB_auxwrap, 1);
  95.   return 1;
  96. }
  97.  
  98.  
  99. static int luaB_yield (lua_State *L) {
  100.   return lua_yield(L, lua_gettop(L));
  101. }
  102.  
  103.  
  104. static int luaB_costatus (lua_State *L) {
  105.   lua_State *co = lua_tothread(L, 1);
  106.   luaL_argcheck(L, co, 1, "coroutine expected");
  107.   if (L == co) lua_pushliteral(L, "running");
  108.   else {
  109.     switch (lua_status(co)) {
  110.       case LUA_YIELD:
  111.         lua_pushliteral(L, "suspended");
  112.         break;
  113.       case LUA_OK: {
  114.         lua_Debug ar;
  115.         if (lua_getstack(co, 0, &ar) > 0)  /* does it have frames? */
  116.           lua_pushliteral(L, "normal");  /* it is running */
  117.         else if (lua_gettop(co) == 0)
  118.             lua_pushliteral(L, "dead");
  119.         else
  120.           lua_pushliteral(L, "suspended");  /* initial state */
  121.         break;
  122.       }
  123.       default:  /* some error occurred */
  124.         lua_pushliteral(L, "dead");
  125.         break;
  126.     }
  127.   }
  128.   return 1;
  129. }
  130.  
  131.  
  132. static int luaB_corunning (lua_State *L) {
  133.   int ismain = lua_pushthread(L);
  134.   lua_pushboolean(L, ismain);
  135.   return 2;
  136. }
  137.  
  138.  
  139. static const luaL_Reg co_funcs[] = {
  140.   {"create", luaB_cocreate},
  141.   {"resume", luaB_coresume},
  142.   {"running", luaB_corunning},
  143.   {"status", luaB_costatus},
  144.   {"wrap", luaB_cowrap},
  145.   {"yield", luaB_yield},
  146.   {NULL, NULL}
  147. };
  148.  
  149.  
  150.  
  151. LUAMOD_API int luaopen_coroutine (lua_State *L) {
  152.   luaL_newlib(L, co_funcs);
  153.   return 1;
  154. }
  155.  
  156.