Coverage Report

Created: 2026-07-16 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/WasmEdge/lib/executor/engine/memoryInstr.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>
10
Executor::runMemorySizeOp(Runtime::StackManager &StackMgr,
11
0
                          Runtime::Instance::MemoryInstance &MemInst) {
12
  // Push SZ = page size to the stack.
13
0
  const auto AddrType = MemInst.getMemoryType().getLimit().getAddrType();
14
0
  StackMgr.push(emplaceAddr(MemInst.getPageSize(), AddrType));
15
0
  return {};
16
0
}
17
18
Expect<void>
19
Executor::runMemoryGrowOp(Runtime::StackManager &StackMgr,
20
0
                          Runtime::Instance::MemoryInstance &MemInst) {
21
  // Pop N, the number of pages to grow.
22
0
  const auto AddrType = MemInst.getMemoryType().getLimit().getAddrType();
23
0
  uint64_t N = extractAddr(StackMgr.pop(), AddrType);
24
25
  // Grow the page and push the result.
26
0
  const uint64_t CurrPageSize = MemInst.getPageSize();
27
0
  if (MemInst.growPage(N)) {
28
0
    StackMgr.push(emplaceAddr(CurrPageSize, AddrType));
29
0
  } else {
30
0
    StackMgr.push(emplaceAddr(static_cast<uint64_t>(-1), AddrType));
31
0
  }
32
0
  return {};
33
0
}
34
35
Expect<void> Executor::runMemoryInitOp(
36
    Runtime::StackManager &StackMgr, Runtime::Instance::MemoryInstance &MemInst,
37
0
    Runtime::Instance::DataInstance &DataInst, const AST::Instruction &Instr) {
38
  // Pop the length, source, and destination from the stack.
39
  // Currently, the length and source offset from the data instance are
40
  // 32-bit.
41
0
  uint64_t Len = static_cast<uint64_t>(StackMgr.pop().get<uint32_t>());
42
0
  uint64_t Src = static_cast<uint64_t>(StackMgr.pop().get<uint32_t>());
43
0
  const auto AddrType = MemInst.getMemoryType().getLimit().getAddrType();
44
0
  uint64_t Dst = extractAddr(StackMgr.pop(), AddrType);
45
46
  // Replace mem[Dst : Dst + Len] with data[Src : Src + Len].
47
0
  return MemInst.setBytes(DataInst.getData(), Dst, Src, Len)
48
0
      .map_error([&Instr](auto E) {
49
0
        spdlog::error(
50
0
            ErrInfo::InfoInstruction(Instr.getOpCode(), Instr.getOffset()));
51
0
        return E;
52
0
      });
53
0
}
54
55
Expect<void>
56
0
Executor::runDataDropOp(Runtime::Instance::DataInstance &DataInst) {
57
  // Clear data instance.
58
0
  DataInst.clear();
59
0
  return {};
60
0
}
61
62
Expect<void>
63
Executor::runMemoryCopyOp(Runtime::StackManager &StackMgr,
64
                          Runtime::Instance::MemoryInstance &MemInstDst,
65
                          Runtime::Instance::MemoryInstance &MemInstSrc,
66
0
                          const AST::Instruction &Instr) {
67
  // Pop the length, source, and destination from the stack.
68
0
  const auto AddrType1 = MemInstSrc.getMemoryType().getLimit().getAddrType();
69
0
  const auto AddrType2 = MemInstDst.getMemoryType().getLimit().getAddrType();
70
0
  uint64_t Len = extractAddr(StackMgr.pop(), std::min(AddrType1, AddrType2));
71
0
  uint64_t Src = extractAddr(StackMgr.pop(), AddrType1);
72
0
  uint64_t Dst = extractAddr(StackMgr.pop(), AddrType2);
73
74
  // Replace mem[Dst : Dst + Len] with mem[Src : Src + Len].
75
  // The overlapping region cases are handled in the setBytes() internal.
76
0
  auto LogError = [&Instr](auto E) {
77
0
    spdlog::error(
78
0
        ErrInfo::InfoInstruction(Instr.getOpCode(), Instr.getOffset()));
79
0
    return E;
80
0
  };
81
0
  EXPECTED_TRY(auto Data, MemInstSrc.getBytes(Src, Len).map_error(LogError));
82
0
  return MemInstDst.setBytes(Data, Dst, 0, Len).map_error(LogError);
83
0
}
84
85
Expect<void>
86
Executor::runMemoryFillOp(Runtime::StackManager &StackMgr,
87
                          Runtime::Instance::MemoryInstance &MemInst,
88
0
                          const AST::Instruction &Instr) {
89
  // Pop the length, value, and offset from the stack.
90
0
  const auto AddrType = MemInst.getMemoryType().getLimit().getAddrType();
91
0
  uint64_t Len = extractAddr(StackMgr.pop(), AddrType);
92
0
  uint8_t Val = static_cast<uint8_t>(StackMgr.pop().get<uint32_t>());
93
0
  uint64_t Off = extractAddr(StackMgr.pop(), AddrType);
94
95
  // Fill data with Val.
96
0
  return MemInst.fillBytes(Val, Off, Len).map_error([&Instr](auto E) {
97
0
    spdlog::error(
98
0
        ErrInfo::InfoInstruction(Instr.getOpCode(), Instr.getOffset()));
99
0
    return E;
100
0
  });
101
0
}
102
103
} // namespace Executor
104
} // namespace WasmEdge