-
-
Save m2ym/1780319 to your computer and use it in GitHub Desktop.
| #include <stdio.h> | |
| #include <memory.h> | |
| #include <jit/jit.h> | |
| struct bf_loop { | |
| jit_label_t start; | |
| jit_label_t end; | |
| struct bf_loop *parent; | |
| }; | |
| typedef struct bf_loop *bf_loop_t; | |
| void bf_loop_start(jit_function_t function, bf_loop_t *loop) | |
| { | |
| bf_loop_t newloop = (bf_loop_t)jit_malloc(sizeof(struct bf_loop)); | |
| newloop->start = jit_label_undefined; | |
| newloop->end = jit_label_undefined; | |
| newloop->parent = *loop; | |
| jit_insn_label(function, &newloop->start); | |
| *loop = newloop; | |
| } | |
| void bf_loop_end(jit_function_t function, bf_loop_t *loop) | |
| { | |
| bf_loop_t curloop = *loop; | |
| if (curloop == NULL) return; | |
| jit_insn_branch(function, &curloop->start); | |
| jit_insn_label(function, &curloop->end); | |
| *loop = curloop->parent; | |
| } | |
| jit_function_t bf_compile(jit_context_t context, FILE *fp) | |
| { | |
| jit_type_t jit_type_ubyte_ptr; | |
| jit_type_t params[1]; | |
| jit_type_t signature; | |
| jit_function_t function; | |
| bf_loop_t loop = NULL; | |
| jit_type_t putchar_sig; | |
| jit_type_t putchar_params[1]; | |
| jit_type_t getchar_sig; | |
| jit_value_t ptr; | |
| jit_value_t ptr1; | |
| jit_value_t ubyte1; | |
| jit_value_t tmp; | |
| jit_type_ubyte_ptr = jit_type_create_pointer(jit_type_ubyte, 1); | |
| params[0] = jit_type_ubyte_ptr; | |
| signature = jit_type_create_signature(jit_abi_cdecl, jit_type_void, params, 1, 1); | |
| function = jit_function_create(context, signature); | |
| putchar_params[0] = jit_type_int; | |
| putchar_sig = jit_type_create_signature(jit_abi_cdecl, jit_type_int, putchar_params, 1, 1); | |
| getchar_sig = jit_type_create_signature(jit_abi_cdecl, jit_type_int, NULL, 0, 1); | |
| ptr = jit_value_get_param(function, 0); | |
| ptr1 = jit_value_create_nint_constant(function, jit_type_ubyte_ptr, 1); | |
| ubyte1 = jit_value_create_nint_constant(function, jit_type_ubyte, 1); | |
| while (!feof(fp)) { | |
| int c = fgetc(fp); | |
| switch (c) { | |
| case '>': | |
| tmp = jit_insn_add(function, ptr, ptr1); | |
| jit_insn_store(function, ptr, tmp); | |
| break; | |
| case '<': | |
| tmp = jit_insn_sub(function, ptr, ptr1); | |
| jit_insn_store(function, ptr, tmp); | |
| break; | |
| case '+': | |
| tmp = jit_insn_load_relative(function, ptr, 0, jit_type_ubyte); | |
| tmp = jit_insn_add(function, tmp, ubyte1); | |
| tmp = jit_insn_convert(function, tmp, jit_type_ubyte, 0); | |
| jit_insn_store_relative(function, ptr, 0, tmp); | |
| break; | |
| case '-': | |
| tmp = jit_insn_load_relative(function, ptr, 0, jit_type_ubyte); | |
| tmp = jit_insn_sub(function, tmp, ubyte1); | |
| tmp = jit_insn_convert(function, tmp, jit_type_ubyte, 0); | |
| jit_insn_store_relative(function, ptr, 0, tmp); | |
| break; | |
| case '.': | |
| tmp = jit_insn_load_relative(function, ptr, 0, jit_type_ubyte); | |
| jit_insn_call_native(function, "putchar", putchar, putchar_sig, &tmp, 1, JIT_CALL_NOTHROW); | |
| break; | |
| case ',': | |
| tmp = jit_insn_call_native(function, "getchar", getchar, getchar_sig, NULL, 0, JIT_CALL_NOTHROW); | |
| jit_insn_store_relative(function, ptr, 0, tmp); | |
| break; | |
| case '[': | |
| bf_loop_start(function, &loop); | |
| tmp = jit_insn_load_relative(function, ptr, 0, jit_type_ubyte); | |
| jit_insn_branch_if_not(function, tmp, &loop->end); | |
| break; | |
| case ']': | |
| bf_loop_end(function, &loop); | |
| break; | |
| } | |
| } | |
| jit_insn_return(function, NULL); | |
| jit_function_compile(function); | |
| /*jit_dump_function(stdout, function, "function");*/ | |
| return function; | |
| } | |
| int main(int argc, char *argv[]) | |
| { | |
| jit_context_t context; | |
| jit_function_t function; | |
| unsigned char data[30000]; | |
| jit_ptr arg1; | |
| void *args[1]; | |
| FILE *fp; | |
| context = jit_context_create(); | |
| jit_context_build_start(context); | |
| fp = fopen(argv[1], "rb"); | |
| function = bf_compile(context, fp); | |
| fclose(fp); | |
| jit_context_build_end(context); | |
| memset(data, 0, sizeof(data)); | |
| arg1 = data; | |
| args[0] = &arg1; | |
| jit_function_apply(function, args, NULL); | |
| jit_context_destroy(context); | |
| return 0; | |
| } |
m2ym
commented
Feb 9, 2012
When I build it with LibJIT from Savannah repository downloaded on January 6th 2018, lot's of bf-programs failed.
Two point below is needed to work on my programs.
First, at Line 129
- args[0] = &arg1;
+ args[0] = arg1;
Second at Line 89-90
tmp = jit_insn_call_native(function, "getchar", getchar, getchar_sig, NULL, 0, JIT_CALL_NOTHROW);
jit_insn_store_relative(function, ptr, 0, tmp);
--
tmp = jit_insn_call_native(function, "getchar", getchar, getchar_sig, NULL, 0, JIT_CALL_NOTHROW);
+ tmp = jit_insn_convert(function, tmp, jit_type_ubyte, 0);
jit_insn_store_relative(function, ptr, 0, tmp);
First point may be due to some calling convention change in LibJIT.
Second should be same reason that bf-oprator '+' and '-' need the appended line.
2018-01-10
The first point
First, at Line 129
- args[0] = &arg1;
+ args[0] = arg1;
was a LibJIT bug which is fixed now.