├── .gitignore ├── AUTHORS ├── COPYING ├── COPYING.LESSER ├── ChangeLog ├── Makefile.am ├── NEWS ├── README ├── TODO ├── attic ├── README.alpha ├── jit-apply-alpha.c ├── jit-apply-alpha.h ├── jit-gen-alpha.h ├── jit-rules-alpha.c ├── jit-rules-alpha.h └── jit-rules-alpha.ins ├── auto_gen.sh ├── build-aux └── .gitignore ├── configure.ac ├── doc ├── .gitignore ├── Makefile.am ├── README ├── extract-docs.sh ├── libjit.3 ├── libjit.texi ├── mangling_rules.txt ├── mkhtml.sh └── mkpdf.sh ├── dpas ├── .gitignore ├── Makefile.am ├── README ├── dpas-builtin.c ├── dpas-function.c ├── dpas-internal.h ├── dpas-main.c ├── dpas-parser.y ├── dpas-scanner.l ├── dpas-scope.c ├── dpas-scope.h ├── dpas-semantics.h ├── dpas-types.c └── dpas-types.h ├── include ├── Makefile.am └── jit │ ├── .gitignore │ ├── Makefile.am │ ├── jit-apply.h │ ├── jit-arch-arm.h │ ├── jit-arch-generic.h │ ├── jit-arch-x86-64.h │ ├── jit-arch-x86.h │ ├── jit-block.h │ ├── jit-common.h │ ├── jit-context.h │ ├── jit-debugger.h │ ├── jit-defs.h.in │ ├── jit-dump.h │ ├── jit-dynamic.h │ ├── jit-elf.h │ ├── jit-except.h │ ├── jit-function.h │ ├── jit-init.h │ ├── jit-insn.h │ ├── jit-intrinsic.h │ ├── jit-memory.h │ ├── jit-meta.h │ ├── jit-objmodel-private.h │ ├── jit-objmodel.h │ ├── jit-opcode-compat.h │ ├── jit-plus.h │ ├── jit-type.h │ ├── jit-unwind.h │ ├── jit-util.h │ ├── jit-value.h │ ├── jit-vmem.h │ ├── jit-walk.h │ └── jit.h ├── jit ├── .gitignore ├── Makefile.am ├── jit-alloc.c ├── jit-apply-arm.c ├── jit-apply-arm.h ├── jit-apply-func.h ├── jit-apply-x86-64.c ├── jit-apply-x86-64.h ├── jit-apply-x86.c ├── jit-apply-x86.h ├── jit-apply.c ├── jit-bitset.c ├── jit-bitset.h ├── jit-block.c ├── jit-cfg.c ├── jit-cfg.h ├── jit-compile.c ├── jit-config.h ├── jit-context.c ├── jit-cpuid-x86.c ├── jit-cpuid-x86.h ├── jit-debugger.c ├── jit-dump.c ├── jit-elf-defs.h ├── jit-elf-read.c ├── jit-elf-write.c ├── jit-except.c ├── jit-function.c ├── jit-gen-arm.c ├── jit-gen-arm.h ├── jit-gen-x86-64.h ├── jit-gen-x86.h ├── jit-init.c ├── jit-insn.c ├── jit-internal.h ├── jit-interp-opcodes.ops ├── jit-interp.c ├── jit-interp.h ├── jit-intrinsic.c ├── jit-live.c ├── jit-memory-cache.c ├── jit-memory.c ├── jit-meta.c ├── jit-objmodel.c ├── jit-opcode-apply.c ├── jit-opcodes.ops ├── jit-pool.c ├── jit-reg-alloc.c ├── jit-reg-alloc.h ├── jit-reg-class.c ├── jit-reg-class.h ├── jit-rules-arm.c ├── jit-rules-arm.h ├── jit-rules-arm.ins ├── jit-rules-interp.c ├── jit-rules-interp.h ├── jit-rules-x86-64.c ├── jit-rules-x86-64.h ├── jit-rules-x86-64.ins ├── jit-rules-x86.c ├── jit-rules-x86.h ├── jit-rules-x86.ins ├── jit-rules.c ├── jit-rules.h ├── jit-setjmp.h ├── jit-signal.c ├── jit-symbol.c ├── jit-thread.c ├── jit-thread.h ├── jit-type.c ├── jit-unwind.c ├── jit-util.c ├── jit-value.c ├── jit-varint.c ├── jit-varint.h ├── jit-vmem.c ├── jit-walk.c └── mklabel.sh ├── jitdynamic ├── Makefile.am ├── jit-cpp-mangle.c └── jit-dynlib.c ├── jitplus ├── Makefile.am ├── jit-plus-context.cpp ├── jit-plus-function.cpp ├── jit-plus-jump-table.cpp └── jit-plus-value.cpp ├── jitruby ├── README ├── ext │ ├── extconf.rb │ ├── insns.inc.rpp │ ├── jit.c │ ├── method_data.c.rpp │ ├── method_data.h │ ├── minimal_node.c │ ├── minimal_node.h │ ├── rubyjit.h │ └── rubypp.rb ├── generate_rdoc.rb ├── lib │ ├── jit.rb │ └── jit │ │ ├── array.rb │ │ ├── function.rb │ │ ├── pointer.rb │ │ ├── struct.rb │ │ └── value.rb ├── metaconfig ├── post-install.rb ├── post-setup.rb ├── ruby-libjit.gemspec ├── run_tests.rb ├── sample │ ├── fib.rb │ ├── gcd_benchmark.rb │ └── simple.rb ├── setup.rb └── test │ ├── assertions.rb │ ├── test_jit_array.rb │ ├── test_jit_function.rb │ ├── test_jit_pointer.rb │ ├── test_jit_struct.rb │ └── test_jit_value.rb ├── m4 └── .gitignore ├── samples └── hellovm.c ├── tests ├── Makefile.am ├── README ├── coerce.pas ├── cond.pas ├── loop.pas ├── math.pas └── param.pas ├── tools ├── .gitignore ├── Makefile.am ├── gen-apply-macosx.h ├── gen-apply.c ├── gen-ops-parser.y ├── gen-ops-scanner.l ├── gen-rules-parser.y └── gen-rules-scanner.l └── tutorial ├── .gitignore ├── Makefile.am ├── README ├── t1.c ├── t2.c ├── t3.c ├── t4.cpp └── t5.c /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.o 3 | *.a 4 | *.lo 5 | *.la 6 | 7 | .deps 8 | .libs 9 | 10 | INSTALL 11 | Makefile 12 | Makefile.in 13 | configure 14 | config.log 15 | config.cache 16 | config.status 17 | aclocal.m4 18 | confdefs.h 19 | config.h 20 | config.h.in 21 | stamp-h 22 | stamp-h.in 23 | libtool 24 | ltconfig 25 | autom4te.cache 26 | stamp-h1 27 | build-aux 28 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Rhys Weatherley 2 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | ACLOCAL_AMFLAGS = -I m4 2 | 3 | SUBDIRS = tools include jit jitdynamic jitplus dpas tutorial tests doc 4 | 5 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | libjit 3 | ------ 4 | 5 | This library in this distribution implements Just-In-Time compilation 6 | functionality. Unlike other JIT's, this one is designed to be independent 7 | of any particular virtual machine bytecode format or language. The hope 8 | is that Free Software projects can get a leg-up on proprietry VM vendors 9 | by using this library rather than spending large amounts of time writing 10 | their own JIT from scratch. 11 | 12 | This JIT is also designed to be portable to multiple archictures. 13 | If you run libjit on a machine for which a native code generator is 14 | not yet available, then libjit will fall back to interpreting the code. 15 | This way, you don't need to write your own interpreter for your 16 | bytecode format if you don't want to. 17 | 18 | The library is distributed under the terms of the GNU Lesser General 19 | Public License. See the COPYING.LESSER file for details. 20 | 21 | The documentation for libjit is in Texinfo format. A general overview 22 | is in "doc/libjit.texi" with the remainder of the function documentation 23 | in the source files themselves. 24 | 25 | Building libjit 26 | --------------- 27 | 28 | To build libjit from a release tarball you will need GNU make, Bison, and 29 | Flex, and it is also highly recommended that you use gcc. To configure, 30 | build, and install, you would do the following: 31 | 32 | ./configure 33 | make 34 | make install 35 | 36 | To build libjit from the repository tree you will also need autotools: 37 | autoconf, automake, and libtool. These tools let you create ./configure 38 | script which is miising in the repository. To run autotools you would 39 | just do the followoing: 40 | 41 | ./auto_gen.sh 42 | 43 | 44 | Compiler notes 45 | -------------- 46 | 47 | It is highly recommended that you build libjit with gcc and not 48 | some other C compiler, even if you plan to use some other C 49 | compiler to access the library. We make use of a number of gcc 50 | builtins to assist with stack walking, dynamic function calls, 51 | and closures. 52 | 53 | It is also recommended that you don't use the "-fomit-frame-pointer" 54 | option when compiling programs that use libjit. Otherwise stack walking 55 | may not work correctly, leading to problems when throwing exceptions. 56 | The configure script for libjit will detect the presence of this 57 | option in CFLAGS and remove it when building libjit itself. 58 | 59 | Contacting the authors 60 | ---------------------- 61 | 62 | The primary author is Rhys Weatherley at Southern Storm Software, Pty Ltd. 63 | He can be reached via e-mail at "rweather@southern-storm.com.au". [ This 64 | address is probably not valid anymore. ] 65 | 66 | A number of other authors have also contributed to libjit. The current 67 | libjit maintainer is Aleksey Demakov . 68 | 69 | Currently it is recommended to obtain libjit source tree from its Savannah 70 | git repository: 71 | 72 | git clone git://git.savannah.gnu.org/libjit.git 73 | 74 | The latest released version of libjit is severely out of date and its use 75 | is discuraged. Still it can be downloaded from here: 76 | 77 | http://ftp.gnu.org/old-gnu/dotgnu/libjit/ 78 | 79 | Discussions about libjit can be carried out on the libjit mailing list, 80 | "libjit@gnu.org". For details on how to subscribe to the list visit libjit 81 | home page: 82 | 83 | http://www.gnu.org/software/libjit/ 84 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | Target release: 0.1.4 2 | ===================== 3 | 4 | * CFG-based liveness analysis and dead code elimination 5 | * global copy and constant propagation 6 | * jitruby (in case copyright issues are resolved) 7 | * sync jitplus with jit (jump tables, compile driver, debug) 8 | * fix catch/throw within finally 9 | * get rid of manual rules 10 | * add direct conversion opcodes to/from float32 and float64 11 | * add rounding towards zero 12 | * try to be smarter with %rax for variadic functions on x86-64 13 | 14 | Target Release: 0.2.0 15 | ===================== 16 | 17 | * linear scan register allocation 18 | * improve exception handling 19 | * align function prolog and basic blocks 20 | * support cross-compilation 21 | 22 | Long-Term Tasks 23 | =============== 24 | 25 | * comprehensive test suite 26 | * ports to ppc, arm, sparc, alpha, coldfire, mips... 27 | * more optimizations: 28 | ** redundancy elimination 29 | ** alias analysis 30 | ** strength reduction 31 | ** loop optimization 32 | ** array data type, ABCD 33 | * tree-based IR and instruction selection ? 34 | * instruction scheduling ? 35 | * finish ELF writer/reader 36 | -------------------------------------------------------------------------------- /attic/README.alpha: -------------------------------------------------------------------------------- 1 | As part of Google's Summer of Code, I am porting libjit to the alpha 2 | architecture for the GNU Project. Please be aware that this is still 3 | very much a work in progress and isn't functional yet. You can follow my 4 | progress via my blog: http://mediumbagel.org/nucleus/index.php?catid=6 5 | 6 | For the first iteration, the alpha port will not implement floating- 7 | point arithmetic. This is done to reduce complexity and to get libjit 8 | working on alpha sooner. Advanced features like prefetching, hints (for 9 | jmp, jsr, ret, and jsrco), and branch elimination with cmov are 10 | optimizations that will be implmented once the alpha port is functional. 11 | 12 | -Thomas Cort 13 | 14 | During the development of the alpha port, I found the following sources 15 | of information to be very useful: 16 | 17 | Alpha Architecture Handbook 18 | ftp://ftp.compaq.com/pub/products/alphaCPUdocs/alpha_arch_ref.pdf 19 | http://ftp.digital.com/pub/Digital/info/semiconductor/literature/alphaahb.pdf 20 | 21 | Compiler Writer's Guide for the 21264/21364 22 | ftp://ftp.compaq.com/pub/products/alphaCPUdocs/comp_guide_v2.pdf 23 | 24 | Assembly Language Programmer's Guide 25 | http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PS31D-TET1_html/TITLE.html 26 | 27 | binutils source code 28 | binutils-2.16.1/opcodes/alpha-opc.c 29 | 30 | ffcall source code 31 | ffcall-1.10/avcall/avcall-alpha.c 32 | 33 | mono source code 34 | mono-.1.1.15/mono/arch/alpha/* 35 | 36 | gcc source code 37 | gcc-3.4.6/gcc/config/alpha/* 38 | 39 | ALPHA: Opcodes 40 | http://www.cs.arizona.edu/alto/Doc/local/alpha.opcode.html 41 | -------------------------------------------------------------------------------- /attic/jit-apply-alpha.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-apply-alpha.h - Special definitions for alpha function application. 3 | * 4 | * Copyright (C) 2006 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_APPLY_ALPHA_H 24 | #define _JIT_APPLY_ALPHA_H 25 | 26 | /* 27 | * The maximum number of bytes that are needed to represent a closure, 28 | * and the alignment to use for the closure. 29 | */ 30 | #define jit_closure_size (35 /* instructions */ * 4 /* bytes per instruction */) 31 | #define jit_closure_align 32 32 | 33 | /* 34 | * The number of bytes that are needed for a redirector stub. 35 | * This includes any extra bytes that are needed for alignment. 36 | */ 37 | #define jit_redirector_size (46 /* instructions */ * 4 /* bytes per instruction */) 38 | 39 | /* 40 | * We should pad unused code space with NOP's. 41 | */ 42 | #define jit_should_pad 1 43 | 44 | #endif /* _JIT_APPLY_ALPHA_H */ 45 | -------------------------------------------------------------------------------- /auto_gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | autoreconf -i -f 4 | -------------------------------------------------------------------------------- /build-aux/.gitignore: -------------------------------------------------------------------------------- 1 | ar-lib 2 | config.guess 3 | config.sub 4 | depcomp 5 | install-sh 6 | ltmain.sh 7 | missing 8 | texinfo.tex 9 | ylwrap 10 | -------------------------------------------------------------------------------- /doc/.gitignore: -------------------------------------------------------------------------------- 1 | libjit.info* 2 | libjitext-* 3 | texinfo.tex 4 | *.pdf 5 | -------------------------------------------------------------------------------- /doc/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | man_MANS = libjit.3 3 | EXTRA_SCRIPTS = extract-docs.sh mkhtml.sh mkpdf.sh 4 | EXTRA_DIST = $(man_MANS) $(EXTRA_SCRIPTS) 5 | 6 | info_TEXINFOS = libjit.texi 7 | libjit_TEXINFOS = \ 8 | $(srcdir)/libjitext-apply.texi \ 9 | $(srcdir)/libjitext-block.texi \ 10 | $(srcdir)/libjitext-compile.texi \ 11 | $(srcdir)/libjitext-context.texi \ 12 | $(srcdir)/libjitext-debugger.texi \ 13 | $(srcdir)/libjitext-dump.texi \ 14 | $(srcdir)/libjitext-dynlib.texi \ 15 | $(srcdir)/libjitext-elf-read.texi \ 16 | $(srcdir)/libjitext-except.texi \ 17 | $(srcdir)/libjitext-function.texi \ 18 | $(srcdir)/libjitext-init.texi \ 19 | $(srcdir)/libjitext-insn.texi \ 20 | $(srcdir)/libjitext-intrinsic.texi \ 21 | $(srcdir)/libjitext-cpp-mangle.texi \ 22 | $(srcdir)/libjitext-util.texi \ 23 | $(srcdir)/libjitext-meta.texi \ 24 | $(srcdir)/libjitext-reg-alloc.texi \ 25 | $(srcdir)/libjitext-rules-interp.texi \ 26 | $(srcdir)/libjitext-type.texi \ 27 | $(srcdir)/libjitext-value.texi \ 28 | $(srcdir)/libjitext-walk.texi \ 29 | $(srcdir)/libjitext-plus-context.texi \ 30 | $(srcdir)/libjitext-plus-function.texi \ 31 | $(srcdir)/libjitext-plus-value.texi 32 | 33 | $(srcdir)/libjitext-apply.texi: $(top_srcdir)/jit/jit-apply.c 34 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 35 | 36 | $(srcdir)/libjitext-block.texi: $(top_srcdir)/jit/jit-block.c 37 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 38 | 39 | $(srcdir)/libjitext-compile.texi: $(top_srcdir)/jit/jit-compile.c 40 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 41 | 42 | $(srcdir)/libjitext-context.texi: $(top_srcdir)/jit/jit-context.c 43 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 44 | 45 | $(srcdir)/libjitext-debugger.texi: $(top_srcdir)/jit/jit-debugger.c 46 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 47 | 48 | $(srcdir)/libjitext-dump.texi: $(top_srcdir)/jit/jit-dump.c 49 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 50 | 51 | $(srcdir)/libjitext-dynlib.texi: $(top_srcdir)/jitdynamic/jit-dynlib.c 52 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 53 | 54 | $(srcdir)/libjitext-elf-read.texi: $(top_srcdir)/jit/jit-elf-read.c 55 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 56 | 57 | $(srcdir)/libjitext-except.texi: $(top_srcdir)/jit/jit-except.c 58 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 59 | 60 | $(srcdir)/libjitext-function.texi: $(top_srcdir)/jit/jit-function.c 61 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 62 | 63 | $(srcdir)/libjitext-init.texi: $(top_srcdir)/jit/jit-init.c 64 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 65 | 66 | $(srcdir)/libjitext-insn.texi: $(top_srcdir)/jit/jit-insn.c 67 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 68 | 69 | $(srcdir)/libjitext-intrinsic.texi: $(top_srcdir)/jit/jit-intrinsic.c 70 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 71 | 72 | $(srcdir)/libjitext-cpp-mangle.texi: $(top_srcdir)/jitdynamic/jit-cpp-mangle.c 73 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 74 | 75 | $(srcdir)/libjitext-util.texi: $(top_srcdir)/jit/jit-util.c 76 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 77 | 78 | $(srcdir)/libjitext-meta.texi: $(top_srcdir)/jit/jit-meta.c 79 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 80 | 81 | $(srcdir)/libjitext-reg-alloc.texi: $(top_srcdir)/jit/jit-reg-alloc.c 82 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 83 | 84 | $(srcdir)/libjitext-rules-interp.texi: $(top_srcdir)/jit/jit-rules-interp.c 85 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 86 | 87 | $(srcdir)/libjitext-type.texi: $(top_srcdir)/jit/jit-type.c 88 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 89 | 90 | $(srcdir)/libjitext-value.texi: $(top_srcdir)/jit/jit-value.c 91 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 92 | 93 | $(srcdir)/libjitext-walk.texi: $(top_srcdir)/jit/jit-walk.c 94 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 95 | 96 | $(srcdir)/libjitext-plus-context.texi: \ 97 | $(top_srcdir)/jitplus/jit-plus-context.cpp 98 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 99 | 100 | $(srcdir)/libjitext-plus-function.texi: \ 101 | $(top_srcdir)/jitplus/jit-plus-function.cpp 102 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 103 | 104 | $(srcdir)/libjitext-plus-value.texi: \ 105 | $(top_srcdir)/jitplus/jit-plus-value.cpp 106 | $(SHELL) $(srcdir)/extract-docs.sh $< >$@ 107 | 108 | CLEANFILES = $(srcdir)/libjit.info $(srcdir)/libjit.info-* \ 109 | $(srcdir)/libjitext-*.texi 110 | -------------------------------------------------------------------------------- /doc/README: -------------------------------------------------------------------------------- 1 | 2 | To generate HTML documentation, use the following command in the 3 | "libjit/doc" directory: 4 | 5 | mkdir outdir 6 | ./mkhtml.sh outdir 7 | 8 | where "outdir" is the name of the directory to place the generated 9 | HTML files in. 10 | 11 | To generate PDF documentation, use the following command in the 12 | "libjit/doc" directory: 13 | 14 | ./mkpdf.sh 15 | 16 | This will generate "libjit.pdf". You will need to have PDFTeX installed 17 | to do this. 18 | -------------------------------------------------------------------------------- /doc/extract-docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # extract-docs.sh - Extract texinfo documentation from a source file. 4 | # 5 | # Usage: extract-docs.sh source.c >output.texi 6 | # 7 | # Copyright (C) 2004 Southern Storm Software, Pty Ltd. 8 | # 9 | # This file is part of the libjit library. 10 | # 11 | # The libjit library is free software: you can redistribute it and/or 12 | # modify it under the terms of the GNU Lesser General Public License 13 | # as published by the Free Software Foundation, either version 2.1 of 14 | # the License, or (at your option) any later version. 15 | # 16 | # The libjit library is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 | # Lesser General Public License for more details. 20 | # 21 | # You should have received a copy of the GNU Lesser General Public 22 | # License along with the libjit library. If not, see 23 | # . 24 | 25 | in_doc=false 26 | echo '' 27 | echo "@c Extracted automatically from $1 - DO NOT EDIT" 28 | echo '' 29 | while read LINE ; do 30 | case "$LINE" in 31 | /\*@*) in_doc=true ;; 32 | @\*/*) echo '' 33 | in_doc=false ;; 34 | *) if test "$in_doc" = true ; then 35 | echo "$LINE" 36 | fi ;; 37 | esac 38 | done < "$1" | sed -e '1,$s/^ *\* *//' 39 | 40 | exit 0 41 | -------------------------------------------------------------------------------- /doc/libjit.3: -------------------------------------------------------------------------------- 1 | .\" Copyright (c) 2004 Southern Storm Software, Pty Ltd. 2 | .\" 3 | .\" This file is part of the libjit library. 4 | .\" 5 | .\" The libjit library is free software: you can redistribute it and/or 6 | .\" modify it under the terms of the GNU Lesser General Public License 7 | .\" as published by the Free Software Foundation, either version 2.1 of 8 | .\" the License, or (at your option) any later version. 9 | .\" 10 | .\" The libjit library is distributed in the hope that it will be useful, 11 | .\" but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | .\" Lesser General Public License for more details. 14 | .\" 15 | .\" You should have received a copy of the GNU Lesser General Public 16 | .\" License along with the libjit library. If not, see 17 | .\" . 18 | .TH libjit 3 "18 April 2004" "Southern Storm Software" "Just-In-Time Compiler Library" 19 | .SH NAME 20 | libjit \- Just-In-Time Compiler Library 21 | .SH SYNOPSIS 22 | .B #include 23 | 24 | Link with 25 | .B -ljit 26 | .SH DESCRIPTION 27 | The \fBlibjit\fR library has an extensive set of routines that takes care 28 | of the bulk of the Just-In-Time compilation process, without tying the 29 | programmer down with language or bytecode specifics. 30 | 31 | Unlike other systems such as the JVM, .NET, Parrot, and LLVM, \fBlibjit\fR 32 | is not a virtual machine in its own right. It is the foundation upon which a 33 | number of different virtual machines, dynamic scripting languages, etc, 34 | can be built. 35 | .SH "AUTHOR" 36 | Written by Southern Storm Software, Pty Ltd. 37 | 38 | http://www.southern-storm.com.au/ 39 | .SH "SEE ALSO" 40 | The full documentation for 41 | .B libjit 42 | is maintained as a Texinfo manual. If the 43 | .B info 44 | and 45 | .B libjit 46 | programs are properly installed at your site, the command 47 | .IP 48 | .B info libjit 49 | .PP 50 | should give you access to the complete manual. 51 | -------------------------------------------------------------------------------- /doc/mkhtml.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # mkhtml.sh - Make html documentation from Texinfo input. 4 | # 5 | # Usage: mkhtml outdir 6 | 7 | # Check the command-line. 8 | if [ -z "$1" ]; then 9 | echo "Usage: $0 outdir" 10 | exit 1 11 | fi 12 | 13 | # Check that we are executed in the correct directory. 14 | if [ ! -f libjit.texi ]; then 15 | echo "Cannot find libjit.texi" 16 | exit 1 17 | fi 18 | 19 | # Create the output directory. 20 | if [ ! -d "$1" ]; then 21 | mkdir "$1" 22 | fi 23 | 24 | # Get the full pathname of the input file. 25 | PATHNAME=`pwd`/libjit.texi 26 | 27 | # Change to the output directory and execute "texi2html". 28 | cd "$1" 29 | exec texi2html -split_chapter "$PATHNAME" 30 | -------------------------------------------------------------------------------- /doc/mkpdf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # mkpdf - Make the PDF version of texinfo documentation 4 | 5 | exec texi2dvi --pdf libjit.texi 6 | -------------------------------------------------------------------------------- /dpas/.gitignore: -------------------------------------------------------------------------------- 1 | dpas-parser.h 2 | dpas-parser.c 3 | dpas-scanner.c 4 | dpas 5 | -------------------------------------------------------------------------------- /dpas/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | noinst_PROGRAMS = dpas 3 | 4 | dpas_SOURCES = \ 5 | dpas-internal.h \ 6 | dpas-main.c \ 7 | dpas-builtin.c \ 8 | dpas-function.c \ 9 | dpas-parser.y \ 10 | dpas-scanner.l \ 11 | dpas-semantics.h \ 12 | dpas-scope.c \ 13 | dpas-scope.h \ 14 | dpas-types.c \ 15 | dpas-types.h 16 | 17 | AM_YFLAGS = -d 18 | 19 | dpas_LDADD = $(top_builddir)/jit/libjit.la 20 | dpas_DEPENDENCIES = $(top_builddir)/jit/libjit.la 21 | 22 | AM_CFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -I. -I$(srcdir) \ 23 | -DDPAS_INCLUDE_DIR=\"$(datadir)/dpas\" 24 | 25 | dpas-scanner.l: dpas-parser.c 26 | 27 | CLEANFILES = dpas-parser.c dpas-scanner.c dpas-parser.h 28 | -------------------------------------------------------------------------------- /dpas/README: -------------------------------------------------------------------------------- 1 | 2 | This directory contains an implementation of "Dynamic Pascal", or "dpas" 3 | as we like to call it. It is provided as an example of using "libjit" 4 | in a real environment. We also use it to write test programs that 5 | exercise the JIT's capabilities. 6 | 7 | More information on Dynamic Pascal can be found in libjit's Texinfo 8 | documentation, "libjit/doc/libjit.texi". 9 | -------------------------------------------------------------------------------- /dpas/dpas-function.c: -------------------------------------------------------------------------------- 1 | /* 2 | * dpas-function.c - Special handling for Dynamic Pascal functions. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #include "dpas-internal.h" 24 | 25 | static jit_context_t current_context; 26 | static jit_function_t *function_stack = 0; 27 | static int function_stack_size = 0; 28 | static jit_function_t *main_list = 0; 29 | static int main_list_size = 0; 30 | 31 | jit_context_t dpas_current_context(void) 32 | { 33 | if(!current_context) 34 | { 35 | current_context = jit_context_create(); 36 | if(!current_context) 37 | { 38 | dpas_out_of_memory(); 39 | } 40 | } 41 | return current_context; 42 | } 43 | 44 | jit_function_t dpas_current_function(void) 45 | { 46 | if(function_stack_size > 0) 47 | { 48 | return function_stack[function_stack_size - 1]; 49 | } 50 | else 51 | { 52 | /* We are probably compiling the "main" method for this module */ 53 | jit_type_t signature = jit_type_create_signature 54 | (jit_abi_cdecl, jit_type_void, 0, 0, 1); 55 | if(!signature) 56 | { 57 | dpas_out_of_memory(); 58 | } 59 | return dpas_new_function(signature); 60 | } 61 | } 62 | 63 | jit_function_t dpas_new_function(jit_type_t signature) 64 | { 65 | jit_function_t func; 66 | func = jit_function_create(dpas_current_context(), signature); 67 | if(!func) 68 | { 69 | dpas_out_of_memory(); 70 | } 71 | function_stack = (jit_function_t *)jit_realloc 72 | (function_stack, sizeof(jit_function_t) * (function_stack_size + 1)); 73 | if(!function_stack) 74 | { 75 | dpas_out_of_memory(); 76 | } 77 | function_stack[function_stack_size++] = func; 78 | return func; 79 | } 80 | 81 | void dpas_pop_function(void) 82 | { 83 | if(function_stack_size > 0) 84 | { 85 | --function_stack_size; 86 | } 87 | } 88 | 89 | int dpas_function_is_nested(void) 90 | { 91 | return (function_stack_size > 1); 92 | } 93 | 94 | dpas_semvalue dpas_lvalue_to_rvalue(dpas_semvalue value) 95 | { 96 | if(dpas_sem_is_lvalue_ea(value)) 97 | { 98 | jit_type_t type = dpas_sem_get_type(value); 99 | jit_value_t rvalue = dpas_sem_get_value(value); 100 | rvalue = jit_insn_load_relative 101 | (dpas_current_function(), rvalue, 0, type); 102 | if(!rvalue) 103 | { 104 | dpas_out_of_memory(); 105 | } 106 | dpas_sem_set_rvalue(value, type, rvalue); 107 | } 108 | return value; 109 | } 110 | 111 | void dpas_add_main_function(jit_function_t func) 112 | { 113 | main_list = (jit_function_t *)jit_realloc 114 | (main_list, sizeof(jit_function_t) * (main_list_size + 1)); 115 | if(!main_list) 116 | { 117 | dpas_out_of_memory(); 118 | } 119 | main_list[main_list_size++] = func; 120 | } 121 | 122 | int dpas_run_main_functions(void) 123 | { 124 | int index; 125 | for(index = 0; index < main_list_size; ++index) 126 | { 127 | if(!jit_function_apply(main_list[index], 0, 0)) 128 | { 129 | fprintf(stderr, "Exception 0x%lx thrown past top level\n", 130 | (long)(jit_nint)(jit_exception_get_last())); 131 | return 0; 132 | } 133 | } 134 | return 1; 135 | } 136 | -------------------------------------------------------------------------------- /dpas/dpas-internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * dpas-internal.h - Internal definitions for the Dynamic Pascal compiler. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _DPAS_INTERNAL_H 24 | #define _DPAS_INTERNAL_H 25 | 26 | #include 27 | #include 28 | 29 | #include "dpas-scope.h" 30 | #include "dpas-types.h" 31 | #include "dpas-semantics.h" 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /* 38 | * Current filename and line number. 39 | */ 40 | extern char *dpas_filename; 41 | extern long dpas_linenum; 42 | 43 | /* 44 | * Flag that indicates that functions should be dumped as they are compiled. 45 | */ 46 | extern int dpas_dump_functions; 47 | 48 | /* 49 | * Information about a parameter list (also used for record fields). 50 | */ 51 | typedef struct 52 | { 53 | char **names; 54 | jit_type_t *types; 55 | int len; 56 | jit_abi_t abi; 57 | 58 | } dpas_params; 59 | 60 | /* 61 | * Flag that is set when an error is encountered. 62 | */ 63 | extern int dpas_error_reported; 64 | 65 | /* 66 | * Function that is called when the system runs out of memory. 67 | */ 68 | void dpas_out_of_memory(void); 69 | 70 | /* 71 | * Process an "import" clause within a program. 72 | */ 73 | void dpas_import(const char *name); 74 | 75 | /* 76 | * Load the contents of a source file. 77 | */ 78 | void dpas_load_file(char *filename, FILE *file); 79 | 80 | /* 81 | * Report an error on the current line. 82 | */ 83 | void dpas_error(const char *format, ...); 84 | 85 | /* 86 | * Report a warning on the current line. 87 | */ 88 | void dpas_warning(const char *format, ...); 89 | 90 | /* 91 | * Report an error on a specific line. 92 | */ 93 | void dpas_error_on_line(const char *filename, long linenum, 94 | const char *format, ...); 95 | 96 | /* 97 | * Get the JIT context that we are using to compile functions. 98 | */ 99 | jit_context_t dpas_current_context(void); 100 | 101 | /* 102 | * Get the current function that is being compiled. Returns NULL 103 | * if we are currently at the global level. 104 | */ 105 | jit_function_t dpas_current_function(void); 106 | 107 | /* 108 | * Create a new function and push it onto the context stack. 109 | * The function is initialized to read parameters that are 110 | * compatible with the supplied signature. 111 | */ 112 | jit_function_t dpas_new_function(jit_type_t signature); 113 | 114 | /* 115 | * Pop out of the current function. 116 | */ 117 | void dpas_pop_function(void); 118 | 119 | /* 120 | * Determine if the current function is nested. 121 | */ 122 | int dpas_function_is_nested(void); 123 | 124 | /* 125 | * Determine if a name corresponds to a builtin function, 126 | * and get its builtin identifier. Returns zero if not a builtin. 127 | */ 128 | int dpas_is_builtin(const char *name); 129 | 130 | /* 131 | * Expand a builtin function reference. 132 | */ 133 | dpas_semvalue dpas_expand_builtin 134 | (int identifier, dpas_semvalue *args, int num_args); 135 | 136 | /* 137 | * Add the current function to the execution list. Used for 138 | * "main" functions within each compiled module. 139 | */ 140 | void dpas_add_main_function(jit_function_t func); 141 | 142 | /* 143 | * Run the "main" functions in the order in which they were compiled. 144 | * Returns zero on an exception. 145 | */ 146 | int dpas_run_main_functions(void); 147 | 148 | #ifdef __cplusplus 149 | }; 150 | #endif 151 | 152 | #endif /* _DPAS_INTERNAL_H */ 153 | -------------------------------------------------------------------------------- /dpas/dpas-scope.h: -------------------------------------------------------------------------------- 1 | /* 2 | * dpas-scope.h - Scope handling for Dynamic Pascal. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _DPAS_SCOPE_H 24 | #define _DPAS_SCOPE_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Kinds of items that may be stored in a scope. 32 | */ 33 | #define DPAS_ITEM_TYPE 1 34 | #define DPAS_ITEM_VARIABLE 2 35 | #define DPAS_ITEM_GLOBAL_VARIABLE 3 36 | #define DPAS_ITEM_CONSTANT 4 37 | #define DPAS_ITEM_PROCEDURE 5 38 | #define DPAS_ITEM_WITH 6 39 | #define DPAS_ITEM_FUNC_RETURN 7 40 | 41 | /* 42 | * Opaque type that represents a scope. 43 | */ 44 | typedef struct dpas_scope *dpas_scope_t; 45 | 46 | /* 47 | * Opaque type that represents a scope item. 48 | */ 49 | typedef struct dpas_scope_item *dpas_scope_item_t; 50 | 51 | /* 52 | * Create a new scope, with a specified parent scope. If the parent 53 | * scope is NULL, then this creates the global scope. 54 | */ 55 | dpas_scope_t dpas_scope_create(dpas_scope_t parent); 56 | 57 | /* 58 | * Destroy a scope that is no longer required. 59 | */ 60 | void dpas_scope_destroy(dpas_scope_t scope); 61 | 62 | /* 63 | * Look up a name within a scope. If "up" is non-zero, then also 64 | * check the parent scopes. 65 | */ 66 | dpas_scope_item_t dpas_scope_lookup(dpas_scope_t scope, 67 | const char *name, int up); 68 | 69 | /* 70 | * Add an entry to a scope. 71 | */ 72 | void dpas_scope_add(dpas_scope_t scope, const char *name, jit_type_t type, 73 | int kind, void *info, jit_meta_free_func free_info, 74 | char *filename, long linenum); 75 | 76 | /* 77 | * Add a "with" field declaration to a scope. 78 | */ 79 | void dpas_scope_add_with(dpas_scope_t scope, jit_type_t type, 80 | void *with_info, jit_meta_free_func free_info); 81 | 82 | /* 83 | * Add a constant value to a scope. 84 | */ 85 | void dpas_scope_add_const(dpas_scope_t scope, const char *name, 86 | jit_constant_t *value, char *filename, long linenum); 87 | 88 | /* 89 | * Search a scope to look for undefined record types that were 90 | * referenced by a construct of the form "^name". 91 | */ 92 | void dpas_scope_check_undefined(dpas_scope_t scope); 93 | 94 | /* 95 | * Get the name associated with a scope item. 96 | */ 97 | const char *dpas_scope_item_name(dpas_scope_item_t item); 98 | 99 | /* 100 | * Get the kind associated with a scope item. 101 | */ 102 | int dpas_scope_item_kind(dpas_scope_item_t item); 103 | 104 | /* 105 | * Get the type associated with a scope item. 106 | */ 107 | jit_type_t dpas_scope_item_type(dpas_scope_item_t item); 108 | 109 | /* 110 | * Get the information block associated with a scope item. 111 | */ 112 | void *dpas_scope_item_info(dpas_scope_item_t item); 113 | 114 | /* 115 | * Set the information block associated with a scope item. 116 | */ 117 | void dpas_scope_item_set_info(dpas_scope_item_t item, void *info); 118 | 119 | /* 120 | * Get the filename associated with a scope item. 121 | */ 122 | const char *dpas_scope_item_filename(dpas_scope_item_t item); 123 | 124 | /* 125 | * Get the line number associated with a scope item. 126 | */ 127 | long dpas_scope_item_linenum(dpas_scope_item_t item); 128 | 129 | /* 130 | * Get the level associated with the current scope (global is zero). 131 | */ 132 | int dpas_scope_level(dpas_scope_t scope); 133 | 134 | /* 135 | * Get the current scope. 136 | */ 137 | dpas_scope_t dpas_scope_current(void); 138 | 139 | /* 140 | * Get the global scope. 141 | */ 142 | dpas_scope_t dpas_scope_global(void); 143 | 144 | /* 145 | * Create a new scope and push into it. 146 | */ 147 | dpas_scope_t dpas_scope_push(void); 148 | 149 | /* 150 | * Pop the current scope level and destroy it. 151 | */ 152 | void dpas_scope_pop(void); 153 | 154 | /* 155 | * Determine if the current scope is the module-global scope. 156 | */ 157 | int dpas_scope_is_module(void); 158 | 159 | #ifdef __cplusplus 160 | }; 161 | #endif 162 | 163 | #endif /* _DPAS_SCOPE_H */ 164 | -------------------------------------------------------------------------------- /include/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | SUBDIRS = jit 3 | -------------------------------------------------------------------------------- /include/jit/.gitignore: -------------------------------------------------------------------------------- 1 | jit-arch.h 2 | jit-defs.h 3 | jit-opcode.h 4 | -------------------------------------------------------------------------------- /include/jit/Makefile.am: -------------------------------------------------------------------------------- 1 | ARCH_HEADER = jit-arch-@JIT_ARCH@.h 2 | 3 | BUILT_SOURCES = jit-arch.h jit-opcode.h 4 | 5 | libjitincludedir = $(includedir)/jit 6 | dist_libjitinclude_HEADERS = \ 7 | jit.h \ 8 | jit-apply.h \ 9 | jit-block.h \ 10 | jit-common.h \ 11 | jit-context.h \ 12 | jit-debugger.h \ 13 | jit-defs.h \ 14 | jit-dump.h \ 15 | jit-dynamic.h \ 16 | jit-elf.h \ 17 | jit-except.h \ 18 | jit-function.h \ 19 | jit-init.h \ 20 | jit-insn.h \ 21 | jit-intrinsic.h \ 22 | jit-memory.h \ 23 | jit-meta.h \ 24 | jit-objmodel.h \ 25 | jit-objmodel-private.h \ 26 | jit-opcode-compat.h \ 27 | jit-opcode.h \ 28 | jit-plus.h \ 29 | jit-type.h \ 30 | jit-unwind.h \ 31 | jit-util.h \ 32 | jit-value.h \ 33 | jit-vmem.h \ 34 | jit-walk.h 35 | 36 | nodist_libjitinclude_HEADERS = \ 37 | jit-arch.h 38 | 39 | noinst_HEADERS = jit-arch-generic.h jit-arch-x86.h jit-arch-x86-64.h 40 | 41 | DISTCLEANFILES = jit-arch.h jit-defs.h jit-opcode.h 42 | 43 | jit-arch.h: $(ARCH_HEADER) 44 | rm -f $@ 45 | $(LN_S) $(srcdir)/$(ARCH_HEADER) $@ 46 | 47 | jit-opcode.h: $(top_srcdir)/jit/jit-opcodes.ops 48 | $(top_builddir)/tools/gen-ops -H $(top_srcdir)/jit/jit-opcodes.ops >jit-opcode.h 49 | -------------------------------------------------------------------------------- /include/jit/jit-apply.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-apply.h - Dynamic invocation and closure support functions. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_APPLY_H 24 | #define _JIT_APPLY_H 25 | 26 | #include 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | /* 33 | * Prototype for closure functions. 34 | */ 35 | typedef void (*jit_closure_func)(jit_type_t signature, void *result, 36 | void **args, void *user_data); 37 | 38 | /* 39 | * Opaque type for accessing vararg parameters on closures. 40 | */ 41 | typedef struct jit_closure_va_list *jit_closure_va_list_t; 42 | 43 | /* 44 | * External function declarations. 45 | */ 46 | void jit_apply(jit_type_t signature, void *func, 47 | void **args, unsigned int num_fixed_args, 48 | void *return_value); 49 | void jit_apply_raw(jit_type_t signature, void *func, 50 | void *args, void *return_value); 51 | int jit_raw_supported(jit_type_t signature); 52 | 53 | void *jit_closure_create(jit_context_t context, jit_type_t signature, 54 | jit_closure_func func, void *user_data); 55 | 56 | jit_nint jit_closure_va_get_nint(jit_closure_va_list_t va); 57 | jit_nuint jit_closure_va_get_nuint(jit_closure_va_list_t va); 58 | jit_long jit_closure_va_get_long(jit_closure_va_list_t va); 59 | jit_ulong jit_closure_va_get_ulong(jit_closure_va_list_t va); 60 | jit_float32 jit_closure_va_get_float32(jit_closure_va_list_t va); 61 | jit_float64 jit_closure_va_get_float64(jit_closure_va_list_t va); 62 | jit_nfloat jit_closure_va_get_nfloat(jit_closure_va_list_t va); 63 | void *jit_closure_va_get_ptr(jit_closure_va_list_t va); 64 | void jit_closure_va_get_struct(jit_closure_va_list_t va, void *buf, jit_type_t type); 65 | 66 | #ifdef __cplusplus 67 | }; 68 | #endif 69 | 70 | #endif /* _JIT_APPLY_H */ 71 | -------------------------------------------------------------------------------- /include/jit/jit-arch-arm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-arch-arm.h - Architecture-specific definitions. 3 | * 4 | * Copyright (C) 2006 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_ARCH_ARM_H 22 | #define _JIT_ARCH_ARM_H 23 | 24 | /* 25 | * If defined _JIT_ARCH_GET_CURRENT_FRAME() macro assigns the current frame 26 | * pointer to the supplied argument that has to be a void pointer. 27 | */ 28 | #if defined(__GNUC__) 29 | #define _JIT_ARCH_GET_CURRENT_FRAME(f) \ 30 | do { \ 31 | register void *__f asm("fp"); \ 32 | f = __f; \ 33 | } while(0) 34 | #else 35 | #undef _JIT_ARCH_GET_CURRENT_FRAME 36 | #endif 37 | 38 | #endif /* _JIT_ARCH_ARM_H */ 39 | -------------------------------------------------------------------------------- /include/jit/jit-arch-generic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-arch-generic.h - Architecture-specific definitions. 3 | * 4 | * Copyright (C) 2006 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_ARCH_GENERIC_H 24 | #define _JIT_ARCH_GENERIC_H 25 | 26 | /* 27 | * If defined _JIT_ARCH_GET_CURRENT_FRAME() macro assigns the current frame 28 | * pointer to the supplied argument that has to be a void pointer. 29 | */ 30 | #undef _JIT_ARCH_GET_CURRENT_FRAME 31 | 32 | /* 33 | * If defined _JIT_ARCH_GET_NEXT_FRAME() assigns the frame address following 34 | * the frame supplied as second arg to the value supplied as first argument. 35 | */ 36 | #undef _JIT_ARCH_GET_NEXT_FRAME 37 | 38 | /* 39 | * If defined _JIT_ARCH_GET_RETURN_ADDRESS() assigns the return address of 40 | * the frame supplied as second arg to the value supplied as first argument. 41 | */ 42 | #undef _JIT_ARCH_GET_RETURN_ADDRESS 43 | 44 | /* 45 | * If defined _JIT_ARCH_GET_CURRENT_RETURN() assigns the return address of 46 | * the current to the supplied argument. 47 | */ 48 | #define _JIT_ARCH_GET_CURRENT_RETURN 49 | 50 | #endif /* _JIT_ARCH_GENERIC_H */ 51 | -------------------------------------------------------------------------------- /include/jit/jit-arch-x86-64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-arch-x86.h - Architecture-specific definitions. 3 | * 4 | * Copyright (C) 2008 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_ARCH_X86_64_H 22 | #define _JIT_ARCH_X86_64_H 23 | 24 | /* 25 | * The frame header structure for X86_64 26 | */ 27 | typedef struct _jit_arch_frame _jit_arch_frame_t; 28 | struct _jit_arch_frame 29 | { 30 | _jit_arch_frame_t *next_frame; 31 | void *return_address; 32 | }; 33 | 34 | /* 35 | * If defined _JIT_ARCH_GET_CURRENT_FRAME() macro assigns the current frame 36 | * pointer to the supplied argument that has to be a void pointer. 37 | */ 38 | #if defined(__GNUC__) 39 | #define _JIT_ARCH_GET_CURRENT_FRAME(f) \ 40 | do { \ 41 | register void *__f asm("rbp"); \ 42 | f = __f; \ 43 | } while(0) 44 | #elif defined(_MSC_VER) && defined(_M_IX86) 45 | #define _JIT_ARCH_GET_CURRENT_FRAME(f) \ 46 | do { \ 47 | void *__ptr; \ 48 | __asm \ 49 | { \ 50 | __asm mov qword ptr __ptr, rbp \ 51 | } \ 52 | (f) = __ptr; \ 53 | } while(0) 54 | #else 55 | #undef _JIT_ARCH_GET_CURRENT_FRAME 56 | #endif 57 | 58 | /* 59 | * If defined _JIT_ARCH_GET_NEXT_FRAME() assigns the frame address following 60 | * the frame supplied as second arg to the value supplied as first argument. 61 | */ 62 | #define _JIT_ARCH_GET_NEXT_FRAME(n, f) \ 63 | do { \ 64 | (n) = (void *)((f) ? ((_jit_arch_frame_t *)(f))->next_frame : 0); \ 65 | } while(0) 66 | 67 | /* 68 | * If defined _JIT_ARCH_GET_RETURN_ADDRESS() assigns the return address of 69 | * the frame supplied as second arg to the value supplied as first argument. 70 | */ 71 | #define _JIT_ARCH_GET_RETURN_ADDRESS(r, f) \ 72 | do { \ 73 | (r) = (void *)((f) ? ((_jit_arch_frame_t *)(f))->return_address : 0); \ 74 | } while(0) 75 | 76 | /* 77 | * If defined _JIT_ARCH_GET_CURRENT_RETURN() assigns the return address of 78 | * the current to the supplied argument. 79 | */ 80 | #define _JIT_ARCH_GET_CURRENT_RETURN(r) \ 81 | do { \ 82 | void *__frame; \ 83 | _JIT_ARCH_GET_CURRENT_FRAME(__frame); \ 84 | _JIT_ARCH_GET_RETURN_ADDRESS((r), __frame); \ 85 | } while(0) 86 | 87 | #endif /* _JIT_ARCH_X86_64_H */ 88 | -------------------------------------------------------------------------------- /include/jit/jit-arch-x86.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-arch-x86.h - Architecture-specific definitions. 3 | * 4 | * Copyright (C) 2006 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_ARCH_X86_H 22 | #define _JIT_ARCH_X86_H 23 | 24 | /* 25 | * If defined _JIT_ARCH_GET_CURRENT_FRAME() macro assigns the current frame 26 | * pointer to the supplied argument that has to be a void pointer. 27 | */ 28 | #if defined(__GNUC__) 29 | #define _JIT_ARCH_GET_CURRENT_FRAME(f) \ 30 | do { \ 31 | register void *__f asm("ebp"); \ 32 | f = __f; \ 33 | } while(0) 34 | #elif defined(_MSC_VER) && defined(_M_IX86) 35 | #define _JIT_ARCH_GET_CURRENT_FRAME(f) \ 36 | do { \ 37 | void *__ptr; \ 38 | __asm \ 39 | { \ 40 | __asm mov dword ptr __ptr, ebp \ 41 | } \ 42 | (f) = __ptr; \ 43 | } while(0) 44 | #else 45 | #undef _JIT_ARCH_GET_CURRENT_FRAME 46 | #endif 47 | 48 | #endif /* _JIT_ARCH_X86_H */ 49 | -------------------------------------------------------------------------------- /include/jit/jit-block.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-block.h - Functions for manipulating blocks. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_BLOCK_H 22 | #define _JIT_BLOCK_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | jit_function_t jit_block_get_function(jit_block_t block) JIT_NOTHROW; 31 | jit_context_t jit_block_get_context(jit_block_t block) JIT_NOTHROW; 32 | jit_label_t jit_block_get_label(jit_block_t block) JIT_NOTHROW; 33 | jit_label_t jit_block_get_next_label(jit_block_t block, 34 | jit_label_t label) JIT_NOTHROW; 35 | jit_block_t jit_block_next(jit_function_t func, 36 | jit_block_t previous) JIT_NOTHROW; 37 | jit_block_t jit_block_previous(jit_function_t func, 38 | jit_block_t previous) JIT_NOTHROW; 39 | jit_block_t jit_block_from_label(jit_function_t func, 40 | jit_label_t label) JIT_NOTHROW; 41 | int jit_block_set_meta(jit_block_t block, int type, void *data, 42 | jit_meta_free_func free_data) JIT_NOTHROW; 43 | void *jit_block_get_meta(jit_block_t block, int type) JIT_NOTHROW; 44 | void jit_block_free_meta(jit_block_t block, int type) JIT_NOTHROW; 45 | int jit_block_is_reachable(jit_block_t block) JIT_NOTHROW; 46 | int jit_block_ends_in_dead(jit_block_t block) JIT_NOTHROW; 47 | int jit_block_current_is_dead(jit_function_t func) JIT_NOTHROW; 48 | 49 | #ifdef __cplusplus 50 | }; 51 | #endif 52 | 53 | #endif /* _JIT_BLOCK_H */ 54 | -------------------------------------------------------------------------------- /include/jit/jit-common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-common.h - Common type definitions that are used by the JIT. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_COMMON_H 22 | #define _JIT_COMMON_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Opaque structure that represents a context. 32 | */ 33 | typedef struct _jit_context *jit_context_t; 34 | 35 | /* 36 | * Opaque structure that represents a function. 37 | */ 38 | typedef struct _jit_function *jit_function_t; 39 | 40 | /* 41 | * Opaque structure that represents a block. 42 | */ 43 | typedef struct _jit_block *jit_block_t; 44 | 45 | /* 46 | * Opaque structure that represents an instruction. 47 | */ 48 | typedef struct _jit_insn *jit_insn_t; 49 | 50 | /* 51 | * Opaque structure that represents a value. 52 | */ 53 | typedef struct _jit_value *jit_value_t; 54 | 55 | /* 56 | * Opaque structure that represents a type descriptor. 57 | */ 58 | typedef struct _jit_type *jit_type_t; 59 | 60 | /* 61 | * Opaque type that represents an exception stack trace. 62 | */ 63 | typedef struct jit_stack_trace *jit_stack_trace_t; 64 | 65 | /* 66 | * Block label identifier. 67 | */ 68 | typedef jit_nuint jit_label_t; 69 | 70 | /* 71 | * Value that represents an undefined label. 72 | */ 73 | #define jit_label_undefined ((jit_label_t)~((jit_uint)0)) 74 | 75 | /* 76 | * Value that represents an undefined offset. 77 | */ 78 | #define JIT_NO_OFFSET (~((unsigned int)0)) 79 | 80 | /* 81 | * Function that is used to free user-supplied metadata. 82 | */ 83 | typedef void (*jit_meta_free_func)(void *data); 84 | 85 | /* 86 | * Function that is used to compile a function on demand. 87 | * Returns zero if the compilation process failed for some reason. 88 | */ 89 | typedef int (*jit_on_demand_func)(jit_function_t func); 90 | 91 | /* 92 | * Function that is used to control on demand compilation. 93 | * Typically, it should take care of the context locking and unlocking, 94 | * calling function's on demand compiler, and final compilation. 95 | */ 96 | typedef void *(*jit_on_demand_driver_func)(jit_function_t func); 97 | 98 | #ifdef __cplusplus 99 | }; 100 | #endif 101 | 102 | #endif /* _JIT_COMMON_H */ 103 | -------------------------------------------------------------------------------- /include/jit/jit-context.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-context.h - Functions for manipulating JIT contexts. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_CONTEXT_H 22 | #define _JIT_CONTEXT_H 23 | 24 | #include 25 | #include 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | jit_context_t jit_context_create(void) JIT_NOTHROW; 32 | void jit_context_destroy(jit_context_t context) JIT_NOTHROW; 33 | 34 | void jit_context_build_start(jit_context_t context) JIT_NOTHROW; 35 | void jit_context_build_end(jit_context_t context) JIT_NOTHROW; 36 | 37 | void jit_context_set_on_demand_driver( 38 | jit_context_t context, 39 | jit_on_demand_driver_func driver) JIT_NOTHROW; 40 | 41 | void jit_context_set_memory_manager( 42 | jit_context_t context, 43 | jit_memory_manager_t manager) JIT_NOTHROW; 44 | 45 | int jit_context_set_meta 46 | (jit_context_t context, int type, void *data, 47 | jit_meta_free_func free_data) JIT_NOTHROW; 48 | int jit_context_set_meta_numeric 49 | (jit_context_t context, int type, jit_nuint data) JIT_NOTHROW; 50 | void *jit_context_get_meta(jit_context_t context, int type) JIT_NOTHROW; 51 | jit_nuint jit_context_get_meta_numeric 52 | (jit_context_t context, int type) JIT_NOTHROW; 53 | void jit_context_free_meta(jit_context_t context, int type) JIT_NOTHROW; 54 | 55 | /* 56 | * Standard meta values for builtin configurable options. 57 | */ 58 | #define JIT_OPTION_CACHE_LIMIT 10000 59 | #define JIT_OPTION_CACHE_PAGE_SIZE 10001 60 | #define JIT_OPTION_PRE_COMPILE 10002 61 | #define JIT_OPTION_DONT_FOLD 10003 62 | #define JIT_OPTION_POSITION_INDEPENDENT 10004 63 | #define JIT_OPTION_CACHE_MAX_PAGE_FACTOR 10005 64 | 65 | #ifdef __cplusplus 66 | }; 67 | #endif 68 | 69 | #endif /* _JIT_CONTEXT_H */ 70 | -------------------------------------------------------------------------------- /include/jit/jit-defs.h.in: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-defs.h - Define the primitive numeric types for use by the JIT. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_DEFS_H 22 | #define _JIT_DEFS_H 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | #ifdef _MSC_VER 29 | #define JIT_EXPORT_DATA extern __declspec(dllimport) 30 | #else 31 | #define JIT_EXPORT_DATA extern 32 | #endif 33 | 34 | @JIT_INT64_INCLUDE@ 35 | 36 | typedef @JITINT8@ jit_sbyte; 37 | typedef @JITUINT8@ jit_ubyte; 38 | typedef @JITINT16@ jit_short; 39 | typedef unsigned @JITINT16@ jit_ushort; 40 | typedef @JITINT32@ jit_int; 41 | typedef unsigned @JITINT32@ jit_uint; 42 | typedef @JITNATIVEINT@ jit_nint; 43 | typedef unsigned @JITNATIVEINT@ jit_nuint; 44 | #if defined(__cplusplus) && defined(__GNUC__) 45 | typedef @JITINT64CXX@ jit_long; 46 | typedef unsigned @JITINT64CXX@ jit_ulong; 47 | #else 48 | typedef @JITINT64@ jit_long; 49 | typedef unsigned @JITINT64@ jit_ulong; 50 | #endif 51 | typedef @JITFLOAT32@ jit_float32; 52 | typedef @JITFLOAT64@ jit_float64; 53 | typedef @JITNATIVEFLOAT@ jit_nfloat; 54 | typedef void *jit_ptr; 55 | 56 | #define @JITNATIVEINTDEFINE@ 1 57 | @JITNFLOATISDOUBLE@ 58 | 59 | #if defined(__cplusplus) && defined(__GNUC__) 60 | #define JIT_NOTHROW @JITTHROWIDIOM@ 61 | #else 62 | #define JIT_NOTHROW 63 | #endif 64 | 65 | #define jit_min_int (((jit_int)1) << (sizeof(jit_int) * 8 - 1)) 66 | #define jit_max_int ((jit_int)(~jit_min_int)) 67 | #define jit_max_uint ((jit_uint)(~((jit_uint)0))) 68 | #define jit_min_long (((jit_long)1) << (sizeof(jit_long) * 8 - 1)) 69 | #define jit_max_long ((jit_long)(~jit_min_long)) 70 | #define jit_max_ulong ((jit_ulong)(~((jit_ulong)0))) 71 | 72 | #ifdef __cplusplus 73 | }; 74 | #endif 75 | 76 | #endif /* _JIT_DEFS_H */ 77 | -------------------------------------------------------------------------------- /include/jit/jit-dump.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-dump.h - Functions for dumping JIT structures, for debugging. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_DUMP_H 22 | #define _JIT_DUMP_H 23 | 24 | #include 25 | #include 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | void jit_dump_type(FILE *stream, jit_type_t type) JIT_NOTHROW; 32 | void jit_dump_value 33 | (FILE *stream, jit_function_t func, 34 | jit_value_t value, const char *prefix) JIT_NOTHROW; 35 | void jit_dump_insn 36 | (FILE *stream, jit_function_t func, jit_insn_t insn) JIT_NOTHROW; 37 | void jit_dump_function 38 | (FILE *stream, jit_function_t func, const char *name) JIT_NOTHROW; 39 | 40 | #ifdef __cplusplus 41 | }; 42 | #endif 43 | 44 | #endif /* _JIT_DUMP_H */ 45 | -------------------------------------------------------------------------------- /include/jit/jit-dynamic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-dynamic.h - Managing dynamic libraries and cross-language invocation. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_DYNAMIC_H 22 | #define _JIT_DYNAMIC_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Dynamic library routines. 32 | */ 33 | typedef void *jit_dynlib_handle_t; 34 | jit_dynlib_handle_t jit_dynlib_open(const char *name) JIT_NOTHROW; 35 | void jit_dynlib_close(jit_dynlib_handle_t handle) JIT_NOTHROW; 36 | void *jit_dynlib_get_symbol 37 | (jit_dynlib_handle_t handle, const char *symbol) JIT_NOTHROW; 38 | const char *jit_dynlib_get_suffix(void) JIT_NOTHROW; 39 | void jit_dynlib_set_debug(int flag) JIT_NOTHROW; 40 | 41 | /* 42 | * C++ name mangling definitions. 43 | */ 44 | #define JIT_MANGLE_PUBLIC 0x0001 45 | #define JIT_MANGLE_PROTECTED 0x0002 46 | #define JIT_MANGLE_PRIVATE 0x0003 47 | #define JIT_MANGLE_STATIC 0x0008 48 | #define JIT_MANGLE_VIRTUAL 0x0010 49 | #define JIT_MANGLE_CONST 0x0020 50 | #define JIT_MANGLE_EXPLICIT_THIS 0x0040 51 | #define JIT_MANGLE_IS_CTOR 0x0080 52 | #define JIT_MANGLE_IS_DTOR 0x0100 53 | #define JIT_MANGLE_BASE 0x0200 54 | char *jit_mangle_global_function 55 | (const char *name, jit_type_t signature, int form) JIT_NOTHROW; 56 | char *jit_mangle_member_function 57 | (const char *class_name, const char *name, 58 | jit_type_t signature, int form, int flags) JIT_NOTHROW; 59 | 60 | #ifdef __cplusplus 61 | }; 62 | #endif 63 | 64 | #endif /* _JIT_DYNAMIC_H */ 65 | -------------------------------------------------------------------------------- /include/jit/jit-elf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * - Routines to read and write ELF-format binaries. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_ELF_H 22 | #define _JIT_ELF_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Opaque types that represent a loaded ELF binary in read or write mode. 32 | */ 33 | typedef struct jit_readelf *jit_readelf_t; 34 | typedef struct jit_writeelf *jit_writeelf_t; 35 | 36 | /* 37 | * Flags for "jit_readelf_open". 38 | */ 39 | #define JIT_READELF_FLAG_FORCE (1 << 0) /* Force file to load */ 40 | #define JIT_READELF_FLAG_DEBUG (1 << 1) /* Print debugging information */ 41 | 42 | /* 43 | * Result codes from "jit_readelf_open". 44 | */ 45 | #define JIT_READELF_OK 0 /* File was opened successfully */ 46 | #define JIT_READELF_CANNOT_OPEN 1 /* Could not open the file */ 47 | #define JIT_READELF_NOT_ELF 2 /* Not an ELF-format binary */ 48 | #define JIT_READELF_WRONG_ARCH 3 /* Wrong architecture for local system */ 49 | #define JIT_READELF_BAD_FORMAT 4 /* ELF file, but badly formatted */ 50 | #define JIT_READELF_MEMORY 5 /* Insufficient memory to load the file */ 51 | 52 | /* 53 | * External function declarations. 54 | */ 55 | int jit_readelf_open 56 | (jit_readelf_t *readelf, const char *filename, int flags) JIT_NOTHROW; 57 | void jit_readelf_close(jit_readelf_t readelf) JIT_NOTHROW; 58 | const char *jit_readelf_get_name(jit_readelf_t readelf) JIT_NOTHROW; 59 | void *jit_readelf_get_symbol 60 | (jit_readelf_t readelf, const char *name) JIT_NOTHROW; 61 | void *jit_readelf_get_section 62 | (jit_readelf_t readelf, const char *name, jit_nuint *size) JIT_NOTHROW; 63 | void *jit_readelf_get_section_by_type 64 | (jit_readelf_t readelf, jit_int type, jit_nuint *size) JIT_NOTHROW; 65 | void *jit_readelf_map_vaddr 66 | (jit_readelf_t readelf, jit_nuint vaddr) JIT_NOTHROW; 67 | unsigned int jit_readelf_num_needed(jit_readelf_t readelf) JIT_NOTHROW; 68 | const char *jit_readelf_get_needed 69 | (jit_readelf_t readelf, unsigned int index) JIT_NOTHROW; 70 | void jit_readelf_add_to_context 71 | (jit_readelf_t readelf, jit_context_t context) JIT_NOTHROW; 72 | int jit_readelf_resolve_all 73 | (jit_context_t context, int print_failures) JIT_NOTHROW; 74 | int jit_readelf_register_symbol 75 | (jit_context_t context, const char *name, 76 | void *value, int after) JIT_NOTHROW; 77 | 78 | jit_writeelf_t jit_writeelf_create(const char *library_name) JIT_NOTHROW; 79 | void jit_writeelf_destroy(jit_writeelf_t writeelf) JIT_NOTHROW; 80 | int jit_writeelf_write 81 | (jit_writeelf_t writeelf, const char *filename) JIT_NOTHROW; 82 | int jit_writeelf_add_function 83 | (jit_writeelf_t writeelf, jit_function_t func, 84 | const char *name) JIT_NOTHROW; 85 | int jit_writeelf_add_needed 86 | (jit_writeelf_t writeelf, const char *library_name) JIT_NOTHROW; 87 | int jit_writeelf_write_section 88 | (jit_writeelf_t writeelf, const char *name, jit_int type, 89 | const void *buf, unsigned int len, int discardable) JIT_NOTHROW; 90 | 91 | #ifdef __cplusplus 92 | }; 93 | #endif 94 | 95 | #endif /* _JIT_ELF_H */ 96 | -------------------------------------------------------------------------------- /include/jit/jit-except.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-except.h - Exception handling functions. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_EXCEPT_H 22 | #define _JIT_EXCEPT_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Builtin exception type codes, and result values for intrinsic functions. 32 | */ 33 | #define JIT_RESULT_OK (1) 34 | #define JIT_RESULT_OVERFLOW (0) 35 | #define JIT_RESULT_ARITHMETIC (-1) 36 | #define JIT_RESULT_DIVISION_BY_ZERO (-2) 37 | #define JIT_RESULT_COMPILE_ERROR (-3) 38 | #define JIT_RESULT_OUT_OF_MEMORY (-4) 39 | #define JIT_RESULT_NULL_REFERENCE (-5) 40 | #define JIT_RESULT_NULL_FUNCTION (-6) 41 | #define JIT_RESULT_CALLED_NESTED (-7) 42 | #define JIT_RESULT_OUT_OF_BOUNDS (-8) 43 | #define JIT_RESULT_UNDEFINED_LABEL (-9) 44 | #define JIT_RESULT_MEMORY_FULL (-10000) 45 | 46 | /* 47 | * Exception handling function for builtin exceptions. 48 | */ 49 | typedef void *(*jit_exception_func)(int exception_type); 50 | 51 | /* 52 | * External function declarations. 53 | */ 54 | void *jit_exception_get_last(void); 55 | void *jit_exception_get_last_and_clear(void); 56 | void jit_exception_set_last(void *object); 57 | void jit_exception_clear_last(void); 58 | void jit_exception_throw(void *object); 59 | void jit_exception_builtin(int exception_type); 60 | jit_exception_func jit_exception_set_handler(jit_exception_func handler); 61 | jit_exception_func jit_exception_get_handler(void); 62 | jit_stack_trace_t jit_exception_get_stack_trace(void); 63 | unsigned int jit_stack_trace_get_size(jit_stack_trace_t trace); 64 | jit_function_t jit_stack_trace_get_function(jit_context_t context, 65 | jit_stack_trace_t trace, 66 | unsigned int posn); 67 | void *jit_stack_trace_get_pc(jit_stack_trace_t trace, unsigned int posn); 68 | unsigned int jit_stack_trace_get_offset(jit_context_t context, 69 | jit_stack_trace_t trace, 70 | unsigned int posn); 71 | void jit_stack_trace_free(jit_stack_trace_t trace); 72 | 73 | #ifdef __cplusplus 74 | }; 75 | #endif 76 | 77 | #endif /* _JIT_EXCEPT_H */ 78 | -------------------------------------------------------------------------------- /include/jit/jit-function.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-function.h - Functions for manipulating functions blocks. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_FUNCTION_H 22 | #define _JIT_FUNCTION_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* Optimization levels */ 31 | #define JIT_OPTLEVEL_NONE 0 32 | #define JIT_OPTLEVEL_NORMAL 1 33 | 34 | jit_function_t jit_function_create 35 | (jit_context_t context, jit_type_t signature) JIT_NOTHROW; 36 | jit_function_t jit_function_create_nested 37 | (jit_context_t context, jit_type_t signature, 38 | jit_function_t parent) JIT_NOTHROW; 39 | void jit_function_abandon(jit_function_t func) JIT_NOTHROW; 40 | jit_context_t jit_function_get_context(jit_function_t func) JIT_NOTHROW; 41 | jit_type_t jit_function_get_signature(jit_function_t func) JIT_NOTHROW; 42 | int jit_function_set_meta 43 | (jit_function_t func, int type, void *data, 44 | jit_meta_free_func free_data, int build_only) JIT_NOTHROW; 45 | void *jit_function_get_meta(jit_function_t func, int type) JIT_NOTHROW; 46 | void jit_function_free_meta(jit_function_t func, int type) JIT_NOTHROW; 47 | jit_function_t jit_function_next 48 | (jit_context_t context, jit_function_t prev) JIT_NOTHROW; 49 | jit_function_t jit_function_previous 50 | (jit_context_t context, jit_function_t prev) JIT_NOTHROW; 51 | jit_block_t jit_function_get_entry(jit_function_t func) JIT_NOTHROW; 52 | jit_block_t jit_function_get_current(jit_function_t func) JIT_NOTHROW; 53 | jit_function_t jit_function_get_nested_parent(jit_function_t func) JIT_NOTHROW; 54 | int jit_function_compile(jit_function_t func) JIT_NOTHROW; 55 | int jit_function_is_compiled(jit_function_t func) JIT_NOTHROW; 56 | void jit_function_set_recompilable(jit_function_t func) JIT_NOTHROW; 57 | void jit_function_clear_recompilable(jit_function_t func) JIT_NOTHROW; 58 | int jit_function_is_recompilable(jit_function_t func) JIT_NOTHROW; 59 | int jit_function_compile_entry(jit_function_t func, void **entry_point) JIT_NOTHROW; 60 | void jit_function_setup_entry(jit_function_t func, void *entry_point) JIT_NOTHROW; 61 | void *jit_function_to_closure(jit_function_t func) JIT_NOTHROW; 62 | jit_function_t jit_function_from_closure 63 | (jit_context_t context, void *closure) JIT_NOTHROW; 64 | jit_function_t jit_function_from_pc 65 | (jit_context_t context, void *pc, void **handler) JIT_NOTHROW; 66 | void *jit_function_to_vtable_pointer(jit_function_t func) JIT_NOTHROW; 67 | jit_function_t jit_function_from_vtable_pointer 68 | (jit_context_t context, void *vtable_pointer) JIT_NOTHROW; 69 | void jit_function_set_on_demand_compiler 70 | (jit_function_t func, jit_on_demand_func on_demand) JIT_NOTHROW; 71 | jit_on_demand_func jit_function_get_on_demand_compiler(jit_function_t func) JIT_NOTHROW; 72 | int jit_function_apply 73 | (jit_function_t func, void **args, void *return_area); 74 | int jit_function_apply_vararg 75 | (jit_function_t func, jit_type_t signature, void **args, void *return_area); 76 | void jit_function_set_optimization_level 77 | (jit_function_t func, unsigned int level) JIT_NOTHROW; 78 | unsigned int jit_function_get_optimization_level 79 | (jit_function_t func) JIT_NOTHROW; 80 | unsigned int jit_function_get_max_optimization_level(void) JIT_NOTHROW; 81 | jit_label_t jit_function_reserve_label(jit_function_t func) JIT_NOTHROW; 82 | int jit_function_labels_equal(jit_function_t func, jit_label_t label, jit_label_t label2); 83 | 84 | #ifdef __cplusplus 85 | }; 86 | #endif 87 | 88 | #endif /* _JIT_FUNCTION_H */ 89 | -------------------------------------------------------------------------------- /include/jit/jit-init.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-init.h - Initialization routines for the JIT. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_INIT_H 22 | #define _JIT_INIT_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | void jit_init(void) JIT_NOTHROW; 31 | 32 | int jit_uses_interpreter(void) JIT_NOTHROW; 33 | 34 | int jit_supports_threads(void) JIT_NOTHROW; 35 | 36 | int jit_supports_virtual_memory(void) JIT_NOTHROW; 37 | 38 | int jit_supports_closures(void); 39 | 40 | unsigned int jit_get_closure_size(void); 41 | unsigned int jit_get_closure_alignment(void); 42 | unsigned int jit_get_trampoline_size(void); 43 | unsigned int jit_get_trampoline_alignment(void); 44 | 45 | #ifdef __cplusplus 46 | }; 47 | #endif 48 | 49 | #endif /* _JIT_INIT_H */ 50 | -------------------------------------------------------------------------------- /include/jit/jit-memory.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-memory.h - Memory management. 3 | * 4 | * Copyright (C) 2012 Aleksey Demakov 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_MEMORY_H 22 | #define _JIT_MEMORY_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Result values for "_jit_cache_start_function" and "_jit_cache_end_function". 32 | */ 33 | #define JIT_MEMORY_OK 0 /* Function is OK */ 34 | #define JIT_MEMORY_RESTART 1 /* Restart is required */ 35 | #define JIT_MEMORY_TOO_BIG 2 /* Function is too big for the cache */ 36 | #define JIT_MEMORY_ERROR 3 /* Other error */ 37 | 38 | 39 | /* TODO: the proper place for this is jit-def.h and it's going to depend on the platform. */ 40 | typedef unsigned int jit_size_t; 41 | 42 | typedef void *jit_memory_context_t; 43 | typedef void *jit_function_info_t; 44 | 45 | typedef struct jit_memory_manager const* jit_memory_manager_t; 46 | 47 | struct jit_memory_manager 48 | { 49 | jit_memory_context_t (*create)(jit_context_t context); 50 | void (*destroy)(jit_memory_context_t memctx); 51 | 52 | jit_function_info_t (*find_function_info)(jit_memory_context_t memctx, void *pc); 53 | jit_function_t (*get_function)(jit_memory_context_t memctx, jit_function_info_t info); 54 | void * (*get_function_start)(jit_memory_context_t memctx, jit_function_info_t info); 55 | void * (*get_function_end)(jit_memory_context_t memctx, jit_function_info_t info); 56 | 57 | jit_function_t (*alloc_function)(jit_memory_context_t memctx); 58 | void (*free_function)(jit_memory_context_t memctx, jit_function_t func); 59 | 60 | int (*start_function)(jit_memory_context_t memctx, jit_function_t func); 61 | int (*end_function)(jit_memory_context_t memctx, int result); 62 | int (*extend_limit)(jit_memory_context_t memctx, int count); 63 | 64 | void * (*get_limit)(jit_memory_context_t memctx); 65 | void * (*get_break)(jit_memory_context_t memctx); 66 | void (*set_break)(jit_memory_context_t memctx, void *brk); 67 | 68 | void * (*alloc_trampoline)(jit_memory_context_t memctx); 69 | void (*free_trampoline)(jit_memory_context_t memctx, void *ptr); 70 | 71 | void * (*alloc_closure)(jit_memory_context_t memctx); 72 | void (*free_closure)(jit_memory_context_t memctx, void *ptr); 73 | 74 | void * (*alloc_data)(jit_memory_context_t memctx, jit_size_t size, jit_size_t align); 75 | }; 76 | 77 | jit_memory_manager_t jit_default_memory_manager(void) JIT_NOTHROW; 78 | 79 | #ifdef __cplusplus 80 | } 81 | #endif 82 | 83 | #endif /* _JIT_MEMORY_H */ 84 | -------------------------------------------------------------------------------- /include/jit/jit-meta.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-meta.h - Manipulate lists of metadata values. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_META_H 22 | #define _JIT_META_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | typedef struct _jit_meta *jit_meta_t; 31 | 32 | int jit_meta_set 33 | (jit_meta_t *list, int type, void *data, 34 | jit_meta_free_func free_data, jit_function_t pool_owner) JIT_NOTHROW; 35 | void *jit_meta_get(jit_meta_t list, int type) JIT_NOTHROW; 36 | void jit_meta_free(jit_meta_t *list, int type) JIT_NOTHROW; 37 | void jit_meta_destroy(jit_meta_t *list) JIT_NOTHROW; 38 | 39 | #ifdef __cplusplus 40 | }; 41 | #endif 42 | 43 | #endif /* _JIT_META_H */ 44 | -------------------------------------------------------------------------------- /include/jit/jit-opcode-compat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-opcode-compat.h - Definition of obsolete opcodes for compatibility 3 | * reasons. 4 | * 5 | * Copyright (C) 2011 Southern Storm Software, Pty Ltd. 6 | * 7 | * The libjit library is free software: you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public License 9 | * as published by the Free Software Foundation, either version 2.1 of 10 | * the License, or (at your option) any later version. 11 | * 12 | * The libjit library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with the libjit library. If not, see 19 | * . 20 | */ 21 | 22 | #ifndef _JIT_OPCODE_COMPAT_H 23 | #define _JIT_OPCODE_COMPAT_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /* 30 | * Some obsolete opcodes that have been removed because they are duplicates 31 | * of other opcodes. 32 | */ 33 | #define JIT_OP_FEQ_INV JIT_OP_FEQ 34 | #define JIT_OP_FNE_INV JIT_OP_FNE 35 | #define JIT_OP_DEQ_INV JIT_OP_DEQ 36 | #define JIT_OP_DNE_INV JIT_OP_DNE 37 | #define JIT_OP_NFEQ_INV JIT_OP_NFEQ 38 | #define JIT_OP_NFNE_INV JIT_OP_NFNE 39 | #define JIT_OP_BR_FEQ_INV JIT_OP_BR_FEQ 40 | #define JIT_OP_BR_FNE_INV JIT_OP_BR_FNE 41 | #define JIT_OP_BR_DEQ_INV JIT_OP_BR_DEQ 42 | #define JIT_OP_BR_DNE_INV JIT_OP_BR_DNE 43 | #define JIT_OP_BR_NFEQ_INV JIT_OP_BR_NFEQ 44 | #define JIT_OP_BR_NFNE_INV JIT_OP_BR_NFNE 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | 50 | #endif /* _JIT_VMEM_H */ 51 | -------------------------------------------------------------------------------- /include/jit/jit-unwind.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-unwind.h - Routines for performing stack unwinding. 3 | * 4 | * Copyright (C) 2008 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_UNWIND_H 24 | #define _JIT_UNWIND_H 25 | 26 | #include 27 | #include 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | typedef struct 34 | { 35 | void *frame; 36 | void *cache; 37 | jit_context_t context; 38 | #ifdef _JIT_ARCH_UNWIND_DATA 39 | _JIT_ARCH_UNWIND_DATA 40 | #endif 41 | } jit_unwind_context_t; 42 | 43 | int jit_unwind_init(jit_unwind_context_t *unwind, jit_context_t context); 44 | void jit_unwind_free(jit_unwind_context_t *unwind); 45 | 46 | int jit_unwind_next(jit_unwind_context_t *unwind); 47 | int jit_unwind_next_pc(jit_unwind_context_t *unwind); 48 | void *jit_unwind_get_pc(jit_unwind_context_t *unwind); 49 | 50 | int jit_unwind_jump(jit_unwind_context_t *unwind, void *pc); 51 | 52 | jit_function_t jit_unwind_get_function(jit_unwind_context_t *unwind); 53 | unsigned int jit_unwind_get_offset(jit_unwind_context_t *unwind); 54 | 55 | #ifdef __cplusplus 56 | }; 57 | #endif 58 | 59 | #endif /* _JIT_UNWIND_H */ 60 | -------------------------------------------------------------------------------- /include/jit/jit-util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-util.h - Utility functions. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_UTIL_H 22 | #define _JIT_UTIL_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Memory allocation routines. 32 | */ 33 | void *jit_malloc(unsigned int size) JIT_NOTHROW; 34 | void *jit_calloc(unsigned int num, unsigned int size) JIT_NOTHROW; 35 | void *jit_realloc(void *ptr, unsigned int size) JIT_NOTHROW; 36 | void jit_free(void *ptr) JIT_NOTHROW; 37 | 38 | #define jit_new(type) ((type *)jit_malloc(sizeof(type))) 39 | #define jit_cnew(type) ((type *)jit_calloc(1, sizeof(type))) 40 | 41 | /* 42 | * Memory set/copy/compare routines. 43 | */ 44 | void *jit_memset(void *dest, int ch, unsigned int len) JIT_NOTHROW; 45 | void *jit_memcpy(void *dest, const void *src, unsigned int len) JIT_NOTHROW; 46 | void *jit_memmove(void *dest, const void *src, unsigned int len) JIT_NOTHROW; 47 | int jit_memcmp(const void *s1, const void *s2, unsigned int len) JIT_NOTHROW; 48 | void *jit_memchr(const void *str, int ch, unsigned int len) JIT_NOTHROW; 49 | 50 | /* 51 | * String routines. 52 | */ 53 | unsigned int jit_strlen(const char *str) JIT_NOTHROW; 54 | char *jit_strcpy(char *dest, const char *src) JIT_NOTHROW; 55 | char *jit_strcat(char *dest, const char *src) JIT_NOTHROW; 56 | char *jit_strncpy(char *dest, const char *src, unsigned int len) JIT_NOTHROW; 57 | char *jit_strdup(const char *str) JIT_NOTHROW; 58 | char *jit_strndup(const char *str, unsigned int len) JIT_NOTHROW; 59 | int jit_strcmp(const char *str1, const char *str2) JIT_NOTHROW; 60 | int jit_strncmp 61 | (const char *str1, const char *str2, unsigned int len) JIT_NOTHROW; 62 | int jit_stricmp(const char *str1, const char *str2) JIT_NOTHROW; 63 | int jit_strnicmp 64 | (const char *str1, const char *str2, unsigned int len) JIT_NOTHROW; 65 | char *jit_strchr(const char *str, int ch) JIT_NOTHROW; 66 | char *jit_strrchr(const char *str, int ch) JIT_NOTHROW; 67 | int jit_sprintf(char *str, const char *format, ...) JIT_NOTHROW; 68 | int jit_snprintf 69 | (char *str, unsigned int len, const char *format, ...) JIT_NOTHROW; 70 | 71 | #ifdef __cplusplus 72 | }; 73 | #endif 74 | 75 | #endif /* _JIT_UTIL_H */ 76 | -------------------------------------------------------------------------------- /include/jit/jit-value.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-value.h - Functions for manipulating temporary values. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_VALUE_H 22 | #define _JIT_VALUE_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Full struction that can hold a constant of any type. 32 | */ 33 | typedef struct 34 | { 35 | jit_type_t type; 36 | union 37 | { 38 | void *ptr_value; 39 | jit_int int_value; 40 | jit_uint uint_value; 41 | jit_nint nint_value; 42 | jit_nuint nuint_value; 43 | jit_long long_value; 44 | jit_ulong ulong_value; 45 | jit_float32 float32_value; 46 | jit_float64 float64_value; 47 | jit_nfloat nfloat_value; 48 | 49 | } un; 50 | 51 | } jit_constant_t; 52 | 53 | /* 54 | * External function declarations. 55 | */ 56 | jit_value_t jit_value_create(jit_function_t func, jit_type_t type) JIT_NOTHROW; 57 | jit_value_t jit_value_create_nint_constant 58 | (jit_function_t func, jit_type_t type, jit_nint const_value) JIT_NOTHROW; 59 | jit_value_t jit_value_create_long_constant 60 | (jit_function_t func, jit_type_t type, jit_long const_value) JIT_NOTHROW; 61 | jit_value_t jit_value_create_float32_constant 62 | (jit_function_t func, jit_type_t type, 63 | jit_float32 const_value) JIT_NOTHROW; 64 | jit_value_t jit_value_create_float64_constant 65 | (jit_function_t func, jit_type_t type, 66 | jit_float64 const_value) JIT_NOTHROW; 67 | jit_value_t jit_value_create_nfloat_constant 68 | (jit_function_t func, jit_type_t type, 69 | jit_nfloat const_value) JIT_NOTHROW; 70 | jit_value_t jit_value_create_constant 71 | (jit_function_t func, const jit_constant_t *const_value) JIT_NOTHROW; 72 | jit_value_t jit_value_get_param 73 | (jit_function_t func, unsigned int param) JIT_NOTHROW; 74 | jit_value_t jit_value_get_struct_pointer(jit_function_t func) JIT_NOTHROW; 75 | int jit_value_is_temporary(jit_value_t value) JIT_NOTHROW; 76 | int jit_value_is_local(jit_value_t value) JIT_NOTHROW; 77 | int jit_value_is_constant(jit_value_t value) JIT_NOTHROW; 78 | int jit_value_is_parameter(jit_value_t value) JIT_NOTHROW; 79 | void jit_value_ref(jit_function_t func, jit_value_t value) JIT_NOTHROW; 80 | void jit_value_set_volatile(jit_value_t value) JIT_NOTHROW; 81 | int jit_value_is_volatile(jit_value_t value) JIT_NOTHROW; 82 | void jit_value_set_addressable(jit_value_t value) JIT_NOTHROW; 83 | int jit_value_is_addressable(jit_value_t value) JIT_NOTHROW; 84 | jit_type_t jit_value_get_type(jit_value_t value) JIT_NOTHROW; 85 | jit_function_t jit_value_get_function(jit_value_t value) JIT_NOTHROW; 86 | jit_block_t jit_value_get_block(jit_value_t value) JIT_NOTHROW; 87 | jit_context_t jit_value_get_context(jit_value_t value) JIT_NOTHROW; 88 | jit_constant_t jit_value_get_constant(jit_value_t value) JIT_NOTHROW; 89 | jit_nint jit_value_get_nint_constant(jit_value_t value) JIT_NOTHROW; 90 | jit_long jit_value_get_long_constant(jit_value_t value) JIT_NOTHROW; 91 | jit_float32 jit_value_get_float32_constant(jit_value_t value) JIT_NOTHROW; 92 | jit_float64 jit_value_get_float64_constant(jit_value_t value) JIT_NOTHROW; 93 | jit_nfloat jit_value_get_nfloat_constant(jit_value_t value) JIT_NOTHROW; 94 | int jit_value_is_true(jit_value_t value) JIT_NOTHROW; 95 | int jit_constant_convert 96 | (jit_constant_t *result, const jit_constant_t *value, 97 | jit_type_t type, int overflow_check) JIT_NOTHROW; 98 | 99 | #ifdef __cplusplus 100 | }; 101 | #endif 102 | 103 | #endif /* _JIT_VALUE_H */ 104 | -------------------------------------------------------------------------------- /include/jit/jit-vmem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-vmem.h - Virtual memory routines. 3 | * 4 | * Copyright (C) 2011 Aleksey Demakov 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_VMEM_H 22 | #define _JIT_VMEM_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | typedef enum { 31 | JIT_PROT_NONE, 32 | JIT_PROT_READ, 33 | JIT_PROT_READ_WRITE, 34 | JIT_PROT_EXEC_READ, 35 | JIT_PROT_EXEC_READ_WRITE, 36 | } jit_prot_t; 37 | 38 | 39 | void jit_vmem_init(void); 40 | 41 | jit_uint jit_vmem_page_size(void); 42 | jit_nuint jit_vmem_round_up(jit_nuint value); 43 | jit_nuint jit_vmem_round_down(jit_nuint value); 44 | 45 | void *jit_vmem_reserve(jit_uint size); 46 | void *jit_vmem_reserve_committed(jit_uint size, jit_prot_t prot); 47 | int jit_vmem_release(void *addr, jit_uint size); 48 | 49 | int jit_vmem_commit(void *addr, jit_uint size, jit_prot_t prot); 50 | int jit_vmem_decommit(void *addr, jit_uint size); 51 | 52 | int jit_vmem_protect(void *addr, jit_uint size, jit_prot_t prot); 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | 58 | #endif /* _JIT_VMEM_H */ 59 | -------------------------------------------------------------------------------- /include/jit/jit-walk.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-walk.h - Functions for walking stack frames. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_WALK_H 22 | #define _JIT_WALK_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Get the frame address for a frame which is "n" levels up the stack. 32 | * A level value of zero indicates the current frame. 33 | */ 34 | void *_jit_get_frame_address(void *start, unsigned int n); 35 | #if defined(__GNUC__) 36 | # define jit_get_frame_address(n) \ 37 | (_jit_get_frame_address(jit_get_current_frame(), (n))) 38 | #else 39 | # define jit_get_frame_address(n) (_jit_get_frame_address(0, (n))) 40 | #endif 41 | 42 | /* 43 | * Get the frame address for the current frame. May be more efficient 44 | * than using "jit_get_frame_address(0)". 45 | * 46 | * Note: some gcc vestions have broken __builtin_frame_address() so use 47 | * _JIT_ARCH_GET_CURRENT_FRAME() if available. 48 | */ 49 | #if defined(__GNUC__) 50 | # define JIT_FAST_GET_CURRENT_FRAME 1 51 | # if defined(_JIT_ARCH_GET_CURRENT_FRAME) 52 | # define jit_get_current_frame() \ 53 | ({ \ 54 | void *address; \ 55 | _JIT_ARCH_GET_CURRENT_FRAME(address); \ 56 | address; \ 57 | }) 58 | # else 59 | # define jit_get_current_frame() (__builtin_frame_address(0)) 60 | # endif 61 | #else 62 | # define JIT_FAST_GET_CURRENT_FRAME 0 63 | # define jit_get_current_frame() (jit_get_frame_address(0)) 64 | #endif 65 | 66 | /* 67 | * Get the next frame up the stack from a specified frame. 68 | * Returns NULL if it isn't possible to retrieve the next frame. 69 | */ 70 | void *_jit_get_next_frame_address(void *frame); 71 | #if defined(__GNUC__) && defined(_JIT_ARCH_GET_NEXT_FRAME) 72 | # define jit_get_next_frame_address(frame) \ 73 | ({ \ 74 | void *address; \ 75 | _JIT_ARCH_GET_NEXT_FRAME(address, (frame)); \ 76 | address; \ 77 | }) 78 | #else 79 | # define jit_get_next_frame_address(frame) \ 80 | (_jit_get_next_frame_address(frame)) 81 | #endif 82 | 83 | /* 84 | * Get the return address for a specific frame. 85 | */ 86 | void *_jit_get_return_address(void *frame, void *frame0, void *return0); 87 | #if defined(__GNUC__) 88 | # if defined(_JIT_ARCH_GET_RETURN_ADDRESS) 89 | # define jit_get_return_address(frame) \ 90 | ({ \ 91 | void *address; \ 92 | _JIT_ARCH_GET_RETURN_ADDRESS(address, (frame)); \ 93 | address; \ 94 | }) 95 | # else 96 | # define jit_get_return_address(frame) \ 97 | (_jit_get_return_address \ 98 | ((frame), \ 99 | __builtin_frame_address(0), \ 100 | __builtin_return_address(0))) 101 | # endif 102 | #else 103 | # define jit_get_return_address(frame) \ 104 | (_jit_get_return_address((frame), 0, 0)) 105 | #endif 106 | 107 | /* 108 | * Get the return address for the current frame. May be more efficient 109 | * than using "jit_get_return_address(0)". 110 | */ 111 | #if defined(__GNUC__) 112 | # if defined(_JIT_ARCH_GET_CURRENT_RETURN) 113 | # define jit_get_current_return() \ 114 | ({ \ 115 | void *address; \ 116 | _JIT_ARCH_GET_CURRENT_RETURN(address); \ 117 | address; \ 118 | }) 119 | # else 120 | # define jit_get_current_return() (__builtin_return_address(0)) 121 | # endif 122 | #else 123 | # define jit_get_current_return() \ 124 | (jit_get_return_address(jit_get_current_frame())) 125 | #endif 126 | 127 | /* 128 | * Declare a stack crawl mark variable. The address of this variable 129 | * can be passed to "jit_frame_contains_crawl_mark" to determine 130 | * if a frame contains the mark. 131 | */ 132 | typedef struct { void * volatile mark; } jit_crawl_mark_t; 133 | #define jit_declare_crawl_mark(name) jit_crawl_mark_t name = {0} 134 | 135 | /* 136 | * Determine if the stack frame just above "frame" contains a 137 | * particular crawl mark. 138 | */ 139 | int jit_frame_contains_crawl_mark(void *frame, jit_crawl_mark_t *mark); 140 | 141 | #ifdef __cplusplus 142 | }; 143 | #endif 144 | 145 | #endif /* _JIT_WALK_H */ 146 | -------------------------------------------------------------------------------- /include/jit/jit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit.h - General definitions for JIT back-ends. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_H 22 | #define _JIT_H 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #ifdef __cplusplus 51 | }; 52 | #endif 53 | 54 | #endif /* _JIT_H */ 55 | -------------------------------------------------------------------------------- /jit/.gitignore: -------------------------------------------------------------------------------- 1 | jit-apply-rules.h 2 | jit-interp-labels.h 3 | jit-interp-opcode.c 4 | jit-interp-opcode.h 5 | jit-opcode.c 6 | *.inc 7 | *.slc 8 | -------------------------------------------------------------------------------- /jit/Makefile.am: -------------------------------------------------------------------------------- 1 | BUILT_SOURCES = jit-opcode.c jit-interp-opcode.h jit-interp-opcode.c 2 | 3 | lib_LTLIBRARIES = libjit.la 4 | 5 | libjit_la_SOURCES = \ 6 | jit-alloc.c \ 7 | jit-apply.c \ 8 | jit-apply-func.h \ 9 | jit-apply-arm.h \ 10 | jit-apply-arm.c \ 11 | jit-apply-x86.h \ 12 | jit-apply-x86.c \ 13 | jit-apply-x86-64.h \ 14 | jit-apply-x86-64.c \ 15 | jit-bitset.h \ 16 | jit-bitset.c \ 17 | jit-block.c \ 18 | jit-compile.c \ 19 | jit-config.h \ 20 | jit-context.c \ 21 | jit-cpuid-x86.h \ 22 | jit-cpuid-x86.c \ 23 | jit-debugger.c \ 24 | jit-dump.c \ 25 | jit-elf-defs.h \ 26 | jit-elf-read.c \ 27 | jit-elf-write.c \ 28 | jit-except.c \ 29 | jit-function.c \ 30 | jit-gen-arm.h \ 31 | jit-gen-arm.c \ 32 | jit-gen-x86.h \ 33 | jit-gen-x86-64.h \ 34 | jit-insn.c \ 35 | jit-init.c \ 36 | jit-internal.h \ 37 | jit-interp.h \ 38 | jit-interp.c \ 39 | jit-interp-opcode.h \ 40 | jit-interp-opcode.c \ 41 | jit-intrinsic.c \ 42 | jit-live.c \ 43 | jit-memory.c \ 44 | jit-memory-cache.c \ 45 | jit-meta.c \ 46 | jit-opcode-apply.c \ 47 | jit-objmodel.c \ 48 | jit-opcode.c \ 49 | jit-pool.c \ 50 | jit-reg-alloc.h \ 51 | jit-reg-alloc.c \ 52 | jit-reg-class.h \ 53 | jit-reg-class.c \ 54 | jit-rules.h \ 55 | jit-rules.c \ 56 | jit-rules-interp.c \ 57 | jit-rules-interp.h \ 58 | jit-rules-arm.h \ 59 | jit-rules-arm.c \ 60 | jit-rules-x86.h \ 61 | jit-rules-x86.c \ 62 | jit-rules-x86-64.h \ 63 | jit-rules-x86-64.c \ 64 | jit-setjmp.h \ 65 | jit-signal.c \ 66 | jit-symbol.c \ 67 | jit-thread.c \ 68 | jit-thread.h \ 69 | jit-type.c \ 70 | jit-unwind.c \ 71 | jit-util.c \ 72 | jit-value.c \ 73 | jit-varint.h \ 74 | jit-varint.c \ 75 | jit-vmem.c \ 76 | jit-walk.c 77 | 78 | EXTRA_DIST = \ 79 | mklabel.sh \ 80 | jit-opcodes.ops \ 81 | jit-interp-opcodes.ops \ 82 | jit-rules-arm.ins \ 83 | jit-rules-x86.ins \ 84 | jit-rules-x86-64.ins 85 | 86 | AM_CFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -I. -I$(srcdir) 87 | 88 | libjit_la_LDFLAGS = -version-info $(LIBJIT_VERSION) -no-undefined 89 | 90 | jit-interp.lo: jit-interp-labels.h 91 | 92 | jit-interp-labels.h: $(top_srcdir)/include/jit/jit-opcode.h \ 93 | $(top_srcdir)/jit/jit-interp-opcode.h $(srcdir)/mklabel.sh 94 | $(SHELL) $(srcdir)/mklabel.sh "$(AWK)" \ 95 | $(top_srcdir)/include/jit/jit-opcode.h \ 96 | $(top_srcdir)/jit/jit-interp-opcode.h >jit-interp-labels.h 97 | 98 | jit-rules-x86.lo: jit-rules-x86.inc 99 | 100 | jit-rules-x86.inc: jit-rules-x86.ins $(top_builddir)/tools/gen-rules$(EXEEXT) 101 | $(top_builddir)/tools/gen-rules$(EXEEXT) $(srcdir)/jit-rules-x86.ins \ 102 | >jit-rules-x86.inc 103 | 104 | jit-rules-arm.lo: jit-rules-arm.inc 105 | 106 | jit-rules-arm.inc: jit-rules-arm.ins $(top_builddir)/tools/gen-rules$(EXEEXT) 107 | $(top_builddir)/tools/gen-rules$(EXEEXT) $(srcdir)/jit-rules-arm.ins \ 108 | >jit-rules-arm.inc 109 | 110 | jit-rules-x86-64.lo: jit-rules-x86-64.inc 111 | 112 | jit-rules-x86-64.inc: jit-rules-x86-64.ins $(top_builddir)/tools/gen-rules$(EXEEXT) 113 | $(top_builddir)/tools/gen-rules$(EXEEXT) $(srcdir)/jit-rules-x86-64.ins \ 114 | >jit-rules-x86-64.inc 115 | 116 | jit-opcode.c: jit-opcodes.ops 117 | $(top_builddir)/tools/gen-ops -T $(srcdir)/jit-opcodes.ops >jit-opcode.c 118 | 119 | jit-interp-opcode.h: jit-interp-opcodes.ops 120 | $(top_builddir)/tools/gen-ops -H $(srcdir)/jit-interp-opcodes.ops \ 121 | >jit-interp-opcode.h 122 | 123 | jit-interp-opcode.c: jit-interp-opcodes.ops 124 | $(top_builddir)/tools/gen-ops -T $(srcdir)/jit-interp-opcodes.ops \ 125 | >jit-interp-opcode.c 126 | 127 | CLEANFILES = \ 128 | jit-interp-labels.h \ 129 | jit-rules-arm.inc \ 130 | jit-rules-x86.inc \ 131 | jit-rules-x86-64.inc 132 | -------------------------------------------------------------------------------- /jit/jit-apply-arm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-apply-arm.h - Special definitions for ARM function application. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_APPLY_ARM_H 24 | #define _JIT_APPLY_ARM_H 25 | 26 | /* 27 | * The maximum number of bytes that are needed to represent a closure, 28 | * and the alignment to use for the closure. 29 | */ 30 | #define jit_closure_size 128 31 | #define jit_closure_align 16 32 | 33 | /* 34 | * The number of bytes that are needed for a redirector stub. 35 | * This includes any extra bytes that are needed for alignment. 36 | */ 37 | #define jit_redirector_size 128 38 | 39 | /* 40 | * The number of bytes that are needed for a indirector stub. 41 | * This includes any extra bytes that are needed for alignment. 42 | */ 43 | #define jit_indirector_size 24 44 | 45 | /* 46 | * We should pad unused code space with NOP's. 47 | */ 48 | #define jit_should_pad 1 49 | 50 | /* 51 | * Defines the alignment for the stack pointer at a public interface. 52 | * As of the "Procedure Call Standard for the ARM Architecture" (AAPCS release 2.07) 53 | * SP mod 8 = 0 54 | * must always be true at every public interface (function calls, etc) 55 | */ 56 | #define JIT_SP_ALIGN_PUBLIC 8 57 | 58 | /* 59 | * Redefine jit_builtin_apply in order to correctly align the stack pointer 60 | * to JIT_SP_ALING_PUBLIC bytes before calling __builtin_apply to execute the 61 | * jit-compiled function 62 | */ 63 | #define jit_builtin_apply(func,args,size,return_float,return_buf) \ 64 | do { \ 65 | register void *sp asm("sp"); \ 66 | sp = (void *) (((unsigned) sp) & ~(JIT_SP_ALIGN_PUBLIC - 1)); \ 67 | (return_buf) = __builtin_apply \ 68 | ((void (*)())(func), (args), (size)); \ 69 | } while (0) 70 | 71 | #endif /* _JIT_APPLY_ARM_H */ 72 | -------------------------------------------------------------------------------- /jit/jit-apply-func.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-apply-func.h - Definition of "__builtin_apply" and friends. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_APPLY_FUNC_H 24 | #define _JIT_APPLY_FUNC_H 25 | 26 | #if defined(__i386) || defined(__i386__) || defined(_M_IX86) 27 | 28 | #include "jit-apply-x86.h" 29 | 30 | #elif defined(__arm) || defined(__arm__) 31 | 32 | #include "jit-apply-arm.h" 33 | 34 | #elif defined(__alpha) || defined(__alpha__) 35 | 36 | #include "jit-apply-alpha.h" 37 | 38 | #elif defined(__x86_64) || defined(__x86_64__) 39 | 40 | #include "jit-apply-x86-64.h" 41 | 42 | #endif 43 | 44 | #if !defined(jit_builtin_apply) 45 | #define jit_builtin_apply(func,args,size,return_float,return_buf) \ 46 | do { \ 47 | (return_buf) = __builtin_apply \ 48 | ((void (*)())(func), (args), (size)); \ 49 | } while (0) 50 | #endif 51 | 52 | #if !defined(jit_builtin_apply_args) 53 | #define jit_builtin_apply_args(type,args) \ 54 | do { \ 55 | (args) = (type)__builtin_apply_args(); \ 56 | } while (0) 57 | #endif 58 | 59 | #if !defined(jit_builtin_return_int) 60 | #define jit_builtin_return_int(return_buf) \ 61 | do { \ 62 | __builtin_return((return_buf)); \ 63 | } while (0) 64 | #endif 65 | 66 | #if !defined(jit_builtin_return_long) 67 | #define jit_builtin_return_long(return_buf) \ 68 | do { \ 69 | __builtin_return((return_buf)); \ 70 | } while (0) 71 | #endif 72 | 73 | #if !defined(jit_builtin_return_float) 74 | #define jit_builtin_return_float(return_buf) \ 75 | do { \ 76 | __builtin_return((return_buf)); \ 77 | } while (0) 78 | #endif 79 | 80 | #if !defined(jit_builtin_return_double) 81 | #define jit_builtin_return_double(return_buf) \ 82 | do { \ 83 | __builtin_return((return_buf)); \ 84 | } while (0) 85 | #endif 86 | 87 | #if !defined(jit_builtin_return_nfloat) 88 | #define jit_builtin_return_nfloat(return_buf) \ 89 | do { \ 90 | __builtin_return((return_buf)); \ 91 | } while (0) 92 | #endif 93 | 94 | /* 95 | * Create a closure for the underlying platform in the given buffer. 96 | * The closure must arrange to call "func" with two arguments: 97 | * "closure" and a pointer to an apply structure. 98 | */ 99 | void _jit_create_closure(unsigned char *buf, void *func, 100 | void *closure, void *type); 101 | 102 | /* 103 | * Create a redirector stub for the underlying platform in the given buffer. 104 | * The redirector arranges to call "func" with the "user_data" argument. 105 | * It is assumed that "func" returns a pointer to the actual function. 106 | * Returns a pointer to the position in "buf" where the redirector starts, 107 | * which may be different than "buf" if alignment occurred. 108 | */ 109 | void *_jit_create_redirector(unsigned char *buf, void *func, 110 | void *user_data, int abi); 111 | 112 | 113 | /* 114 | * Create the indirector for the function. 115 | */ 116 | void *_jit_create_indirector(unsigned char *buf, void **entry); 117 | 118 | /* 119 | * Pad a buffer with NOP instructions. Used to align code. 120 | * This will only be called if "jit_should_pad" is defined. 121 | */ 122 | void _jit_pad_buffer(unsigned char *buf, int len); 123 | 124 | #endif /* _JIT_APPLY_FUNC_H */ 125 | -------------------------------------------------------------------------------- /jit/jit-bitset.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-bitset.h - Bitset routines for the JIT. 3 | * 4 | * Copyright (C) 2006 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #include "jit-internal.h" 24 | #include "jit-bitset.h" 25 | 26 | void 27 | _jit_bitset_init(_jit_bitset_t *bs) 28 | { 29 | bs->size = 0; 30 | bs->bits = 0; 31 | } 32 | 33 | int 34 | _jit_bitset_allocate(_jit_bitset_t *bs, int size) 35 | { 36 | bs->size = size; 37 | if(size > 0) 38 | { 39 | size = (size + _JIT_BITSET_WORD_BITS - 1) / _JIT_BITSET_WORD_BITS; 40 | bs->bits = jit_calloc(size, sizeof(_jit_bitset_word_t)); 41 | if(!bs->bits) 42 | { 43 | jit_free(bs); 44 | return 0; 45 | } 46 | } 47 | else 48 | { 49 | bs->bits = 0; 50 | } 51 | return 1; 52 | } 53 | 54 | int 55 | _jit_bitset_is_allocated(_jit_bitset_t *bs) 56 | { 57 | return (bs->bits != 0); 58 | } 59 | 60 | void 61 | _jit_bitset_free(_jit_bitset_t *bs) 62 | { 63 | if(bs->bits) 64 | { 65 | jit_free(bs->bits); 66 | bs->size = 0; 67 | bs->bits = 0; 68 | } 69 | } 70 | 71 | void 72 | _jit_bitset_set_bit(_jit_bitset_t *bs, int bit) 73 | { 74 | int word; 75 | word = bit / _JIT_BITSET_WORD_BITS; 76 | bit = bit % _JIT_BITSET_WORD_BITS; 77 | bs->bits[word] |= bit; 78 | } 79 | 80 | void 81 | _jit_bitset_clear_bit(_jit_bitset_t *bs, int bit) 82 | { 83 | int word; 84 | word = bit / _JIT_BITSET_WORD_BITS; 85 | bit = bit % _JIT_BITSET_WORD_BITS; 86 | bs->bits[word] &= ~bit; 87 | } 88 | 89 | int 90 | _jit_bitset_test_bit(_jit_bitset_t *bs, int bit) 91 | { 92 | int word; 93 | word = bit / _JIT_BITSET_WORD_BITS; 94 | bit = bit % _JIT_BITSET_WORD_BITS; 95 | return (bs->bits[word] & bit) != 0; 96 | } 97 | 98 | void 99 | _jit_bitset_clear(_jit_bitset_t *bs) 100 | { 101 | int i; 102 | for(i = 0; i < bs->size; i++) 103 | { 104 | bs->bits[i] = 0; 105 | } 106 | } 107 | 108 | int 109 | _jit_bitset_empty(_jit_bitset_t *bs) 110 | { 111 | int i; 112 | for(i = 0; i < bs->size; i++) 113 | { 114 | if(bs->bits[i]) 115 | { 116 | return 0; 117 | } 118 | } 119 | return 1; 120 | } 121 | 122 | void 123 | _jit_bitset_add(_jit_bitset_t *dest, _jit_bitset_t *src) 124 | { 125 | int i; 126 | for(i = 0; i < dest->size; i++) 127 | { 128 | dest->bits[i] |= src->bits[i]; 129 | } 130 | } 131 | 132 | void 133 | _jit_bitset_sub(_jit_bitset_t *dest, _jit_bitset_t *src) 134 | { 135 | int i; 136 | for(i = 0; i < dest->size; i++) 137 | { 138 | dest->bits[i] &= ~src->bits[i]; 139 | } 140 | } 141 | 142 | int 143 | _jit_bitset_copy(_jit_bitset_t *dest, _jit_bitset_t *src) 144 | { 145 | int i; 146 | int changed; 147 | 148 | changed = 0; 149 | for(i = 0; i < dest->size; i++) 150 | { 151 | if(dest->bits[i] != src->bits[i]) 152 | { 153 | dest->bits[i] = src->bits[i]; 154 | changed = 1; 155 | } 156 | } 157 | return changed; 158 | } 159 | 160 | int 161 | _jit_bitset_equal(_jit_bitset_t *bs1, _jit_bitset_t *bs2) 162 | { 163 | int i; 164 | for(i = 0; i < bs1->size; i++) 165 | { 166 | if(bs1->bits[i] != bs2->bits[i]) 167 | { 168 | return 0; 169 | } 170 | } 171 | return 1; 172 | } 173 | -------------------------------------------------------------------------------- /jit/jit-bitset.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-bitset.h - Bitset routines for the JIT. 3 | * 4 | * Copyright (C) 2006 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_BITSET_H 24 | #define _JIT_BITSET_H 25 | 26 | #define _JIT_BITSET_WORD_BITS (8 * sizeof(_jit_bitset_word_t)) 27 | 28 | typedef unsigned long _jit_bitset_word_t; 29 | typedef struct _jit_bitset _jit_bitset_t; 30 | 31 | /* TODO: Use less space. Perhaps borrow bitmap from gcc. */ 32 | struct _jit_bitset 33 | { 34 | int size; 35 | _jit_bitset_word_t *bits; 36 | }; 37 | 38 | void _jit_bitset_init(_jit_bitset_t *bs); 39 | int _jit_bitset_allocate(_jit_bitset_t *bs, int size); 40 | int _jit_bitset_is_allocated(_jit_bitset_t *bs); 41 | void _jit_bitset_free(_jit_bitset_t *bs); 42 | void _jit_bitset_set_bit(_jit_bitset_t *bs, int bit); 43 | void _jit_bitset_clear_bit(_jit_bitset_t *bs, int bit); 44 | int _jit_bitset_test_bit(_jit_bitset_t *bs, int bit); 45 | void _jit_bitset_clear(_jit_bitset_t *bs); 46 | int _jit_bitset_empty(_jit_bitset_t *bs); 47 | void _jit_bitset_add(_jit_bitset_t *dest, _jit_bitset_t *src); 48 | void _jit_bitset_sub(_jit_bitset_t *dest, _jit_bitset_t *src); 49 | int _jit_bitset_copy(_jit_bitset_t *dest, _jit_bitset_t *src); 50 | int _jit_bitset_equal(_jit_bitset_t *bs1, _jit_bitset_t *bs2); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /jit/jit-cfg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-cfg.h - Control Flow Graph routines for the JIT. 3 | * 4 | * Copyright (C) 2006 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_CFG_H 24 | #define _JIT_CFG_H 25 | 26 | #include 27 | #include "jit-bitset.h" 28 | 29 | #define _JIT_BLOCK_CFG_NODE 10010 30 | 31 | #define _JIT_NODE_VISITED 1 32 | 33 | typedef struct _jit_cfg *_jit_cfg_t; 34 | typedef struct _jit_node *_jit_node_t; 35 | typedef struct _jit_edge *_jit_edge_t; 36 | typedef struct _jit_value_entry *_jit_value_entry_t; 37 | 38 | /* 39 | * Control flow graph. 40 | */ 41 | struct _jit_cfg 42 | { 43 | jit_function_t func; 44 | 45 | /* Special nodes */ 46 | _jit_node_t entry; 47 | _jit_node_t exit; 48 | 49 | /* Array of nodes */ 50 | _jit_node_t nodes; 51 | int num_nodes; 52 | 53 | /* Array of edges */ 54 | _jit_edge_t edges; 55 | int num_edges; 56 | 57 | /* depth first search post order. */ 58 | _jit_node_t *post_order; 59 | 60 | /* values */ 61 | _jit_value_entry_t values; 62 | int num_values; 63 | int max_values; 64 | }; 65 | 66 | /* 67 | * Control flow graph node. 68 | */ 69 | struct _jit_node 70 | { 71 | jit_block_t block; 72 | int flags; 73 | 74 | /* edges to successor nodes */ 75 | _jit_edge_t *succs; 76 | int num_succs; 77 | 78 | /* edges to predecessor nodes */ 79 | _jit_edge_t *preds; 80 | int num_preds; 81 | 82 | /* liveness analysis data */ 83 | _jit_bitset_t live_in; 84 | _jit_bitset_t live_out; 85 | _jit_bitset_t live_use; 86 | _jit_bitset_t live_def; 87 | 88 | /* depth first search number */ 89 | int dfn; 90 | }; 91 | 92 | /* 93 | * Control flow graph edge. 94 | */ 95 | struct _jit_edge 96 | { 97 | _jit_node_t src; 98 | _jit_node_t dst; 99 | int flags; 100 | }; 101 | 102 | /* 103 | * Value entry that contains information for data flow analysis 104 | * and register allocation. 105 | */ 106 | struct _jit_value_entry 107 | { 108 | jit_value_t value; 109 | short reg; 110 | short other_reg; 111 | }; 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /jit/jit-config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-config.h - Configuration macros for the JIT. 3 | * 4 | * Copyright (C) 2011 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_CONFIG_H 24 | #define _JIT_CONFIG_H 25 | 26 | #include 27 | 28 | /* 29 | * Determine what kind of system we are running on. 30 | */ 31 | #if defined(__CYGWIN__) || defined(__CYGWIN32__) 32 | # define JIT_WIN32_CYGWIN 1 33 | # define JIT_WIN32_PLATFORM 1 34 | #elif defined(_WIN32) || defined(WIN32) 35 | # define JIT_WIN32_NATIVE 1 36 | # define JIT_WIN32_PLATFORM 1 37 | #elif defined(__APPLE__) && defined(__MACH__) 38 | # define JIT_DARWIN_PLATFORM 1 39 | #elif defined(__linux__) 40 | # define JIT_LINUX_PLATFORM 1 41 | #endif 42 | 43 | /* 44 | * Determine the type of threading library that we are using. 45 | */ 46 | #if defined(HAVE_PTHREAD_H) && defined(HAVE_LIBPTHREAD) 47 | # define JIT_THREADS_SUPPORTED 1 48 | # define JIT_THREADS_PTHREAD 1 49 | #elif defined(JIT_WIN32_PLATFORM) 50 | # define JIT_THREADS_SUPPORTED 1 51 | # define JIT_THREADS_WIN32 1 52 | #else 53 | # define JIT_THREADS_SUPPORTED 0 54 | #endif 55 | 56 | /* 57 | * Determine the type of virtual memory API that we are using. 58 | */ 59 | #if defined(JIT_WIN32_PLATFORM) 60 | # define JIT_VMEM_SUPPORTED 1 61 | # define JIT_VMEM_WIN32 1 62 | #elif defined(HAVE_SYS_MMAN_H) 63 | # define JIT_VMEM_SUPPORTED 1 64 | # define JIT_VMEM_MMAP 1 65 | #else 66 | # define JIT_VMEM_SUPPORTED 0 67 | #endif 68 | 69 | /* 70 | * Determine which backend to use. 71 | */ 72 | #if defined(USE_LIBJIT_INTERPRETER) 73 | # define JIT_BACKEND_INTERP 1 74 | # define JIT_HAVE_BACKEND 1 75 | #elif defined(__alpha) || defined(__alpha__) 76 | # define JIT_BACKEND_ALPHA 1 77 | # define JIT_HAVE_BACKEND 1 78 | #elif defined(__arm) || defined(__arm__) 79 | # define JIT_BACKEND_ARM 1 80 | # define JIT_HAVE_BACKEND 1 81 | #elif defined(__i386) || defined(__i386__) || defined(_M_IX86) 82 | # define JIT_BACKEND_X86 1 83 | # define JIT_HAVE_BACKEND 1 84 | #elif defined(__amd64) || defined(__amd64__) || defined(_x86_64) || defined(_x86_64__) 85 | # define JIT_BACKEND_X86_64 1 86 | # define JIT_HAVE_BACKEND 1 87 | #endif 88 | 89 | /* 90 | * Fallback to interpreter if there is no appropriate native backend. 91 | */ 92 | #if !defined(JIT_HAVE_BACKEND) 93 | # define JIT_BACKEND_INTERP 1 94 | #endif 95 | 96 | /* 97 | #define _JIT_COMPILE_DEBUG 1 98 | #define _JIT_BLOCK_DEBUG 1 99 | */ 100 | 101 | #endif /* _JIT_CONFIG_H */ 102 | 103 | -------------------------------------------------------------------------------- /jit/jit-cpuid-x86.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-cpuid-x86.c - Wrapper for the CPUID instruction. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #include "jit-cpuid-x86.h" 24 | 25 | #if defined(__i386) || defined(__i386__) || defined(_M_IX86) 26 | 27 | /* 28 | * Determine if the "cpuid" instruction is present by twiddling 29 | * bit 21 of the EFLAGS register. 30 | */ 31 | static int cpuid_present(void) 32 | { 33 | #if defined(__GNUC__) 34 | int result; 35 | __asm__ __volatile__ ( 36 | "\tpushfl\n" 37 | "\tpopl %%eax\n" 38 | "\tmovl %%eax, %%ecx\n" 39 | "\tandl $0x200000, %%ecx\n" 40 | "\txorl $0x200000, %%eax\n" 41 | "\tpushl %%eax\n" 42 | "\tpopfl\n" 43 | "\tpushfl\n" 44 | "\tandl $0x200000, %%eax\n" 45 | "\txorl %%ecx, %%eax\n" 46 | "\tmovl %%eax, %0\n" 47 | : "=m" (result) : : "eax", "ecx" 48 | ); 49 | return (result != 0); 50 | #else 51 | return 0; 52 | #endif 53 | } 54 | 55 | /* 56 | * Issue a "cpuid" query and get the result. 57 | */ 58 | static void cpuid_query(unsigned int index, jit_cpuid_x86_t *info) 59 | { 60 | #if defined(__GNUC__) 61 | __asm__ __volatile__ ( 62 | "\tmovl %0, %%eax\n" 63 | "\tpushl %%ebx\n" 64 | "\txorl %%ebx, %%ebx\n" 65 | "\txorl %%ecx, %%ecx\n" 66 | "\txorl %%edx, %%edx\n" 67 | "\t.byte 0x0F\n" /* cpuid, safe against old assemblers */ 68 | "\t.byte 0xA2\n" 69 | "\tmovl %1, %%esi\n" 70 | "\tmovl %%eax, (%%esi)\n" 71 | "\tmovl %%ebx, 4(%%esi)\n" 72 | "\tmovl %%ecx, 8(%%esi)\n" 73 | "\tmovl %%edx, 12(%%esi)\n" 74 | "\tpopl %%ebx\n" 75 | : : "m"(index), "m"(info) : "eax", "ecx", "edx", "esi" 76 | ); 77 | #endif 78 | } 79 | 80 | int _jit_cpuid_x86_get(unsigned int index, jit_cpuid_x86_t *info) 81 | { 82 | /* Determine if this cpu has the "cpuid" instruction */ 83 | if(!cpuid_present()) 84 | { 85 | return 0; 86 | } 87 | 88 | /* Validate the index */ 89 | if((index & 0x80000000) == 0) 90 | { 91 | cpuid_query(0, info); 92 | } 93 | else 94 | { 95 | cpuid_query(0x80000000, info); 96 | } 97 | if(index > info->eax) 98 | { 99 | return 0; 100 | } 101 | 102 | /* Execute the actual requested query */ 103 | cpuid_query(index, info); 104 | return 1; 105 | } 106 | 107 | int _jit_cpuid_x86_has_feature(unsigned int feature) 108 | { 109 | jit_cpuid_x86_t info; 110 | if(!_jit_cpuid_x86_get(JIT_X86CPUID_FEATURES, &info)) 111 | { 112 | return 0; 113 | } 114 | return ((info.edx & feature) != 0); 115 | } 116 | 117 | unsigned int _jit_cpuid_x86_line_size(void) 118 | { 119 | jit_cpuid_x86_t info; 120 | if(!_jit_cpuid_x86_get(JIT_X86CPUID_FEATURES, &info)) 121 | { 122 | return 0; 123 | } 124 | if((info.edx & JIT_X86FEATURE_CLFSH) == 0) 125 | { 126 | return 0; 127 | } 128 | return ((info.ebx & 0x0000FF00) >> 5); 129 | } 130 | 131 | #endif /* i386 */ 132 | -------------------------------------------------------------------------------- /jit/jit-cpuid-x86.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-cpuid-x86.h - Wrapper for the CPUID instruction. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_CPUID_X86_H 24 | #define _JIT_CPUID_X86_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Structure that is used to return CPU identification information. 32 | */ 33 | typedef struct 34 | { 35 | unsigned int eax; 36 | unsigned int ebx; 37 | unsigned int ecx; 38 | unsigned int edx; 39 | 40 | } jit_cpuid_x86_t; 41 | 42 | /* 43 | * Indexes for querying cpuid information. 44 | */ 45 | #define JIT_X86CPUID_FEATURES 1 46 | #define JIT_X86CPUID_CACHE_TLB 2 47 | #define JIT_X86CPUID_SERIAL_NUMBER 3 48 | 49 | /* 50 | * Feature information. 51 | */ 52 | #define JIT_X86FEATURE_FPU 0x00000001 53 | #define JIT_X86FEATURE_VME 0x00000002 54 | #define JIT_X86FEATURE_DE 0x00000004 55 | #define JIT_X86FEATURE_PSE 0x00000008 56 | #define JIT_X86FEATURE_TSC 0x00000010 57 | #define JIT_X86FEATURE_MSR 0x00000020 58 | #define JIT_X86FEATURE_PAE 0x00000040 59 | #define JIT_X86FEATURE_MCE 0x00000080 60 | #define JIT_X86FEATURE_CX8 0x00000100 61 | #define JIT_X86FEATURE_APIC 0x00000200 62 | #define JIT_X86FEATURE_RESERVED_1 0x00000400 63 | #define JIT_X86FEATURE_SEP 0x00000800 64 | #define JIT_X86FEATURE_MTRR 0x00001000 65 | #define JIT_X86FEATURE_PGE 0x00002000 66 | #define JIT_X86FEATURE_MCA 0x00004000 67 | #define JIT_X86FEATURE_CMOV 0x00008000 68 | #define JIT_X86FEATURE_PAT 0x00010000 69 | #define JIT_X86FEATURE_PSE36 0x00020000 70 | #define JIT_X86FEATURE_PSN 0x00040000 71 | #define JIT_X86FEATURE_CLFSH 0x00080000 72 | #define JIT_X86FEATURE_RESERVED_2 0x00100000 73 | #define JIT_X86FEATURE_DS 0x00200000 74 | #define JIT_X86FEATURE_ACPI 0x00400000 75 | #define JIT_X86FEATURE_MMX 0x00800000 76 | #define JIT_X86FEATURE_FXSR 0x01000000 77 | #define JIT_X86FEATURE_SSE 0x02000000 78 | #define JIT_X86FEATURE_SSE2 0x04000000 79 | #define JIT_X86FEATURE_SS 0x08000000 80 | #define JIT_X86FEATURE_RESERVED_3 0x10000000 81 | #define JIT_X86FEATURE_TM 0x20000000 82 | #define JIT_X86FEATURE_RESERVED_4 0x40000000 83 | #define JIT_X86FEATURE_RESERVED_5 0x80000000 84 | 85 | /* 86 | * Get CPU identification information. Returns zero if the requested 87 | * information is not available. 88 | */ 89 | int _jit_cpuid_x86_get(unsigned int index, jit_cpuid_x86_t *info); 90 | 91 | /* 92 | * Determine if the CPU has a particular feature. 93 | */ 94 | int _jit_cpuid_x86_has_feature(unsigned int feature); 95 | 96 | /* 97 | * Get the size of the CPU cache line, or zero if flushing is not required. 98 | */ 99 | unsigned int _jit_cpuid_x86_line_size(void); 100 | 101 | #ifdef __cplusplus 102 | }; 103 | #endif 104 | 105 | #endif /* _JIT_CPUID_X86_H */ 106 | -------------------------------------------------------------------------------- /jit/jit-gen-arm.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-gen-arm.c - Machine-dependent definitions for ARM. 3 | * 4 | * Copyright (C) 2003, 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #include "jit-internal.h" 24 | 25 | #if defined(__arm) || defined(__arm__) 26 | 27 | #define arm_execute execute_prefix 28 | #define arm_execute_cc (execute_prefix | (1 << 20)) 29 | #define arm_execute_imm (execute_prefix | (1 << 25)) 30 | 31 | #include "jit-gen-arm.h" 32 | 33 | void _arm_mov_reg_imm 34 | (arm_inst_buf *inst, int reg, int value, int execute_prefix) 35 | { 36 | int bit; 37 | 38 | /* Handle bytes in various positions */ 39 | for(bit = 0; bit <= (32 - 8); bit += 2) 40 | { 41 | if((value & (0xFF << bit)) == value) 42 | { 43 | arm_mov_reg_imm8_rotate 44 | (*inst, reg, ((value >> bit) & 0xFF), (16 - bit / 2) & 0x0F); 45 | return; 46 | } 47 | } 48 | 49 | /* Handle inverted bytes in various positions */ 50 | value = ~value; 51 | for(bit = 0; bit <= (32 - 8); bit += 2) 52 | { 53 | if((value & (0xFF << bit)) == value) 54 | { 55 | arm_alu_reg_imm8_rotate 56 | (*inst, ARM_MVN, reg, 0, 57 | ((value >> bit) & 0xFF), (16 - bit / 2) & 0x0F); 58 | return; 59 | } 60 | } 61 | 62 | /* Build the value the hard way, byte by byte */ 63 | value = ~value; 64 | if((value & 0xFF000000) != 0) 65 | { 66 | arm_mov_reg_imm8_rotate(*inst, reg, ((value >> 24) & 0xFF), 4); 67 | if((value & 0x00FF0000) != 0) 68 | { 69 | arm_alu_reg_imm8_rotate 70 | (*inst, ARM_ADD, reg, reg, ((value >> 16) & 0xFF), 8); 71 | } 72 | if((value & 0x0000FF00) != 0) 73 | { 74 | arm_alu_reg_imm8_rotate 75 | (*inst, ARM_ADD, reg, reg, ((value >> 8) & 0xFF), 12); 76 | } 77 | if((value & 0x000000FF) != 0) 78 | { 79 | arm_alu_reg_imm8(*inst, ARM_ADD, reg, reg, (value & 0xFF)); 80 | } 81 | } 82 | else if((value & 0x00FF0000) != 0) 83 | { 84 | arm_mov_reg_imm8_rotate(*inst, reg, ((value >> 16) & 0xFF), 8); 85 | if((value & 0x0000FF00) != 0) 86 | { 87 | arm_alu_reg_imm8_rotate 88 | (*inst, ARM_ADD, reg, reg, ((value >> 8) & 0xFF), 12); 89 | } 90 | if((value & 0x000000FF) != 0) 91 | { 92 | arm_alu_reg_imm8(*inst, ARM_ADD, reg, reg, (value & 0xFF)); 93 | } 94 | } 95 | else if((value & 0x0000FF00) != 0) 96 | { 97 | arm_mov_reg_imm8_rotate(*inst, reg, ((value >> 8) & 0xFF), 12); 98 | if((value & 0x000000FF) != 0) 99 | { 100 | arm_alu_reg_imm8(*inst, ARM_ADD, reg, reg, (value & 0xFF)); 101 | } 102 | } 103 | else 104 | { 105 | arm_mov_reg_imm8(*inst, reg, (value & 0xFF)); 106 | } 107 | } 108 | 109 | int arm_is_complex_imm(int value) 110 | { 111 | int bit; 112 | int inv_value = ~value; 113 | for(bit = 0; bit <= (32 - 8); bit += 2) 114 | { 115 | if((value & (0xFF << bit)) == value) 116 | { 117 | return 0; 118 | } 119 | if((inv_value & (0xFF << bit)) == inv_value) 120 | { 121 | return 0; 122 | } 123 | } 124 | return 1; 125 | } 126 | 127 | void _arm_alu_reg_imm 128 | (arm_inst_buf *inst, int opc, int dreg, 129 | int sreg, int imm, int saveWork, int execute_prefix) 130 | { 131 | int bit, tempreg; 132 | for(bit = 0; bit <= (32 - 8); bit += 2) 133 | { 134 | if((imm & (0xFF << bit)) == imm) 135 | { 136 | arm_alu_reg_imm8_rotate 137 | (*inst, opc, dreg, sreg, 138 | ((imm >> bit) & 0xFF), (16 - bit / 2) & 0x0F); 139 | return; 140 | } 141 | } 142 | if(saveWork) 143 | { 144 | if(dreg != ARM_R2 && sreg != ARM_R2) 145 | { 146 | tempreg = ARM_R2; 147 | } 148 | else if(dreg != ARM_R3 && sreg != ARM_R3) 149 | { 150 | tempreg = ARM_R3; 151 | } 152 | else 153 | { 154 | tempreg = ARM_R4; 155 | } 156 | arm_push_reg(*inst, tempreg); 157 | } 158 | else 159 | { 160 | tempreg = ARM_WORK; 161 | } 162 | _arm_mov_reg_imm(inst, tempreg, imm, execute_prefix); 163 | arm_alu_reg_reg(*inst, opc, dreg, sreg, tempreg); 164 | if(saveWork) 165 | { 166 | arm_pop_reg(*inst, tempreg); 167 | } 168 | } 169 | 170 | #endif /* arm */ 171 | -------------------------------------------------------------------------------- /jit/jit-init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-init.c - Initialization routines for the JIT. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #include "jit-internal.h" 24 | #include "jit-rules.h" 25 | 26 | /*@ 27 | * @deftypefun void jit_init (void) 28 | * This is normally the first function that you call when using 29 | * @code{libjit}. It initializes the library and prepares for 30 | * JIT operations. 31 | * 32 | * The @code{jit_context_create} function also calls this, so you can 33 | * avoid using @code{jit_init} if @code{jit_context_create} is the first 34 | * JIT function that you use. 35 | * 36 | * It is safe to initialize the JIT multiple times. Subsequent 37 | * initializations are quietly ignored. 38 | * @end deftypefun 39 | @*/ 40 | void 41 | jit_init(void) 42 | { 43 | static int init_done = 0; 44 | 45 | /* Make sure that the thread subsystem is initialized */ 46 | _jit_thread_init(); 47 | 48 | /* Make sure that the initialization is done only once 49 | (requires the global lock initialized above) */ 50 | jit_mutex_lock(&_jit_global_lock); 51 | if(init_done) 52 | { 53 | goto done; 54 | } 55 | init_done = 1; 56 | 57 | #ifdef JIT_USE_SIGNALS 58 | /* Initialize the signal handlers */ 59 | _jit_signal_init(); 60 | #endif 61 | 62 | /* Initialize the virtual memory system */ 63 | jit_vmem_init(); 64 | 65 | /* Initialize the backend */ 66 | _jit_init_backend(); 67 | 68 | done: 69 | jit_mutex_unlock(&_jit_global_lock); 70 | } 71 | 72 | /*@ 73 | * @deftypefun int jit_uses_interpreter (void) 74 | * Determine if the JIT uses a fall-back interpreter to execute code 75 | * rather than generating and executing native code. This can be 76 | * called prior to @code{jit_init}. 77 | * @end deftypefun 78 | @*/ 79 | int 80 | jit_uses_interpreter(void) 81 | { 82 | #if defined(JIT_BACKEND_INTERP) 83 | return 1; 84 | #else 85 | return 0; 86 | #endif 87 | } 88 | 89 | /*@ 90 | * @deftypefun int jit_supports_threads (void) 91 | * Determine if the JIT supports threads. 92 | * @end deftypefun 93 | @*/ 94 | int 95 | jit_supports_threads(void) 96 | { 97 | return JIT_THREADS_SUPPORTED; 98 | } 99 | 100 | /*@ 101 | * @deftypefun int jit_supports_virtual_memory (void) 102 | * Determine if the JIT supports virtual memory. 103 | * @end deftypefun 104 | @*/ 105 | int 106 | jit_supports_virtual_memory(void) 107 | { 108 | return JIT_VMEM_SUPPORTED; 109 | } 110 | -------------------------------------------------------------------------------- /jit/jit-interp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-interp.h - Bytecode interpreter for platforms without native support. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_INTERP_H 24 | #define _JIT_INTERP_H 25 | 26 | #include "jit-internal.h" 27 | #include "jit-apply-rules.h" 28 | #include "jit-interp-opcode.h" 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /* 35 | * Structure of a stack item. 36 | */ 37 | typedef union 38 | { 39 | jit_int int_value; 40 | jit_uint uint_value; 41 | jit_long long_value; 42 | jit_ulong ulong_value; 43 | jit_float32 float32_value; 44 | jit_float64 float64_value; 45 | jit_nfloat nfloat_value; 46 | void *ptr_value; 47 | #if JIT_APPLY_MAX_STRUCT_IN_REG != 0 48 | char struct_value[JIT_APPLY_MAX_STRUCT_IN_REG]; 49 | #endif 50 | 51 | } jit_item; 52 | 53 | /* 54 | * Number of items that make up a struct or union value on the stack. 55 | */ 56 | #define JIT_NUM_ITEMS_IN_STRUCT(size) \ 57 | (((size) + (sizeof(jit_item) - 1)) / sizeof(jit_item)) 58 | 59 | /* 60 | * Information that is prefixed to a function that describes 61 | * its interpretation context. The code starts just after this. 62 | */ 63 | typedef struct jit_function_interp *jit_function_interp_t; 64 | struct jit_function_interp 65 | { 66 | /* The function that this structure is associated with */ 67 | jit_function_t func; 68 | 69 | /* Size of the argument area to allocate, in bytes */ 70 | unsigned int args_size; 71 | 72 | /* Size of the local stack frame to allocate, in bytes */ 73 | unsigned int frame_size; 74 | 75 | /* Size of the working stack area of the frame, in items */ 76 | unsigned int working_area; 77 | }; 78 | 79 | /* 80 | * Get the size of the "jit_function_interp" structure, rounded 81 | * up to a multiple of "void *". 82 | */ 83 | #define jit_function_interp_size \ 84 | ((sizeof(struct jit_function_interp) + sizeof(void *) - 1) & \ 85 | ~(sizeof(void *) - 1)) 86 | 87 | /* 88 | * Get the entry point for a function, from its "jit_function_interp_t" block. 89 | */ 90 | #define jit_function_interp_entry_pc(info) \ 91 | ((void **)(((unsigned char *)(info)) + jit_function_interp_size)) 92 | 93 | #ifdef __cplusplus 94 | }; 95 | #endif 96 | 97 | #endif /* _JIT_INTERP_H */ 98 | -------------------------------------------------------------------------------- /jit/jit-pool.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-pool.c - Functions for managing memory pools. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #include "jit-internal.h" 24 | 25 | void _jit_memory_pool_init(jit_memory_pool *pool, unsigned int elem_size) 26 | { 27 | pool->elem_size = elem_size; 28 | pool->elems_per_block = 4000 / elem_size; 29 | pool->elems_in_last = pool->elems_per_block; 30 | pool->blocks = 0; 31 | pool->free_list = 0; 32 | } 33 | 34 | void _jit_memory_pool_free(jit_memory_pool *pool, jit_meta_free_func func) 35 | { 36 | jit_pool_block_t block; 37 | while(pool->blocks != 0) 38 | { 39 | block = pool->blocks; 40 | pool->blocks = block->next; 41 | if(func) 42 | { 43 | while(pool->elems_in_last > 0) 44 | { 45 | --(pool->elems_in_last); 46 | (*func)(block->data + pool->elems_in_last * pool->elem_size); 47 | } 48 | } 49 | jit_free(block); 50 | pool->elems_in_last = pool->elems_per_block; 51 | } 52 | pool->free_list = 0; 53 | } 54 | 55 | void *_jit_memory_pool_alloc(jit_memory_pool *pool) 56 | { 57 | void *data; 58 | if(pool->free_list) 59 | { 60 | /* Reclaim an item that was previously deallocated */ 61 | data = pool->free_list; 62 | pool->free_list = *((void **)data); 63 | jit_memzero(data, pool->elem_size); 64 | return data; 65 | } 66 | if(pool->elems_in_last >= pool->elems_per_block) 67 | { 68 | data = (void *)jit_calloc(1, sizeof(struct jit_pool_block) + 69 | pool->elem_size * pool->elems_per_block - 1); 70 | if(!data) 71 | { 72 | return 0; 73 | } 74 | ((jit_pool_block_t)data)->next = pool->blocks; 75 | pool->blocks = (jit_pool_block_t)data; 76 | pool->elems_in_last = 0; 77 | } 78 | data = (void *)(pool->blocks->data + 79 | pool->elems_in_last * pool->elem_size); 80 | ++(pool->elems_in_last); 81 | return data; 82 | } 83 | 84 | void _jit_memory_pool_dealloc(jit_memory_pool *pool, void *item) 85 | { 86 | *((void **)item) = pool->free_list; 87 | pool->free_list = item; 88 | } 89 | -------------------------------------------------------------------------------- /jit/jit-reg-class.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-reg-class.c - Register class routines for the JIT. 3 | * 4 | * Copyright (C) 2006 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #include "jit-internal.h" 24 | #include "jit-reg-class.h" 25 | #include 26 | 27 | _jit_regclass_t * 28 | _jit_regclass_create(const char *name, int flags, int num_regs, ...) 29 | { 30 | _jit_regclass_t *regclass; 31 | va_list args; 32 | int reg; 33 | 34 | regclass = jit_malloc(sizeof(_jit_regclass_t) + sizeof(int) * (num_regs - 1)); 35 | if(!regclass) 36 | { 37 | return 0; 38 | } 39 | regclass->name = name; 40 | regclass->flags = flags; 41 | regclass->num_regs = num_regs; 42 | 43 | va_start(args, num_regs); 44 | for(reg = 0; reg < num_regs; reg++) 45 | { 46 | regclass->regs[reg] = va_arg(args, int); 47 | } 48 | va_end(args); 49 | 50 | return regclass; 51 | } 52 | 53 | _jit_regclass_t * 54 | _jit_regclass_combine(const char *name, int flags, 55 | _jit_regclass_t *class1, 56 | _jit_regclass_t *class2) 57 | { 58 | _jit_regclass_t *regclass; 59 | int num_regs; 60 | 61 | num_regs = class1->num_regs + class2->num_regs; 62 | 63 | regclass = jit_malloc(sizeof(_jit_regclass_t) + sizeof(int) * (num_regs - 1)); 64 | if(!regclass) 65 | { 66 | return 0; 67 | } 68 | regclass->name = name; 69 | regclass->flags = flags; 70 | regclass->num_regs = num_regs; 71 | 72 | jit_memcpy(regclass->regs, class1->regs, sizeof(int) * class1->num_regs); 73 | jit_memcpy(regclass->regs + class1->num_regs, class2->regs, sizeof(int) * class2->num_regs); 74 | 75 | return regclass; 76 | } 77 | 78 | void 79 | _jit_regclass_free(_jit_regclass_t *regclass) 80 | { 81 | jit_free(regclass); 82 | } 83 | -------------------------------------------------------------------------------- /jit/jit-reg-class.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-reg-class.h - Register class routines for the JIT. 3 | * 4 | * Copyright (C) 2006 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_REG_CLASS_H 24 | #define _JIT_REG_CLASS_H 25 | 26 | #include "jit-rules.h" 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | /* 33 | * Information about a register class. 34 | */ 35 | typedef struct 36 | { 37 | const char *name; /* Name of the register class, for debugging */ 38 | int flags; /* Register flags */ 39 | int num_regs; /* The number of registers in the class */ 40 | int regs[1]; /* JIT_REG_INFO index for each register */ 41 | 42 | } _jit_regclass_t; 43 | 44 | /* Create a register class. */ 45 | _jit_regclass_t *_jit_regclass_create(const char *name, int flags, int num_regs, ...); 46 | 47 | /* Combine two register classes into another one. */ 48 | _jit_regclass_t *_jit_regclass_combine(const char *name, int flags, 49 | _jit_regclass_t *class1, 50 | _jit_regclass_t *class2); 51 | 52 | /* Free a register class. */ 53 | void _jit_regclass_free(_jit_regclass_t *regclass); 54 | 55 | #ifdef __cplusplus 56 | }; 57 | #endif 58 | 59 | #endif /* _JIT_REG_CLASS_H */ 60 | -------------------------------------------------------------------------------- /jit/jit-rules-interp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-rules-interp.h - Rules that define the interpreter characteristics. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_RULES_INTERP_H 24 | #define _JIT_RULES_INTERP_H 25 | 26 | #include "jit-interp.h" 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | /* 33 | * Information about all of the registers, in allocation order. 34 | */ 35 | #define JIT_REG_INFO \ 36 | {"r0", 0, -1, JIT_REG_ALL | JIT_REG_CALL_USED}, \ 37 | {"r1", 1, -1, JIT_REG_ALL | JIT_REG_CALL_USED}, \ 38 | {"r2", 2, -1, JIT_REG_ALL | JIT_REG_CALL_USED}, 39 | #define JIT_NUM_REGS 3 40 | #define JIT_NUM_GLOBAL_REGS 0 41 | 42 | /* 43 | * Define to 1 if we should always load values into registers 44 | * before operating on them. i.e. the CPU does not have reg-mem 45 | * and mem-reg addressing modes. 46 | */ 47 | #define JIT_ALWAYS_REG_REG 1 48 | 49 | /* 50 | * The maximum number of bytes to allocate for the prolog. 51 | * This may be shortened once we know the true prolog size. 52 | */ 53 | #define JIT_PROLOG_SIZE jit_function_interp_size 54 | 55 | /* 56 | * Preferred alignment for the start of functions. 57 | */ 58 | #define JIT_FUNCTION_ALIGNMENT (sizeof(void *)) 59 | 60 | /* 61 | * Define this to 1 if the platform allows reads and writes on 62 | * any byte boundary. Define to 0 if only properly-aligned 63 | * memory accesses are allowed. 64 | */ 65 | #define JIT_ALIGN_OVERRIDES 0 66 | 67 | /* 68 | * Extra state information that is added to the "jit_gencode" structure. 69 | */ 70 | #define jit_extra_gen_state \ 71 | int working_area; \ 72 | int max_working_area; \ 73 | int extra_working_space 74 | #define jit_extra_gen_init(gen) \ 75 | do { \ 76 | (gen)->working_area = 0; \ 77 | (gen)->max_working_area = 0; \ 78 | (gen)->extra_working_space = 0; \ 79 | } while (0) 80 | #define jit_extra_gen_cleanup(gen) do { ; } while (0) 81 | 82 | #ifdef __cplusplus 83 | }; 84 | #endif 85 | 86 | #endif /* _JIT_RULES_INTERP_H */ 87 | -------------------------------------------------------------------------------- /jit/jit-rules-x86.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-rules-x86.h - Rules that define the characteristics of the x86. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_RULES_X86_H 24 | #define _JIT_RULES_X86_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Information about all of the registers, in allocation order. 32 | */ 33 | #define JIT_REG_X86_FLOAT \ 34 | (JIT_REG_FLOAT32 | JIT_REG_FLOAT64 | JIT_REG_NFLOAT) 35 | #define JIT_REG_INFO \ 36 | {"eax", 0, 2, JIT_REG_WORD | JIT_REG_LONG | JIT_REG_CALL_USED}, \ 37 | {"ecx", 1, 3, JIT_REG_WORD | JIT_REG_LONG | JIT_REG_CALL_USED}, \ 38 | {"edx", 2, -1, JIT_REG_WORD | JIT_REG_CALL_USED}, \ 39 | {"ebx", 3, -1, JIT_REG_WORD | JIT_REG_GLOBAL}, \ 40 | {"esi", 6, -1, JIT_REG_WORD | JIT_REG_GLOBAL}, \ 41 | {"edi", 7, -1, JIT_REG_WORD | JIT_REG_GLOBAL}, \ 42 | {"ebp", 4, -1, JIT_REG_FRAME | JIT_REG_FIXED}, \ 43 | {"esp", 5, -1, JIT_REG_STACK_PTR | JIT_REG_FIXED | JIT_REG_CALL_USED}, \ 44 | {"st", 0, -1, JIT_REG_X86_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, \ 45 | {"st1", 1, -1, JIT_REG_X86_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, \ 46 | {"st2", 2, -1, JIT_REG_X86_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, \ 47 | {"st3", 3, -1, JIT_REG_X86_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, \ 48 | {"st4", 4, -1, JIT_REG_X86_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, \ 49 | {"st5", 5, -1, JIT_REG_X86_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, \ 50 | {"st6", 6, -1, JIT_REG_X86_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, \ 51 | {"st7", 7, -1, JIT_REG_X86_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, 52 | #define JIT_NUM_REGS 16 53 | #define JIT_NUM_GLOBAL_REGS 3 54 | 55 | #define JIT_REG_STACK 1 56 | #define JIT_REG_STACK_START 8 57 | #define JIT_REG_STACK_END 15 58 | 59 | /* 60 | * Define to 1 if we should always load values into registers 61 | * before operating on them. i.e. the CPU does not have reg-mem 62 | * and mem-reg addressing modes. 63 | */ 64 | #define JIT_ALWAYS_REG_REG 0 65 | 66 | /* 67 | * The maximum number of bytes to allocate for the prolog. 68 | * This may be shortened once we know the true prolog size. 69 | */ 70 | #define JIT_PROLOG_SIZE 32 71 | 72 | /* 73 | * Preferred alignment for the start of functions. 74 | */ 75 | #define JIT_FUNCTION_ALIGNMENT 32 76 | 77 | /* 78 | * Define this to 1 if the platform allows reads and writes on 79 | * any byte boundary. Define to 0 if only properly-aligned 80 | * memory accesses are allowed. 81 | */ 82 | #define JIT_ALIGN_OVERRIDES 1 83 | 84 | /* 85 | * Parameter passing rules. 86 | */ 87 | #define JIT_CDECL_WORD_REG_PARAMS {-1} 88 | #define JIT_FASTCALL_WORD_REG_PARAMS {1, 2, -1} /* ecx, edx */ 89 | #define JIT_MAX_WORD_REG_PARAMS 2 90 | #define JIT_INITIAL_STACK_OFFSET (2 * sizeof(void *)) 91 | #define JIT_INITIAL_FRAME_SIZE 0 92 | 93 | #ifdef __cplusplus 94 | }; 95 | #endif 96 | 97 | #endif /* _JIT_RULES_X86_H */ 98 | -------------------------------------------------------------------------------- /jit/jit-setjmp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-setjmp.h - Support definitions that use "setjmp" for exceptions. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_SETJMP_H 24 | #define _JIT_SETJMP_H 25 | 26 | #include 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | /* 33 | * Jump buffer structure, with link. 34 | */ 35 | typedef struct jit_jmp_buf 36 | { 37 | jmp_buf buf; 38 | jit_backtrace_t trace; 39 | void *catch_pc; 40 | struct jit_jmp_buf *parent; 41 | 42 | } jit_jmp_buf; 43 | #define jit_jmp_catch_pc_offset \ 44 | ((jit_nint)&(((jit_jmp_buf *)0)->catch_pc)) 45 | 46 | /* 47 | * Push a "setjmp" buffer onto the current thread's unwind stck. 48 | */ 49 | void _jit_unwind_push_setjmp(jit_jmp_buf *jbuf); 50 | 51 | /* 52 | * Pop the top-most "setjmp" buffer from the current thread's unwind stack. 53 | */ 54 | void _jit_unwind_pop_setjmp(void); 55 | 56 | /* 57 | * Pop the top-most "setjmp" buffer and rethrow the current exception. 58 | */ 59 | void _jit_unwind_pop_and_rethrow(void); 60 | 61 | #ifdef __cplusplus 62 | }; 63 | #endif 64 | 65 | #endif /* _JIT_SETJMP_H */ 66 | -------------------------------------------------------------------------------- /jit/jit-signal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-signal.c - Internal management routines to use Operating System 3 | * signals for libjit exceptions handling. 4 | * 5 | * Copyright (C) 2006 Southern Storm Software, Pty Ltd. 6 | * 7 | * This file is part of the libjit library. 8 | * 9 | * The libjit library is free software: you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public License 11 | * as published by the Free Software Foundation, either version 2.1 of 12 | * the License, or (at your option) any later version. 13 | * 14 | * The libjit library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with the libjit library. If not, see 21 | * . 22 | */ 23 | 24 | #include "jit-internal.h" 25 | 26 | #ifdef JIT_USE_SIGNALS 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | /* 33 | * Use SIGSEGV for builtin libjit exception. 34 | */ 35 | static void sigsegv_handler(int signum, siginfo_t *info, void *uap) 36 | { 37 | jit_exception_builtin(JIT_RESULT_NULL_REFERENCE); 38 | } 39 | 40 | /* 41 | * Use SIGFPE for builtin libjit exception. 42 | */ 43 | static void sigfpe_handler(int signum, siginfo_t *info, void *uap) 44 | { 45 | switch(info->si_code) 46 | { 47 | case FPE_INTDIV: 48 | jit_exception_builtin(JIT_RESULT_DIVISION_BY_ZERO); 49 | break; 50 | case FPE_INTOVF: 51 | jit_exception_builtin(JIT_RESULT_OVERFLOW); 52 | break; 53 | case FPE_FLTDIV: 54 | jit_exception_builtin(JIT_RESULT_DIVISION_BY_ZERO); 55 | break; 56 | case FPE_FLTOVF: 57 | jit_exception_builtin(JIT_RESULT_OVERFLOW); 58 | break; 59 | case FPE_FLTUND: 60 | jit_exception_builtin(JIT_RESULT_ARITHMETIC); 61 | break; 62 | case FPE_FLTSUB: 63 | jit_exception_builtin(JIT_RESULT_ARITHMETIC); 64 | break; 65 | default: 66 | jit_exception_builtin(JIT_RESULT_ARITHMETIC); 67 | break; 68 | } 69 | } 70 | 71 | /* 72 | * Initialize signal handlers. 73 | */ 74 | void _jit_signal_init(void) 75 | { 76 | struct sigaction sa_fpe, sa_segv; 77 | 78 | sa_fpe.sa_sigaction = sigfpe_handler; 79 | sigemptyset(&sa_fpe.sa_mask); 80 | sa_fpe.sa_flags = SA_SIGINFO; 81 | if (sigaction(SIGFPE, &sa_fpe, 0)) { 82 | perror("Sigaction SIGFPE"); 83 | exit(1); 84 | } 85 | 86 | sa_segv.sa_sigaction = sigsegv_handler; 87 | sigemptyset(&sa_segv.sa_mask); 88 | sa_segv.sa_flags = SA_SIGINFO; 89 | if (sigaction(SIGSEGV, &sa_segv, 0)) { 90 | perror("Sigaction SIGSEGV"); 91 | exit(1); 92 | } 93 | } 94 | 95 | #endif /* JIT_USE_SIGNALS */ 96 | -------------------------------------------------------------------------------- /jit/jit-varint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-varint.h - Variable length integer encoding. 3 | * 4 | * Copyright (C) 2011 Aleksey Demakov 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_VARINT_H 22 | #define _JIT_VARINT_H 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | #define JIT_VARINT_BUFFER_SIZE 500 29 | 30 | typedef struct jit_varint_data *jit_varint_data_t; 31 | struct jit_varint_data 32 | { 33 | jit_varint_data_t next; 34 | unsigned char data[]; 35 | }; 36 | 37 | typedef struct jit_varint_encoder jit_varint_encoder_t; 38 | struct jit_varint_encoder 39 | { 40 | unsigned char buf[JIT_VARINT_BUFFER_SIZE]; 41 | int len; 42 | jit_varint_data_t data; 43 | jit_varint_data_t last; 44 | 45 | }; 46 | 47 | typedef struct jit_varint_decoder jit_varint_decoder_t; 48 | struct jit_varint_decoder 49 | { 50 | jit_varint_data_t data; 51 | int len; 52 | int end; 53 | }; 54 | 55 | void _jit_varint_init_encoder(jit_varint_encoder_t *encoder); 56 | void _jit_varint_init_decoder(jit_varint_decoder_t *decoder, jit_varint_data_t data); 57 | int _jit_varint_encode_end(jit_varint_encoder_t *encoder); 58 | int _jit_varint_encode_uint(jit_varint_encoder_t *encoder, jit_uint value); 59 | jit_varint_data_t _jit_varint_get_data(jit_varint_encoder_t *encoder); 60 | void _jit_varint_free_data(jit_varint_data_t data); 61 | int _jit_varint_decode_end(jit_varint_decoder_t *decoder); 62 | jit_uint _jit_varint_decode_uint(jit_varint_decoder_t *decoder); 63 | 64 | 65 | #ifdef __cplusplus 66 | } 67 | #endif 68 | 69 | #endif /* _JIT_VARINT_H */ 70 | 71 | -------------------------------------------------------------------------------- /jitdynamic/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | lib_LTLIBRARIES = libjitdynamic.la 3 | 4 | libjitdynamic_la_SOURCES = \ 5 | jit-dynlib.c \ 6 | jit-cpp-mangle.c 7 | 8 | AM_CFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include \ 9 | -I. -I$(srcdir) -I$(top_srcdir)/jit -I$(top_builddir)/jit 10 | 11 | libjitdynamic_la_LDFLAGS = \ 12 | -version-info $(LIBJIT_VERSION) \ 13 | -no-undefined \ 14 | -L$(top_builddir)/jit -L$(top_builddir)/jit/.libs -ljit 15 | libjitdynamic_la_DEPENDENCIES = $(top_builddir)/jit/libjit.la 16 | -------------------------------------------------------------------------------- /jitplus/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | lib_LTLIBRARIES = libjitplus.la 3 | 4 | libjitplus_la_SOURCES = \ 5 | jit-plus-context.cpp \ 6 | jit-plus-function.cpp \ 7 | jit-plus-value.cpp \ 8 | jit-plus-jump-table.cpp 9 | 10 | AM_CXXFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -I. -I$(srcdir) 11 | 12 | libjitplus_la_LDFLAGS = \ 13 | -version-info $(LIBJIT_VERSION) \ 14 | -no-undefined \ 15 | -L$(top_builddir)/jit -L$(top_builddir)/jit/.libs -ljit $(LIB_STDCPP) 16 | libjitplus_la_DEPENDENCIES = $(top_builddir)/jit/libjit.la 17 | -------------------------------------------------------------------------------- /jitplus/jit-plus-context.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-plus-context.cpp - C++ wrapper for JIT contexts. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #include 24 | 25 | /*@ 26 | 27 | The @code{jit_context} class provides a C++ counterpart to the 28 | C @code{jit_context_t} type. @xref{Initialization}, for more 29 | information on creating and managing contexts. 30 | 31 | @*/ 32 | 33 | /*@ 34 | * @defop Constructor jit_context jit_context () 35 | * Construct a new JIT context. This is equivalent to calling 36 | * @code{jit_context_create} in the C API. The raw C context is 37 | * destroyed when the @code{jit_context} object is destructed. 38 | * @end defop 39 | @*/ 40 | jit_context::jit_context() 41 | { 42 | jit_init(); 43 | context = jit_context_create(); 44 | copied = 0; 45 | } 46 | 47 | /*@ 48 | * @defop Constructor jit_context jit_context (jit_context_t @var{context}) 49 | * Construct a new JIT context by wrapping up an existing raw C context. 50 | * This is useful for importing a context from third party C code 51 | * into a program that prefers to use C++. 52 | * 53 | * When you use this form of construction, @code{jit_context_destroy} 54 | * will not be called on the context when the @code{jit_context} 55 | * object is destructed. You will need to arrange for that manually. 56 | * @end defop 57 | @*/ 58 | jit_context::jit_context(jit_context_t context) 59 | { 60 | this->context = context; 61 | this->copied = 1; 62 | } 63 | 64 | /*@ 65 | * @defop Destructor jit_context ~jit_context () 66 | * Destruct a JIT context. 67 | * @end defop 68 | @*/ 69 | jit_context::~jit_context() 70 | { 71 | if(!copied) 72 | { 73 | jit_context_destroy(context); 74 | } 75 | } 76 | 77 | /*@ 78 | * @deftypemethod jit_context void build_start () 79 | * Start an explicit build process. Not needed if you will be using 80 | * on-demand compilation. 81 | * @end deftypemethod 82 | * 83 | * @deftypemethod jit_context void build_end () 84 | * End an explicit build process. 85 | * @end deftypemethod 86 | * 87 | * @deftypemethod jit_context jit_context_t raw () const 88 | * Get the raw C context pointer that underlies this object. 89 | * @end deftypemethod 90 | @*/ 91 | -------------------------------------------------------------------------------- /jitplus/jit-plus-jump-table.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-plus-jump-table.cpp - C++ wrapper for JIT jump tables. 3 | * 4 | * Copyright (C) 2008 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #include 24 | 25 | jit_jump_table::jit_jump_table(int size) 26 | { 27 | try 28 | { 29 | labels = new jit_label_t[size]; 30 | } 31 | catch(...) 32 | { 33 | throw jit_build_exception(JIT_RESULT_OUT_OF_MEMORY); 34 | } 35 | for (int i = 0; i < size; i++) 36 | { 37 | labels[i] = jit_label_undefined; 38 | } 39 | num_labels = size; 40 | } 41 | 42 | jit_jump_table::~jit_jump_table() 43 | { 44 | delete [] labels; 45 | } 46 | 47 | jit_label 48 | jit_jump_table::get(int index) 49 | { 50 | if (index < 0 || index >= num_labels) 51 | { 52 | throw jit_build_exception(JIT_RESULT_COMPILE_ERROR); 53 | } 54 | return jit_label(labels[index]); 55 | } 56 | 57 | void 58 | jit_jump_table::set(int index, jit_label label) 59 | { 60 | if (index < 0 || index >= num_labels) 61 | { 62 | throw jit_build_exception(JIT_RESULT_COMPILE_ERROR); 63 | } 64 | labels[index] = label.raw(); 65 | } 66 | -------------------------------------------------------------------------------- /jitruby/README: -------------------------------------------------------------------------------- 1 | Ruby-libjit 0.1.0 2 | Copyright (C) 2008 Paul Brannan 3 | 4 | Ruby-libjit is a wrapper for the libjit library. It provides basic 5 | functionality for jit-compiling functions, including integrating those 6 | functions as callable methods from within Ruby. Abstractions are also 7 | provided so that jit code may be written in a ruby-like manner. 8 | 9 | Please see the file COPYING for license information. 10 | 11 | A simple example: 12 | 13 | :include: sample/simple.rb 14 | 15 | Looping structures and other abstractions are provided to make writing 16 | jit code easier: 17 | 18 | :include: sample/fib.rb 19 | 20 | To build ruby-libjit, you will need to install libjit. If it is not 21 | available pre-compiled for your platform, you may build the latest 22 | release like this: 23 | 24 | $ wget ftp://ftp.gnu.org/gnu/dotgnu/pnet/libjit-0.1.0.tar.gz 25 | $ tar xvfz libjit-0.1.0.tar.gz 26 | $ cd libjit-0.1.0 27 | $ ./configure 28 | $ make 29 | $ sudo make install 30 | 31 | Or the latest development version like this: 32 | 33 | $ cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/dotgnu-pnet co libjit 34 | $ cd libjit 35 | $ ./auto_gen.sh 36 | $ ./configure 37 | $ make 38 | $ sudo make install 39 | 40 | To build ruby-libjit, run setup.rb: 41 | 42 | $ ruby setup.rb config 43 | $ ruby setup.rb setup 44 | $ sudo ruby setup.rb install 45 | 46 | For a more complete JIT framework and compiler for Ruby code, please 47 | take a look at Ludicrous: 48 | 49 | http://rubystuff.org/ludicrous/ 50 | 51 | -------------------------------------------------------------------------------- /jitruby/ext/extconf.rb: -------------------------------------------------------------------------------- 1 | require 'mkmf' 2 | require 'rbconfig' 3 | 4 | if Config::CONFIG['host_os'] =~ /cygwin|win32|windows/ then 5 | need_windows_h = [ 'windows.h' ] 6 | $defs << ' -DNEED_WINDOWS_H' 7 | else 8 | need_windows_h = [ ] 9 | end 10 | 11 | if not have_library('jit', 'jit_init', need_windows_h + ["jit/jit.h"]) then 12 | $stderr.puts "libjit not found" 13 | exit 1 14 | end 15 | 16 | if not have_macro("SIZEOF_VALUE", "ruby.h") then 17 | check_sizeof("VALUE", "ruby.h") 18 | end 19 | 20 | if not have_macro("SIZEOF_ID", "ruby.h") then 21 | check_sizeof("ID", "ruby.h") 22 | end 23 | 24 | if have_macro("_GNU_SOURCE", "ruby.h") then 25 | $defs.push("-DRUBY_DEFINES_GNU_SOURCE") 26 | end 27 | 28 | have_func("rb_class_boot", "ruby.h") 29 | have_func("rb_errinfo", "ruby.h") 30 | have_func('fmemopen') 31 | have_func("rb_ensure", "ruby.h") 32 | 33 | if have_header('ruby/node.h') then 34 | # ruby.h defines HAVE_RUBY_NODE_H, even though it is not there 35 | $defs.push("-DREALLY_HAVE_RUBY_NODE_H") 36 | elsif have_header('node.h') then 37 | # okay 38 | else 39 | $defs.push("-DNEED_MINIMAL_NODE") 40 | end 41 | 42 | have_header('env.h') 43 | 44 | checking_for("whether VALUE is a pointer") do 45 | if not try_link(<<"SRC") 46 | #include 47 | int main() 48 | { 49 | VALUE v; 50 | v /= 5; 51 | } 52 | SRC 53 | then 54 | $defs.push("-DVALUE_IS_PTR"); 55 | end 56 | end 57 | 58 | if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'rbx' then 59 | $defs.push("-DHAVE_RUBINIUS") 60 | end 61 | 62 | rb_files = Dir['*.rb'] 63 | rpp_files = Dir['*.rpp'] 64 | generated_files = rpp_files.map { |f| f.sub(/\.rpp$/, '') } 65 | 66 | srcs = Dir['*.c'] 67 | generated_files.each do |f| 68 | if f =~ /\.c$/ then 69 | srcs << f 70 | end 71 | end 72 | srcs.uniq! 73 | $objs = srcs.map { |f| f.sub(/\.c$/, ".#{$OBJEXT}") } 74 | 75 | if Config::CONFIG['CC'] == 'gcc' then 76 | # $CFLAGS << ' -Wall -g -pedantic -Wno-long-long' 77 | $CFLAGS << ' -Wall -g' 78 | end 79 | 80 | create_makefile("jit") 81 | 82 | append_to_makefile = '' 83 | 84 | rpp_files.each do |rpp_file| 85 | dest_file = rpp_file.sub(/\.rpp$/, '') 86 | append_to_makefile << < 5 | 6 | void define_method_with_data( 7 | VALUE klass, ID id, VALUE (*cfunc)(ANYARGS), int arity, VALUE data); 8 | 9 | VALUE get_method_data(); 10 | 11 | #endif // METHOD_DATA_H 12 | -------------------------------------------------------------------------------- /jitruby/ext/minimal_node.c: -------------------------------------------------------------------------------- 1 | #ifdef NEED_MINIMAL_NODE 2 | 3 | #include "minimal_node.h" 4 | #include 5 | 6 | int NODE_MEMO = 0; 7 | int NODE_METHOD = 0; 8 | int NODE_FBODY = 0; 9 | int NODE_CFUNC = 0; 10 | 11 | char const * ruby_node_name(int node); 12 | 13 | static int node_value(char const * name) 14 | { 15 | /* TODO: any way to end the block? */ 16 | int j; 17 | for(j = 0; ; ++j) 18 | { 19 | if(!strcmp(name, ruby_node_name(j))) 20 | { 21 | return j; 22 | } 23 | } 24 | } 25 | 26 | void Init_minimal_node() 27 | { 28 | NODE_MEMO = node_value("NODE_MEMO"); 29 | NODE_METHOD = node_value("NODE_METHOD"); 30 | NODE_FBODY = node_value("NODE_FBODY"); 31 | NODE_CFUNC = node_value("NODE_CFUNC"); 32 | } 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /jitruby/ext/minimal_node.h: -------------------------------------------------------------------------------- 1 | #ifndef minimal_node_h 2 | #define minimal_node_h 3 | 4 | #ifdef NEED_MINIMAL_NODE 5 | 6 | #include "ruby.h" 7 | 8 | typedef struct RNode { 9 | unsigned long flags; 10 | void * reserved; 11 | union { 12 | struct RNode * node; 13 | VALUE (*cfunc)(ANYARGS); 14 | } u1; 15 | union { 16 | struct RNode * node; 17 | VALUE value; 18 | } u2; 19 | union { 20 | struct RNode * node; 21 | } u3; 22 | } NODE; 23 | 24 | #define nd_cfnc u1.cfunc 25 | #define nd_rval u2.value 26 | 27 | #define NEW_NODE(t,a0,a1,a2) rb_node_newnode((t),(VALUE)(a0),(VALUE)(a1),(VALUE)(a2)) 28 | 29 | /* TODO: No way to know the correct size of node_type */ 30 | enum node_type { 31 | NODE_FOO, 32 | }; 33 | 34 | void rb_add_method(VALUE, ID, NODE *, int); 35 | NODE *rb_node_newnode(enum node_type, VALUE, VALUE, VALUE); 36 | 37 | extern int NODE_MEMO; 38 | extern int NODE_METHOD; 39 | extern int NODE_FBODY; 40 | extern int NODE_CFUNC; 41 | 42 | void Init_minimal_node(); 43 | 44 | #define NOEX_PUBLIC 0x0 45 | 46 | #define NEW_METHOD(n,x,v) NEW_NODE(NODE_METHOD,x,n,v) 47 | #define NEW_FBODY(n,i) NEW_NODE(NODE_FBODY,i,n,0) 48 | #define NEW_CFUNC(f,c) NEW_NODE(NODE_CFUNC,f,c,0) 49 | 50 | #endif 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /jitruby/ext/rubyjit.h: -------------------------------------------------------------------------------- 1 | #ifndef RUBYJIT_H 2 | #define RUBYJIT_H 3 | 4 | enum Ruby_Libjit_Tag 5 | { 6 | RJT_OBJECT, 7 | RJT_ID, 8 | RJT_FUNCTION_PTR, 9 | RJT_RUBY_VARARG_SIGNATURE, 10 | RJT_VALUE_OBJECTS, 11 | RJT_FUNCTIONS, 12 | RJT_CONTEXT, 13 | RJT_TAG_FOR_SIGNATURE 14 | }; 15 | 16 | extern jit_type_t jit_type_VALUE; 17 | extern jit_type_t jit_type_ID; 18 | extern jit_type_t jit_type_Function_Ptr; 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /jitruby/ext/rubypp.rb: -------------------------------------------------------------------------------- 1 | class Preprocessor 2 | def initialize(input, output, filename) 3 | @input = input 4 | @output = output 5 | @filename = filename 6 | @linenum = 1 7 | end 8 | 9 | def getline 10 | line = @input.gets 11 | @linenum += 1 if not line.nil? 12 | return line 13 | end 14 | 15 | def preprocess 16 | success = false 17 | begin 18 | loop do 19 | line = getline 20 | break if line.nil? 21 | case line 22 | when /(.*[^\\]|^)\#\{(.*?)\}(.*)/ 23 | puts "#{$1}#{evaluate($2, @linenum)}#{$3}" 24 | when /^\#ruby\s+<<(.*)/ 25 | marker = $1 26 | str = '' 27 | evalstart = @linenum 28 | loop do 29 | line = getline 30 | if line.nil? then 31 | raise "End of input without #{marker}" 32 | end 33 | break if line.chomp == marker 34 | str << line 35 | end 36 | result = evaluate(str, evalstart) 37 | puts result if not result.nil? 38 | when /^\#ruby\s+(.*)/ 39 | str = line = $1 40 | while line[-1] == ?\\ 41 | str.chop! 42 | line = getline 43 | break if line.nil? 44 | line.chomp! 45 | str << line 46 | end 47 | result = evaluate(str, @linenum) 48 | puts result if not result.nil? 49 | else 50 | puts line 51 | end 52 | end 53 | success = true 54 | ensure 55 | if not success then 56 | $stderr.puts "Error on line #{@linenum}:" 57 | end 58 | end 59 | end 60 | 61 | def evaluate(str, linenum) 62 | result = eval(str, TOPLEVEL_BINDING, @filename, linenum) 63 | success = true 64 | return result 65 | end 66 | 67 | def puts(line='') 68 | @output.puts(line) 69 | end 70 | end 71 | 72 | def puts(line='') 73 | $preprocessor.puts(line) 74 | end 75 | 76 | def rubypp(input_file, output_file) 77 | input = input_file ? File.open(input_file) : $stdin 78 | output = output_file ? File.open(output_file, 'w') : $stdout 79 | 80 | success = false 81 | begin 82 | $preprocessor = Preprocessor.new(input, output, input_file || "(stdin)") 83 | $preprocessor.preprocess() 84 | success = true 85 | ensure 86 | if not success then 87 | File.unlink(output_file) rescue Errno::ENOENT 88 | end 89 | end 90 | end 91 | 92 | if __FILE__ == $0 then 93 | input_file = ARGV[0] 94 | output_file = ARGV[1] 95 | rubypp(input_file, output_file) 96 | end 97 | 98 | -------------------------------------------------------------------------------- /jitruby/generate_rdoc.rb: -------------------------------------------------------------------------------- 1 | require 'find' 2 | 3 | def list_files(dir, pattern) 4 | arr = [] 5 | Find.find(dir) do |filename| 6 | if filename =~ pattern then 7 | arr.push(filename) 8 | end 9 | end 10 | return arr 11 | end 12 | 13 | def generate_rdoc(*options) 14 | begin 15 | require 'rdoc/rdoc' 16 | rescue LoadError 17 | puts "WARNING: RDoc not installed; skipping generation of docs" 18 | return 19 | end 20 | 21 | r = RDoc::RDoc.new 22 | rdoc_files = [] 23 | rdoc_files.concat [ 'README' ] 24 | rdoc_files.concat list_files('lib', /\.rb$/) if File.exist?('lib') 25 | rdoc_files.concat list_files('ext', /\.c$/) if File.exist?('ext') 26 | rdoc_files.reject! { |file| file =~ %r{^ext/cached/} } 27 | r.document(options + rdoc_files) 28 | end 29 | 30 | if __FILE__ == $0 then 31 | generate_rdoc(*ARGV) 32 | end 33 | 34 | -------------------------------------------------------------------------------- /jitruby/lib/jit.rb: -------------------------------------------------------------------------------- 1 | require 'jit.so' 2 | require 'jit/array' 3 | require 'jit/function' 4 | require 'jit/struct' 5 | require 'jit/value' 6 | -------------------------------------------------------------------------------- /jitruby/lib/jit/array.rb: -------------------------------------------------------------------------------- 1 | require 'jit' 2 | require 'jit/value' 3 | 4 | module JIT 5 | 6 | # An abstraction for a fixed-length array type. 7 | # 8 | # Example usage: 9 | # 10 | # array_type = JIT::Array.new(JIT::Type::INT, 4) 11 | # 12 | # JIT::Context.build do |context| 13 | # signature = JIT::Type.create_signature( 14 | # JIT::ABI::CDECL, JIT::Type::INT, [ ]) 15 | # 16 | # function = JIT::Function.compile(context, signature) do |f| 17 | # array_instance = array_type.create(f) 18 | # array_instance[0] = f.const(JIT::Type::INT, 42) 19 | # f.insn_return(array_instance[0]) 20 | # end 21 | # 22 | # end 23 | # 24 | class Array < JIT::Type 25 | attr_reader :type 26 | attr_reader :length 27 | 28 | # Create a new JIT array type. 29 | # 30 | # +type+:: The type of the elements in the array. 31 | # +length+:: The number of elements in the array. 32 | # 33 | def self.new(type, length) 34 | array = self.create_struct([ type ] * length) 35 | array.instance_eval do 36 | @type = type 37 | @length = length 38 | end 39 | return array 40 | end 41 | 42 | # Wrap an existing array. 43 | # 44 | # +ptr+:: A pointer to the first element in the array. 45 | # 46 | def wrap(ptr) 47 | return Instance.wrap(self, ptr) 48 | end 49 | 50 | # Create a new array. 51 | # 52 | # +function+:: The JIT::Function this array will be used in. 53 | # 54 | def create(function) 55 | instance = function.value(self) 56 | ptr = function.insn_address_of(instance) 57 | return wrap(ptr) 58 | end 59 | 60 | # Return the offset (in bytes) of the element at the given +index+. 61 | # 62 | # +index+:: The index of the desired element. 63 | # 64 | def offset_of(index) 65 | return self.get_offset(index) 66 | end 67 | 68 | # Return the type of the element at the given +index+. 69 | # 70 | # +index+:: The index of the desired element. 71 | # 72 | def type_of(index) 73 | return @type 74 | end 75 | 76 | # An abstraction for an instance of a fixed-length array. 77 | # 78 | class Instance < JIT::Value 79 | attr_reader :array_type 80 | attr_reader :type 81 | 82 | # A pointer to the first element of the array. Note that this 83 | # differs from +address+, which returns the address of a pointer 84 | # to the array. 85 | attr_reader :ptr 86 | 87 | # TODO: This breaks code below? 88 | # attr_reader :function 89 | 90 | # Wrap an existing array. 91 | # 92 | # +array_type+:: The JIT::Array type to wrap. 93 | # +ptr+:: A pointer to the first element in the array. 94 | # 95 | def self.wrap(array_type, ptr) 96 | pointer_type = JIT::Type.create_pointer(array_type) 97 | value = self.new_value(ptr.function, pointer_type) 98 | value.store(ptr) 99 | value.instance_eval do 100 | @array_type = array_type 101 | @type = array_type.type 102 | @function = ptr.function 103 | @ptr = ptr 104 | end 105 | return value 106 | end 107 | 108 | # Generate JIT code to retrieve the element at the given +index+. 109 | # 110 | # +index+:: The index of the desired element. The value of the 111 | # index must be known at compile-time. 112 | # 113 | def [](index) 114 | @function.insn_load_relative( 115 | @ptr, 116 | @array_type.offset_of(index), 117 | @array_type.type_of(index)) 118 | end 119 | 120 | # Generate JIT code to assign to the element at the given +index+. 121 | # 122 | # +index+:: The index of the desired element. The value of the 123 | # index must be known at compile-time. 124 | # +value+:: The JIT::Value to assign to the element. 125 | # 126 | def []=(index, value) 127 | @function.insn_store_relative( 128 | @ptr, 129 | @array_type.offset_of(index), 130 | value) 131 | end 132 | end 133 | end 134 | end 135 | 136 | -------------------------------------------------------------------------------- /jitruby/lib/jit/pointer.rb: -------------------------------------------------------------------------------- 1 | require 'jit' 2 | require 'jit/value' 3 | 4 | module JIT 5 | 6 | # An abstraction for a pointer to a non-void type. 7 | # 8 | # Example usage: 9 | # 10 | # TODO 11 | # 12 | class Pointer < JIT::Type 13 | attr_reader :type 14 | 15 | # Create a new JIT pointer type. 16 | # 17 | # +type+:: The pointed-to type. 18 | # 19 | def self.new(type) 20 | pointer_type = self.create_pointer(type) 21 | pointer_type.instance_eval do 22 | @type = type 23 | end 24 | return pointer_type 25 | end 26 | 27 | # Wrap an existing void pointer. 28 | # 29 | # +ptr+:: The pointer to wrap. 30 | # 31 | def wrap(ptr) 32 | return Instance.wrap(self, ptr) 33 | end 34 | 35 | # Return the offset (in bytes) of the element at the given +index+. 36 | # 37 | # +index+:: The index of the desired element. 38 | # 39 | def offset_of(index) 40 | return index * @type.size 41 | end 42 | 43 | # Return the type of the element at the given +index+. 44 | # 45 | # +index+:: The index of the desired element. 46 | # 47 | def type_of(index) 48 | return @type 49 | end 50 | 51 | # An abstraction for a pointer object. 52 | # 53 | class Instance < JIT::Value 54 | # Wrap an existing void pointer. 55 | # 56 | # +array_type+:: The JIT::Array type to wrap. 57 | # +ptr+:: A pointer to the first element in the array. 58 | # 59 | def self.wrap(pointer_type, ptr) 60 | value = self.new_value(ptr.function, pointer_type) 61 | value.store(ptr) 62 | value.instance_eval do 63 | @pointer_type = pointer_type 64 | @pointed_type = pointer_type.type 65 | @function = ptr.function 66 | @ptr = ptr 67 | end 68 | return value 69 | end 70 | 71 | # Generate JIT code to retrieve the element at the given +index+. 72 | # 73 | # +index+:: The index of the desired element. The value of the 74 | # index must be known at compile-time. 75 | # 76 | def [](index) 77 | @function.insn_load_relative( 78 | @ptr, 79 | @pointer_type.offset_of(index), 80 | @pointer_type.type_of(index)) 81 | end 82 | 83 | # Generate JIT code to assign to the element at the given +index+. 84 | # 85 | # +index+:: The index of the desired element. The value of the 86 | # index must be known at compile-time. 87 | # +value+:: The JIT::Value to assign to the element. 88 | # 89 | def []=(index, value) 90 | @function.insn_store_relative( 91 | @ptr, 92 | @pointer_type.offset_of(index), 93 | value) 94 | end 95 | end 96 | end 97 | end 98 | 99 | -------------------------------------------------------------------------------- /jitruby/metaconfig: -------------------------------------------------------------------------------- 1 | add_bool_config( 2 | 'without-tests', 3 | false, 4 | 'does not run tests') 5 | -------------------------------------------------------------------------------- /jitruby/post-install.rb: -------------------------------------------------------------------------------- 1 | require 'generate_rdoc' 2 | 3 | generate_rdoc('--ri-site') 4 | 5 | -------------------------------------------------------------------------------- /jitruby/post-setup.rb: -------------------------------------------------------------------------------- 1 | require 'run_tests' 2 | require 'generate_rdoc' 3 | 4 | if config('without-tests') != 'yes' then 5 | run_tests() 6 | end 7 | 8 | -------------------------------------------------------------------------------- /jitruby/ruby-libjit.gemspec: -------------------------------------------------------------------------------- 1 | require 'enumerator' 2 | 3 | spec = Gem::Specification.new do |s| 4 | s.name = 'ruby-libjit' 5 | s.version = '0.1.0' 6 | s.summary = 'A wrapper for the libjit library' 7 | s.homepage = 'http://ruby-libjit.rubyforge.org' 8 | s.rubyforge_project = 'ruby-libjit' 9 | s.author = 'Paul Brannan' 10 | s.email = 'curlypaul924@gmail.com' 11 | 12 | s.description = <<-END 13 | A wrapper for the libjit library 14 | END 15 | 16 | 17 | patterns = [ 18 | 'COPYING', 19 | 'LGPL', 20 | 'LICENSE', 21 | 'README', 22 | 'lib/*.rb', 23 | 'lib/jit/*.rb', 24 | 'ext/*.rb', 25 | 'ext/*.c', 26 | 'ext/*.h', 27 | 'ext/*.rpp', 28 | 'sample/*.rb', 29 | ] 30 | 31 | s.files = patterns.collect { |p| Dir.glob(p) }.flatten 32 | 33 | s.test_files = Dir.glob('test/test_*.rb') 34 | 35 | s.extensions = 'ext/extconf.rb' 36 | 37 | s.has_rdoc = true 38 | end 39 | 40 | -------------------------------------------------------------------------------- /jitruby/run_tests.rb: -------------------------------------------------------------------------------- 1 | $mini_unit_exit_code = 0 2 | 3 | def disable_mini_unit_auto_run 4 | MiniTest::Unit.class_eval do 5 | alias :run_ :run 6 | def run(*args) 7 | return $mini_unit_exit_code 8 | end 9 | end 10 | end 11 | 12 | def run_tests_with_mini_unit 13 | begin 14 | test = MiniTest::Unit.new 15 | args = ARGV.dup 16 | args << '-v' 17 | $mini_unit_exit_code = test.run(args) 18 | exit($mini_unit_exit_code) 19 | ensure 20 | disable_mini_unit_auto_run 21 | end 22 | end 23 | 24 | def run_tests_with_test_unit 25 | tests = [] 26 | ObjectSpace.each_object(Class) do |o| 27 | if o < Test::Unit::TestCase then 28 | tests << o 29 | end 30 | end 31 | 32 | suite = Test::Unit::TestSuite.new("RubyInternal") 33 | tests.each do |test| 34 | test.suite.tests.each do |testcase| 35 | suite << testcase 36 | end 37 | end 38 | 39 | require 'test/unit/ui/console/testrunner' 40 | verbose = nil 41 | begin 42 | verbose = Test::Unit::UI.const_get(:VERBOSE) 43 | rescue NameError 44 | verbose = Test::Unit::UI::Console::TestRunner.const_get(:VERBOSE) 45 | end 46 | 47 | result = Test::Unit::UI::Console::TestRunner.run( 48 | suite, 49 | verbose) 50 | exit(result.error_count + result.failure_count) 51 | end 52 | 53 | def run_tests 54 | begin 55 | require 'test/unit' 56 | rescue LoadError 57 | puts "WARNING: Test::Unit not installed; skipping tests" 58 | return 59 | end 60 | 61 | $:.unshift(File.join(Dir.pwd, 'ext')) 62 | $:.unshift(File.join(Dir.pwd, 'lib')) 63 | Dir.chdir('test') 64 | tests = Dir['test_*.rb'] 65 | tests.each do |test| 66 | load test 67 | end 68 | 69 | if defined?(MiniTest) then 70 | run_tests_with_mini_unit 71 | else 72 | run_tests_with_test_unit 73 | end 74 | end 75 | 76 | if __FILE__ == $0 then 77 | require 'timeout' 78 | result = nil 79 | timeout(600) { run_tests() } 80 | end 81 | 82 | -------------------------------------------------------------------------------- /jitruby/sample/fib.rb: -------------------------------------------------------------------------------- 1 | require 'jit' 2 | 3 | fib = nil 4 | signature = JIT::Type.create_signature( 5 | :CDECL, 6 | :INT, 7 | [ :INT ]) 8 | fib = JIT::Function.build(signature) do |f| 9 | n = f.param(0) 10 | 11 | a = f.value(:INT, 0) 12 | b = f.value(:INT, 1) 13 | c = f.value(:INT, 1) 14 | 15 | i = f.value(:INT, 0) 16 | 17 | f.while{ i < n }.do { 18 | c.store(a + b) 19 | a.store(b) 20 | b.store(c) 21 | i.store(i + 1) 22 | }.end 23 | 24 | f.return(c) 25 | end 26 | 27 | values = (0...10).collect { |x| fib.apply(x) } 28 | p values #=> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] 29 | 30 | -------------------------------------------------------------------------------- /jitruby/sample/gcd_benchmark.rb: -------------------------------------------------------------------------------- 1 | require 'jit' 2 | require 'benchmark' 3 | 4 | # GCD, JIT-compiled 5 | 6 | jit_gcd = nil 7 | 8 | JIT::Context.build do |context| 9 | signature = JIT::Type.create_signature( 10 | JIT::ABI::CDECL, 11 | JIT::Type::INT, 12 | [ JIT::Type::INT, JIT::Type::INT ]) 13 | jit_gcd = JIT::Function.compile(context, signature) do |f| 14 | x = f.get_param(0) 15 | y = f.get_param(1) 16 | temp1 = f.insn_eq(x, y) 17 | label1 = JIT::Label.new 18 | f.insn_branch_if_not(temp1, label1) 19 | f.insn_return(x) 20 | f.insn_label(label1) 21 | temp2 = f.insn_lt(x, y) 22 | label2 = JIT::Label.new 23 | f.insn_branch_if_not(temp2, label2) 24 | s1 = f.insn_sub(y, x) 25 | temp3 = f.insn_call("gcd", f, 0, x, s1) 26 | f.insn_return(temp3) 27 | f.insn_label(label2) 28 | s2 = f.insn_sub(x, y) 29 | temp4 = f.insn_call("gcd", f, 0, s2, y) 30 | f.insn_return(temp4) 31 | 32 | f.optimization_level = 3 33 | end 34 | end 35 | 36 | if jit_gcd.apply(28, 21) != 7 then 37 | puts "jit_gcd is broken" 38 | exit 1 39 | end 40 | 41 | 42 | # GCD with tail recursion optimization 43 | 44 | jit_gcd_tail = nil 45 | 46 | JIT::Context.build do |context| 47 | signature = JIT::Type.create_signature( 48 | JIT::ABI::CDECL, 49 | JIT::Type::INT, 50 | [ JIT::Type::INT, JIT::Type::INT ]) 51 | jit_gcd_tail = JIT::Function.compile(context, signature) do |f| 52 | x = f.get_param(0) 53 | y = f.get_param(1) 54 | temp1 = f.insn_eq(x, y) 55 | label1 = JIT::Label.new 56 | f.insn_branch_if_not(temp1, label1) 57 | f.insn_return(x) 58 | f.insn_label(label1) 59 | temp2 = f.insn_lt(x, y) 60 | label2 = JIT::Label.new 61 | f.insn_branch_if_not(temp2, label2) 62 | s1 = f.insn_sub(y, x) 63 | temp3 = f.insn_call("gcd", f, JIT::Call::TAIL, x, s1) 64 | # f.insn_return(temp3) 65 | f.insn_label(label2) 66 | s2 = f.insn_sub(x, y) 67 | temp4 = f.insn_call("gcd", f, JIT::Call::TAIL, s2, x) 68 | # f.insn_return(temp4) 69 | 70 | f.optimization_level = 3 71 | end 72 | end 73 | 74 | if jit_gcd_tail.apply(28, 21) != 7 then 75 | puts "jit_gcd_tail is broken" 76 | exit 1 77 | end 78 | 79 | 80 | # GCD in ruby with recursion 81 | 82 | def gcd(x, y) 83 | if x == y 84 | return x 85 | elsif x < y 86 | return gcd(x, y - x) 87 | else 88 | return gcd(x - y, y) 89 | end 90 | end 91 | 92 | 93 | # GCD in ruby without recursion 94 | 95 | def gcd2(x, y) 96 | while x != y do 97 | if x < y 98 | y -= x 99 | else 100 | x -= y 101 | end 102 | end 103 | return x 104 | end 105 | 106 | N = 1000 107 | 108 | X = 1000 109 | Y = 1005 110 | 111 | Benchmark.bm(16) do |x| 112 | x.report("jit") { N.times { jit_gcd.apply(X, Y) } } 113 | x.report("jit tail:") { N.times { jit_gcd_tail.apply(X, Y) } } 114 | x.report("ruby recur:") { N.times { gcd(X, Y) } } 115 | x.report("ruby iter:") { N.times { gcd2(X, Y) } } 116 | end 117 | 118 | -------------------------------------------------------------------------------- /jitruby/sample/simple.rb: -------------------------------------------------------------------------------- 1 | require 'jit' 2 | 3 | function = nil 4 | JIT::Context.build do |context| 5 | signature = JIT::Type.create_signature( 6 | JIT::ABI::CDECL, 7 | JIT::Type::INT, # returns an integer 8 | [ JIT::Type::INT ]) # and tages an integer as a parameter 9 | function = JIT::Function.compile(context, signature) do |f| 10 | value = f.get_param(0) 11 | f.insn_return(value) 12 | end 13 | end 14 | 15 | p function.apply(42) #=> 42 16 | -------------------------------------------------------------------------------- /jitruby/test/assertions.rb: -------------------------------------------------------------------------------- 1 | module JitAssertions 2 | def assert_function_result(args, &block) 3 | result_type = nil 4 | expected_result = nil 5 | param_types = [] 6 | params = [] 7 | 8 | args.each do |k, v| 9 | case k.to_s 10 | when /^arg(\d+)$/ 11 | n = $1.to_i 12 | param_types[n] = v[0] 13 | params[n] = v[1] 14 | when 'result' 15 | result_type = v[0] 16 | expected_result = v[1] 17 | else 18 | raise "Bad arg #{arg}" 19 | end 20 | end 21 | 22 | function = nil 23 | JIT::Context.build do |context| 24 | signature = JIT::Type.create_signature( 25 | JIT::ABI::CDECL, 26 | result_type, 27 | param_types) 28 | function = JIT::Function.compile(context, signature, &block) 29 | end 30 | 31 | assert_equal(expected_result, function.apply(*params)) 32 | end 33 | end 34 | 35 | -------------------------------------------------------------------------------- /jitruby/test/test_jit_array.rb: -------------------------------------------------------------------------------- 1 | require 'jit/array' 2 | require 'jit/function' 3 | require 'test/unit' 4 | require 'assertions' 5 | 6 | class TestJitArray < Test::Unit::TestCase 7 | include JitAssertions 8 | 9 | def test_new_array 10 | a_type = JIT::Array.new(JIT::Type::INT, 12) 11 | assert_equal JIT::Type::INT, a_type.type 12 | assert_equal 12, a_type.length 13 | end 14 | 15 | # TODO: wrap 16 | 17 | def test_create 18 | p = proc { |f| 19 | a_type = JIT::Array.new(JIT::Type::INT, 4) 20 | a = a_type.create(f) 21 | f.return f.const(JIT::Type::INT, 0) 22 | } 23 | assert_function_result( 24 | :result => [ JIT::Type::INT, 0 ], 25 | &p) 26 | end 27 | 28 | def test_offset_of 29 | a_type = JIT::Array.new(JIT::Type::INT, 4) 30 | assert_equal 0, a_type.offset_of(0) 31 | assert_equal 4, a_type.offset_of(1) 32 | assert_equal 8, a_type.offset_of(2) 33 | assert_equal 12, a_type.offset_of(3) 34 | # TODO: check out of bounds 35 | end 36 | 37 | def test_type_of 38 | a_type = JIT::Array.new(JIT::Type::INT, 4) 39 | assert_equal JIT::Type::INT, a_type.type_of(0) 40 | assert_equal JIT::Type::INT, a_type.type_of(1) 41 | assert_equal JIT::Type::INT, a_type.type_of(2) 42 | assert_equal JIT::Type::INT, a_type.type_of(3) 43 | # TODO: check out of bounds 44 | end 45 | 46 | def test_instance_bracket 47 | p = proc { |f| 48 | a_type = JIT::Array.new(JIT::Type::INT, 4) 49 | a = a_type.create(f) 50 | f.insn_store_relative(a.ptr, 4, f.const(JIT::Type::INT, 42)) 51 | f.return a[1] 52 | } 53 | assert_function_result( 54 | :result => [ JIT::Type::INT, 42 ], 55 | &p) 56 | end 57 | 58 | def test_instance_bracket_eq 59 | p = proc { |f| 60 | a_type = JIT::Array.new(JIT::Type::INT, 4) 61 | a = a_type.create(f) 62 | a[1] = f.const(JIT::Type::INT, 42) 63 | f.return a[1] 64 | } 65 | assert_function_result( 66 | :result => [ JIT::Type::INT, 42 ], 67 | &p) 68 | end 69 | end 70 | 71 | -------------------------------------------------------------------------------- /jitruby/test/test_jit_pointer.rb: -------------------------------------------------------------------------------- 1 | require 'jit/pointer' 2 | require 'jit/array' 3 | require 'jit/function' 4 | require 'test/unit' 5 | require 'assertions' 6 | 7 | class TestJitArray < Test::Unit::TestCase 8 | include JitAssertions 9 | 10 | def test_new_pointer 11 | p_type = JIT::Pointer.new(JIT::Type::INT) 12 | assert_equal JIT::Type::INT, p_type.type 13 | end 14 | 15 | # TODO: wrap 16 | 17 | def test_offset_of 18 | p_type = JIT::Pointer.new(JIT::Type::INT) 19 | assert_equal 0, p_type.offset_of(0) 20 | assert_equal 4, p_type.offset_of(1) 21 | assert_equal 8, p_type.offset_of(2) 22 | assert_equal 12, p_type.offset_of(3) 23 | # TODO: check out of bounds 24 | end 25 | 26 | def test_type_of 27 | p_type = JIT::Pointer.new(JIT::Type::INT) 28 | assert_equal JIT::Type::INT, p_type.type_of(0) 29 | assert_equal JIT::Type::INT, p_type.type_of(1) 30 | assert_equal JIT::Type::INT, p_type.type_of(2) 31 | assert_equal JIT::Type::INT, p_type.type_of(3) 32 | # TODO: check out of bounds 33 | end 34 | 35 | def test_instance_bracket 36 | p = proc { |f| 37 | a_type = JIT::Array.new(JIT::Type::INT, 4) 38 | p_type = JIT::Pointer.new(JIT::Type::INT) 39 | a = a_type.create(f) 40 | ptr = p_type.wrap(a.ptr) 41 | f.insn_store_relative(a.ptr, 4, f.const(JIT::Type::INT, 42)) 42 | f.return ptr[1] 43 | } 44 | assert_function_result( 45 | :result => [ JIT::Type::INT, 42 ], 46 | &p) 47 | end 48 | 49 | def test_instance_bracket_eq 50 | p = proc { |f| 51 | a_type = JIT::Array.new(JIT::Type::INT, 4) 52 | p_type = JIT::Pointer.new(JIT::Type::INT) 53 | a = a_type.create(f) 54 | ptr = p_type.wrap(a.ptr) 55 | ptr[1] = f.const(JIT::Type::INT, 42) 56 | f.return a[1] 57 | } 58 | assert_function_result( 59 | :result => [ JIT::Type::INT, 42 ], 60 | &p) 61 | end 62 | end 63 | 64 | -------------------------------------------------------------------------------- /jitruby/test/test_jit_struct.rb: -------------------------------------------------------------------------------- 1 | require 'jit/array' 2 | require 'jit/function' 3 | require 'test/unit' 4 | require 'assertions' 5 | 6 | class TestJitStruct < Test::Unit::TestCase 7 | include JitAssertions 8 | 9 | def test_new_struct 10 | s_type = JIT::Struct.new( 11 | [ :foo, JIT::Type::INT ], 12 | [ :bar, JIT::Type::VOID_PTR ], 13 | [ :baz, JIT::Type::FLOAT32 ]) 14 | assert_equal [ :foo, :bar, :baz ], s_type.members 15 | end 16 | 17 | def test_create 18 | p = proc { |f| 19 | s_type = JIT::Struct.new( 20 | [ :foo, JIT::Type::INT ], 21 | [ :bar, JIT::Type::VOID_PTR ], 22 | [ :baz, JIT::Type::FLOAT32 ]) 23 | s = s_type.create(f) 24 | f.return f.const(JIT::Type::INT, 0) 25 | } 26 | assert_function_result( 27 | :result => [ JIT::Type::INT, 0 ], 28 | &p) 29 | end 30 | 31 | def test_offset_of 32 | s_type = JIT::Struct.new( 33 | [ :foo, JIT::Type::INT ], 34 | [ :bar, JIT::Type::FLOAT64 ], 35 | [ :baz, JIT::Type::VOID_PTR ]) 36 | assert_equal 0, s_type.offset_of(:foo) 37 | assert_equal 4, s_type.offset_of(:bar) 38 | assert_equal 12, s_type.offset_of(:baz) 39 | end 40 | 41 | def test_type_of 42 | s_type = JIT::Struct.new( 43 | [ :foo, JIT::Type::INT ], 44 | [ :bar, JIT::Type::FLOAT64 ], 45 | [ :baz, JIT::Type::VOID_PTR ]) 46 | assert_equal JIT::Type::INT, s_type.type_of(:foo) 47 | assert_equal JIT::Type::FLOAT64, s_type.type_of(:bar) 48 | assert_equal JIT::Type::VOID_PTR, s_type.type_of(:baz) 49 | end 50 | 51 | def test_instance_bracket 52 | p = proc { |f| 53 | s_type = JIT::Struct.new( 54 | [ :foo, JIT::Type::INT ], 55 | [ :bar, JIT::Type::FLOAT64 ], 56 | [ :baz, JIT::Type::VOID_PTR ]) 57 | s = s_type.create(f) 58 | f.insn_store_relative(s.ptr, 4, f.const(JIT::Type::FLOAT64, 42.0)) 59 | f.return s[:bar] 60 | } 61 | assert_function_result( 62 | :result => [ JIT::Type::FLOAT64, 42.0 ], 63 | &p) 64 | end 65 | 66 | def test_instance_attrget 67 | p = proc { |f| 68 | s_type = JIT::Struct.new( 69 | [ :foo, JIT::Type::INT ], 70 | [ :bar, JIT::Type::FLOAT64 ], 71 | [ :baz, JIT::Type::VOID_PTR ]) 72 | s = s_type.create(f) 73 | f.insn_store_relative(s.ptr, 4, f.const(JIT::Type::FLOAT64, 42.0)) 74 | f.return s.bar 75 | } 76 | assert_function_result( 77 | :result => [ JIT::Type::FLOAT64, 42.0 ], 78 | &p) 79 | end 80 | 81 | def test_instance_bracket_eq 82 | p = proc { |f| 83 | s_type = JIT::Struct.new( 84 | [ :foo, JIT::Type::INT ], 85 | [ :bar, JIT::Type::FLOAT64 ], 86 | [ :baz, JIT::Type::VOID_PTR ]) 87 | s = s_type.create(f) 88 | s[:bar] = f.const(JIT::Type::FLOAT64, 42.0) 89 | f.return s[:bar] 90 | } 91 | assert_function_result( 92 | :result => [ JIT::Type::FLOAT64, 42.0 ], 93 | &p) 94 | end 95 | 96 | def test_instance_attrset 97 | p = proc { |f| 98 | s_type = JIT::Struct.new( 99 | [ :foo, JIT::Type::INT ], 100 | [ :bar, JIT::Type::FLOAT64 ], 101 | [ :baz, JIT::Type::VOID_PTR ]) 102 | s = s_type.create(f) 103 | s.bar = f.const(JIT::Type::FLOAT64, 42.0) 104 | f.return s.bar 105 | } 106 | assert_function_result( 107 | :result => [ JIT::Type::FLOAT64, 42.0 ], 108 | &p) 109 | end 110 | end 111 | 112 | -------------------------------------------------------------------------------- /m4/.gitignore: -------------------------------------------------------------------------------- 1 | *.m4 -------------------------------------------------------------------------------- /tests/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | TESTS = coerce.pas \ 3 | loop.pas \ 4 | math.pas \ 5 | param.pas \ 6 | cond.pas 7 | EXTRA_DIST = $(TESTS) 8 | TESTS_ENVIRONMENT = $(top_builddir)/dpas/dpas --dont-fold 9 | -------------------------------------------------------------------------------- /tests/README: -------------------------------------------------------------------------------- 1 | 2 | This directory contains test cases for libjit, written in the 3 | "Dynamic Pascal" language. To add a new test case, perform the 4 | following steps: 5 | 6 | 1. Create the "foo.pas" file, containing the source code for the 7 | test case. The test case should exit normally if it succeeds, 8 | or call "Terminate(1)" if it fails. 9 | 10 | 2. Add "foo.pas" to the "TESTS" list in "Makefile.am". 11 | 12 | 3. Re-run "auto_gen.sh" and "configure". 13 | 14 | 4. Type "make check" in this directory to run all of the test cases. 15 | 16 | Or you can run the test case manually with "../dpas/dpas foo.pas". 17 | The test case is compiled and executed in a single step, in a similar 18 | fashion to using a scripting language. 19 | 20 | The following two options to "dpas" can help with debugging problems 21 | in libjit: 22 | 23 | -d 24 | Dump the three-address form of each function as it is compiled. 25 | 26 | -D 27 | Dump the three-address and compiled forms of each function. 28 | 29 | If you are unfamiliar with the syntax of Pascal, or merely a little rusty, 30 | then the following EBNF grammar should help: 31 | 32 | http://www.cs.qub.ac.uk/~S.Fitzpatrick/Teaching/Pascal/EBNF.html 33 | 34 | You can also get copies of the Pascal standards at: 35 | 36 | http://www.pascal-central.com/ 37 | 38 | Dynamic Pascal is a subset of Standard Pascal, designed primarily for 39 | testing libjit. Patches are welcome to make it a more faithful Pascal 40 | implementation. 41 | 42 | Also see the file "dpas-builtin.c" for a list of builtin procedures and 43 | functions that you can use in your test cases. 44 | -------------------------------------------------------------------------------- /tests/loop.pas: -------------------------------------------------------------------------------- 1 | { Test code generation for long backwards branches in the x86 back end } 2 | { Evin Robertson } 3 | 4 | program loop; 5 | 6 | Procedure main; 7 | var g : ShortInt; 8 | begin 9 | for g := 0 to 10 do begin 10 | write('.'); write('.'); write('.'); write('.'); 11 | write('.'); write('.'); write('.'); write('.'); 12 | write('.'); write('.'); write('.'); write('.'); 13 | write('.'); write('.'); write('.'); write('.'); 14 | write('.'); write('.'); write('.'); write('.'); 15 | write('.'); write('.'); write('.'); write('.'); 16 | write('.'); write('.'); write('.'); write('.'); 17 | end; 18 | WriteLn(''); 19 | end; { main } 20 | 21 | begin 22 | main 23 | end. 24 | -------------------------------------------------------------------------------- /tools/.gitignore: -------------------------------------------------------------------------------- 1 | gen-apply 2 | gen-apply.exe 3 | gen-ops 4 | gen-ops.exe 5 | gen-rules 6 | gen-rules.exe 7 | gen-rules-parser.c 8 | gen-rules-parser.h 9 | gen-rules-scanner.c 10 | gen-ops-parser.c 11 | gen-ops-parser.h 12 | gen-ops-scanner.c 13 | jit-arch.h 14 | -------------------------------------------------------------------------------- /tools/Makefile.am: -------------------------------------------------------------------------------- 1 | ARCH_HEADER = jit-arch-@JIT_ARCH@.h 2 | 3 | BUILT_SOURCES = jit-arch.h 4 | 5 | noinst_PROGRAMS = gen-apply gen-rules gen-ops 6 | 7 | noinst_HEADERS = gen-apply-macosx.h 8 | 9 | dist_gen_apply_SOURCES = gen-apply.c 10 | 11 | nodist_gen_apply_SOURCES = jit-arch.h 12 | 13 | gen_rules_SOURCES = gen-rules-parser.y gen-rules-scanner.l 14 | 15 | gen_ops_SOURCES = gen-ops-scanner.l gen-ops-parser.y 16 | 17 | AM_YFLAGS = -d 18 | 19 | jit-arch.h: $(top_srcdir)/include/jit/$(ARCH_HEADER) 20 | rm -f $@ 21 | $(LN_S) $(top_srcdir)/include/jit/$(ARCH_HEADER) $@ 22 | 23 | gen-rules-scanner.l: gen-rules-parser.c 24 | 25 | gen-ops-scanner.l: gen-ops-parser.c 26 | 27 | all-local: $(top_builddir)/jit/jit-apply-rules.h 28 | 29 | $(top_builddir)/jit/jit-apply-rules.h: gen-apply$(EXEEXT) 30 | ./gen-apply >$@ 31 | 32 | AM_CFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include \ 33 | -I$(top_srcdir)/jit -I$(top_builddir)/jit 34 | 35 | CLEANFILES = $(top_builddir)/jit/jit-apply-rules.h jit-arch.h \ 36 | gen-rules-parser.c gen-rules-parser.h gen-rules-scanner.c \ 37 | gen-ops-parser.c gen-ops-parser.h gen-ops-scanner.c 38 | -------------------------------------------------------------------------------- /tools/gen-apply-macosx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * gen-apply-macosx.h - MacOSX-specific definitions. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _GEN_APPLY_MACOSX_H 24 | #define _GEN_APPLY_MACOSX_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | #define JIT_APPLY_NUM_WORD_REGS 8 31 | #define JIT_APPLY_NUM_FLOAT_REGS 13 32 | #define JIT_APPLY_PASS_STACK_FLOAT_AS_DOUBLE 0 33 | #define JIT_APPLY_PASS_STACK_FLOAT_AS_NFLOAT 0 34 | #define JIT_APPLY_PASS_STACK_DOUBLE_AS_NFLOAT 0 35 | #define JIT_APPLY_PASS_STACK_NFLOAT_AS_DOUBLE 1 36 | #define JIT_APPLY_PASS_REG_FLOAT_AS_DOUBLE 1 37 | #define JIT_APPLY_PASS_REG_FLOAT_AS_NFLOAT 0 38 | #define JIT_APPLY_PASS_REG_DOUBLE_AS_NFLOAT 0 39 | #define JIT_APPLY_PASS_REG_NFLOAT_AS_DOUBLE 1 40 | #define JIT_APPLY_RETURN_FLOAT_AS_DOUBLE 1 41 | #define JIT_APPLY_RETURN_FLOAT_AS_NFLOAT 0 42 | #define JIT_APPLY_RETURN_DOUBLE_AS_NFLOAT 0 43 | #define JIT_APPLY_RETURN_NFLOAT_AS_DOUBLE 1 44 | #define JIT_APPLY_FLOATS_IN_WORD_REGS 0 45 | #define JIT_APPLY_RETURN_FLOATS_AFTER 8 46 | #define JIT_APPLY_VARARGS_ON_STACK 0 47 | #define JIT_APPLY_STRUCT_RETURN_SPECIAL_REG 0 48 | #define JIT_APPLY_STRUCT_REG_OVERLAPS_WORD_REG 0 49 | #define JIT_APPLY_ALIGN_LONG_REGS 1 50 | #define JIT_APPLY_ALIGN_LONG_STACK 1 51 | #define JIT_APPLY_CAN_SPLIT_LONG 0 52 | #define JIT_APPLY_STRUCT_RETURN_IN_REG \ 53 | {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 54 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 55 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 56 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 57 | #define JIT_APPLY_MAX_STRUCT_IN_REG 0 58 | #define JIT_APPLY_X86_FASTCALL 0 59 | #define JIT_APPLY_PARENT_FRAME_OFFSET 0 60 | #define JIT_APPLY_RETURN_ADDRESS_OFFSET 0 61 | #define JIT_APPLY_BROKEN_FRAME_BUILTINS 1 62 | #define JIT_APPLY_X86_POP_STRUCT_RETURN 0 63 | #define JIT_APPLY_PAD_FLOAT_REGS 1 64 | 65 | #define JIT_APPLY_NUM_DOUBLE_REGS 0 66 | #define JIT_APPLY_NUM_NFLOAT_REGS 0 67 | #define JIT_APPLY_DOUBLES_IN_WORD_REGS 0 68 | #define JIT_APPLY_NFLOATS_IN_WORD_REGS 0 69 | #define JIT_APPLY_RETURN_DOUBLES_AFTER 0 70 | #define JIT_APPLY_RETURN_NFLOATS_AFTER 0 71 | 72 | #ifdef __cplusplus 73 | }; 74 | #endif 75 | 76 | #endif /* _GEN_APPLY_MACOSX_H */ 77 | -------------------------------------------------------------------------------- /tutorial/.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | t1 3 | t2 4 | t3 5 | t4 6 | t5 7 | -------------------------------------------------------------------------------- /tutorial/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | noinst_PROGRAMS = t1 t2 t3 t4 t5 3 | 4 | t1_SOURCES = t1.c 5 | t1_LDADD = $(top_builddir)/jit/libjit.la 6 | t1_DEPENDENCIES = $(top_builddir)/jit/libjit.la 7 | 8 | t2_SOURCES = t2.c 9 | t2_LDADD = $(top_builddir)/jit/libjit.la 10 | t2_DEPENDENCIES = $(top_builddir)/jit/libjit.la 11 | 12 | t3_SOURCES = t3.c 13 | t3_LDADD = $(top_builddir)/jit/libjit.la 14 | t3_DEPENDENCIES = $(top_builddir)/jit/libjit.la 15 | 16 | t4_SOURCES = t4.cpp 17 | t4_LDADD = $(top_builddir)/jitplus/libjitplus.la $(top_builddir)/jit/libjit.la 18 | t4_DEPENDENCIES = $(top_builddir)/jitplus/libjitplus.la \ 19 | $(top_builddir)/jit/libjit.la 20 | 21 | t5_SOURCES = t5.c 22 | t5_LDADD = $(top_builddir)/jit/libjit.la 23 | t5_DEPENDENCIES = $(top_builddir)/jit/libjit.la 24 | 25 | AM_CFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -I. -I$(srcdir) 26 | AM_CXXFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -I. -I$(srcdir) 27 | -------------------------------------------------------------------------------- /tutorial/README: -------------------------------------------------------------------------------- 1 | 2 | This directory contains the source code for the tutorial programs. 3 | The tutorials themselves can be found in "libjit/doc/libjit.texi". 4 | 5 | The source code for these tutorials is hereby placed into the public domain. 6 | You can do whatever you wish with the source, including cutting and pasting 7 | bits and pieces into your own program. 8 | 9 | However, libjit itself remains under the terms of the GNU Lesser General 10 | Public License, so you must still obey the terms of the LGPL when you link 11 | your program against libjit. 12 | -------------------------------------------------------------------------------- /tutorial/t1.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Tutorial 1 - mul_add 4 | 5 | Builds and compiles the following function: 6 | 7 | int mul_add(int x, int y, int z) 8 | { 9 | return x * y + z; 10 | } 11 | 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | int main(int argc, char **argv) 18 | { 19 | jit_context_t context; 20 | jit_type_t params[3]; 21 | jit_type_t signature; 22 | jit_function_t function; 23 | jit_value_t x, y, z; 24 | jit_value_t temp1, temp2; 25 | jit_int arg1, arg2, arg3; 26 | void *args[3]; 27 | jit_int result; 28 | 29 | /* Create a context to hold the JIT's primary state */ 30 | context = jit_context_create(); 31 | 32 | /* Lock the context while we build and compile the function */ 33 | jit_context_build_start(context); 34 | 35 | /* Build the function signature */ 36 | params[0] = jit_type_int; 37 | params[1] = jit_type_int; 38 | params[2] = jit_type_int; 39 | signature = jit_type_create_signature 40 | (jit_abi_cdecl, jit_type_int, params, 3, 1); 41 | 42 | /* Create the function object */ 43 | function = jit_function_create(context, signature); 44 | jit_type_free(signature); 45 | 46 | /* Construct the function body */ 47 | x = jit_value_get_param(function, 0); 48 | y = jit_value_get_param(function, 1); 49 | z = jit_value_get_param(function, 2); 50 | temp1 = jit_insn_mul(function, x, y); 51 | temp2 = jit_insn_add(function, temp1, z); 52 | jit_insn_return(function, temp2); 53 | 54 | /* Compile the function */ 55 | jit_function_compile(function); 56 | 57 | /* Unlock the context */ 58 | jit_context_build_end(context); 59 | 60 | /* Execute the function and print the result */ 61 | arg1 = 3; 62 | arg2 = 5; 63 | arg3 = 2; 64 | args[0] = &arg1; 65 | args[1] = &arg2; 66 | args[2] = &arg3; 67 | jit_function_apply(function, args, &result); 68 | printf("mul_add(3, 5, 2) = %d\n", (int)result); 69 | 70 | /* Clean up */ 71 | jit_context_destroy(context); 72 | 73 | /* Finished */ 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /tutorial/t2.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Tutorial 2 - gcd 4 | 5 | Builds and compiles the following function: 6 | 7 | unsigned int gcd(unsigned int x, unsigned int y) 8 | { 9 | if(x == y) 10 | { 11 | return x; 12 | } 13 | else if(x < y) 14 | { 15 | return gcd(x, y - x); 16 | } 17 | else 18 | { 19 | return gcd(x - y, y); 20 | } 21 | } 22 | 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | int main(int argc, char **argv) 29 | { 30 | jit_context_t context; 31 | jit_type_t params[2]; 32 | jit_type_t signature; 33 | jit_function_t function; 34 | jit_value_t x, y; 35 | jit_value_t temp1, temp2; 36 | jit_value_t temp3, temp4; 37 | jit_value_t temp_args[2]; 38 | jit_label_t label1 = jit_label_undefined; 39 | jit_label_t label2 = jit_label_undefined; 40 | jit_uint arg1, arg2; 41 | void *args[2]; 42 | jit_uint result; 43 | 44 | /* Create a context to hold the JIT's primary state */ 45 | context = jit_context_create(); 46 | 47 | /* Lock the context while we build and compile the function */ 48 | jit_context_build_start(context); 49 | 50 | /* Build the function signature */ 51 | params[0] = jit_type_uint; 52 | params[1] = jit_type_uint; 53 | signature = jit_type_create_signature 54 | (jit_abi_cdecl, jit_type_uint, params, 2, 1); 55 | 56 | /* Create the function object */ 57 | function = jit_function_create(context, signature); 58 | jit_type_free(signature); 59 | 60 | /* Check the condition "if(x == y)" */ 61 | x = jit_value_get_param(function, 0); 62 | y = jit_value_get_param(function, 1); 63 | temp1 = jit_insn_eq(function, x, y); 64 | jit_insn_branch_if_not(function, temp1, &label1); 65 | 66 | /* Implement "return x" */ 67 | jit_insn_return(function, x); 68 | 69 | /* Set "label1" at this position */ 70 | jit_insn_label(function, &label1); 71 | 72 | /* Check the condition "if(x < y)" */ 73 | temp2 = jit_insn_lt(function, x, y); 74 | jit_insn_branch_if_not(function, temp2, &label2); 75 | 76 | /* Implement "return gcd(x, y - x)" */ 77 | temp_args[0] = x; 78 | temp_args[1] = jit_insn_sub(function, y, x); 79 | temp3 = jit_insn_call 80 | (function, "gcd", function, 0, temp_args, 2, 0); 81 | jit_insn_return(function, temp3); 82 | 83 | /* Set "label2" at this position */ 84 | jit_insn_label(function, &label2); 85 | 86 | /* Implement "return gcd(x - y, y)" */ 87 | temp_args[0] = jit_insn_sub(function, x, y); 88 | temp_args[1] = y; 89 | temp4 = jit_insn_call 90 | (function, "gcd", function, 0, temp_args, 2, 0); 91 | jit_insn_return(function, temp4); 92 | 93 | /* Compile the function */ 94 | jit_function_compile(function); 95 | 96 | /* Unlock the context */ 97 | jit_context_build_end(context); 98 | 99 | /* Execute the function and print the result */ 100 | arg1 = 27; 101 | arg2 = 14; 102 | args[0] = &arg1; 103 | args[1] = &arg2; 104 | jit_function_apply(function, args, &result); 105 | printf("gcd(27, 14) = %u\n", (unsigned int)result); 106 | 107 | /* Clean up */ 108 | jit_context_destroy(context); 109 | 110 | /* Finished */ 111 | return 0; 112 | } 113 | -------------------------------------------------------------------------------- /tutorial/t3.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Tutorial 3 - compiling on-demand 4 | 5 | Builds and compiles the following function: 6 | 7 | int mul_add(int x, int y, int z) 8 | { 9 | return x * y + z; 10 | } 11 | 12 | Differs from Tutorial 1 in that this version only builds the function 13 | when it is called, not at startup time. 14 | 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | int compile_mul_add(jit_function_t function) 21 | { 22 | jit_value_t x, y, z; 23 | jit_value_t temp1, temp2; 24 | 25 | printf("Compiling mul_add on demand\n"); 26 | 27 | x = jit_value_get_param(function, 0); 28 | y = jit_value_get_param(function, 1); 29 | z = jit_value_get_param(function, 2); 30 | 31 | temp1 = jit_insn_mul(function, x, y); 32 | temp2 = jit_insn_add(function, temp1, z); 33 | 34 | jit_insn_return(function, temp2); 35 | return 1; 36 | } 37 | 38 | int main(int argc, char **argv) 39 | { 40 | jit_context_t context; 41 | jit_type_t params[3]; 42 | jit_type_t signature; 43 | jit_function_t function; 44 | jit_int arg1, arg2, arg3; 45 | void *args[3]; 46 | jit_int result; 47 | 48 | /* Create a context to hold the JIT's primary state */ 49 | context = jit_context_create(); 50 | 51 | /* Lock the context while we construct the function */ 52 | jit_context_build_start(context); 53 | 54 | /* Build the function signature */ 55 | params[0] = jit_type_int; 56 | params[1] = jit_type_int; 57 | params[2] = jit_type_int; 58 | signature = jit_type_create_signature 59 | (jit_abi_cdecl, jit_type_int, params, 3, 1); 60 | 61 | /* Create the function object */ 62 | function = jit_function_create(context, signature); 63 | jit_type_free(signature); 64 | 65 | /* Make the function recompilable */ 66 | jit_function_set_recompilable(function); 67 | 68 | /* Set the on-demand compiler for "mul_add" */ 69 | jit_function_set_on_demand_compiler(function, compile_mul_add); 70 | 71 | /* Unlock the context. It will be automatically locked for 72 | us when the on-demand compiler is called */ 73 | jit_context_build_end(context); 74 | 75 | /* Execute the function and print the result. This will arrange 76 | to call the on-demand compiler to build the function's body */ 77 | arg1 = 3; 78 | arg2 = 5; 79 | arg3 = 2; 80 | args[0] = &arg1; 81 | args[1] = &arg2; 82 | args[2] = &arg3; 83 | jit_function_apply(function, args, &result); 84 | printf("mul_add(3, 5, 2) = %d\n", (int)result); 85 | 86 | /* Execute the function again, to demonstrate that the 87 | on-demand compiler is not invoked a second time */ 88 | arg1 = 13; 89 | arg2 = 5; 90 | arg3 = 7; 91 | args[0] = &arg1; 92 | args[1] = &arg2; 93 | args[2] = &arg3; 94 | jit_function_apply(function, args, &result); 95 | printf("mul_add(13, 5, 7) = %d\n", (int)result); 96 | 97 | /* Force the function to be recompiled. Normally we'd use another 98 | on-demand compiler with greater optimization capabilities */ 99 | jit_context_build_start(context); 100 | jit_function_get_on_demand_compiler(function)(function); 101 | jit_function_compile(function); 102 | jit_context_build_end(context); 103 | 104 | /* Execute the function a third time, after it is recompiled */ 105 | arg1 = 2; 106 | arg2 = 18; 107 | arg3 = -3; 108 | args[0] = &arg1; 109 | args[1] = &arg2; 110 | args[2] = &arg3; 111 | jit_function_apply(function, args, &result); 112 | printf("mul_add(2, 18, -3) = %d\n", (int)result); 113 | 114 | /* Clean up */ 115 | jit_context_destroy(context); 116 | 117 | /* Finished */ 118 | return 0; 119 | } 120 | -------------------------------------------------------------------------------- /tutorial/t4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Tutorial 4 - mul_add, C++ version 4 | 5 | Builds and compiles the following function: 6 | 7 | int mul_add(int x, int y, int z) 8 | { 9 | return x * y + z; 10 | } 11 | 12 | Differs from Tutorial 3 in that this version is written in C++. 13 | 14 | */ 15 | 16 | #include 17 | #include 18 | 19 | class mul_add_function : public jit_function 20 | { 21 | public: 22 | mul_add_function(jit_context& context) : jit_function(context) 23 | { 24 | create(); 25 | set_recompilable(); 26 | } 27 | 28 | virtual void build(); 29 | 30 | protected: 31 | virtual jit_type_t create_signature(); 32 | }; 33 | 34 | jit_type_t mul_add_function::create_signature() 35 | { 36 | // Return type, followed by three parameters, terminated with "end_params". 37 | return signature_helper 38 | (jit_type_int, jit_type_int, jit_type_int, jit_type_int, end_params); 39 | } 40 | 41 | void mul_add_function::build() 42 | { 43 | printf("Compiling mul_add on demand\n"); 44 | 45 | jit_value x = get_param(0); 46 | jit_value y = get_param(1); 47 | jit_value z = get_param(2); 48 | 49 | insn_return(x * y + z); 50 | } 51 | 52 | int main(int argc, char **argv) 53 | { 54 | jit_int arg1, arg2, arg3; 55 | void *args[3]; 56 | jit_int result; 57 | 58 | // Create a context to hold the JIT's primary state. 59 | jit_context context; 60 | 61 | // Create the function object. 62 | mul_add_function mul_add(context); 63 | 64 | // Execute the function and print the result. This will arrange 65 | // to call "mul_add_function::build" to build the function's body. 66 | arg1 = 3; 67 | arg2 = 5; 68 | arg3 = 2; 69 | args[0] = &arg1; 70 | args[1] = &arg2; 71 | args[2] = &arg3; 72 | mul_add.apply(args, &result); 73 | printf("mul_add(3, 5, 2) = %d\n", (int)result); 74 | 75 | // Execute the function again, to demonstrate that the 76 | // on-demand compiler is not invoked a second time. 77 | arg1 = 13; 78 | arg2 = 5; 79 | arg3 = 7; 80 | args[0] = &arg1; 81 | args[1] = &arg2; 82 | args[2] = &arg3; 83 | mul_add.apply(args, &result); 84 | printf("mul_add(13, 5, 7) = %d\n", (int)result); 85 | 86 | // Force the function to be recompiled. 87 | mul_add.build_start(); 88 | mul_add.build(); 89 | mul_add.compile(); 90 | mul_add.build_end(); 91 | 92 | // Execute the function a third time, after it is recompiled. 93 | arg1 = 2; 94 | arg2 = 18; 95 | arg3 = -3; 96 | args[0] = &arg1; 97 | args[1] = &arg2; 98 | args[2] = &arg3; 99 | mul_add.apply(args, &result); 100 | printf("mul_add(2, 18, -3) = %d\n", (int)result); 101 | 102 | /* Finished */ 103 | return 0; 104 | } 105 | -------------------------------------------------------------------------------- /tutorial/t5.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Tutorial 5 - gcd, with tail call optimization 4 | 5 | Builds and compiles the following function: 6 | 7 | unsigned int gcd(unsigned int x, unsigned int y) 8 | { 9 | if(x == y) 10 | { 11 | return x; 12 | } 13 | else if(x < y) 14 | { 15 | return gcd(x, y - x); 16 | } 17 | else 18 | { 19 | return gcd(x - y, y); 20 | } 21 | } 22 | 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | int main(int argc, char **argv) 29 | { 30 | jit_context_t context; 31 | jit_type_t params[2]; 32 | jit_type_t signature; 33 | jit_function_t function; 34 | jit_value_t x, y; 35 | jit_value_t temp1, temp2; 36 | jit_value_t temp_args[2]; 37 | jit_label_t label1 = jit_label_undefined; 38 | jit_label_t label2 = jit_label_undefined; 39 | jit_uint arg1, arg2; 40 | void *args[2]; 41 | jit_uint result; 42 | 43 | /* Create a context to hold the JIT's primary state */ 44 | context = jit_context_create(); 45 | 46 | /* Lock the context while we build and compile the function */ 47 | jit_context_build_start(context); 48 | 49 | /* Build the function signature */ 50 | params[0] = jit_type_uint; 51 | params[1] = jit_type_uint; 52 | signature = jit_type_create_signature 53 | (jit_abi_cdecl, jit_type_uint, params, 2, 1); 54 | 55 | /* Create the function object */ 56 | function = jit_function_create(context, signature); 57 | jit_type_free(signature); 58 | 59 | /* Check the condition "if(x == y)" */ 60 | x = jit_value_get_param(function, 0); 61 | y = jit_value_get_param(function, 1); 62 | temp1 = jit_insn_eq(function, x, y); 63 | jit_insn_branch_if_not(function, temp1, &label1); 64 | 65 | /* Implement "return x" */ 66 | jit_insn_return(function, x); 67 | 68 | /* Set "label1" at this position */ 69 | jit_insn_label(function, &label1); 70 | 71 | /* Check the condition "if(x < y)" */ 72 | temp2 = jit_insn_lt(function, x, y); 73 | jit_insn_branch_if_not(function, temp2, &label2); 74 | 75 | /* Implement "return gcd(x, y - x)" */ 76 | temp_args[0] = x; 77 | temp_args[1] = jit_insn_sub(function, y, x); 78 | jit_insn_call(function, "gcd", function, 0, temp_args, 2, JIT_CALL_TAIL); 79 | 80 | /* Set "label2" at this position */ 81 | jit_insn_label(function, &label2); 82 | 83 | /* Implement "return gcd(x - y, y)" */ 84 | temp_args[0] = jit_insn_sub(function, x, y); 85 | temp_args[1] = y; 86 | jit_insn_call(function, "gcd", function, 0, temp_args, 2, JIT_CALL_TAIL); 87 | 88 | /* Compile the function */ 89 | jit_function_compile(function); 90 | 91 | /* Unlock the context */ 92 | jit_context_build_end(context); 93 | 94 | /* Execute the function and print the result */ 95 | arg1 = 27; 96 | arg2 = 14; 97 | args[0] = &arg1; 98 | args[1] = &arg2; 99 | jit_function_apply(function, args, &result); 100 | printf("gcd(27, 14) = %u\n", (unsigned int)result); 101 | 102 | /* Clean up */ 103 | jit_context_destroy(context); 104 | 105 | /* Finished */ 106 | return 0; 107 | } 108 | --------------------------------------------------------------------------------