Coverage Report

Created: 2026-11-12 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/WasmEdge/lib/executor/engine/tableInstr.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
6
namespace WasmEdge {
7
namespace Executor {
8
9
Expect<void> Executor::runTableGetOp(Runtime::StackManager &StackMgr,
10
                                     Runtime::Instance::TableInstance &TabInst,
11
0
                                     const AST::Instruction &Instr) {
12
  // Pop Idx from the stack.
13
0
  const auto AddrType = TabInst.getTableType().getLimit().getAddrType();
14
0
  uint64_t Idx = extractAddr(StackMgr.pop(), AddrType);
15
16
  // Get table[Idx] and push it to the stack.
17
0
  return TabInst.getRefAddr(Idx)
18
0
      .map_error([&Instr, &Idx, &AddrType](auto E) {
19
0
        spdlog::error(ErrInfo::InfoInstruction(
20
0
            Instr.getOpCode(), Instr.getOffset(), {Idx},
21
0
            {ValTypeFromAddressType(AddrType)}));
22
0
        return E;
23
0
      })
24
0
      .and_then([&](auto Ref) -> Expect<void> {
25
0
        StackMgr.push(Ref);
26
0
        return {};
27
0
      });
28
0
}
29
30
Expect<void> Executor::runTableSetOp(Runtime::StackManager &StackMgr,
31
                                     Runtime::Instance::TableInstance &TabInst,
32
0
                                     const AST::Instruction &Instr) {
33
  // Pop Ref from the stack.
34
0
  RefVariant Ref = StackMgr.pop().get<RefVariant>();
35
36
  // Pop Idx from the stack.
37
0
  const auto AddrType = TabInst.getTableType().getLimit().getAddrType();
38
0
  uint64_t Idx = extractAddr(StackMgr.pop(), AddrType);
39
40
  // Set table[Idx] with Ref.
41
0
  return TabInst.setRefAddr(Idx, Ref).map_error([&Instr, &Idx,
42
0
                                                 &AddrType](auto E) {
43
0
    spdlog::error(ErrInfo::InfoInstruction(Instr.getOpCode(), Instr.getOffset(),
44
0
                                           {Idx},
45
0
                                           {ValTypeFromAddressType(AddrType)}));
46
0
    return E;
47
0
  });
48
0
}
49
50
Expect<void>
51
Executor::runTableInitOp(Runtime::StackManager &StackMgr,
52
                         Runtime::Instance::TableInstance &TabInst,
53
                         Runtime::Instance::ElementInstance &ElemInst,
54
0
                         const AST::Instruction &Instr) {
55
  // Pop the length, source, and destination from the stack.
56
  // Currently, the length and source offset from the element instance are
57
  // 32-bit.
58
0
  uint64_t Len = static_cast<uint64_t>(StackMgr.pop().get<uint32_t>());
59
0
  uint64_t Src = static_cast<uint64_t>(StackMgr.pop().get<uint32_t>());
60
0
  const auto AddrType = TabInst.getTableType().getLimit().getAddrType();
61
0
  uint64_t Dst = extractAddr(StackMgr.pop(), AddrType);
62
63
  // Replace tab[Dst : Dst + Len] with elem[Src : Src + Len].
64
0
  return TabInst.setRefs(ElemInst.getRefs(), Dst, Src, Len)
65
0
      .map_error([&Instr](auto E) {
66
0
        spdlog::error(
67
0
            ErrInfo::InfoInstruction(Instr.getOpCode(), Instr.getOffset()));
68
0
        return E;
69
0
      });
70
0
}
71
72
Expect<void>
73
0
Executor::runElemDropOp(Runtime::Instance::ElementInstance &ElemInst) {
74
  // Clear element instance.
75
0
  ElemInst.clear();
76
0
  return {};
77
0
}
78
79
Expect<void>
80
Executor::runTableCopyOp(Runtime::StackManager &StackMgr,
81
                         Runtime::Instance::TableInstance &TabInstDst,
82
                         Runtime::Instance::TableInstance &TabInstSrc,
83
0
                         const AST::Instruction &Instr) {
84
  // Pop the length, source, and destination from the stack.
85
0
  const auto AddrType1 = TabInstSrc.getTableType().getLimit().getAddrType();
86
0
  const auto AddrType2 = TabInstDst.getTableType().getLimit().getAddrType();
87
0
  uint64_t Len = extractAddr(StackMgr.pop(), std::min(AddrType1, AddrType2));
88
0
  uint64_t Src = extractAddr(StackMgr.pop(), AddrType1);
89
0
  uint64_t Dst = extractAddr(StackMgr.pop(), AddrType2);
90
91
  // Replace tab_dst[Dst : Dst + Len] with tab_src[Src : Src + Len].
92
  // The overlapping region cases are handled in the setRefs() internal.
93
0
  auto LogError = [&Instr](auto E) {
94
0
    spdlog::error(
95
0
        ErrInfo::InfoInstruction(Instr.getOpCode(), Instr.getOffset()));
96
0
    return E;
97
0
  };
98
0
  EXPECTED_TRY(auto Refs, TabInstSrc.getRefs(Src, Len).map_error(LogError));
99
0
  return TabInstDst.setRefs(Refs, Dst, 0, Len).map_error(LogError);
100
0
}
101
102
Expect<void>
103
Executor::runTableGrowOp(Runtime::StackManager &StackMgr,
104
0
                         Runtime::Instance::TableInstance &TabInst) {
105
  // Pop N for the growing size and Val for the initial reference value.
106
0
  const auto AddrType = TabInst.getTableType().getLimit().getAddrType();
107
0
  uint64_t N = extractAddr(StackMgr.pop(), AddrType);
108
0
  RefVariant Ref = StackMgr.pop().get<RefVariant>();
109
110
  // Grow size and push result.
111
0
  const uint64_t CurrSize = TabInst.getSize();
112
0
  if (TabInst.growTable(N, Ref)) {
113
0
    StackMgr.push(emplaceAddr(CurrSize, AddrType));
114
0
  } else {
115
0
    StackMgr.push(emplaceAddr(static_cast<uint64_t>(-1), AddrType));
116
0
  }
117
0
  return {};
118
0
}
119
120
Expect<void>
121
Executor::runTableSizeOp(Runtime::StackManager &StackMgr,
122
0
                         Runtime::Instance::TableInstance &TabInst) {
123
  // Push SZ = size to the stack.
124
0
  const auto AddrType = TabInst.getTableType().getLimit().getAddrType();
125
0
  StackMgr.push(emplaceAddr(TabInst.getSize(), AddrType));
126
0
  return {};
127
0
}
128
129
Expect<void> Executor::runTableFillOp(Runtime::StackManager &StackMgr,
130
                                      Runtime::Instance::TableInstance &TabInst,
131
0
                                      const AST::Instruction &Instr) {
132
  // Pop the length, ref_value, and offset from the stack.
133
0
  const auto AddrType = TabInst.getTableType().getLimit().getAddrType();
134
0
  uint64_t Len = extractAddr(StackMgr.pop(), AddrType);
135
0
  RefVariant Val = StackMgr.pop().get<RefVariant>();
136
0
  uint64_t Off = extractAddr(StackMgr.pop(), AddrType);
137
138
  // Fill refs with ref_value.
139
0
  return TabInst.fillRefs(Val, Off, Len).map_error([&Instr](auto E) {
140
0
    spdlog::error(
141
0
        ErrInfo::InfoInstruction(Instr.getOpCode(), Instr.getOffset()));
142
0
    return E;
143
0
  });
144
0
}
145
146
} // namespace Executor
147
} // namespace WasmEdge