Made interpreter reentrant.

This commit is contained in:
Brad Nelson
2021-01-29 22:11:47 -08:00
parent 62d427b1f0
commit b8c42111c3
7 changed files with 36 additions and 39 deletions

View File

@ -343,30 +343,24 @@ static cell_t ResizeFile(cell_t fd, cell_t size) {
#ifdef ENABLE_WEBSERVER_SUPPORT #ifdef ENABLE_WEBSERVER_SUPPORT
static void InvokeWebServerOn(WebServer *ws, const char *url, cell_t xt) { static void InvokeWebServerOn(WebServer *ws, const char *url, cell_t xt) {
ws->on(url, [xt]() { ws->on(url, [xt]() {
cell_t *old_ip = g_sys.ip;
cell_t *old_rp = g_sys.rp;
cell_t *old_sp = g_sys.sp;
cell_t stack[16];
cell_t rstack[16];
g_sys.sp = stack + 1;
g_sys.rp = rstack;
cell_t code[2]; cell_t code[2];
code[0] = xt; code[0] = xt;
code[1] = g_sys.YIELD_XT; code[1] = g_sys.YIELD_XT;
g_sys.ip = code; cell_t stack[16];
ueforth_run(); cell_t rstack[16];
g_sys.ip = old_ip; cell_t *rp = rstack;
g_sys.rp = old_rp; *++rp = (cell_t) (stack + 1);
g_sys.sp = old_sp; *++rp = (cell_t) code;
ueforth_run(rp);
}); });
} }
#endif #endif
void setup() { void setup() {
cell_t *heap = (cell_t *) malloc(HEAP_SIZE); cell_t *heap = (cell_t *) malloc(HEAP_SIZE);
ueforth(0, 0, heap, boot, sizeof(boot)); ueforth_init(0, 0, heap, boot, sizeof(boot));
} }
void loop() { void loop() {
ueforth_run(); g_sys.rp = ueforth_run(g_sys.rp);
} }

View File

@ -14,7 +14,7 @@ static struct {
cell_t *heap, *last, notfound; cell_t *heap, *last, notfound;
int argc; int argc;
char **argv; char **argv;
cell_t *ip, *sp, *rp; // Parked alternates cell_t *rp; // spot to park main thread
cell_t DOLIT_XT, DOEXIT_XT, YIELD_XT; cell_t DOLIT_XT, DOEXIT_XT, YIELD_XT;
} g_sys; } g_sys;
@ -120,30 +120,29 @@ static cell_t *evaluate1(cell_t *sp) {
return sp; return sp;
} }
static void ueforth_run(void); static cell_t *ueforth_run(cell_t *initrp);
static void ueforth(int argc, char *argv[], void *heap, static void ueforth_init(int argc, char *argv[], void *heap,
const char *src, cell_t src_len) { const char *src, cell_t src_len) {
g_sys.ip = 0;
g_sys.heap = (cell_t *) heap + 4; // Leave a little room. g_sys.heap = (cell_t *) heap + 4; // Leave a little room.
ueforth_run(); ueforth_run(0);
g_sys.sp = g_sys.heap + 1; g_sys.heap += STACK_SIZE; cell_t *sp = g_sys.heap + 1; g_sys.heap += STACK_SIZE;
g_sys.rp = g_sys.heap + 1; g_sys.heap += STACK_SIZE; cell_t *rp = g_sys.heap + 1; g_sys.heap += STACK_SIZE;
g_sys.last[-1] = 1; // Make ; IMMEDIATE g_sys.last[-1] = 1; // Make ; IMMEDIATE
g_sys.DOLIT_XT = FIND("DOLIT"); g_sys.DOLIT_XT = FIND("DOLIT");
g_sys.DOEXIT_XT = FIND("EXIT"); g_sys.DOEXIT_XT = FIND("EXIT");
g_sys.YIELD_XT = FIND("YIELD"); g_sys.YIELD_XT = FIND("YIELD");
g_sys.notfound = FIND("DROP"); g_sys.notfound = FIND("DROP");
g_sys.ip = g_sys.heap; cell_t *start = g_sys.heap;
*g_sys.heap++ = FIND("EVALUATE1"); *g_sys.heap++ = FIND("EVALUATE1");
*g_sys.heap++ = FIND("BRANCH"); *g_sys.heap++ = FIND("BRANCH");
*g_sys.heap++ = (cell_t) g_sys.ip; *g_sys.heap++ = (cell_t) start;
g_sys.argc = argc; g_sys.argc = argc;
g_sys.argv = argv; g_sys.argv = argv;
g_sys.base = 10; g_sys.base = 10;
g_sys.tib = src; g_sys.tib = src;
g_sys.ntib = src_len; g_sys.ntib = src_len;
for (;;) { *++rp = (cell_t) sp;
ueforth_run(); *++rp = (cell_t) start;
} g_sys.rp = rp;
} }

