vm.hpp 3.3 KB

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