diff --git a/common/core.h b/common/core.h index ce0b710..3e427db 100644 --- a/common/core.h +++ b/common/core.h @@ -250,12 +250,12 @@ static void forth_init(int argc, char *argv[], g_sys->heap_start = (cell_t *) heap; g_sys->heap_size = heap_size; g_sys->stack_cells = STACK_CELLS; - g_sys->boot = src; - g_sys->boot_size = src_len; // Start heap after G_SYS area. g_sys->heap = g_sys->heap_start + sizeof(G_SYS) / sizeof(cell_t); g_sys->heap += 4; // Leave a little room. + + // Allocate stacks. float *fp = (float *) (g_sys->heap + 1); g_sys->heap += STACK_CELLS; cell_t *rp = g_sys->heap + 1; g_sys->heap += STACK_CELLS; cell_t *sp = g_sys->heap + 1; g_sys->heap += STACK_CELLS; @@ -263,13 +263,17 @@ static void forth_init(int argc, char *argv[], // FORTH worldlist (relocated when vocabularies added). cell_t *forth_wordlist = g_sys->heap; *g_sys->heap++ = 0; - // Vocabulary stack + // Vocabulary stack. g_sys->current = (cell_t **) forth_wordlist; g_sys->context = (cell_t ***) g_sys->heap; g_sys->latestxt = 0; *g_sys->heap++ = (cell_t) forth_wordlist; for (int i = 0; i < VOCABULARY_DEPTH; ++i) { *g_sys->heap++ = 0; } + // Setup boot text. + g_sys->boot = src; + g_sys->boot_size = src_len; + forth_run(0); #define V(name) \ create(#name "-builtins", sizeof(#name "-builtins") - 1, \ @@ -283,15 +287,19 @@ static void forth_init(int argc, char *argv[], g_sys->DOEXIT_XT = FIND("EXIT"); g_sys->YIELD_XT = FIND("YIELD"); g_sys->notfound = FIND("DROP"); + + // Init code. cell_t *start = g_sys->heap; *g_sys->heap++ = FIND("EVALUATE1"); *g_sys->heap++ = FIND("BRANCH"); *g_sys->heap++ = (cell_t) start; + g_sys->argc = argc; g_sys->argv = argv; g_sys->base = 10; g_sys->tib = src; g_sys->ntib = src_len; + *++rp = (cell_t) fp; *++rp = (cell_t) sp; *++rp = (cell_t) start; diff --git a/web/dump_web_opcodes.c b/web/dump_web_opcodes.c index f3443c8..e70a843 100644 --- a/web/dump_web_opcodes.c +++ b/web/dump_web_opcodes.c @@ -55,7 +55,7 @@ int main(int argc, char *argv[]) { } else if (argc == 2 && strcmp(argv[1], "dict") == 0) { #define V(name) \ printf(" create(\"" #name "-builtins\", %d);\n", BUILTIN_FORK, OP_DOCREATE); \ - printf(" COMMA(%d);\n", VOC_ ## name); + printf(" comma(%d);\n", VOC_ ## name); VOCABULARY_LIST #undef V #define XV(flags, name, op, code) \ diff --git a/web/fuse_web.js b/web/fuse_web.js index 5f240ef..a257461 100755 --- a/web/fuse_web.js +++ b/web/fuse_web.js @@ -72,6 +72,7 @@ cases = ReplaceAll(cases, '(float) ', ''); cases = ReplaceAll(cases, '0.0f', '0.0'); cases = ReplaceAll(cases, /[(]ucell_t[)] ([^ ;)]+)/, '($1>>>0)'); cases = ReplaceAll(cases, '*(w + 4)', '((i32[w>>2]|0+4||0))'); +cases = ReplaceAll(cases, '&g_sys->builtins->code', '((i32[g_sys_builtins>>2] + 8)|0)'); cases = ReplaceAll(cases, /[&]g_sys[-][>]([A-Za-z_]+)/, 'g_sys_$1'); cases = ReplaceAll(cases, /g_sys[-][>]([A-Za-z_]+)/, 'i32[g_sys_$1>>2]'); cases = ReplaceAll(cases, '&& OP_DOCOL', '0'); diff --git a/web/web.template.js b/web/web.template.js index b12e8ac..dea3968 100644 --- a/web/web.template.js +++ b/web/web.template.js @@ -18,6 +18,7 @@ const HEAP_SIZE = (1024 * 1024); const STACK_CELLS = 4096; +const VOCABULARY_DEPTH = 16; {{boot}} @@ -101,7 +102,7 @@ function GetName(xt) { } function Find(name) { - var pos = i32[i32[g_context>>2]>>2]; + var pos = i32[i32[g_sys_context>>2]>>2]; while (pos) { if (Same(GetName(pos), name)) { return pos; @@ -111,23 +112,31 @@ function Find(name) { return 0; } -function create(name, opcode) { - i32[g_heap>>2] = Load(i32[g_heap>>2], name); // name - g_heap = (g_heap + 3) & ~3; +function comma(value) { + i32[i32[g_sys_heap>>2]>>2] = value; + i32[g_sys_heap>>2] = (i32[g_sys_heap>>2] + 4) | 0; +} - i32[i32[g_heap>>2]>>2] = name.length; // length - i32[g_heap>>2] += 4; +function create(name, flags, opcode) { + i32[g_sys_heap>>2] = Load(i32[g_sys_heap>>2], name); // name + g_sys_heap = (g_sys_heap + 3) & ~3; - i32[i32[g_heap>>2]>>2] = i32[i32[i32[g_current]>>2]>>2]; // link - i32[g_heap>>2] += 4; + i32[i32[g_sys_heap>>2]>>2] = name.length; // length + i32[g_sys_heap>>2] += 4; - i32[i32[g_heap>>2]>>2] = 0; // flags - i32[g_heap>>2] += 4; + i32[i32[g_sys_heap>>2]>>2] = i32[i32[i32[g_sys_current]>>2]>>2]; // link + i32[g_sys_heap>>2] += 4; - i32[i32[g_current>>2]>>2] = i32[g_heap>>2]; + i32[i32[g_sys_heap>>2]>>2] = 0; // flags + i32[g_sys_heap>>2] += 4; - i32[i32[i32[g_current>>2]>>2]>>2] = opcode; // code - i32[g_heap>>2] += 4; + i32[i32[g_sys_current>>2]>>2] = i32[g_sys_heap>>2]; + + i32[i32[i32[g_sys_current>>2]>>2]>>2] = opcode; // code + i32[g_sys_heap>>2] += 4; +} + +function builtin(name, flags, vocab, opcode) { } function InitDictionary() { @@ -135,31 +144,60 @@ function InitDictionary() { } function Init() { - i32[g_heap>>2] = g_sys + 16 * 4; - var source = g_heap; - i32[g_heap>>2] = Load(i32[g_heap>>2], boot); - var source_len = g_heap - source; + i32[g_sys_heap_start>>2] = 0; + i32[g_sys_heap_size>>2] = HEAP_SIZE; + i32[g_sys_stack_cells>>2] = STACK_CELLS; + + // Start heap after G_SYS area. + i32[g_sys_heap>>2] = i32[g_sys_heap_start>>2] + 256; + i32[g_sys_heap>>2] += 4; + + // Allocate stacks. + var fp = i32[g_sys_heap>>2] + 4; i32[g_sys_heap>>2] += STACK_CELLS * 4; + var rp = i32[g_sys_heap>>2] + 4; i32[g_sys_heap>>2] += STACK_CELLS * 4; + var sp = i32[g_sys_heap>>2] + 4; i32[g_sys_heap>>2] += STACK_CELLS * 4; + + // FORTH worldlist (relocated when vocabularies added). + var forth_wordlist = i32[g_sys_heap>>2]; + comma(0); + // Vocabulary stack. + i32[g_sys_current>>2] = forth_wordlist; + i32[g_sys_context>>2] = i32[g_sys_heap>>2]; + i32[g_sys_latestxt>>2] = 0; + comma(forth_wordlist); + for (var i = 0; i < VOCABULARY_DEPTH; ++i) { comma(0); } + + // setup boot text. + var source = g_sys_heap; + i32[g_sys_heap>>2] = Load(i32[g_sys_heap>>2], boot); + var source_len = g_sys_heap - source; + i32[g_sys_boot>>2] = source; + i32[g_sys_boot_size>>2] = source_len; InitDictionary(); - i32[g_sp>>2] = i32[g_heap>>2] + 1; - i32[g_heap>>2] += STACK_CELLS; - i32[g_rp>>2] = i32[g_heap>>2] + 1; - i32[g_heap>>2] += STACK_CELLS; - i32[((i32[g_current]>>2) - 4)>>2] = 1; // Make ; IMMMEDIATE - // Do not need DOLIT_XT, DOEXIT_XT, YIELD_XT (do by convention) - i32[g_notfound>>2] = Find('DROP'); - i32[g_ip>>2] = i32[g_heap>>2]; - i32[i32[g_heap>>2]>>2] = Find('EVALUATE1'); - i32[g_heap>>2] += 4; - i32[i32[g_heap>>2]>>2] = Find('BRANCH'); - i32[g_heap>>2] += 4; - i32[i32[g_heap>>2]>>2] = g_ip; - i32[g_heap>>2] += 4; - // argc, argv would have gone here. - i32[g_heap>>2] += 4; - i32[g_base>>2] = 10; - i32[g_tib>>2] = source; - i32[g_ntib>>2] = source_len; + + i32[g_sys_latestxt>>2] = 0; // So last builtin doesn't get wrong size. + i32[g_sys_DOLIT_XT>>2] = Find("DOLIT"); + i32[g_sys_DOFLIT_XT>>2] = Find("DOFLIT"); + i32[g_sys_DOEXIT_XT>>2] = Find("EXIT"); + i32[g_sys_YIELD_XT>>2] = Find("YIELD"); + + // Init code. + var start = i32[g_sys_heap>>2]; + comma(Find("EVALUATE1")); + comma(Find("BRANCH")); + comma(start); + + i32[g_sys_argc>>2] = 0; + i32[g_sys_argv>>2] = 0; + i32[g_sys_base>>2] = 10; + i32[g_sys_tib>>2] = source; + i32[g_sys_ntib>>2] = source_len; + + i32[rp>>2] = fp; rp += 4; + i32[rp>>2] = sp; rp += 4; + i32[rp>>2] = start; rp += 4; + i32[g_sys_rp] = rp; } function VM(stdlib, foreign, heap) { @@ -235,9 +273,12 @@ function VM(stdlib, foreign, heap) { var fp = 0; var w = 0; var ir = 0; - sp = i32[g_sp>>2]|0; - rp = i32[g_rp>>2]|0; - ip = i32[g_ip>>2]|0; + + // UNPARK + rp = i32[g_sys_rp>>2]|0; + ip = i32[rp>>2]|0; rp = (rp - 4)|0; + sp = i32[rp>>2]|0; rp = (rp - 4)|0; + fp = i32[rp>>2]|0; rp = (rp - 4)|0; tos = i32[sp>>2]|0; sp = (sp - 4)|0; for (;;) { w = i32[ip>>2]|0; @@ -247,27 +288,9 @@ function VM(stdlib, foreign, heap) { ir = u8[w]|0; log(ir|0); switch (ir&0xff) { - case 0: // OP_DOCOL - rp = (rp + 4) | 0; - i32[rp>>2] = ip; - ip = (w + 4) | 0; - break; - case 1: // OP_DOVAR - sp = (sp + 4) | 0; - i32[sp>>2] = tos; - tos = (w + 8) | 0; // 4 * 2 - break; - case 2: // OP_DODOES - sp = (sp + 4) | 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; {{cases}} default: - return; + break; } break; } @@ -280,8 +303,8 @@ var ffi = { Call: Call, create: function() { console.log('create'); }, parse: function() { console.log('parse'); }, - COMMA: function(n) { i32[i32[g_heap>>2]] = n; i32[g_heap>>2] += 4; console.log('comma'); }, - CCOMMA: function(n) { u8[i32[g_heap>>2]] = n; i32[g_heap>>2] += 1; console.log('ccomma'); }, + COMMA: function(n) { i32[i32[g_sys_heap>>2]] = n; i32[g_sys_heap>>2] += 4; console.log('comma'); }, + CCOMMA: function(n) { u8[i32[g_sys_heap>>2]] = n; i32[g_sys_heap>>2] += 1; console.log('ccomma'); }, SSMOD: function() { console.log('ssmod'); }, DOES: function() { console.log('does'); }, DOIMMEDIATE: function() { console.log('immediate'); },