static int addk(FuncState *fs, Tvalue *key, Tvalue *v) { Tvalue *idx = ktapc_table_set(fs->h, key); Proto *f = fs->f; int k, oldsize; if (ttisnumber(idx)) { ktap_Number n = nvalue(idx); ktap_number2int(k, n); if (ktapc_equalobj(&f->k[k], v)) return k; /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0"); go through and create a new entry for this value */ } /* constant not found; create a new entry */ oldsize = f->sizek; k = fs->nk; /* numerical value does not need GC barrier; table has no metatable, so it does not need to invalidate cache */ setnvalue(idx, (ktap_Number)(k)); ktapc_growvector(f->k, k, f->sizek, Tvalue, MAXARG_Ax, "constants"); while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); setobj(NULL, &f->k[k], v); fs->nk++; return k; }
static int addk (FuncState *fs, TValue *key, TValue *v) { lua_State *L = fs->ls->L; TValue *idx = luaH_set(L, fs->h, key); Proto *f = fs->f; int k, oldsize; if (ttisnumber(idx)) { lua_Number n = nvalue(idx); lua_number2int(k, n); if (luaV_rawequalobj(&f->k[k], v)) return k; /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0"); go through and create a new entry for this value */ } /* constant not found; create a new entry */ oldsize = f->sizek; k = fs->nk; /* numerical value does not need GC barrier; table has no metatable, so it does not need to invalidate cache */ setnvalue(idx, cast_num(k)); luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); setobj(L, &f->k[k], v); fs->nk++; luaC_barrier(L, f, v); return k; }
static int addk (FuncState *fs, TValue *k, TValue *v) { lua_State *L = fs->L; TValue *idx = luaH_set(L, fs->h, k); Proto *f = fs->f; int oldsize = f->sizek; if (ttisnumber(idx)) { lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); return cast_int(nvalue(idx)); } else { /* constant not found; create a new entry */ setnvalue(idx, cast_num(fs->nk)); #if LUA_MEMORY_STATS luaM_setname(L, "lua.parser.constants"); #endif /* LUA_MEMORY_STATS */ luaM_growvector(L, f->k, fs->nk, f->sizek, TValue, MAXARG_Bx, "constant table overflow"); #if LUA_MEMORY_STATS luaM_setname(L, 0); #endif /* LUA_MEMORY_STATS */ #if LUA_REFCOUNT while (oldsize < f->sizek) setnilvalue2n(L, &f->k[oldsize++]); #else while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); #endif /* LUA_REFCOUNT */ setobj(L, &f->k[fs->nk], v); luaC_barrier(L, f, v); return fs->nk++; } }
static Tvalue *table_newkey(ktap_State *ks, Table *t, const Tvalue *key) { Node *mp; mp = mainposition(t, key); if (!isnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */ Node *othern; Node *n = getfreepos(t); /* get a free place */ if (n == NULL) { /* cannot find a free place? */ rehash(ks, t, key); /* grow table */ /* whatever called 'newkey' take care of TM cache and GC barrier */ return kp_table_set(ks, t, key); /* insert key into grown table */ } othern = mainposition(t, gkey(mp)); if (othern != mp) { /* is colliding node out of its main position? */ /* yes; move colliding node into free position */ while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ gnext(mp) = NULL; /* now `mp' is free */ setnilvalue(gval(mp)); } else { /* colliding node is in its own main position */ /* new node will go into free position */ gnext(n) = gnext(mp); /* chain new position */ gnext(mp) = n; mp = n; } } setobj(ks, gkey(mp), key); return gval(mp); }
void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { int loop; TValue temp; for (loop = 0; loop < MAXTAGLOOP; loop++) { const TValue *tm; if (ttistable(t) || ttisrotable(t)) { /* `t' is a table? */ void *h = ttistable(t) ? hvalue(t) : rvalue(t); const TValue *res = ttistable(t) ? luaH_get((Table*)h, key) : luaH_get_ro(h, key); /* do a primitive get */ if (!ttisnil(res) || /* result is no nil? */ (tm = fasttm(L, ttistable(t) ? ((Table*)h)->metatable : (Table*)luaR_getmeta(h), TM_INDEX)) == NULL) { /* or no TM? */ setobj2s(L, val, res); return; } /* else will try the tag method */ } else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) luaG_typeerror(L, t, "index"); if (ttisfunction(tm) || ttislightfunction(tm)) { callTMres(L, val, tm, t, key); return; } /* else repeat with `tm' */ setobj(L, &temp, tm); /* avoid pointing inside table (may rehash) */ t = &temp; } luaG_runerror(L, "loop in gettable"); }
/* weet: * 1. 将idx所在位置设置为当前栈顶元素 * 2. 栈顶指针下移一个 * */ LUA_API void lua_replace (lua_State *L, int idx) { lua_lock(L); api_checknelems(L, 1); setobj(luaA_index(L, idx), L->top - 1); /* write barrier */ L->top--; lua_unlock(L); }
void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { int loop; TValue temp; for (loop = 0; loop < MAXTAGLOOP; loop++) { const TValue *tm; if (ttistable(t)) { /* `t' is a table? */ Table *h = hvalue(t); TValue *oldval = luaH_set(L, h, key); /* do a primitive set */ if (!ttisnil(oldval) || /* result is no nil? */ (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ setobj2t(L, oldval, val); luaC_barriert(L, h, val); return; } /* else will try the tag method */ } else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) luaG_typeerror(L, t, "index"); if (ttisfunction(tm)) { callTM(L, tm, t, key, val); return; } /* else repeat with `tm' */ setobj(L, &temp, tm); /* avoid pointing inside table (may rehash) */ t = &temp; } luaG_runerror(L, "loop in settable"); }
/* ** Add constant 'v' to prototype's list of constants (field 'k'). ** Use scanner's table to cache position of constants in constant list ** and try to reuse constants. Because some values should not be used ** as keys (nil cannot be a key, integer keys can collapse with float ** keys), the caller must provide a useful 'key' for indexing the cache. */ static int addk (FuncState *fs, TValue *key, TValue *v) { lua_State *L = fs->ls->L; Proto *f = fs->f; TValue *idx = luaH_set(L, fs->ls->h, key); /* index scanner table */ int k, oldsize; if (ttisinteger(idx)) { /* is there an index there? */ k = cast_int(ivalue(idx)); /* correct value? (warning: must distinguish floats from integers!) */ if (k < fs->nk && ttype(&f->k[k]) == ttype(v) && luaV_rawequalobj(&f->k[k], v)) return k; /* reuse index */ } /* constant not found; create a new entry */ oldsize = f->sizek; k = fs->nk; /* numerical value does not need GC barrier; table has no metatable, so it does not need to invalidate cache */ setivalue(idx, k); luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); setobj(L, &f->k[k], v); fs->nk++; luaC_barrier(L, f, v); return k; }
int o_face( /* print out a polygon */ char *mod, char *typ, char *id, FUNARGS *fa ) { char entbuf[2048], *linestart; register char *cp; register int i; if ((fa->nfargs < 9) | (fa->nfargs % 3)) return(-1); setmat(mod); setobj(id); cp = linestart = entbuf; *cp++ = 'f'; for (i = 0; i < fa->nfargs; i += 3) { *cp++ = ' '; if (cp - linestart > 72) { *cp++ = '\\'; *cp++ = '\n'; linestart = cp; *cp++ = ' '; *cp++ = ' '; } getvertid(cp, fa->farg + i); while (*cp) cp++; } puts(entbuf); return(0); }
static UpVal *makeupval(lua_State *L, int stackpos) { UpVal *uv = luaM_new(L, UpVal); uv->tt = LUA_TUPVAL; uv->v = &uv->value; setobj(uv->v, getobject(L, stackpos)); luaC_link(L, valtogco(uv), LUA_TUPVAL); return uv; }
/* ** Reverse the stack segment from 'from' to 'to' ** (auxiliary to 'lua_rotate') */ static void reverse (lua_State *L, StkId from, StkId to) { for (; from < to; from++, to--) { TValue temp; setobj(L, &temp, from); setobjs2s(L, from, to); setobj2s(L, to, &temp); } }
LUAPLUS_API void lua_pushtobject(lua_State *L, void* tobject) { TValue* tobj = (TValue*)tobject; lua_lock(L); setobj(L, L->top, tobj); api_incr_top(L); lua_unlock(L); }
static void moveto (lua_State *L, TValue *fr, int idx) { TValue *to = index2addr(L, idx); api_checkvalidindex(L, to); setobj(L, to, fr); if (idx < LUA_REGISTRYINDEX) /* function upvalue? */ luaC_barrier(L, clCvalue(L->ci->func), fr); /* LUA_REGISTRYINDEX does not need gc barrier (collector revisits it before finishing collection) */ }
static void gettable(ktap_state *ks, const ktap_value *t, ktap_value *key, StkId val) { if (ttistable(t)) { setobj(val, kp_table_get(hvalue(t), key)); } else if (ttisaggrtable(t)) { kp_aggrtable_get(ks, ahvalue(t), key, val); } else { kp_error(ks, "get key from non-table\n"); } }
UpVal *makeUpValue(lua_State *luaState, int stackPos) { UpVal *uv = lua_new(luaState, UpVal); lua_link(luaState, (GCObject *)uv, LUA_TUPVAL); uv->tt = LUA_TUPVAL; uv->v = &uv->u.value; uv->u.l.prev = NULL; uv->u.l.next = NULL; setobj(luaState, uv->v, getObject(luaState, stackPos)); return uv; }
LUA_API void lua_replace (lua_State *L, int idx) { lua_lock(L); /* explicit test for incompatible code */ if ( idx == LUA_ENVIRONINDEX && !hascallingenv( L ) ) { luaG_runerror(L, "no calling environment"); } api_checknelems(L, 1); { rtStack_t& rtStack = L->rtStack; rtStack.Lock( L ); StkId stackTop = L->GetCurrentStackFrame().TopMutable( L, L->rtStack ); if ( idx == LUA_ENVIRONINDEX ) { Closure *func = curr_func(L); const TValue *val = stackTop; func->env = gcvalue(val); luaC_barrier(L, func, val); } else if ( idx == LUA_STORAGEINDEX ) { const TValue *val = stackTop; setgcvalue( L, &L->storage, gcvalue( val ) ); luaC_barrier( L, L, val ); } else { ValueAddress o = index2adr(L, idx); api_checkvalidindex(L, o); setobj( L, o, stackTop ); if ( idx < LUA_GLOBALSINDEX ) /* function upvalue? */ { luaC_barrier(L, curr_func(L), stackTop); } } popstack( L, 1 ); rtStack.Unlock( L ); } lua_unlock(L); }
void luaF_close (lua_State *L, StkId level) { UpVal *uv; while (L->openupval != NULL && (uv = L->openupval, uplevel(uv) >= level)) { TValue *slot = &uv->u.value; /* new position for value */ luaF_unlinkupval(uv); setobj(L, slot, uv->v); /* move value to upvalue slot */ uv->v = slot; /* now current value lives here */ if (!iswhite(uv)) gray2black(uv); /* closed upvalues cannot be gray */ luaC_barrier(L, uv, slot); } }
LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) { TValue *fr, *to; lua_lock(L); fr = index2addr(L, fromidx); to = index2addr(L, toidx); api_checkvalidindex(to); setobj(L, to, fr); if (isupvalue(toidx)) /* function upvalue? */ luaC_barrier(L, clCvalue(L->ci->func), fr); /* LUA_REGISTRYINDEX does not need gc barrier (collector revisits it before finishing collection) */ lua_unlock(L); }
int kp_table_next(ktap_State *ks, Table *t, StkId key) { int i = findindex(ks, t, key); /* find original element */ for (i++; i < t->sizearray; i++) { /* try first array part */ if (!ttisnil(&t->array[i])) { /* a non-nil value? */ setnvalue(key, i+1); setobj(ks, key+1, &t->array[i]); return 1; } } for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ setobj(ks, key, gkey(gnode(t, i))); setobj(ks, key+1, gval(gnode(t, i))); return 1; } } return 0; /* no more elements */ }
void luaF_close (lua_State *L, StkId level) { UpVal *uv; while (L->openupval != NULL && (uv = L->openupval)->v >= level) { lua_assert(upisopen(uv)); L->openupval = uv->u.open.next; /* remove from 'open' list */ if (uv->refcount == 0) /* no references? */ luaM_free(L, uv); /* free upvalue */ else { setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ uv->v = &uv->u.value; /* now current value lives here */ luaC_upvalbarrier(L, uv); } } }
ktap_closure *kp_load(ktap_state *ks, unsigned char *buff) { struct load_state S; ktap_closure *cl; ktap_lclosure *f; int ret, i; S.ks = ks; S.buff = buff; S.pos = 0; ret = load_header(&S); if (ret) return NULL; cl = kp_newlclosure(ks, 1); if (!cl) return cl; /* put closure on the top, prepare to run with this closure */ setcllvalue(ks->top, cl); incr_top(ks); cl->l.p = kp_newproto(ks); if (load_function(&S, cl->l.p)) return NULL; if (cl->l.p->sizeupvalues != 1) { ktap_proto *p = cl->l.p; cl = kp_newlclosure(ks, cl->l.p->sizeupvalues); cl->l.p = p; setcllvalue(ks->top - 1, cl); } f = &cl->l; for (i = 0; i < f->nupvalues; i++) { /* initialize upvalues */ ktap_upval *up = kp_newupval(ks); f->upvals[i] = up; } /* set global table as 1st upvalue of 'f' */ if (f->nupvalues == 1) { ktap_table *reg = hvalue(&G(ks)->registry); const ktap_value *gt = kp_table_getint(reg, KTAP_RIDX_GLOBALS); setobj(f->upvals[0]->v, gt); } verify_code(&S, cl->l.p); return cl; }
void kp_table_setint(ktap_State *ks, Table *t, int key, Tvalue *v) { const Tvalue *p = kp_table_getint(t, key); Tvalue *cell; if (p != ktap_nilobject) cell = (Tvalue *)p; else { Tvalue k; setnvalue(&k, key); cell = table_newkey(ks, t, &k); } setobj(ks, cell, v); }
void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { TValue tmp; int loop; for (loop = 0; loop < MAXTAGLOOP; loop++) { const TValue *tm; if (ttistable(t)) { /* `t' is a table? */ Table *h = hvalue(t); TValue *oldval = luaH_set(L, h, key); /* do a primitive set */ if (!ttisnil(oldval) || /* result is no nil? */ (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ setobj2t(L, oldval, val); luaC_barriert(L, h, val); #if LUA_REFCOUNT if (ttisnil(val)) { Node* keyNode = luaH_getkey(h, key); if (keyNode) { luaH_removekey(L, h, keyNode); } } #endif /* LUA_REFCOUNT */ return; } /* else will try the tag method */ } else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) luaG_typeerror(L, t, "index"); if (ttisfunction(tm)) { callTM(L, tm, t, key, val); #if LUA_REFCOUNT { TValue *newval; if (ttistable(t)) { newval = luaH_set(L, hvalue(t), key); if (ttisnil(newval)) { Node* keyNode = luaH_getkey(hvalue(t), key); if (keyNode) luaH_removekey(L, hvalue(t), keyNode); } } } #endif /* LUA_REFCOUNT */ return; } setobj(L, &tmp, tm); t = &tmp; /* else repeat with copy of `tm' */ } luaG_runerror(L, "loop in settable"); }
static StkId adjust_varargs(ktap_state *ks, ktap_proto *p, int actual) { int i; int nfixargs = p->numparams; StkId base, fixed; /* move fixed parameters to final position */ fixed = ks->top - actual; /* first fixed argument */ base = ks->top; /* final position of first argument */ for (i=0; i < nfixargs; i++) { setobj(ks->top++, fixed + i); setnilvalue(fixed + i); } return base; }
void vm_mini_vm(lua_State *L, LClosure *cl, int count, int pseudo_ops_offset) { const Instruction *pc; StkId base; TValue *k; k = cl->p->k; pc = cl->p->code + pseudo_ops_offset; base = L->base; /* process next 'count' ops */ for (; count > 0; count--) { const Instruction i = *pc++; StkId ra = RA(i); lua_assert(base == L->base && L->base == L->ci->base); lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); lua_assert(L->top == L->ci->top || luaG_checkopenop(i)); switch (GET_OPCODE(i)) { case OP_MOVE: { setobjs2s(L, ra, RB(i)); continue; } case OP_LOADK: { setobj2s(L, ra, KBx(i)); continue; } case OP_GETUPVAL: { int b = GETARG_B(i); setobj2s(L, ra, cl->upvals[b]->v); continue; } case OP_SETUPVAL: { UpVal *uv = cl->upvals[GETARG_B(i)]; setobj(L, uv->v, ra); luaC_barrier(L, uv, ra); continue; } case OP_SETTABLE: { Protect(luaV_settable(L, ra, RKB(i), RKC(i))); continue; } default: { luaG_runerror(L, "Bad opcode: opcode=%d", GET_OPCODE(i)); continue; } } } }
int o_sphere( /* print out a sphere */ char *mod, char *typ, char *id, register FUNARGS *fa ) { char cent[6]; if (fa->nfargs != 4) return(-1); setmat(mod); setobj(id); printf("sph %s %.12g\n", getvertid(cent, fa->farg), typ[0]=='b' ? -fa->farg[3] : fa->farg[3]); return(0); }
void luaF_close (lua_State *L, StkId level) { UpVal *uv; global_State *g = G(L); while (L->openupval != NULL && (uv = gco2uv(L->openupval))->v >= level) { GCObject *o = obj2gco(uv); lua_assert(!isblack(o) && uv->v != &uv->u.value); L->openupval = uv->next; /* remove from `open' list */ if (isdead(g, o)) luaF_freeupval(L, uv); /* free upvalue */ else { unlinkupval(uv); /* remove upvalue from 'uvhead' list */ setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ uv->v = &uv->u.value; /* now current value lives here */ gch(o)->next = g->allgc; /* link upvalue into 'allgc' list */ g->allgc = o; luaC_checkupvalcolor(g, uv); } } }
static int ICACHE_FLASH_ATTR addk (FuncState *fs, TValue *k, TValue *v) { lua_State *L = fs->L; TValue *idx = luaH_set(L, fs->h, k); Proto *f = fs->f; int oldsize = f->sizek; if (ttisnumber(idx)) { lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); return cast_int(nvalue(idx)); } else { /* constant not found; create a new entry */ setnvalue(idx, cast_num(fs->nk)); luaM_growvector(L, f->k, fs->nk, f->sizek, TValue, MAXARG_Bx, "constant table overflow"); while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); setobj(L, &f->k[fs->nk], v); luaC_barrier(L, f, v); return fs->nk++; } }
int o_instance( /* convert an instance (or mesh) */ char *mod, char *typ, char *id, FUNARGS *fa ) { register int i; register char *cp; char *start = NULL, *end = NULL; /* * We don't really know how to do this, so we just create * a reference to an undefined MGF file and it's the user's * responsibility to create this file and put the appropriate * stuff into it. */ if (fa->nsargs < 1) return(-1); setmat(mod); /* only works if surfaces are void */ setobj(id); for (cp = fa->sarg[0]; *cp; cp++) /* construct MGF file name */ if (*cp == '/') start = cp+1; else if (*cp == '.') end = cp; if (start == NULL) start = fa->sarg[0]; if (end == NULL || start >= end) end = cp; fputs("i ", stdout); /* print include entity */ for (cp = start; cp < end; cp++) putchar(*cp); fputs(".mgf", stdout); /* add MGF suffix */ for (i = 1; i < fa->nsargs; i++) { /* add transform */ putchar(' '); fputs(fa->sarg[i], stdout); } putchar('\n'); clrverts(); /* vertex id's no longer reliable */ return(0); }
static int addk (FuncState *fs, TValue *k, TValue *v) { lua_State *L = fs->L; TValue *idx = luaH_set(L, fs->h, k); #ifdef LUA_TINT /* Note: Integer-valued LUA_TNUMBER's are handled as in unpatched Lua (below) */ if (ttype(idx)==LUA_TINT) { int i; # ifdef LNUM_INT64 lua_assert( (int)ivalue(idx) == ivalue(idx) ); /* make sure no data is lost in the casting */ # endif i= (int)ivalue(idx); lua_assert(luaO_rawequalObj(&fs->f->k[i], v)); return i; } else if (ttype(idx)==LUA_TNUMBER) { #else if (ttisnumber(idx)) { #endif int i= cast_int(nvalue_fast(idx)); lua_assert(luaO_rawequalObj(&fs->f->k[i], v)); return i; } else { /* constant not found; create a new entry */ Proto *f = fs->f; int oldsize = f->sizek; setivalue(idx, fs->nk); luaM_growvector(L, f->k, fs->nk, f->sizek, TValue, MAXARG_Bx, "constant table overflow"); while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); setobj(L, &f->k[fs->nk], v); luaC_barrier(L, f, v); return fs->nk++; } } int luaK_stringK (FuncState *fs, TString *s) { TValue o; setsvalue(fs->L, &o, s); return addk(fs, &o, &o); }