├── CMakeFiles └── modules │ ├── FindClang.cmake │ ├── FindLLVM.cmake │ └── FindLibDL.cmake ├── CMakeLists.txt ├── LICENSE.BSD ├── LICENSE.LLVM ├── README ├── include ├── CMakeLists.txt └── dcompile │ ├── common.hpp │ ├── context_holder.hpp │ ├── dcompile.hpp │ ├── dynamic_compiler.hpp │ ├── exceptions.hpp │ ├── function.hpp │ ├── header_path.hpp │ ├── linker.hpp │ ├── loader.hpp │ ├── mktemp.hpp │ ├── module.hpp │ ├── native_target.hpp │ └── object.hpp └── src ├── CMakeLists.txt ├── common.cpp ├── dcompile.cpp ├── dlambda.cpp ├── dynamic_compiler.cpp ├── function.cpp ├── loader.cpp ├── mktemp.cpp ├── module.cpp ├── object.cpp ├── resources ├── fuga.cpp ├── hoge.cpp └── test.cpp ├── sample1.cpp ├── sample2.cpp ├── sample3.cpp ├── sample4.cpp ├── sample5.cpp └── sample6.cpp /CMakeFiles/modules/FindClang.cmake: -------------------------------------------------------------------------------- 1 | # Detect CLANG 2 | if (NOT LLVM_INCLUDE_DIR OR NOT LLVM_LIB_DIR) 3 | message(FATAL_ERROR "No LLVM and Clang support requires LLVM") 4 | else (NOT LLVM_INCLUDE_DIR OR NOT LLVM_LIB_DIR) 5 | 6 | MACRO(FIND_AND_ADD_CLANG_LIB _libname_) 7 | find_library(CLANG_${_libname_}_LIB ${_libname_} ${LLVM_LIB_DIR} ${CLANG_LIB_DIR}) 8 | if (CLANG_${_libname_}_LIB) 9 | set(CLANG_LIBS ${CLANG_LIBS} ${_libname_} ) 10 | endif(CLANG_${_libname_}_LIB) 11 | ENDMACRO(FIND_AND_ADD_CLANG_LIB) 12 | 13 | set(CLANG_INCLUDE_DIRS ${CLANG_INCLUDE_DIRS} ${LLVM_INCLUDE_DIR}) 14 | set(CLANG_INCLUDE_DIRS ${CLANG_INCLUDE_DIRS} ${CLANG_INCLUDE_DIR}) 15 | 16 | #FIND_AND_ADD_CLANG_LIB(clang) 17 | FIND_AND_ADD_CLANG_LIB(clangARCMigrate) 18 | FIND_AND_ADD_CLANG_LIB(clangASTMatchers) 19 | FIND_AND_ADD_CLANG_LIB(clangAnalysis) 20 | FIND_AND_ADD_CLANG_LIB(clangAST) 21 | FIND_AND_ADD_CLANG_LIB(clangBasic) 22 | FIND_AND_ADD_CLANG_LIB(clangCodeGen) 23 | FIND_AND_ADD_CLANG_LIB(clangDriver) 24 | FIND_AND_ADD_CLANG_LIB(clangEdit) 25 | FIND_AND_ADD_CLANG_LIB(clangFrontend) 26 | FIND_AND_ADD_CLANG_LIB(clangFrontendTool) 27 | #FIND_AND_ADD_CLANG_LIB(clangIndex) 28 | FIND_AND_ADD_CLANG_LIB(clangLex) 29 | FIND_AND_ADD_CLANG_LIB(clangParse) 30 | FIND_AND_ADD_CLANG_LIB(clangRewrite) 31 | FIND_AND_ADD_CLANG_LIB(clangSema) 32 | FIND_AND_ADD_CLANG_LIB(clangSerialization) 33 | FIND_AND_ADD_CLANG_LIB(clangStaticAnalyzerCheckers) 34 | FIND_AND_ADD_CLANG_LIB(clangStaticAnalyzerCore) 35 | FIND_AND_ADD_CLANG_LIB(clangStaticAnalyzerFrontend) 36 | FIND_AND_ADD_CLANG_LIB(clangTooling) 37 | 38 | MESSAGE(STATUS "Clang libs: " ${CLANG_LIBS}) 39 | 40 | if(CLANG_LIBS) 41 | set(CLANG_FOUND TRUE) 42 | endif(CLANG_LIBS) 43 | 44 | if(CLANG_FOUND) 45 | message(STATUS "Found Clang: ${CLANG_INCLUDE_DIRS}") 46 | else(CLANG_FOUND) 47 | if(CLANG_FIND_REQUIRED) 48 | message(FATAL_ERROR "Could NOT find Clang") 49 | endif(CLANG_FIND_REQUIRED) 50 | endif(CLANG_FOUND) 51 | 52 | endif (NOT LLVM_INCLUDE_DIR OR NOT LLVM_LIB_DIR) 53 | -------------------------------------------------------------------------------- /CMakeFiles/modules/FindLLVM.cmake: -------------------------------------------------------------------------------- 1 | # Detect LLVM and set various variable to link against the different component of LLVM 2 | # 3 | # NOTE: This is a modified version of the module originally found in the OpenGTL project 4 | # at www.opengtl.org 5 | # 6 | # LLVM_BIN_DIR : directory with LLVM binaries 7 | # LLVM_LIB_DIR : directory with LLVM library 8 | # LLVM_INCLUDE_DIR : directory with LLVM include 9 | # 10 | # LLVM_COMPILE_FLAGS : compile flags needed to build a program using LLVM headers 11 | # LLVM_LDFLAGS : ldflags needed to link 12 | # LLVM_LIBS : ldflags needed to link against a LLVM library 13 | 14 | if (LLVM_INCLUDE_DIR) 15 | set(LLVM_FOUND TRUE) 16 | else (LLVM_INCLUDE_DIR) 17 | 18 | find_program(LLVM_CONFIG_EXECUTABLE 19 | NAMES llvm-config 20 | PATHS 21 | /opt/local/bin 22 | ) 23 | 24 | MACRO(FIND_LLVM_LIBS LLVM_CONFIG_EXECUTABLE _libname_ LIB_VAR OBJECT_VAR) 25 | exec_program( ${LLVM_CONFIG_EXECUTABLE} ARGS --libs ${_libname_} OUTPUT_VARIABLE ${LIB_VAR} ) 26 | STRING(REGEX MATCHALL "[^ ]*[.]o[ $]" ${OBJECT_VAR} ${${LIB_VAR}}) 27 | SEPARATE_ARGUMENTS(${OBJECT_VAR}) 28 | STRING(REGEX REPLACE "[^ ]*[.]o[ $]" "" ${LIB_VAR} ${${LIB_VAR}}) 29 | ENDMACRO(FIND_LLVM_LIBS) 30 | 31 | 32 | exec_program(${LLVM_CONFIG_EXECUTABLE} ARGS --bindir OUTPUT_VARIABLE LLVM_BIN_DIR ) 33 | exec_program(${LLVM_CONFIG_EXECUTABLE} ARGS --libdir OUTPUT_VARIABLE LLVM_LIB_DIR ) 34 | #MESSAGE(STATUS "LLVM lib dir: " ${LLVM_LIB_DIR}) 35 | exec_program(${LLVM_CONFIG_EXECUTABLE} ARGS --includedir OUTPUT_VARIABLE LLVM_INCLUDE_DIR ) 36 | 37 | 38 | exec_program(${LLVM_CONFIG_EXECUTABLE} ARGS --cppflags OUTPUT_VARIABLE LLVM_COMPILE_FLAGS ) 39 | MESSAGE(STATUS "LLVM CXX flags: " ${LLVM_COMPILE_FLAGS}) 40 | exec_program(${LLVM_CONFIG_EXECUTABLE} ARGS --ldflags OUTPUT_VARIABLE LLVM_LDFLAGS ) 41 | MESSAGE(STATUS "LLVM LD flags: " ${LLVM_LDFLAGS}) 42 | exec_program(${LLVM_CONFIG_EXECUTABLE} ARGS --libs asmparser asmprinter bitreader bitwriter executionengine jit mcjit native nativecodegen codegen ipo core linker instrumentation OUTPUT_VARIABLE LLVM_LIBS ) 43 | MESSAGE(STATUS "LLVM libs: " ${LLVM_LIBS}) 44 | 45 | if(LLVM_INCLUDE_DIR) 46 | set(LLVM_FOUND TRUE) 47 | endif(LLVM_INCLUDE_DIR) 48 | 49 | if(LLVM_FOUND) 50 | message(STATUS "Found LLVM: ${LLVM_INCLUDE_DIR}") 51 | else(LLVM_FOUND) 52 | if(LLVM_FIND_REQUIRED) 53 | message(FATAL_ERROR "Could NOT find LLVM") 54 | endif(LLVM_FIND_REQUIRED) 55 | endif(LLVM_FOUND) 56 | 57 | endif (LLVM_INCLUDE_DIR) 58 | -------------------------------------------------------------------------------- /CMakeFiles/modules/FindLibDL.cmake: -------------------------------------------------------------------------------- 1 | # - Find libdl 2 | # Find the native LIBDL includes and library 3 | # 4 | # LIBDL_INCLUDE_DIR - where to find dlfcn.h, etc. 5 | # LIBDL_LIBRARIES - List of libraries when using libdl. 6 | # LIBDL_FOUND - True if libdl found. 7 | 8 | 9 | IF (LIBDL_INCLUDE_DIR) 10 | # Already in cache, be silent 11 | SET(LIBDL_FIND_QUIETLY TRUE) 12 | ENDIF (LIBDL_INCLUDE_DIR) 13 | 14 | FIND_PATH(LIBDL_INCLUDE_DIR dlfcn.h) 15 | 16 | SET(LIBDL_NAMES dl libdl ltdl libltdl) 17 | FIND_LIBRARY(LIBDL_LIBRARY NAMES ${LIBDL_NAMES} ) 18 | 19 | # handle the QUIETLY and REQUIRED arguments and set LIBDL_FOUND to TRUE if 20 | # all listed variables are TRUE 21 | INCLUDE(FindPackageHandleStandardArgs) 22 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibDL DEFAULT_MSG LIBDL_LIBRARY LIBDL_INCLUDE_DIR) 23 | 24 | IF(LIBDL_FOUND) 25 | SET( LIBDL_LIBRARIES ${LIBDL_LIBRARY} ) 26 | ELSE(LIBDL_FOUND) 27 | SET( LIBDL_LIBRARIES ) 28 | ENDIF(LIBDL_FOUND) 29 | 30 | MARK_AS_ADVANCED( LIBDL_LIBRARY LIBDL_INCLUDE_DIR ) 31 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/CMakeFiles/modules/") 3 | 4 | PROJECT(dcompile) 5 | 6 | INCLUDE (CheckIncludeFiles) 7 | include (FindPkgConfig) 8 | 9 | # build type 10 | set(CMAKE_BUILD_TYPE Debug) 11 | 12 | # compile option (Debug) 13 | set(CMAKE_CXX_FLAGS_DEBUG "-g") 14 | set(CMAKE_C_FLAGS_DEBUG "-g") 15 | 16 | # compile option (Release) 17 | set(CMAKE_CXX_FLAGS_RELEASE "-W -Wall -O3") 18 | set(CMAKE_C_FLAGS_RELEASE "-W -Wall -O3") 19 | 20 | #if you don't want the full compiler output, remove the following line 21 | set(CMAKE_VERBOSE_MAKEFILE ON) 22 | 23 | set(Boost_USE_MULTITHREADED ON) 24 | find_package(Boost 1.42.0 COMPONENTS thread filesystem system REQUIRED ) 25 | if (NOT Boost_FOUND) 26 | message(SEND_ERROR "Boost not found - skipping building tests") 27 | endif (NOT Boost_FOUND) 28 | 29 | find_package(LLVM REQUIRED ) 30 | if (NOT LLVM_FOUND) 31 | message(SEND_ERROR "LLVM not found - skipping building tests") 32 | endif (NOT LLVM_FOUND) 33 | 34 | find_package(Clang REQUIRED ) 35 | if (NOT CLANG_FOUND) 36 | message(SEND_ERROR "Clang not found - skipping building tests") 37 | endif (NOT CLANG_FOUND) 38 | 39 | find_package(LibDL REQUIRED ) 40 | if (NOT LIBDL_FOUND) 41 | message(SEND_ERROR "libdl not found - skipping building tests") 42 | endif (NOT LIBDL_FOUND) 43 | 44 | INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}/include ${Boost_INCLUDE_DIRS} ${LLVM_INCLUDE_DIR} ${CLANG_INCLUDE_DIR} ${LIBDL_INCLUDE_DIR} ) 45 | LINK_DIRECTORIES( ${LLVM_LIB_DIR} ) 46 | SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LLVM_COMPILE_FLAGS}" ) 47 | SET( CMAKE_LD_FLAGS "${CMAKE_LD_FLAGS} ${LLVM_LIBS} -Wl,-E" ) 48 | subdirs( include src ) 49 | -------------------------------------------------------------------------------- /LICENSE.BSD: -------------------------------------------------------------------------------- 1 | Copyright (C) 2012, Naomasa Matsubayashi 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions 6 | are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /LICENSE.LLVM: -------------------------------------------------------------------------------- 1 | ============================================================================== 2 | LLVM Release License 3 | ============================================================================== 4 | University of Illinois/NCSA 5 | Open Source License 6 | 7 | Copyright (c) 2003-2011 University of Illinois at Urbana-Champaign. 8 | All rights reserved. 9 | 10 | Developed by: 11 | 12 | LLVM Team 13 | 14 | University of Illinois at Urbana-Champaign 15 | 16 | http://llvm.org 17 | 18 | Permission is hereby granted, free of charge, to any person obtaining a copy of 19 | this software and associated documentation files (the "Software"), to deal with 20 | the Software without restriction, including without limitation the rights to 21 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 22 | of the Software, and to permit persons to whom the Software is furnished to do 23 | so, subject to the following conditions: 24 | 25 | * Redistributions of source code must retain the above copyright notice, 26 | this list of conditions and the following disclaimers. 27 | 28 | * Redistributions in binary form must reproduce the above copyright notice, 29 | this list of conditions and the following disclaimers in the 30 | documentation and/or other materials provided with the distribution. 31 | 32 | * Neither the names of the LLVM Team, University of Illinois at 33 | Urbana-Champaign, nor the names of its contributors may be used to 34 | endorse or promote products derived from this Software without specific 35 | prior written permission. 36 | 37 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 38 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 39 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 40 | CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 41 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 42 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE 43 | SOFTWARE. 44 | 45 | ============================================================================== 46 | Copyrights and Licenses for Third Party Software Distributed with LLVM: 47 | ============================================================================== 48 | The LLVM software contains code written by third parties. Such software will 49 | have its own individual LICENSE.TXT file in the directory in which it appears. 50 | This file will describe the copyrights, license, and restrictions which apply 51 | to that code. 52 | 53 | The disclaimer of warranty in the University of Illinois Open Source License 54 | applies to all code in the LLVM Distribution, and nothing in any of the 55 | other licenses gives permission to use the names of the LLVM Team or the 56 | University of Illinois to endorse or promote products derived from this 57 | Software. 58 | 59 | The following pieces of software have additional or alternate copyrights, 60 | licenses, and/or restrictions: 61 | 62 | Program Directory 63 | ------- --------- 64 | Autoconf llvm/autoconf 65 | llvm/projects/ModuleMaker/autoconf 66 | llvm/projects/sample/autoconf 67 | CellSPU backend llvm/lib/Target/CellSPU/README.txt 68 | Google Test llvm/utils/unittest/googletest 69 | OpenBSD regex llvm/lib/Support/{reg*, COPYRIGHT.regex} 70 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | libdcompile is a C++ library to compile and execute C++ code in runtime. 2 | 3 | Requirements 4 | LLVM 3.1 ( http://llvm.org/ ) compiled with Clang ( http://clang.llvm.org/ ) 5 | libjpeg ( http://www.ijg.org/ ) ( only used in sample program ) 6 | 7 | Installation 8 | $ git clone git://github.com/Fadis/libdcompile.git 9 | $ mkdir build 10 | $ cd build 11 | $ cmake ../libdcompile -DCMAKE_INSTALL_PREFIX= 12 | $ make 13 | $ make insetll 14 | 15 | Known Issue 16 | System include path doesn't work on Linux 17 | -------------------------------------------------------------------------------- /include/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | INSTALL( DIRECTORY dcompile/ 2 | DESTINATION include/dcompile/ 3 | FILES_MATCHING PATTERN "*.hpp" ) 4 | -------------------------------------------------------------------------------- /include/dcompile/common.hpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #ifndef DCOMPILE_COMMON_HPP 29 | #define DCOMPILE_COMMON_HPP 30 | 31 | namespace dcompile { 32 | enum OptimizeLevel { 33 | None, 34 | Less, 35 | Default, 36 | Aggressive 37 | }; 38 | enum Language { 39 | CXX, 40 | ObjC, 41 | C, 42 | CUDA, 43 | OpenCL 44 | }; 45 | const char *getFileSuffix( Language lang ); 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /include/dcompile/context_holder.hpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #ifndef DCOMPILE_CONTEXT_HOLDER_HPP 29 | #define DCOMPILE_CONTEXT_HOLDER_HPP 30 | 31 | #include 32 | 33 | #include 34 | 35 | namespace dcompile { 36 | class context_holder { 37 | public: 38 | context_holder() : llvm_context( new llvm::LLVMContext ) { 39 | } 40 | context_holder( const boost::shared_ptr< llvm::LLVMContext > &context ) : llvm_context( context ) { 41 | } 42 | const boost::shared_ptr< llvm::LLVMContext > &getContext() const { 43 | return llvm_context; 44 | } 45 | private: 46 | boost::shared_ptr< llvm::LLVMContext > llvm_context; 47 | }; 48 | } 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /include/dcompile/dcompile.hpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #ifndef DCOMPILE_DCOMPILE_HPP 29 | #define DCOMPILE_DCOMPILE_HPP 30 | 31 | #include 32 | #include 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /include/dcompile/dynamic_compiler.hpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #ifndef DCOMPILE_DYNAMIC_COMPILER_HPP 29 | #define DCOMPILE_DYNAMIC_COMPILER_HPP 30 | 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | 53 | namespace dcompile { 54 | /* class result { 55 | public: 56 | result( unsigned int _errs, unsigned int _warns, const std::string &_ ) 57 | }*/ 58 | 59 | class dynamic_compiler : public context_holder { 60 | public: 61 | dynamic_compiler(); 62 | dynamic_compiler( const boost::filesystem::path &resource ); 63 | void setOptimizeLevel( OptimizeLevel new_level ); 64 | OptimizeLevel getOptimizeLevel() const; 65 | loader &getLoader() { 66 | return library_loader; 67 | } 68 | const loader &getLoader() const { 69 | return library_loader; 70 | } 71 | header_path &getHeaderPath() { 72 | return header; 73 | } 74 | const header_path &getHeaderPath() const { 75 | return header; 76 | } 77 | module operator()( const std::string &source_code, Language lang ) const; 78 | object getObject( const std::string &source_code, Language lang ) const; 79 | std::string dumpLLVM( const std::string &source_code, Language lang ) const; 80 | std::string dumpAsm( const std::string &source_code, Language lang ) const; 81 | module operator()( const boost::filesystem::path &path ) const; 82 | object getObject( const boost::filesystem::path &path ) const; 83 | std::string dumpLLVM( const boost::filesystem::path &path ) const; 84 | std::string dumpAsm( const boost::filesystem::path &path ) const; 85 | void compileEachSource( boost::shared_ptr< TemporaryFile > &bc, const boost::filesystem::path &src ) const; 86 | template< typename Iterator > 87 | module operator()( Iterator begin, Iterator end, 88 | typename boost::enable_if< boost::is_same< typename boost::remove_cv< typename boost::iterator_value< Iterator >::type >::type, boost::filesystem::path > >::type* = 0 89 | ) const { 90 | native_target::init(); 91 | std::vector< boost::shared_ptr< TemporaryFile > > bc_file_names( std::distance( begin, end ) ); 92 | typename std::vector< boost::shared_ptr< TemporaryFile > >::iterator bc_iter; 93 | Iterator src_iter; 94 | for( src_iter = begin, bc_iter = bc_file_names.begin(); src_iter != end, bc_iter != bc_file_names.end(); ++src_iter, ++bc_iter ) { 95 | compileEachSource( *bc_iter, *src_iter ); 96 | } 97 | llvm::Linker linker( "linker", "composite", *getContext().get(), 0 ); 98 | for( bc_iter = bc_file_names.begin(); bc_iter != bc_file_names.end(); ++bc_iter ) { 99 | llvm::sys::Path bc_path; 100 | bc_path.set( (*bc_iter)->getPath().c_str() ); 101 | bool is_native; 102 | linker.LinkInFile( bc_path, is_native ); 103 | } 104 | return module( getContext(), optlevel, linker.releaseModule() ); 105 | } 106 | template< typename Iterator > 107 | object getObject( Iterator begin, Iterator end, 108 | typename boost::enable_if< boost::is_same< typename boost::remove_cv< typename boost::iterator_value< Iterator >::type >::type, boost::filesystem::path > >::type* = 0 109 | ) const { 110 | std::vector< boost::shared_ptr< TemporaryFile > > bc_file_names( std::distance( begin, end ) ); 111 | typename std::vector< boost::shared_ptr< TemporaryFile > >::iterator bc_iter; 112 | Iterator src_iter; 113 | for( src_iter = begin, bc_iter = bc_file_names.begin(); src_iter != end, bc_iter != bc_file_names.end(); ++src_iter, ++bc_iter ) { 114 | compileEachSource( *bc_iter, *src_iter ); 115 | } 116 | llvm::Linker linker( "linker", "composite", *getContext().get(), 0 ); 117 | for( bc_iter = bc_file_names.begin(); bc_iter != bc_file_names.end(); ++bc_iter ) { 118 | llvm::sys::Path bc_path; 119 | bc_path.set( (*bc_iter)->getPath().c_str() ); 120 | bool is_native; 121 | linker.LinkInFile( bc_path, is_native ); 122 | } 123 | return object( getContext(), optlevel, linker.releaseModule() ); 124 | } 125 | private: 126 | void buildArguments( std::vector< std::string > &arguments ) const; 127 | void buildArguments( std::vector< std::string > &arguments, const boost::filesystem::path &_from, const boost::filesystem::path &_to ) const; 128 | void setupCompiler( clang::CompilerInstance &compiler, const std::vector< std::string > &arguments ) const; 129 | void setupCompiler( clang::CompilerInstance &compiler, const boost::filesystem::path &_from, const boost::filesystem::path &_to ) const; 130 | bool begin( clang::CompilerInstance &compiler, clang::FrontendAction &action, const clang::FrontendInputFile &file ) const; 131 | void execute( clang::CompilerInstance &compiler, clang::FrontendAction &action ) const; 132 | module getModule( clang::CompilerInstance &compiler, TemporaryFile &bc_file_name ) const; 133 | object getObject( clang::CompilerInstance &compiler, TemporaryFile &bc_file_name ) const; 134 | const boost::filesystem::path resource_directory; 135 | header_path header; 136 | loader library_loader; 137 | OptimizeLevel optlevel; 138 | boost::shared_ptr< llvm::LLVMContext > llvm_context; 139 | }; 140 | } 141 | 142 | #endif 143 | -------------------------------------------------------------------------------- /include/dcompile/exceptions.hpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #ifndef DCOMPILE_EXCEPTIONS_HPP 29 | #define DCOMPILE_EXCEPTIONS_HPP 30 | 31 | namespace dcompile { 32 | class UnableToLoadModule {}; 33 | class UnknownOptimizeLevel {}; 34 | class InvalidArgument {}; 35 | class UnableToCreateUniqueFile {}; 36 | class UnsupportedLanguage {}; 37 | class LinkFailed {}; 38 | } 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /include/dcompile/function.hpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #ifndef DCOMPILE_FUNCTION_HPP 29 | #define DCOMPILE_FUNCTION_HPP 30 | 31 | #include 32 | #include 33 | 34 | #include 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | 53 | namespace dcompile { 54 | template< typename Type > 55 | void setParam( llvm::GenericValue &_dest, Type value, 56 | typename boost::enable_if< boost::mpl::bool_< 57 | boost::is_pod< Type >::value && 58 | boost::is_pointer< Type >::value && 59 | !boost::is_const< typename boost::remove_pointer< Type >::type >::value 60 | > >::type* = 0 ) { 61 | _dest.PointerVal = static_cast< void* >( value ); 62 | } 63 | template< typename Type > 64 | void setParam( llvm::GenericValue &_dest, Type value, 65 | typename boost::enable_if< boost::mpl::bool_< 66 | boost::is_pod< Type >::value && 67 | boost::is_pointer< Type >::value && 68 | boost::is_const< typename boost::remove_pointer< Type >::type >::value 69 | > >::type* = 0 ) { 70 | _dest.PointerVal = static_cast< void* >( const_cast< typename boost::remove_const< typename boost::remove_pointer< Type >::type >::type* >( value ) ); 71 | } 72 | template< typename Type > 73 | void setParam( llvm::GenericValue &_dest, Type value, 74 | typename boost::enable_if< boost::mpl::bool_< 75 | boost::is_pod< Type >::value && 76 | !boost::is_pointer< Type >::value && 77 | boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, float >::value 78 | > >::type* = 0 ) { 79 | _dest.FloatVal = value; 80 | } 81 | template< typename Type > 82 | void setParam( llvm::GenericValue &_dest, Type value, 83 | typename boost::enable_if< boost::mpl::bool_< 84 | boost::is_pod< Type >::value && 85 | !boost::is_pointer< Type >::value && 86 | boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, double >::value 87 | > >::type* = 0 ) { 88 | _dest.DoubleVal = value; 89 | } 90 | template< typename Type > 91 | void setParam( llvm::GenericValue &_dest, Type value, 92 | typename boost::enable_if< boost::mpl::bool_< 93 | boost::is_pod< Type >::value && 94 | !boost::is_pointer< Type >::value && 95 | boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, signed char >::value 96 | > >::type* = 0 ) { 97 | _dest.IntVal = llvm::APInt( sizeof( signed char ) * 8, static_cast< uint64_t >( value ), true ); 98 | } 99 | template< typename Type > 100 | void setParam( llvm::GenericValue &_dest, Type value, 101 | typename boost::enable_if< boost::mpl::bool_< 102 | boost::is_pod< Type >::value && 103 | !boost::is_pointer< Type >::value && 104 | boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, unsigned char >::value 105 | > >::type* = 0 ) { 106 | _dest.IntVal = llvm::APInt( sizeof( unsigned char ) * 8, static_cast< uint64_t >( value ), false ); 107 | } 108 | template< typename Type > 109 | void setParam( llvm::GenericValue &_dest, Type value, 110 | typename boost::enable_if< boost::mpl::bool_< 111 | boost::is_pod< Type >::value && 112 | !boost::is_pointer< Type >::value && 113 | boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, signed short >::value 114 | > >::type* = 0 ) { 115 | _dest.IntVal = llvm::APInt( sizeof( signed short ) * 8, static_cast< uint64_t >( value ), true ); 116 | } 117 | template< typename Type > 118 | void setParam( llvm::GenericValue &_dest, Type value, 119 | typename boost::enable_if< boost::mpl::bool_< 120 | boost::is_pod< Type >::value && 121 | !boost::is_pointer< Type >::value && 122 | boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, unsigned short >::value 123 | > >::type* = 0 ) { 124 | _dest.IntVal = llvm::APInt( sizeof( unsigned short ) * 8, static_cast< uint64_t >( value ), false ); 125 | } 126 | template< typename Type > 127 | void setParam( llvm::GenericValue &_dest, Type value, 128 | typename boost::enable_if< boost::mpl::bool_< 129 | boost::is_pod< Type >::value && 130 | !boost::is_pointer< Type >::value && 131 | boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, signed int >::value 132 | > >::type* = 0 ) { 133 | _dest.IntVal = llvm::APInt( sizeof( signed int ) * 8, static_cast< uint64_t >( value ), true ); 134 | } 135 | template< typename Type > 136 | void setParam( llvm::GenericValue &_dest, Type value, 137 | typename boost::enable_if< boost::mpl::bool_< 138 | boost::is_pod< Type >::value && 139 | !boost::is_pointer< Type >::value && 140 | boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, unsigned int >::value 141 | > >::type* = 0 ) { 142 | _dest.IntVal = llvm::APInt( sizeof( unsigned int ) * 8, static_cast< uint64_t >( value ), false ); 143 | } 144 | template< typename Type > 145 | void setParam( llvm::GenericValue &_dest, Type value, 146 | typename boost::enable_if< boost::mpl::bool_< 147 | boost::is_pod< Type >::value && 148 | !boost::is_pointer< Type >::value && 149 | boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, signed long >::value 150 | > >::type* = 0 ) { 151 | _dest.IntVal = llvm::APInt( sizeof( signed long ) * 8, static_cast< uint64_t >( value ), true ); 152 | } 153 | template< typename Type > 154 | void setParam( llvm::GenericValue &_dest, Type value, 155 | typename boost::enable_if< boost::mpl::bool_< 156 | boost::is_pod< Type >::value && 157 | !boost::is_pointer< Type >::value && 158 | boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, unsigned long >::value 159 | > >::type* = 0 ) { 160 | _dest.IntVal = llvm::APInt( sizeof( unsigned long ) * 8, static_cast< uint64_t >( value ), false ); 161 | } 162 | template< typename Type > 163 | void setParam( llvm::GenericValue &_dest, Type value, 164 | typename boost::enable_if< boost::mpl::bool_< 165 | boost::is_pod< Type >::value && 166 | !boost::is_pointer< Type >::value && 167 | boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, signed long long >::value 168 | > >::type* = 0 ) { 169 | _dest.IntVal = llvm::APInt( sizeof( signed long long ) * 8, static_cast< uint64_t >( value ), true ); 170 | } 171 | template< typename Type > 172 | void setParam( llvm::GenericValue &_dest, Type value, 173 | typename boost::enable_if< boost::mpl::bool_< 174 | boost::is_pod< Type >::value && 175 | !boost::is_pointer< Type >::value && 176 | boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, unsigned long long >::value 177 | > >::type* = 0 ) { 178 | _dest.IntVal = llvm::APInt( sizeof( unsigned long long ) * 8, static_cast< uint64_t >( value ), false ); 179 | } 180 | template< typename Type > 181 | void setParam( llvm::GenericValue &_dest, Type value, 182 | typename boost::enable_if< boost::mpl::bool_< 183 | boost::is_pod< Type >::value && 184 | !boost::is_pointer< Type >::value && 185 | !boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, float >::value && 186 | !boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, double >::value && 187 | !boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, signed char >::value && 188 | !boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, unsigned char >::value && 189 | !boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, signed short >::value && 190 | !boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, unsigned short >::value && 191 | !boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, signed int >::value && 192 | !boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, unsigned int >::value && 193 | !boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, signed long >::value && 194 | !boost::is_same< typename boost::remove_cv< typename boost::remove_reference< Type >::type >::type, unsigned long >::value 195 | > >::type* = 0 ) { 196 | if( sizeof( Type ) <= 8 ) 197 | *static_cast< Type* >( static_cast< void* >( _dest.Untyped ) ) = value; 198 | else 199 | throw InvalidArgument(); 200 | } 201 | enum { 202 | SIGNED_CHAR = 0, 203 | UNSIGNED_CHAR, 204 | SIGNED_SHORT, 205 | UNSIGNED_SHORT, 206 | SIGNED_INT, 207 | UNSIGNED_INT, 208 | SIGNED_LONG, 209 | UNSIGNED_LONG, 210 | SIGNED_LONG_LONG, 211 | UNSIGNED_LONG_LONG, 212 | SIGNED_FLOAT, 213 | UNSIGNED_DOUBLE, 214 | UNSIGNED_POINTER 215 | }; 216 | typedef boost::variant< 217 | signed char, 218 | unsigned char, 219 | signed short, 220 | unsigned short, 221 | signed int, 222 | unsigned int, 223 | signed long, 224 | unsigned long, 225 | signed long long, 226 | unsigned long long, 227 | float, 228 | double, 229 | void* 230 | > return_value; 231 | return_value getReturnValue( const llvm::Type &type, const llvm::GenericValue &_value ); 232 | class function : public context_holder { 233 | public: 234 | function( 235 | const boost::shared_ptr< llvm::LLVMContext > &_llvm_context, 236 | const boost::shared_ptr< llvm::EngineBuilder > &_builder, 237 | const boost::shared_ptr< llvm::ExecutionEngine > &_engine, 238 | llvm::Module *_module, 239 | llvm::Function *_function 240 | ); 241 | void operator()(); 242 | #define DCOMPILE_FUNCTION_CALL_TEMPLATE_ARGS_EACH( z, index, args ) \ 243 | typename BOOST_PP_CAT( Arg, index ) 244 | 245 | #define DCOMPILE_FUNCTION_CALL_ARGS_EACH( z, index, args ) \ 246 | BOOST_PP_CAT( Arg, index ) BOOST_PP_CAT( arg, index ) 247 | 248 | #define DCOMPILE_FUNCTION_CALL_SETPARAM_EACH( z, index, args ) \ 249 | setParam( run_args[ index ], BOOST_PP_CAT( arg, index ) ); 250 | 251 | #define DCOMPILE_FUNCTION_CALL_EACH( z, index, args ) \ 252 | template< BOOST_PP_ENUM( index, DCOMPILE_FUNCTION_CALL_TEMPLATE_ARGS_EACH, args ) > \ 253 | void operator()( BOOST_PP_ENUM( index, DCOMPILE_FUNCTION_CALL_ARGS_EACH, args ) ) { \ 254 | std::vector< llvm::GenericValue > run_args( index ); \ 255 | if( entry_point->getFunctionType()->getNumParams() != index || \ 256 | ( entry_point->getFunctionType()->isVarArg() && entry_point->getFunctionType()->getNumParams() > index ) ) \ 257 | throw InvalidArgument(); \ 258 | BOOST_PP_REPEAT( index, DCOMPILE_FUNCTION_CALL_SETPARAM_EACH, args ) \ 259 | llvm::GenericValue Result = engine->runFunction( entry_point, run_args ); \ 260 | } 261 | 262 | BOOST_PP_REPEAT_FROM_TO( 1, 20, DCOMPILE_FUNCTION_CALL_EACH, ) 263 | 264 | private: 265 | boost::shared_ptr< llvm::EngineBuilder > builder; 266 | boost::shared_ptr< llvm::ExecutionEngine > engine; 267 | llvm::Module *llvm_module; 268 | llvm::Function *entry_point; 269 | }; 270 | } 271 | 272 | #endif 273 | -------------------------------------------------------------------------------- /include/dcompile/header_path.hpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #ifndef DCOMPILE_HEADER_PATH_HPP 29 | #define DCOMPILE_HEADER_PATH_HPP 30 | 31 | #include 32 | 33 | #include 34 | 35 | namespace dcompile { 36 | class header_path { 37 | public: 38 | header_path() : enable_system_path( false ) { 39 | } 40 | void enableSystemPath( bool flag = true ) { 41 | enable_system_path = flag; 42 | } 43 | void disableSystemPath( bool flag = true ) { 44 | enableSystemPath( !flag ); 45 | } 46 | bool includeSystemPath() const { 47 | return enable_system_path; 48 | } 49 | void addPath( const boost::filesystem::path &path ) { 50 | user_path.insert( path ); 51 | } 52 | void delPath( const boost::filesystem::path &path ) { 53 | user_path.erase( path ); 54 | } 55 | boost::unordered_set< boost::filesystem::path > &getPath() { 56 | return user_path; 57 | } 58 | const boost::unordered_set< boost::filesystem::path > &getPath() const { 59 | return user_path; 60 | } 61 | private: 62 | boost::unordered_set< boost::filesystem::path > user_path; 63 | bool enable_system_path; 64 | }; 65 | } 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /include/dcompile/linker.hpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #ifndef DCOMPILE_LINKER_HPP 29 | #define DCOMPILE_LINKER_HPP 30 | 31 | #include 32 | #include 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include 40 | #include 41 | #include 42 | #include 43 | 44 | #include 45 | #include 46 | #include 47 | #include 48 | 49 | #include 50 | #include 51 | #include 52 | 53 | namespace dcompile { 54 | template< typename Iterator > 55 | object link( 56 | Iterator begin, Iterator end, 57 | typename boost::enable_if< boost::is_same< typename boost::remove_cv< typename boost::iterator_value< Iterator >::type >::type, object > >::type* = 0 58 | ) { 59 | if( std::distance( begin, end ) == 0 ) 60 | throw LinkFailed(); 61 | llvm::Linker linker( "linker", "composite", *begin->getContext().get(), 0 ); 62 | for( Iterator iter = begin; iter != end; ++iter ) { 63 | if( linker.LinkInModule( llvm::CloneModule( iter->get().get() ) ) ) 64 | throw LinkFailed(); 65 | } 66 | boost::shared_ptr< llvm::Module > llvm_module( linker.releaseModule() ); 67 | return object( begin->getContext(), begin->getOptimizeLevel(), llvm_module ); 68 | } 69 | module load( const object &_obj ) { 70 | llvm::Module *llvm_module( llvm::CloneModule( _obj.get().get() ) ); 71 | return module( _obj.getContext(), _obj.getOptimizeLevel(), llvm_module ); 72 | } 73 | } 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /include/dcompile/loader.hpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #ifndef DCOMPILE_LOADER_HPP 29 | #define DCOMPILE_LOADER_HPP 30 | 31 | #include 32 | #include 33 | 34 | #include 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | #include 42 | 43 | namespace dcompile { 44 | class loader : public context_holder { 45 | public: 46 | loader( const boost::shared_ptr< llvm::LLVMContext > &_context ); 47 | bool load( const std::string &name ) const; 48 | boost::optional< boost::filesystem::path > findLib( const std::string &name ) const; 49 | boost::optional< boost::filesystem::path > findLibInDirectory( const std::string &name, const boost::filesystem::path &path ) const; 50 | void enableSystemPath( bool flag = true ); 51 | void disableSystemPath( bool flag = true ) { 52 | enableSystemPath( !flag ); 53 | } 54 | void addPath( const boost::filesystem::path &path ) { 55 | user_path.insert( path ); 56 | } 57 | void delPath( const boost::filesystem::path &path ) { 58 | user_path.erase( path ); 59 | } 60 | boost::unordered_set< boost::filesystem::path > &getPath() { 61 | return user_path; 62 | } 63 | const boost::unordered_set< boost::filesystem::path > &getPath() const { 64 | return user_path; 65 | } 66 | private: 67 | boost::unordered_set< boost::filesystem::path > user_path; 68 | std::vector< boost::filesystem::path > system_path; 69 | bool enable_system_path; 70 | }; 71 | } 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /include/dcompile/mktemp.hpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #ifndef DCOMPILE_MKTEMP_HPP 29 | #define DCOMPILE_MKTEMP_HPP 30 | 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | namespace dcompile { 40 | template< typename CharType > 41 | boost::filesystem::path temp_file_path( int length, const std::basic_string< CharType > &prefix, const std::basic_string< CharType > &postfix ) { 42 | std::string filename_template; 43 | for( int index = 0; index < length; ++index ) filename_template += '%'; 44 | boost::filesystem::path temp_file; 45 | int try_count = 0; 46 | do { 47 | if( try_count == 1000 ) throw UnableToCreateUniqueFile(); 48 | ++try_count; 49 | temp_file = boost::filesystem::temp_directory_path() / ( 50 | prefix + 51 | boost::filesystem::unique_path( filename_template ).generic_string< std::basic_string< CharType > >() + 52 | postfix 53 | ); 54 | } while( boost::filesystem::exists( temp_file ) ); 55 | return temp_file; 56 | } 57 | 58 | template< typename CharType > 59 | boost::filesystem::path temp_file_path( int length, const std::basic_string< CharType > &postfix ) { 60 | return temp_file_path( length, std::basic_string< CharType >(), postfix ); 61 | } 62 | 63 | template< typename CharType > 64 | boost::filesystem::path temp_file_path( int length, const CharType *prefix, const CharType *postfix ) { 65 | return temp_file_path( length, std::basic_string< CharType >( prefix ), std::basic_string< CharType >( postfix ) ); 66 | } 67 | 68 | template< typename CharType > 69 | boost::filesystem::path temp_file_path( int length, const CharType *postfix ) { 70 | return temp_file_path( length, std::basic_string< CharType >(), std::basic_string< CharType >( postfix ) ); 71 | } 72 | 73 | boost::filesystem::path temp_file_path( int length ); 74 | 75 | 76 | class TemporaryFile { 77 | static boost::mutex mutex; 78 | public: 79 | TemporaryFile( int length, const std::string &prefix, const std::string &postfix ) { 80 | boost::mutex::scoped_lock( mutex ); 81 | path = temp_file_path( length, prefix, postfix ); 82 | std::fstream stream( path.c_str() ); 83 | if( stream.bad() ) 84 | throw UnableToCreateUniqueFile(); 85 | } 86 | ~TemporaryFile() { 87 | boost::mutex::scoped_lock( mutex ); 88 | boost::filesystem::remove( path ); 89 | } 90 | TemporaryFile( int length, const std::string &postfix ) { 91 | boost::mutex::scoped_lock( mutex ); 92 | path = temp_file_path( length, postfix ); 93 | std::fstream stream( path.c_str() ); 94 | if( stream.bad() ) 95 | throw UnableToCreateUniqueFile(); 96 | } 97 | TemporaryFile( int length, const char *prefix, const char *postfix ) { 98 | boost::mutex::scoped_lock( mutex ); 99 | path = temp_file_path( length, prefix, postfix ); 100 | std::fstream stream( path.c_str() ); 101 | if( stream.bad() ) 102 | throw UnableToCreateUniqueFile(); 103 | } 104 | TemporaryFile( int length, const char *postfix ) { 105 | boost::mutex::scoped_lock( mutex ); 106 | path = temp_file_path( length, postfix ); 107 | std::fstream stream( path.c_str() ); 108 | if( stream.bad() ) 109 | throw UnableToCreateUniqueFile(); 110 | } 111 | explicit TemporaryFile( int length = 64 ) { 112 | boost::mutex::scoped_lock( mutex ); 113 | path = temp_file_path( length ); 114 | std::fstream stream( path.c_str() ); 115 | if( stream.bad() ) 116 | throw UnableToCreateUniqueFile(); 117 | } 118 | const boost::filesystem::path &getPath() { 119 | return path; 120 | } 121 | private: 122 | TemporaryFile( const TemporaryFile& ) {} 123 | void operator=( const TemporaryFile& ) {} 124 | boost::filesystem::path path; 125 | }; 126 | } 127 | 128 | #endif 129 | -------------------------------------------------------------------------------- /include/dcompile/module.hpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #ifndef DCOMPILE_MODULE_HPP 29 | #define DCOMPILE_MODULE_HPP 30 | 31 | #include 32 | #include 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include 40 | #include 41 | #include 42 | #include 43 | 44 | #include 45 | #include 46 | #include 47 | #include 48 | 49 | #include 50 | #include 51 | 52 | 53 | namespace dcompile { 54 | class module : public context_holder { 55 | public: 56 | module( 57 | const boost::shared_ptr< llvm::LLVMContext > &context, 58 | OptimizeLevel optlevel, 59 | llvm::Module *_module 60 | ); 61 | int operator()( const std::vector< std::string > &argv, char * const *envp ); 62 | boost::optional< function > getFunction( const std::string &name ); 63 | private: 64 | static void deleteBuilder( llvm::EngineBuilder *builder, boost::shared_ptr< llvm::ExecutionEngine > engine ); 65 | boost::shared_ptr< llvm::EngineBuilder > builder; 66 | llvm::Module *llvm_module; 67 | boost::shared_ptr< llvm::ExecutionEngine > engine; 68 | }; 69 | } 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /include/dcompile/native_target.hpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #ifndef DCOMPILE_NATIVE_TARGET_HPP 29 | #define DCOMPILE_NATIVE_TARGET_HPP 30 | 31 | #include 32 | 33 | #include 34 | 35 | namespace dcompile { 36 | class native_target { 37 | public: 38 | static void init() { 39 | get(); 40 | } 41 | static native_target &get() { 42 | static boost::mutex singleton_lock; 43 | static native_target *instance; 44 | boost::mutex::scoped_lock lock ( singleton_lock ); 45 | if ( !instance ) { 46 | instance = getNonThreadSafe(); 47 | } 48 | return *instance; 49 | } 50 | private: 51 | static native_target *getNonThreadSafe() { 52 | static native_target singleton; 53 | return &singleton; 54 | } 55 | native_target() { 56 | llvm::InitializeNativeTarget(); 57 | llvm::InitializeNativeTargetAsmPrinter(); 58 | } 59 | }; 60 | } 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /include/dcompile/object.hpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #ifndef DCOMPILE_OBJECT_HPP 29 | #define DCOMPILE_OBJECT_HPP 30 | 31 | #include 32 | #include 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | #include 53 | 54 | 55 | namespace dcompile { 56 | class object : public context_holder { 57 | public: 58 | object( 59 | const boost::shared_ptr< llvm::LLVMContext > &context, 60 | OptimizeLevel optlevel, 61 | boost::shared_ptr< llvm::Module > _module 62 | ); 63 | boost::shared_ptr< llvm::Module > get() const { 64 | return boost::shared_ptr< llvm::Module >( llvm::CloneModule( llvm_module.get() ) ); 65 | } 66 | OptimizeLevel getOptimizeLevel() const { 67 | return optlevel; 68 | } 69 | private: 70 | boost::shared_ptr< llvm::Module > llvm_module; 71 | OptimizeLevel optlevel; 72 | }; 73 | } 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_definitions( -DRESOURCE_DIRECTORY=${LLVM_LIB_DIR}/clang/ ) 2 | add_definitions( -DSAMPLE_SOURCE_DIRECTORY=${CMAKE_CURRENT_SOURCE_DIR}/resources ) 3 | 4 | ADD_LIBRARY( dcompile SHARED common.cpp dcompile.cpp mktemp.cpp function.cpp module.cpp loader.cpp dynamic_compiler.cpp object.cpp ) 5 | target_link_libraries( dcompile ${CLANG_LIBS} ${Boost_LIBRARIES} ${LLVM_LIBS} ${LIBDL_LIBRARIES} ) 6 | set_target_properties( dcompile PROPERTIES 7 | VERSION 0.0.1 8 | SOVERSION 0.0.1 9 | ) 10 | ADD_EXECUTABLE( sample1 sample1.cpp ) 11 | target_link_libraries( sample1 ${Boost_LIBRARIES} dcompile ) 12 | ADD_EXECUTABLE( sample2 sample2.cpp ) 13 | target_link_libraries( sample2 dcompile ) 14 | ADD_EXECUTABLE( sample3 sample3.cpp ) 15 | target_link_libraries( sample3 dcompile ) 16 | ADD_EXECUTABLE( sample4 sample4.cpp ) 17 | target_link_libraries( sample4 dcompile ) 18 | ADD_EXECUTABLE( sample5 sample5.cpp ) 19 | target_link_libraries( sample5 dcompile ) 20 | ADD_EXECUTABLE( sample6 sample6.cpp ) 21 | target_link_libraries( sample6 dcompile ) 22 | ADD_EXECUTABLE( sample_kernelvm sample_kernelvm.cpp ) 23 | target_link_libraries( sample_kernelvm dcompile ) 24 | install( TARGETS dcompile 25 | RUNTIME DESTINATION bin 26 | LIBRARY DESTINATION lib 27 | ) 28 | -------------------------------------------------------------------------------- /src/common.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #include 29 | #include 30 | 31 | namespace dcompile { 32 | const char *getFileSuffix( Language lang ) { 33 | switch( lang ) { 34 | case CXX: 35 | return ".cpp"; 36 | case ObjC: 37 | return ".m"; 38 | case C: 39 | return ".c"; 40 | case CUDA: 41 | return ".cu"; 42 | case OpenCL: 43 | return ".cl"; 44 | }; 45 | throw UnsupportedLanguage(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/dcompile.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | namespace dcompile { 29 | } 30 | -------------------------------------------------------------------------------- /src/dlambda.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | #include 35 | 36 | class node { 37 | public: 38 | node() { 39 | } 40 | virtual unsigned int getMaxPlaceholder() const = 0; 41 | virtual std::string getInitializeCode() const = 0; 42 | virtual std::string getCode() const = 0; 43 | private: 44 | }; 45 | 46 | template< typename Type, unsigned int size > 47 | class constant : public node { 48 | public: 49 | constant( const boost::array< Type, size > &_values ) : values( _values ) { 50 | } 51 | unsigned int getMaxPlaceholder() const { 52 | return 0; 53 | } 54 | std::string getInitializeCode() const { 55 | std::string code( "static const st c" ); 56 | code += boost::lexical_cast< std::string >( this ) + "={"; 57 | for( typename boost::array< Type, size >::const_iterator iter = values.begin(); iter != values.end(); ++iter ) 58 | code += boost::lexical_cast< std::string >( *iter ) + ","; 59 | code += "};"; 60 | return code; 61 | } 62 | std::string getCode() const { 63 | std::string code( "c" ); 64 | code += boost::lexical_cast< std::string >( this ); 65 | return code; 66 | } 67 | private: 68 | const boost::array< Type, size > values; 69 | }; 70 | 71 | class placeholder : public node { 72 | public: 73 | placeholder( unsigned int _pos ) : pos( _pos ) { 74 | } 75 | unsigned int getMaxPlaceholder() const { 76 | return pos; 77 | } 78 | std::string getInitializeCode() const { 79 | std::string code( "const st a" ); 80 | code += boost::lexical_cast< std::string >( pos ) + "=pack(arg" + boost::lexical_cast< std::string >( pos ) + ");"; 81 | return code; 82 | } 83 | std::string getCode() const { 84 | std::string code( "a" ); 85 | code += boost::lexical_cast< std::string >( pos ); 86 | return code; 87 | } 88 | private: 89 | const unsigned int pos; 90 | }; 91 | 92 | class oper_1l : public node { 93 | public: 94 | oper_1l( const std::string &_oper, const boost::shared_ptr< node > &_arg0 ) : arg0( _arg0 ), oper( _oper ) { 95 | } 96 | unsigned int getMaxPlaceholder() const { 97 | return arg0->getMaxPlaceholder(); 98 | } 99 | std::string getInitializeCode() const { 100 | return arg0->getInitializeCode(); 101 | } 102 | std::string getCode() const { 103 | std::string code( "(" ); 104 | code += oper + arg0->getCode() + ")"; 105 | return code; 106 | } 107 | private: 108 | boost::shared_ptr< node > arg0; 109 | const std::string oper; 110 | }; 111 | 112 | class oper_1r : public node { 113 | public: 114 | oper_1r( const std::string &_oper, const boost::shared_ptr< node > &_arg0 ) : arg0( _arg0 ), oper( _oper ) { 115 | } 116 | unsigned int getMaxPlaceholder() const { 117 | return arg0->getMaxPlaceholder(); 118 | } 119 | std::string getInitializeCode() const { 120 | return arg0->getInitializeCode(); 121 | } 122 | std::string getCode() const { 123 | std::string code( "(" ); 124 | code += arg0->getCode() + oper + ")"; 125 | return code; 126 | } 127 | private: 128 | boost::shared_ptr< node > arg0; 129 | const std::string oper; 130 | }; 131 | 132 | class oper_2 : public node { 133 | public: 134 | oper2( const std::string &_oper, const boost::shared_ptr< node > &_arg0, const boost::shared_ptr< node > &_arg1 ) : arg0( _arg0 ), arg1( _arg1 ), oper( _oper ) { 135 | } 136 | unsigned int getMaxPlaceholder() const { 137 | return std::max( arg0->getMaxPlaceholder(), arg1->getMaxPlaceholder() ); 138 | } 139 | std::string getInitializeCode() const { 140 | return arg0->getInitializeCode() + arg1->getInitializeCode(); 141 | } 142 | std::string getCode() const { 143 | std::string code( "(" ); 144 | code += arg0->getCode() + "+" + arg1->getCode() + ")"; 145 | return code; 146 | } 147 | private: 148 | boost::shared_ptr< node > arg0; 149 | boost::shared_ptr< node > arg1; 150 | const std::string oper; 151 | }; 152 | 153 | class left_increment : public oper_1l { 154 | public: 155 | left_increment( const boost::shared_ptr< node > &_arg0 ) : oper_1l( "++", _arg0 ) {} 156 | }; 157 | 158 | class right_increment : public oper_1r { 159 | public: 160 | left_increment( const boost::shared_ptr< node > &_arg0 ) : oper_1r( "++", _arg0 ) {} 161 | }; 162 | 163 | 164 | class sub : public node { 165 | public: 166 | sub( const boost::shared_ptr< node > &_left, const boost::shared_ptr< node > &_right ) : left( _left ), right( _right ) { 167 | } 168 | unsigned int getMaxPlaceholder() const { 169 | return std::max( left->getMaxPlaceholder(), right->getMaxPlaceholder() ); 170 | } 171 | std::string getInitializeCode() const { 172 | return left->getInitializeCode() + right->getInitializeCode(); 173 | } 174 | std::string getCode() const { 175 | std::string code( "(" ); 176 | code += left->getCode() + "-" + right->getCode() + ")"; 177 | return code; 178 | } 179 | private: 180 | boost::shared_ptr< node > left; 181 | boost::shared_ptr< node > right; 182 | }; 183 | 184 | class mul : public node { 185 | public: 186 | sub( const boost::shared_ptr< node > &_left, const boost::shared_ptr< node > &_right ) : left( _left ), right( _right ) { 187 | } 188 | unsigned int getMaxPlaceholder() const { 189 | return std::max( left->getMaxPlaceholder(), right->getMaxPlaceholder() ); 190 | } 191 | std::string getInitializeCode() const { 192 | return left->getInitializeCode() + right->getInitializeCode(); 193 | } 194 | std::string getCode() const { 195 | std::string code( "(" ); 196 | code += left->getCode() + "-" + right->getCode() + ")"; 197 | return code; 198 | } 199 | private: 200 | boost::shared_ptr< node > left; 201 | boost::shared_ptr< node > right; 202 | }; 203 | 204 | template< typename Type, unsigned int size > 205 | class simd { 206 | public: 207 | simd( const boost::shared_ptr< node > &_node ) : internal_node( _node ) { 208 | } 209 | simd( const boost::array< Type, size > &_array ) : internal_node( new constant< Type, size >( _array ) ) { 210 | } 211 | simd( unsigned int _pos ) : internal_node( new placeholder( _pos ) ) { 212 | } 213 | const boost::shared_ptr< node > &getNode() const { 214 | return internal_node; 215 | } 216 | void operator()() { 217 | std::string code; 218 | code += "typedef float* sst;"; 219 | code += "typedef float st __attribute__((ext_vector_type(16)));"; 220 | code += "st pack(sst src){st dest;for(int i=0;i!=16;++i)dest[i]=src[i];return dest;}"; 221 | code += "void unpack(sst dest,st src){for(int i=0;i!=16;++i)dest[i]=src[i];}"; 222 | code += "void calc(sst dest"; 223 | unsigned int max_placeholder = internal_node->getMaxPlaceholder() + 1; 224 | for( unsigned int index = 0; index != max_placeholder; ++index ) 225 | code += std::string( ",const sst arg" ) + boost::lexical_cast< std::string >( index ); 226 | code += "){"; 227 | code += internal_node->getInitializeCode(); 228 | code += "unpack(dest,"; 229 | code += internal_node->getCode(); 230 | code += ");}"; 231 | std::cout << code << std::endl; 232 | } 233 | private: 234 | boost::shared_ptr< node > internal_node; 235 | }; 236 | 237 | template< typename Type, unsigned int size > 238 | simd< Type, size > operator+( const simd< Type, size > &_left, const simd< Type, size > &_right ) { 239 | boost::shared_ptr< node > temp( new add( _left.getNode(), _right.getNode() ) ); 240 | return simd< Type, size >( temp ); 241 | } 242 | 243 | template< typename Type, unsigned int size > 244 | simd< Type, size > operator-( const simd< Type, size > &_left, const simd< Type, size > &_right ) { 245 | boost::shared_ptr< node > temp( new sub( _left.getNode(), _right.getNode() ) ); 246 | return simd< Type, size >( temp ); 247 | } 248 | 249 | int main() { 250 | boost::array< float, 16 > a = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768 }; 251 | typedef simd< float, 16 > s; 252 | s f = s( a ) + s( 1 ) - s( 2 ); 253 | f(); 254 | } 255 | 256 | -------------------------------------------------------------------------------- /src/dynamic_compiler.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #include 44 | #include 45 | #include 46 | 47 | #include 48 | #include 49 | #include 50 | #include 51 | 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | #include 59 | 60 | namespace dcompile { 61 | dynamic_compiler::dynamic_compiler() 62 | : resource_directory( boost::filesystem::path( BOOST_PP_STRINGIZE( RESOURCE_DIRECTORY ) ) / CLANG_VERSION_STRING ), 63 | library_loader( getContext() ), optlevel( Aggressive ) { 64 | } 65 | dynamic_compiler::dynamic_compiler( const boost::filesystem::path &resource ) 66 | : resource_directory( resource ), library_loader( getContext() ), optlevel( Aggressive ) { 67 | } 68 | void dynamic_compiler::setOptimizeLevel( OptimizeLevel new_level ) { 69 | optlevel = new_level; 70 | } 71 | OptimizeLevel dynamic_compiler::getOptimizeLevel() const { 72 | return optlevel; 73 | } 74 | void dynamic_compiler::buildArguments( std::vector< std::string > &arguments ) const { 75 | arguments.push_back( "dcompile" ); 76 | switch( optlevel ) { 77 | case None: 78 | arguments.push_back( "-O0" ); 79 | break; 80 | case Less: 81 | arguments.push_back( "-O1" ); 82 | break; 83 | case Default: 84 | arguments.push_back( "-O2" ); 85 | break; 86 | case Aggressive: 87 | arguments.push_back( "-O3" ); 88 | break; 89 | default: 90 | throw UnknownOptimizeLevel(); 91 | }; 92 | if( !header.includeSystemPath() ) 93 | arguments.push_back( "-nostdsysteminc" ); 94 | for( 95 | boost::unordered_set< boost::filesystem::path >::const_iterator iter = header.getPath().begin(); 96 | iter != header.getPath().end(); 97 | ++iter 98 | ) { 99 | arguments.push_back( "-I" ); 100 | arguments.push_back( iter->string() ); 101 | } 102 | arguments.push_back( "-resource-dir" ); 103 | arguments.push_back( resource_directory.string() ); 104 | } 105 | void dynamic_compiler::buildArguments( std::vector< std::string > &arguments, const boost::filesystem::path &_from, const boost::filesystem::path &_to ) const { 106 | buildArguments( arguments ); 107 | arguments.push_back( _from.string() ); 108 | arguments.push_back( "-o" ); 109 | arguments.push_back( _to.string() ); 110 | arguments.push_back( "" ); 111 | } 112 | void dynamic_compiler::setupCompiler( clang::CompilerInstance &compiler, const std::vector< std::string > &arguments ) const { 113 | std::vector< const char* > cstyle_arguments; 114 | for( std::vector< std::string >::const_iterator iter = arguments.begin(); iter != arguments.end(); ++iter ) 115 | cstyle_arguments.push_back( iter->c_str() ); 116 | compiler.createDiagnostics( cstyle_arguments.size(), cstyle_arguments.data(), NULL ); 117 | clang::CompilerInvocation::CreateFromArgs( 118 | compiler.getInvocation(), 119 | &cstyle_arguments[ 1 ], &cstyle_arguments.back(), 120 | compiler.getDiagnostics() 121 | ); 122 | clang::TargetOptions target_opts; 123 | target_opts.Triple = LLVM_DEFAULT_TARGET_TRIPLE; 124 | target_opts.CPU = llvm::sys::getHostCPUName(); 125 | compiler.setTarget( clang::TargetInfo::CreateTargetInfo( 126 | compiler.getDiagnostics(), 127 | target_opts 128 | ) ); 129 | compiler.getTarget().setForcedLangOptions(compiler.getLangOpts()); 130 | compiler.createFileManager(); 131 | compiler.createSourceManager( compiler.getFileManager() ); 132 | } 133 | void dynamic_compiler::setupCompiler( clang::CompilerInstance &compiler, const boost::filesystem::path &_from, const boost::filesystem::path &_to ) const { 134 | std::vector< std::string > arguments; 135 | buildArguments( arguments, _from, _to ); 136 | setupCompiler( compiler, arguments ); 137 | } 138 | bool dynamic_compiler::begin( clang::CompilerInstance &compiler, clang::FrontendAction &action, const clang::FrontendInputFile &file ) const { 139 | action.setCurrentInput( file ); 140 | action.setCompilerInstance( &compiler ); 141 | // if( action.BeginInvocation( compiler ) ) 142 | // goto FAILED; 143 | /////////// STUB /////////// 144 | } 145 | void dynamic_compiler::execute( clang::CompilerInstance &compiler, clang::FrontendAction &action ) const { 146 | for (unsigned i = 0, e = compiler.getFrontendOpts().Inputs.size(); i != e; ++i) { 147 | if ( compiler.hasSourceManager()) 148 | compiler.getSourceManager().clearIDTables(); 149 | if ( action.BeginSourceFile( compiler, compiler.getFrontendOpts().Inputs[i] ) ) { 150 | action.Execute(); 151 | action.EndSourceFile(); 152 | } 153 | } 154 | compiler.getDiagnostics().getClient()->finish(); 155 | } 156 | void dynamic_compiler::compileEachSource( boost::shared_ptr< TemporaryFile > &bc, const boost::filesystem::path &src ) const { 157 | bc.reset( new TemporaryFile( 64, ".bc" ) ); 158 | clang::CompilerInstance compiler; 159 | setupCompiler( compiler, src, bc->getPath() ); 160 | clang::EmitBCAction action( getContext().get() ); 161 | execute ( compiler, action ); 162 | } 163 | module dynamic_compiler::operator()( const std::string &source_code, Language lang ) const { 164 | TemporaryFile source_file_name( 64, getFileSuffix( lang ) ); 165 | TemporaryFile bc_file_name( 64, ".bc" ); 166 | clang::CompilerInstance compiler; 167 | setupCompiler( compiler, source_file_name.getPath(), bc_file_name.getPath() ); 168 | { 169 | std::fstream source_file( source_file_name.getPath().c_str(), std::ios::out ); 170 | source_file << source_code; 171 | } 172 | 173 | return getModule( compiler, bc_file_name ); 174 | } 175 | object dynamic_compiler::getObject( const std::string &source_code, Language lang ) const { 176 | TemporaryFile source_file_name( 64, getFileSuffix( lang ) ); 177 | TemporaryFile bc_file_name( 64, ".bc" ); 178 | { 179 | std::fstream source_file( source_file_name.getPath().c_str(), std::ios::out ); 180 | source_file << source_code; 181 | } 182 | clang::CompilerInstance compiler; 183 | setupCompiler( compiler, source_file_name.getPath(), bc_file_name.getPath() ); 184 | 185 | return getObject( compiler, bc_file_name ); 186 | } 187 | std::string dynamic_compiler::dumpLLVM( const std::string &source_code, Language lang ) const { 188 | TemporaryFile source_file_name( 64, getFileSuffix( lang ) ); 189 | TemporaryFile ast_file_name( 64, ".ll" ); 190 | { 191 | std::fstream source_file( source_file_name.getPath().c_str(), std::ios::out ); 192 | source_file << source_code; 193 | } 194 | clang::CompilerInstance compiler; 195 | setupCompiler( compiler, source_file_name.getPath(), ast_file_name.getPath() ); 196 | 197 | clang::EmitLLVMAction action( getContext().get() ); 198 | execute ( compiler, action ); 199 | std::string result; 200 | std::fstream asm_file( ast_file_name.getPath().c_str(), std::ios::in ); 201 | return std::string( std::istreambuf_iterator(asm_file), std::istreambuf_iterator() ); 202 | } 203 | std::string dynamic_compiler::dumpAsm( const std::string &source_code, Language lang ) const { 204 | native_target::init(); 205 | TemporaryFile source_file_name( 64, getFileSuffix( lang ) ); 206 | TemporaryFile ast_file_name( 64, ".S" ); 207 | { 208 | std::fstream source_file( source_file_name.getPath().c_str(), std::ios::out ); 209 | source_file << source_code; 210 | } 211 | clang::CompilerInstance compiler; 212 | setupCompiler( compiler, source_file_name.getPath(), ast_file_name.getPath() ); 213 | 214 | clang::EmitAssemblyAction action( getContext().get() ); 215 | execute ( compiler, action ); 216 | std::string result; 217 | std::fstream asm_file( ast_file_name.getPath().c_str(), std::ios::in ); 218 | return std::string( std::istreambuf_iterator(asm_file), std::istreambuf_iterator() ); 219 | } 220 | module dynamic_compiler::operator()( const boost::filesystem::path &path ) const { 221 | TemporaryFile bc_file_name( 64, ".bc" ); 222 | clang::CompilerInstance compiler; 223 | setupCompiler( compiler, path, bc_file_name.getPath() ); 224 | 225 | return getModule( compiler, bc_file_name ); 226 | } 227 | object dynamic_compiler::getObject( const boost::filesystem::path &path ) const { 228 | TemporaryFile bc_file_name( 64, ".bc" ); 229 | clang::CompilerInstance compiler; 230 | setupCompiler( compiler, path, bc_file_name.getPath() ); 231 | 232 | return getObject( compiler, bc_file_name ); 233 | } 234 | std::string dynamic_compiler::dumpLLVM( const boost::filesystem::path &path ) const { 235 | TemporaryFile ast_file_name( 64, ".ll" ); 236 | clang::CompilerInstance compiler; 237 | setupCompiler( compiler, path, ast_file_name.getPath() ); 238 | 239 | clang::EmitLLVMAction action( getContext().get() ); 240 | execute ( compiler, action ); 241 | std::string result; 242 | std::fstream asm_file( ast_file_name.getPath().c_str(), std::ios::in ); 243 | return std::string( std::istreambuf_iterator(asm_file), std::istreambuf_iterator() ); 244 | } 245 | std::string dynamic_compiler::dumpAsm( const boost::filesystem::path &path ) const { 246 | native_target::init(); 247 | TemporaryFile ast_file_name( 64, ".S" ); 248 | clang::CompilerInstance compiler; 249 | setupCompiler( compiler, path, ast_file_name.getPath() ); 250 | 251 | clang::EmitAssemblyAction action( getContext().get() ); 252 | execute ( compiler, action ); 253 | std::string result; 254 | std::fstream asm_file( ast_file_name.getPath().c_str(), std::ios::in ); 255 | return std::string( std::istreambuf_iterator(asm_file), std::istreambuf_iterator() ); 256 | } 257 | module dynamic_compiler::getModule( clang::CompilerInstance &compiler, TemporaryFile &bc_file_name ) const { 258 | native_target::init(); 259 | clang::EmitBCAction action( getContext().get() ); 260 | execute ( compiler, action ); 261 | llvm::SMDiagnostic Err; 262 | llvm::Module *llvm_module = llvm::ParseIRFile( bc_file_name.getPath().c_str(), Err, *getContext() ); 263 | std::string ErrorMsg; 264 | if ( llvm_module->MaterializeAllPermanently(&ErrorMsg)) { 265 | llvm::errs() << "dcompile::module" << ": bitcode didn't read correctly.\n"; 266 | llvm::errs() << "Reason: " << ErrorMsg << "\n"; 267 | throw UnableToLoadModule(); 268 | } 269 | module lib( getContext(), optlevel, llvm_module ); 270 | return lib; 271 | } 272 | object dynamic_compiler::getObject( clang::CompilerInstance &compiler, TemporaryFile &bc_file_name ) const { 273 | clang::EmitBCAction action( getContext().get() ); 274 | execute ( compiler, action ); 275 | native_target::init(); 276 | llvm::SMDiagnostic Err; 277 | boost::shared_ptr< llvm::Module > llvm_module( llvm::ParseIRFile( bc_file_name.getPath().c_str(), Err, *getContext() ) ); 278 | std::string ErrorMsg; 279 | if ( !llvm_module || llvm_module->MaterializeAllPermanently(&ErrorMsg)) { 280 | llvm::errs() << "dcompile::module" << ": bitcode didn't read correctly.\n"; 281 | llvm::errs() << "Reason: " << ErrorMsg << "\n"; 282 | throw UnableToLoadModule(); 283 | } 284 | object lib( getContext(), optlevel, llvm_module ); 285 | return lib; 286 | } 287 | } 288 | -------------------------------------------------------------------------------- /src/function.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | 34 | #include 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | namespace dcompile { 44 | return_value getReturnValue( const llvm::Type &type, const llvm::GenericValue &_value ) { 45 | switch ( type.getTypeID() ) { 46 | case llvm::Type::VoidTyID: 47 | return return_value(); 48 | case llvm::Type::IntegerTyID: 49 | case llvm::Type::FloatTyID: 50 | case llvm::Type::DoubleTyID: 51 | case llvm::Type::PointerTyID: 52 | default: 53 | throw InvalidArgument(); 54 | }; 55 | } 56 | function::function( 57 | const boost::shared_ptr< llvm::LLVMContext > &_llvm_context, 58 | const boost::shared_ptr< llvm::EngineBuilder > &_builder, 59 | const boost::shared_ptr< llvm::ExecutionEngine > &_engine, 60 | llvm::Module *_module, 61 | llvm::Function *_function 62 | ) : context_holder( _llvm_context ), builder( _builder ), engine( _engine ), llvm_module( _module ), 63 | entry_point( _function ) {} 64 | void function::operator()() { 65 | std::vector< llvm::GenericValue > run_args( 0 ); 66 | if( entry_point->getFunctionType()->getNumParams() != 0 ) 67 | throw InvalidArgument(); 68 | llvm::GenericValue Result = engine->runFunction( entry_point, run_args ); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/loader.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include 40 | #include 41 | #include 42 | 43 | namespace dcompile { 44 | loader::loader( const boost::shared_ptr< llvm::LLVMContext > &_context ) : context_holder( _context ), enable_system_path( false ) { 45 | } 46 | void loader::enableSystemPath( bool flag ) { 47 | enable_system_path = flag; 48 | if( enable_system_path && system_path.empty() ) { 49 | std::vector< llvm::sys::Path > llvm_system_path; 50 | llvm::sys::Path::GetSystemLibraryPaths ( llvm_system_path ); 51 | system_path.reserve( llvm_system_path.size() ); 52 | for( 53 | std::vector< llvm::sys::Path >::const_iterator iter = llvm_system_path.begin(); 54 | iter != llvm_system_path.end(); 55 | ++iter 56 | ) system_path.push_back( boost::filesystem::path( iter->c_str() ) ); 57 | } 58 | } 59 | bool loader::load( const std::string &name ) const { 60 | boost::optional< boost::filesystem::path > path = findLib( name ); 61 | if( path ) 62 | return !llvm::sys::DynamicLibrary::LoadLibraryPermanently( path->c_str() ); 63 | else 64 | return false; 65 | } 66 | boost::optional< boost::filesystem::path > loader::findLib( const std::string &name ) const { 67 | llvm::sys::Path llvm_path; 68 | llvm_path.set( name.c_str() ); 69 | if ( llvm_path.isDynamicLibrary() || llvm_path.isBitcodeFile() ) 70 | return boost::filesystem::path( name ); 71 | for( 72 | boost::unordered_set< boost::filesystem::path >::const_iterator iter = user_path.begin(); 73 | iter != user_path.end(); 74 | ++iter 75 | ) { 76 | boost::optional< boost::filesystem::path > path = findLibInDirectory( name, *iter ); 77 | if( path ) 78 | return path; 79 | } 80 | if( enable_system_path ) { 81 | for( 82 | std::vector< boost::filesystem::path >::const_iterator iter = system_path.begin(); 83 | iter != system_path.end(); 84 | ++iter 85 | ) { 86 | boost::optional< boost::filesystem::path > path = findLibInDirectory( name, *iter ); 87 | if( path ) 88 | return path; 89 | } 90 | } 91 | return boost::optional< boost::filesystem::path >(); 92 | } 93 | boost::optional< boost::filesystem::path > loader::findLibInDirectory( const std::string &name, const boost::filesystem::path &path ) const { 94 | llvm::sys::Path llvm_path; 95 | llvm_path.set( path.c_str() ); 96 | llvm_path.appendComponent( "lib" + name ); 97 | llvm_path.appendSuffix( llvm::sys::Path::GetDLLSuffix() ); 98 | if ( llvm_path.isDynamicLibrary() || llvm_path.isBitcodeFile() ) 99 | return boost::filesystem::path( llvm_path.c_str() ); 100 | llvm_path.eraseSuffix(); 101 | if ( llvm_path.isDynamicLibrary() || llvm_path.isBitcodeFile() ) 102 | return boost::filesystem::path( llvm_path.c_str() ); 103 | return boost::optional< boost::filesystem::path >(); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/mktemp.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #include 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | namespace dcompile { 35 | boost::filesystem::path temp_file_path( int length ) { 36 | std::string filename_template; 37 | for( int index = 0; index < length; ++index ) filename_template += '%'; 38 | boost::filesystem::path temp_file; 39 | int try_count = 0; 40 | do { 41 | if( try_count == 1000 ) throw UnableToCreateUniqueFile(); 42 | ++try_count; 43 | temp_file = boost::filesystem::temp_directory_path() / 44 | boost::filesystem::unique_path( filename_template ); 45 | } while( boost::filesystem::exists( temp_file ) ); 46 | return temp_file; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/module.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include 39 | #include 40 | #include 41 | 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | 55 | namespace dcompile { 56 | module::module( 57 | const boost::shared_ptr< llvm::LLVMContext > &context, 58 | OptimizeLevel optlevel, 59 | llvm::Module *_module 60 | ) : context_holder( context ), llvm_module( _module ) { 61 | native_target::init(); 62 | std::string ErrorMsg; 63 | if (llvm_module->MaterializeAllPermanently(&ErrorMsg)) { 64 | llvm::errs() << "dcompile::module" << ": bitcode didn't read correctly.\n"; 65 | llvm::errs() << "Reason: " << ErrorMsg << "\n"; 66 | throw UnableToLoadModule(); 67 | } 68 | llvm::EngineBuilder *engine_builder = new llvm::EngineBuilder( llvm_module ); 69 | engine_builder->setErrorStr(&ErrorMsg); 70 | engine_builder->setEngineKind(llvm::EngineKind::JIT); 71 | switch( optlevel ) { 72 | case None: 73 | engine_builder->setOptLevel( llvm::CodeGenOpt::None ); 74 | break; 75 | case Less: 76 | engine_builder->setOptLevel( llvm::CodeGenOpt::Less ); 77 | break; 78 | case Default: 79 | engine_builder->setOptLevel( llvm::CodeGenOpt::Default ); 80 | break; 81 | case Aggressive: 82 | engine_builder->setOptLevel( llvm::CodeGenOpt::Aggressive ); 83 | break; 84 | default: 85 | throw UnknownOptimizeLevel(); 86 | }; 87 | engine.reset( engine_builder->create() ); 88 | builder.reset( engine_builder, boost::bind( &module::deleteBuilder, _1, engine ) ); 89 | builder->setRelocationModel(llvm::Reloc::Default); 90 | builder->setCodeModel( llvm::CodeModel::JITDefault ); 91 | builder->setUseMCJIT(true); 92 | if (!engine) { 93 | if (!ErrorMsg.empty()) 94 | llvm::errs() << "dcompile::module" << ": error creating EE: " << ErrorMsg << "\n"; 95 | else 96 | llvm::errs() << "dcompile::module" << ": unknown error creating EE!\n"; 97 | throw UnableToLoadModule(); 98 | } 99 | engine->RegisterJITEventListener(llvm::JITEventListener::createOProfileJITEventListener()); 100 | engine->DisableLazyCompilation(true); 101 | engine->runStaticConstructorsDestructors(false); 102 | } 103 | int module::operator()( const std::vector< std::string > &argv, char * const *envp ) { 104 | llvm::Function *entry_point = llvm_module->getFunction( "main" ); 105 | return engine->runFunctionAsMain( entry_point, argv, envp ); 106 | } 107 | boost::optional< function > module::getFunction( const std::string &name ) { 108 | llvm::Function *entry_point = llvm_module->getFunction( name.c_str() ); 109 | if( !entry_point ) 110 | return boost::optional< function >(); 111 | return function( getContext(), builder, engine, llvm_module, entry_point ); 112 | } 113 | void module::deleteBuilder( llvm::EngineBuilder *builder, boost::shared_ptr< llvm::ExecutionEngine > engine ) { 114 | engine->runStaticConstructorsDestructors(true); 115 | delete builder; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/object.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include 39 | #include 40 | #include 41 | 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | namespace dcompile { 57 | object::object( 58 | const boost::shared_ptr< llvm::LLVMContext > &context, 59 | OptimizeLevel _optlevel, 60 | boost::shared_ptr< llvm::Module > _module 61 | ) : context_holder( context ), llvm_module( _module ), optlevel( _optlevel ) { 62 | std::string ErrorMsg; 63 | if (llvm_module->MaterializeAllPermanently(&ErrorMsg)) { 64 | llvm::errs() << "dcompile::object" << ": bitcode didn't read correctly.\n"; 65 | llvm::errs() << "Reason: " << ErrorMsg << "\n"; 66 | throw UnableToLoadModule(); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/resources/fuga.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern "C" 4 | void moo( float *a ) { 5 | std::cout << *a << " inslide" << std::endl; 6 | std::cout << "Hello, world!" << std::endl; 7 | *a += 0.1f; 8 | } 9 | -------------------------------------------------------------------------------- /src/resources/hoge.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | extern "C" void moo( float *a ); 5 | 6 | extern "C" void foo( float *a ) { 7 | struct jpeg_compress_struct cinfo; 8 | jpeg_create_compress( &cinfo ); 9 | moo( a ); 10 | } 11 | -------------------------------------------------------------------------------- /src/resources/test.cpp: -------------------------------------------------------------------------------- 1 | typedef float* host_buffer; 2 | const unsigned int vector_size = 64; 3 | typedef float buffer __attribute__((ext_vector_type(64))); 4 | typedef bool bool_buffer __attribute__((ext_vector_type(64))); 5 | extern "C" float floorf(float x); 6 | extern "C" float ceilf(float x); 7 | 8 | 9 | const unsigned int sin_table_size = 512; 10 | const float sin_table[ sin_table_size ] = { 11 | 0,0.0122715,0.0245412,0.0368072,0.0490677,0.0613207,0.0735646,0.0857973, 12 | 0.0980171,0.110222,0.122411,0.134581,0.14673,0.158858,0.170962,0.18304, 13 | 0.19509,0.207111,0.219101,0.231058,0.24298,0.254866,0.266713,0.27852, 14 | 0.290285,0.302006,0.313682,0.32531,0.33689,0.348419,0.359895,0.371317, 15 | 0.382683,0.393992,0.405241,0.41643,0.427555,0.438616,0.449611,0.460539, 16 | 0.471397,0.482184,0.492898,0.503538,0.514103,0.52459,0.534998,0.545325, 17 | 0.55557,0.565732,0.575808,0.585798,0.595699,0.605511,0.615232,0.62486, 18 | 0.634393,0.643832,0.653173,0.662416,0.671559,0.680601,0.689541,0.698376, 19 | 0.707107,0.715731,0.724247,0.732654,0.740951,0.749136,0.757209,0.765167, 20 | 0.77301,0.780737,0.788346,0.795837,0.803208,0.810457,0.817585,0.824589, 21 | 0.83147,0.838225,0.844854,0.851355,0.857729,0.863973,0.870087,0.87607, 22 | 0.881921,0.88764,0.893224,0.898674,0.903989,0.909168,0.91421,0.919114, 23 | 0.92388,0.928506,0.932993,0.937339,0.941544,0.945607,0.949528,0.953306, 24 | 0.95694,0.960431,0.963776,0.966976,0.970031,0.97294,0.975702,0.978317, 25 | 0.980785,0.983105,0.985278,0.987301,0.989177,0.990903,0.99248,0.993907, 26 | 0.995185,0.996313,0.99729,0.998118,0.998795,0.999322,0.999699,0.999925, 27 | 1,0.999925,0.999699,0.999322,0.998795,0.998118,0.99729,0.996313, 28 | 0.995185,0.993907,0.99248,0.990903,0.989177,0.987301,0.985278,0.983105, 29 | 0.980785,0.978317,0.975702,0.97294,0.970031,0.966976,0.963776,0.960431, 30 | 0.95694,0.953306,0.949528,0.945607,0.941544,0.937339,0.932993,0.928506, 31 | 0.92388,0.919114,0.91421,0.909168,0.903989,0.898674,0.893224,0.88764, 32 | 0.881921,0.87607,0.870087,0.863973,0.857729,0.851355,0.844854,0.838225, 33 | 0.83147,0.824589,0.817585,0.810457,0.803207,0.795837,0.788346,0.780737, 34 | 0.77301,0.765167,0.757209,0.749136,0.740951,0.732654,0.724247,0.715731, 35 | 0.707107,0.698376,0.689541,0.680601,0.671559,0.662416,0.653173,0.643832, 36 | 0.634393,0.624859,0.615232,0.605511,0.595699,0.585798,0.575808,0.565732, 37 | 0.55557,0.545325,0.534998,0.52459,0.514103,0.503538,0.492898,0.482184, 38 | 0.471397,0.460539,0.449611,0.438616,0.427555,0.41643,0.405241,0.393992, 39 | 0.382684,0.371317,0.359895,0.348419,0.33689,0.32531,0.313682,0.302006, 40 | 0.290285,0.27852,0.266713,0.254866,0.24298,0.231058,0.219101,0.207111, 41 | 0.19509,0.18304,0.170962,0.158858,0.146731,0.134581,0.122411,0.110222, 42 | 0.0980171,0.0857972,0.0735644,0.0613208,0.0490677,0.0368072,0.0245412,0.0122715, 43 | -8.74228e-08,-0.0122714,-0.0245411,-0.0368072,-0.0490677,-0.0613208,-0.0735646,-0.0857974, 44 | -0.098017,-0.110222,-0.122411,-0.134581,-0.14673,-0.158858,-0.170962,-0.18304, 45 | -0.19509,-0.207111,-0.219101,-0.231058,-0.24298,-0.254866,-0.266713,-0.27852, 46 | -0.290285,-0.302006,-0.313682,-0.32531,-0.33689,-0.348419,-0.359895,-0.371317, 47 | -0.382683,-0.393992,-0.405241,-0.41643,-0.427555,-0.438616,-0.449611,-0.460539, 48 | -0.471397,-0.482184,-0.492898,-0.503538,-0.514103,-0.52459,-0.534998,-0.545325, 49 | -0.55557,-0.565732,-0.575808,-0.585798,-0.595699,-0.605511,-0.615232,-0.62486, 50 | -0.634393,-0.643831,-0.653173,-0.662416,-0.671559,-0.680601,-0.689541,-0.698376, 51 | -0.707107,-0.715731,-0.724247,-0.732654,-0.740951,-0.749136,-0.757209,-0.765167, 52 | -0.77301,-0.780737,-0.788346,-0.795837,-0.803208,-0.810457,-0.817585,-0.824589, 53 | -0.831469,-0.838225,-0.844853,-0.851355,-0.857729,-0.863973,-0.870087,-0.87607, 54 | -0.881921,-0.88764,-0.893224,-0.898674,-0.903989,-0.909168,-0.91421,-0.919114, 55 | -0.923879,-0.928506,-0.932993,-0.937339,-0.941544,-0.945607,-0.949528,-0.953306, 56 | -0.95694,-0.960431,-0.963776,-0.966977,-0.970031,-0.97294,-0.975702,-0.978317, 57 | -0.980785,-0.983105,-0.985278,-0.987301,-0.989177,-0.990903,-0.99248,-0.993907, 58 | -0.995185,-0.996313,-0.99729,-0.998118,-0.998795,-0.999322,-0.999699,-0.999925, 59 | -1,-0.999925,-0.999699,-0.999322,-0.998795,-0.998118,-0.99729,-0.996313, 60 | -0.995185,-0.993907,-0.99248,-0.990903,-0.989177,-0.987301,-0.985278,-0.983105, 61 | -0.980785,-0.978317,-0.975702,-0.97294,-0.970031,-0.966977,-0.963776,-0.960431, 62 | -0.95694,-0.953306,-0.949528,-0.945607,-0.941544,-0.937339,-0.932993,-0.928506, 63 | -0.923879,-0.919114,-0.91421,-0.909168,-0.903989,-0.898674,-0.893224,-0.88764, 64 | -0.881921,-0.87607,-0.870087,-0.863973,-0.857729,-0.851355,-0.844853,-0.838225, 65 | -0.83147,-0.824589,-0.817585,-0.810457,-0.803208,-0.795837,-0.788346,-0.780737, 66 | -0.77301,-0.765167,-0.757209,-0.749136,-0.740951,-0.732654,-0.724247,-0.715731, 67 | -0.707107,-0.698376,-0.689541,-0.680601,-0.671559,-0.662416,-0.653173,-0.643831, 68 | -0.634393,-0.624859,-0.615231,-0.605511,-0.595699,-0.585798,-0.575808,-0.565732, 69 | -0.55557,-0.545325,-0.534998,-0.52459,-0.514103,-0.503538,-0.492898,-0.482184, 70 | -0.471397,-0.460539,-0.449612,-0.438616,-0.427555,-0.41643,-0.405241,-0.393992, 71 | -0.382683,-0.371317,-0.359895,-0.348419,-0.33689,-0.32531,-0.313682,-0.302006, 72 | -0.290285,-0.27852,-0.266713,-0.254866,-0.24298,-0.231058,-0.219101,-0.207111, 73 | -0.19509,-0.18304,-0.170962,-0.158858,-0.14673,-0.134581,-0.122411,-0.110222, 74 | -0.0980172,-0.0857974,-0.0735646,-0.0613207,-0.0490676,-0.0368072,-0.0245411,-0.0122714, 75 | }; 76 | 77 | 78 | const unsigned int max_uniforms = 200; 79 | const unsigned int max_variables = 16; 80 | const unsigned int max_locals = 16; 81 | 82 | float uniforms[ max_uniforms ]; 83 | unsigned int variables_size[ max_variables ]; 84 | const float *variables[ max_variables ]; 85 | 86 | inline float uniform( unsigned int name ) { 87 | return uniforms[ name ]; 88 | } 89 | inline buffer vectorize( float src ) { 90 | buffer temp; 91 | for( unsigned int index = 0; index != vector_size; ++index ) 92 | temp[ index ] = src; 93 | return temp; 94 | } 95 | inline buffer count() { 96 | buffer temp; 97 | for( unsigned int index = 0; index != vector_size; ++index ) 98 | temp[ index ] = index; 99 | return temp; 100 | } 101 | inline float linear( float a, float b, float src ) { 102 | return a * src + b; 103 | } 104 | inline buffer linear( float a, float b, const buffer &src ) { 105 | return vectorize( a ) * src + vectorize( b ); 106 | } 107 | inline buffer linear( const buffer & a, const buffer & b, const buffer &src ) { 108 | return a * src + b; 109 | } 110 | inline float interpolate( float l, float r, float p ) { 111 | return l * p + r * ( 1.0f - p ); 112 | } 113 | inline buffer interpolate( const buffer &l, const buffer &r, const buffer &p ) { 114 | return l * p + r * ( vectorize( 1.0f ) - p ); 115 | } 116 | inline float floor( float src ) { 117 | return floorf( src ); 118 | } 119 | inline buffer floor( const buffer &src ) { 120 | buffer temp; 121 | for( unsigned int index = 0; index != vector_size; ++index ) { 122 | temp[ index ] = floor( src[ index ] ); 123 | } 124 | return temp; 125 | } 126 | inline float ceil( float src ) { 127 | return ceilf( src ); 128 | } 129 | inline buffer ceil( const buffer &src ) { 130 | buffer temp; 131 | for( unsigned int index = 0; index != vector_size; ++index ) { 132 | temp[ index ] = ceil( src[ index ] ); 133 | } 134 | return temp; 135 | } 136 | inline float loop( float src ) { 137 | return src - floor( src ); 138 | } 139 | inline buffer loop( const buffer &src ) { 140 | return src - floor( src ); 141 | } 142 | inline float sin( float src ) { 143 | float level = loop( src ) * sin_table_size; 144 | float lower = floor( level ); 145 | float higher = ceil( level ); 146 | lower = sin_table[ static_cast< int >( lower ) ]; 147 | higher = sin_table[ static_cast< int >( higher ) % sin_table_size ]; 148 | return interpolate( lower, higher, loop( level ) ); 149 | } 150 | inline buffer sin( const buffer &src ) { 151 | buffer level = loop( src ) * vectorize( sin_table_size ); 152 | buffer lower = floor( level ); 153 | buffer higher = ceil( level ); 154 | for( unsigned int index = 0; index != vector_size; ++index ) { 155 | lower[ index ] = sin_table[ static_cast< int >( lower[ index ] ) ]; 156 | higher[ index ] = sin_table[ static_cast< int >( higher[ index ] ) % sin_table_size ]; 157 | } 158 | return interpolate( lower, higher, loop( level ) ); 159 | } 160 | inline float cos( float src ) { 161 | return sin( src + 0.5f ); 162 | } 163 | inline buffer cos( const buffer &src ) { 164 | return sin( src + vectorize( 0.5f ) ); 165 | } 166 | inline float variable( unsigned int name, float src ) { 167 | float level = loop( src ) * variables_size[ name ]; 168 | float lower = floor( level ); 169 | float higher = ceil( level ); 170 | lower = variables[ name ][ static_cast< int >( lower ) ]; 171 | higher = variables[ name ][ static_cast< int >( higher ) % variables_size[ name ] ]; 172 | return interpolate( lower, higher, loop( level ) ); 173 | } 174 | inline buffer variable( unsigned int name, const buffer &src ) { 175 | buffer level = loop( src ) * vectorize( variables_size[ name ] ); 176 | buffer lower = floor( level ); 177 | buffer higher = ceil( level ); 178 | for( unsigned int index = 0; index != vector_size; ++index ) { 179 | lower[ index ] = variables[ name ][ static_cast< int >( lower[ index ] ) ]; 180 | higher[ index ] = variables[ name ][ static_cast< int >( higher[ index ] ) % variables_size[ name ] ]; 181 | } 182 | return interpolate( lower, higher, loop( level ) ); 183 | } 184 | inline float envelope( float src, float attack, float decay, float sustain, float release ) { 185 | if( src < attack ) 186 | return interpolate( 0.0f, 1.0f, src/attack ); 187 | src -= attack; 188 | if( src < decay ) 189 | return interpolate( 1.0f, sustain, src/decay ); 190 | return sustain; 191 | } 192 | inline buffer envelope( buffer src, buffer attack, buffer decay, buffer sustain, buffer release ) { 193 | buffer result; 194 | for( unsigned int index = 0; index != vector_size; ++index ) { 195 | result[ index ] = envelope( src[ index ], attack[ index ], decay[ index ], sustain[ index ], release[ index ] ); 196 | } 197 | return result; 198 | } 199 | 200 | struct context { 201 | inline buffer operator()() { 202 | buffer time = linear( uniform( 0 ), uniform( 1 ), count() ); 203 | return sin( variable( 2, time ) ); 204 | } 205 | inline float local( unsigned int name ) { 206 | return uniforms[ name ]; 207 | } 208 | float uniforms[ max_locals ]; 209 | buffer result; 210 | }; 211 | 212 | extern "C" void setVariables( unsigned int name, unsigned int size, float *value ) { 213 | variables[ name ] = value; 214 | variables_size[ name ] = size; 215 | } 216 | 217 | extern "C" void setUniform( unsigned int name, float value ) { 218 | uniforms[ name ] =value; 219 | } 220 | 221 | extern "C" void getContextSize( unsigned int *size ) { 222 | *size = sizeof( context ); 223 | } 224 | 225 | extern "C" void createContext( context *inst ) { 226 | } 227 | 228 | extern "C" void destroyContext( context *inst ) { 229 | } 230 | 231 | extern "C" void setLocal( context *ctx, unsigned int name, float value ) { 232 | ctx->uniforms[ name ] =value; 233 | } 234 | 235 | extern "C" void getResult( context *ctx, float *value ) { 236 | ctx->result = (*ctx)(); 237 | for( unsigned int index = 0; index != vector_size; ++index ) { 238 | value[ index ] = ctx->result[ index ]; 239 | } 240 | } 241 | 242 | #include 243 | 244 | int main() { 245 | context *ctx = createContext(); 246 | float final[ 64 ]; 247 | float v[ 64 ]; 248 | for( int index = 0; index != 64; ++index ) 249 | v[ index ] = index; 250 | setVariables( 2, 64, v ); 251 | setUniform( 0, 0.01f ); 252 | setUniform( 1, 0.5f ); 253 | getResult( ctx, final ); 254 | destroyContext( ctx ); 255 | for( int index = 0; index != 64; ++index ) 256 | std::cout << final[ index ] << " "; 257 | std::cout << std::endl; 258 | } 259 | -------------------------------------------------------------------------------- /src/sample1.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #include 29 | #include 30 | 31 | #include 32 | void hoge() { 33 | std::cout << "moo" << std::endl; 34 | } 35 | 36 | int main() { 37 | float a = 5.0f; 38 | 39 | std::string source_code = 40 | "#include \n" 41 | "#include \n" 42 | "void hoge();" 43 | "extern \"C\" void foo( float *a ) {" 44 | " struct jpeg_compress_struct cinfo;" 45 | " std::cout << *a << \" inside\" << std::endl;" 46 | " jpeg_create_compress( &cinfo );" 47 | " *a += 0.1f;" 48 | " hoge();" 49 | "}"; 50 | dcompile::dynamic_compiler dc; 51 | dc.getLoader().enableSystemPath(); 52 | dc.getHeaderPath().enableSystemPath(); 53 | if( !dc.getLoader().load( "jpeg" ) ) { 54 | std::cout << "unable to load libjpeg." << std::endl; 55 | } 56 | else { 57 | // std::cout << dc.dumpLLVM( source_code, dcompile::CXX ) << std::endl; 58 | std::cout << dc.dumpAsm( source_code, dcompile::CXX ) << std::endl; 59 | boost::optional< dcompile::module > lib = dc( source_code, dcompile::CXX ); 60 | if( lib ) { 61 | boost::optional< dcompile::function > foo = lib->getFunction( "foo" ); 62 | if( foo ) 63 | (*foo)( &a ); 64 | } 65 | } 66 | std::cout << a << " outside" << std::endl; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /src/sample2.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #include 29 | #include 30 | 31 | #include 32 | 33 | float hoge() { return 1.0f; } 34 | float a[ 4 ] = { 5.0f, 6.0f, 7.0f, 8.0f }; 35 | int main() { 36 | 37 | 38 | std::string source_code = 39 | "float hoge();" 40 | "extern float a[ 4 ];" 41 | "extern \"C\" void foo() {" 42 | " a[ 0 ] = hoge();" 43 | "}"; 44 | dcompile::dynamic_compiler dc; 45 | std::cout << dc.dumpAsm( source_code, dcompile::CXX ) << std::endl; 46 | dcompile::module lib = dc( source_code, dcompile::CXX ); 47 | boost::optional< dcompile::function > foo = lib.getFunction( "foo" ); 48 | if( foo ) 49 | (*foo)(); 50 | else 51 | std::cout << "no function!" << std::endl; 52 | std::cout << a[0] << " " << a[1] << " " << a[2] << " " << a[3] << std::endl; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /src/sample3.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | 34 | int main() { 35 | float a = 5.0f; 36 | 37 | std::vector< boost::filesystem::path > files; 38 | boost::filesystem::path sample_source_dir( BOOST_PP_STRINGIZE( SAMPLE_SOURCE_DIRECTORY ) ); 39 | files.push_back( sample_source_dir/"hoge.cpp" ); 40 | files.push_back( sample_source_dir/"fuga.cpp" ); 41 | dcompile::dynamic_compiler dc; 42 | dc.getLoader().enableSystemPath(); 43 | dc.getHeaderPath().enableSystemPath(); 44 | dcompile::module lib = dc( files.begin(), files.end() ); 45 | boost::optional< dcompile::function > foo = lib.getFunction( "foo" ); 46 | if( foo ) 47 | (*foo)( &a ); 48 | else 49 | std::cout << "No function!!" << std::endl; 50 | std::cout << a << " outside" << std::endl; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /src/sample4.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | 34 | int main() { 35 | float a = 5.0f; 36 | 37 | boost::filesystem::path sample_source_dir( BOOST_PP_STRINGIZE( SAMPLE_SOURCE_DIRECTORY ) ); 38 | dcompile::dynamic_compiler dc; 39 | dc.getLoader().enableSystemPath(); 40 | dc.getHeaderPath().enableSystemPath(); 41 | std::vector< dcompile::object > objs; 42 | objs.push_back( dc.getObject( sample_source_dir/"hoge.cpp" ) ); 43 | objs.push_back( dc.getObject( sample_source_dir/"fuga.cpp" ) ); 44 | dcompile::module mod = dcompile::load( dcompile::link( objs.begin(), objs.end() ) ); 45 | boost::optional< dcompile::function > foo = mod.getFunction( "foo" ); 46 | if( foo ) 47 | (*foo)( &a ); 48 | else 49 | std::cout << "No function!!" << std::endl; 50 | std::cout << a << " outside" << std::endl; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /src/sample5.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #include 29 | 30 | int main() { 31 | static const char print_code[] = 32 | "#include \n" 33 | "void p( const char *s ) { std::cout << s << std::endl; }"; 34 | static const char foo_code[] = 35 | "void p( const char *s );" 36 | "extern \"C\" void foo() { p( \"foo\" ); }"; 37 | static const char bar_code[] = 38 | "void p( const char *s );" 39 | "extern \"C\" void foo() { p( \"bar\" ); }"; 40 | static const char moo_code[] = 41 | "void p( const char *s );" 42 | "extern \"C\" void foo() { p( \"moo\" ); }"; 43 | static const char *codes[ 3 ] = { foo_code, bar_code, moo_code }; 44 | 45 | dcompile::dynamic_compiler dc; 46 | dc.getLoader().enableSystemPath(); 47 | dc.getHeaderPath().enableSystemPath(); 48 | dcompile::object print = dc.getObject( print_code, dcompile::CXX ); 49 | for( int index = 0; index != 3; ++index ) { 50 | dcompile::object obj = dc.getObject( codes[ index ], dcompile::CXX ); 51 | std::vector< dcompile::object > objs; 52 | objs.push_back( print ); 53 | objs.push_back( obj ); 54 | dcompile::module mod = dcompile::load( dcompile::link( objs.begin(), objs.end() ) ); 55 | boost::optional< dcompile::function > foo = mod.getFunction( "foo" ); 56 | if( foo ) 57 | (*foo)(); 58 | else 59 | std::cout << "No function!!" << std::endl; 60 | } 61 | } 62 | 63 | -------------------------------------------------------------------------------- /src/sample6.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (C) 2012, Naomasa Matsubayashi * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with or without * 6 | * modification, are permitted provided that the following conditions * 7 | * are met: * 8 | * * 9 | * 1. Redistributions of source code must retain the above copyright * 10 | * notice, this list of conditions and the following disclaimer. * 11 | * 2. Redistributions in binary form must reproduce the above copyright * 12 | * notice, this list of conditions and the following disclaimer in the * 13 | * documentation and/or other materials provided with the distribution. * 14 | * * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 25 | * * 26 | *****************************************************************************/ 27 | 28 | #include 29 | #include 30 | 31 | #include 32 | 33 | void eval( int *count, const char *str ) { 34 | dcompile::dynamic_compiler dc; 35 | boost::optional< dcompile::module > lib = dc( str, dcompile::CXX ); 36 | if( lib ) { 37 | boost::optional< dcompile::function > foo = lib->getFunction( "foo" ); 38 | if( foo ) 39 | (*foo)( count, str ); 40 | } 41 | } 42 | int main() { 43 | int count = 5; 44 | std::string source_code = 45 | "void eval( int *, const char * );" 46 | "extern \"C\" void foo( int *count, const char *str ) {" 47 | " --*count;" 48 | " if( *count )" 49 | " eval( count, str );" 50 | "}"; 51 | eval( &count, source_code.c_str() ); 52 | std::cout << count << std::endl; 53 | } 54 | 55 | --------------------------------------------------------------------------------