#ifndef PKMNLIB_WEBASSEMBLYFUNCTIONCALL_H #define PKMNLIB_WEBASSEMBLYFUNCTIONCALL_H #include #include #include #include "wasm.h" template class WebAssemblyFunctionCall { public: WebAssemblyFunctionCall(const ArbUt::BorrowedPtr& func) : _func(func) {} NO_COPY_OR_MOVE(WebAssemblyFunctionCall) void Call() { wasm_val_vec_t args = {argsCount, _arguments.Data}; wasm_val_vec_t results; if constexpr (returnsCount > 0) { results = {returnsCount, _results.Data}; } else { results = WASM_EMPTY_VEC; } auto* result = wasm_func_call(_func, &args, &results); if (result != nullptr) { wasm_message_t retrieved_message; wasm_trap_message(result, &retrieved_message); auto msg = std::string(retrieved_message.data, retrieved_message.size); THROW(msg); } } inline void Loadi32(size_t index, i32 value) { _arguments.Data[index] = WASM_I32_VAL(value); } inline void Loadi64(size_t index, i64 value) { _arguments.Data[index] = WASM_I64_VAL(value); } inline void Loadf32(size_t index, f32 value) { _arguments.Data[index] = WASM_F32_VAL(value); } inline void Loadf64(size_t index, f64 value) { _arguments.Data[index] = WASM_F64_VAL(value); } template inline void LoadExternRef(size_t index, T* value) { _arguments.Data[index] = WASM_I64_VAL(reinterpret_cast(value)); } [[nodiscard]] inline i32 GetResultAsi32() const { if constexpr (returnsCount > 0) { Ensure(_results.Data[0].kind == WASM_I32); return _results.Data[0].of.i32; } else { return 0; } } [[nodiscard]] inline i64 GetResultAsi64() const { if constexpr (returnsCount > 0) { Ensure(_results.Data[0].kind == WASM_I64); return _results.Data[0].of.i64; } else { return 0; } } [[nodiscard]] inline f32 GetResultAsf32() const { if constexpr (returnsCount > 0) { Ensure(_results.Data[0].kind == WASM_F32); return _results.Data[0].of.f32; } else { return 0; } } [[nodiscard]] inline f64 GetResultAsf64() const { if constexpr (returnsCount > 0) { Ensure(_results.Data[0].kind == WASM_F64); return _results.Data[0].of.f64; } else { return 0; } } template [[nodiscard]] inline T* GetResultAsExternRef() const { if constexpr (returnsCount > 0) { Ensure(_results.Data[0].kind == WASM_ANYREF); return reinterpret_cast(_results.Data[0].of.i64); } else { return 0; } } inline const wasm_val_t* GetRawResults() const { if constexpr (returnsCount > 0) { return _results.Data; } else { return 0; } } private: ArbUt::BorrowedPtr _func; struct Empty {}; template struct NonEmpty { wasm_val_t Data[size]; }; typedef typename std::conditional>::type args_t; typedef typename std::conditional>::type result_t; args_t _arguments; result_t _results; }; #endif // PKMNLIB_WEBASSEMBLYFUNCTIONCALL_H