Kagome
Polkadot Runtime Engine in C++17
module.cpp
Go to the documentation of this file.
1 
7 
8 #include <WAVM/Runtime/Linker.h>
9 #include <WAVM/Runtime/Runtime.h>
10 #include <WAVM/WASM/WASM.h>
11 #include <boost/assert.hpp>
12 
20 
21 namespace kagome::runtime::wavm {
22 
23  std::unique_ptr<ModuleImpl> ModuleImpl::compileFrom(
24  std::shared_ptr<CompartmentWrapper> compartment,
25  ModuleParams &module_params,
26  std::shared_ptr<IntrinsicModule> intrinsic_module,
27  std::shared_ptr<const InstanceEnvironmentFactory> env_factory,
28  gsl::span<const uint8_t> code,
29  const common::Hash256 &code_hash) {
30  std::shared_ptr<WAVM::Runtime::Module> module = nullptr;
31  WAVM::WASM::LoadError loadError;
32  WAVM::IR::FeatureSpec featureSpec;
33 
34  log::Logger logger = log::createLogger("WAVM Module", "wavm");
35  logger->info(
36  "Compiling WebAssembly module for Runtime (going to take a few dozens "
37  "of seconds)");
38  if (!WAVM::Runtime::loadBinaryModule(
39  code.data(), code.size(), module, featureSpec, &loadError)) {
40  logger->critical("Error loading WAVM binary module: {}",
41  loadError.message);
42  return nullptr;
43  }
44 
45  auto imports = WAVM::Runtime::getModuleIR(module).memories.imports;
46  if (not imports.empty()) {
47  module_params.intrinsicMemoryType = imports[0].type;
48  }
49  intrinsic_module = std::make_shared<IntrinsicModule>(
50  *intrinsic_module, module_params.intrinsicMemoryType);
51  runtime::wavm::registerHostApiMethods(*intrinsic_module);
52 
53  return std::unique_ptr<ModuleImpl>(
54  new ModuleImpl{std::move(compartment),
55  std::move(intrinsic_module),
56  std::move(env_factory),
57  std::move(module),
58  code_hash});
59  }
60 
62  std::shared_ptr<CompartmentWrapper> compartment,
63  std::shared_ptr<const IntrinsicModule> intrinsic_module,
64  std::shared_ptr<const InstanceEnvironmentFactory> env_factory,
65  std::shared_ptr<WAVM::Runtime::Module> module,
66  const common::Hash256 &code_hash)
67  : env_factory_{std::move(env_factory)},
68  compartment_{std::move(compartment)},
69  intrinsic_module_{std::move(intrinsic_module)},
70  module_{std::move(module)},
71  code_hash_(code_hash),
72  logger_{log::createLogger("WAVM Module", "wavm")} {
73  BOOST_ASSERT(compartment_);
74  BOOST_ASSERT(env_factory_);
75  BOOST_ASSERT(intrinsic_module_);
76  BOOST_ASSERT(module_);
77  }
78 
79  outcome::result<std::shared_ptr<ModuleInstance>> ModuleImpl::instantiate()
80  const {
81  const auto &ir_module = WAVM::Runtime::getModuleIR(module_);
82  bool imports_memory =
83  std::find_if(ir_module.imports.cbegin(),
84  ir_module.imports.cend(),
85  [](auto &import) {
86  return import.kind == WAVM::IR::ExternKind::memory;
87  })
88  != ir_module.imports.cend();
89  auto memory_origin =
92 
93  auto new_intrinsic_module_instance =
94  std::shared_ptr<IntrinsicModuleInstance>(
95  intrinsic_module_->instantiate());
96 
97  auto resolver =
98  std::make_shared<IntrinsicResolverImpl>(new_intrinsic_module_instance);
99 
100  auto internal_instance =
101  WAVM::Runtime::instantiateModule(compartment_->getCompartment(),
102  module_,
103  link(*resolver),
104  "runtime_module");
105 
106  auto env = env_factory_->make(
107  memory_origin, internal_instance, new_intrinsic_module_instance);
108 
109  auto instance = std::make_shared<ModuleInstanceImpl>(
110  std::move(env), internal_instance, module_, compartment_, code_hash_);
111 
112  return instance;
113  }
114 
116  IntrinsicResolver &resolver) const {
117  auto &ir_module = WAVM::Runtime::getModuleIR(module_);
118 
119  auto link_result = WAVM::Runtime::linkModule(ir_module, resolver);
120  if (!link_result.success) {
121  logger_->error("Failed to link module:");
122  for (auto &import : link_result.missingImports) {
123  logger_->error("\t{}::{}: {}",
124  import.moduleName,
125  import.exportName,
126  WAVM::IR::asString(import.type));
127  }
128  throw std::runtime_error("Failed to link module");
129  }
130  return link_result.resolvedImports;
131  }
132 
133 } // namespace kagome::runtime::wavm
std::vector< Object * > ImportBindings
Definition: module.hpp:20
ModuleImpl(std::shared_ptr< CompartmentWrapper > compartment, std::shared_ptr< const IntrinsicModule > intrinsic_module, std::shared_ptr< const InstanceEnvironmentFactory > env_factory, std::shared_ptr< WAVM::Runtime::Module > module, const common::Hash256 &code_hash)
Definition: module.cpp:61
outcome::result< std::shared_ptr< ModuleInstance > > instantiate() const override
Definition: module.cpp:79
WAVM::Runtime::ImportBindings link(IntrinsicResolver &resolver) const
Definition: module.cpp:115
Global parameters for module instantiation. Currently contains only memory type that may be changed o...
WAVM::IR::MemoryType intrinsicMemoryType
std::shared_ptr< soralog::Logger > Logger
Definition: logger.hpp:23
static std::unique_ptr< ModuleImpl > compileFrom(std::shared_ptr< CompartmentWrapper > compartment, ModuleParams &module_params, std::shared_ptr< IntrinsicModule > intrinsic_module, std::shared_ptr< const InstanceEnvironmentFactory > env_factory, gsl::span< const uint8_t > code, const common::Hash256 &code_hash)
Definition: module.cpp:23
std::shared_ptr< const InstanceEnvironmentFactory > env_factory_
Definition: module.hpp:53
std::shared_ptr< CompartmentWrapper > compartment_
Definition: module.hpp:54
Logger createLogger(const std::string &tag)
Definition: logger.cpp:112
std::shared_ptr< const IntrinsicModule > intrinsic_module_
Definition: module.hpp:55
std::shared_ptr< WAVM::Runtime::Module > module_
Definition: module.hpp:56
void registerHostApiMethods(IntrinsicModule &module)
const common::Hash256 code_hash_
Definition: module.hpp:57