Coverage Report

Created: 2026-11-09 06:49

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