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
19namespace 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
33 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
41 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
49 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
57 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
65 unsigned arity() const { return arity_; }
66 bool operator!() const { return fptr == 0; }
67
68 private:
69
70 friend class vmachine;
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
87 llvm::Module* module() const
88 {
89 return module_;
90 }
91
92 llvm::ExecutionEngine* execution_engine() const
93 {
94 return execution_engine_;
95 }
96
97 void print_assembler() const
98 {
99 module_->dump();
100 }
101
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

source code of boost/libs/spirit/example/qi/compiler_tutorial/conjure3/vm.hpp