1 /*============================================================================= 2 Copyright (c) 2001-2011 Joel de Guzman 3 4 Distributed under the Boost Software License, Version 1.0. (See accompanying 5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 =============================================================================*/ 7 #if !defined(BOOST_SPIRIT_CONJURE_VM_HPP) 8 #define BOOST_SPIRIT_CONJURE_VM_HPP 9 10 #include <llvm/ExecutionEngine/ExecutionEngine.h> 11 #include <llvm/ExecutionEngine/JIT.h> 12 #include <llvm/LLVMContext.h> 13 #include <llvm/Module.h> 14 #include <llvm/Target/TargetData.h> 15 #include <llvm/Target/TargetSelect.h> 16 17 #include <boost/assert.hpp> 18 19 namespace client 20 { 21 class vmachine; 22 23 /////////////////////////////////////////////////////////////////////////// 24 // A light wrapper to a function pointer returning int and accepting 25 // from 0 to 3 arguments, where arity is determined at runtime. 26 /////////////////////////////////////////////////////////////////////////// 27 class function 28 { 29 public: 30 31 typedef int result_type; 32 operator ()() const33 int operator()() const 34 { 35 BOOST_ASSERT(fptr != 0); 36 BOOST_ASSERT(arity() == 0); 37 int (*fp)() = (int(*)())(intptr_t)fptr; 38 return fp(); 39 } 40 operator ()(int _1) const41 int operator()(int _1) const 42 { 43 BOOST_ASSERT(fptr != 0); 44 BOOST_ASSERT(arity() == 1); 45 int (*fp)(int) = (int(*)(int))(intptr_t)fptr; 46 return fp(_1); 47 } 48 operator ()(int _1,int _2) const49 int operator()(int _1, int _2) const 50 { 51 BOOST_ASSERT(fptr != 0); 52 BOOST_ASSERT(arity() == 2); 53 int (*fp)(int, int) = (int(*)(int, int))(intptr_t)fptr; 54 return fp(_1, _2); 55 } 56 operator ()(int _1,int _2,int _3) const57 int operator()(int _1, int _2, int _3) const 58 { 59 BOOST_ASSERT(fptr != 0); 60 BOOST_ASSERT(arity() == 3); 61 int (*fp)(int, int, int) = (int(*)(int, int, int))(intptr_t)fptr; 62 return fp(_1, _2, _3); 63 } 64 arity() const65 unsigned arity() const { return arity_; } operator !() const66 bool operator!() const { return fptr == 0; } 67 68 private: 69 70 friend class vmachine; function(void * fptr,unsigned arity_)71 function(void* fptr, unsigned arity_) 72 : fptr(fptr), arity_(arity_) {} 73 74 void* fptr; 75 unsigned arity_; 76 }; 77 78 /////////////////////////////////////////////////////////////////////////// 79 // The Virtual Machine (light wrapper over LLVM JIT) 80 /////////////////////////////////////////////////////////////////////////// 81 class vmachine 82 { 83 public: 84 85 vmachine(); 86 module() const87 llvm::Module* module() const 88 { 89 return module_; 90 } 91 execution_engine() const92 llvm::ExecutionEngine* execution_engine() const 93 { 94 return execution_engine_; 95 } 96 print_assembler() const97 void print_assembler() const 98 { 99 module_->dump(); 100 } 101 get_function(char const * name)102 function get_function(char const* name) 103 { 104 llvm::Function* callee = module_->getFunction(name); 105 if (callee == 0) 106 return function(0, 0); 107 108 // JIT the function 109 void *fptr = execution_engine_->getPointerToFunction(callee); 110 return function(fptr, callee->arg_size()); 111 } 112 113 private: 114 115 llvm::Module* module_; 116 llvm::ExecutionEngine* execution_engine_; 117 }; 118 } 119 120 #endif 121 122