LUA_API const void *lua_topointer (lua_State *L, int idx) { StkId o = index2addr(L, idx); switch (ttype(o)) { case LUA_TTABLE: return hvalue(o); case LUA_TLCL: return clLvalue(o); case LUA_TCCL: return clCvalue(o); case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o))); case LUA_TTHREAD: return thvalue(o); case LUA_TUSERDATA: case LUA_TLIGHTUSERDATA: return lua_touserdata(L, idx); default: return NULL; } }
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; }
const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) { Table *mt; switch (ttype(o)) { case LUA_TTABLE: mt = hvalue(o)->metatable; break; case LUA_TUSERDATA: mt = uvalue(o)->metatable; break; default: mt = G(L)->mt[ttype(o)]; } return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); }
LUA_API void lua_settag (lua_State *L, int tag) { luaT_realtag(L, tag); switch (ttype(L->top-1)) { case LUA_TTABLE: hvalue(L->top-1)->htag = tag; break; case LUA_TUSERDATA: tsvalue(L->top-1)->u.d.tag = tag; break; default: luaO_verror(L, "cannot change the tag of a %.20s", luaO_typename(L->top-1)); } }
LUA_API void lua_rawset (lua_State *L, int idx) { StkId o; Table *t; lua_lock(L); api_checknelems(L, 2); o = index2addr(L, idx); api_check(L, ttistable(o), "table expected"); t = hvalue(o); setobj2t(L, luaH_set(L, t, L->top-2), L->top-1); invalidateTMcache(t); luaC_barrierback(L, t, L->top-1); L->top -= 2; lua_unlock(L); }
static int kplib_print_hist(ktap_state_t *ks) { int n ; kp_arg_check(ks, 1, KTAP_TTAB); n = kp_arg_checkoptnumber(ks, 2, HISTOGRAM_DEFAULT_TOP_NUM); n = min(n, 1000); n = max(n, HISTOGRAM_DEFAULT_TOP_NUM); kp_tab_print_hist(ks, hvalue(kp_arg(ks, 1)), n); return 0; }
LUA_API void lua_rawseti (lua_State *L, int idx, int n) { StkId o; lua_lock(L); api_checknelems(L, 1); o = luaA_index(L, idx); api_check(L, ttistable(o)); setobj2t(luaH_setnum(L, hvalue(o), n), L->top-1); /* write barrier */ #if LUA_REFCOUNT setnilvalue(--L->top); #else !LUA_REFCOUNT L->top--; #endif LUA_REFCOUNT lua_unlock(L); }
/* * equality of ktap values. ks == NULL means raw equality */ int kp_equalobjv(ktap_state *ks, const ktap_value *t1, const ktap_value *t2) { switch (ttype(t1)) { case KTAP_TNIL: return 1; case KTAP_TNUMBER: return nvalue(t1) == nvalue(t2); case KTAP_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ case KTAP_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); case KTAP_TLCF: return fvalue(t1) == fvalue(t2); case KTAP_TSHRSTR: return eqshrstr(rawtsvalue(t1), rawtsvalue(t2)); case KTAP_TLNGSTR: return kp_tstring_eqlngstr(rawtsvalue(t1), rawtsvalue(t2)); case KTAP_TUSERDATA: if (uvalue(t1) == uvalue(t2)) return 1; else if (ks == NULL) return 0; case KTAP_TTABLE: if (hvalue(t1) == hvalue(t2)) return 1; else if (ks == NULL) return 0; #ifdef __KERNEL__ case KTAP_TBTRACE: return kp_btrace_equal(btvalue(t1), btvalue(t2)); #endif default: return gcvalue(t1) == gcvalue(t2); } return 0; }
int luaV_equalval(lua_State *L, const TValue *t1, const TValue *t2) { const TValue* tm = 0; lua_assert(ttype(t1) == ttype(t2)); switch (ttype(t1)) { case LUA_TNIL: return 1; case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); case LUA_TUSERDATA: { if (uvalue(t1) == uvalue(t2)) return 1; tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ); break; /* will try TM */ } case LUA_TTABLE: { if (hvalue(t1) == hvalue(t2)) return 1; tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); break; /* will try TM */ } default: return gcvalue(t1) == gcvalue(t2); } if (tm == NULL) return 0; /* no TM? */ callTMres(L, L->top, tm, t1, t2); /* call TM */ return !l_isfalse(L->top); }
LUA_API const void *lua_topointer (lua_State *L, int idx) { StkId o = luaA_indexAcceptable(L, idx); if (o == NULL) return NULL; else { switch (ttype(o)) { case LUA_TTABLE: return hvalue(o); case LUA_TFUNCTION: return clvalue(o); case LUA_TTHREAD: return thvalue(o); case LUA_TUSERDATA: case LUA_TLIGHTUSERDATA: return lua_touserdata(L, idx); default: return NULL; } } }
LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) { StkId o; Table *t; TValue k; lua_lock(L); api_checknelems(L, 1); o = index2addr(L, idx); api_check(ttistable(o), "table expected"); t = hvalue(o); setpvalue(&k, cast(void *, p)); setobj2t(L, luaH_set(L, t, &k), L->top - 1); luaC_barrierback(L, t, L->top - 1); L->top--; lua_unlock(L); }
LUA_API void lua_rawset (lua_State *L, int idx) { StkId t; lua_lock(L); api_checknelems(L, 2); t = luaA_index(L, idx); api_check(L, ttistable(t)); setobj2t(luaH_set(L, hvalue(t), L->top-2), L->top-1); /* write barrier */ #if LUA_REFCOUNT setnilvalue(--L->top); setnilvalue(--L->top); #else !LUA_REFCOUNT L->top -= 2; #endif LUA_REFCOUNT lua_unlock(L); }
static int ktap_lib_histogram(ktap_state *ks) { ktap_value *v = kp_arg(ks, 1); if (G(ks)->mainthread != ks) { kp_error(ks, "only mainthread can call table historgram\n"); return -1; } if (ttistable(v)) kp_table_histogram(ks, hvalue(v)); else if (ttisaggrtable(v)) kp_aggrtable_histogram(ks, ahvalue(v)); return 0; }
LUA_API int lua_next (lua_State *L, int index) { StkId t = luaA_index(L, index); Node *n; LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected"); n = luaH_next(L, hvalue(t), luaA_index(L, -1)); if (n) { *(L->top-1) = *key(n); *L->top = *val(n); api_incr_top(L); return 1; } else { /* no more elements */ L->top -= 1; /* remove key */ return 0; } }
void kp_showobj(ktap_state *ks, const ktap_value *v) { switch (ttype(v)) { case KTAP_TNIL: kp_puts(ks, "nil"); break; case KTAP_TNUMBER: kp_printf(ks, "%ld", nvalue(v)); break; case KTAP_TBOOLEAN: kp_puts(ks, (bvalue(v) == 1) ? "true" : "false"); break; case KTAP_TLIGHTUSERDATA: kp_printf(ks, "0x%lx", (unsigned long)pvalue(v)); break; case KTAP_TLCF: kp_printf(ks, "0x%lx", (unsigned long)fvalue(v)); break; case KTAP_TSHRSTR: case KTAP_TLNGSTR: kp_puts(ks, svalue(v)); break; case KTAP_TUSERDATA: kp_printf(ks, "0x%lx", (unsigned long)uvalue(v)); break; case KTAP_TTABLE: kp_table_dump(ks, hvalue(v)); break; #ifdef __KERNEL__ case KTAP_TEVENT: kp_transport_event_write(ks, evalue(v)); break; case KTAP_TBTRACE: kp_btrace_dump(ks, btvalue(v)); break; case KTAP_TAGGRTABLE: kp_aggrtable_dump(ks, ahvalue(v)); break; case KTAP_TAGGRACCVAL: kp_aggraccval_dump(ks, aggraccvalue(v)); break; #endif default: kp_error(ks, "print unknown value type: %d\n", ttype(v)); break; } }
void kp_obj_show(ktap_state *ks, const ktap_value *v) { switch (ttype(v)) { case KTAP_TYPE_NIL: kp_puts(ks, "nil"); break; case KTAP_TYPE_NUMBER: kp_printf(ks, "%ld", nvalue(v)); break; case KTAP_TYPE_BOOLEAN: kp_puts(ks, (bvalue(v) == 1) ? "true" : "false"); break; case KTAP_TYPE_LIGHTUSERDATA: kp_printf(ks, "0x%lx", (unsigned long)pvalue(v)); break; case KTAP_TYPE_CFUNCTION: kp_printf(ks, "0x%lx", (unsigned long)fvalue(v)); break; case KTAP_TYPE_SHRSTR: case KTAP_TYPE_LNGSTR: kp_puts(ks, svalue(v)); break; case KTAP_TYPE_TABLE: kp_tab_dump(ks, hvalue(v)); break; #ifdef CONFIG_KTAP_FFI case KTAP_TYPE_CDATA: kp_cdata_dump(ks, cdvalue(v)); break; #endif case KTAP_TYPE_EVENT: kp_transport_event_write(ks, evalue(v)); break; case KTAP_TYPE_BTRACE: btrace_dump(ks, btvalue(v)); break; case KTAP_TYPE_PTABLE: kp_ptab_dump(ks, phvalue(v)); break; case KTAP_TYPE_STATDATA: kp_statdata_dump(ks, sdvalue(v)); break; default: kp_error(ks, "print unknown value type: %d\n", ttype(v)); break; } }
LUA_API void lua_setglobal (lua_State *L, const char *var) { //terminal_writehexln(&G(L)->l_registry); Table *reg = hvalue(&G(L)->l_registry); const TValue *gt; /* global table */ lua_lock(L); api_checknelems(L, 1); //terminal_writehexln(reg); gt = luaH_getint(reg, LUA_RIDX_GLOBALS); //terminal_writehexln(gt); setsvalue2s(L, L->top++, luaS_new(L, var)); luaV_settable(L, gt, L->top - 1, L->top - 2); L->top -= 2; /* pop value and key */ lua_unlock(L); }
LUA_API int lua_getn (lua_State *L, int index) { Hash *h = hvalue(luaA_index(L, index)); const TObject *value = luaH_getstr(h, luaS_new(L, "n")); /* value = h.n */ if (ttype(value) == LUA_TNUMBER) return (int)nvalue(value); else { Number max = 0; int i = h->size; Node *n = h->node; while (i--) { if (ttype(key(n)) == LUA_TNUMBER && ttype(val(n)) != LUA_TNIL && nvalue(key(n)) > max) max = nvalue(key(n)); n++; } return (int)max; } }
static int ktap_lib_table_count(ktap_state *ks) { ktap_table *tbl; ktap_value *k = kp_arg(ks, 2); int n; kp_arg_check(ks, 1, KTAP_TTABLE); tbl = hvalue(kp_arg(ks, 1)); if (kp_arg_nr(ks) > 2) n = nvalue(kp_arg(ks, 3)); else n = 1; kp_table_atomic_inc(ks, tbl, k, n); return 0; }
static int ktap_lib_count(ktap_State *ks) { Table *tbl = hvalue(GetArg(ks, 1)); Tvalue *k = GetArg(ks, 2); int n; Tvalue *v; if (GetArgN(ks) > 2) n = nvalue(GetArg(ks, 3)); else n = 1; v = kp_table_set(ks, tbl, k); if (unlikely(isnil(v))) { setnvalue(v, 1); } else setnvalue(v, nvalue(v) + n); return 0; }
LUAPLUS_API bool LuaPlusH_next(LuaState* state, LuaObject* table, LuaObject* key, LuaObject* value) { Table* t = hvalue(table->GetTObject()); int i = luaH_findindex(*state, t, key->GetTObject()); /* find original element */ for (i++; i < t->sizearray; i++) { /* try first array part */ if (!ttisnil(&t->array[i])) { /* a non-nil value? */ key->AssignInteger(state, i + 1); value->AssignTObject(state, &t->array[i]); return true; } } for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ key->AssignTObject(state, key2tval(gnode(t, i))); value->AssignTObject(state, gval(gnode(t, i))); return true; } } return false; /* no more elements */ }
static void traverseclosure (GCState *st, Closure *cl) { if (cl->c.isC) { int i; for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */ markobject(st, &cl->c.upvalue[i]); } else { int i; lua_assert(cl->l.nupvalues == cl->l.p->nups); markvalue(st, hvalue(&cl->l.g)); markvalue(st, cl->l.p); for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */ UpVal *u = cl->l.upvals[i]; if (!u->marked) { markobject(st, &u->value); u->marked = 1; } } } }
static int kplib_histogram(ktap_state *ks) { ktap_value *v = kp_arg(ks, 1); int n = HISTOGRAM_DEFAULT_TOP_NUM; if (kp_arg_nr(ks) >= 2) { kp_arg_check(ks, 2, KTAP_TYPE_NUMBER); n = nvalue(kp_arg(ks, 2)); if (n > 1000) n = 1000; } n = max(n, HISTOGRAM_DEFAULT_TOP_NUM); if (is_table(v)) kp_tab_histogram(ks, hvalue(v), n); else if (is_ptable(v)) kp_ptab_histogram(ks, phvalue(v), n); return 0; }
LUALIB_API int load_compiled_protos(lua_State *L, jit_proto *p) { Closure *cl; Proto *tf; int i; // load compiled lua code. luaC_checkGC(L); set_block_gc(L); /* stop collector during jit function loading. */ tf = load_jit_proto(L, p); #if DUMP_PROTOS luaU_dump_proto(tf,2); #endif cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); cl->l.p = tf; for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */ cl->l.upvals[i] = luaF_newupval(L); setclvalue(L, L->top, cl); incr_top(L); unset_block_gc(L); return 0; }
static int kplib_pairs(ktap_state *ks) { ktap_value *v = kp_arg(ks, 1); ktap_tab *t; if (is_table(v)) { t = hvalue(v); } else if (is_ptable(v)) { t = kp_ptab_synthesis(ks, phvalue(v)); } else if (is_nil(v)) { kp_error(ks, "table is nil in pairs\n"); return 0; } else { kp_error(ks, "wrong argument for pairs\n"); return 0; } set_cfunction(ks->top++, table_iter_next); set_table(ks->top++, t); set_nil(ks->top++); return 3; }
void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { int loop; TValue temp; setnilvalue(L->top); L->top++; fixedstack(L); 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); TValue *oldval = ttistable(t) ? luaH_set(L, (Table*)h, key) : NULL; /* do a primitive set */ if ((oldval && !ttisnil(oldval)) || /* result is no nil? */ (tm = fasttm(L, ttistable(t) ? ((Table*)h)->metatable : (Table*)luaR_getmeta(h), TM_NEWINDEX)) == NULL) { /* or no TM? */ if(oldval) { L->top--; unfixedstack(L); setobj2t(L, oldval, val); ((Table *)h)->flags = 0; luaC_barriert(L, (Table*)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) || ttislightfunction(tm)) { L->top--; unfixedstack(L); callTM(L, tm, t, key, val); return; } /* else repeat with `tm' */ setobj(L, &temp, tm); /* avoid pointing inside table (may rehash) */ t = &temp; setobj2s(L, L->top-1, t); /* need to protect value from EGC. */ } luaG_runerror(L, "loop in settable"); }
void vm_OP_SETLIST(lua_State *L, int a, int b, int c) { TValue *base = L->base; TValue *ra = base + a; int last; Table *h; fixedstack(L); if (b == 0) { b = cast_int(L->top - ra) - 1; L->top = L->ci->top; } runtime_check(L, ttistable(ra)); h = hvalue(ra); last = ((c-1)*LFIELDS_PER_FLUSH) + b; if (last > h->sizearray) /* needs more space? */ luaH_resizearray(L, h, last); /* pre-alloc it at once */ for (; b > 0; b--) { TValue *val = ra+b; setobj2t(L, luaH_setnum(L, h, last--), val); luaC_barriert(L, h, val); } unfixedstack(L); }
/* ** Main function for table assignment (invoking metamethods if needed). ** Compute 't[key] = val' */ void luaV_finishset (lua_State *L, const TValue *t, TValue *key, StkId val, const TValue *oldval) { int loop; /* counter to avoid infinite loops */ for (loop = 0; loop < MAXTAGLOOP; loop++) { const TValue *tm; if (oldval != NULL) { Table *h = hvalue(t); /* save 't' table */ lua_assert(ttisnil(oldval)); /* must check the metamethod */ if ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL && /* no metamethod; is there a previous entry in the table? */ (oldval != luaO_nilobject || /* no previous entry; must create one. (The next test is always true; we only need the assignment.) */ (oldval = luaH_newkey(L, h, key), 1))) { /* no metamethod and (now) there is an entry with given key */ setobj2t(L, cast(TValue *, oldval), val); invalidateTMcache(h); luaC_barrierback(L, h, val); return; } /* else will try the metamethod */ } else { /* not a table; check metamethod */ if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) luaG_typeerror(L, t, "index"); } /* try the metamethod */ if (ttisfunction(tm)) { luaT_callTM(L, tm, t, key, val, 0); return; } t = tm; /* else repeat assignment over 'tm' */ if (luaV_fastset(L, t, key, oldval, luaH_get, val)) return; /* done */ /* else loop */ } luaG_runerror(L, "settable chain too long; possible loop"); }
TObject *negindex (lua_State *L, int idx) { if (idx > LUA_REGISTRYINDEX) { api_check(L, idx != 0 && -idx <= L->top - L->base); return L->top+idx; } else if (idx < -40000) { return (TObject*)luaH_getnum(hvalue(registry(L)), -idx - 40000); } else switch (idx) { /* pseudo-indices */ case LUA_REGISTRYINDEX: return registry(L); case LUA_GLOBALSINDEX: return gt(L); default: { TObject *func = (L->base - 1); idx = LUA_GLOBALSINDEX - idx; lua_assert(iscfunction(func)); return (idx <= clvalue(func)->c.nupvalues) ? &clvalue(func)->c.upvalue[idx-1] : NULL; } } }
void kp_showobj(ktap_State *ks, const Tvalue *v) { switch (ttype(v)) { case KTAP_TNIL: kp_printf(ks, "nil"); break; case KTAP_TNUMBER: kp_printf(ks, "%d", nvalue(v)); break; case KTAP_TBOOLEAN: kp_printf(ks, "%s", (bvalue(v) == 1) ? "true" : "false"); break; case KTAP_TLIGHTUSERDATA: kp_printf(ks, "%d", pvalue(v)); break; case KTAP_TLCF: kp_printf(ks, "0x%x", fvalue(v)); break; case KTAP_TSHRSTR: case KTAP_TLNGSTR: kp_printf(ks, "\"%s\"", getstr(rawtsvalue(v))); break; case KTAP_TUSERDATA: kp_printf(ks, "%d", uvalue(v)); break; case KTAP_TTABLE: kp_table_dump(ks, hvalue(v)); break; #ifdef __KERNEL__ case KTAP_TEVENT: kp_show_event(ks); break; #endif default: kp_printf(ks, "[unknown value type: %d]", ttype(v)); break; } }