diff --git a/ueforth/arduino/arduino.template.ino b/ueforth/arduino/arduino.template.ino index c6834ac..b0429d7 100644 --- a/ueforth/arduino/arduino.template.ino +++ b/ueforth/arduino/arduino.template.ino @@ -343,30 +343,24 @@ static cell_t ResizeFile(cell_t fd, cell_t size) { #ifdef ENABLE_WEBSERVER_SUPPORT static void InvokeWebServerOn(WebServer *ws, const char *url, cell_t 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]; code[0] = xt; code[1] = g_sys.YIELD_XT; - g_sys.ip = code; - ueforth_run(); - g_sys.ip = old_ip; - g_sys.rp = old_rp; - g_sys.sp = old_sp; + cell_t stack[16]; + cell_t rstack[16]; + cell_t *rp = rstack; + *++rp = (cell_t) (stack + 1); + *++rp = (cell_t) code; + ueforth_run(rp); }); } #endif void setup() { 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() { - ueforth_run(); + g_sys.rp = ueforth_run(g_sys.rp); } diff --git a/ueforth/common/core.h b/ueforth/common/core.h index c2d3b09..4620076 100644 --- a/ueforth/common/core.h +++ b/ueforth/common/core.h @@ -14,7 +14,7 @@ static struct { cell_t *heap, *last, notfound; int argc; 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; } g_sys; @@ -120,30 +120,29 @@ static cell_t *evaluate1(cell_t *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, - const char *src, cell_t src_len) { - g_sys.ip = 0; +static void ueforth_init(int argc, char *argv[], void *heap, + const char *src, cell_t src_len) { g_sys.heap = (cell_t *) heap + 4; // Leave a little room. - ueforth_run(); - g_sys.sp = g_sys.heap + 1; g_sys.heap += STACK_SIZE; - g_sys.rp = g_sys.heap + 1; g_sys.heap += STACK_SIZE; + ueforth_run(0); + cell_t *sp = 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.DOLIT_XT = FIND("DOLIT"); g_sys.DOEXIT_XT = FIND("EXIT"); g_sys.YIELD_XT = FIND("YIELD"); 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("BRANCH"); - *g_sys.heap++ = (cell_t) g_sys.ip; + *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; - for (;;) { - ueforth_run(); - } + *++rp = (cell_t) sp; + *++rp = (cell_t) start; + g_sys.rp = rp; } diff --git a/ueforth/common/interp.h b/ueforth/common/interp.h index 4f9a933..76a7021 100644 --- a/ueforth/common/interp.h +++ b/ueforth/common/interp.h @@ -4,15 +4,16 @@ #define ADDR_DOCREATE && OP_DOCREATE #define ADDR_DODOES && OP_DODOES -static void ueforth_run(void) { - if (!g_sys.ip) { +static cell_t *ueforth_run(cell_t *init_rp) { + if (!init_rp) { #define X(name, op, code) create(name, sizeof(name) - 1, name[0] == ';', && OP_ ## op); PLATFORM_OPCODE_LIST OPCODE_LIST #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; #define X(name, op, code) OP_ ## op: { code; } NEXT; PLATFORM_OPCODE_LIST diff --git a/ueforth/common/opcodes.h b/ueforth/common/opcodes.h index 72aa88c..5efa69b 100644 --- a/ueforth/common/opcodes.h +++ b/ueforth/common/opcodes.h @@ -11,7 +11,7 @@ typedef uintptr_t ucell_t; #define COMMA(n) *g_sys.heap++ = (n) #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 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 # if __SIZEOF_POINTER__ == 8 @@ -71,7 +71,7 @@ typedef int64_t dcell_t; X("DOES>", DOES, DOES(ip); ip = (cell_t *) *rp; --rp) \ X("IMMEDIATE", IMMEDIATE, IMMEDIATE()) \ 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); \ create((const char *) *sp, tos, 0, ADDR_DOCOLON); \ g_sys.state = -1; --sp; DROP) \ diff --git a/ueforth/posix/posix_main.c b/ueforth/posix/posix_main.c index 674c5a0..9b9284c 100644 --- a/ueforth/posix/posix_main.c +++ b/ueforth/posix/posix_main.c @@ -18,6 +18,7 @@ int main(int argc, char *argv[]) { 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; } diff --git a/ueforth/windows/windows_interp.h b/ueforth/windows/windows_interp.h index 562a1e8..e80733d 100644 --- a/ueforth/windows/windows_interp.h +++ b/ueforth/windows/windows_interp.h @@ -14,16 +14,17 @@ enum { #undef X }; -static void ueforth_run(void) { - if (!g_sys.ip) { +static cell_t *ueforth_run(cell_t *init_rp) { + if (!init_rp) { #define X(name, op, code) \ create(name, sizeof(name) - 1, name[0] == ';', (void *) OP_ ## op); PLATFORM_OPCODE_LIST OPCODE_LIST #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; for (;;) { next: diff --git a/ueforth/windows/windows_main.c b/ueforth/windows/windows_main.c index 5293455..41e2f60 100644 --- a/ueforth/windows/windows_main.c +++ b/ueforth/windows/windows_main.c @@ -38,6 +38,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmd, int show) { #endif void *heap = VirtualAlloc( 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); } }