/* * 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 struct wasm_remove_const_ref { using type = typename std::remove_const::type>::type; }; template struct true_false_type { static constexpr bool value = V; }; template struct _wasm_is_simple_type; //定义简单的类型,该类型会直接被放在栈上 template <> struct _wasm_is_simple_type : true_false_type { }; // template<> struct _wasm_is_simple_type : true_false_type {}; // template<> struct _wasm_is_simple_type : true_false_type {}; template <> struct _wasm_is_simple_type : true_false_type { }; template <> struct _wasm_is_simple_type : true_false_type { }; template <> struct _wasm_is_simple_type : true_false_type { }; template <> struct _wasm_is_simple_type : true_false_type { }; template <> struct _wasm_is_simple_type : true_false_type { }; template <> struct _wasm_is_simple_type : true_false_type { }; // enum为true,非enum为false template struct _wasm_is_simple_type::value>::type> : true_false_type { }; template struct _wasm_is_simple_type::value>::type> : true_false_type { }; template struct wasm_is_simple_type { static constexpr bool value = _wasm_is_simple_type::type>::value; }; static_assert(wasm_is_simple_type::value, ""); static_assert(wasm_is_simple_type::value, ""); static_assert(wasm_is_simple_type::value, ""); static_assert(wasm_is_simple_type::value, ""); static_assert(!wasm_is_simple_type::value, ""); //定义复杂类型,该类型会被当作指针放在栈上 template struct _wasm_is_complex_type { //这里有点奇怪 // 属性数量大于1的结构体当指针 // 小于32的结构体当int32,小于64的结构体当int64,大于64的当指针 // 我们判断不了属性数量,所以强制规定,结构体必须大于64 static constexpr bool value = !wasm_is_simple_type::value && std::is_class::value && std::is_trivially_copyable::value && (sizeof(T) > 8); }; template struct wasm_is_complex_type { static constexpr bool value = _wasm_is_complex_type::type>::value; }; template <> struct wasm_is_complex_type { static constexpr bool value = false; }; static_assert(!wasm_is_complex_type::value, ""); template struct wasm_is_support_pointer_type { using No_PTr = typename std::remove_pointer::type; static constexpr bool value = std::is_pointer::value && !wasm_is_complex_type::value && !wasm_is_simple_type::value; }; template struct wasm_is_all_support_type; template struct wasm_is_all_support_type { static constexpr bool value = wasm_is_complex_type::value || wasm_is_simple_type::value || wasm_is_support_pointer_type::value; }; template struct wasm_is_all_support_type { static constexpr bool value = wasm_is_all_support_type::value && wasm_is_all_support_type::value; }; template struct _wasm_call_params_translator { }; template <> struct _wasm_call_params_translator { using type = float; }; template <> struct _wasm_call_params_translator { using type = double; }; template struct _wasm_call_params_translator::value && (sizeof(T) <= 4)>::type> { using type = int32; }; template struct _wasm_call_params_translator::value && (sizeof(T) > 4) && (sizeof(T) <= 8)>::type> { using type = int64; }; template struct _wasm_call_params_translator::value>::type> { using type = WASM_PTR; }; template struct _wasm_call_params_translator::value>::type> { using type = WASM_PTR; }; template struct wasm_call_params_translator { using translated_type = typename _wasm_call_params_translator::type>::type; }; template using is_enum_of_t = typename std::enable_if::value && std::is_same, U>::value>::type; template struct m3_sig { static const char value = c; }; template struct _m3_type_to_sig; template struct _m3_type_to_sig> : m3_sig<'i'> { }; template struct _m3_type_to_sig> : m3_sig<'I'> { }; template <> struct _m3_type_to_sig : m3_sig<'i'> { }; template <> struct _m3_type_to_sig : m3_sig<'i'> { }; template <> struct _m3_type_to_sig : m3_sig<'i'> { }; template <> struct _m3_type_to_sig : m3_sig<'i'> { }; template <> struct _m3_type_to_sig : m3_sig<'i'> { }; template <> struct _m3_type_to_sig : m3_sig<'I'> { }; template <> struct _m3_type_to_sig : m3_sig<'I'> { }; template <> struct _m3_type_to_sig : m3_sig<'f'> { }; template <> struct _m3_type_to_sig : m3_sig<'F'> { }; template <> struct _m3_type_to_sig : m3_sig<'v'> { }; template struct _m3_type_to_sig::type> : m3_sig<'*'> { }; template struct _m3_type_to_sig::value>::type> : m3_sig<'*'> { }; template struct _m3_type_to_sig::value>::type> : m3_sig<'*'> { }; template struct m3_type_to_sig; //引用当指针处理 template struct m3_type_to_sig::value>::type> { using TT = typename wasm_remove_const_ref::type; static const char value = '*'; }; template struct m3_type_to_sig::value>::type> { using TT = typename wasm_remove_const_ref::type; static const char value = _m3_type_to_sig::value; }; template struct m3_signature { //不支持返回值的引用 static_assert(!std::is_reference::value, ""); static const char* get() { static char value[] = {m3_type_to_sig::value, '(', m3_type_to_sig::value..., ')', 0}; return (const char*) value; } }; //记录不同类型的指针,再wasm存的类型 template struct _wasm_pointer_support_ptr_in_wasm; template struct _wasm_pointer_support_ptr_in_wasm::value>::type> { using type = UObjectBase*; }; template struct _wasm_pointer_support_ptr_in_wasm::value>::type> { using type = void*; }; template struct wasm_pointer_support_ptr_in_wasm { using type = typename _wasm_pointer_support_ptr_in_wasm< typename std::remove_pointer::type>::type>::type; }; //指针 template >, typename t_remove_pointer = typename std::remove_pointer::type> typename std::enable_if::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::type; WASM_PTR offset = *((WASM_PTR*) (_sp + index)); ptr_type_in_wasm* tmp = (ptr_type_in_wasm*) m3ApiOffsetToPtr(offset); *stack_ptr = static_cast(*tmp); return 0; } //简单类型,非引用 template >> typename std::enable_if::value && !std::is_reference::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 std::enable_if::value && std::is_reference::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; WASM_PTR offset = *((WASM_PTR*) (_sp + index)); T_noRef* tmp = (T_noRef*) m3ApiOffsetToPtr(offset); stack_ptr = tmp; return 0; } //复杂类型 template >> typename std::enable_if::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; WASM_PTR offset = *((WASM_PTR*) (_sp + index)); T_noRef* tmp = (T_noRef*) m3ApiOffsetToPtr(offset); stack_ptr = tmp; return 0; } template struct wasm_link_helper; template struct wasm_link_helper { template struct Functor; template struct Functor> { //返回值是指针 //规避malloc,需要link的函数,返回值禁止是指针 /*template static typename std::enable_if::value && !std::is_same::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()...); auto parm = std::make_tuple>...>(&std::get(stack_mem)...); auto tmp = std::make_tuple(wasm_link_get_args_from_stack(rt, _ctx, _sp, _mem, std::get(parm), Index)...); //_sp += sizeof...(Args); using T_RemoveConst = typename wasm_remove_const_ref::type; T_RemoveConst r = (T_RemoveConst)func(*std::get(parm)...); WASM_PTR ptr = TryGetWasmPointerWithObject(r, rt); { *raw_return = ptr; return nullptr; } }*/ //没有返回值 template static typename std::enable_if::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()...); auto parm = std::make_tuple>...>( &std::get(stack_mem)...); auto tmp = std::make_tuple(wasm_link_get_args_from_stack(rt, _ctx, _sp, _mem, std::get(parm), Index)...); //_sp不是引用,所以也不用加了 //_sp += sizeof...(Args); func(*std::get(parm)...); return nullptr; } //返回值是复杂类型 template static typename std::enable_if::value && !std::is_same::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::type; m3ApiReturnType(WASM_PTR); T_RemoveConst* ptr = (T_RemoveConst*) m3ApiOffsetToPtr(*raw_return); auto stack_mem = std::make_tuple...>(typename std::remove_reference_t()...); auto parm = std::make_tuple>...>( &std::get(stack_mem)...); auto tmp = std::make_tuple(wasm_link_get_args_from_stack(rt, _ctx, _sp, _mem, std::get(parm), Index)...); //_sp += sizeof...(Args); *ptr = func(*std::get(parm)...); return nullptr; } //返回值是简单类型 template static typename std::enable_if::value && !std::is_same::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()...); auto parm = std::make_tuple>...>( &std::get(stack_mem)...); auto tmp = std::make_tuple(wasm_link_get_args_from_stack(rt, _ctx, _sp, _mem, std::get(parm), Index)...); //_sp += sizeof...(Args); T r = func(*std::get(parm)...); { *raw_return = r; return nullptr; } } static const void* Invoke(IM3Runtime rt, IM3ImportContext _ctx, wasm_stack_type _sp, wasm_mem_type _mem) { return _InternalInvoke(rt, _ctx, _sp, _mem); } }; }; template struct wasm_link_wrapper; template struct wasm_link_wrapper { //为了规避malloc,暂时禁止返回值是指针的函数link /*template static typename std::enable_if::value && !std::is_same::value, bool>::type InternalLink(IM3Module _module, const char* const function_name) { //返回值不能是引用 static_assert(!std::is_reference::value, ""); return Export_m3_LinkRawFunctionEx(_module, "*", function_name, m3_signature::get(), &wasm_link_helper::template Functor>::Invoke, nullptr); }*/ template static typename std::enable_if::value, bool>::type InternalLink( IM3Module _module, const char* const function_name) { return Export_m3_LinkRawFunctionEx(_module, "*", function_name, m3_signature::get(), &wasm_link_helper::template Functor>::Invoke, nullptr); } template static typename std::enable_if::value && !std::is_same::value, bool>::type InternalLink( IM3Module _module, const char* const function_name) { //返回值不能是引用 static_assert(!std::is_reference::value, ""); return Export_m3_LinkRawFunctionEx(_module, "*", function_name, m3_signature::get(), &wasm_link_helper::template Functor>::Invoke, nullptr); } template static typename std::enable_if::value && !std::is_same::value, bool>::type InternalLink( IM3Module _module, const char* const function_name) { //返回值不能是引用 static_assert(!std::is_reference::value, ""); return Export_m3_LinkRawFunctionEx(_module, "*", function_name, m3_signature::get(), &wasm_link_helper::template Functor>::Invoke, nullptr); } static bool link(IM3Module _module, const char* const function_name) { return InternalLink(_module, function_name); } };