Refining asm.js version.
This commit is contained in:
@ -143,14 +143,13 @@ static void finish(void) {
|
|||||||
static void create(const char *name, cell_t nlength, cell_t flags, void *op) {
|
static void create(const char *name, cell_t nlength, cell_t flags, void *op) {
|
||||||
finish();
|
finish();
|
||||||
g_sys->heap = (cell_t *) CELL_ALIGNED(g_sys->heap);
|
g_sys->heap = (cell_t *) CELL_ALIGNED(g_sys->heap);
|
||||||
char *pos = (char *) g_sys->heap;
|
for (cell_t n = nlength; n; --n) { CCOMMA(*name++); } // name
|
||||||
for (cell_t n = nlength; n; --n) { *pos++ = *name++; } // name
|
g_sys->heap = (cell_t *) CELL_ALIGNED(g_sys->heap);
|
||||||
g_sys->heap += CELL_LEN(nlength);
|
COMMA(*g_sys->current); // link
|
||||||
*g_sys->heap++ = (cell_t) *g_sys->current; // link
|
COMMA((nlength << 8) | flags); // flags & length
|
||||||
*g_sys->heap++ = (nlength << 8) | flags; // flags & length
|
|
||||||
*g_sys->current = g_sys->heap;
|
*g_sys->current = g_sys->heap;
|
||||||
g_sys->latestxt = g_sys->heap;
|
g_sys->latestxt = g_sys->heap;
|
||||||
*g_sys->heap++ = (cell_t) op; // code
|
COMMA(op); // code
|
||||||
}
|
}
|
||||||
|
|
||||||
static int match(char sep, char ch) {
|
static int match(char sep, char ch) {
|
||||||
@ -181,7 +180,7 @@ static cell_t *evaluate1(cell_t *rp) {
|
|||||||
cell_t xt = find((const char *) name, len);
|
cell_t xt = find((const char *) name, len);
|
||||||
if (xt) {
|
if (xt) {
|
||||||
if (g_sys->state && !(((cell_t *) xt)[-1] & IMMEDIATE)) {
|
if (g_sys->state && !(((cell_t *) xt)[-1] & IMMEDIATE)) {
|
||||||
*g_sys->heap++ = xt;
|
COMMA(xt);
|
||||||
} else {
|
} else {
|
||||||
call = xt;
|
call = xt;
|
||||||
}
|
}
|
||||||
@ -189,8 +188,8 @@ static cell_t *evaluate1(cell_t *rp) {
|
|||||||
cell_t n;
|
cell_t n;
|
||||||
if (convert((const char *) name, len, g_sys->base, &n)) {
|
if (convert((const char *) name, len, g_sys->base, &n)) {
|
||||||
if (g_sys->state) {
|
if (g_sys->state) {
|
||||||
*g_sys->heap++ = g_sys->DOLIT_XT;
|
COMMA(g_sys->DOLIT_XT);
|
||||||
*g_sys->heap++ = n;
|
COMMA(n);
|
||||||
} else {
|
} else {
|
||||||
PUSH n;
|
PUSH n;
|
||||||
}
|
}
|
||||||
@ -198,7 +197,7 @@ static cell_t *evaluate1(cell_t *rp) {
|
|||||||
float f;
|
float f;
|
||||||
if (fconvert((const char *) name, len, &f)) {
|
if (fconvert((const char *) name, len, &f)) {
|
||||||
if (g_sys->state) {
|
if (g_sys->state) {
|
||||||
*g_sys->heap++ = g_sys->DOFLIT_XT;
|
COMMA(g_sys->DOFLIT_XT);
|
||||||
*(float *) g_sys->heap++ = f;
|
*(float *) g_sys->heap++ = f;
|
||||||
} else {
|
} else {
|
||||||
*++fp = f;
|
*++fp = f;
|
||||||
@ -243,13 +242,13 @@ static void forth_init(int argc, char *argv[],
|
|||||||
|
|
||||||
// FORTH worldlist (relocated when vocabularies added).
|
// FORTH worldlist (relocated when vocabularies added).
|
||||||
cell_t *forth_wordlist = g_sys->heap;
|
cell_t *forth_wordlist = g_sys->heap;
|
||||||
*g_sys->heap++ = 0;
|
COMMA(0);
|
||||||
// Vocabulary stack.
|
// Vocabulary stack.
|
||||||
g_sys->current = (cell_t **) forth_wordlist;
|
g_sys->current = (cell_t **) forth_wordlist;
|
||||||
g_sys->context = (cell_t ***) g_sys->heap;
|
g_sys->context = (cell_t ***) g_sys->heap;
|
||||||
g_sys->latestxt = 0;
|
g_sys->latestxt = 0;
|
||||||
*g_sys->heap++ = (cell_t) forth_wordlist;
|
COMMA(forth_wordlist);
|
||||||
for (int i = 0; i < VOCABULARY_DEPTH; ++i) { *g_sys->heap++ = 0; }
|
for (int i = 0; i < VOCABULARY_DEPTH; ++i) { COMMA(0); }
|
||||||
|
|
||||||
// Setup boot text.
|
// Setup boot text.
|
||||||
g_sys->boot = src;
|
g_sys->boot = src;
|
||||||
@ -259,7 +258,7 @@ static void forth_init(int argc, char *argv[],
|
|||||||
#define V(name) \
|
#define V(name) \
|
||||||
create(#name "-builtins", sizeof(#name "-builtins") - 1, \
|
create(#name "-builtins", sizeof(#name "-builtins") - 1, \
|
||||||
BUILTIN_FORK, g_sys->DOCREATE_OP); \
|
BUILTIN_FORK, g_sys->DOCREATE_OP); \
|
||||||
*g_sys->heap++ = VOC_ ## name;
|
COMMA(VOC_ ## name);
|
||||||
VOCABULARY_LIST
|
VOCABULARY_LIST
|
||||||
#undef V
|
#undef V
|
||||||
g_sys->latestxt = 0; // So last builtin doesn't get wrong size.
|
g_sys->latestxt = 0; // So last builtin doesn't get wrong size.
|
||||||
@ -271,9 +270,9 @@ static void forth_init(int argc, char *argv[],
|
|||||||
|
|
||||||
// Init code.
|
// Init code.
|
||||||
cell_t *start = g_sys->heap;
|
cell_t *start = g_sys->heap;
|
||||||
*g_sys->heap++ = FIND("EVALUATE1");
|
COMMA(FIND("EVALUATE1"));
|
||||||
*g_sys->heap++ = FIND("BRANCH");
|
COMMA(FIND("BRANCH"));
|
||||||
*g_sys->heap++ = (cell_t) start;
|
COMMA(start);
|
||||||
|
|
||||||
g_sys->argc = argc;
|
g_sys->argc = argc;
|
||||||
g_sys->argv = argv;
|
g_sys->argv = argv;
|
||||||
|
|||||||
@ -46,7 +46,7 @@ typedef uintptr_t ucell_t;
|
|||||||
(void *) *((cell_t *) xt) == ADDROF(DODOES) ? 2 : 1))
|
(void *) *((cell_t *) xt) == ADDROF(DODOES) ? 2 : 1))
|
||||||
|
|
||||||
#ifndef COMMA
|
#ifndef COMMA
|
||||||
# define COMMA(n) *g_sys->heap++ = (n)
|
# define COMMA(n) *g_sys->heap++ = (cell_t) (n)
|
||||||
# define CCOMMA(n) *(uint8_t *) g_sys->heap = (n); \
|
# define CCOMMA(n) *(uint8_t *) g_sys->heap = (n); \
|
||||||
g_sys->heap = (cell_t *) (1 + ((cell_t) g_sys->heap));
|
g_sys->heap = (cell_t *) (1 + ((cell_t) g_sys->heap));
|
||||||
# define DOES(ip) **g_sys->current = (cell_t) ADDROF(DODOES); (*g_sys->current)[1] = (cell_t) ip
|
# define DOES(ip) **g_sys->current = (cell_t) ADDROF(DODOES); (*g_sys->current)[1] = (cell_t) ip
|
||||||
|
|||||||
@ -58,12 +58,12 @@ int main(int argc, char *argv[]) {
|
|||||||
#undef Z
|
#undef Z
|
||||||
} else if (argc == 2 && strcmp(argv[1], "dict") == 0) {
|
} else if (argc == 2 && strcmp(argv[1], "dict") == 0) {
|
||||||
#define V(name) \
|
#define V(name) \
|
||||||
printf(" create(\"" #name "-builtins\", %d);\n", BUILTIN_FORK, OP_DOCREATE); \
|
printf(" Create(\"" #name "-builtins\", %d);\n", BUILTIN_FORK, OP_DOCREATE); \
|
||||||
printf(" comma(%d);\n", VOC_ ## name);
|
printf(" COMMA(%d);\n", VOC_ ## name);
|
||||||
VOCABULARY_LIST
|
VOCABULARY_LIST
|
||||||
#undef V
|
#undef V
|
||||||
#define Z(flags, name, op, code) \
|
#define Z(flags, name, op, code) \
|
||||||
printf(" builtin(" #name ", %d, %d, %d);\n", \
|
printf(" Builtin(" #name ", %d, %d, %d);\n", \
|
||||||
((VOC_ ## flags >> 8) & 0xff) | BUILTIN_MARK, \
|
((VOC_ ## flags >> 8) & 0xff) | BUILTIN_MARK, \
|
||||||
(VOC_ ## flags & 0xff), OP_ ## op);
|
(VOC_ ## flags & 0xff), OP_ ## op);
|
||||||
PLATFORM_OPCODE_LIST
|
PLATFORM_OPCODE_LIST
|
||||||
|
|||||||
@ -20,11 +20,18 @@ const HEAP_SIZE = (1024 * 1024);
|
|||||||
const STACK_CELLS = 4096;
|
const STACK_CELLS = 4096;
|
||||||
const VOCABULARY_DEPTH = 16;
|
const VOCABULARY_DEPTH = 16;
|
||||||
|
|
||||||
|
const IMMEDIATE = 1;
|
||||||
|
const SMUDGE = 2;
|
||||||
|
const BUILTIN_FORK = 4;
|
||||||
|
const BUILTIN_MARK = 8;
|
||||||
|
|
||||||
{{boot}}
|
{{boot}}
|
||||||
|
|
||||||
var heap = new ArrayBuffer(HEAP_SIZE);
|
var heap = new ArrayBuffer(HEAP_SIZE);
|
||||||
var i32 = new Int32Array(heap);
|
var i32 = new Int32Array(heap);
|
||||||
|
var u16 = new Uint16Array(heap);
|
||||||
var u8 = new Uint8Array(heap);
|
var u8 = new Uint8Array(heap);
|
||||||
|
var builtins = [];
|
||||||
var objects = [SetEval];
|
var objects = [SetEval];
|
||||||
|
|
||||||
{{sys}}
|
{{sys}}
|
||||||
@ -68,55 +75,126 @@ function Same(a, b) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function GetName(xt) {
|
function GetString(a, n) {
|
||||||
var clen = i32[(xt - 3*4)>>2];
|
|
||||||
var ret = '';
|
var ret = '';
|
||||||
for (var i = 0; i < clen; ++i) {
|
for (var i = 0; i < n; ++i) {
|
||||||
ret += String.fromCharCode(u8[xt - 3 * 4 - clen + i]);
|
ret += String.fromCharCode(u8[a + i]);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Find(name) {
|
|
||||||
var pos = i32[i32[g_sys_context>>2]>>2];
|
function CELL_ALIGNED(n) { return (n + 3) & ~3; }
|
||||||
while (pos) {
|
|
||||||
if (Same(GetName(pos), name)) {
|
function TOFLAGS(xt) { return xt - 4; }
|
||||||
return pos;
|
function TONAMELEN(xt) { return xt + 1; }
|
||||||
|
function TOPARAMS(xt) { return TOFLAGS(xt) + 2; }
|
||||||
|
function TOSIZE(xt) { return CELL_ALIGNED(u8[TONAMELEN(xt)>>2]) + 4 * i32[TOPARAMS(xt)>>2]; }
|
||||||
|
function TOLINK(xt) { return xt - 2; }
|
||||||
|
function TONAME(xt) {
|
||||||
|
return (i32[TOFLAGS(xt)] & BUILTIN_MARK)
|
||||||
|
? u8[TOLINK(xt)] : TOLINK(xt) - CELL_ALIGNED(u8[TONAMELEN(xt)]);
|
||||||
|
}
|
||||||
|
function TOBODY(xt) {
|
||||||
|
return xt + (i32[xt>>2] === OP_DOCREATE || i32[xt>>2] === OP_DODOES ? 2 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function BUILTIN_ITEM(i) {
|
||||||
|
return i32[g_sys_builtins>>2] + 4 * 3 * i;
|
||||||
|
}
|
||||||
|
function BUILTIN_NAME(i) {
|
||||||
|
return i32[(BUILTIN_ITEM(i) + 0 * 4)>>2];
|
||||||
|
}
|
||||||
|
function BUILTIN_FLAGS(i) {
|
||||||
|
return u8[BUILTIN_ITEM(i) + 1 * 4 + 0];
|
||||||
|
}
|
||||||
|
function BUILTIN_NAMELEN(i) {
|
||||||
|
return i32[BUILTIN_ITEM(i) + 1 * 4 + 1];
|
||||||
|
}
|
||||||
|
function BUILTIN_VOCAB(i) {
|
||||||
|
return u16[(BUILTIN_ITEM(i) + 1 * 4 + 2)>>1];
|
||||||
|
}
|
||||||
|
function BUILTIN_CODE(i) {
|
||||||
|
return BUILTIN_ITEM(i) + 2 * 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Find(name) {
|
||||||
|
for (var voc = i32[g_sys_context>>2]; i32[voc>>2]; voc += 4) {
|
||||||
|
var xt = i32[i32[voc>>2]>>2];
|
||||||
|
while (xt) {
|
||||||
|
if (u8[TOFLAGS(xt)] & BUILTIN_FORK) {
|
||||||
|
var vocab = i32[(TOLINK(xt) + 4 * 3)>>2];
|
||||||
|
for (var i = 0; BUILTIN_NAME(i); ++i) {
|
||||||
|
if (BUILTIN_VOCAB(i) === vocab &&
|
||||||
|
name.length === BUILTIN_NAMELEN(i) &&
|
||||||
|
name === GetString(BUILTIN_NAME(i), name.length)) {
|
||||||
|
return BUILTIN_CODE(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(u8[TOFLAGS(xt)] & SMUDGE) &&
|
||||||
|
name.length === u8[TONAMELEN(xt)] &&
|
||||||
|
name === GetString(TONAME(xt), name.length)) {
|
||||||
|
return xt;
|
||||||
|
}
|
||||||
|
xt = i32[TOLINK(xt)>>2];
|
||||||
}
|
}
|
||||||
pos = i32[(pos - 2*4)>>2];
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function comma(value) {
|
function COMMA(value) {
|
||||||
i32[i32[g_sys_heap>>2]>>2] = value;
|
i32[i32[g_sys_heap>>2]>>2] = value;
|
||||||
i32[g_sys_heap>>2] = (i32[g_sys_heap>>2] + 4) | 0;
|
i32[g_sys_heap>>2] += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
function create(name, flags, opcode) {
|
function CCOMMA(value) {
|
||||||
|
u8[i32[g_sys_heap>>2]>>2] = value;
|
||||||
|
i32[g_sys_heap>>2]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Finish() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
function Create(name, flags, op) {
|
||||||
|
Finish();
|
||||||
|
i32[g_sys_heap>>2] = CELL_ALIGNED(i32[g_sys_heap>>2]);
|
||||||
i32[g_sys_heap>>2] = Load(i32[g_sys_heap>>2], name); // name
|
i32[g_sys_heap>>2] = Load(i32[g_sys_heap>>2], name); // name
|
||||||
i32[g_sys_heap>>2] = (i32[g_sys_heap>>2] + 3) & ~3;
|
i32[g_sys_heap>>2] = CELL_ALIGNED(i32[g_sys_heap>>2]);
|
||||||
|
COMMA(i32[i32[g_sys_current>>2]>>2]); // link
|
||||||
i32[i32[g_sys_heap>>2]>>2] = name.length; // length
|
COMMA((name.length << 8) | flags); // flags & length
|
||||||
i32[g_sys_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_sys_heap>>2]>>2] = 0; // flags
|
|
||||||
i32[g_sys_heap>>2] += 4;
|
|
||||||
|
|
||||||
i32[i32[g_sys_current>>2]>>2] = i32[g_sys_heap>>2];
|
i32[i32[g_sys_current>>2]>>2] = i32[g_sys_heap>>2];
|
||||||
|
i32[g_sys_latestxt>>2] = i32[g_sys_heap>>2];
|
||||||
i32[i32[i32[g_sys_current>>2]>>2]>>2] = opcode; // code
|
COMMA(op);
|
||||||
i32[g_sys_heap>>2] += 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function builtin(name, flags, vocab, opcode) {
|
function Builtin(name, flags, vocab, opcode) {
|
||||||
|
builtins.push([name, flags | BUILTIN_MARK, vocab, opcode]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SetupBuiltins() {
|
||||||
|
for (var i = 0; i < builtins.length; ++i) {
|
||||||
|
var name = builtins[i][0];
|
||||||
|
builtins[i][0] = i32[g_sys_heap>>2];
|
||||||
|
i32[g_sys_heap>>2] = Load(i32[g_sys_heap>>2], name); // name
|
||||||
|
i32[g_sys_heap>>2] = CELL_ALIGNED(i32[g_sys_heap>>2]);
|
||||||
|
builtins[i][1] |= (name.length << 8);
|
||||||
|
}
|
||||||
|
i32[g_sys_builtins>>2] = i32[g_sys_heap>>2];
|
||||||
|
for (var i = 0; i < builtins.length; ++i) {
|
||||||
|
COMMA(builtins[i][0]);
|
||||||
|
COMMA(builtins[i][1] | (builtins[i][2] << 16));
|
||||||
|
COMMA(builtins[i][3]);
|
||||||
|
}
|
||||||
|
COMMA(0);
|
||||||
|
COMMA(0);
|
||||||
|
COMMA(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function InitDictionary() {
|
function InitDictionary() {
|
||||||
{{dict}}
|
{{dict}}
|
||||||
|
SetupBuiltins();
|
||||||
}
|
}
|
||||||
|
|
||||||
function Init() {
|
function Init() {
|
||||||
@ -135,13 +213,13 @@ function Init() {
|
|||||||
|
|
||||||
// FORTH worldlist (relocated when vocabularies added).
|
// FORTH worldlist (relocated when vocabularies added).
|
||||||
var forth_wordlist = i32[g_sys_heap>>2];
|
var forth_wordlist = i32[g_sys_heap>>2];
|
||||||
comma(0);
|
COMMA(0);
|
||||||
// Vocabulary stack.
|
// Vocabulary stack.
|
||||||
i32[g_sys_current>>2] = forth_wordlist;
|
i32[g_sys_current>>2] = forth_wordlist;
|
||||||
i32[g_sys_context>>2] = i32[g_sys_heap>>2];
|
i32[g_sys_context>>2] = i32[g_sys_heap>>2];
|
||||||
i32[g_sys_latestxt>>2] = 0;
|
i32[g_sys_latestxt>>2] = 0;
|
||||||
comma(forth_wordlist);
|
COMMA(forth_wordlist);
|
||||||
for (var i = 0; i < VOCABULARY_DEPTH; ++i) { comma(0); }
|
for (var i = 0; i < VOCABULARY_DEPTH; ++i) { COMMA(0); }
|
||||||
|
|
||||||
// setup boot text.
|
// setup boot text.
|
||||||
var source = g_sys_heap;
|
var source = g_sys_heap;
|
||||||
@ -160,9 +238,9 @@ function Init() {
|
|||||||
|
|
||||||
// Init code.
|
// Init code.
|
||||||
var start = i32[g_sys_heap>>2];
|
var start = i32[g_sys_heap>>2];
|
||||||
comma(Find("EVALUATE1"));
|
COMMA(Find("EVALUATE1"));
|
||||||
comma(Find("BRANCH"));
|
COMMA(Find("BRANCH"));
|
||||||
comma(start);
|
COMMA(start);
|
||||||
|
|
||||||
i32[g_sys_argc>>2] = 0;
|
i32[g_sys_argc>>2] = 0;
|
||||||
i32[g_sys_argv>>2] = 0;
|
i32[g_sys_argv>>2] = 0;
|
||||||
@ -170,10 +248,10 @@ function Init() {
|
|||||||
i32[g_sys_tib>>2] = source;
|
i32[g_sys_tib>>2] = source;
|
||||||
i32[g_sys_ntib>>2] = source_len;
|
i32[g_sys_ntib>>2] = source_len;
|
||||||
|
|
||||||
i32[rp>>2] = fp; rp += 4;
|
rp += 4; i32[rp>>2] = fp;
|
||||||
i32[rp>>2] = sp; rp += 4;
|
rp += 4; i32[rp>>2] = sp;
|
||||||
i32[rp>>2] = start; rp += 4;
|
rp += 4; i32[rp>>2] = start;
|
||||||
i32[g_sys_rp] = rp;
|
i32[g_sys_rp>>2] = rp;
|
||||||
}
|
}
|
||||||
|
|
||||||
function VM(stdlib, foreign, heap) {
|
function VM(stdlib, foreign, heap) {
|
||||||
@ -257,8 +335,8 @@ var ffi = {
|
|||||||
Call: Call,
|
Call: Call,
|
||||||
create: function() { console.log('create'); },
|
create: function() { console.log('create'); },
|
||||||
parse: function() { console.log('parse'); },
|
parse: function() { console.log('parse'); },
|
||||||
COMMA: function(n) { i32[i32[g_sys_heap>>2]] = n; i32[g_sys_heap>>2] += 4; console.log('comma'); },
|
COMMA: function(n) { COMMA(n); },
|
||||||
CCOMMA: function(n) { u8[i32[g_sys_heap>>2]] = n; i32[g_sys_heap>>2] += 1; console.log('ccomma'); },
|
CCOMMA: function(n) { COMMA(n); },
|
||||||
SSMOD: function() { console.log('ssmod'); },
|
SSMOD: function() { console.log('ssmod'); },
|
||||||
DOES: function() { console.log('does'); },
|
DOES: function() { console.log('does'); },
|
||||||
DOIMMEDIATE: function() { console.log('immediate'); },
|
DOIMMEDIATE: function() { console.log('immediate'); },
|
||||||
|
|||||||
Reference in New Issue
Block a user