Coverage Report

Created: 2025-08-29 06:29

/src/WasmEdge/lib/executor/engine/proxy.cpp
Line
Count
Source (jump to first uncovered line)
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: 2019-2024 Second State INC
3
4
#include "executor/executor.h"
5
#include "system/fault.h"
6
7
#include <cstdint>
8
9
namespace WasmEdge {
10
namespace Executor {
11
12
thread_local Executor *Executor::This = nullptr;
13
thread_local Runtime::StackManager *Executor::CurrentStack = nullptr;
14
thread_local Executor::ExecutionContextStruct Executor::ExecutionContext;
15
thread_local std::array<uint32_t, 256> Executor::StackTrace;
16
thread_local size_t Executor::StackTraceSize = 0;
17
18
template <typename RetT, typename... ArgsT>
19
struct Executor::ProxyHelper<Expect<RetT> (Executor::*)(Runtime::StackManager &,
20
                                                        ArgsT...) noexcept> {
21
  template <Expect<RetT> (Executor::*Func)(Runtime::StackManager &,
22
                                           ArgsT...) noexcept>
23
0
  static auto proxy(ArgsT... Args) {
24
#if defined(__s390x__)
25
    // Required on s390x: materializing args prevents runtime failures in
26
    // release builds.
27
    auto Materialize = [](auto &&A) -> decltype(auto) {
28
      using T = std::decay_t<decltype(A)>;
29
      if constexpr (std::is_integral_v<T>) {
30
        volatile T Tmp = A;
31
        return Tmp;
32
      } else {
33
        return std::forward<decltype(A)>(A);
34
      }
35
    };
36
    Expect<RetT> Res = (This->*Func)(*CurrentStack, Materialize(Args)...);
37
#else
38
0
    Expect<RetT> Res = (This->*Func)(*CurrentStack, Args...);
39
0
#endif
40
0
    if (unlikely(!Res)) {
41
0
      Fault::emitFault(Res.error());
42
0
    }
43
0
    if constexpr (std::is_same_v<RetT, RefVariant>) {
44
#if defined(_MSC_VER) && !defined(__clang__) // MSVC
45
      return *reinterpret_cast<__m128 *>((*Res).getRawData().data());
46
#else
47
0
      return (*Res).getRawData();
48
0
#endif // MSVC
49
0
    } else if constexpr (!std::is_void_v<RetT>) {
50
0
      return *Res;
51
0
    }
52
0
  }
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyTrap>(unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant> const*, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant>*) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyCall>(unsigned int, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant> const*, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant>*)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int, unsigned int, unsigned int, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant> const*, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant>*) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyCallIndirect>(unsigned int, unsigned int, unsigned int, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant> const*, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant>*)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, WasmEdge::RefVariant, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant> const*, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant>*) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyCallRef>(WasmEdge::RefVariant, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant> const*, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant>*)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<WasmEdge::RefVariant, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyRefFunc>(unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<WasmEdge::RefVariant, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant> const*, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyStructNew>(unsigned int, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant> const*, unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, WasmEdge::RefVariant, unsigned int, unsigned int, bool, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant>*) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyStructGet>(WasmEdge::RefVariant, unsigned int, unsigned int, bool, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant>*)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, WasmEdge::RefVariant, unsigned int, unsigned int, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant> const*) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyStructSet>(WasmEdge::RefVariant, unsigned int, unsigned int, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant> const*)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<WasmEdge::RefVariant, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int, unsigned int, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant> const*, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyArrayNew>(unsigned int, unsigned int, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant> const*, unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<WasmEdge::RefVariant, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int, unsigned int, unsigned int, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyArrayNewData>(unsigned int, unsigned int, unsigned int, unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<WasmEdge::RefVariant, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int, unsigned int, unsigned int, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyArrayNewElem>(unsigned int, unsigned int, unsigned int, unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, WasmEdge::RefVariant, unsigned int, unsigned int, bool, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant>*) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyArrayGet>(WasmEdge::RefVariant, unsigned int, unsigned int, bool, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant>*)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, WasmEdge::RefVariant, unsigned int, unsigned int, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant> const*) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyArraySet>(WasmEdge::RefVariant, unsigned int, unsigned int, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant> const*)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<unsigned int, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, WasmEdge::RefVariant) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyArrayLen>(WasmEdge::RefVariant)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, WasmEdge::RefVariant, unsigned int, unsigned int, unsigned int, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant> const*) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyArrayFill>(WasmEdge::RefVariant, unsigned int, unsigned int, unsigned int, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, unsigned long __vector(2), long __vector(2), unsigned int __vector(4), int __vector(4), unsigned short __vector(8), short __vector(8), unsigned char __vector(16), signed char __vector(16), float __vector(4), double __vector(2), WasmEdge::RefVariant> const*)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, WasmEdge::RefVariant, unsigned int, unsigned int, WasmEdge::RefVariant, unsigned int, unsigned int, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyArrayCopy>(WasmEdge::RefVariant, unsigned int, unsigned int, WasmEdge::RefVariant, unsigned int, unsigned int, unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, WasmEdge::RefVariant, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyArrayInitData>(WasmEdge::RefVariant, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, WasmEdge::RefVariant, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyArrayInitElem>(WasmEdge::RefVariant, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<unsigned int, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, WasmEdge::RefVariant, WasmEdge::ValType) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyRefTest>(WasmEdge::RefVariant, WasmEdge::ValType)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<WasmEdge::RefVariant, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, WasmEdge::RefVariant, WasmEdge::ValType) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyRefCast>(WasmEdge::RefVariant, WasmEdge::ValType)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<WasmEdge::RefVariant, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyTableGet>(unsigned int, unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int, unsigned int, WasmEdge::RefVariant) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyTableSet>(unsigned int, unsigned int, WasmEdge::RefVariant)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyTableInit>(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyElemDrop>(unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyTableCopy>(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<unsigned int, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int, WasmEdge::RefVariant, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyTableGrow>(unsigned int, WasmEdge::RefVariant, unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<unsigned int, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyTableSize>(unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int, unsigned int, WasmEdge::RefVariant, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyTableFill>(unsigned int, unsigned int, WasmEdge::RefVariant, unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<unsigned int, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyMemGrow>(unsigned int, unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<unsigned int, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyMemSize>(unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyMemInit>(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyDataDrop>(unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyMemCopy>(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int, unsigned int, unsigned char, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyMemFill>(unsigned int, unsigned int, unsigned char, unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<unsigned int, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int, unsigned int, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyMemAtomicNotify>(unsigned int, unsigned int, unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<unsigned int, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int, unsigned int, unsigned long, long, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyMemAtomicWait>(unsigned int, unsigned int, unsigned long, long, unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void*, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, unsigned int, unsigned int, unsigned int) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyTableGetFuncSymbol>(unsigned int, unsigned int, unsigned int)
Unexecuted instantiation: auto WasmEdge::Executor::Executor::ProxyHelper<cxx20::expected<void*, WasmEdge::ErrCode> (WasmEdge::Executor::Executor::*)(WasmEdge::Runtime::StackManager&, WasmEdge::RefVariant) noexcept>::proxy<&WasmEdge::Executor::Executor::proxyRefGetFuncSymbol>(WasmEdge::RefVariant)
53
};
54
55
#if defined(__clang_major__) && __clang_major__ >= 10
56
#pragma clang diagnostic push
57
#pragma clang diagnostic ignored "-Wc99-designator"
58
#endif
59
60
// Intrinsics table
61
const Executable::IntrinsicsTable Executor::Intrinsics = {
62
#if defined(_MSC_VER) && !defined(__clang__)
63
#define ENTRY(NAME, FUNC)                                                      \
64
  reinterpret_cast<void *>(&Executor::ProxyHelper<                             \
65
                           decltype(&Executor::FUNC)>::proxy<&Executor::FUNC>)
66
#else
67
#define ENTRY(NAME, FUNC)                                                      \
68
  [uint8_t(Executable::Intrinsics::NAME)] = reinterpret_cast<void *>(          \
69
      &Executor::ProxyHelper<decltype(&Executor::FUNC)>::proxy<                \
70
          &Executor::FUNC>)
71
#endif
72
    ENTRY(kTrap, proxyTrap),
73
    ENTRY(kCall, proxyCall),
74
    ENTRY(kCallIndirect, proxyCallIndirect),
75
    ENTRY(kCallRef, proxyCallRef),
76
    ENTRY(kRefFunc, proxyRefFunc),
77
    ENTRY(kStructNew, proxyStructNew),
78
    ENTRY(kStructGet, proxyStructGet),
79
    ENTRY(kStructSet, proxyStructSet),
80
    ENTRY(kArrayNew, proxyArrayNew),
81
    ENTRY(kArrayNewData, proxyArrayNewData),
82
    ENTRY(kArrayNewElem, proxyArrayNewElem),
83
    ENTRY(kArrayGet, proxyArrayGet),
84
    ENTRY(kArraySet, proxyArraySet),
85
    ENTRY(kArrayLen, proxyArrayLen),
86
    ENTRY(kArrayFill, proxyArrayFill),
87
    ENTRY(kArrayCopy, proxyArrayCopy),
88
    ENTRY(kArrayInitData, proxyArrayInitData),
89
    ENTRY(kArrayInitElem, proxyArrayInitElem),
90
    ENTRY(kRefTest, proxyRefTest),
91
    ENTRY(kRefCast, proxyRefCast),
92
    ENTRY(kTableGet, proxyTableGet),
93
    ENTRY(kTableSet, proxyTableSet),
94
    ENTRY(kTableInit, proxyTableInit),
95
    ENTRY(kElemDrop, proxyElemDrop),
96
    ENTRY(kTableCopy, proxyTableCopy),
97
    ENTRY(kTableGrow, proxyTableGrow),
98
    ENTRY(kTableSize, proxyTableSize),
99
    ENTRY(kTableFill, proxyTableFill),
100
    ENTRY(kMemGrow, proxyMemGrow),
101
    ENTRY(kMemSize, proxyMemSize),
102
    ENTRY(kMemInit, proxyMemInit),
103
    ENTRY(kDataDrop, proxyDataDrop),
104
    ENTRY(kMemCopy, proxyMemCopy),
105
    ENTRY(kMemFill, proxyMemFill),
106
    ENTRY(kMemAtomicNotify, proxyMemAtomicNotify),
107
    ENTRY(kMemAtomicWait, proxyMemAtomicWait),
108
    ENTRY(kTableGetFuncSymbol, proxyTableGetFuncSymbol),
109
    ENTRY(kRefGetFuncSymbol, proxyRefGetFuncSymbol),
110
#undef ENTRY
111
};
112
113
#if defined(__clang_major__) && __clang_major__ >= 10
114
#pragma clang diagnostic pop
115
#endif
116
117
Expect<void> Executor::proxyTrap(Runtime::StackManager &,
118
0
                                 const uint32_t Code) noexcept {
119
0
  return Unexpect(static_cast<ErrCategory>(Code >> 24), Code);
120
0
}
121
122
Expect<void> Executor::proxyCall(Runtime::StackManager &StackMgr,
123
                                 const uint32_t FuncIdx, const ValVariant *Args,
124
0
                                 ValVariant *Rets) noexcept {
125
0
  const auto *FuncInst = getFuncInstByIdx(StackMgr, FuncIdx);
126
0
  const auto &FuncType = FuncInst->getFuncType();
127
0
  const uint32_t ParamsSize =
128
0
      static_cast<uint32_t>(FuncType.getParamTypes().size());
129
0
  const uint32_t ReturnsSize =
130
0
      static_cast<uint32_t>(FuncType.getReturnTypes().size());
131
132
0
  for (uint32_t I = 0; I < ParamsSize; ++I) {
133
0
    StackMgr.push(Args[I]);
134
0
  }
135
136
0
  auto Instrs = FuncInst->getInstrs();
137
0
  EXPECTED_TRY(auto StartIt, enterFunction(StackMgr, *FuncInst, Instrs.end()));
138
0
  EXPECTED_TRY(execute(StackMgr, StartIt, Instrs.end()));
139
140
0
  for (uint32_t I = 0; I < ReturnsSize; ++I) {
141
0
    Rets[ReturnsSize - 1 - I] = StackMgr.pop();
142
0
  }
143
0
  return {};
144
0
}
145
146
Expect<void> Executor::proxyCallIndirect(Runtime::StackManager &StackMgr,
147
                                         const uint32_t TableIdx,
148
                                         const uint32_t FuncTypeIdx,
149
                                         const uint32_t FuncIdx,
150
                                         const ValVariant *Args,
151
0
                                         ValVariant *Rets) noexcept {
152
0
  const auto *TabInst = getTabInstByIdx(StackMgr, TableIdx);
153
0
  assuming(TabInst);
154
155
0
  if (unlikely(FuncIdx >= TabInst->getSize())) {
156
0
    return Unexpect(ErrCode::Value::UndefinedElement);
157
0
  }
158
159
0
  auto Ref = TabInst->getRefAddr(FuncIdx);
160
0
  assuming(Ref);
161
0
  if (unlikely(Ref->isNull())) {
162
0
    return Unexpect(ErrCode::Value::UninitializedElement);
163
0
  }
164
165
0
  const auto *ModInst = StackMgr.getModule();
166
0
  assuming(ModInst);
167
0
  const auto &ExpDefType = **ModInst->getType(FuncTypeIdx);
168
0
  const auto *FuncInst = retrieveFuncRef(*Ref);
169
0
  assuming(FuncInst);
170
0
  bool IsMatch = false;
171
0
  if (FuncInst->getModule()) {
172
0
    IsMatch = AST::TypeMatcher::matchType(
173
0
        ModInst->getTypeList(), *ExpDefType.getTypeIndex(),
174
0
        FuncInst->getModule()->getTypeList(), FuncInst->getTypeIndex());
175
0
  } else {
176
    // Independent host module instance case. Matching the composite type
177
    // directly.
178
0
    IsMatch = AST::TypeMatcher::matchType(
179
0
        ModInst->getTypeList(), ExpDefType.getCompositeType(),
180
0
        FuncInst->getHostFunc().getDefinedType().getCompositeType());
181
0
  }
182
0
  if (!IsMatch) {
183
0
    return Unexpect(ErrCode::Value::IndirectCallTypeMismatch);
184
0
  }
185
186
0
  const auto &FuncType = FuncInst->getFuncType();
187
0
  const uint32_t ParamsSize =
188
0
      static_cast<uint32_t>(FuncType.getParamTypes().size());
189
0
  const uint32_t ReturnsSize =
190
0
      static_cast<uint32_t>(FuncType.getReturnTypes().size());
191
192
0
  for (uint32_t I = 0; I < ParamsSize; ++I) {
193
0
    StackMgr.push(Args[I]);
194
0
  }
195
196
0
  auto Instrs = FuncInst->getInstrs();
197
0
  EXPECTED_TRY(auto StartIt, enterFunction(StackMgr, *FuncInst, Instrs.end()));
198
0
  EXPECTED_TRY(execute(StackMgr, StartIt, Instrs.end()));
199
200
0
  for (uint32_t I = 0; I < ReturnsSize; ++I) {
201
0
    Rets[ReturnsSize - 1 - I] = StackMgr.pop();
202
0
  }
203
0
  return {};
204
0
}
205
206
Expect<void> Executor::proxyCallRef(Runtime::StackManager &StackMgr,
207
                                    const RefVariant Ref,
208
                                    const ValVariant *Args,
209
0
                                    ValVariant *Rets) noexcept {
210
0
  const auto *FuncInst = retrieveFuncRef(Ref);
211
0
  const auto &FuncType = FuncInst->getFuncType();
212
0
  const uint32_t ParamsSize =
213
0
      static_cast<uint32_t>(FuncType.getParamTypes().size());
214
0
  const uint32_t ReturnsSize =
215
0
      static_cast<uint32_t>(FuncType.getReturnTypes().size());
216
217
0
  for (uint32_t I = 0; I < ParamsSize; ++I) {
218
0
    StackMgr.push(Args[I]);
219
0
  }
220
221
0
  auto Instrs = FuncInst->getInstrs();
222
0
  EXPECTED_TRY(auto StartIt, enterFunction(StackMgr, *FuncInst, Instrs.end()));
223
0
  EXPECTED_TRY(execute(StackMgr, StartIt, Instrs.end()));
224
225
0
  for (uint32_t I = 0; I < ReturnsSize; ++I) {
226
0
    Rets[ReturnsSize - 1 - I] = StackMgr.pop();
227
0
  }
228
229
0
  return {};
230
0
}
231
232
Expect<RefVariant> Executor::proxyRefFunc(Runtime::StackManager &StackMgr,
233
0
                                          const uint32_t FuncIdx) noexcept {
234
0
  auto *FuncInst = getFuncInstByIdx(StackMgr, FuncIdx);
235
0
  assuming(FuncInst);
236
0
  return RefVariant(FuncInst->getDefType(), FuncInst);
237
0
}
238
239
Expect<RefVariant> Executor::proxyStructNew(Runtime::StackManager &StackMgr,
240
                                            const uint32_t TypeIdx,
241
                                            const ValVariant *Args,
242
0
                                            const uint32_t ArgSize) noexcept {
243
0
  if (Args == nullptr) {
244
0
    return structNew(StackMgr, TypeIdx);
245
0
  } else {
246
0
    return structNew(StackMgr, TypeIdx, Span<const ValVariant>(Args, ArgSize));
247
0
  }
248
0
}
249
250
Expect<void> Executor::proxyStructGet(Runtime::StackManager &StackMgr,
251
                                      const RefVariant Ref,
252
                                      const uint32_t TypeIdx,
253
                                      const uint32_t Off, const bool IsSigned,
254
0
                                      ValVariant *Ret) noexcept {
255
0
  EXPECTED_TRY(auto Val, structGet(StackMgr, Ref, TypeIdx, Off, IsSigned));
256
0
  *Ret = Val;
257
0
  return {};
258
0
}
259
260
Expect<void> Executor::proxyStructSet(Runtime::StackManager &StackMgr,
261
                                      const RefVariant Ref,
262
                                      const uint32_t TypeIdx,
263
                                      const uint32_t Off,
264
0
                                      const ValVariant *Val) noexcept {
265
0
  return structSet(StackMgr, Ref, *Val, TypeIdx, Off);
266
0
}
267
268
Expect<RefVariant> Executor::proxyArrayNew(Runtime::StackManager &StackMgr,
269
                                           const uint32_t TypeIdx,
270
                                           const uint32_t Length,
271
                                           const ValVariant *Args,
272
0
                                           const uint32_t ArgSize) noexcept {
273
0
  assuming(ArgSize == 0 || ArgSize == 1 || ArgSize == Length);
274
0
  if (ArgSize == 0) {
275
0
    return arrayNew(StackMgr, TypeIdx, Length);
276
0
  } else if (ArgSize == 1) {
277
0
    return arrayNew(StackMgr, TypeIdx, Length, {Args[0]});
278
0
  } else {
279
0
    return arrayNew(StackMgr, TypeIdx, Length,
280
0
                    Span<const ValVariant>(Args, ArgSize));
281
0
  }
282
0
}
283
284
Expect<RefVariant> Executor::proxyArrayNewData(Runtime::StackManager &StackMgr,
285
                                               const uint32_t TypeIdx,
286
                                               const uint32_t DataIdx,
287
                                               const uint32_t Start,
288
0
                                               const uint32_t Length) noexcept {
289
0
  return arrayNewData(StackMgr, TypeIdx, DataIdx, Start, Length);
290
0
}
291
292
Expect<RefVariant> Executor::proxyArrayNewElem(Runtime::StackManager &StackMgr,
293
                                               const uint32_t TypeIdx,
294
                                               const uint32_t ElemIdx,
295
                                               const uint32_t Start,
296
0
                                               const uint32_t Length) noexcept {
297
0
  return arrayNewElem(StackMgr, TypeIdx, ElemIdx, Start, Length);
298
0
}
299
300
Expect<void> Executor::proxyArrayGet(Runtime::StackManager &StackMgr,
301
                                     const RefVariant Ref,
302
                                     const uint32_t TypeIdx, const uint32_t Idx,
303
                                     const bool IsSigned,
304
0
                                     ValVariant *Ret) noexcept {
305
0
  EXPECTED_TRY(auto Val, arrayGet(StackMgr, Ref, TypeIdx, Idx, IsSigned));
306
0
  *Ret = Val;
307
0
  return {};
308
0
}
309
310
Expect<void> Executor::proxyArraySet(Runtime::StackManager &StackMgr,
311
                                     const RefVariant Ref,
312
                                     const uint32_t TypeIdx, const uint32_t Idx,
313
0
                                     const ValVariant *Val) noexcept {
314
0
  return arraySet(StackMgr, Ref, *Val, TypeIdx, Idx);
315
0
}
316
317
Expect<uint32_t> Executor::proxyArrayLen(Runtime::StackManager &,
318
0
                                         const RefVariant Ref) noexcept {
319
0
  auto *Inst = Ref.getPtr<Runtime::Instance::ArrayInstance>();
320
0
  if (Inst == nullptr) {
321
0
    return Unexpect(ErrCode::Value::AccessNullArray);
322
0
  }
323
0
  return Inst->getLength();
324
0
}
325
326
Expect<void> Executor::proxyArrayFill(Runtime::StackManager &StackMgr,
327
                                      const RefVariant Ref,
328
                                      const uint32_t TypeIdx,
329
                                      const uint32_t Idx, const uint32_t Cnt,
330
0
                                      const ValVariant *Val) noexcept {
331
0
  return arrayFill(StackMgr, Ref, *Val, TypeIdx, Idx, Cnt);
332
0
}
333
334
Expect<void>
335
Executor::proxyArrayCopy(Runtime::StackManager &StackMgr,
336
                         const RefVariant DstRef, const uint32_t DstTypeIdx,
337
                         const uint32_t DstIdx, const RefVariant SrcRef,
338
                         const uint32_t SrcTypeIdx, const uint32_t SrcIdx,
339
0
                         const uint32_t Cnt) noexcept {
340
0
  return arrayCopy(StackMgr, DstRef, DstTypeIdx, DstIdx, SrcRef, SrcTypeIdx,
341
0
                   SrcIdx, Cnt);
342
0
}
343
344
Expect<void> Executor::proxyArrayInitData(
345
    Runtime::StackManager &StackMgr, const RefVariant Ref,
346
    const uint32_t TypeIdx, const uint32_t DataIdx, const uint32_t DstIdx,
347
0
    const uint32_t SrcIdx, const uint32_t Cnt) noexcept {
348
0
  return arrayInitData(StackMgr, Ref, TypeIdx, DataIdx, DstIdx, SrcIdx, Cnt);
349
0
}
350
351
Expect<void> Executor::proxyArrayInitElem(
352
    Runtime::StackManager &StackMgr, const RefVariant Ref,
353
    const uint32_t TypeIdx, const uint32_t ElemIdx, const uint32_t DstIdx,
354
0
    const uint32_t SrcIdx, const uint32_t Cnt) noexcept {
355
0
  return arrayInitElem(StackMgr, Ref, TypeIdx, ElemIdx, DstIdx, SrcIdx, Cnt);
356
0
}
357
358
Expect<uint32_t> Executor::proxyRefTest(Runtime::StackManager &StackMgr,
359
                                        const RefVariant Ref,
360
0
                                        ValType VTTest) noexcept {
361
  // Copy the value type here due to handling the externalized case.
362
0
  auto VT = Ref.getType();
363
0
  if (VT.isExternalized()) {
364
0
    VT = ValType(TypeCode::Ref, TypeCode::ExternRef);
365
0
  }
366
0
  const auto *ModInst = StackMgr.getModule();
367
0
  assuming(ModInst);
368
0
  Span<const AST::SubType *const> GotTypeList = ModInst->getTypeList();
369
0
  if (!VT.isAbsHeapType()) {
370
0
    auto *Inst = Ref.getPtr<Runtime::Instance::CompositeBase>();
371
    // Reference must not be nullptr here because the null references are typed
372
    // with the least abstract heap type.
373
0
    if (Inst->getModule()) {
374
0
      GotTypeList = Inst->getModule()->getTypeList();
375
0
    }
376
0
  }
377
378
0
  if (AST::TypeMatcher::matchType(ModInst->getTypeList(), VTTest, GotTypeList,
379
0
                                  VT)) {
380
0
    return static_cast<uint32_t>(1);
381
0
  } else {
382
0
    return static_cast<uint32_t>(0);
383
0
  }
384
0
}
385
386
Expect<RefVariant> Executor::proxyRefCast(Runtime::StackManager &StackMgr,
387
                                          const RefVariant Ref,
388
0
                                          ValType VTCast) noexcept {
389
  // Copy the value type here due to handling the externalized case.
390
0
  auto VT = Ref.getType();
391
0
  if (VT.isExternalized()) {
392
0
    VT = ValType(TypeCode::Ref, TypeCode::ExternRef);
393
0
  }
394
0
  const auto *ModInst = StackMgr.getModule();
395
0
  assuming(ModInst);
396
0
  Span<const AST::SubType *const> GotTypeList = ModInst->getTypeList();
397
0
  if (!VT.isAbsHeapType()) {
398
0
    auto *Inst = Ref.getPtr<Runtime::Instance::CompositeBase>();
399
    // Reference must not be nullptr here because the null references are typed
400
    // with the least abstract heap type.
401
0
    if (Inst->getModule()) {
402
0
      GotTypeList = Inst->getModule()->getTypeList();
403
0
    }
404
0
  }
405
406
0
  if (!AST::TypeMatcher::matchType(ModInst->getTypeList(), VTCast, GotTypeList,
407
0
                                   VT)) {
408
0
    return Unexpect(ErrCode::Value::CastFailed);
409
0
  }
410
0
  return Ref;
411
0
}
412
413
Expect<RefVariant> Executor::proxyTableGet(Runtime::StackManager &StackMgr,
414
                                           const uint32_t TableIdx,
415
0
                                           const uint32_t Off) noexcept {
416
0
  auto *TabInst = getTabInstByIdx(StackMgr, TableIdx);
417
0
  assuming(TabInst);
418
0
  return TabInst->getRefAddr(Off);
419
0
}
420
421
Expect<void> Executor::proxyTableSet(Runtime::StackManager &StackMgr,
422
                                     const uint32_t TableIdx,
423
                                     const uint32_t Off,
424
0
                                     const RefVariant Ref) noexcept {
425
0
  auto *TabInst = getTabInstByIdx(StackMgr, TableIdx);
426
0
  assuming(TabInst);
427
0
  return TabInst->setRefAddr(Off, Ref);
428
0
}
429
430
Expect<void> Executor::proxyTableInit(Runtime::StackManager &StackMgr,
431
                                      const uint32_t TableIdx,
432
                                      const uint32_t ElemIdx,
433
                                      const uint32_t DstOff,
434
                                      const uint32_t SrcOff,
435
0
                                      const uint32_t Len) noexcept {
436
0
  auto *TabInst = getTabInstByIdx(StackMgr, TableIdx);
437
0
  assuming(TabInst);
438
0
  auto *ElemInst = getElemInstByIdx(StackMgr, ElemIdx);
439
0
  assuming(ElemInst);
440
0
  return TabInst->setRefs(ElemInst->getRefs(), DstOff, SrcOff, Len);
441
0
}
442
443
Expect<void> Executor::proxyElemDrop(Runtime::StackManager &StackMgr,
444
0
                                     const uint32_t ElemIdx) noexcept {
445
0
  auto *ElemInst = getElemInstByIdx(StackMgr, ElemIdx);
446
0
  assuming(ElemInst);
447
0
  ElemInst->clear();
448
0
  return {};
449
0
}
450
451
Expect<void> Executor::proxyTableCopy(Runtime::StackManager &StackMgr,
452
                                      const uint32_t TableIdxDst,
453
                                      const uint32_t TableIdxSrc,
454
                                      const uint32_t DstOff,
455
                                      const uint32_t SrcOff,
456
0
                                      const uint32_t Len) noexcept {
457
0
  auto *TabInstDst = getTabInstByIdx(StackMgr, TableIdxDst);
458
0
  assuming(TabInstDst);
459
0
  auto *TabInstSrc = getTabInstByIdx(StackMgr, TableIdxSrc);
460
0
  assuming(TabInstSrc);
461
462
0
  EXPECTED_TRY(auto Refs, TabInstSrc->getRefs(0, SrcOff + Len));
463
0
  return TabInstDst->setRefs(Refs, DstOff, SrcOff, Len);
464
0
}
465
466
Expect<uint32_t> Executor::proxyTableGrow(Runtime::StackManager &StackMgr,
467
                                          const uint32_t TableIdx,
468
                                          const RefVariant Val,
469
0
                                          const uint32_t NewSize) noexcept {
470
0
  auto *TabInst = getTabInstByIdx(StackMgr, TableIdx);
471
0
  assuming(TabInst);
472
0
  const uint32_t CurrTableSize = TabInst->getSize();
473
0
  if (likely(TabInst->growTable(NewSize, Val))) {
474
0
    return CurrTableSize;
475
0
  } else {
476
0
    return static_cast<uint32_t>(-1);
477
0
  }
478
0
}
479
480
Expect<uint32_t> Executor::proxyTableSize(Runtime::StackManager &StackMgr,
481
0
                                          const uint32_t TableIdx) noexcept {
482
0
  auto *TabInst = getTabInstByIdx(StackMgr, TableIdx);
483
0
  assuming(TabInst);
484
0
  return TabInst->getSize();
485
0
}
486
487
Expect<void> Executor::proxyTableFill(Runtime::StackManager &StackMgr,
488
                                      const uint32_t TableIdx,
489
                                      const uint32_t Off, const RefVariant Ref,
490
0
                                      const uint32_t Len) noexcept {
491
0
  auto *TabInst = getTabInstByIdx(StackMgr, TableIdx);
492
0
  assuming(TabInst);
493
0
  return TabInst->fillRefs(Ref, Off, Len);
494
0
}
495
496
Expect<uint32_t> Executor::proxyMemGrow(Runtime::StackManager &StackMgr,
497
                                        const uint32_t MemIdx,
498
0
                                        const uint32_t NewSize) noexcept {
499
0
  auto *MemInst = getMemInstByIdx(StackMgr, MemIdx);
500
0
  assuming(MemInst);
501
0
  const uint32_t CurrPageSize = MemInst->getPageSize();
502
0
  if (MemInst->growPage(NewSize)) {
503
0
    return CurrPageSize;
504
0
  } else {
505
0
    return static_cast<uint32_t>(-1);
506
0
  }
507
0
}
508
509
Expect<uint32_t> Executor::proxyMemSize(Runtime::StackManager &StackMgr,
510
0
                                        const uint32_t MemIdx) noexcept {
511
0
  auto *MemInst = getMemInstByIdx(StackMgr, MemIdx);
512
0
  assuming(MemInst);
513
0
  return MemInst->getPageSize();
514
0
}
515
516
Expect<void>
517
Executor::proxyMemInit(Runtime::StackManager &StackMgr, const uint32_t MemIdx,
518
                       const uint32_t DataIdx, const uint32_t DstOff,
519
0
                       const uint32_t SrcOff, const uint32_t Len) noexcept {
520
0
  auto *MemInst = getMemInstByIdx(StackMgr, MemIdx);
521
0
  assuming(MemInst);
522
0
  auto *DataInst = getDataInstByIdx(StackMgr, DataIdx);
523
0
  assuming(DataInst);
524
0
  return MemInst->setBytes(DataInst->getData(), DstOff, SrcOff, Len);
525
0
}
526
527
Expect<void> Executor::proxyDataDrop(Runtime::StackManager &StackMgr,
528
0
                                     const uint32_t DataIdx) noexcept {
529
0
  auto *DataInst = getDataInstByIdx(StackMgr, DataIdx);
530
0
  assuming(DataInst);
531
0
  DataInst->clear();
532
0
  return {};
533
0
}
534
535
Expect<void> Executor::proxyMemCopy(Runtime::StackManager &StackMgr,
536
                                    const uint32_t DstMemIdx,
537
                                    const uint32_t SrcMemIdx,
538
                                    const uint32_t DstOff,
539
                                    const uint32_t SrcOff,
540
0
                                    const uint32_t Len) noexcept {
541
0
  auto *MemInstDst = getMemInstByIdx(StackMgr, DstMemIdx);
542
0
  assuming(MemInstDst);
543
0
  auto *MemInstSrc = getMemInstByIdx(StackMgr, SrcMemIdx);
544
0
  assuming(MemInstSrc);
545
546
0
  EXPECTED_TRY(auto Data, MemInstSrc->getBytes(SrcOff, Len));
547
0
  return MemInstDst->setBytes(Data, DstOff, 0, Len);
548
0
}
549
550
Expect<void> Executor::proxyMemFill(Runtime::StackManager &StackMgr,
551
                                    const uint32_t MemIdx, const uint32_t Off,
552
                                    const uint8_t Val,
553
0
                                    const uint32_t Len) noexcept {
554
0
  auto *MemInst = getMemInstByIdx(StackMgr, MemIdx);
555
0
  assuming(MemInst);
556
0
  return MemInst->fillBytes(Val, Off, Len);
557
0
}
558
559
Expect<uint32_t> Executor::proxyMemAtomicNotify(Runtime::StackManager &StackMgr,
560
                                                const uint32_t MemIdx,
561
                                                const uint32_t Offset,
562
0
                                                const uint32_t Count) noexcept {
563
0
  auto *MemInst = getMemInstByIdx(StackMgr, MemIdx);
564
0
  assuming(MemInst);
565
0
  return atomicNotify(*MemInst, Offset, Count);
566
0
}
567
568
Expect<uint32_t>
569
Executor::proxyMemAtomicWait(Runtime::StackManager &StackMgr,
570
                             const uint32_t MemIdx, const uint32_t Offset,
571
                             const uint64_t Expected, const int64_t Timeout,
572
0
                             const uint32_t BitWidth) noexcept {
573
0
  auto *MemInst = getMemInstByIdx(StackMgr, MemIdx);
574
0
  assuming(MemInst);
575
576
0
  if (BitWidth == 64) {
577
0
    return atomicWait<uint64_t>(*MemInst, Offset, Expected, Timeout);
578
0
  } else if (BitWidth == 32) {
579
0
    return atomicWait<uint32_t>(*MemInst, Offset,
580
0
                                static_cast<uint32_t>(Expected), Timeout);
581
0
  }
582
0
  assumingUnreachable();
583
0
}
584
585
Expect<void *> Executor::proxyTableGetFuncSymbol(
586
    Runtime::StackManager &StackMgr, const uint32_t TableIdx,
587
0
    const uint32_t FuncTypeIdx, const uint32_t FuncIdx) noexcept {
588
0
  const auto *TabInst = getTabInstByIdx(StackMgr, TableIdx);
589
0
  assuming(TabInst);
590
591
0
  if (unlikely(FuncIdx >= TabInst->getSize())) {
592
0
    return Unexpect(ErrCode::Value::UndefinedElement);
593
0
  }
594
595
0
  auto Ref = TabInst->getRefAddr(FuncIdx);
596
0
  assuming(Ref);
597
0
  if (unlikely(Ref->isNull())) {
598
0
    return Unexpect(ErrCode::Value::UninitializedElement);
599
0
  }
600
601
0
  const auto *ModInst = StackMgr.getModule();
602
0
  assuming(ModInst);
603
0
  const auto &ExpDefType = **ModInst->getType(FuncTypeIdx);
604
0
  const auto *FuncInst = retrieveFuncRef(*Ref);
605
0
  assuming(FuncInst);
606
0
  bool IsMatch = false;
607
0
  if (FuncInst->getModule()) {
608
0
    IsMatch = AST::TypeMatcher::matchType(
609
0
        ModInst->getTypeList(), *ExpDefType.getTypeIndex(),
610
0
        FuncInst->getModule()->getTypeList(), FuncInst->getTypeIndex());
611
0
  } else {
612
    // Independent host module instance case. Matching the composite type
613
    // directly.
614
0
    IsMatch = AST::TypeMatcher::matchType(
615
0
        ModInst->getTypeList(), ExpDefType.getCompositeType(),
616
0
        FuncInst->getHostFunc().getDefinedType().getCompositeType());
617
0
  }
618
0
  if (!IsMatch) {
619
0
    return Unexpect(ErrCode::Value::IndirectCallTypeMismatch);
620
0
  }
621
622
0
  if (unlikely(!FuncInst->isCompiledFunction())) {
623
0
    return nullptr;
624
0
  }
625
0
  return FuncInst->getSymbol().get();
626
0
}
627
628
Expect<void *> Executor::proxyRefGetFuncSymbol(Runtime::StackManager &,
629
0
                                               const RefVariant Ref) noexcept {
630
0
  const auto *FuncInst = retrieveFuncRef(Ref);
631
0
  assuming(FuncInst);
632
0
  if (unlikely(!FuncInst->isCompiledFunction())) {
633
0
    return nullptr;
634
0
  }
635
0
  return FuncInst->getSymbol().get();
636
0
}
637
638
} // namespace Executor
639
} // namespace WasmEdge