From 8f444b8c410f6b19e26f5d3fc54f16aa08343da4 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Sun, 5 Sep 2004 09:50:57 +0000 Subject: [PATCH] Add a sample program that demonstrates a simple VM based on libjit (committed by Rhys). --- ChangeLog | 5 + samples/hellovm.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 247 insertions(+) create mode 100644 samples/hellovm.c diff --git a/ChangeLog b/ChangeLog index 3ee8162..7962c33 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,9 @@ +2004-09-05 Norbert Bollow + + * samples/hellovm.c: add a sample program that demonstrates a + simple VM based on libjit (committed by Rhys). + 2004-08-30 Rhys Weatherley * jit-rules-x86.sel: fix x86 code generation for floating-point diff --git a/samples/hellovm.c b/samples/hellovm.c new file mode 100644 index 0000000..d89d91a --- /dev/null +++ b/samples/hellovm.c @@ -0,0 +1,242 @@ +/* hellovm.c - a kind of "hello world" for libjit + * + * Written by Norbert Bollow + * + * This program is a JIT for the "Hello VM" bytecode language, which + * has just one (string) register, and three opcodes: A) load string + * constant into register, B) output contents of register, C) exit program. + * + * Compile with: gcc hellovm.c -ljit -o hellovm + * + * A valid "Hello VM" bytecode language program, suitable as input file for + * this JIT, can be generated by the following perl script + * + * #!/usr/bin/perl + * open TEST, ">test"; + * $bytecode="AHello World!\n\x00BC"; + * print TEST "HelloVM\x00", pack('i',length($bytecode)), $bytecode; + * + * A slightly less trivial example can be generated e.g. with + * $bytecode="AHello, \x00BBAWorld!\n\x00BC"; + * + * The contents of this file are in the Public Domain. + */ + +#include +#include +#include +#include +char* readbytes(int, int); +static void hellovm_output(char *); +static void hellovm_exit(); +static void out_of_memory(); + +int main(int argc, char *argv[]) +{ + int fd; + char *buf; + int len; + jit_context_t context; + const jit_type_t hellovm_output_arg_type=jit_type_void_ptr; + jit_type_t hellovm_signature_main; + jit_type_t hellovm_signature_exit, hellovm_signature_output; + jit_type_t hellovm_type_string; + jit_value_t hellovm_reg; + jit_value_t tmp; + char *str; + jit_function_t hellovm_main; + int pos; + int willexit=0; + int retval; + + if(argc != 2) + { + printf("Usage: hellovm program\n"); + return 99; + } + + if((fd = open(argv[1], O_RDONLY)) < 0) + { + perror(argv[1]); + return 99; + } + + /* read filetype identification string and length field */ + buf=readbytes(fd, 12); + + /* check filetype identification string */ + if(jit_strcmp("HelloVM", buf)!=0) + { + fprintf(stderr, "%s is not in HelloVM format.\n", argv[1]); + return 99; + } + + /* check length field and read bytecode data */ + len=*((int*) (buf+8)); + if(len<0) + { + fprintf(stderr, "%s: Invalid length field.\n", argv[1]); + return 99; + } + free(buf); + buf=readbytes(fd, len); + close(fd); + + /* Now the fun begins :) */ + jit_init(); + context = jit_context_create(); + jit_context_build_start(context); + /* Build signatures for output and exit functions */ + hellovm_signature_output = jit_type_create_signature + (jit_abi_cdecl, jit_type_void, + (jit_type_t*)&hellovm_output_arg_type, 1, 0); + if (!hellovm_signature_output) out_of_memory(); + hellovm_signature_exit = jit_type_create_signature + (jit_abi_cdecl, jit_type_void, NULL, 0, 0); + if (!hellovm_signature_exit) out_of_memory(); + /* There is always a single function with signature: int main() */ + hellovm_signature_main = jit_type_create_signature + (jit_abi_cdecl, jit_type_int, NULL, 0, 0); + if (!hellovm_signature_main) out_of_memory(); + hellovm_main = jit_function_create(context, hellovm_signature_main); + if (!hellovm_main) out_of_memory(); + /* The HelloVM has a single register holding a NUL-terminated string */ + hellovm_type_string = jit_type_create_pointer(jit_type_sys_char, 1); + if (!hellovm_type_string) out_of_memory(); + hellovm_reg = jit_value_create(hellovm_main, hellovm_type_string); + if (!hellovm_reg) out_of_memory(); + /* Initialize the string register with "" */ + tmp=jit_value_create_nint_constant + (hellovm_main, hellovm_type_string, (int)""); + if (!tmp) out_of_memory(); + jit_insn_store(hellovm_main, hellovm_reg, tmp); + /* Now JIT the supplied bytecodes */ + pos=0; + while(pos