Sfoglia il codice sorgente

a brainfuck jit. kind of amazing.

Lucas Stadler 11 anni fa
parent
commit
74a1a1902e
3 ha cambiato i file con 108 aggiunte e 1 eliminazioni
  1. 4 0
      c/jit/.gitignore
  2. 7 1
      c/jit/Makefile
  3. 97 0
      c/jit/bf.dasc

+ 4 - 0
c/jit/.gitignore

@ -5,3 +5,7 @@
5 5
6 6
/hello_dynasm
7 7
/hello_dynasm.c
8
9
/bf
10
/bf.c
11
/mandelbrot.bf

+ 7 - 1
c/jit/Makefile

@ -1,4 +1,10 @@
1
CFLAGS=-Iluajit
1
CFLAGS=-std=gnu99 -Iluajit
2
3
bf: bf.c dynasm-driver.c
4
	$(CC) $(CFLAGS) -o bf dynasm-driver.c -DJIT=\"bf.c\"
5
6
mandelbrot.bf:
7
	curl -L -O https://github.com/pablojorge/brainfuck/raw/master/samples/mandelbrot.bf
2 8
3 9
hello_dynasm: hello_dynasm.c dynasm-driver.c
4 10
	$(CC) $(CFLAGS) -o hello_dynasm dynasm-driver.c -DJIT=\"hello_dynasm.c\"

+ 97 - 0
c/jit/bf.dasc

@ -0,0 +1,97 @@
1
#include <stdint.h>
2
3
|.arch x64
4
|.actionlist actions
5
|
6
| // rbx is the pointer to the current cell
7
| //   (and it's preserved across calls to functions)
8
| .define PTR, rbx
9
|
10
| // macro for calling a function.
11
|.macro callp, addr
12
|  mov64 rax, (uintptr_t)addr
13
|  call  rax
14
|.endmacro
15
16
#define Dst &state
17
#define MAX_NESTING 256
18
19
void error(const char *msg) {
20
	fprintf(stderr, "%s\n", msg);
21
	exit(1);
22
}
23
24
int main(int argc, char *argv[]) {
25
	if (argc < 2) {
26
		error("Usage: bf <program>");
27
	}
28
29
	dasm_State *state;
30
	initjit(&state, actions);
31
32
	unsigned int maxpc = 0;
33
	int pcstack[MAX_NESTING];
34
	int *top = pcstack, *limit = pcstack + MAX_NESTING;
35
36
	// function prologue
37
	| push PTR
38
	| mov  PTR, rdi
39
40
	for (char *p = argv[1]; *p; p++) {
41
		switch (*p) {
42
			case '>':
43
				| inc PTR
44
				break;
45
			case '<':
46
				| dec PTR
47
				break;
48
			case '+':
49
				| inc byte [PTR]
50
				break;
51
			case '-':
52
				| dec byte [PTR]
53
				break;
54
			case '.':
55
				| movzx edi, byte [PTR]
56
				| callp putchar
57
				break;
58
			case ',':
59
				| callp getchar
60
				| mov   byte [PTR], al
61
				break;
62
			case '[':
63
				if (top == limit) {
64
					error("Nesting too deep.");
65
				}
66
67
				maxpc += 2;
68
				*top++ = maxpc;
69
				dasm_growpc(&state, maxpc);
70
				| cmp byte [PTR], 0
71
				| je  =>(maxpc-2)
72
				|=>(maxpc-1):
73
				break;
74
			case ']':
75
				if (top == pcstack) {
76
					error("Unmatched ']'");
77
				}
78
79
				top--;
80
				| cmp byte [PTR], 0
81
				| jne =>(*top-1)
82
				|=>(*top-2):
83
				break;
84
		}
85
	}
86
87
	// function epilogue
88
	| pop PTR
89
	| ret
90
91
	void (*bf_program)(char*) = jitcode(&state);
92
	char *mem = calloc(30000, 1);
93
	bf_program(mem);
94
	free(mem);
95
	free_jitcode(bf_program);
96
	return 0;
97
}