asm.js verifies again.

This commit is contained in:
Brad Nelson
2021-01-13 19:37:59 -08:00
parent ea2fec02e9
commit 222a51826f
4 changed files with 90 additions and 63 deletions

View File

@ -4,6 +4,7 @@
#include <string.h> #include <string.h>
typedef intptr_t cell_t; typedef intptr_t cell_t;
typedef uintptr_t ucell_t;
#if __SIZEOF_POINTER__ == 8 #if __SIZEOF_POINTER__ == 8
typedef __int128_t dcell_t; typedef __int128_t dcell_t;
typedef __uint128_t udcell_t; typedef __uint128_t udcell_t;
@ -29,57 +30,54 @@ typedef uint64_t udcell_t;
#define OPCODE_LIST \ #define OPCODE_LIST \
X("0=", ZEQUAL, tos = !tos ? -1 : 0) \ X("0=", ZEQUAL, tos = !tos ? -1 : 0) \
X("0<", ZLESS, tos = (tos|0) < 0 ? -1 : 0) \ X("0<", ZLESS, tos = (tos|0) < 0 ? -1 : 0) \
X("+", PLUS, tos = (tos + *sp) | 0; --sp) \ X("+", PLUS, tos += *sp--) \
X("U/MOD", USMOD, w = *sp; *sp = (uintptr_t) w % (uintptr_t) tos; \ X("U/MOD", USMOD, w = *sp; *sp = (ucell_t) w % (ucell_t) tos; \
tos = (uintptr_t) w / tos) \ tos = (ucell_t) w / (ucell_t) tos) \
X("*/MOD", SSMOD, SSMOD_FUNC) \ X("*/MOD", SSMOD, SSMOD_FUNC) \
X("AND", AND, tos = tos & *sp; --sp) \ X("AND", AND, tos &= *sp--) \
X("OR", OR, tos = tos | *sp; --sp) \ X("OR", OR, tos |= *sp--) \
X("XOR", XOR, tos = tos ^ *sp; --sp) \ X("XOR", XOR, tos ^= *sp--) \
X("DUP", DUP, DUP) \ X("DUP", DUP, DUP) \
X("SWAP", SWAP, w = tos; tos = (*sp)|0; *sp = w) \ X("SWAP", SWAP, w = tos; tos = *sp; *sp = w) \
X("OVER", OVER, DUP; tos = sp[-1] | 0) \ X("OVER", OVER, DUP; tos = sp[-1]) \
X("DROP", DROP, DROP) \ X("DROP", DROP, DROP) \
X("@", AT, tos = (*(cell_t *) tos)|0) \ X("@", AT, tos = *(cell_t *) tos) \
X("L@", LAT, tos = (*(int32_t *) tos)|0) \ X("L@", LAT, tos = *(int32_t *) tos) \
X("C@", CAT, tos = (*(uint8_t *) tos)|0) \ X("C@", CAT, tos = *(uint8_t *) tos) \
X("!", STORE, *(cell_t *) tos = (*sp)|0; --sp; DROP) \ X("!", STORE, *(cell_t *) tos = *sp--; DROP) \
X("L!", LSTORE, *(int32_t *) tos = (*sp)|0; --sp; DROP) \ X("L!", LSTORE, *(int32_t *) tos = *sp--; DROP) \
X("C!", CSTORE, *(uint8_t *) tos = (*sp)|0; --sp; DROP) \ X("C!", CSTORE, *(uint8_t *) tos = *sp--; DROP) \
X("SP@", SPAT, DUP; tos = (cell_t) sp) \ X("SP@", SPAT, DUP; tos = (cell_t) sp) \
X("SP!", SPSTORE, sp = (cell_t *) tos; DROP) \ X("SP!", SPSTORE, sp = (cell_t *) tos; DROP) \
X("RP@", RPAT, DUP; tos = (cell_t) rp) \ X("RP@", RPAT, DUP; tos = (cell_t) rp) \
X("RP!", RPSTORE, rp = (cell_t *) tos; DROP) \ X("RP!", RPSTORE, rp = (cell_t *) tos; DROP) \
X(">R", TOR, ++rp; *rp = tos; DROP) \ X(">R", TOR, *++rp = tos; DROP) \
X("R>", FROMR, DUP; tos = (*rp)|0; --rp) \ X("R>", FROMR, DUP; tos = *rp; --rp) \
X("R@", RAT, DUP; tos = (*rp)|0) \ X("R@", RAT, DUP; tos = *rp) \
X("EXECUTE", EXECUTE, w = tos; DROP; goto **(void **) w) \ X("EXECUTE", EXECUTE, w = tos; DROP; goto **(void **) w) \
X("BRANCH", BRANCH, ip = (cell_t *) (*ip | 0)) \ X("BRANCH", BRANCH, ip = (cell_t *) *ip) \
X("0BRANCH", ZBRANCH, if (!tos) ip = (cell_t *) (*ip | 0); else ++ip; DROP) \ X("0BRANCH", ZBRANCH, if (!tos) ip = (cell_t *) *ip; else ++ip; DROP) \
X("DONEXT", DONEXT, *rp = ((*rp|0) - 1) | 0; \ X("DONEXT", DONEXT, *rp = *rp - 1; \
if (~(*rp|0)) ip = (cell_t *) (*ip | 0); else (--rp, ++ip)) \ if (~*rp) ip = (cell_t *) *ip; else (--rp, ++ip)) \
X("DOLIT", DOLIT, DUP; tos = (*ip | 0); ++ip) \ X("DOLIT", DOLIT, DUP; tos = *ip++) \
X("ALITERAL", ALITERAL, COMMA(g_sys.DOLIT_XT | 0); COMMA(tos | 0); DROP) \ X("ALITERAL", ALITERAL, COMMA(g_sys.DOLIT_XT); COMMA(tos); DROP) \
X("CELL", CELL, DUP; tos = sizeof(cell_t)) \ X("CELL", CELL, DUP; tos = sizeof(cell_t)) \
X("FIND", FIND, tos = find((const char *) (*sp | 0), tos|0)|0; --sp) \ X("FIND", FIND, tos = find((const char *) *sp, tos); --sp) \
X("PARSE", PARSE, DUP; tos = parse(tos|0, (cell_t *) ((cell_t) sp | 0))|0) \ X("PARSE", PARSE, DUP; tos = parse(tos, sp)) \
X("S>NUMBER?", CONVERT, \ X("S>NUMBER?", CONVERT, tos = convert((const char *) *sp, tos, sp); \
tos = convert((const char *) (*sp | 0), tos|0, (cell_t *) ((cell_t) sp | 0))|0; \
if (!tos) --sp) \ if (!tos) --sp) \
X("CREATE", CREATE, DUP; DUP; tos = parse(32, (cell_t *) ((cell_t) sp | 0))|0; \ X("CREATE", CREATE, DUP; DUP; tos = parse(32, sp); \
create((const char *) (*sp | 0), tos|0, 0, && OP_DOCREATE); \ create((const char *) *sp, tos, 0, && OP_DOCREATE); \
COMMA(0); --sp; DROP) \ COMMA(0); --sp; DROP) \
X("DOES>", DOES, DOES((cell_t *) ((cell_t) ip|0)); ip = (cell_t *) (*rp | 0); --rp) \ X("DOES>", DOES, DOES(ip); ip = (cell_t *) *rp; --rp) \
X("IMMEDIATE", IMMEDIATE, IMMEDIATE()) \ X("IMMEDIATE", IMMEDIATE, IMMEDIATE()) \
X("'SYS", SYS, DUP; tos = (cell_t) &g_sys) \ X("'SYS", SYS, DUP; tos = (cell_t) &g_sys) \
X("YIELD", YIELD, PARK; return) \ X("YIELD", YIELD, PARK; return) \
X(":", COLON, DUP; DUP; tos = parse(32, (cell_t *) ((cell_t) sp | 0))|0; \ X(":", COLON, DUP; DUP; tos = parse(32, sp); \
create((const char *) (*sp | 0), tos|0, 0, && OP_DOCOLON); \ create((const char *) *sp, tos, 0, && OP_DOCOLON); \
g_sys.state = -1; --sp; DROP) \ g_sys.state = -1; --sp; DROP) \
X("EVALUATE1", EVALUATE1, \ X("EVALUATE1", EVALUATE1, DUP; sp = evaluate1(sp); w = *sp--; DROP; \
DUP; sp = (cell_t *) ((cell_t) evaluate1((cell_t *) ((cell_t) sp | 0))|0); \
w = (*sp | 0); --sp; DROP; \
if (w) goto **(void **) w) \ if (w) goto **(void **) w) \
X("EXIT", EXIT, ip = (cell_t *) (*rp | 0); --rp) \ X("EXIT", EXIT, ip = (cell_t *) *rp--) \
X(";", SEMICOLON, COMMA(g_sys.DOEXIT_XT | 0); g_sys.state = 0) \ X(";", SEMICOLON, COMMA(g_sys.DOEXIT_XT); g_sys.state = 0) \

