~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/lua/src/lcorolib.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
** $Id: lcorolib.c,v 1.5 2013/02/21 13:44:53 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