From 03946ac978d9a1a3230619e3da048002e5fda2d1 Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Thu, 17 Feb 2011 00:44:14 +0100 Subject: DUALNUM: Add integer type to core VM. --- src/lj_parse.c | 129 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 96 insertions(+), 33 deletions(-) (limited to 'src/lj_parse.c') diff --git a/src/lj_parse.c b/src/lj_parse.c index 0f5577e1..858891d2 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c @@ -73,7 +73,8 @@ typedef struct ExpDesc { #define expr_isnumk_nojump(e) (expr_isnumk(e) && !expr_hasjump(e)) #define expr_isstrk(e) ((e)->k == VKSTR) -#define expr_numV(e) check_exp(expr_isnumk((e)), numV(&(e)->u.nval)) +#define expr_numtv(e) check_exp(expr_isnumk((e)), &(e)->u.nval) +#define expr_numberV(e) numberVnum(expr_numtv((e))) /* Initialize expression. */ static LJ_AINLINE void expr_init(ExpDesc *e, ExpKind k, uint32_t info) @@ -83,6 +84,13 @@ static LJ_AINLINE void expr_init(ExpDesc *e, ExpKind k, uint32_t info) e->f = e->t = NO_JMP; } +/* Check number constant for +-0. */ +static int expr_numiszero(ExpDesc *e) +{ + TValue *o = expr_numtv(e); + return tvisint(o) ? (intV(o) == 0) : tviszero(o); +} + /* Per-function linked list of scope blocks. */ typedef struct FuncScope { struct FuncScope *prev; /* Link to outer scope. */ @@ -174,16 +182,19 @@ LJ_NORET static void err_limit(FuncState *fs, uint32_t limit, const char *what) /* Return bytecode encoding for primitive constant. */ #define const_pri(e) check_exp((e)->k <= VKTRUE, (e)->k) +#define tvhaskslot(o) ((o)->u32.hi == 0) +#define tvkslot(o) ((o)->u32.lo) + /* Add a number constant. */ static BCReg const_num(FuncState *fs, ExpDesc *e) { lua_State *L = fs->L; - TValue *val; + TValue *o; lua_assert(expr_isnumk(e)); - val = lj_tab_set(L, fs->kt, &e->u.nval); - if (tvisnum(val)) - return val->u32.lo; - val->u64 = fs->nkn; + o = lj_tab_set(L, fs->kt, &e->u.nval); + if (tvhaskslot(o)) + return tvkslot(o); + o->u64 = fs->nkn; return fs->nkn++; } @@ -191,13 +202,13 @@ static BCReg const_num(FuncState *fs, ExpDesc *e) static BCReg const_gc(FuncState *fs, GCobj *gc, uint32_t itype) { lua_State *L = fs->L; - TValue o, *val; - setgcV(L, &o, gc, itype); + TValue key, *o; + setgcV(L, &key, gc, itype); /* NOBARRIER: the key is new or kept alive. */ - val = lj_tab_set(L, fs->kt, &o); - if (tvisnum(val)) - return val->u32.lo; - val->u64 = fs->nkgc; + o = lj_tab_set(L, fs->kt, &key); + if (tvhaskslot(o)) + return tvkslot(o); + o->u64 = fs->nkgc; return fs->nkgc++; } @@ -344,7 +355,7 @@ static void bcreg_bump(FuncState *fs, BCReg n) if (sz > fs->framesize) { if (sz >= LJ_MAX_SLOTS) err_syntax(fs->ls, LJ_ERR_XSLOTS); - fs->framesize = cast_byte(sz); + fs->framesize = (uint8_t)sz; } } @@ -478,11 +489,18 @@ static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg) if (e->k == VKSTR) { ins = BCINS_AD(BC_KSTR, reg, const_str(fs, e)); } else if (e->k == VKNUM) { - lua_Number n = expr_numV(e); +#if LJ_DUALNUM + cTValue *tv = expr_numtv(e); + if (tvisint(tv) && checki16(intV(tv))) + ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)intV(tv)); + else +#else + lua_Number n = expr_numberV(e); int32_t k = lj_num2int(n); - if (checki16(k) && n == cast_num(k)) + if (checki16(k) && n == (lua_Number)k) ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)k); else +#endif ins = BCINS_AD(BC_KNUM, reg, const_num(fs, e)); #if LJ_HASFFI } else if (e->k == VKCDATA) { @@ -720,10 +738,19 @@ static void bcemit_branch_f(FuncState *fs, ExpDesc *e) static int foldarith(BinOpr opr, ExpDesc *e1, ExpDesc *e2) { TValue o; + lua_Number n; if (!expr_isnumk_nojump(e1) || !expr_isnumk_nojump(e2)) return 0; - setnumV(&o, lj_vm_foldarith(expr_numV(e1), expr_numV(e2), (int)opr-OPR_ADD)); + n = lj_vm_foldarith(expr_numberV(e1), expr_numberV(e2), (int)opr-OPR_ADD); + setnumV(&o, n); if (tvisnan(&o) || tvismzero(&o)) return 0; /* Avoid NaN and -0 as consts. */ - setnumV(&e1->u.nval, numV(&o)); + if (LJ_DUALNUM) { + int32_t k = lj_num2int(n); + if ((lua_Number)k == n) { + setintV(&e1->u.nval, k); + return 1; + } + } + setnumV(&e1->u.nval, n); return 1; } @@ -900,9 +927,18 @@ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e) return; } else #endif - if (expr_isnumk(e) && expr_numV(e) != 0) { /* Avoid folding to -0. */ - e->u.nval.u64 ^= U64x(80000000,00000000); - return; + if (expr_isnumk(e) && !expr_numiszero(e)) { /* Avoid folding to -0. */ + TValue *o = expr_numtv(e); + if (tvisint(o)) { + int32_t k = intV(o); + if (k == -k) + setnumV(o, -(lua_Number)k); + else + setintV(o, -k); + } else { + o->u64 ^= U64x(80000000,00000000); + return; + } } } expr_toanyreg(fs, e); @@ -986,7 +1022,7 @@ static void var_new(LexState *ls, BCReg n, GCstr *name) static void var_add(LexState *ls, BCReg nvars) { FuncState *fs = ls->fs; - fs->nactvar = cast_byte(fs->nactvar + nvars); + fs->nactvar = (uint8_t)(fs->nactvar + nvars); for (; nvars; nvars--) var_get(ls, fs, fs->nactvar - nvars).startpc = fs->pc; } @@ -1094,16 +1130,33 @@ static void fs_fixup_k(FuncState *fs, GCproto *pt, void *kptr) kt = fs->kt; array = tvref(kt->array); for (i = 0; i < kt->asize; i++) - if (tvisnum(&array[i])) - ((lua_Number *)kptr)[array[i].u32.lo] = cast_num(i); + if (tvhaskslot(&array[i])) { + TValue *tv = &((TValue *)kptr)[tvkslot(&array[i])]; + if (LJ_DUALNUM) + setintV(tv, (int32_t)i); + else + setnumV(tv, (lua_Number)i); + } node = noderef(kt->node); hmask = kt->hmask; for (i = 0; i <= hmask; i++) { Node *n = &node[i]; - if (tvisnum(&n->val)) { - ptrdiff_t kidx = (ptrdiff_t)n->val.u32.lo; + if (tvhaskslot(&n->val)) { + ptrdiff_t kidx = (ptrdiff_t)tvkslot(&n->val); + lua_assert(!tvisint(&n->key)); if (tvisnum(&n->key)) { - ((lua_Number *)kptr)[kidx] = numV(&n->key); + TValue *tv = &((TValue *)kptr)[kidx]; + if (LJ_DUALNUM) { + lua_Number nn = numV(&n->key); + int32_t k = lj_num2int(nn); + lua_assert(!tvismzero(&n->key)); + if ((lua_Number)k == nn) + setintV(tv, k); + else + *tv = n->key; + } else { + *tv = n->key; + } } else { GCobj *o = gcV(&n->key); setgcref(((GCRef *)kptr)[~kidx], o); @@ -1286,12 +1339,22 @@ static void expr_index(FuncState *fs, ExpDesc *t, ExpDesc *e) /* Already called: expr_toval(fs, e). */ t->k = VINDEXED; if (expr_isnumk(e)) { - lua_Number n = expr_numV(e); +#if LJ_DUALNUM + if (tvisint(expr_numtv(e))) { + int32_t k = intV(expr_numtv(e)); + if (checku8(k)) { + t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */ + return; + } + } +#else + lua_Number n = expr_numberV(e); int32_t k = lj_num2int(n); - if (checku8(k) && n == cast_num(k)) { + if (checku8(k) && n == (lua_Number)k) { t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */ return; } +#endif } else if (expr_isstrk(e)) { BCReg idx = const_str(fs, e); if (idx <= BCMAX_C) { @@ -1331,8 +1394,8 @@ static void expr_kvalue(TValue *v, ExpDesc *e) setgcref(v->gcr, obj2gco(e->u.sval)); setitype(v, LJ_TSTR); } else { - lua_assert(e->k == VKNUM); - setnumV(v, expr_numV(e)); + lua_assert(tvisnumber(expr_numtv(e))); + *v = *expr_numtv(e); } } @@ -1357,7 +1420,7 @@ static void expr_table(LexState *ls, ExpDesc *e) if (ls->token == '[') { expr_bracket(ls, &key); /* Already calls expr_toval. */ if (!expr_isk(&key)) expr_index(fs, e, &key); - if (expr_isnumk(&key) && expr_numV(&key) == 0) needarr = 1; else nhash++; + if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++; lex_check(ls, '='); } else if (ls->token == TK_name && lj_lex_lookahead(ls) == '=') { expr_str(ls, &key); @@ -2119,10 +2182,10 @@ static int predict_next(LexState *ls, FuncState *fs, BCPos pc) case BC_GGET: /* There's no inverse index (yet), so lookup the strings. */ o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "pairs")); - if (o && tvisnum(o) && o->u32.lo == bc_d(ins)) + if (o && tvhaskslot(o) && tvkslot(o) == bc_d(ins)) return 1; o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "next")); - if (o && tvisnum(o) && o->u32.lo == bc_d(ins)) + if (o && tvhaskslot(o) && tvkslot(o) == bc_d(ins)) return 1; return 0; default: -- cgit v1.2.3-55-g6feb