/* Persist all stack members */ static void persistthread(PersistInfo *pi) { size_t posremaining; lua_State *L2; /* perms reftbl ... thr */ L2 = lua_tothread(pi->L, -1); lua_checkstack(pi->L, L2->top - L2->stack + 1); if(pi->L == L2) { lua_pushstring(pi->L, "Can't persist currently running thread"); lua_error(pi->L); return; /* not reached */ } /* Persist the stack */ posremaining = revappendstack(L2, pi->L); /* perms reftbl ... thr (rev'ed contents of L2) */ pi->writer(pi->L, &posremaining, sizeof(size_t), pi->ud); for(; posremaining > 0; posremaining--) { persist(pi); lua_pop(pi->L, 1); } /* perms reftbl ... thr */ /* Now, persist the CallInfo stack. */ { size_t i, numframes = (L2->ci - L2->base_ci) + 1; pi->writer(pi->L, &numframes, sizeof(size_t), pi->ud); for(i=0; i<numframes; i++) { CallInfo *ci = L2->base_ci + i; size_t stackbase = ci->base - L2->stack; size_t stackfunc = ci->func - L2->stack; size_t stacktop = ci->top - L2->stack; size_t savedpc = (ci != L2->base_ci) ? ci->savedpc - ci_func(ci)->l.p->code : 0; pi->writer(pi->L, &stackbase, sizeof(size_t), pi->ud); pi->writer(pi->L, &stackfunc, sizeof(size_t), pi->ud); pi->writer(pi->L, &stacktop, sizeof(size_t), pi->ud); pi->writer(pi->L, &ci->nresults, sizeof(int), pi->ud); pi->writer(pi->L, &savedpc, sizeof(size_t), pi->ud); } } /* Serialize the state's other parameters, with the exception of upval stuff */ { size_t stackbase = L2->base - L2->stack; size_t stacktop = L2->top - L2->stack; lua_assert(L2->nCcalls <= 1); pi->writer(pi->L, &L2->status, sizeof(lu_byte), pi->ud); pi->writer(pi->L, &stackbase, sizeof(size_t), pi->ud); pi->writer(pi->L, &stacktop, sizeof(size_t), pi->ud); pi->writer(pi->L, &L2->errfunc, sizeof(ptrdiff_t), pi->ud); } /* Finally, record upvalues which need to be reopened */ /* See the comment above persistupval() for why we do this */ { GCObject *gco; UpVal *uv; /* perms reftbl ... thr */ for(gco = L2->openupval; gco != NULL; gco = uv->next) { size_t stackpos; uv = gco2uv(gco); /* Make sure upvalue is really open */ lua_assert(uv->v != &uv->u.value); pushupval(pi->L, uv); /* perms reftbl ... thr uv */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... thr */ stackpos = uv->v - L2->stack; pi->writer(pi->L, &stackpos, sizeof(size_t), pi->ud); } /* perms reftbl ... thr */ lua_pushnil(pi->L); /* perms reftbl ... thr nil */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... thr */ } /* perms reftbl ... thr */ }
/* Persist all stack members */ static void persistthread(PersistInfo *pi) { int posremaining; lua_State *L2; /* perms reftbl ... thr */ L2 = lua_tothread(pi->L, -1); if(pi->L == L2) { lua_pushstring(pi->L, "Can't persist currently running thread"); lua_error(pi->L); return; /* not reached */ } posremaining = revappendstack(L2, pi->L); /* perms reftbl ... thr (rev'ed contents of L2) */ pi->writer(pi->L, &posremaining, sizeof(int), pi->ud); for(; posremaining > 0; posremaining--) { persist(pi); lua_pop(pi->L, 1); } /* perms reftbl ... thr */ /* Now, persist the CallInfo stack. */ { int i, numframes = (L2->ci - L2->base_ci) + 1; pi->writer(pi->L, &numframes, sizeof(int), pi->ud); for(i=0; i<numframes; i++) { CallInfo *ci = L2->base_ci + i; int stackbase = ci->base - L2->stack; int stacktop = ci->top - L2->stack; int pc = (ci != L2->base_ci) ? ci->u.l.savedpc - ci_func(ci)->l.p->code : 0; pi->writer(pi->L, &stackbase, sizeof(int), pi->ud); pi->writer(pi->L, &stacktop, sizeof(int), pi->ud); pi->writer(pi->L, &pc, sizeof(int), pi->ud); pi->writer(pi->L, &(ci->state), sizeof(int), pi->ud); } } /* Serialize the state's top and base */ { int stackbase = L2->base - L2->stack; int stacktop = L2->top - L2->stack; pi->writer(pi->L, &stackbase, sizeof(int), pi->ud); pi->writer(pi->L, &stacktop, sizeof(int), pi->ud); } /* Finally, record upvalues which need to be reopened */ /* See the comment above persistupval() for why we do this */ { UpVal *uv; /* perms reftbl ... thr */ for(uv = gcotouv(L2->openupval); uv != NULL; uv = gcotouv(uv->next)) { int stackpos; /* Make sure upvalue is really open */ lua_assert(uv->v != &uv->value); pushupval(pi->L, uv); /* perms reftbl ... thr uv */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... thr */ stackpos = uv->v - L2->stack; pi->writer(pi->L, &stackpos, sizeof(int), pi->ud); } /* perms reftbl ... thr */ lua_pushnil(pi->L); /* perms reftbl ... thr nil */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... thr */ } /* perms reftbl ... thr */ }