github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/jit/cpp_ir.cpp (about) 1 // Copyright (C) 2018 go-nebulas authors 2 // 3 // This file is part of the go-nebulas library. 4 // 5 // the go-nebulas library is free software: you can redistribute it and/or 6 // modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation, either version 3 of the License, or 9 // (at your option) any later version. 10 // 11 // the go-nebulas library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with the go-nebulas library. If not, see 18 // <http://www.gnu.org/licenses/>. 19 // 20 #include "jit/cpp_ir.h" 21 #include "fs/util.h" 22 #include "util/chrono.h" 23 24 namespace neb { 25 namespace cpp { 26 std::atomic_int cpp_ir::s_file_counter(1); 27 28 cpp_ir::cpp_ir(const cpp_t &cpp) 29 : m_name_version(cpp.first), m_cpp_content(cpp.second), 30 m_b_got_error(false) {} 31 32 neb::bytes cpp_ir::llvm_ir_content() { 33 if (m_llvm_ir_fp == std::string("") && !m_b_got_error) { 34 35 std::string fp_base = generate_fp() + '_' + m_name_version; 36 std::string cpp_fp = fp_base + ".cpp"; 37 std::string ir_fp = fp_base + ".bc"; 38 m_cpp_fp = cpp_fp; 39 m_llvm_ir_fp = ir_fp; 40 41 std::ofstream ofp(cpp_fp); 42 ofp.write(m_cpp_content.c_str(), m_cpp_content.size()); 43 ofp.close(); 44 auto ret = make_ir_bitcode(cpp_fp, ir_fp); 45 if (ret != 0) { 46 m_b_got_error = true; 47 } 48 } 49 if (m_b_got_error) { 50 return neb::bytes(); 51 } 52 if (!::neb::fs::exists(m_llvm_ir_fp)) { 53 return neb::bytes(); 54 } 55 56 std::ifstream ifs; 57 ifs.open(m_llvm_ir_fp.c_str(), std::ios::in | std::ios::binary); 58 if (!ifs.is_open()) 59 return neb::bytes(); 60 ifs.seekg(0, ifs.end); 61 std::ifstream::pos_type size = ifs.tellg(); 62 neb::bytes buf(size); 63 ifs.seekg(0, ifs.beg); 64 ifs.read((char *)buf.value(), buf.size()); 65 ifs.close(); 66 return buf; 67 } 68 std::string cpp_ir::generate_fp() { 69 std::string temp_path = neb::fs::tmp_dir(); 70 71 std::string name = std::to_string(util::now()) + std::string("_") + 72 std::to_string(s_file_counter); 73 auto t = 74 neb::fs::join_path(neb::configuration::instance().nbre_db_dir(), name); 75 s_file_counter++; 76 return t; 77 } 78 79 int cpp_ir::make_ir_bitcode(const std::string &cpp_file, 80 const std::string &ir_bc_file) { 81 int result = -1; 82 83 std::string nbre_path = ::neb::configuration::instance().nbre_root_dir(); 84 std::string command_string( 85 neb::fs::join_path(nbre_path, "lib_llvm/bin/clang") + 86 " -O2 -c -emit-llvm "); 87 88 std::string include_string = 89 std::string("-I") + 90 neb::fs::join_path(::neb::configuration::instance().nbre_root_dir(), 91 "lib/include") + 92 std::string(" "); 93 94 command_string += include_string + " -o " + ir_bc_file; 95 command_string += std::string(" ") + cpp_file; 96 std::cout << command_string << std::endl; 97 LOG(INFO) << command_string; 98 99 result = util::command_executor::execute_command(command_string); 100 if (result != 0) { 101 LOG(ERROR) << "error: executed by boost::process::system."; 102 LOG(ERROR) << "result code = " << result; 103 return -1; 104 } 105 return 0; 106 } 107 108 } // namespace cpp 109 } // namespace neb