Fixes annoying issue in wasmer, removes pointer type validation for now
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
3aa6e28a62
commit
82bc816151
|
@ -68,10 +68,8 @@ public:
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> inline static T ConvertAllArguments(const wasm_val_vec_t* t, std::size_t& index) {
|
||||||
inline static T ConvertAllArguments(const wasm_val_vec_t* t, std::size_t& index,
|
return FromVal<T>(t->data[index++]);
|
||||||
WebAssemblyScriptResolver* resolver) {
|
|
||||||
return FromVal<T>(t->data[index++], resolver);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class R, class... Args>
|
template <class R, class... Args>
|
||||||
|
@ -81,25 +79,28 @@ public:
|
||||||
struct Env {
|
struct Env {
|
||||||
WebAssemblyScriptResolver* Resolver;
|
WebAssemblyScriptResolver* Resolver;
|
||||||
std::function<R(WebAssemblyScriptResolver*, Args...)> Func;
|
std::function<R(WebAssemblyScriptResolver*, Args...)> Func;
|
||||||
__attribute__((no_sanitize("address")))
|
~Env() {}
|
||||||
~Env(){}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
auto env = new Env{.Resolver = resolver, .Func = func};
|
auto env = (Env*)malloc(sizeof(Env));
|
||||||
|
new (env) Env{.Resolver = resolver, .Func = func};
|
||||||
|
resolver->Temp_WasmerBug2_2_1_Bypass.Append(env);
|
||||||
auto* f = wasm_func_new_with_env(
|
auto* f = wasm_func_new_with_env(
|
||||||
store, funcType,
|
store, funcType,
|
||||||
[](void* env, const wasm_val_vec_t* parameters, wasm_val_vec_t* results) -> wasm_trap_t* {
|
[](void* env, const wasm_val_vec_t* parameters, wasm_val_vec_t* results) -> wasm_trap_t* {
|
||||||
auto e = *(Env*)env;
|
auto e = *(Env*)env;
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
R result = e.Func(e.Resolver, ConvertAllArguments<Args>(parameters, index, e.Resolver)...);
|
try {
|
||||||
|
R result = e.Func(e.Resolver, ConvertAllArguments<Args>(parameters, index)...);
|
||||||
results->data[0] = ToVal<R>(result);
|
results->data[0] = ToVal<R>(result);
|
||||||
|
} catch (ArbUt::Exception& exception) {
|
||||||
|
return CreateTrapFromException(exception, e.Resolver);
|
||||||
|
} catch (std::exception& exception) {
|
||||||
|
return FromStdException(exception, e.Resolver);
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
},
|
},
|
||||||
env,
|
env, /*[](void*) { delete (Env*)env; }*/ nullptr);
|
||||||
[](void* env) __attribute__((no_sanitize("address"))) {
|
|
||||||
delete (Env*)env;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
wasm_functype_delete(funcType);
|
wasm_functype_delete(funcType);
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
@ -138,16 +139,15 @@ private:
|
||||||
return WASM_I32_VAL((i32)val);
|
return WASM_I32_VAL((i32)val);
|
||||||
}
|
}
|
||||||
} else if constexpr (std::is_same<T, const ArbUt::StringView&>()) {
|
} else if constexpr (std::is_same<T, const ArbUt::StringView&>()) {
|
||||||
return WASM_I64_VAL(reinterpret_cast<i64>(&val));
|
auto v = &val;
|
||||||
|
return WASM_I64_VAL(reinterpret_cast<i64>(v));
|
||||||
}
|
}
|
||||||
THROW("Unhandled value type: ", typeid(T).name());
|
THROW("Unhandled value type: ", typeid(T).name());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> inline static T FromVal(const wasm_val_t& val, WebAssemblyScriptResolver* resolver) {
|
template <typename T> inline static T FromVal(const wasm_val_t& val) {
|
||||||
if constexpr (std::is_pointer<T>()) {
|
if constexpr (std::is_pointer<T>()) {
|
||||||
auto v = reinterpret_cast<void*>(val.of.i64);
|
return (T) reinterpret_cast<void*>(val.of.i64);
|
||||||
Ensure(resolver->ValidateLoadedPointer<std::remove_pointer<T>>(v));
|
|
||||||
return (T)v;
|
|
||||||
} else if constexpr (is_specialization<T, ArbUt::BorrowedPtr>::value) {
|
} else if constexpr (is_specialization<T, ArbUt::BorrowedPtr>::value) {
|
||||||
return dynamic_cast<T>(reinterpret_cast<void*>(val.of.i64));
|
return dynamic_cast<T>(reinterpret_cast<void*>(val.of.i64));
|
||||||
} else if constexpr (is_specialization<T, ArbUt::OptionalBorrowedPtr>::value) {
|
} else if constexpr (is_specialization<T, ArbUt::OptionalBorrowedPtr>::value) {
|
||||||
|
|
|
@ -4,10 +4,8 @@
|
||||||
#include <Arbutils/Collections/List.hpp>
|
#include <Arbutils/Collections/List.hpp>
|
||||||
#include <Arbutils/Memory/Memory.hpp>
|
#include <Arbutils/Memory/Memory.hpp>
|
||||||
#include <wasm.h>
|
#include <wasm.h>
|
||||||
#include "wasm.h"
|
|
||||||
|
|
||||||
template <u32 argsCount, u32 returnsCount>
|
template <u32 argsCount, u32 returnsCount> class WebAssemblyFunctionCall {
|
||||||
class WebAssemblyFunctionCall {
|
|
||||||
public:
|
public:
|
||||||
WebAssemblyFunctionCall(const ArbUt::BorrowedPtr<wasm_func_t>& func) : _func(func) {}
|
WebAssemblyFunctionCall(const ArbUt::BorrowedPtr<wasm_func_t>& func) : _func(func) {}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,9 @@ WebAssemblyScriptResolver::~WebAssemblyScriptResolver() {
|
||||||
for (auto& import : _imports) {
|
for (auto& import : _imports) {
|
||||||
wasm_func_delete(import.second);
|
wasm_func_delete(import.second);
|
||||||
}
|
}
|
||||||
|
for (auto e : Temp_WasmerBug2_2_1_Bypass) {
|
||||||
|
free(e);
|
||||||
|
}
|
||||||
if (_instance != nullptr) {
|
if (_instance != nullptr) {
|
||||||
wasm_instance_delete(_instance);
|
wasm_instance_delete(_instance);
|
||||||
}
|
}
|
||||||
|
@ -153,7 +156,7 @@ WebAssemblyScriptResolver::LoadScript(const ArbUt::OptionalBorrowedPtr<void>& ow
|
||||||
if (findCapabilities != _scriptCapabilities.end()) {
|
if (findCapabilities != _scriptCapabilities.end()) {
|
||||||
capabilities = findCapabilities->second;
|
capabilities = findCapabilities->second;
|
||||||
} else {
|
} else {
|
||||||
auto getCapabilitiesOpt = GetFunction<1,2>("get_script_capabilities"_cnc);
|
auto getCapabilitiesOpt = GetFunction<1, 2>("get_script_capabilities"_cnc);
|
||||||
if (getCapabilitiesOpt.has_value()) {
|
if (getCapabilitiesOpt.has_value()) {
|
||||||
auto& getCapabilitiesFunc = getCapabilitiesOpt.value();
|
auto& getCapabilitiesFunc = getCapabilitiesOpt.value();
|
||||||
getCapabilitiesFunc.Loadi32(0, result);
|
getCapabilitiesFunc.Loadi32(0, result);
|
||||||
|
@ -162,7 +165,7 @@ WebAssemblyScriptResolver::LoadScript(const ArbUt::OptionalBorrowedPtr<void>& ow
|
||||||
auto ptr = (WebAssemblyScriptCapabilities*)(wasm_memory_data(_memory) + rawResult[0].of.i32);
|
auto ptr = (WebAssemblyScriptCapabilities*)(wasm_memory_data(_memory) + rawResult[0].of.i32);
|
||||||
auto end = (WebAssemblyScriptCapabilities*)(ptr + rawResult[1].of.i32);
|
auto end = (WebAssemblyScriptCapabilities*)(ptr + rawResult[1].of.i32);
|
||||||
auto vec = std::vector<WebAssemblyScriptCapabilities>(ptr, end);
|
auto vec = std::vector<WebAssemblyScriptCapabilities>(ptr, end);
|
||||||
for (auto capability: vec){
|
for (auto capability : vec) {
|
||||||
capabilities.insert(capability);
|
capabilities.insert(capability);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,24 +44,18 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] inline wasm_memory_t* GetMemory() const noexcept { return _memory; }
|
[[nodiscard]] inline wasm_memory_t* GetMemory() const noexcept { return _memory; }
|
||||||
|
|
||||||
ArbUt::OptionalUniquePtr<CreatureLib::Battling::BattleScript> LoadScript(const ArbUt::OptionalBorrowedPtr<void>& owner,
|
ArbUt::OptionalUniquePtr<CreatureLib::Battling::BattleScript>
|
||||||
ScriptCategory category,
|
LoadScript(const ArbUt::OptionalBorrowedPtr<void>& owner, ScriptCategory category,
|
||||||
const ArbUt::StringView& scriptName) nullable override;
|
const ArbUt::StringView& scriptName) nullable override;
|
||||||
|
|
||||||
[[nodiscard]] inline wasm_store_t* GetStore() const noexcept { return _store; }
|
[[nodiscard]] inline wasm_store_t* GetStore() const noexcept { return _store; }
|
||||||
|
|
||||||
inline void RemoveRegisteredScript(i32 wasmPtr) { _loadedScripts.Remove(wasmPtr); }
|
inline void RemoveRegisteredScript(i32 wasmPtr) { _loadedScripts.Remove(wasmPtr); }
|
||||||
|
|
||||||
template <typename T>
|
// HACK: This is a temporary way to bypass a bug in wasmer 2.2.1. As finalizers on wasm_func_new_with_env are called
|
||||||
inline void MarkLoadedPointer(T* ptr){
|
// twice, the environment objects of WasmHelpers::CreateFunc are deleted twice. This causes major issues. This
|
||||||
_loadedPointers.Set((void*)ptr, typeid(T));
|
// should be fixed in the next wasmer release.
|
||||||
}
|
ArbUt::List<void*> Temp_WasmerBug2_2_1_Bypass;
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool ValidateLoadedPointer(void* ptr){
|
|
||||||
const auto& opt = _loadedPointers.TryGet(ptr);
|
|
||||||
return opt.has_value() && opt.value() == typeid(T);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wasm_engine_t* _engine;
|
wasm_engine_t* _engine;
|
||||||
|
@ -85,8 +79,6 @@ private:
|
||||||
};
|
};
|
||||||
std::unordered_map<scriptCapabilitiesKey, std::unordered_set<WebAssemblyScriptCapabilities>, pair_hash>
|
std::unordered_map<scriptCapabilitiesKey, std::unordered_set<WebAssemblyScriptCapabilities>, pair_hash>
|
||||||
_scriptCapabilities;
|
_scriptCapabilities;
|
||||||
|
|
||||||
ArbUt::Dictionary<void*, std::type_info> _loadedPointers;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PKMNLIB_WEBASSEMBLYSCRIPTRESOLVER_HPP
|
#endif // PKMNLIB_WEBASSEMBLYSCRIPTRESOLVER_HPP
|
||||||
|
|
Loading…
Reference in New Issue