#ifndef PKMNLIB_WEBASSEMBLYSCRIPTRESOLVER_HPP #define PKMNLIB_WEBASSEMBLYSCRIPTRESOLVER_HPP #include #include #include #include #include "../../Battling/Library/ScriptResolver.hpp" #include "WebAssemblyBattleScript.hpp" #include "WebAssemblyFunctionCall.hpp" #include "WebAssemblyScriptCapabilities.hpp" class WebAssemblyScriptResolver : public PkmnLib::Battling::ScriptResolver { public: WebAssemblyScriptResolver(); ~WebAssemblyScriptResolver(); u8 LoadWasmFromFile(const std::string& path); u8 LoadWasmFromBytes(std::vector); u8 LoadWatFromString(const std::string& data); void RegisterFunction(); void Finalize(); template inline std::optional> GetFunction(const ArbUt::StringView& name) const { auto res = _exportedFunctions.TryGet(name); if (!res.has_value()) { return {}; } return std::make_optional>( ArbUt::BorrowedPtr(res.value())); } std::pair AllocateMemory(u32 size, u32 align) const { auto funcOpt = GetFunction<2, 1>("allocate_mem"); auto& func = funcOpt.value(); func.Loadi32(0, size); func.Loadi32(1, align); func.Call(); auto memoryOffset = func.GetResultAsi32(); return std::make_pair(reinterpret_cast(wasm_memory_data(_memory) + memoryOffset), memoryOffset); } [[nodiscard]] inline wasm_memory_t* GetMemory() const noexcept { return _memory; } ArbUt::OptionalUniquePtr LoadScript(const ArbUt::OptionalBorrowedPtr& owner, ScriptCategory category, const ArbUt::StringView& scriptName) nullable override; [[nodiscard]] inline wasm_store_t* GetStore() const noexcept { return _store; } inline void RemoveRegisteredScript(i32 wasmPtr) { _loadedScripts.Remove(wasmPtr); } template inline void MarkLoadedPointer(T* ptr){ _loadedPointers.Set((void*)ptr, typeid(T)); } template inline bool ValidateLoadedPointer(void* ptr){ const auto& opt = _loadedPointers.TryGet(ptr); return opt.has_value() && opt.value() == typeid(T); } private: wasm_engine_t* _engine; wasm_store_t* _store; wasm_module_t* _module = nullptr; wasm_instance_t* _instance = nullptr; wasm_memory_t* _memory = nullptr; ArbUt::Dictionary _imports; wasm_extern_vec_t _exports = {0, nullptr}; ArbUt::Dictionary _exportedFunctions; ArbUt::Dictionary _loadedScripts; void RegisterDefaultMethods(); typedef std::pair scriptCapabilitiesKey; struct pair_hash { template std::size_t operator()(const std::pair& pair) const { return std::hash()(pair.first) ^ std::hash()(pair.second); } }; std::unordered_map, pair_hash> _scriptCapabilities; ArbUt::Dictionary _loadedPointers; }; #endif // PKMNLIB_WEBASSEMBLYSCRIPTRESOLVER_HPP