Spicy
jit.h
1 // Copyright (c) 2020-2021 by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <iostream>
6 #include <map>
7 #include <memory>
8 #include <string>
9 #include <utility>
10 #include <vector>
11 
12 #include <hilti/rt/filesystem.h>
13 #include <hilti/rt/library.h>
14 
15 #include <hilti/base/util.h>
16 #include <hilti/compiler/context.h>
17 #include <hilti/compiler/detail/cxx/unit.h>
18 
19 namespace reproc {
20 class process;
21 }
22 
23 namespace hilti {
24 
25 namespace logging::debug {
26 inline const DebugStream Jit("jit");
27 } // namespace logging::debug
28 
29 namespace detail::jit {
30 class Cxx;
31 } // namespace detail::jit
32 
34 class CxxCode {
35 public:
41  CxxCode(const hilti::rt::filesystem::path& path) { load(path); }
42 
49  CxxCode(const std::string& id, std::istream& code) { load(id, code); }
50 
56  explicit CxxCode(const detail::cxx::Unit& u);
57 
64  bool save(const hilti::rt::filesystem::path& p) const;
65 
72  bool save(std::ostream& out) const;
73 
75  auto code() const { return _code; }
76 
78  auto isLoaded() const { return _code.has_value(); }
79 
85  const std::string& id() const { return _id; }
86 
88  std::size_t hash() const { return _hash; }
89 
90 protected:
97  bool load(const hilti::rt::filesystem::path& path);
98 
106  bool load(const std::string& id, std::istream& in);
107 
108 private:
109  std::string _id;
110  std::optional<std::string> _code;
111  std::size_t _hash = 0;
112 };
113 
114 using hilti::rt::Library;
115 
122 class JIT {
123 public:
128  explicit JIT(const std::shared_ptr<Context>& context, bool dump_code = false);
129  ~JIT();
130 
131  JIT() = delete;
132  JIT(const JIT&) = delete;
133  JIT(JIT&&) noexcept = delete;
134  JIT& operator=(const JIT&) = delete;
135  JIT& operator=(JIT&&) noexcept = delete;
136 
143  void add(CxxCode d);
144 
151  void add(const hilti::rt::filesystem::path& p);
152 
157  bool hasInputs() { return _codes.size() || _files.size(); }
158 
165 
167  auto context() const { return _context.lock(); }
168 
170  auto options() const { return context()->options(); }
171 
172 private:
173  // Check if we have a working compiler.
174  hilti::Result<Nothing> _checkCompiler();
175 
176  // Compile C++ to object files.
177  hilti::Result<Nothing> _compile();
178 
179  // Link object files into shared library.
181 
182  // Clean up after compilation.
183  void _finish();
184 
185  using JobID = uint64_t;
186  Result<JobID> _spawnJob(const hilti::rt::filesystem::path& cmd, std::vector<std::string> args);
187  Result<Nothing> _waitForJobs();
188 
189  std::weak_ptr<Context> _context; // global context for options
190  bool _dump_code; // save all C++ code for debugging
191 
192  std::vector<hilti::rt::filesystem::path> _files; // all added source files
193  std::vector<CxxCode> _codes; // all C++ code units to be compiled
194  std::vector<hilti::rt::filesystem::path> _objects;
195 
196  struct Job {
197  std::unique_ptr<reproc::process> process;
198  std::string stdout_;
199  std::string stderr_;
200 
201  void collectOutputs(int events);
202  };
203 
204  JobID _job_counter = 0;
205  std::map<JobID, Job> _jobs;
206 
207  std::size_t _hash;
208 };
209 
210 } // namespace hilti
auto context() const
Definition: jit.h:167
const std::string & id() const
Definition: jit.h:85
CxxCode(const hilti::rt::filesystem::path &path)
Definition: jit.h:41
Definition: jit.h:19
CxxCode(const std::string &id, std::istream &code)
Definition: jit.h:49
Definition: unit.h:68
Definition: jit.h:122
Definition: library.h:61
bool hasInputs()
Definition: jit.h:157
auto code() const
Definition: jit.h:75
Definition: jit.h:34
std::size_t hash() const
Definition: jit.h:88
auto options() const
Definition: jit.h:170
Definition: result.h:67
auto isLoaded() const
Definition: jit.h:78