Made interpreter reentrant.
This commit is contained in:
@ -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);
|
||||
}
|
||||
|
||||
@ -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,
|
||||
static void ueforth_init(int argc, char *argv[], void *heap,
|
||||
const char *src, cell_t src_len) {
|
||||
g_sys.ip = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) \
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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); }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user