int32 luaV_tonumber (TObject *obj) { /* LUA_NUMBER */ double t; char c; if (ttype(obj) != LUA_T_STRING) return 1; else if (sscanf(svalue(obj), "%lf %c",&t, &c) == 1) { nvalue(obj) = (real)t; ttype(obj) = LUA_T_NUMBER; return 0; } else return 2; }
void luaV_pack(StkId firstel, int32 nvararg, TObject *tab) { TObject *firstelem = lua_state->stack.stack + firstel; int32 i; if (nvararg < 0) nvararg = 0; avalue(tab) = luaH_new(nvararg + 1); // +1 for field 'n' ttype(tab) = LUA_T_ARRAY; for (i = 0; i < nvararg; i++) { TObject index; ttype(&index) = LUA_T_NUMBER; nvalue(&index) = (float)i + 1; *(luaH_set(avalue(tab), &index)) = *(firstelem + i); } // store counter in field "n" */ { TObject index, extra; ttype(&index) = LUA_T_STRING; tsvalue(&index) = luaS_new("n"); ttype(&extra) = LUA_T_NUMBER; nvalue(&extra) = (float)nvararg; *(luaH_set(avalue(tab), &index)) = extra; } }
/* * equality of ktap values. */ int kp_obj_rawequal(const ktap_val_t *t1, const ktap_val_t *t2) { switch (itype(t1)) { case KTAP_TNIL: case KTAP_TTRUE: case KTAP_TFALSE: return 1; case KTAP_TNUM: return nvalue(t1) == nvalue(t2); case KTAP_TLIGHTUD: return pvalue(t1) == pvalue(t2); case KTAP_TFUNC: return fvalue(t1) == fvalue(t2); case KTAP_TSTR: return rawtsvalue(t1) == rawtsvalue(t2); case KTAP_TTAB: return hvalue(t1) == hvalue(t2); default: return gcvalue(t1) == gcvalue(t2); } return 0; }
/* ** Try to convert a value to a float. The float case is already handled ** by the macro 'tonumber'. */ int luaV_tonumber_ (const TValue *obj, lua_Number *n) { TValue v; if (ttisinteger(obj)) { *n = cast_num(ivalue(obj)); return 1; } else if (cvt2num(obj) && /* string convertible to number? */ luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) { *n = nvalue(&v); /* convert result of 'luaO_str2num' to a float */ return 1; } else return 0; /* conversion failed */ }
/* ** returns the `main' position of an element in a table (that is, the index ** of its hash value) */ static Node *mainposition (const Table *t, const TValue *key) { switch (ttype(key)) { case LUA_TNUMBER: return hashnum(t, nvalue(key)); case LUA_TSTRING: return hashstr(t, rawtsvalue(key)); case LUA_TBOOLEAN: return hashboolean(t, bvalue(key)); case LUA_TLIGHTUSERDATA: return hashpointer(t, pvalue(key)); default: return hashpointer(t, gcvalue(key)); } }
static void Arith (lua_State *L, StkId ra, const TValue *rb, const TValue *rc, TMS op) { TValue tempb, tempc; const TValue *b, *c; if ((b = luaV_tonumber(rb, &tempb)) != NULL && (c = luaV_tonumber(rc, &tempc)) != NULL) { lua_Number nb = nvalue(b), nc = nvalue(c); switch (op) { case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break; case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break; case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break; case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break; case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break; case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break; case TM_UNM: setnvalue(ra, luai_numunm(nb)); break; default: lua_assert(0); break; } } else if (!call_binTM(L, rb, rc, ra, op)) luaG_aritherror(L, rb, rc); }
static int kplib_ffi_new(ktap_state *ks) { int n = kp_arg_nr(ks), array_size, is_array; csymbol_id cs_id; ktap_cdata *cd; if (unlikely(n != 3)) { /* this is not likely to happen since ffi.new arguments are * generated by compiler */ set_nil(ks->top++); kp_error(ks, "wrong number of arguments\n"); return 1; } kp_arg_check(ks, 1, KTAP_TYPE_NUMBER); kp_arg_check(ks, 2, KTAP_TYPE_NUMBER); kp_arg_check(ks, 3, KTAP_TYPE_NUMBER); cs_id = nvalue(kp_arg(ks, 1)); array_size = nvalue(kp_arg(ks, 2)); is_array = nvalue(kp_arg(ks, 3)); if (unlikely(cs_id > max_csym_id(ks))) kp_error(ks, "invalid csymbol id\n"); kp_verbose_printf(ks, "ffi.new symbol %s with length %d\n", id_to_csym(ks, cs_id)->name, array_size); if (is_array) cd = kp_cdata_new_ptr(ks, NULL, array_size, cs_id, 1); else cd = kp_cdata_new_by_id(ks, NULL, cs_id); set_cdata(ks->top, cd); incr_top(ks); return 1; }
/* * 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; }
int32 luaV_tostring (TObject *obj) { /* LUA_NUMBER */ /* The Lua scripts for Grim Fandango sometimes end up executing str..nil. The nil shows up in the original engine as "(nil)"... */ if (ttype(obj) == LUA_T_NIL) { tsvalue(obj) = luaS_new("(nil)"); ttype(obj) = LUA_T_STRING; return 0; } else if (ttype(obj) != LUA_T_NUMBER) return 1; else { char s[60]; real f = nvalue(obj); int32 i; if ((real)(-MAX_INT) <= f && f <= (real)MAX_INT && (real)(i=(int32)f) == f) sprintf (s, "%d", (int)i); else sprintf (s, NUMBER_FMT, nvalue(obj)); tsvalue(obj) = luaS_new(s); ttype(obj) = LUA_T_STRING; return 0; } }
LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *isnum) { TValue n; const TValue *o = index2addr(L, idx); if (tonumber(o, &n)) { lua_Unsigned res; lua_Number num = nvalue(o); lua_number2unsigned(res, num); if (isnum) *isnum = 1; return res; } else { if (isnum) *isnum = 0; 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 lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) { TValue n; const TValue *o = index2addr(L, idx); if (tonumber(o, &n)) { lua_Integer res; lua_Number num = nvalue(o); lua_number2integer(res, num); if (isnum) *isnum = 1; return res; } else { if (isnum) *isnum = 0; return 0; } }
/* ** Convert, if possible, to a number object. ** Return 0 if success, not 0 if error. */ static int lua_tonumber (Object *obj) { float t; char c; if (tag(obj) != LUA_T_STRING) return 1; else if (sscanf(svalue(obj), "%f %c",&t, &c) == 1) { nvalue(obj) = t; tag(obj) = LUA_T_NUMBER; return 0; } else return 2; }
int luaV_towstring (lua_State *L, TValue *obj) { if (ttype(obj) != LUA_TNUMBER) return 0; else { char s[32]; /* 16 digits, sign, point and \0 (+ some extra...) */ lua_WChar ws[32]; /* 16 digits, sign, point and \0 (+ some extra...) */ char* ptr = s; lua_WChar* wptr = ws; lua_number2wstr(s, nvalue(obj)); /* convert `s' to number */ while (*ptr != 0) *wptr++ = *ptr++; *wptr = 0; setwsvalue2s(L, obj, luaWS_new(L, ws)); return 1; } }
static int ktap_lib_user_string(ktap_State *ks) { unsigned long addr = nvalue(GetArg(ks, 1)); char str[256] = {0}; int ret; pagefault_disable(); ret = __copy_from_user_inatomic((void *)str, (const void *)addr, 256); (void) &ret; /* Silence compiler warning. */ pagefault_enable(); str[255] = '\0'; setsvalue(ks->top, kp_tstring_new(ks, str)); incr_top(ks); return 1; }
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; } }
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; } }
const Tvalue *kp_table_getint(Table *t, int key) { Node *n; if ((unsigned int)(key - 1) < (unsigned int)t->sizearray) return &t->array[key - 1]; n = hashnum(t, key); do { if (ttisnumber(gkey(n)) && nvalue(gkey(n)) == key) return gval(n); else n = gnext(n); } while (n); return ktap_nilobject; }
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(); }
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; }
/* ** try to remove a key without value from a table. To avoid problems with ** hash, change `key' for a number with the same hash. */ void luaH_remove (Hash *t, TObject *key) { if (ttype(key) == LUA_TNUMBER || (ttype(key) == LUA_TSTRING && tsvalue(key)->len <= 30)) return; /* do not remove numbers nor small strings */ else { /* try to find a number `n' with the same hash as `key' */ Node *mp = luaH_mainposition(t, key); int n = mp - &t->node[0]; /* make sure `n' is not in `t' */ while (luaH_getnum(t, n) != &luaO_nilobject) { if (n >= MAX_INT - t->size) return; /* give up; (to avoid overflow) */ n += t->size; } ttype(key) = LUA_TNUMBER; nvalue(key) = n; LUA_ASSERT(luaH_mainposition(t, key) == mp, "cannot change hash"); } }
static int kplib_kernel_string(ktap_state *ks) { unsigned long addr; char str[256] = {0}; char *ret; kp_arg_check(ks, 1, KTAP_TYPE_NUMBER); addr = nvalue(kp_arg(ks, 1)); ret = strncpy((void *)str, (const void *)addr, 256); (void) &ret; /* Silence compiler warning. */ str[255] = '\0'; set_string(ks->top, kp_str_new_local(ks, str)); incr_top(ks); return 1; }
static void PrintConstant(const Proto* f, int i) { const TObject* o=&f->k[i]; switch (ttype(o)) { case LUA_TNUMBER: printf(LUA_NUMBER_FMT,nvalue(o)); break; case LUA_TSTRING: PrintString(f,i); break; case LUA_TNIL: printf("nil"); break; default: /* cannot happen */ printf("? type=%d",ttype(o)); break; } }
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 int kplib_stringof(ktap_state_t *ks) { ktap_val_t *v = kp_arg(ks, 1); const ktap_str_t *ts = NULL; if (itype(v) == KTAP_TEVENTSTR) { ts = kp_event_stringify(ks); } else if (itype(v) == KTAP_TKIP) { char str[KSYM_SYMBOL_LEN]; SPRINT_SYMBOL(str, nvalue(v)); ts = kp_str_newz(ks, str); } if (unlikely(!ts)) return -1; set_string(ks->top++, ts); return 1; }
static void luaB_foreachi (void) { Hash *t = gethash(1); int i; int n = (int)getnarg(t); TObject f; /* 'f' cannot be a pointer to TObject, because it is on the stack, and the stack may be reallocated by the call. Moreover, some C compilers do not initialize structs, so we must do the assignment after the declaration */ f = *luaA_Address(luaL_functionarg(2)); luaD_checkstack(3); /* for f, ref, and val */ for (i=1; i<=n; i++) { *(L->stack.top++) = f; ttype(L->stack.top) = LUA_T_NUMBER; nvalue(L->stack.top++) = i; *(L->stack.top++) = *luaH_getint(t, i); luaD_calln(2, 1); if (ttype(L->stack.top-1) != LUA_T_NIL) return; L->stack.top--; } }
static int kplib_user_string(ktap_state *ks) { unsigned long addr; char str[256] = {0}; int ret; kp_arg_check(ks, 1, KTAP_TYPE_NUMBER); addr = nvalue(kp_arg(ks, 1)); pagefault_disable(); ret = __copy_from_user_inatomic((void *)str, (const void *)addr, 256); (void) &ret; /* Silence compiler warning. */ pagefault_enable(); str[255] = '\0'; set_string(ks->top, kp_str_new(ks, str)); incr_top(ks); return 1; }
static void PrintConstant(const Proto *f, int i) { const TValue *o = &f->k[i]; switch (ttype(o)) { case LUA_TNIL: printf("nil"); break; case LUA_TBOOLEAN: printf(bvalue(o) ? "true" : "false"); break; case LUA_TNUMBER: printf(LUA_NUMBER_FMT, nvalue(o)); break; case LUA_TSTRING: PrintString(rawtsvalue(o)); break; default: /* cannot happen */ printf("? type=%d", ttype(o)); break; } }
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; }
/** * Return the source IP address for a given sock */ static int kplib_ip_sock_saddr(ktap_state *ks) { struct inet_sock *isk; int family; kp_arg_check(ks, 1, KTAP_TYPE_NUMBER); /* need to validate the address firstly */ isk = (struct inet_sock *)nvalue(kp_arg(ks, 1)); family = isk->sk.__sk_common.skc_family; if (family == AF_INET) { set_number(ks->top, isk->inet_rcv_saddr); } else { kp_error(ks, "ip_sock_saddr only support ipv4 now\n"); set_nil(ks->top); } incr_top(ks); return 1; }