View File

@ -4,15 +4,16 @@
#define ADDR_DOCREATE && OP_DOCREATE #define ADDR_DOCREATE && OP_DOCREATE
#define ADDR_DODOES && OP_DODOES #define ADDR_DODOES && OP_DODOES
static void ueforth_run(void) { static cell_t *ueforth_run(cell_t *init_rp) {
if (!g_sys.ip) { if (!init_rp) {
#define X(name, op, code) create(name, sizeof(name) - 1, name[0] == ';', && OP_ ## op); #define X(name, op, code) create(name, sizeof(name) - 1, name[0] == ';', && OP_ ## op);
PLATFORM_OPCODE_LIST PLATFORM_OPCODE_LIST
OPCODE_LIST OPCODE_LIST
#undef X #undef X
return; return 0;
} }
register cell_t *ip = g_sys.ip, *rp = g_sys.rp, *sp = g_sys.sp, tos, w; register cell_t *ip, *rp, *sp, tos, w;
rp = init_rp; ip = (cell_t *) *rp--; sp = (cell_t *) *rp--;
DROP; NEXT; DROP; NEXT;
#define X(name, op, code) OP_ ## op: { code; } NEXT; #define X(name, op, code) OP_ ## op: { code; } NEXT;
PLATFORM_OPCODE_LIST PLATFORM_OPCODE_LIST

View File

@ -11,7 +11,7 @@ typedef uintptr_t ucell_t;
#define COMMA(n) *g_sys.heap++ = (n) #define COMMA(n) *g_sys.heap++ = (n)
#define IMMEDIATE() g_sys.last[-1] |= 1 #define IMMEDIATE() g_sys.last[-1] |= 1
#define DOES(ip) *g_sys.last = (cell_t) ADDR_DODOES; g_sys.last[1] = (cell_t) ip #define DOES(ip) *g_sys.last = (cell_t) ADDR_DODOES; g_sys.last[1] = (cell_t) ip
#define PARK DUP; g_sys.ip = ip; g_sys.rp = rp; g_sys.sp = sp #define PARK DUP; *++rp = (cell_t) sp; *++rp = (cell_t) ip
#ifndef SSMOD_FUNC #ifndef SSMOD_FUNC
# if __SIZEOF_POINTER__ == 8 # if __SIZEOF_POINTER__ == 8
@ -71,7 +71,7 @@ typedef int64_t dcell_t;
X("DOES>", DOES, DOES(ip); ip = (cell_t *) *rp; --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 rp) \
X(":", COLON, DUP; DUP; tos = parse(32, sp); \ X(":", COLON, DUP; DUP; tos = parse(32, sp); \
create((const char *) *sp, tos, 0, ADDR_DOCOLON); \ create((const char *) *sp, tos, 0, ADDR_DOCOLON); \
g_sys.state = -1; --sp; DROP) \ g_sys.state = -1; --sp; DROP) \

View File

@ -18,6 +18,7 @@
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
void *heap = mmap(0, HEAP_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); void *heap = mmap(0, HEAP_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
ueforth(argc, argv, heap, boot, sizeof(boot)); ueforth_init(argc, argv, heap, boot, sizeof(boot));
for (;;) { g_sys.rp = ueforth_run(g_sys.rp); }
return 1; return 1;
} }

View File

@ -14,16 +14,17 @@ enum {
#undef X #undef X
}; };
static void ueforth_run(void) { static cell_t *ueforth_run(cell_t *init_rp) {
if (!g_sys.ip) { if (!init_rp) {
#define X(name, op, code) \ #define X(name, op, code) \
create(name, sizeof(name) - 1, name[0] == ';', (void *) OP_ ## op); create(name, sizeof(name) - 1, name[0] == ';', (void *) OP_ ## op);
PLATFORM_OPCODE_LIST PLATFORM_OPCODE_LIST
OPCODE_LIST OPCODE_LIST
#undef X #undef X
return; return 0;
} }
register cell_t *ip = g_sys.ip, *rp = g_sys.rp, *sp = g_sys.sp, tos, w; register cell_t *ip, *rp, *sp, tos, w;
rp = init_rp; ip = (cell_t *) *rp--; sp = (cell_t *) *rp--;
DROP; DROP;
for (;;) { for (;;) {
next: next:

View File

@ -38,6 +38,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmd, int show) {
#endif #endif
void *heap = VirtualAlloc( void *heap = VirtualAlloc(
NULL, HEAP_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); NULL, HEAP_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
ueforth(0, 0, heap, boot, sizeof(boot)); ueforth_init(0, 0, heap, boot, sizeof(boot));
for (;;) { g_sys.rp = ueforth_run(g_sys.rp); }
} }