swapforth
1#include <stdio.h>2#include <stdint.h>3#include <inttypes.h>4#include <string.h>5#include <stdlib.h>6#include <sys/mman.h>7
8// These are Forth-callable C functions
9// SwapForth is passed the array CFUNCS, so it knows the
10// address of each of function at run-time.
11//
12// This means that SwapForth itself does not refer to any
13// external symbols, so it can be relocated with memcpy().
14
15typedef size_t cell_t;16
17void _dotx(cell_t x)18{
19printf("%016zx ", x);20}
21
22void _bye()23{
24exit(0);25}
26
27void _emit(char c)28{
29putchar(c);30fflush(stdout);31}
32
33int _key()34{
35return getchar();36}
37
38static const size_t cfuncs[] = {39(size_t)_dotx,40(size_t)_bye,41(size_t)_emit,42(size_t)_key43};44
45
46#define MEMSIZE (1024 * 1024)47
48int main()49{
50extern unsigned char swapforth, swapforth_ends;51
52// allocate executable memory via sys call53void* mem = mmap(NULL, MEMSIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);54
55// copy runtime code into allocated memory56memcpy(mem, &swapforth, &swapforth_ends - &swapforth);57printf("swapforth = %p\n", &swapforth);58printf("mem = %p\n", mem);59
60// typecast allocated memory to a function pointer61int64_t (*func) () = mem;62
63int64_t stack[512 + 500];64cell_t r = func(stack + 512, cfuncs);65printf("(%p, %p)\n", stack + 512, cfuncs);66printf("r = %zx\n", r);67// printf("\ndepth = %d\n", (int)((stack + 512) - (int64_t*)r));68
69// Free up allocated memory70munmap(mem, MEMSIZE);71
72return 0;73}
74