commit addbe8c8b0587fd316f33fb013034e035f9217ed
parent 6bb5cb1cbd7a0f0f99242c09ecec7d081cb42000
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Tue, 5 Feb 2002 20:38:15 -0200
protected execution of `resume'
Diffstat:
M | ldo.c | | | 64 | ++++++++++++++++++++++++++++++++++++++-------------------------- |
1 file changed, 38 insertions(+), 26 deletions(-)
diff --git a/ldo.c b/ldo.c
@@ -36,7 +36,6 @@ struct lua_longjmp {
struct lua_longjmp *previous;
CallInfo *ci; /* index of call info of active function that set protection */
StkId top; /* top stack when protection was set */
- TObject *stack; /* active stack for this entry */
int allowhooks; /* `allowhook' state when protection was set */
volatile int status; /* error code */
};
@@ -47,10 +46,8 @@ static void correctstack (lua_State *L, TObject *oldstack) {
CallInfo *ci;
UpVal *up;
L->top = (L->top - oldstack) + L->stack;
- for (lj = L->errorJmp; lj && lj->stack == oldstack; lj = lj->previous) {
+ for (lj = L->errorJmp; lj != NULL; lj = lj->previous)
lj->top = (lj->top - oldstack) + L->stack;
- lj->stack = L->stack;
- }
for (up = L->openupval; up != NULL; up = up->next)
up->v = (up->v - oldstack) + L->stack;
for (ci = L->base_ci; ci <= L->ci; ci++) {
@@ -147,7 +144,7 @@ static void luaD_callHook (lua_State *L, lua_Hook callhook, const char *event) {
static void correctCI (lua_State *L, CallInfo *oldci) {
struct lua_longjmp *lj;
- for (lj = L->errorJmp; lj && lj->stack == L->stack; lj = lj->previous) {
+ for (lj = L->errorJmp; lj != NULL; lj = lj->previous) {
lj->ci = (lj->ci - oldci) + L->base_ci;
}
}
@@ -287,35 +284,51 @@ LUA_API void lua_cobegin (lua_State *L, int nargs) {
}
-static void resume_results (lua_State *L, lua_State *from, int numresults) {
- while (numresults) {
- setobj(L->top, from->top - numresults);
- numresults--;
+static void move_results (lua_State *L, TObject *from, TObject *to) {
+ while (from < to) {
+ setobj(L->top, from);
+ from++;
incr_top(L);
}
}
-LUA_API void lua_resume (lua_State *L, lua_State *co) {
+static void resume (lua_State *L, void *numres) {
StkId firstResult;
- lua_lock(L);
- if (co->ci == co->base_ci) /* no activation record? ?? */
- luaD_error(L, "thread is dead - cannot be resumed");
- lua_assert(co->errorJmp == NULL);
- co->errorJmp = L->errorJmp;
- firstResult = luaV_execute(co);
- if (firstResult != NULL) { /* `return'? */
- resume_results(L, co, co->top - firstResult);
- luaD_poscall(co, 0, firstResult); /* ends this coroutine */
+ CallInfo *ci = L->ci;
+ if (ci->savedpc != ci_func(ci)->l.p->code) { /* not first time? */
+ /* finish interupted execution of `OP_CALL' */
+ int nresults;
+ lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL);
+ nresults = GETARG_C(*((ci-1)->savedpc - 1)) - 1;
+ luaD_poscall(L, nresults, L->top); /* complete it */
+ if (nresults >= 0) L->top = L->ci->top;
}
- else { /* `yield' */
- int nresults = GETARG_C(*((co->ci-1)->savedpc - 1)) - 1;
- resume_results(L, co, co->ci->yield_results);
- luaD_poscall(co, nresults, co->top); /* complete it */
- if (nresults >= 0) co->top = co->ci->top;
+ firstResult = luaV_execute(L);
+ if (firstResult == NULL) /* yield? */
+ *(int *)numres = L->ci->yield_results;
+ else { /* return */
+ *(int *)numres = L->top - firstResult;
+ luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */
}
- co->errorJmp = NULL;
+}
+
+
+LUA_API int lua_resume (lua_State *L, lua_State *co) {
+ CallInfo *ci;
+ int numres;
+ int status;
+ lua_lock(L);
+ ci = co->ci;
+ if (ci == co->base_ci) /* no activation record? ?? */
+ luaD_error(L, "thread is dead - cannot be resumed");
+ if (co->errorJmp != NULL) /* ?? */
+ luaD_error(L, "thread is active - cannot be resumed");
+ status = luaD_runprotected(co, resume, &numres);
+ if (status == 0)
+ move_results(L, co->top - numres, co->top);
lua_unlock(L);
+ return status;
}
@@ -486,7 +499,6 @@ int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) {
struct lua_longjmp lj;
lj.ci = L->ci;
lj.top = L->top;
- lj.stack = L->stack;
lj.allowhooks = L->allowhooks;
lj.status = 0;
lj.previous = L->errorJmp; /* chain new error handler */