View File

@ -18,7 +18,8 @@ enum {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
if (argc == 2 && strcmp(argv[1], "cases") == 0) { if (argc == 2 && strcmp(argv[1], "cases") == 0) {
#define X(name, op, code) printf(" case %d: %s; break;\n", OP_ ## op, #code); #define X(name, op, code) \
printf(" case %d: // %s\n %s; break;\n", OP_ ## op, name, #code);
PLATFORM_OPCODE_LIST PLATFORM_OPCODE_LIST
OPCODE_LIST OPCODE_LIST
#undef X #undef X

View File

@ -16,34 +16,54 @@ function ReplaceAll(haystack, needle, replacement) {
} }
} }
cases = ReplaceAll(cases, 'DROP', 'tos = i32[sp>>2] | 0; sp = (sp - 4) | 0'); cases = ReplaceAll(cases, 'DROP', 'tos = *sp--');
cases = ReplaceAll(cases, 'DUP', 'sp = (sp + 4) | 0; i32[sp>>2] = tos'); cases = ReplaceAll(cases, 'DUP', '*++sp = tos');
cases = ReplaceAll(cases, '*(cell_t *) tos', 'i32[tos>>2]'); cases = ReplaceAll(cases, 'tos += *sp--', 'tos = (tos + *sp)|0; --sp');
cases = ReplaceAll(cases, '*(int32_t *) tos', 'i32[tos>>2]'); cases = ReplaceAll(cases, /tos (.)= /, 'tos = tos $1 ');
cases = ReplaceAll(cases, '*(uint8_t *) tos', 'u8[tos]'); cases = ReplaceAll(cases, /[*](.)p[+][+]/, '*$1p; ++$1p');
cases = ReplaceAll(cases, '*sp', 'i32[sp>>2]'); cases = ReplaceAll(cases, /[*](.)p[-][-]/, '*$1p; --$1p');
cases = ReplaceAll(cases, '*rp', 'i32[rp>>2]'); cases = ReplaceAll(cases, /[*][+][+](.)p/, '++$1p; *$1p');
cases = ReplaceAll(cases, '*ip', 'i32[ip>>2]'); cases = ReplaceAll(cases, '*(cell_t *) tos = ', 'i32[tos>>2] = ');
cases = ReplaceAll(cases, 'sp[-1]', 'i32[(sp - 4)>>2]'); cases = ReplaceAll(cases, '*(int32_t *) tos = ', 'i32[tos>>2] = ');
cases = ReplaceAll(cases, '++ip', 'ip = (ip + 4) | 0'); cases = ReplaceAll(cases, '*(uint8_t *) tos = ', 'u8[tos] = ');
cases = ReplaceAll(cases, '++sp', 'sp = (sp + 4) | 0'); cases = ReplaceAll(cases, '*(cell_t *) tos', '(i32[tos>>2]|0)');
cases = ReplaceAll(cases, '++rp', 'rp = (rp + 4) | 0'); cases = ReplaceAll(cases, '*(int32_t *) tos', '(i32[tos>>2]|0)');
cases = ReplaceAll(cases, '--sp', 'sp = (sp - 4) | 0'); cases = ReplaceAll(cases, '*(uint8_t *) tos', '(u8[tos]|0)');
cases = ReplaceAll(cases, '--rp', 'rp = (rp - 4) | 0'); cases = ReplaceAll(cases, /[*](.)p = /, 'i32[$1p>>2] = ');
cases = ReplaceAll(cases, 'sp[-1] = ', 'i32[(sp - 4)>>2] = ');
cases = ReplaceAll(cases, /[*](.)p/, '(i32[$1p>>2]|0)');
cases = ReplaceAll(cases, 'sp[-1]', '(i32[(sp - 4)>>2]|0)');
cases = ReplaceAll(cases, /([+-]).(.)p/, '$2p = ($2p $1 4) | 0');
cases = ReplaceAll(cases, 'sp -= 2', 'sp = (sp - 8) | 0'); cases = ReplaceAll(cases, 'sp -= 2', 'sp = (sp - 8) | 0');
cases = ReplaceAll(cases, 'sizeof(cell_t)', '4'); cases = ReplaceAll(cases, 'sizeof(cell_t)', '4');
cases = ReplaceAll(cases, '(void *) ', ''); cases = ReplaceAll(cases, '(void *) ', '');
cases = ReplaceAll(cases, '(const char *) ', ''); cases = ReplaceAll(cases, '(const char *) ', '');
cases = ReplaceAll(cases, '(cell_t *) ', ''); cases = ReplaceAll(cases, '(cell_t *) ', '');
cases = ReplaceAll(cases, '(cell_t) ', ''); cases = ReplaceAll(cases, '(cell_t) ', '');
cases = ReplaceAll(cases, /[(]ucell_t[)] ([^ ;]+)/, '($1>>>0)');
cases = ReplaceAll(cases, 'g_sys.state', 'i32[(i32[g_sys>>2] + (3 * 4))>>2]'); cases = ReplaceAll(cases, 'g_sys.state', 'i32[(i32[g_sys>>2] + (3 * 4))>>2]');
cases = ReplaceAll(cases, 'g_sys.DOLIT_XT', 'i32[(i32[g_sys>>2] + (10 * 4))>>2]'); cases = ReplaceAll(cases, 'g_sys.DOLIT_XT', 'i32[(i32[g_sys>>2] + (10 * 4))>>2]|0');
cases = ReplaceAll(cases, 'g_sys.DOEXIT_XT', 'i32[(i32[g_sys>>2] + (11 * 4))>>2]'); cases = ReplaceAll(cases, 'g_sys.DOEXIT_XT', 'i32[(i32[g_sys>>2] + (11 * 4))>>2]|0');
cases = ReplaceAll(cases, '&g_sys', 'g_sys'); cases = ReplaceAll(cases, '&g_sys', 'g_sys');
cases = ReplaceAll(cases, '&& OP_DOCOLON', '0'); cases = ReplaceAll(cases, '&& OP_DOCOLON', '0');
cases = ReplaceAll(cases, '&& OP_DOCREATE', '1'); cases = ReplaceAll(cases, '&& OP_DOCREATE', '1');
cases = ReplaceAll(cases, 'goto **(void **) w', 'break decode'); cases = ReplaceAll(cases, 'goto **(void **) w', 'break decode');
cases = ReplaceAll(cases, 'SSMOD', ''); cases = ReplaceAll(cases, 'SSMOD_FUNC', '');
// Keep Together vvv
cases = ReplaceAll(cases, /tos ([^=]?)= /, 'txx $1= ');
cases = ReplaceAll(cases, ' tos', ' (tos|0)');
cases = ReplaceAll(cases, /txx ([^=]?)= /, 'tos $1= ');
// Keep Together ^^^
cases = ReplaceAll(cases, ' (w>>>0) / (tos>>>0)', ' ((w>>>0) / (tos>>>0))|0');
cases = ReplaceAll(cases, 'COMMA(tos)', 'COMMA(tos|0)');
cases = ReplaceAll(cases, /find\(([^\n]+)\);/, 'find($1)|0;');
cases = ReplaceAll(cases, 'tos = parse(tos, sp)', 'tos = parse(tos|0, sp|0)|0');
cases = ReplaceAll(cases, 'tos = parse(32, sp)', 'tos = parse(32, sp|0)|0');
cases = ReplaceAll(cases, 'sp = evaluate1(sp)', 'sp = evaluate1(sp|0)|0');
cases = ReplaceAll(cases, /convert\(([^\n]+), sp\)/, 'convert($1, sp|0)|0');
cases = ReplaceAll(cases, 'DOES(ip)', 'DOES(ip|0)');
cases = ReplaceAll(cases, 'PARK;', ''); // TODO
cases = ReplaceAll(cases, '; ', ';\n ');
code = code.replace('{{boot}}', function() { return boot; }); code = code.replace('{{boot}}', function() { return boot; });
code = code.replace('{{dict}}', function() { return dict; }); code = code.replace('{{dict}}', function() { return dict; });

View File

@ -79,14 +79,22 @@ function VM(stdlib, foreign, heap) {
ip = (ip + 4)|0; ip = (ip + 4)|0;
switch (ir&0xff) { switch (ir&0xff) {
case 0: // OP_DOCOLON case 0: // OP_DOCOLON
rp = (rp + 4) | 0; i32[rp>>2] = ip; ip = (w + 4) | 0; rp = (rp + 4) | 0;
i32[rp>>2] = ip;
ip = (w + 4) | 0;
break; break;
case 1: // OP_DOCREATE case 1: // OP_DOCREATE
sp = (sp + 4) | 0; i32[sp>>2] = tos; tos = (w + 8) | 0; // 4 * 2 sp = (sp + 4) | 0;
i32[sp>>2] = tos;
tos = (w + 8) | 0; // 4 * 2
break; break;
case 2: // OP_DODOES case 2: // OP_DODOES
sp = (sp + 4) | 0; i32[sp>>2] = tos; tos = (w + 8) | 0; // 4 * 2 sp = (sp + 4) | 0;
rp = (rp + 4) | 0; i32[rp>>2] = ip; ip = i32[(w + 4)>>2] | 0; i32[sp>>2] = tos;
tos = (w + 8) | 0; // 4 * 2
rp = (rp + 4) | 0;
i32[rp>>2] = ip;
ip = i32[(w + 4)>>2] | 0;
break; break;
{{cases}} {{cases}}
} }