diff options
author | Mike Pall <mike> | 2011-02-17 00:44:14 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2011-02-17 00:44:14 +0100 |
commit | 03946ac978d9a1a3230619e3da048002e5fda2d1 (patch) | |
tree | c0a7b8edaccf789f128468320d451d9a1fee1495 /src/lj_parse.c | |
parent | 963f05c7e153714921484e0de71a7cb6bab338d9 (diff) | |
download | luajit-03946ac978d9a1a3230619e3da048002e5fda2d1.tar.gz luajit-03946ac978d9a1a3230619e3da048002e5fda2d1.tar.bz2 luajit-03946ac978d9a1a3230619e3da048002e5fda2d1.zip |
DUALNUM: Add integer type to core VM.
Diffstat (limited to 'src/lj_parse.c')
-rw-r--r-- | src/lj_parse.c | 129 |
1 files changed, 96 insertions, 33 deletions
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 { | |||
73 | #define expr_isnumk_nojump(e) (expr_isnumk(e) && !expr_hasjump(e)) | 73 | #define expr_isnumk_nojump(e) (expr_isnumk(e) && !expr_hasjump(e)) |
74 | #define expr_isstrk(e) ((e)->k == VKSTR) | 74 | #define expr_isstrk(e) ((e)->k == VKSTR) |
75 | 75 | ||
76 | #define expr_numV(e) check_exp(expr_isnumk((e)), numV(&(e)->u.nval)) | 76 | #define expr_numtv(e) check_exp(expr_isnumk((e)), &(e)->u.nval) |
77 | #define expr_numberV(e) numberVnum(expr_numtv((e))) | ||
77 | 78 | ||
78 | /* Initialize expression. */ | 79 | /* Initialize expression. */ |
79 | static LJ_AINLINE void expr_init(ExpDesc *e, ExpKind k, uint32_t info) | 80 | 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) | |||
83 | e->f = e->t = NO_JMP; | 84 | e->f = e->t = NO_JMP; |
84 | } | 85 | } |
85 | 86 | ||
87 | /* Check number constant for +-0. */ | ||
88 | static int expr_numiszero(ExpDesc *e) | ||
89 | { | ||
90 | TValue *o = expr_numtv(e); | ||
91 | return tvisint(o) ? (intV(o) == 0) : tviszero(o); | ||
92 | } | ||
93 | |||
86 | /* Per-function linked list of scope blocks. */ | 94 | /* Per-function linked list of scope blocks. */ |
87 | typedef struct FuncScope { | 95 | typedef struct FuncScope { |
88 | struct FuncScope *prev; /* Link to outer scope. */ | 96 | 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) | |||
174 | /* Return bytecode encoding for primitive constant. */ | 182 | /* Return bytecode encoding for primitive constant. */ |
175 | #define const_pri(e) check_exp((e)->k <= VKTRUE, (e)->k) | 183 | #define const_pri(e) check_exp((e)->k <= VKTRUE, (e)->k) |
176 | 184 | ||
185 | #define tvhaskslot(o) ((o)->u32.hi == 0) | ||
186 | #define tvkslot(o) ((o)->u32.lo) | ||
187 | |||
177 | /* Add a number constant. */ | 188 | /* Add a number constant. */ |
178 | static BCReg const_num(FuncState *fs, ExpDesc *e) | 189 | static BCReg const_num(FuncState *fs, ExpDesc *e) |
179 | { | 190 | { |
180 | lua_State *L = fs->L; | 191 | lua_State *L = fs->L; |
181 | TValue *val; | 192 | TValue *o; |
182 | lua_assert(expr_isnumk(e)); | 193 | lua_assert(expr_isnumk(e)); |
183 | val = lj_tab_set(L, fs->kt, &e->u.nval); | 194 | o = lj_tab_set(L, fs->kt, &e->u.nval); |
184 | if (tvisnum(val)) | 195 | if (tvhaskslot(o)) |
185 | return val->u32.lo; | 196 | return tvkslot(o); |
186 | val->u64 = fs->nkn; | 197 | o->u64 = fs->nkn; |
187 | return fs->nkn++; | 198 | return fs->nkn++; |
188 | } | 199 | } |
189 | 200 | ||
@@ -191,13 +202,13 @@ static BCReg const_num(FuncState *fs, ExpDesc *e) | |||
191 | static BCReg const_gc(FuncState *fs, GCobj *gc, uint32_t itype) | 202 | static BCReg const_gc(FuncState *fs, GCobj *gc, uint32_t itype) |
192 | { | 203 | { |
193 | lua_State *L = fs->L; | 204 | lua_State *L = fs->L; |
194 | TValue o, *val; | 205 | TValue key, *o; |
195 | setgcV(L, &o, gc, itype); | 206 | setgcV(L, &key, gc, itype); |
196 | /* NOBARRIER: the key is new or kept alive. */ | 207 | /* NOBARRIER: the key is new or kept alive. */ |
197 | val = lj_tab_set(L, fs->kt, &o); | 208 | o = lj_tab_set(L, fs->kt, &key); |
198 | if (tvisnum(val)) | 209 | if (tvhaskslot(o)) |
199 | return val->u32.lo; | 210 | return tvkslot(o); |
200 | val->u64 = fs->nkgc; | 211 | o->u64 = fs->nkgc; |
201 | return fs->nkgc++; | 212 | return fs->nkgc++; |
202 | } | 213 | } |
203 | 214 | ||
@@ -344,7 +355,7 @@ static void bcreg_bump(FuncState *fs, BCReg n) | |||
344 | if (sz > fs->framesize) { | 355 | if (sz > fs->framesize) { |
345 | if (sz >= LJ_MAX_SLOTS) | 356 | if (sz >= LJ_MAX_SLOTS) |
346 | err_syntax(fs->ls, LJ_ERR_XSLOTS); | 357 | err_syntax(fs->ls, LJ_ERR_XSLOTS); |
347 | fs->framesize = cast_byte(sz); | 358 | fs->framesize = (uint8_t)sz; |
348 | } | 359 | } |
349 | } | 360 | } |
350 | 361 | ||
@@ -478,11 +489,18 @@ static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg) | |||
478 | if (e->k == VKSTR) { | 489 | if (e->k == VKSTR) { |
479 | ins = BCINS_AD(BC_KSTR, reg, const_str(fs, e)); | 490 | ins = BCINS_AD(BC_KSTR, reg, const_str(fs, e)); |
480 | } else if (e->k == VKNUM) { | 491 | } else if (e->k == VKNUM) { |
481 | lua_Number n = expr_numV(e); | 492 | #if LJ_DUALNUM |
493 | cTValue *tv = expr_numtv(e); | ||
494 | if (tvisint(tv) && checki16(intV(tv))) | ||
495 | ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)intV(tv)); | ||
496 | else | ||
497 | #else | ||
498 | lua_Number n = expr_numberV(e); | ||
482 | int32_t k = lj_num2int(n); | 499 | int32_t k = lj_num2int(n); |
483 | if (checki16(k) && n == cast_num(k)) | 500 | if (checki16(k) && n == (lua_Number)k) |
484 | ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)k); | 501 | ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)k); |
485 | else | 502 | else |
503 | #endif | ||
486 | ins = BCINS_AD(BC_KNUM, reg, const_num(fs, e)); | 504 | ins = BCINS_AD(BC_KNUM, reg, const_num(fs, e)); |
487 | #if LJ_HASFFI | 505 | #if LJ_HASFFI |
488 | } else if (e->k == VKCDATA) { | 506 | } else if (e->k == VKCDATA) { |
@@ -720,10 +738,19 @@ static void bcemit_branch_f(FuncState *fs, ExpDesc *e) | |||
720 | static int foldarith(BinOpr opr, ExpDesc *e1, ExpDesc *e2) | 738 | static int foldarith(BinOpr opr, ExpDesc *e1, ExpDesc *e2) |
721 | { | 739 | { |
722 | TValue o; | 740 | TValue o; |
741 | lua_Number n; | ||
723 | if (!expr_isnumk_nojump(e1) || !expr_isnumk_nojump(e2)) return 0; | 742 | if (!expr_isnumk_nojump(e1) || !expr_isnumk_nojump(e2)) return 0; |
724 | setnumV(&o, lj_vm_foldarith(expr_numV(e1), expr_numV(e2), (int)opr-OPR_ADD)); | 743 | n = lj_vm_foldarith(expr_numberV(e1), expr_numberV(e2), (int)opr-OPR_ADD); |
744 | setnumV(&o, n); | ||
725 | if (tvisnan(&o) || tvismzero(&o)) return 0; /* Avoid NaN and -0 as consts. */ | 745 | if (tvisnan(&o) || tvismzero(&o)) return 0; /* Avoid NaN and -0 as consts. */ |
726 | setnumV(&e1->u.nval, numV(&o)); | 746 | if (LJ_DUALNUM) { |
747 | int32_t k = lj_num2int(n); | ||
748 | if ((lua_Number)k == n) { | ||
749 | setintV(&e1->u.nval, k); | ||
750 | return 1; | ||
751 | } | ||
752 | } | ||
753 | setnumV(&e1->u.nval, n); | ||
727 | return 1; | 754 | return 1; |
728 | } | 755 | } |
729 | 756 | ||
@@ -900,9 +927,18 @@ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e) | |||
900 | return; | 927 | return; |
901 | } else | 928 | } else |
902 | #endif | 929 | #endif |
903 | if (expr_isnumk(e) && expr_numV(e) != 0) { /* Avoid folding to -0. */ | 930 | if (expr_isnumk(e) && !expr_numiszero(e)) { /* Avoid folding to -0. */ |
904 | e->u.nval.u64 ^= U64x(80000000,00000000); | 931 | TValue *o = expr_numtv(e); |
905 | return; | 932 | if (tvisint(o)) { |
933 | int32_t k = intV(o); | ||
934 | if (k == -k) | ||
935 | setnumV(o, -(lua_Number)k); | ||
936 | else | ||
937 | setintV(o, -k); | ||
938 | } else { | ||
939 | o->u64 ^= U64x(80000000,00000000); | ||
940 | return; | ||
941 | } | ||
906 | } | 942 | } |
907 | } | 943 | } |
908 | expr_toanyreg(fs, e); | 944 | expr_toanyreg(fs, e); |
@@ -986,7 +1022,7 @@ static void var_new(LexState *ls, BCReg n, GCstr *name) | |||
986 | static void var_add(LexState *ls, BCReg nvars) | 1022 | static void var_add(LexState *ls, BCReg nvars) |
987 | { | 1023 | { |
988 | FuncState *fs = ls->fs; | 1024 | FuncState *fs = ls->fs; |
989 | fs->nactvar = cast_byte(fs->nactvar + nvars); | 1025 | fs->nactvar = (uint8_t)(fs->nactvar + nvars); |
990 | for (; nvars; nvars--) | 1026 | for (; nvars; nvars--) |
991 | var_get(ls, fs, fs->nactvar - nvars).startpc = fs->pc; | 1027 | var_get(ls, fs, fs->nactvar - nvars).startpc = fs->pc; |
992 | } | 1028 | } |
@@ -1094,16 +1130,33 @@ static void fs_fixup_k(FuncState *fs, GCproto *pt, void *kptr) | |||
1094 | kt = fs->kt; | 1130 | kt = fs->kt; |
1095 | array = tvref(kt->array); | 1131 | array = tvref(kt->array); |
1096 | for (i = 0; i < kt->asize; i++) | 1132 | for (i = 0; i < kt->asize; i++) |
1097 | if (tvisnum(&array[i])) | 1133 | if (tvhaskslot(&array[i])) { |
1098 | ((lua_Number *)kptr)[array[i].u32.lo] = cast_num(i); | 1134 | TValue *tv = &((TValue *)kptr)[tvkslot(&array[i])]; |
1135 | if (LJ_DUALNUM) | ||
1136 | setintV(tv, (int32_t)i); | ||
1137 | else | ||
1138 | setnumV(tv, (lua_Number)i); | ||
1139 | } | ||
1099 | node = noderef(kt->node); | 1140 | node = noderef(kt->node); |
1100 | hmask = kt->hmask; | 1141 | hmask = kt->hmask; |
1101 | for (i = 0; i <= hmask; i++) { | 1142 | for (i = 0; i <= hmask; i++) { |
1102 | Node *n = &node[i]; | 1143 | Node *n = &node[i]; |
1103 | if (tvisnum(&n->val)) { | 1144 | if (tvhaskslot(&n->val)) { |
1104 | ptrdiff_t kidx = (ptrdiff_t)n->val.u32.lo; | 1145 | ptrdiff_t kidx = (ptrdiff_t)tvkslot(&n->val); |
1146 | lua_assert(!tvisint(&n->key)); | ||
1105 | if (tvisnum(&n->key)) { | 1147 | if (tvisnum(&n->key)) { |
1106 | ((lua_Number *)kptr)[kidx] = numV(&n->key); | 1148 | TValue *tv = &((TValue *)kptr)[kidx]; |
1149 | if (LJ_DUALNUM) { | ||
1150 | lua_Number nn = numV(&n->key); | ||
1151 | int32_t k = lj_num2int(nn); | ||
1152 | lua_assert(!tvismzero(&n->key)); | ||
1153 | if ((lua_Number)k == nn) | ||
1154 | setintV(tv, k); | ||
1155 | else | ||
1156 | *tv = n->key; | ||
1157 | } else { | ||
1158 | *tv = n->key; | ||
1159 | } | ||
1107 | } else { | 1160 | } else { |
1108 | GCobj *o = gcV(&n->key); | 1161 | GCobj *o = gcV(&n->key); |
1109 | setgcref(((GCRef *)kptr)[~kidx], o); | 1162 | setgcref(((GCRef *)kptr)[~kidx], o); |
@@ -1286,12 +1339,22 @@ static void expr_index(FuncState *fs, ExpDesc *t, ExpDesc *e) | |||
1286 | /* Already called: expr_toval(fs, e). */ | 1339 | /* Already called: expr_toval(fs, e). */ |
1287 | t->k = VINDEXED; | 1340 | t->k = VINDEXED; |
1288 | if (expr_isnumk(e)) { | 1341 | if (expr_isnumk(e)) { |
1289 | lua_Number n = expr_numV(e); | 1342 | #if LJ_DUALNUM |
1343 | if (tvisint(expr_numtv(e))) { | ||
1344 | int32_t k = intV(expr_numtv(e)); | ||
1345 | if (checku8(k)) { | ||
1346 | t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */ | ||
1347 | return; | ||
1348 | } | ||
1349 | } | ||
1350 | #else | ||
1351 | lua_Number n = expr_numberV(e); | ||
1290 | int32_t k = lj_num2int(n); | 1352 | int32_t k = lj_num2int(n); |
1291 | if (checku8(k) && n == cast_num(k)) { | 1353 | if (checku8(k) && n == (lua_Number)k) { |
1292 | t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */ | 1354 | t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */ |
1293 | return; | 1355 | return; |
1294 | } | 1356 | } |
1357 | #endif | ||
1295 | } else if (expr_isstrk(e)) { | 1358 | } else if (expr_isstrk(e)) { |
1296 | BCReg idx = const_str(fs, e); | 1359 | BCReg idx = const_str(fs, e); |
1297 | if (idx <= BCMAX_C) { | 1360 | if (idx <= BCMAX_C) { |
@@ -1331,8 +1394,8 @@ static void expr_kvalue(TValue *v, ExpDesc *e) | |||
1331 | setgcref(v->gcr, obj2gco(e->u.sval)); | 1394 | setgcref(v->gcr, obj2gco(e->u.sval)); |
1332 | setitype(v, LJ_TSTR); | 1395 | setitype(v, LJ_TSTR); |
1333 | } else { | 1396 | } else { |
1334 | lua_assert(e->k == VKNUM); | 1397 | lua_assert(tvisnumber(expr_numtv(e))); |
1335 | setnumV(v, expr_numV(e)); | 1398 | *v = *expr_numtv(e); |
1336 | } | 1399 | } |
1337 | } | 1400 | } |
1338 | 1401 | ||
@@ -1357,7 +1420,7 @@ static void expr_table(LexState *ls, ExpDesc *e) | |||
1357 | if (ls->token == '[') { | 1420 | if (ls->token == '[') { |
1358 | expr_bracket(ls, &key); /* Already calls expr_toval. */ | 1421 | expr_bracket(ls, &key); /* Already calls expr_toval. */ |
1359 | if (!expr_isk(&key)) expr_index(fs, e, &key); | 1422 | if (!expr_isk(&key)) expr_index(fs, e, &key); |
1360 | if (expr_isnumk(&key) && expr_numV(&key) == 0) needarr = 1; else nhash++; | 1423 | if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++; |
1361 | lex_check(ls, '='); | 1424 | lex_check(ls, '='); |
1362 | } else if (ls->token == TK_name && lj_lex_lookahead(ls) == '=') { | 1425 | } else if (ls->token == TK_name && lj_lex_lookahead(ls) == '=') { |
1363 | expr_str(ls, &key); | 1426 | expr_str(ls, &key); |
@@ -2119,10 +2182,10 @@ static int predict_next(LexState *ls, FuncState *fs, BCPos pc) | |||
2119 | case BC_GGET: | 2182 | case BC_GGET: |
2120 | /* There's no inverse index (yet), so lookup the strings. */ | 2183 | /* There's no inverse index (yet), so lookup the strings. */ |
2121 | o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "pairs")); | 2184 | o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "pairs")); |
2122 | if (o && tvisnum(o) && o->u32.lo == bc_d(ins)) | 2185 | if (o && tvhaskslot(o) && tvkslot(o) == bc_d(ins)) |
2123 | return 1; | 2186 | return 1; |
2124 | o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "next")); | 2187 | o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "next")); |
2125 | if (o && tvisnum(o) && o->u32.lo == bc_d(ins)) | 2188 | if (o && tvhaskslot(o) && tvkslot(o) == bc_d(ins)) |
2126 | return 1; | 2189 | return 1; |
2127 | return 0; | 2190 | return 0; |
2128 | default: | 2191 | default: |