diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-01-11 18:27:41 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-01-11 18:27:41 -0200 |
commit | 6272c843dee7544bf319afbac85e8064fa1f3a4b (patch) | |
tree | b6b36f35516fe87ec3b29fb404a0091472894767 /ldo.c | |
parent | 5d14ce612baf55c4f019842947388b44f8732d34 (diff) | |
download | lua-6272c843dee7544bf319afbac85e8064fa1f3a4b.tar.gz lua-6272c843dee7544bf319afbac85e8064fa1f3a4b.tar.bz2 lua-6272c843dee7544bf319afbac85e8064fa1f3a4b.zip |
`yield' passes its arguments to `resume'
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 46 |
1 files changed, 19 insertions, 27 deletions
@@ -29,9 +29,6 @@ | |||
29 | #include "lzio.h" | 29 | #include "lzio.h" |
30 | 30 | ||
31 | 31 | ||
32 | /* space to handle stack overflow errors */ | ||
33 | #define EXTRA_STACK (2*LUA_MINSTACK) | ||
34 | |||
35 | 32 | ||
36 | static void restore_stack_limit (lua_State *L) { | 33 | static void restore_stack_limit (lua_State *L) { |
37 | StkId limit = L->stack+(L->stacksize-EXTRA_STACK)-1; | 34 | StkId limit = L->stack+(L->stacksize-EXTRA_STACK)-1; |
@@ -40,21 +37,6 @@ static void restore_stack_limit (lua_State *L) { | |||
40 | } | 37 | } |
41 | 38 | ||
42 | 39 | ||
43 | void luaD_init (lua_State *L, int stacksize) { | ||
44 | stacksize += EXTRA_STACK; | ||
45 | L->stack = luaM_newvector(L, stacksize, TObject); | ||
46 | L->stacksize = stacksize; | ||
47 | L->top = L->stack + RESERVED_STACK_PREFIX; | ||
48 | restore_stack_limit(L); | ||
49 | luaM_reallocvector(L, L->base_ci, 0, 20, CallInfo); | ||
50 | L->ci = L->base_ci; | ||
51 | L->ci->base = L->top; | ||
52 | L->ci->savedpc = NULL; | ||
53 | L->size_ci = 20; | ||
54 | L->end_ci = L->base_ci + L->size_ci; | ||
55 | } | ||
56 | |||
57 | |||
58 | void luaD_stackerror (lua_State *L) { | 40 | void luaD_stackerror (lua_State *L) { |
59 | if (L->stack_last == L->stack+L->stacksize-1) { | 41 | if (L->stack_last == L->stack+L->stacksize-1) { |
60 | /* overflow while handling overflow */ | 42 | /* overflow while handling overflow */ |
@@ -231,15 +213,21 @@ void luaD_call (lua_State *L, StkId func, int nResults) { | |||
231 | 213 | ||
232 | 214 | ||
233 | LUA_API void lua_cobegin (lua_State *L, int nargs) { | 215 | LUA_API void lua_cobegin (lua_State *L, int nargs) { |
234 | StkId func; | ||
235 | lua_lock(L); | 216 | lua_lock(L); |
236 | func = L->top - (nargs+1); /* coroutine main function */ | 217 | luaD_precall(L, L->top - (nargs+1)); |
237 | if (luaD_precall(L, func) != NULL) | ||
238 | luaD_error(L, "coroutine started with a C function"); | ||
239 | lua_unlock(L); | 218 | lua_unlock(L); |
240 | } | 219 | } |
241 | 220 | ||
242 | 221 | ||
222 | static void resume_results (lua_State *L, lua_State *from, int numresults) { | ||
223 | while (numresults) { | ||
224 | setobj(L->top, from->top - numresults); | ||
225 | numresults--; | ||
226 | incr_top; | ||
227 | } | ||
228 | } | ||
229 | |||
230 | |||
243 | LUA_API void lua_resume (lua_State *L, lua_State *co) { | 231 | LUA_API void lua_resume (lua_State *L, lua_State *co) { |
244 | StkId firstResult; | 232 | StkId firstResult; |
245 | lua_lock(L); | 233 | lua_lock(L); |
@@ -248,10 +236,13 @@ LUA_API void lua_resume (lua_State *L, lua_State *co) { | |||
248 | lua_assert(co->errorJmp == NULL); | 236 | lua_assert(co->errorJmp == NULL); |
249 | co->errorJmp = L->errorJmp; | 237 | co->errorJmp = L->errorJmp; |
250 | firstResult = luaV_execute(co); | 238 | firstResult = luaV_execute(co); |
251 | if (firstResult != NULL) /* `return'? */ | 239 | if (firstResult != NULL) { /* `return'? */ |
252 | luaD_poscall(co, LUA_MULTRET, firstResult); /* ends this coroutine */ | 240 | resume_results(L, co, co->top - firstResult); |
241 | luaD_poscall(co, 0, firstResult); /* ends this coroutine */ | ||
242 | } | ||
253 | else { /* `yield' */ | 243 | else { /* `yield' */ |
254 | int nresults = GETARG_C(*((co->ci-1)->savedpc - 1)) - 1; | 244 | int nresults = GETARG_C(*((co->ci-1)->savedpc - 1)) - 1; |
245 | resume_results(L, co, co->ci->yield_results); | ||
255 | luaD_poscall(co, nresults, co->top); /* complete it */ | 246 | luaD_poscall(co, nresults, co->top); /* complete it */ |
256 | if (nresults >= 0) co->top = co->ci->top; | 247 | if (nresults >= 0) co->top = co->ci->top; |
257 | } | 248 | } |
@@ -264,10 +255,11 @@ LUA_API int lua_yield (lua_State *L, int nresults) { | |||
264 | CallInfo *ci; | 255 | CallInfo *ci; |
265 | int ibase; | 256 | int ibase; |
266 | lua_lock(L); | 257 | lua_lock(L); |
267 | ci = L->ci - 1; /* call info of calling function */ | 258 | ci = L->ci; |
268 | if (ci->pc == NULL) | 259 | if (ci_func(ci-1)->c.isC) |
269 | luaD_error(L, "cannot `yield' a C function"); | 260 | luaD_error(L, "cannot `yield' a C function"); |
270 | ibase = L->top - ci->base; | 261 | ci->yield_results = nresults; /* very dirty trick! */ |
262 | ibase = L->top - (ci-1)->base; | ||
271 | lua_unlock(L); | 263 | lua_unlock(L); |
272 | return ibase; | 264 | return ibase; |
273 | } | 265 | } |