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 | } |
