Init
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making Puerts available.
|
||||
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may
|
||||
* be subject to their corresponding license terms. This file is subject to the terms and conditions defined in file 'LICENSE',
|
||||
* which is part of this source code package.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "CoreMinimal.h"
|
||||
#include "wasm3.h"
|
||||
#include "m3_env.h"
|
||||
|
||||
// true表示成功,false表示失败
|
||||
WASMCORE_API bool Export_m3_GetResults(IM3Function i_function, uint32_t i_retc, const void* o_retptrs[]);
|
||||
WASMCORE_API bool Export_m3_Call(IM3Function i_function, uint32_t i_argc, const void* i_argptrs[]);
|
||||
WASMCORE_API bool Export_m3_LinkRawFunctionEx(IM3Module io_module, const char* const i_moduleName, const char* const i_functionName,
|
||||
const char* const i_signature, M3RawCall i_function, const void* i_userdata);
|
||||
@@ -0,0 +1,501 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making Puerts available.
|
||||
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may
|
||||
* be subject to their corresponding license terms. This file is subject to the terms and conditions defined in file 'LICENSE',
|
||||
* which is part of this source code package.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "wasm3.h"
|
||||
#include "m3_env.h"
|
||||
#include "WasmCommonIncludes.h"
|
||||
#include "Wasm3ExportDef.h"
|
||||
|
||||
typedef uint64_t* wasm_stack_type;
|
||||
typedef void* wasm_mem_type;
|
||||
|
||||
template <typename T>
|
||||
struct wasm_remove_const_ref
|
||||
{
|
||||
using type = typename std::remove_const<typename std::remove_reference<T>::type>::type;
|
||||
};
|
||||
|
||||
template <bool V>
|
||||
struct true_false_type
|
||||
{
|
||||
static constexpr bool value = V;
|
||||
};
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct _wasm_is_simple_type;
|
||||
|
||||
//定义简单的类型,该类型会直接被放在栈上
|
||||
template <>
|
||||
struct _wasm_is_simple_type<bool> : true_false_type<true>
|
||||
{
|
||||
};
|
||||
// template<> struct _wasm_is_simple_type<char> : true_false_type<true> {};
|
||||
// template<> struct _wasm_is_simple_type<unsigned char> : true_false_type<true> {};
|
||||
template <>
|
||||
struct _wasm_is_simple_type<int32> : true_false_type<true>
|
||||
{
|
||||
};
|
||||
template <>
|
||||
struct _wasm_is_simple_type<uint32> : true_false_type<true>
|
||||
{
|
||||
};
|
||||
template <>
|
||||
struct _wasm_is_simple_type<int64> : true_false_type<true>
|
||||
{
|
||||
};
|
||||
template <>
|
||||
struct _wasm_is_simple_type<uint64> : true_false_type<true>
|
||||
{
|
||||
};
|
||||
template <>
|
||||
struct _wasm_is_simple_type<float> : true_false_type<true>
|
||||
{
|
||||
};
|
||||
template <>
|
||||
struct _wasm_is_simple_type<double> : true_false_type<true>
|
||||
{
|
||||
};
|
||||
// enum为true,非enum为false
|
||||
template <typename T>
|
||||
struct _wasm_is_simple_type<T, typename std::enable_if<std::is_enum<T>::value>::type> : true_false_type<true>
|
||||
{
|
||||
};
|
||||
template <typename T>
|
||||
struct _wasm_is_simple_type<T, typename std::enable_if<!std::is_enum<T>::value>::type> : true_false_type<false>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct wasm_is_simple_type
|
||||
{
|
||||
static constexpr bool value = _wasm_is_simple_type<typename wasm_remove_const_ref<T>::type>::value;
|
||||
};
|
||||
|
||||
static_assert(wasm_is_simple_type<const int&>::value, "");
|
||||
static_assert(wasm_is_simple_type<int&>::value, "");
|
||||
static_assert(wasm_is_simple_type<int>::value, "");
|
||||
static_assert(wasm_is_simple_type<const int>::value, "");
|
||||
static_assert(!wasm_is_simple_type<void*>::value, "");
|
||||
|
||||
//定义复杂类型,该类型会被当作指针放在栈上
|
||||
template <typename T>
|
||||
struct _wasm_is_complex_type
|
||||
{
|
||||
//这里有点奇怪
|
||||
// 属性数量大于1的结构体当指针
|
||||
// 小于32的结构体当int32,小于64的结构体当int64,大于64的当指针
|
||||
// 我们判断不了属性数量,所以强制规定,结构体必须大于64
|
||||
static constexpr bool value =
|
||||
!wasm_is_simple_type<T>::value && std::is_class<T>::value && std::is_trivially_copyable<T>::value && (sizeof(T) > 8);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct wasm_is_complex_type
|
||||
{
|
||||
static constexpr bool value = _wasm_is_complex_type<typename wasm_remove_const_ref<T>::type>::value;
|
||||
};
|
||||
template <>
|
||||
struct wasm_is_complex_type<void>
|
||||
{
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
static_assert(!wasm_is_complex_type<void*>::value, "");
|
||||
|
||||
template <typename T>
|
||||
struct wasm_is_support_pointer_type
|
||||
{
|
||||
using No_PTr = typename std::remove_pointer<T>::type;
|
||||
static constexpr bool value =
|
||||
std::is_pointer<T>::value && !wasm_is_complex_type<No_PTr>::value && !wasm_is_simple_type<No_PTr>::value;
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
struct wasm_is_all_support_type;
|
||||
|
||||
template <typename T>
|
||||
struct wasm_is_all_support_type<T>
|
||||
{
|
||||
static constexpr bool value =
|
||||
wasm_is_complex_type<T>::value || wasm_is_simple_type<T>::value || wasm_is_support_pointer_type<T>::value;
|
||||
};
|
||||
|
||||
template <typename T, typename... Args>
|
||||
struct wasm_is_all_support_type<T, Args...>
|
||||
{
|
||||
static constexpr bool value = wasm_is_all_support_type<T>::value && wasm_is_all_support_type<Args...>::value;
|
||||
};
|
||||
|
||||
template <typename T, typename Enabled = void>
|
||||
struct _wasm_call_params_translator
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct _wasm_call_params_translator<float>
|
||||
{
|
||||
using type = float;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct _wasm_call_params_translator<double>
|
||||
{
|
||||
using type = double;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct _wasm_call_params_translator<T, typename std::enable_if<wasm_is_simple_type<T>::value && (sizeof(T) <= 4)>::type>
|
||||
{
|
||||
using type = int32;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct _wasm_call_params_translator<T,
|
||||
typename std::enable_if<wasm_is_simple_type<T>::value && (sizeof(T) > 4) && (sizeof(T) <= 8)>::type>
|
||||
{
|
||||
using type = int64;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct _wasm_call_params_translator<T, typename std::enable_if<wasm_is_complex_type<T>::value>::type>
|
||||
{
|
||||
using type = WASM_PTR;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct _wasm_call_params_translator<T, typename std::enable_if<wasm_is_support_pointer_type<T>::value>::type>
|
||||
{
|
||||
using type = WASM_PTR;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct wasm_call_params_translator
|
||||
{
|
||||
using translated_type = typename _wasm_call_params_translator<typename wasm_remove_const_ref<T>::type>::type;
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
using is_enum_of_t = typename std::enable_if<std::is_enum<T>::value && std::is_same<std::underlying_type_t<T>, U>::value>::type;
|
||||
|
||||
template <char c>
|
||||
struct m3_sig
|
||||
{
|
||||
static const char value = c;
|
||||
};
|
||||
template <typename T, typename = void>
|
||||
struct _m3_type_to_sig;
|
||||
|
||||
template <typename T>
|
||||
struct _m3_type_to_sig<T, is_enum_of_t<T, int32_t>> : m3_sig<'i'>
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct _m3_type_to_sig<T, is_enum_of_t<T, int64_t>> : m3_sig<'I'>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct _m3_type_to_sig<bool> : m3_sig<'i'>
|
||||
{
|
||||
};
|
||||
template <>
|
||||
struct _m3_type_to_sig<char> : m3_sig<'i'>
|
||||
{
|
||||
};
|
||||
template <>
|
||||
struct _m3_type_to_sig<unsigned char> : m3_sig<'i'>
|
||||
{
|
||||
};
|
||||
template <>
|
||||
struct _m3_type_to_sig<int32_t> : m3_sig<'i'>
|
||||
{
|
||||
};
|
||||
template <>
|
||||
struct _m3_type_to_sig<uint32_t> : m3_sig<'i'>
|
||||
{
|
||||
};
|
||||
template <>
|
||||
struct _m3_type_to_sig<int64_t> : m3_sig<'I'>
|
||||
{
|
||||
};
|
||||
template <>
|
||||
struct _m3_type_to_sig<uint64_t> : m3_sig<'I'>
|
||||
{
|
||||
};
|
||||
template <>
|
||||
struct _m3_type_to_sig<float> : m3_sig<'f'>
|
||||
{
|
||||
};
|
||||
template <>
|
||||
struct _m3_type_to_sig<double> : m3_sig<'F'>
|
||||
{
|
||||
};
|
||||
template <>
|
||||
struct _m3_type_to_sig<void> : m3_sig<'v'>
|
||||
{
|
||||
};
|
||||
template <typename T>
|
||||
struct _m3_type_to_sig<T, typename std::is_reference<T>::type> : m3_sig<'*'>
|
||||
{
|
||||
};
|
||||
template <typename T>
|
||||
struct _m3_type_to_sig<T, typename std::enable_if<wasm_is_complex_type<T>::value>::type> : m3_sig<'*'>
|
||||
{
|
||||
};
|
||||
template <typename T>
|
||||
struct _m3_type_to_sig<T, typename std::enable_if<wasm_is_support_pointer_type<T>::value>::type> : m3_sig<'*'>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct m3_type_to_sig;
|
||||
|
||||
//引用当指针处理
|
||||
template <typename T>
|
||||
struct m3_type_to_sig<T, typename std::enable_if<std::is_reference<T>::value>::type>
|
||||
{
|
||||
using TT = typename wasm_remove_const_ref<T>::type;
|
||||
static const char value = '*';
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct m3_type_to_sig<T, typename std::enable_if<!std::is_reference<T>::value>::type>
|
||||
{
|
||||
using TT = typename wasm_remove_const_ref<T>::type;
|
||||
static const char value = _m3_type_to_sig<TT>::value;
|
||||
};
|
||||
|
||||
template <typename Ret, typename... Args>
|
||||
struct m3_signature
|
||||
{
|
||||
//不支持返回值的引用
|
||||
static_assert(!std::is_reference<Ret>::value, "");
|
||||
|
||||
static const char* get()
|
||||
{
|
||||
static char value[] = {m3_type_to_sig<Ret>::value, '(', m3_type_to_sig<Args>::value..., ')', 0};
|
||||
return (const char*) value;
|
||||
}
|
||||
};
|
||||
//记录不同类型的指针,再wasm存的类型
|
||||
template <typename T, typename = void>
|
||||
struct _wasm_pointer_support_ptr_in_wasm;
|
||||
|
||||
template <typename T>
|
||||
struct _wasm_pointer_support_ptr_in_wasm<T, typename std::enable_if<std::is_base_of<UObject, T>::value>::type>
|
||||
{
|
||||
using type = UObjectBase*;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct _wasm_pointer_support_ptr_in_wasm<T, typename std::enable_if<!std::is_base_of<UObject, T>::value>::type>
|
||||
{
|
||||
using type = void*;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct wasm_pointer_support_ptr_in_wasm
|
||||
{
|
||||
using type = typename _wasm_pointer_support_ptr_in_wasm<
|
||||
typename std::remove_pointer<typename wasm_remove_const_ref<T>::type>::type>::type;
|
||||
};
|
||||
|
||||
//指针
|
||||
template <typename T, typename memstack_t = typename std::add_pointer_t<typename std::remove_reference_t<T>>,
|
||||
typename t_remove_pointer = typename std::remove_pointer<T>::type>
|
||||
typename std::enable_if<wasm_is_support_pointer_type<T>::value, int>::type wasm_link_get_args_from_stack(
|
||||
IM3Runtime rt, IM3ImportContext _ctx, wasm_stack_type _sp, wasm_mem_type _mem, memstack_t& stack_ptr, int index)
|
||||
{
|
||||
using ptr_type_in_wasm = typename wasm_pointer_support_ptr_in_wasm<T>::type;
|
||||
WASM_PTR offset = *((WASM_PTR*) (_sp + index));
|
||||
ptr_type_in_wasm* tmp = (ptr_type_in_wasm*) m3ApiOffsetToPtr(offset);
|
||||
*stack_ptr = static_cast<T>(*tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//简单类型,非引用
|
||||
template <typename T, typename memstack_t = typename std::add_pointer_t<typename std::remove_reference_t<T>>>
|
||||
typename std::enable_if<wasm_is_simple_type<T>::value && !std::is_reference<T>::value, int>::type wasm_link_get_args_from_stack(
|
||||
IM3Runtime rt, IM3ImportContext _ctx, wasm_stack_type _sp, wasm_mem_type _mem, memstack_t& stack_ptr, int index)
|
||||
{
|
||||
T tmp = *((T*) (_sp + index));
|
||||
*stack_ptr = tmp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//简单类型引用
|
||||
template <typename T, typename memstack_t = typename std::add_pointer_t<typename std::remove_reference_t<T>>>
|
||||
typename std::enable_if<wasm_is_simple_type<T>::value && std::is_reference<T>::value, int>::type wasm_link_get_args_from_stack(
|
||||
IM3Runtime rt, IM3ImportContext _ctx, wasm_stack_type _sp, wasm_mem_type _mem, memstack_t& stack_ptr, int index)
|
||||
{
|
||||
using T_noRef = typename std::remove_reference_t<T>;
|
||||
WASM_PTR offset = *((WASM_PTR*) (_sp + index));
|
||||
T_noRef* tmp = (T_noRef*) m3ApiOffsetToPtr(offset);
|
||||
stack_ptr = tmp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//复杂类型
|
||||
template <typename T, typename memstack_t = typename std::add_pointer_t<typename std::remove_reference_t<T>>>
|
||||
typename std::enable_if<wasm_is_complex_type<T>::value, int>::type wasm_link_get_args_from_stack(
|
||||
IM3Runtime rt, IM3ImportContext _ctx, wasm_stack_type _sp, wasm_mem_type _mem, memstack_t& stack_ptr, int index)
|
||||
{
|
||||
using T_noRef = typename std::remove_reference_t<T>;
|
||||
WASM_PTR offset = *((WASM_PTR*) (_sp + index));
|
||||
T_noRef* tmp = (T_noRef*) m3ApiOffsetToPtr(offset);
|
||||
stack_ptr = tmp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename Func, Func* func>
|
||||
struct wasm_link_helper;
|
||||
|
||||
template <typename Ret, typename... Args, Ret (*func)(Args...)>
|
||||
struct wasm_link_helper<Ret(Args...), func>
|
||||
{
|
||||
template <typename X>
|
||||
struct Functor;
|
||||
|
||||
template <int... Index>
|
||||
struct Functor<std::index_sequence<Index...>>
|
||||
{
|
||||
//返回值是指针
|
||||
//规避malloc,需要link的函数,返回值禁止是指针
|
||||
/*template<class T>
|
||||
static typename std::enable_if<wasm_is_support_pointer_type<T>::value && !std::is_same<T, void>::value, const void*>::type
|
||||
_InternalInvoke(IM3Runtime rt, IM3ImportContext _ctx, wasm_stack_type _sp, wasm_mem_type _mem)
|
||||
{
|
||||
m3ApiReturnType(WASM_PTR);
|
||||
auto stack_mem = std::make_tuple<typename std::remove_reference_t<Args>...>(typename
|
||||
std::remove_reference_t<Args>()...); auto parm = std::make_tuple<typename std::add_pointer_t<typename
|
||||
std::remove_reference_t<Args>>...>(&std::get<Index>(stack_mem)...); auto tmp =
|
||||
std::make_tuple(wasm_link_get_args_from_stack<Args>(rt, _ctx, _sp, _mem, std::get<Index>(parm), Index)...);
|
||||
//_sp += sizeof...(Args);
|
||||
using T_RemoveConst = typename wasm_remove_const_ref<T>::type;
|
||||
T_RemoveConst r = (T_RemoveConst)func(*std::get<Index>(parm)...);
|
||||
WASM_PTR ptr = TryGetWasmPointerWithObject(r, rt);
|
||||
{
|
||||
*raw_return = ptr;
|
||||
return nullptr;
|
||||
}
|
||||
}*/
|
||||
|
||||
//没有返回值
|
||||
template <class T>
|
||||
static typename std::enable_if<std::is_same<T, void>::value, void>::type _InternalInvoke(
|
||||
IM3Runtime rt, IM3ImportContext _ctx, wasm_stack_type _sp, wasm_mem_type _mem)
|
||||
{
|
||||
auto stack_mem =
|
||||
std::make_tuple<typename std::remove_reference_t<Args>...>(typename std::remove_reference_t<Args>()...);
|
||||
auto parm = std::make_tuple<typename std::add_pointer_t<typename std::remove_reference_t<Args>>...>(
|
||||
&std::get<Index>(stack_mem)...);
|
||||
auto tmp = std::make_tuple(wasm_link_get_args_from_stack<Args>(rt, _ctx, _sp, _mem, std::get<Index>(parm), Index)...);
|
||||
//_sp不是引用,所以也不用加了
|
||||
//_sp += sizeof...(Args);
|
||||
func(*std::get<Index>(parm)...);
|
||||
return nullptr;
|
||||
}
|
||||
//返回值是复杂类型
|
||||
template <class T>
|
||||
static typename std::enable_if<wasm_is_complex_type<T>::value && !std::is_same<T, void>::value, const void*>::type
|
||||
_InternalInvoke(IM3Runtime rt, IM3ImportContext _ctx, wasm_stack_type _sp, wasm_mem_type _mem)
|
||||
{
|
||||
using T_RemoveConst = typename wasm_remove_const_ref<T>::type;
|
||||
m3ApiReturnType(WASM_PTR);
|
||||
T_RemoveConst* ptr = (T_RemoveConst*) m3ApiOffsetToPtr(*raw_return);
|
||||
|
||||
auto stack_mem =
|
||||
std::make_tuple<typename std::remove_reference_t<Args>...>(typename std::remove_reference_t<Args>()...);
|
||||
auto parm = std::make_tuple<typename std::add_pointer_t<typename std::remove_reference_t<Args>>...>(
|
||||
&std::get<Index>(stack_mem)...);
|
||||
auto tmp = std::make_tuple(wasm_link_get_args_from_stack<Args>(rt, _ctx, _sp, _mem, std::get<Index>(parm), Index)...);
|
||||
//_sp += sizeof...(Args);
|
||||
|
||||
*ptr = func(*std::get<Index>(parm)...);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
//返回值是简单类型
|
||||
template <class T>
|
||||
static typename std::enable_if<wasm_is_simple_type<T>::value && !std::is_same<T, void>::value, const void*>::type
|
||||
_InternalInvoke(IM3Runtime rt, IM3ImportContext _ctx, wasm_stack_type _sp, wasm_mem_type _mem)
|
||||
{
|
||||
m3ApiReturnType(T);
|
||||
auto stack_mem =
|
||||
std::make_tuple<typename std::remove_reference_t<Args>...>(typename std::remove_reference_t<Args>()...);
|
||||
auto parm = std::make_tuple<typename std::add_pointer_t<typename std::remove_reference_t<Args>>...>(
|
||||
&std::get<Index>(stack_mem)...);
|
||||
auto tmp = std::make_tuple(wasm_link_get_args_from_stack<Args>(rt, _ctx, _sp, _mem, std::get<Index>(parm), Index)...);
|
||||
//_sp += sizeof...(Args);
|
||||
|
||||
T r = func(*std::get<Index>(parm)...);
|
||||
{
|
||||
*raw_return = r;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static const void* Invoke(IM3Runtime rt, IM3ImportContext _ctx, wasm_stack_type _sp, wasm_mem_type _mem)
|
||||
{
|
||||
return _InternalInvoke<Ret>(rt, _ctx, _sp, _mem);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <typename Func, Func* func>
|
||||
struct wasm_link_wrapper;
|
||||
|
||||
template <typename Ret, typename... Args, Ret (*func)(Args...)>
|
||||
struct wasm_link_wrapper<Ret(Args...), func>
|
||||
{
|
||||
//为了规避malloc,暂时禁止返回值是指针的函数link
|
||||
/*template<typename T>
|
||||
static typename std::enable_if<wasm_is_support_pointer_type<T>::value && !std::is_same<T, void>::value, bool>::type
|
||||
InternalLink(IM3Module _module, const char* const function_name)
|
||||
{
|
||||
//返回值不能是引用
|
||||
static_assert(!std::is_reference<Ret>::value, "");
|
||||
return Export_m3_LinkRawFunctionEx(_module, "*", function_name, m3_signature<Ret, Args...>::get(),
|
||||
&wasm_link_helper<Ret(Args...), func>::template Functor<std::make_index_sequence<sizeof...(Args)>>::Invoke, nullptr);
|
||||
}*/
|
||||
|
||||
template <typename T>
|
||||
static typename std::enable_if<std::is_same<T, void>::value, bool>::type InternalLink(
|
||||
IM3Module _module, const char* const function_name)
|
||||
{
|
||||
return Export_m3_LinkRawFunctionEx(_module, "*", function_name, m3_signature<void, Args...>::get(),
|
||||
&wasm_link_helper<void(Args...), func>::template Functor<std::make_index_sequence<sizeof...(Args)>>::Invoke, nullptr);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static typename std::enable_if<wasm_is_simple_type<T>::value && !std::is_same<T, void>::value, bool>::type InternalLink(
|
||||
IM3Module _module, const char* const function_name)
|
||||
{
|
||||
//返回值不能是引用
|
||||
static_assert(!std::is_reference<Ret>::value, "");
|
||||
return Export_m3_LinkRawFunctionEx(_module, "*", function_name, m3_signature<Ret, Args...>::get(),
|
||||
&wasm_link_helper<Ret(Args...), func>::template Functor<std::make_index_sequence<sizeof...(Args)>>::Invoke, nullptr);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static typename std::enable_if<wasm_is_complex_type<T>::value && !std::is_same<T, void>::value, bool>::type InternalLink(
|
||||
IM3Module _module, const char* const function_name)
|
||||
{
|
||||
//返回值不能是引用
|
||||
static_assert(!std::is_reference<Ret>::value, "");
|
||||
return Export_m3_LinkRawFunctionEx(_module, "*", function_name, m3_signature<void, Ret&, Args...>::get(),
|
||||
&wasm_link_helper<Ret(Args...), func>::template Functor<std::make_index_sequence<sizeof...(Args)>>::Invoke, nullptr);
|
||||
}
|
||||
|
||||
static bool link(IM3Module _module, const char* const function_name)
|
||||
{
|
||||
return InternalLink<Ret>(_module, function_name);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making Puerts available.
|
||||
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may
|
||||
* be subject to their corresponding license terms. This file is subject to the terms and conditions defined in file 'LICENSE',
|
||||
* which is part of this source code package.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "CoreMinimal.h"
|
||||
#include "wasm3.h"
|
||||
#include "m3_env.h"
|
||||
#define WASM_PTR u32
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making Puerts available.
|
||||
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may
|
||||
* be subject to their corresponding license terms. This file is subject to the terms and conditions defined in file 'LICENSE',
|
||||
* which is part of this source code package.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
class WasmCoreModule : public IModuleInterface
|
||||
{
|
||||
public:
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making Puerts available.
|
||||
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may
|
||||
* be subject to their corresponding license terms. This file is subject to the terms and conditions defined in file 'LICENSE',
|
||||
* which is part of this source code package.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "CoreMinimal.h"
|
||||
#include "WasmCommonIncludes.h"
|
||||
|
||||
class WASMCORE_API WasmEnv final
|
||||
{
|
||||
private:
|
||||
IM3Environment _Env;
|
||||
|
||||
public:
|
||||
WasmEnv();
|
||||
~WasmEnv();
|
||||
FORCEINLINE IM3Environment GetEnv()
|
||||
{
|
||||
return _Env;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,357 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making Puerts available.
|
||||
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may
|
||||
* be subject to their corresponding license terms. This file is subject to the terms and conditions defined in file 'LICENSE',
|
||||
* which is part of this source code package.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "CoreMinimal.h"
|
||||
#include "wasm3.h"
|
||||
#include "m3_env.h"
|
||||
#include "WasmBindingTemplate.hpp"
|
||||
#include "WasmRuntime.h"
|
||||
#include "Wasm3ExportDef.h"
|
||||
|
||||
class WASMCORE_API WasmFunction final
|
||||
{
|
||||
private:
|
||||
M3Function* _Function;
|
||||
|
||||
public:
|
||||
WasmFunction(M3Function* Func) : _Function(Func)
|
||||
{
|
||||
}
|
||||
FORCEINLINE M3Function* GetFunction() const
|
||||
{
|
||||
return _Function;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Ret, typename... Args>
|
||||
struct CallHelper
|
||||
{
|
||||
//不支持返回值是引用
|
||||
static_assert(!std::is_reference<Ret>::value, "");
|
||||
|
||||
template <typename X>
|
||||
struct Functor;
|
||||
|
||||
template <int... Index>
|
||||
struct Functor<std::index_sequence<Index...>>
|
||||
{
|
||||
static bool InvokeNoReturn(WasmFunction* Outer, Args... args)
|
||||
{
|
||||
static_assert(wasm_is_all_support_type<Args...>::value, "");
|
||||
|
||||
WasmRuntime* Runtime = Outer->GetRuntime();
|
||||
WasmStackAllocCacheInfo Backup = Runtime->GetCurrentStackAllocInfo();
|
||||
|
||||
auto stack_params = std::make_tuple<typename wasm_call_params_translator<Args>::translated_type...>(
|
||||
typename wasm_call_params_translator<Args>::translated_type()...);
|
||||
void* args_pointer[sizeof...(args)] = {Outer->InternalTranslatePointer<Args>(
|
||||
&std::get<Index>(stack_params), (typename wasm_remove_const_ref<Args>::type*) &args)...};
|
||||
if (Outer->CallWithArgsNoReturn(sizeof...(args), (const void**) args_pointer))
|
||||
{
|
||||
const WASM_PTR free_ptr_list[sizeof...(args)] = {
|
||||
Outer->InternalCopyback<Args>(args_pointer[Index], (typename wasm_remove_const_ref<Args>::type*) &args)...};
|
||||
Runtime->RestoreCurrentStackAllocInfo(Backup);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Runtime->RestoreCurrentStackAllocInfo(Backup);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//没有返回值
|
||||
template <typename T>
|
||||
static typename std::enable_if<std::is_same<T, void>::value, void>::type InnerInvoke(WasmFunction* Outer, Args... args)
|
||||
{
|
||||
InvokeNoReturn(Outer, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// 返回值是复杂类型
|
||||
template <typename T>
|
||||
static typename std::enable_if<wasm_is_complex_type<T>::value, T>::type InnerInvoke(WasmFunction* Outer, Args... args)
|
||||
{
|
||||
static_assert(wasm_is_all_support_type<Args...>::value, "");
|
||||
WasmRuntime* Runtime = Outer->GetRuntime();
|
||||
WasmStackAllocCacheInfo Backup = Runtime->GetCurrentStackAllocInfo();
|
||||
|
||||
//复杂类型,栈的第一个是类型地址
|
||||
WASM_PTR inner_ptr = Runtime->AllocStackParam(sizeof(T)).PtrInWasm;
|
||||
auto stack_params = std::make_tuple<typename wasm_call_params_translator<Args>::translated_type...>(
|
||||
typename wasm_call_params_translator<Args>::translated_type()...);
|
||||
void* args_pointer[1 + sizeof...(args)] = {
|
||||
(void*) &inner_ptr, Outer->InternalTranslatePointer<Args>(&std::get<Index>(stack_params),
|
||||
(typename wasm_remove_const_ref<Args>::type*) &args)...};
|
||||
|
||||
if (Outer->CallWithArgsNoReturn(1 + sizeof...(args), (const void**) args_pointer))
|
||||
{
|
||||
const WASM_PTR free_ptr_list[1 + sizeof...(args)] = {inner_ptr,
|
||||
Outer->InternalCopyback<Args>(args_pointer[Index], (typename wasm_remove_const_ref<Args>::type*) &args)...};
|
||||
Ret* ret_ptr = (Ret*) Runtime->GetPlatformAddress(inner_ptr);
|
||||
Ret r = *ret_ptr;
|
||||
Runtime->RestoreCurrentStackAllocInfo(Backup);
|
||||
return r;
|
||||
}
|
||||
else
|
||||
{
|
||||
Runtime->RestoreCurrentStackAllocInfo(Backup);
|
||||
return T();
|
||||
}
|
||||
}
|
||||
//返回值是简单类型
|
||||
template <typename T>
|
||||
static typename std::enable_if<wasm_is_simple_type<T>::value, T>::type InnerInvoke(WasmFunction* Outer, Args... args)
|
||||
{
|
||||
static_assert(wasm_is_all_support_type<Args...>::value, "");
|
||||
|
||||
WasmRuntime* Runtime = Outer->GetRuntime();
|
||||
WasmStackAllocCacheInfo Backup = Runtime->GetCurrentStackAllocInfo();
|
||||
|
||||
auto stack_params = std::make_tuple<typename wasm_call_params_translator<Args>::translated_type...>(
|
||||
typename wasm_call_params_translator<Args>::translated_type()...);
|
||||
void* args_pointer[sizeof...(args)] = {Outer->InternalTranslatePointer<Args>(
|
||||
&std::get<Index>(stack_params), (typename wasm_remove_const_ref<Args>::type*) &args)...};
|
||||
if (Outer->CallWithArgsNoReturn(sizeof...(args), (const void**) args_pointer))
|
||||
{
|
||||
const WASM_PTR free_ptr_list[sizeof...(args)] = {
|
||||
Outer->InternalCopyback<Args>(args_pointer[Index], (typename wasm_remove_const_ref<Args>::type*) &args)...};
|
||||
T r = Outer->GetReturnValue<T>();
|
||||
Runtime->RestoreCurrentStackAllocInfo(Backup);
|
||||
return r;
|
||||
}
|
||||
else
|
||||
{
|
||||
Runtime->RestoreCurrentStackAllocInfo(Backup);
|
||||
return T();
|
||||
}
|
||||
}
|
||||
// 返回值是指针,等价于先返回一个wasm_ptr,再解析这个wasm_ptr
|
||||
template <typename T>
|
||||
static typename std::enable_if<wasm_is_support_pointer_type<T>::value, T>::type InnerInvoke(
|
||||
WasmFunction* Outer, Args... args)
|
||||
{
|
||||
using ptr_type_in_wasm = typename wasm_pointer_support_ptr_in_wasm<T>::type;
|
||||
WASM_PTR ptr = InnerInvoke<WASM_PTR>(Outer, std::forward<Args>(args)...);
|
||||
ptr_type_in_wasm* realPtr = (ptr_type_in_wasm*) Outer->GetRuntime()->GetPlatformAddress(ptr);
|
||||
return static_cast<T>(*realPtr);
|
||||
}
|
||||
|
||||
static Ret Invoke(WasmFunction* Outer, Args... args)
|
||||
{
|
||||
return InnerInvoke<Ret>(Outer, std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
public:
|
||||
//内部接口,谨慎调用
|
||||
bool CallWithArgsNoReturn(int arg_count, const void** args) const
|
||||
{
|
||||
check(_Function);
|
||||
if (!Export_m3_Call(_Function, arg_count, args))
|
||||
{
|
||||
UE_LOG(LogTemp, Error, TEXT("Error In Call Simple Function %s"), ANSI_TO_TCHAR(_Function->export_name));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//简单类型返回值
|
||||
template <typename Ret>
|
||||
typename std::enable_if<wasm_is_simple_type<Ret>::value, Ret>::type GetReturnValue() const
|
||||
{
|
||||
//不支持返回值是引用
|
||||
static_assert(!std::is_reference<Ret>::value, "");
|
||||
Ret r;
|
||||
void* ret_ptrs[] = {&r};
|
||||
if (!Export_m3_GetResults(_Function, 1, (const void**) ret_ptrs))
|
||||
{
|
||||
UE_LOG(LogTemp, Error, TEXT("Error In GetReturnValue %s"), ANSI_TO_TCHAR(_Function->export_name));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
//并不支持复杂类型返回值使用这个接口,直接使用Call,因为复杂类型的返回值传参不太一样,这里只考虑指针和简单类型
|
||||
template <typename Ret>
|
||||
typename std::enable_if<wasm_is_support_pointer_type<Ret>::value, Ret>::type GetReturnValue() const
|
||||
{
|
||||
//不支持返回值是引用
|
||||
static_assert(!std::is_reference<Ret>::value, "");
|
||||
using ptr_type_in_wasm = typename wasm_pointer_support_ptr_in_wasm<Ret>::type;
|
||||
WASM_PTR r;
|
||||
void* ret_ptrs[] = {&r};
|
||||
if (!Export_m3_GetResults(_Function, 1, (const void**) ret_ptrs))
|
||||
{
|
||||
UE_LOG(LogTemp, Error, TEXT("Error In GetReturnValue %s"), ANSI_TO_TCHAR(_Function->export_name));
|
||||
}
|
||||
ptr_type_in_wasm* ptr = (ptr_type_in_wasm*) GetRuntime()->GetPlatformAddress(r);
|
||||
return static_cast<Ret>(*ptr);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
bool CallNoReturn(Args... args)
|
||||
{
|
||||
// todo 看看是否需要把栈补一下,要不然可能会不平衡?
|
||||
return CallHelper<void, Args...>::template Functor<std::make_index_sequence<sizeof...(Args)>>::InvokeNoReturn(
|
||||
this, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
bool CallNoReturn()
|
||||
{
|
||||
return CallWithArgsNoReturn(0, nullptr);
|
||||
}
|
||||
|
||||
template <typename Ret, typename... Args>
|
||||
Ret Call(Args... args)
|
||||
{
|
||||
return CallHelper<Ret, Args...>::template Functor<std::make_index_sequence<sizeof...(Args)>>::Invoke(
|
||||
this, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
//简单类型或者指针类型
|
||||
template <typename Ret>
|
||||
typename std::enable_if<wasm_is_simple_type<Ret>::value || wasm_is_support_pointer_type<Ret>::value, Ret>::type Call()
|
||||
{
|
||||
//不支持返回值是引用
|
||||
static_assert(!std::is_reference<Ret>::value, "");
|
||||
if (CallWithArgsNoReturn(0, nullptr))
|
||||
{
|
||||
return GetReturnValue<Ret>();
|
||||
}
|
||||
return Ret();
|
||||
}
|
||||
//复杂类型
|
||||
template <typename Ret>
|
||||
typename std::enable_if<wasm_is_complex_type<Ret>::value, Ret>::type Call()
|
||||
{
|
||||
//不支持返回值是引用
|
||||
static_assert(!std::is_reference<Ret>::value, "");
|
||||
WasmRuntime* Runtime = GetRuntime();
|
||||
WasmStackAllocCacheInfo Backup = Runtime->GetCurrentStackAllocInfo();
|
||||
|
||||
WASM_PTR inner_ptr = Runtime->AllocStackParam(sizeof(Ret)).PtrInWasm;
|
||||
void* args_pointer[] = {
|
||||
&inner_ptr,
|
||||
};
|
||||
if (CallWithArgsNoReturn(1, (const void**) args_pointer))
|
||||
{
|
||||
Ret* ptr = (Ret*) Runtime->GetPlatformAddress(inner_ptr);
|
||||
Ret r = *ptr;
|
||||
Runtime->RestoreCurrentStackAllocInfo(Backup);
|
||||
return r;
|
||||
}
|
||||
else
|
||||
{
|
||||
Runtime->RestoreCurrentStackAllocInfo(Backup);
|
||||
}
|
||||
return Ret();
|
||||
}
|
||||
|
||||
private:
|
||||
// 简单类型,非引用
|
||||
template <typename T, typename T_Translatedtype = typename wasm_call_params_translator<T>::translated_type,
|
||||
typename RT = typename wasm_remove_const_ref<T>::type>
|
||||
typename std::enable_if<wasm_is_simple_type<T>::value && !std::is_reference<T>::value, void*>::type InternalTranslatePointer(
|
||||
T_Translatedtype* stack_pointer, RT* src_pointer)
|
||||
{
|
||||
//非引用的,直接使用原来的地址就好了,因为本来就是传值的语义
|
||||
return (void*) src_pointer;
|
||||
}
|
||||
// 简单类型的引用
|
||||
template <typename T, typename T_Translatedtype = typename wasm_call_params_translator<T>::translated_type,
|
||||
typename RT = typename wasm_remove_const_ref<T>::type>
|
||||
typename std::enable_if<wasm_is_simple_type<T>::value && std::is_reference<T>::value, void*>::type InternalTranslatePointer(
|
||||
T_Translatedtype* stack_pointer, RT* src_pointer)
|
||||
{
|
||||
//引用被wasm当作指针来传递
|
||||
WasmRuntime* Runtime = GetRuntime();
|
||||
WasmStackAllocCacheInfo NewMalloc = Runtime->AllocStackParam(sizeof(T));
|
||||
FMemory::Memcpy(NewMalloc.RealPtr, src_pointer, sizeof(T));
|
||||
*((WASM_PTR*) stack_pointer) = NewMalloc.PtrInWasm;
|
||||
return stack_pointer;
|
||||
}
|
||||
// 复杂类型
|
||||
template <typename T, typename T_Translatedtype = typename wasm_call_params_translator<T>::translated_type,
|
||||
typename RT = typename wasm_remove_const_ref<T>::type>
|
||||
typename std::enable_if<wasm_is_complex_type<T>::value, void*>::type InternalTranslatePointer(
|
||||
void* stack_pointer, RT* src_pointer)
|
||||
{
|
||||
static_assert(std::is_same<T_Translatedtype, WASM_PTR>::value, "");
|
||||
WasmRuntime* Runtime = GetRuntime();
|
||||
WasmStackAllocCacheInfo NewMalloc = Runtime->AllocStackParam(sizeof(T));
|
||||
FMemory::Memcpy(NewMalloc.RealPtr, src_pointer, sizeof(T));
|
||||
*((WASM_PTR*) stack_pointer) = NewMalloc.PtrInWasm;
|
||||
return stack_pointer;
|
||||
}
|
||||
//指针
|
||||
template <typename T, typename T_Translatedtype = typename wasm_call_params_translator<T>::translated_type,
|
||||
typename RT = typename wasm_remove_const_ref<T>::type>
|
||||
typename std::enable_if<wasm_is_support_pointer_type<T>::value, void*>::type InternalTranslatePointer(
|
||||
void* stack_pointer, RT* src_pointer)
|
||||
{
|
||||
WasmRuntime* Runtime = GetRuntime();
|
||||
WasmStackAllocCacheInfo NewMalloc = Runtime->AllocStackParam(sizeof(void*));
|
||||
T_Translatedtype value = static_cast<T_Translatedtype>(*src_pointer);
|
||||
*((T_Translatedtype*) (NewMalloc.RealPtr)) = value;
|
||||
*((WASM_PTR*) stack_pointer) = NewMalloc.PtrInWasm;
|
||||
return stack_pointer;
|
||||
}
|
||||
|
||||
template <typename T, typename T_Translatedtype = typename wasm_call_params_translator<T>::translated_type,
|
||||
typename RT = typename wasm_remove_const_ref<T>::type>
|
||||
typename std::enable_if<wasm_is_support_pointer_type<T>::value, WASM_PTR>::type InternalCopyback(
|
||||
void* stack_pointer, RT* src_pointer)
|
||||
{
|
||||
// 指针也啥都不用干
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T, typename T_Translatedtype = typename wasm_call_params_translator<T>::translated_type,
|
||||
typename RT = typename wasm_remove_const_ref<T>::type>
|
||||
typename std::enable_if<wasm_is_simple_type<T>::value && !std::is_reference<T>::value, WASM_PTR>::type InternalCopyback(
|
||||
void* stack_pointer, RT* src_pointer)
|
||||
{
|
||||
// 非引用的简单类型,啥都不用干
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T, typename T_Translatedtype = typename wasm_call_params_translator<T>::translated_type,
|
||||
typename RT = typename wasm_remove_const_ref<T>::type>
|
||||
typename std::enable_if<wasm_is_simple_type<T>::value && std::is_reference<T>::value, WASM_PTR>::type InternalCopyback(
|
||||
void* stack_pointer, RT* src_pointer)
|
||||
{
|
||||
// 引用的简单类型,还要把值拷贝回去
|
||||
WASM_PTR ptr = *((WASM_PTR*) stack_pointer);
|
||||
WasmRuntime* Runtime = GetRuntime();
|
||||
if (std::is_reference<T>::value && !std::is_const<typename std::remove_reference<T>::type>::value)
|
||||
{
|
||||
void* real_ptr = Runtime->GetPlatformAddress(ptr);
|
||||
FMemory::Memcpy((void*) src_pointer, real_ptr, sizeof(T));
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
template <typename T, typename T_Translatedtype = typename wasm_call_params_translator<T>::translated_type,
|
||||
typename RT = typename wasm_remove_const_ref<T>::type>
|
||||
typename std::enable_if<wasm_is_complex_type<T>::value, WASM_PTR>::type InternalCopyback(void* stack_pointer, RT* src_pointer)
|
||||
{
|
||||
static_assert(std::is_same<T_Translatedtype, WASM_PTR>::value, "");
|
||||
WASM_PTR ptr = *((WASM_PTR*) stack_pointer);
|
||||
WasmRuntime* Runtime = GetRuntime();
|
||||
if (std::is_reference<T>::value && !std::is_const<typename std::remove_reference<T>::type>::value)
|
||||
{
|
||||
void* real_ptr = Runtime->GetPlatformAddress(ptr);
|
||||
FMemory::Memcpy((void*) src_pointer, real_ptr, sizeof(T));
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
FORCEINLINE WasmRuntime* GetRuntime() const
|
||||
{
|
||||
return (WasmRuntime*) _Function->module->runtime->userdata;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making Puerts available.
|
||||
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may
|
||||
* be subject to their corresponding license terms. This file is subject to the terms and conditions defined in file 'LICENSE',
|
||||
* which is part of this source code package.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "CoreMinimal.h"
|
||||
#include "wasm3.h"
|
||||
#include "WasmEnv.h"
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making Puerts available.
|
||||
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may
|
||||
* be subject to their corresponding license terms. This file is subject to the terms and conditions defined in file 'LICENSE',
|
||||
* which is part of this source code package.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "CoreMinimal.h"
|
||||
#include "wasm3.h"
|
||||
#include "m3_env.h"
|
||||
#include "WasmCommonIncludes.h"
|
||||
#include <functional>
|
||||
class WasmRuntime;
|
||||
class WasmFunction;
|
||||
class WasmEnv;
|
||||
|
||||
using AdditionLinkFunc = std::function<bool(IM3Module)>;
|
||||
|
||||
class WASMCORE_API WasmModuleInstance final
|
||||
{
|
||||
private:
|
||||
IM3Module _Module;
|
||||
TMap<FName, WasmFunction*> _AllExportFunctions;
|
||||
TArray<uint8> Data;
|
||||
|
||||
public:
|
||||
WasmModuleInstance(TArray<uint8>& InData);
|
||||
|
||||
int Index = -1;
|
||||
|
||||
bool ParseModule(WasmEnv* Env);
|
||||
bool LoadModule(WasmRuntime* Runtime, int LinkCategory, AdditionLinkFunc _Func = nullptr);
|
||||
|
||||
size_t TableGrow(size_t N) const;
|
||||
|
||||
void TableSet(size_t Idx, IM3Function Function) const;
|
||||
|
||||
size_t TableLen() const;
|
||||
|
||||
~WasmModuleInstance();
|
||||
const TMap<FName, WasmFunction*>& GetAllExportFunctions()
|
||||
{
|
||||
return _AllExportFunctions;
|
||||
}
|
||||
IM3Module GetModule()
|
||||
{
|
||||
return _Module;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making Puerts available.
|
||||
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may
|
||||
* be subject to their corresponding license terms. This file is subject to the terms and conditions defined in file 'LICENSE',
|
||||
* which is part of this source code package.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "CoreMinimal.h"
|
||||
#include "WasmCommonIncludes.h"
|
||||
#include "WasmEnv.h"
|
||||
|
||||
class WasmModuleInstance;
|
||||
class WasmFunction;
|
||||
class WasmPointerSupport;
|
||||
|
||||
struct WASMCORE_API WasmStackAllocCacheInfo
|
||||
{
|
||||
WASM_PTR PtrInWasm = 0;
|
||||
char* RealPtr = nullptr;
|
||||
};
|
||||
|
||||
class WASMCORE_API WasmRuntime final
|
||||
{
|
||||
private:
|
||||
WasmEnv* _Env;
|
||||
IM3Runtime _Runtime;
|
||||
TArray<WasmModuleInstance*> _AllModuleInstances;
|
||||
uint16 _RuntimeSeq;
|
||||
|
||||
WasmStackAllocCacheInfo CurrentStackAllocInfo;
|
||||
WasmStackAllocCacheInfo BaseStackAllocInfo;
|
||||
WASM_PTR MaxWasmStackAllocCount = 0;
|
||||
|
||||
public:
|
||||
WasmEnv* GetEnv()
|
||||
{
|
||||
return _Env;
|
||||
}
|
||||
WasmStackAllocCacheInfo GetCurrentStackAllocInfo()
|
||||
{
|
||||
return CurrentStackAllocInfo;
|
||||
}
|
||||
WasmStackAllocCacheInfo AllocStackParam(int Count)
|
||||
{
|
||||
WasmStackAllocCacheInfo ret = CurrentStackAllocInfo;
|
||||
if (Count < 8)
|
||||
Count = 8;
|
||||
CurrentStackAllocInfo.PtrInWasm += Count;
|
||||
CurrentStackAllocInfo.RealPtr += Count;
|
||||
check(CurrentStackAllocInfo.PtrInWasm - BaseStackAllocInfo.PtrInWasm < MaxWasmStackAllocCount);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void RestoreCurrentStackAllocInfo(const WasmStackAllocCacheInfo& NewInfo)
|
||||
{
|
||||
check(NewInfo.PtrInWasm >= BaseStackAllocInfo.PtrInWasm && NewInfo.RealPtr >= BaseStackAllocInfo.RealPtr);
|
||||
CurrentStackAllocInfo = NewInfo;
|
||||
}
|
||||
|
||||
WasmRuntime(WasmEnv* Env, int MaxPage = 10, int InitPage = 1, int StackSizeInBytes = 5 * 1024);
|
||||
~WasmRuntime();
|
||||
|
||||
int Grow(int number);
|
||||
uint8* GetBuffer(int& Length);
|
||||
|
||||
uint16 GetRuntimeSeq() const
|
||||
{
|
||||
return _RuntimeSeq;
|
||||
}
|
||||
|
||||
WasmModuleInstance* GetModuleInstance(int index) const
|
||||
{
|
||||
return _AllModuleInstances[index];
|
||||
}
|
||||
|
||||
WasmModuleInstance* OnModuleInstance(WasmModuleInstance* InModuleInstance);
|
||||
|
||||
FORCEINLINE IM3Runtime GetRuntime() const
|
||||
{
|
||||
return _Runtime;
|
||||
}
|
||||
|
||||
//转换wasm与host的地址
|
||||
void* GetPlatformAddress(WASM_PTR ptr);
|
||||
|
||||
static WasmRuntime* StaticGetWasmRuntime(IM3Runtime Runtime);
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making Puerts available.
|
||||
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may
|
||||
* be subject to their corresponding license terms. This file is subject to the terms and conditions defined in file 'LICENSE',
|
||||
* which is part of this source code package.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "CoreMinimal.h"
|
||||
#include "wasm3.h"
|
||||
#include "m3_env.h"
|
||||
#include "WasmBindingTemplate.hpp"
|
||||
|
||||
typedef bool (*WasmStaticLinkClassFunction)(IM3Module _Module);
|
||||
|
||||
class WASMCORE_API WasmStaticLinkClass
|
||||
{
|
||||
public:
|
||||
WasmStaticLinkClass(WasmStaticLinkClassFunction func, int Category);
|
||||
|
||||
static bool Link(IM3Module _Module, int Category);
|
||||
};
|
||||
|
||||
#define WASM_BEGIN_LINK_GLOBAL(GlobalID, Category) \
|
||||
static bool _WASM_##GlobalID##_Link_##Category##_Func(IM3Module _Module) \
|
||||
{
|
||||
#define WASM_LINK_GLOBAL(Func) \
|
||||
if (!wasm_link_wrapper<decltype(Func), Func>::link(_Module, #Func)) \
|
||||
return false;
|
||||
|
||||
#define WASM_LINK_GLOBAL_WITH_NAME(Func, LinkName) \
|
||||
if (!wasm_link_wrapper<decltype(Func), Func>::link(_Module, #LinkName)) \
|
||||
return false;
|
||||
|
||||
#define WASM_END_LINK_GLOBAL(GlobalID, Category) \
|
||||
return true; \
|
||||
} \
|
||||
; \
|
||||
static WasmStaticLinkClass _WASM_##GlobalID##_Link_##Category##_Func_ExportMember( \
|
||||
_WASM_##GlobalID##_Link_##Category##_Func, Category);
|
||||
Reference in New Issue
Block a user