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