8 #include <WAVM/Runtime/Runtime.h> 9 #include <WAVM/RuntimeABI/RuntimeABI.h> 21 WAVM::IR::InitializerExpression expression) {
22 using WAVM::IR::InitializerExpression;
23 switch (expression.type) {
24 case InitializerExpression::Type::i32_const:
25 return expression.i32;
26 case InitializerExpression::Type::i64_const:
27 return expression.i64;
28 case InitializerExpression::Type::f32_const:
29 return expression.f32;
30 case InitializerExpression::Type::f64_const:
31 return expression.f64;
32 case InitializerExpression::Type::v128_const:
33 return expression.v128;
34 case InitializerExpression::Type::global_get: {
35 throw std::runtime_error{
"Not implemented on WAVM yet"};
37 case InitializerExpression::Type::ref_null:
38 return WAVM::IR::Value(asValueType(expression.nullReferenceType),
39 WAVM::IR::UntaggedValue());
41 case InitializerExpression::Type::ref_func:
45 case InitializerExpression::Type::invalid:
52 WAVM::IR::IndexType indexType) {
54 case WAVM::IR::IndexType::i32:
55 WAVM_ASSERT(value.type == WAVM::IR::ValueType::i32);
57 case WAVM::IR::IndexType::i64:
58 WAVM_ASSERT(value.type == WAVM::IR::ValueType::i64);
70 case E::WRONG_ARG_COUNT:
71 return "The provided function argument count should equal to 2";
72 case E::FUNC_NOT_FOUND:
73 return "The requested function not found";
74 case E::EXECUTION_ERROR:
75 return "An error occurred during wasm call execution; Check the logs for " 77 case E::WRONG_RETURN_TYPE:
78 return "Runtime function returned result of unsupported type";
80 return "Unknown error in ModuleInstance";
87 WAVM::Runtime::GCPointer<WAVM::Runtime::Instance> instance,
88 WAVM::Runtime::ModuleRef module,
89 std::shared_ptr<const CompartmentWrapper> compartment,
91 : env_{std::move(
env)},
99 BOOST_ASSERT(
module_ !=
nullptr);
106 PtrSize args_span{memory.get().storeBuffer(encoded_args)};
108 auto res = [
this, name, args_span]() -> outcome::result<PtrSize> {
109 WAVM::Runtime::GCPointer<WAVM::Runtime::Context> context =
110 WAVM::Runtime::createContext(
compartment_->getCompartment());
111 WAVM::Runtime::Function *
function = WAVM::Runtime::asFunctionNullable(
112 WAVM::Runtime::getInstanceExport(
instance_, name.data()));
114 SL_DEBUG(
logger_,
"The requested function {} not found", name);
117 const WAVM::IR::FunctionType functionType =
118 WAVM::Runtime::getFunctionType(
function);
119 if (functionType.params().size() != 2) {
122 "The provided function argument count should equal to 2, got {} " 124 functionType.params().size());
127 WAVM_ASSERT(
function)
129 WAVM::IR::TypeTuple invokeArgTypes{WAVM::IR::ValueType::i32,
130 WAVM::IR::ValueType::i32};
133 const WAVM::IR::FunctionType invokeSig(
134 WAVM::Runtime::getFunctionType(
function).results(),
135 std::move(invokeArgTypes));
137 BOOST_ASSERT(invokeSig.results().size() == 1);
138 std::array<WAVM::IR::UntaggedValue, 1> untaggedInvokeResults;
140 std::const_pointer_cast<ModuleInstanceImpl>(shared_from_this()));
143 WAVM::Runtime::unwindSignalsAsExceptions(
148 resultsDestination = untaggedInvokeResults.data()] {
149 std::array<WAVM::IR::UntaggedValue, 2> untaggedInvokeArgs{
150 static_cast<WAVM::U32
>(args.ptr),
151 static_cast<WAVM::U32>(args.size)};
152 WAVM::Runtime::invokeFunction(context,
155 untaggedInvokeArgs.data(),
158 return PtrSize{untaggedInvokeResults[0].u64};
159 }
catch (WAVM::Runtime::Exception *e) {
160 const auto desc = WAVM::Runtime::describeException(e);
162 WAVM::Runtime::destroyException(e);
166 WAVM::Runtime::collectCompartmentGarbage(
compartment_->getCompartment());
171 std::string_view name)
const {
172 auto global = WAVM::Runtime::asGlobalNullable(
173 WAVM::Runtime::getInstanceExport(
instance_, name.data()));
174 if (global ==
nullptr)
return std::nullopt;
175 WAVM::Runtime::GCPointer<WAVM::Runtime::Context> context =
176 WAVM::Runtime::createContext(
compartment_->getCompartment());
177 auto value = WAVM::Runtime::getGlobalValue(context, global);
178 switch (value.type) {
179 case WAVM::IR::ValueType::i32:
180 return WasmValue{
static_cast<int32_t
>(value.i32)};
181 case WAVM::IR::ValueType::i64:
182 return WasmValue{
static_cast<int64_t
>(value.i64)};
183 case WAVM::IR::ValueType::f32:
184 return WasmValue{
static_cast<float>(value.f32)};
185 case WAVM::IR::ValueType::f64:
186 return WasmValue{
static_cast<double>(value.f64)};
189 "Runtime function returned result of unsupported type: {}",
198 using WAVM::IR::DataSegment;
199 using WAVM::IR::MemoryType;
200 using WAVM::IR::Value;
201 auto ir = getModuleIR(
module_);
203 for (Uptr segmentIndex = 0; segmentIndex < ir.dataSegments.size();
205 const DataSegment &dataSegment = ir.dataSegments[segmentIndex];
206 if (dataSegment.isActive) {
207 const Value baseOffsetValue =
209 const MemoryType &memoryType =
210 ir.memories.getType(dataSegment.memoryIndex);
211 Uptr baseOffset =
getIndexValue(baseOffsetValue, memoryType.indexType);
212 callback(baseOffset, *dataSegment.data);
223 return outcome::success();
std::function< void(SegmentOffset, SegmentData)> DataSegmentProcessor
void popBorrowedRuntimeInstance()
InstanceEnvironment const & getEnvironment() const override
static WAVM::IR::Value evaluateInitializer(WAVM::IR::InitializerExpression expression)
common::Hash256 code_hash_
static const wasm::Name env
static WAVM::Uptr getIndexValue(const WAVM::IR::Value &value, WAVM::IR::IndexType indexType)
outcome::result< PtrSize > callExportFunction(std::string_view name, common::BufferView encoded_args) const override
void forDataSegment(DataSegmentProcessor const &callback) const override
std::shared_ptr< const CompartmentWrapper > compartment_
std::shared_ptr< MemoryProvider > memory_provider
ModuleInstanceImpl(InstanceEnvironment &&env, WAVM::Runtime::GCPointer< WAVM::Runtime::Instance > instance, WAVM::Runtime::ModuleRef module, std::shared_ptr< const CompartmentWrapper > compartment, const common::Hash256 &code_hash)
boost::variant< int32_t, int64_t, float, double > WasmValue
std::shared_ptr< host_api::HostApi > host_api
WAVM::Runtime::ModuleRef module_
WAVM::Runtime::GCPointer< WAVM::Runtime::Instance > instance_
OUTCOME_CPP_DEFINE_CATEGORY(kagome::runtime::wavm, ModuleInstanceImpl::Error, e)
Logger createLogger(const std::string &tag)
outcome::result< void > resetEnvironment() override
outcome::result< std::optional< WasmValue > > getGlobal(std::string_view name) const override
void pushBorrowedRuntimeInstance(std::shared_ptr< ModuleInstance > borrowed_runtime_instance)