static void next() { lua_Object o = luaL_tablearg(1); lua_Object r = luaL_nonnullarg(2); Node *n = luaH_next(luaA_Address(o), luaA_Address(r)); if (n) { luaA_pushobject(&n->ref); luaA_pushobject(&n->val); } }
int luaA_next (Hash *t, int i) { int tsize = nhash(t); for (; i<tsize; i++) { Node *n = node(t, i); if (ttype(val(n)) != LUA_T_NIL) { luaA_pushobject(ref(n)); luaA_pushobject(val(n)); return i+1; /* index to be used next time */ } } return 0; /* no more elements */ }
static void pushstring (TaggedString *s) { TObject o; o.ttype = LUA_T_STRING; o.value.ts = s; luaA_pushobject(&o); }
void luaT_setfallback() { static const char *oldnames [] = { "error", "getglobal", "arith", "order", NULL }; TObject oldfunc; lua_CFunction replace; if (!tmFBAdded) { luaL_addlibtolist(tmFB, (sizeof(tmFB) / sizeof(tmFB[0]))); tmFBAdded = true; } const char *name = luaL_check_string(1); lua_Object func = lua_getparam(2); luaL_arg_check(lua_isfunction(func), 2, "function expected"); switch (luaO_findstring(name, oldnames)) { case 0: // old error fallback oldfunc = errorim; errorim = *luaA_Address(func); replace = errorFB; break; case 1: // old getglobal fallback oldfunc = *luaT_getim(LUA_T_NIL, IM_GETGLOBAL); *luaT_getim(LUA_T_NIL, IM_GETGLOBAL) = *luaA_Address(func); replace = nilFB; break; case 2: { // old arith fallback int32 i; oldfunc = *luaT_getim(LUA_T_NUMBER, IM_POW); for (i = IM_ADD; i <= IM_UNM; i++) // ORDER IM fillvalids(i, luaA_Address(func)); replace = typeFB; break; } case 3: { // old order fallback int32 i; oldfunc = *luaT_getim(LUA_T_NIL, IM_LT); for (i = IM_LT; i <= IM_GE; i++) // ORDER IM fillvalids(i, luaA_Address(func)); replace = typeFB; break; } default: { int32 e; if ((e = luaO_findstring(name, luaT_eventname)) >= 0) { oldfunc = *luaT_getim(LUA_T_NIL, e); fillvalids(e, luaA_Address(func)); replace = (e == IM_GC || e == IM_INDEX) ? nilFB : typeFB; } else { luaL_verror("`%.50s' is not a valid fallback name", name); replace = NULL; // to avoid warnings oldfunc.ttype = LUA_T_NIL; // to avoid warnings } } } if (oldfunc.ttype != LUA_T_NIL) luaA_pushobject(&oldfunc); else lua_pushcfunction(replace); }
static void foreach (void) { TObject t = *luaA_Address(luaL_tablearg(1)); TObject f = *luaA_Address(luaL_functionarg(2)); int32 i; for (i=0; i<avalue(&t)->nhash; i++) { Node *nd = &(avalue(&t)->node[i]); if (ttype(ref(nd)) != LUA_T_NIL && ttype(val(nd)) != LUA_T_NIL) { luaA_pushobject(&f); luaA_pushobject(ref(nd)); luaA_pushobject(val(nd)); luaD_call((L->stack.top-L->stack.stack)-2, 1); if (ttype(L->stack.top-1) != LUA_T_NIL) return; L->stack.top--; } } }
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { CallInfo *ci = L->base_ci + ar->i_ci; const char *name = findlocal(L, ci, n); lua_lock(L); if (name) luaA_pushobject(L, ci->base + (n - 1)); lua_unlock(L); return name; }
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { const char *name; StkId f = ar->_func; Proto *fp = getluaproto(f); if (!fp) return NULL; /* `f' is not a Lua function? */ name = luaF_getlocalname(fp, n, currentpc(f)); if (!name) return NULL; luaA_pushobject(L, (f+1)+(n-1)); /* push value */ return name; }
/* Upvalues are tricky. Here's why. * * A particular upvalue may be either "open", in which case its member v * points into a thread's stack, or "closed" in which case it points to the * upvalue itself. An upvalue is closed under any of the following conditions: * -- The function that initially declared the variable "local" returns * -- The thread in which the closure was created is garbage collected * * To make things wackier, just because a thread is reachable by Lua doesn't * mean it's in our root set. We need to be able to treat an open upvalue * from an unreachable thread as a closed upvalue. * * The solution: * (a) For the purposes of persisting, don't indicate whether an upvalue is * closed or not. * (b) When unpersisting, pretend that all upvalues are closed. * (c) When persisting, persist all open upvalues referenced by a thread * that is persisted, and tag each one with the corresponding stack position * (d) When unpersisting, "reopen" each of these upvalues as the thread is * unpersisted */ static void persistupval(PersistInfo *pi) { /* perms reftbl ... upval */ UpVal *uv = toupval(pi->L, -1); luaA_pushobject(pi->L, uv->v); /* perms reftbl ... upval obj */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... upval */ }
static void luaB_tremove (void) { Hash *a = gethash(1); int n = (int)getnarg(a); int pos = luaL_opt_int(2, n); if (n <= 0) return; /* table is "empty" */ luaA_pushobject(luaH_getint(a, pos)); /* result = a[pos] */ for ( ;pos<n; pos++) luaH_move(a, pos+1, pos); /* a[pos] = a[pos+1] */ luaV_setn(a, n-1); /* a.n = n-1 */ luaH_setint(a, n, &luaO_nilobject); /* a[n] = nil */ }
int luaR_findfunction(lua_State *L, const luaR_entry *ptable) { const TValue *res = NULL; const char *key = luaL_checkstring(L, 2); res = luaR_auxfind(ptable, key, 0, NULL); if (res && ttislightfunction(res)) { luaA_pushobject(L, res); return 1; } else return 0; }
void luaT_setfallback (void) { static char *oldnames [] = {"error", "getglobal", "arith", "order", NULL}; TObject oldfunc; lua_CFunction replace; char *name = luaL_check_string(1); lua_Object func = lua_getparam(2); luaL_arg_check(lua_isfunction(func), 2, "function expected"); switch (luaL_findstring(name, oldnames)) { case 0: /* old error fallback */ oldfunc = L->errorim; L->errorim = *luaA_Address(func); replace = errorFB; break; case 1: /* old getglobal fallback */ oldfunc = *luaT_getim(LUA_T_NIL, IM_GETGLOBAL); *luaT_getim(LUA_T_NIL, IM_GETGLOBAL) = *luaA_Address(func); replace = nilFB; break; case 2: { /* old arith fallback */ int i; oldfunc = *luaT_getim(LUA_T_NUMBER, IM_POW); for (i=IM_ADD; i<=IM_UNM; i++) /* ORDER IM */ fillvalids(i, luaA_Address(func)); replace = typeFB; break; } case 3: { /* old order fallback */ int i; oldfunc = *luaT_getim(LUA_T_NIL, IM_LT); for (i=IM_LT; i<=IM_GE; i++) /* ORDER IM */ fillvalids(i, luaA_Address(func)); replace = typeFB; break; } default: { int e; if ((e = luaL_findstring(name, luaT_eventname)) >= 0) { oldfunc = *luaT_getim(LUA_T_NIL, e); fillvalids(e, luaA_Address(func)); replace = (e == IM_GC || e == IM_INDEX) ? nilFB : typeFB; } else { luaL_verror("`%.50s' is not a valid fallback name", name); replace = NULL; /* to avoid warnings */ } } } if (oldfunc.ttype != LUA_T_NIL) luaA_pushobject(&oldfunc); else lua_pushcfunction(replace); }
static void foreachvar (void) { TObject f = *luaA_Address(luaL_functionarg(1)); GCnode *g; StkId name = L->Cstack.base++; /* place to keep var name (to avoid GC) */ ttype(L->stack.stack+name) = LUA_T_NIL; L->stack.top++; for (g = L->rootglobal.next; g; g = g->next) { TaggedString *s = (TaggedString *)g; if (s->u.s.globalval.ttype != LUA_T_NIL) { ttype(L->stack.stack+name) = LUA_T_STRING; tsvalue(L->stack.stack+name) = s; /* keep s on stack to avoid GC */ luaA_pushobject(&f); pushstring(s); luaA_pushobject(&s->u.s.globalval); luaD_call((L->stack.top-L->stack.stack)-2, 1); if (ttype(L->stack.top-1) != LUA_T_NIL) return; L->stack.top--; } } }
static void foreachvar() { TObject f = *luaA_Address(luaL_functionarg(1)); GCnode *g; StkId name = lua_state->Cstack.base++; // place to keep var name (to avoid GC) ttype(lua_state->stack.stack + name) = LUA_T_NIL; lua_state->stack.top++; for (g = rootglobal.next; g; g = g->next) { TaggedString *s = (TaggedString *)g; if (s->globalval.ttype != LUA_T_NIL) { ttype(lua_state->stack.stack + name) = LUA_T_STRING; tsvalue(lua_state->stack.stack + name) = s; // keep s on stack to avoid GC luaA_pushobject(&f); pushstring(s); luaA_pushobject(&s->globalval); lua_state->state_counter1++; luaD_call((lua_state->stack.top - lua_state->stack.stack) - 2, 1); lua_state->state_counter1--; if (ttype(lua_state->stack.top - 1) != LUA_T_NIL) return; lua_state->stack.top--; } } }
static void luaI_print (void) { TaggedString *ts = luaS_new("tostring"); lua_Object obj; int32 i = 1; while ((obj = lua_getparam(i++)) != LUA_NOOBJECT) { luaA_pushobject(&ts->u.s.globalval); lua_pushobject(obj); luaD_call((L->stack.top-L->stack.stack)-1, 1); if (ttype(L->stack.top-1) != LUA_T_STRING) lua_error("`tostring' must return a string to `print'"); printf("%s\t", svalue(L->stack.top-1)); L->stack.top--; } printf("\n"); }
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { const char *name; CallInfo *ci; Proto *fp; lua_lock(L); name = NULL; ci = L->base_ci + ar->i_ci; fp = getluaproto(ci); if (fp) { /* is a Lua function? */ name = luaF_getlocalname(fp, n, currentpc(ci)); if (name) luaA_pushobject(L, ci->base+(n-1)); /* push value */ } lua_unlock(L); return name; }
TaggedString *luaA_nextvar (TaggedString *g) { if (g == NULL) g = (TaggedString *)L->rootglobal.next; /* first variable */ else { /* check whether name is in global var list */ luaL_arg_check((GCnode *)g != g->head.next, 1, "variable name expected"); g = (TaggedString *)g->head.next; /* get next */ } while (g && g->u.s.globalval.ttype == LUA_T_NIL) /* skip globals with nil */ g = (TaggedString *)g->head.next; if (g) { ttype(L->stack.top) = LUA_T_STRING; tsvalue(L->stack.top) = g; incr_top; luaA_pushobject(&g->u.s.globalval); } return g; }
static void persistproto(PersistInfo *pi) { /* perms reftbl ... proto */ Proto *p = toproto(pi->L, -1); /* Persist constant refs */ { int i; pi->writer(pi->L, &p->sizek, sizeof(int), pi->ud); for(i=0; i<p->sizek; i++) { luaA_pushobject(pi->L, &p->k[i]); /* perms reftbl ... proto const */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... proto */ } } /* perms reftbl ... proto */ /* serialize inner Proto refs */ { int i; pi->writer(pi->L, &p->sizep, sizeof(int), pi->ud); for(i=0; i<p->sizep; i++) { pushproto(pi->L, p->p[i]); /* perms reftbl ... proto subproto */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... proto */ } } /* perms reftbl ... proto */ /* Serialize code */ { pi->writer(pi->L, &p->sizecode, sizeof(int), pi->ud); pi->writer(pi->L, p->code, sizeof(Instruction) * p->sizecode, pi->ud); } /* Serialize misc values */ { pi->writer(pi->L, &p->nups, sizeof(lu_byte), pi->ud); pi->writer(pi->L, &p->numparams, sizeof(lu_byte), pi->ud); pi->writer(pi->L, &p->is_vararg, sizeof(lu_byte), pi->ud); pi->writer(pi->L, &p->maxstacksize, sizeof(lu_byte), pi->ud); } /* We do not currently persist upvalue names, local variable names, * variable lifetimes, line info, or source code. */ }
void identify_script() { lua_Object paramObj = lua_getparam(1); lua_Type type = ttype(Address(paramObj)); if (paramObj == LUA_NOOBJECT || type != LUA_T_TASK) lua_error("Bad argument to identify_script"); uint32 task = (uint32)nvalue(Address(paramObj)); LState *state; for (state = lua_rootState->next; state != NULL; state = state->next) { if (state->id == task) { luaA_pushobject(&state->taskFunc); return; } } lua_pushnil(); }
void start_script() { lua_Object paramObj = lua_getparam(1); lua_Type type = ttype(Address(paramObj)); if (paramObj == LUA_NOOBJECT || (type != LUA_T_CPROTO && type != LUA_T_PROTO)) { warning("lua: Bad argument to start_script. - lua/ltask.cpp:32"); // NOTE: Decomment the lua_error if you want to see the stacktrace. // It is commented out because si.lua, in the function si.set_up_actors (line 848), // calls "start_script(si.naranja_drinking)", which doesn't exist. The problem with // that is that lua_error ends the function that was going on, breaking // si.set really badly. // lua_error("Bad argument to start_script"); return; } LState *state = luaM_new(LState); lua_stateinit(state); state->next = lua_state->next; state->prev = lua_state; if (state->next) state->next->prev = state; lua_state->next = state; state->taskFunc.ttype = type; state->taskFunc.value = Address(paramObj)->value; int l = 2; for (lua_Object object = lua_getparam(l++); object != LUA_NOOBJECT; object = lua_getparam(l++)) { TObject ptr; ptr.ttype = Address(object)->ttype; ptr.value = Address(object)->value; LState *tmpState = lua_state; lua_state = state; luaA_pushobject(&ptr); lua_state = tmpState; } ttype(lua_state->stack.top) = LUA_T_TASK; nvalue(lua_state->stack.top) = (float)state->id; incr_top; }
static void nextvar() { TObject *o = luaA_Address(luaL_nonnullarg(1)); TaggedString *g; if (ttype(o) == LUA_T_NIL) g = (TaggedString *)rootglobal.next; else { luaL_arg_check(ttype(o) == LUA_T_STRING, 1, "variable name expected"); g = tsvalue(o); // check whether name is in global var list luaL_arg_check((GCnode *)g != g->head.next, 1, "variable name expected"); g = (TaggedString *)g->head.next; } while (g && g->globalval.ttype == LUA_T_NIL) { // skip globals with nil g = (TaggedString *)g->head.next; } if (g) { pushstring(g); luaA_pushobject(&g->globalval); } }
void start_script() { lua_Object paramObj = lua_getparam(1); lua_Type type = paramObj == LUA_NOOBJECT ? LUA_T_NIL : ttype(Address(paramObj)); if (paramObj == LUA_NOOBJECT || (type != LUA_T_CPROTO && type != LUA_T_PROTO)) { lua_error("Bad argument to start_script"); return; } LState *state = luaM_new(LState); lua_stateinit(state); state->next = lua_state->next; state->prev = lua_state; if (state->next) state->next->prev = state; lua_state->next = state; state->taskFunc.ttype = type; state->taskFunc.value = Address(paramObj)->value; int l = 2; for (lua_Object object = lua_getparam(l++); object != LUA_NOOBJECT; object = lua_getparam(l++)) { TObject ptr; ptr.ttype = Address(object)->ttype; ptr.value = Address(object)->value; LState *tmpState = lua_state; lua_state = state; luaA_pushobject(&ptr); lua_state = tmpState; } ttype(lua_state->stack.top) = LUA_T_TASK; nvalue(lua_state->stack.top) = (float)state->id; incr_top; }
static void pushproto(lua_State *L, Proto *proto) { TObject o; o.tt = LUA_TPROTO; o.value.gc = valtogco(proto); luaA_pushobject(L, &o); }
static void pushclosure(lua_State *L, Closure *closure) { TObject o; o.tt = LUA_TFUNCTION; o.value.gc = valtogco(closure); luaA_pushobject(L, &o); }
static void pushupval(lua_State *L, UpVal *upval) { TObject o; o.tt = LUA_TUPVAL; o.value.gc = valtogco(upval); luaA_pushobject(L, &o); }