Coverage Report

Created: 2026-09-28 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/WasmEdge/lib/executor/engine/engine.cpp
Line
Count
Source
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright The WasmEdge Authors
3
4
#include "common/endian.h"
5
#include "executor/coredump.h"
6
#include "executor/executor.h"
7
#include "system/stacktrace.h"
8
9
#include <array>
10
#include <cstdint>
11
#include <cstring>
12
13
using namespace std::literals;
14
15
namespace WasmEdge {
16
namespace Executor {
17
18
Expect<void> Executor::runExpression(Runtime::StackManager &StackMgr,
19
0
                                     AST::InstrView Instrs) {
20
0
  return execute(StackMgr, Instrs.begin(), Instrs.end());
21
0
}
22
23
Expect<void>
24
Executor::runFunction(Runtime::StackManager &StackMgr,
25
                      const Runtime::Instance::FunctionInstance &Func,
26
0
                      Span<const ValVariant> Params) {
27
  // Set start time.
28
0
  if (Stat && Conf.getStatisticsConfigure().isTimeMeasuring()) {
29
0
    Stat->startRecordWasm();
30
0
  }
31
32
  // Clear any trace from a previous execution; its entries may reference
33
  // modules that have since been freed.
34
0
  StackTraceSize = 0;
35
36
  // Reset and push a dummy frame into stack.
37
0
  StackMgr.pushFrame(nullptr, AST::InstrView::iterator(), 0, 0);
38
39
  // Push arguments.
40
0
  const auto &PTypes = Func.getFuncType().getParamTypes();
41
0
  for (uint32_t I = 0; I < Params.size(); I++) {
42
    // For the references, transform to non-null reference type if the value not
43
    // null.
44
0
    if (PTypes[I].isRefType() && Params[I].get<RefVariant>().getPtr<void>() &&
45
0
        Params[I].get<RefVariant>().getType().isNullableRefType()) {
46
0
      auto Val = Params[I];
47
0
      Val.get<RefVariant>().getType().toNonNullableRef();
48
0
      StackMgr.push(Val);
49
0
    } else {
50
0
      StackMgr.push(Params[I]);
51
0
    }
52
0
  }
53
54
  // Enter and execute function.
55
0
  Expect<void> Res =
56
0
      enterFunction(StackMgr, Func, Func.getInstrs().end(), false, true)
57
0
          .and_then([&](AST::InstrView::iterator StartIt) {
58
            // If not terminated, execute the instructions in interpreter mode.
59
            // For the entered AOT or host functions, `StartIt` is equal to
60
            // the end of instruction list, therefore the execution will return
61
            // immediately.
62
0
            return execute(StackMgr, StartIt, Func.getInstrs().end());
63
0
          });
64
65
0
  if (unlikely(!Res && Res.error() == ErrCode::Value::PendingException)) {
66
    // The pending exception reaching the top level is not caught: consume it
67
    // and turn it into the uncaught exception error.
68
0
    assuming(PendingExn.TagInst != nullptr);
69
0
    spdlog::error(ErrCode::Value::UncaughtException);
70
0
    PendingExn = {};
71
0
    Res = Unexpect(ErrCode::Value::UncaughtException);
72
0
  }
73
74
0
  if (Res) {
75
0
    spdlog::debug(" Execution succeeded."sv);
76
0
  } else if (likely(Res.error() == ErrCode::Value::Terminated)) {
77
0
    spdlog::debug(" Terminated."sv);
78
0
  }
79
80
0
  if (Stat && Conf.getStatisticsConfigure().isTimeMeasuring()) {
81
0
    Stat->stopRecordWasm();
82
0
  }
83
84
  // If statistics are enabled, dump them here.
85
0
  if (Stat) {
86
0
    Stat->dumpToLog(Conf);
87
0
  }
88
89
0
  if (!Res && likely(Res.error() == ErrCode::Value::Terminated)) {
90
0
    StackMgr.reset();
91
0
  }
92
93
0
  return Res;
94
0
}
95
96
Expect<void> Executor::execute(Runtime::StackManager &StackMgr,
97
                               const AST::InstrView::iterator Start,
98
0
                               const AST::InstrView::iterator End) {
99
0
  AST::InstrView::iterator PC = Start;
100
0
  AST::InstrView::iterator PCEnd = End;
101
102
  // Force the per-instruction dispatch inline; otherwise the compiler may emit
103
  // this switch out-of-line as one call per instruction (MSVC: see use site).
104
0
  auto Dispatch = [this, &PC, &StackMgr]()
105
0
#if defined(__GNUC__) || defined(__clang__)
106
0
                      __attribute__((always_inline))
107
0
#endif
108
0
  -> Expect<void> {
109
0
    const AST::Instruction &Instr = *PC;
110
0
    switch (Instr.getOpCode()) {
111
    // Control instructions
112
0
    case OpCode::Unreachable:
113
0
      spdlog::error(ErrCode::Value::Unreachable);
114
0
      spdlog::error(
115
0
          ErrInfo::InfoInstruction(Instr.getOpCode(), Instr.getOffset()));
116
0
      return Unexpect(ErrCode::Value::Unreachable);
117
0
    case OpCode::Nop:
118
0
      return {};
119
0
    case OpCode::Block:
120
0
      return {};
121
0
    case OpCode::Loop:
122
0
      return {};
123
0
    case OpCode::If:
124
0
      return runIfElseOp(StackMgr, Instr, PC);
125
0
    case OpCode::Else:
126
0
      if (Stat && Conf.getStatisticsConfigure().isCostMeasuring()) {
127
        // Reach here means end of if-statement.
128
0
        if (unlikely(!Stat->subInstrCost(Instr.getOpCode()))) {
129
0
          spdlog::error(ErrCode::Value::CostLimitExceeded);
130
0
          spdlog::error(
131
0
              ErrInfo::InfoInstruction(Instr.getOpCode(), Instr.getOffset()));
132
0
          return Unexpect(ErrCode::Value::CostLimitExceeded);
133
0
        }
134
0
        if (unlikely(!Stat->addInstrCost(OpCode::End))) {
135
0
          spdlog::error(ErrCode::Value::CostLimitExceeded);
136
0
          spdlog::error(
137
0
              ErrInfo::InfoInstruction(Instr.getOpCode(), Instr.getOffset()));
138
0
          return Unexpect(ErrCode::Value::CostLimitExceeded);
139
0
        }
140
0
      }
141
0
      PC += PC->getJumpEnd() - 1;
142
0
      return {};
143
0
    case OpCode::End:
144
0
      PC = StackMgr.maybePopFrameOrHandler(PC);
145
0
      return {};
146
0
    case OpCode::Throw:
147
0
      return runThrowOp(StackMgr, Instr, PC);
148
0
    case OpCode::Throw_ref:
149
0
      return runThrowRefOp(StackMgr, Instr, PC);
150
0
    case OpCode::Br:
151
0
      return runBrOp(StackMgr, Instr, PC);
152
0
    case OpCode::Br_if:
153
0
      return runBrIfOp(StackMgr, Instr, PC);
154
0
    case OpCode::Br_table:
155
0
      return runBrTableOp(StackMgr, Instr, PC);
156
0
    case OpCode::Br_on_null:
157
0
      return runBrOnNullOp(StackMgr, Instr, PC);
158
0
    case OpCode::Br_on_non_null:
159
0
      return runBrOnNonNullOp(StackMgr, Instr, PC);
160
0
    case OpCode::Br_on_cast:
161
0
      return runBrOnCastOp(StackMgr, Instr, PC);
162
0
    case OpCode::Br_on_cast_fail:
163
0
      return runBrOnCastOp(StackMgr, Instr, PC, true);
164
0
    case OpCode::Return:
165
0
      return runReturnOp(StackMgr, PC);
166
0
    case OpCode::Call:
167
0
      return runCallOp(StackMgr, Instr, PC);
168
0
    case OpCode::Call_indirect:
169
0
      return runCallIndirectOp(StackMgr, Instr, PC);
170
0
    case OpCode::Return_call:
171
0
      return runCallOp(StackMgr, Instr, PC, true);
172
0
    case OpCode::Return_call_indirect:
173
0
      return runCallIndirectOp(StackMgr, Instr, PC, true);
174
0
    case OpCode::Call_ref:
175
0
      return runCallRefOp(StackMgr, Instr, PC);
176
0
    case OpCode::Return_call_ref:
177
0
      return runCallRefOp(StackMgr, Instr, PC, true);
178
0
    case OpCode::Try_table:
179
0
      return runTryTableOp(StackMgr, Instr, PC);
180
181
    // Reference Instructions
182
0
    case OpCode::Ref__null:
183
0
      return runRefNullOp(StackMgr, Instr.getValType());
184
0
    case OpCode::Ref__is_null:
185
0
      return runRefIsNullOp(StackMgr.getTop());
186
0
    case OpCode::Ref__func:
187
0
      return runRefFuncOp(StackMgr, Instr.getTargetIndex());
188
0
    case OpCode::Ref__eq: {
189
0
      ValVariant Rhs = StackMgr.pop();
190
0
      return runRefEqOp(StackMgr.getTop(), Rhs);
191
0
    }
192
0
    case OpCode::Ref__as_non_null:
193
0
      return runRefAsNonNullOp(StackMgr.getTop().get<RefVariant>(), Instr);
194
195
    // Reference Instructions (GC proposal)
196
0
    case OpCode::Struct__new:
197
0
      return runStructNewOp(StackMgr, Instr.getTargetIndex());
198
0
    case OpCode::Struct__new_default:
199
0
      return runStructNewOp(StackMgr, Instr.getTargetIndex(), true);
200
0
    case OpCode::Struct__get:
201
0
    case OpCode::Struct__get_u:
202
0
      return runStructGetOp(StackMgr, Instr.getTargetIndex(),
203
0
                            Instr.getSourceIndex(), Instr);
204
0
    case OpCode::Struct__get_s:
205
0
      return runStructGetOp(StackMgr, Instr.getTargetIndex(),
206
0
                            Instr.getSourceIndex(), Instr, true);
207
0
    case OpCode::Struct__set:
208
0
      return runStructSetOp(StackMgr, StackMgr.pop(), Instr.getTargetIndex(),
209
0
                            Instr.getSourceIndex(), Instr);
210
0
    case OpCode::Array__new:
211
0
      return runArrayNewOp(StackMgr, Instr.getTargetIndex(), 1,
212
0
                           StackMgr.pop().get<uint32_t>());
213
0
    case OpCode::Array__new_default:
214
0
      return runArrayNewOp(StackMgr, Instr.getTargetIndex(), 0,
215
0
                           StackMgr.pop().get<uint32_t>());
216
0
    case OpCode::Array__new_fixed:
217
0
      return runArrayNewOp(StackMgr, Instr.getTargetIndex(),
218
0
                           Instr.getSourceIndex(), Instr.getSourceIndex());
219
0
    case OpCode::Array__new_data:
220
0
      return runArrayNewDataOp(StackMgr, Instr.getTargetIndex(),
221
0
                               Instr.getSourceIndex(), Instr);
222
0
    case OpCode::Array__new_elem:
223
0
      return runArrayNewElemOp(StackMgr, Instr.getTargetIndex(),
224
0
                               Instr.getSourceIndex(), Instr);
225
0
    case OpCode::Array__get:
226
0
    case OpCode::Array__get_u:
227
0
      return runArrayGetOp(StackMgr, Instr.getTargetIndex(), Instr);
228
0
    case OpCode::Array__get_s:
229
0
      return runArrayGetOp(StackMgr, Instr.getTargetIndex(), Instr, true);
230
0
    case OpCode::Array__set:
231
0
      return runArraySetOp(StackMgr, StackMgr.pop(), Instr.getTargetIndex(),
232
0
                           Instr);
233
0
    case OpCode::Array__len:
234
0
      return runArrayLenOp(StackMgr.getTop(), Instr);
235
0
    case OpCode::Array__fill: {
236
0
      const uint32_t Cnt = StackMgr.pop().get<uint32_t>();
237
0
      return runArrayFillOp(StackMgr, Cnt, StackMgr.pop(),
238
0
                            Instr.getTargetIndex(), Instr);
239
0
    }
240
0
    case OpCode::Array__copy:
241
0
      return runArrayCopyOp(StackMgr, StackMgr.pop().get<uint32_t>(),
242
0
                            Instr.getTargetIndex(), Instr.getSourceIndex(),
243
0
                            Instr);
244
0
    case OpCode::Array__init_data:
245
0
      return runArrayInitDataOp(StackMgr, StackMgr.pop().get<uint32_t>(),
246
0
                                Instr.getTargetIndex(), Instr.getSourceIndex(),
247
0
                                Instr);
248
0
    case OpCode::Array__init_elem:
249
0
      return runArrayInitElemOp(StackMgr, StackMgr.pop().get<uint32_t>(),
250
0
                                Instr.getTargetIndex(), Instr.getSourceIndex(),
251
0
                                Instr);
252
0
    case OpCode::Ref__test:
253
0
    case OpCode::Ref__test_null:
254
0
      return runRefTestOp(StackMgr.getModule(), StackMgr.getTop(), Instr);
255
0
    case OpCode::Ref__cast:
256
0
    case OpCode::Ref__cast_null:
257
0
      return runRefTestOp(StackMgr.getModule(), StackMgr.getTop(), Instr, true);
258
0
    case OpCode::Any__convert_extern:
259
0
      return runRefConvOp(StackMgr.getTop().get<RefVariant>(),
260
0
                          TypeCode::AnyRef);
261
0
    case OpCode::Extern__convert_any:
262
0
      return runRefConvOp(StackMgr.getTop().get<RefVariant>(),
263
0
                          TypeCode::ExternRef);
264
0
    case OpCode::Ref__i31:
265
0
      return runRefI31Op(StackMgr.getTop());
266
0
    case OpCode::I31__get_s:
267
0
      return runI31GetOp(StackMgr.getTop(), Instr, true);
268
0
    case OpCode::I31__get_u:
269
0
      return runI31GetOp(StackMgr.getTop(), Instr);
270
271
    // Parametric Instructions
272
0
    case OpCode::Drop:
273
0
      StackMgr.pop();
274
0
      return {};
275
0
    case OpCode::Select:
276
0
    case OpCode::Select_t: {
277
      // Pop the i32 value and select values from the stack.
278
0
      ValVariant CondVal = StackMgr.pop();
279
0
      ValVariant Val2 = StackMgr.pop();
280
0
      ValVariant Val1 = StackMgr.pop();
281
282
      // Select the value.
283
0
      if (CondVal.get<uint32_t>() == 0) {
284
0
        StackMgr.push(Val2);
285
0
      } else {
286
0
        StackMgr.push(Val1);
287
0
      }
288
0
      return {};
289
0
    }
290
291
    // Variable Instructions
292
0
    case OpCode::Local__get:
293
0
      return runLocalGetOp(StackMgr, Instr.getStackOffset());
294
0
    case OpCode::Local__set:
295
0
      return runLocalSetOp(StackMgr, Instr.getStackOffset());
296
0
    case OpCode::Local__tee:
297
0
      return runLocalTeeOp(StackMgr, Instr.getStackOffset());
298
0
    case OpCode::Global__get:
299
0
      return runGlobalGetOp(StackMgr, Instr.getTargetIndex());
300
0
    case OpCode::Global__set:
301
0
      return runGlobalSetOp(StackMgr, Instr.getTargetIndex());
302
303
    // Table Instructions
304
0
    case OpCode::Table__get:
305
0
      return runTableGetOp(
306
0
          StackMgr,
307
0
          *getTabInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
308
0
          Instr);
309
0
    case OpCode::Table__set:
310
0
      return runTableSetOp(
311
0
          StackMgr,
312
0
          *getTabInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
313
0
          Instr);
314
0
    case OpCode::Table__init:
315
0
      return runTableInitOp(
316
0
          StackMgr,
317
0
          *getTabInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
318
0
          *getElemInstByIdx(StackMgr.getModule(), Instr.getSourceIndex()),
319
0
          Instr);
320
0
    case OpCode::Elem__drop:
321
0
      return runElemDropOp(
322
0
          *getElemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()));
323
0
    case OpCode::Table__copy:
324
0
      return runTableCopyOp(
325
0
          StackMgr,
326
0
          *getTabInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
327
0
          *getTabInstByIdx(StackMgr.getModule(), Instr.getSourceIndex()),
328
0
          Instr);
329
0
    case OpCode::Table__grow:
330
0
      return runTableGrowOp(StackMgr, *getTabInstByIdx(StackMgr.getModule(),
331
0
                                                       Instr.getTargetIndex()));
332
0
    case OpCode::Table__size:
333
0
      return runTableSizeOp(StackMgr, *getTabInstByIdx(StackMgr.getModule(),
334
0
                                                       Instr.getTargetIndex()));
335
0
    case OpCode::Table__fill:
336
0
      return runTableFillOp(
337
0
          StackMgr,
338
0
          *getTabInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
339
0
          Instr);
340
341
    // Memory Instructions
342
0
    case OpCode::I32__load:
343
0
      return runLoadOp<uint32_t>(
344
0
          StackMgr,
345
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
346
0
          Instr);
347
0
    case OpCode::I64__load:
348
0
      return runLoadOp<uint64_t>(
349
0
          StackMgr,
350
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
351
0
          Instr);
352
0
    case OpCode::F32__load:
353
0
      return runLoadOp<float>(
354
0
          StackMgr,
355
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
356
0
          Instr);
357
0
    case OpCode::F64__load:
358
0
      return runLoadOp<double>(
359
0
          StackMgr,
360
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
361
0
          Instr);
362
0
    case OpCode::I32__load8_s:
363
0
      return runLoadOp<int32_t, 8>(
364
0
          StackMgr,
365
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
366
0
          Instr);
367
0
    case OpCode::I32__load8_u:
368
0
      return runLoadOp<uint32_t, 8>(
369
0
          StackMgr,
370
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
371
0
          Instr);
372
0
    case OpCode::I32__load16_s:
373
0
      return runLoadOp<int32_t, 16>(
374
0
          StackMgr,
375
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
376
0
          Instr);
377
0
    case OpCode::I32__load16_u:
378
0
      return runLoadOp<uint32_t, 16>(
379
0
          StackMgr,
380
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
381
0
          Instr);
382
0
    case OpCode::I64__load8_s:
383
0
      return runLoadOp<int64_t, 8>(
384
0
          StackMgr,
385
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
386
0
          Instr);
387
0
    case OpCode::I64__load8_u:
388
0
      return runLoadOp<uint64_t, 8>(
389
0
          StackMgr,
390
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
391
0
          Instr);
392
0
    case OpCode::I64__load16_s:
393
0
      return runLoadOp<int64_t, 16>(
394
0
          StackMgr,
395
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
396
0
          Instr);
397
0
    case OpCode::I64__load16_u:
398
0
      return runLoadOp<uint64_t, 16>(
399
0
          StackMgr,
400
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
401
0
          Instr);
402
0
    case OpCode::I64__load32_s:
403
0
      return runLoadOp<int64_t, 32>(
404
0
          StackMgr,
405
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
406
0
          Instr);
407
0
    case OpCode::I64__load32_u:
408
0
      return runLoadOp<uint64_t, 32>(
409
0
          StackMgr,
410
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
411
0
          Instr);
412
0
    case OpCode::I32__store:
413
0
      return runStoreOp<uint32_t>(
414
0
          StackMgr,
415
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
416
0
          Instr);
417
0
    case OpCode::I64__store:
418
0
      return runStoreOp<uint64_t>(
419
0
          StackMgr,
420
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
421
0
          Instr);
422
0
    case OpCode::F32__store:
423
0
      return runStoreOp<float>(
424
0
          StackMgr,
425
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
426
0
          Instr);
427
0
    case OpCode::F64__store:
428
0
      return runStoreOp<double>(
429
0
          StackMgr,
430
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
431
0
          Instr);
432
0
    case OpCode::I32__store8:
433
0
      return runStoreOp<uint32_t, 8>(
434
0
          StackMgr,
435
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
436
0
          Instr);
437
0
    case OpCode::I32__store16:
438
0
      return runStoreOp<uint32_t, 16>(
439
0
          StackMgr,
440
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
441
0
          Instr);
442
0
    case OpCode::I64__store8:
443
0
      return runStoreOp<uint64_t, 8>(
444
0
          StackMgr,
445
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
446
0
          Instr);
447
0
    case OpCode::I64__store16:
448
0
      return runStoreOp<uint64_t, 16>(
449
0
          StackMgr,
450
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
451
0
          Instr);
452
0
    case OpCode::I64__store32:
453
0
      return runStoreOp<uint64_t, 32>(
454
0
          StackMgr,
455
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
456
0
          Instr);
457
0
    case OpCode::Memory__grow:
458
0
      return runMemoryGrowOp(
459
0
          StackMgr,
460
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()));
461
0
    case OpCode::Memory__size:
462
0
      return runMemorySizeOp(
463
0
          StackMgr,
464
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()));
465
0
    case OpCode::Memory__init:
466
0
      return runMemoryInitOp(
467
0
          StackMgr,
468
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
469
0
          *getDataInstByIdx(StackMgr.getModule(), Instr.getSourceIndex()),
470
0
          Instr);
471
0
    case OpCode::Data__drop:
472
0
      return runDataDropOp(
473
0
          *getDataInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()));
474
0
    case OpCode::Memory__copy:
475
0
      return runMemoryCopyOp(
476
0
          StackMgr,
477
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
478
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getSourceIndex()),
479
0
          Instr);
480
0
    case OpCode::Memory__fill:
481
0
      return runMemoryFillOp(
482
0
          StackMgr,
483
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
484
0
          Instr);
485
486
    // Const Numeric Instructions
487
0
    case OpCode::I32__const:
488
0
    case OpCode::I64__const:
489
0
    case OpCode::F32__const:
490
0
    case OpCode::F64__const:
491
0
      StackMgr.push(Instr.getNum());
492
0
      return {};
493
494
    // Unary Numeric Instructions
495
0
    case OpCode::I32__eqz:
496
0
      return runEqzOp<uint32_t>(StackMgr.getTop());
497
0
    case OpCode::I64__eqz:
498
0
      return runEqzOp<uint64_t>(StackMgr.getTop());
499
0
    case OpCode::I32__clz:
500
0
      return runClzOp<uint32_t>(StackMgr.getTop());
501
0
    case OpCode::I32__ctz:
502
0
      return runCtzOp<uint32_t>(StackMgr.getTop());
503
0
    case OpCode::I32__popcnt:
504
0
      return runPopcntOp<uint32_t>(StackMgr.getTop());
505
0
    case OpCode::I64__clz:
506
0
      return runClzOp<uint64_t>(StackMgr.getTop());
507
0
    case OpCode::I64__ctz:
508
0
      return runCtzOp<uint64_t>(StackMgr.getTop());
509
0
    case OpCode::I64__popcnt:
510
0
      return runPopcntOp<uint64_t>(StackMgr.getTop());
511
0
    case OpCode::F32__abs:
512
0
      return runAbsOp<float>(StackMgr.getTop());
513
0
    case OpCode::F32__neg:
514
0
      return runNegOp<float>(StackMgr.getTop());
515
0
    case OpCode::F32__ceil:
516
0
      return runCeilOp<float>(StackMgr.getTop());
517
0
    case OpCode::F32__floor:
518
0
      return runFloorOp<float>(StackMgr.getTop());
519
0
    case OpCode::F32__trunc:
520
0
      return runTruncOp<float>(StackMgr.getTop());
521
0
    case OpCode::F32__nearest:
522
0
      return runNearestOp<float>(StackMgr.getTop());
523
0
    case OpCode::F32__sqrt:
524
0
      return runSqrtOp<float>(StackMgr.getTop());
525
0
    case OpCode::F64__abs:
526
0
      return runAbsOp<double>(StackMgr.getTop());
527
0
    case OpCode::F64__neg:
528
0
      return runNegOp<double>(StackMgr.getTop());
529
0
    case OpCode::F64__ceil:
530
0
      return runCeilOp<double>(StackMgr.getTop());
531
0
    case OpCode::F64__floor:
532
0
      return runFloorOp<double>(StackMgr.getTop());
533
0
    case OpCode::F64__trunc:
534
0
      return runTruncOp<double>(StackMgr.getTop());
535
0
    case OpCode::F64__nearest:
536
0
      return runNearestOp<double>(StackMgr.getTop());
537
0
    case OpCode::F64__sqrt:
538
0
      return runSqrtOp<double>(StackMgr.getTop());
539
0
    case OpCode::I32__wrap_i64:
540
0
      return runWrapOp<uint64_t, uint32_t>(StackMgr.getTop());
541
0
    case OpCode::I32__trunc_f32_s:
542
0
      return runTruncateOp<float, int32_t>(Instr, StackMgr.getTop());
543
0
    case OpCode::I32__trunc_f32_u:
544
0
      return runTruncateOp<float, uint32_t>(Instr, StackMgr.getTop());
545
0
    case OpCode::I32__trunc_f64_s:
546
0
      return runTruncateOp<double, int32_t>(Instr, StackMgr.getTop());
547
0
    case OpCode::I32__trunc_f64_u:
548
0
      return runTruncateOp<double, uint32_t>(Instr, StackMgr.getTop());
549
0
    case OpCode::I64__extend_i32_s:
550
0
      return runExtendOp<int32_t, uint64_t>(StackMgr.getTop());
551
0
    case OpCode::I64__extend_i32_u:
552
0
      return runExtendOp<uint32_t, uint64_t>(StackMgr.getTop());
553
0
    case OpCode::I64__trunc_f32_s:
554
0
      return runTruncateOp<float, int64_t>(Instr, StackMgr.getTop());
555
0
    case OpCode::I64__trunc_f32_u:
556
0
      return runTruncateOp<float, uint64_t>(Instr, StackMgr.getTop());
557
0
    case OpCode::I64__trunc_f64_s:
558
0
      return runTruncateOp<double, int64_t>(Instr, StackMgr.getTop());
559
0
    case OpCode::I64__trunc_f64_u:
560
0
      return runTruncateOp<double, uint64_t>(Instr, StackMgr.getTop());
561
0
    case OpCode::F32__convert_i32_s:
562
0
      return runConvertOp<int32_t, float>(StackMgr.getTop());
563
0
    case OpCode::F32__convert_i32_u:
564
0
      return runConvertOp<uint32_t, float>(StackMgr.getTop());
565
0
    case OpCode::F32__convert_i64_s:
566
0
      return runConvertOp<int64_t, float>(StackMgr.getTop());
567
0
    case OpCode::F32__convert_i64_u:
568
0
      return runConvertOp<uint64_t, float>(StackMgr.getTop());
569
0
    case OpCode::F32__demote_f64:
570
0
      return runDemoteOp<double, float>(StackMgr.getTop());
571
0
    case OpCode::F64__convert_i32_s:
572
0
      return runConvertOp<int32_t, double>(StackMgr.getTop());
573
0
    case OpCode::F64__convert_i32_u:
574
0
      return runConvertOp<uint32_t, double>(StackMgr.getTop());
575
0
    case OpCode::F64__convert_i64_s:
576
0
      return runConvertOp<int64_t, double>(StackMgr.getTop());
577
0
    case OpCode::F64__convert_i64_u:
578
0
      return runConvertOp<uint64_t, double>(StackMgr.getTop());
579
0
    case OpCode::F64__promote_f32:
580
0
      return runPromoteOp<float, double>(StackMgr.getTop());
581
0
    case OpCode::I32__reinterpret_f32:
582
0
      return runReinterpretOp<float, uint32_t>(StackMgr.getTop());
583
0
    case OpCode::I64__reinterpret_f64:
584
0
      return runReinterpretOp<double, uint64_t>(StackMgr.getTop());
585
0
    case OpCode::F32__reinterpret_i32:
586
0
      return runReinterpretOp<uint32_t, float>(StackMgr.getTop());
587
0
    case OpCode::F64__reinterpret_i64:
588
0
      return runReinterpretOp<uint64_t, double>(StackMgr.getTop());
589
0
    case OpCode::I32__extend8_s:
590
0
      return runExtendOp<int32_t, uint32_t, 8>(StackMgr.getTop());
591
0
    case OpCode::I32__extend16_s:
592
0
      return runExtendOp<int32_t, uint32_t, 16>(StackMgr.getTop());
593
0
    case OpCode::I64__extend8_s:
594
0
      return runExtendOp<int64_t, uint64_t, 8>(StackMgr.getTop());
595
0
    case OpCode::I64__extend16_s:
596
0
      return runExtendOp<int64_t, uint64_t, 16>(StackMgr.getTop());
597
0
    case OpCode::I64__extend32_s:
598
0
      return runExtendOp<int64_t, uint64_t, 32>(StackMgr.getTop());
599
600
    // Binary Numeric Instructions
601
0
    case OpCode::I32__eq: {
602
0
      ValVariant Rhs = StackMgr.pop();
603
0
      return runEqOp<uint32_t>(StackMgr.getTop(), Rhs);
604
0
    }
605
0
    case OpCode::I32__ne: {
606
0
      ValVariant Rhs = StackMgr.pop();
607
0
      return runNeOp<uint32_t>(StackMgr.getTop(), Rhs);
608
0
    }
609
0
    case OpCode::I32__lt_s: {
610
0
      ValVariant Rhs = StackMgr.pop();
611
0
      return runLtOp<int32_t>(StackMgr.getTop(), Rhs);
612
0
    }
613
0
    case OpCode::I32__lt_u: {
614
0
      ValVariant Rhs = StackMgr.pop();
615
0
      return runLtOp<uint32_t>(StackMgr.getTop(), Rhs);
616
0
    }
617
0
    case OpCode::I32__gt_s: {
618
0
      ValVariant Rhs = StackMgr.pop();
619
0
      return runGtOp<int32_t>(StackMgr.getTop(), Rhs);
620
0
    }
621
0
    case OpCode::I32__gt_u: {
622
0
      ValVariant Rhs = StackMgr.pop();
623
0
      return runGtOp<uint32_t>(StackMgr.getTop(), Rhs);
624
0
    }
625
0
    case OpCode::I32__le_s: {
626
0
      ValVariant Rhs = StackMgr.pop();
627
0
      return runLeOp<int32_t>(StackMgr.getTop(), Rhs);
628
0
    }
629
0
    case OpCode::I32__le_u: {
630
0
      ValVariant Rhs = StackMgr.pop();
631
0
      return runLeOp<uint32_t>(StackMgr.getTop(), Rhs);
632
0
    }
633
0
    case OpCode::I32__ge_s: {
634
0
      ValVariant Rhs = StackMgr.pop();
635
0
      return runGeOp<int32_t>(StackMgr.getTop(), Rhs);
636
0
    }
637
0
    case OpCode::I32__ge_u: {
638
0
      ValVariant Rhs = StackMgr.pop();
639
0
      return runGeOp<uint32_t>(StackMgr.getTop(), Rhs);
640
0
    }
641
0
    case OpCode::I64__eq: {
642
0
      ValVariant Rhs = StackMgr.pop();
643
0
      return runEqOp<uint64_t>(StackMgr.getTop(), Rhs);
644
0
    }
645
0
    case OpCode::I64__ne: {
646
0
      ValVariant Rhs = StackMgr.pop();
647
0
      return runNeOp<uint64_t>(StackMgr.getTop(), Rhs);
648
0
    }
649
0
    case OpCode::I64__lt_s: {
650
0
      ValVariant Rhs = StackMgr.pop();
651
0
      return runLtOp<int64_t>(StackMgr.getTop(), Rhs);
652
0
    }
653
0
    case OpCode::I64__lt_u: {
654
0
      ValVariant Rhs = StackMgr.pop();
655
0
      return runLtOp<uint64_t>(StackMgr.getTop(), Rhs);
656
0
    }
657
0
    case OpCode::I64__gt_s: {
658
0
      ValVariant Rhs = StackMgr.pop();
659
0
      return runGtOp<int64_t>(StackMgr.getTop(), Rhs);
660
0
    }
661
0
    case OpCode::I64__gt_u: {
662
0
      ValVariant Rhs = StackMgr.pop();
663
0
      return runGtOp<uint64_t>(StackMgr.getTop(), Rhs);
664
0
    }
665
0
    case OpCode::I64__le_s: {
666
0
      ValVariant Rhs = StackMgr.pop();
667
0
      return runLeOp<int64_t>(StackMgr.getTop(), Rhs);
668
0
    }
669
0
    case OpCode::I64__le_u: {
670
0
      ValVariant Rhs = StackMgr.pop();
671
0
      return runLeOp<uint64_t>(StackMgr.getTop(), Rhs);
672
0
    }
673
0
    case OpCode::I64__ge_s: {
674
0
      ValVariant Rhs = StackMgr.pop();
675
0
      return runGeOp<int64_t>(StackMgr.getTop(), Rhs);
676
0
    }
677
0
    case OpCode::I64__ge_u: {
678
0
      ValVariant Rhs = StackMgr.pop();
679
0
      return runGeOp<uint64_t>(StackMgr.getTop(), Rhs);
680
0
    }
681
0
    case OpCode::F32__eq: {
682
0
      ValVariant Rhs = StackMgr.pop();
683
0
      return runEqOp<float>(StackMgr.getTop(), Rhs);
684
0
    }
685
0
    case OpCode::F32__ne: {
686
0
      ValVariant Rhs = StackMgr.pop();
687
0
      return runNeOp<float>(StackMgr.getTop(), Rhs);
688
0
    }
689
0
    case OpCode::F32__lt: {
690
0
      ValVariant Rhs = StackMgr.pop();
691
0
      return runLtOp<float>(StackMgr.getTop(), Rhs);
692
0
    }
693
0
    case OpCode::F32__gt: {
694
0
      ValVariant Rhs = StackMgr.pop();
695
0
      return runGtOp<float>(StackMgr.getTop(), Rhs);
696
0
    }
697
0
    case OpCode::F32__le: {
698
0
      ValVariant Rhs = StackMgr.pop();
699
0
      return runLeOp<float>(StackMgr.getTop(), Rhs);
700
0
    }
701
0
    case OpCode::F32__ge: {
702
0
      ValVariant Rhs = StackMgr.pop();
703
0
      return runGeOp<float>(StackMgr.getTop(), Rhs);
704
0
    }
705
0
    case OpCode::F64__eq: {
706
0
      ValVariant Rhs = StackMgr.pop();
707
0
      return runEqOp<double>(StackMgr.getTop(), Rhs);
708
0
    }
709
0
    case OpCode::F64__ne: {
710
0
      ValVariant Rhs = StackMgr.pop();
711
0
      return runNeOp<double>(StackMgr.getTop(), Rhs);
712
0
    }
713
0
    case OpCode::F64__lt: {
714
0
      ValVariant Rhs = StackMgr.pop();
715
0
      return runLtOp<double>(StackMgr.getTop(), Rhs);
716
0
    }
717
0
    case OpCode::F64__gt: {
718
0
      ValVariant Rhs = StackMgr.pop();
719
0
      return runGtOp<double>(StackMgr.getTop(), Rhs);
720
0
    }
721
0
    case OpCode::F64__le: {
722
0
      ValVariant Rhs = StackMgr.pop();
723
0
      return runLeOp<double>(StackMgr.getTop(), Rhs);
724
0
    }
725
0
    case OpCode::F64__ge: {
726
0
      ValVariant Rhs = StackMgr.pop();
727
0
      return runGeOp<double>(StackMgr.getTop(), Rhs);
728
0
    }
729
0
    case OpCode::I32__add: {
730
0
      ValVariant Rhs = StackMgr.pop();
731
0
      return runAddOp<uint32_t>(StackMgr.getTop(), Rhs);
732
0
    }
733
0
    case OpCode::I32__sub: {
734
0
      ValVariant Rhs = StackMgr.pop();
735
0
      return runSubOp<uint32_t>(StackMgr.getTop(), Rhs);
736
0
    }
737
0
    case OpCode::I32__mul: {
738
0
      ValVariant Rhs = StackMgr.pop();
739
0
      return runMulOp<uint32_t>(StackMgr.getTop(), Rhs);
740
0
    }
741
0
    case OpCode::I32__div_s: {
742
0
      ValVariant Rhs = StackMgr.pop();
743
0
      return runDivOp<int32_t>(Instr, StackMgr.getTop(), Rhs);
744
0
    }
745
0
    case OpCode::I32__div_u: {
746
0
      ValVariant Rhs = StackMgr.pop();
747
0
      return runDivOp<uint32_t>(Instr, StackMgr.getTop(), Rhs);
748
0
    }
749
0
    case OpCode::I32__rem_s: {
750
0
      ValVariant Rhs = StackMgr.pop();
751
0
      return runRemOp<int32_t>(Instr, StackMgr.getTop(), Rhs);
752
0
    }
753
0
    case OpCode::I32__rem_u: {
754
0
      ValVariant Rhs = StackMgr.pop();
755
0
      return runRemOp<uint32_t>(Instr, StackMgr.getTop(), Rhs);
756
0
    }
757
0
    case OpCode::I32__and: {
758
0
      ValVariant Rhs = StackMgr.pop();
759
0
      return runAndOp<uint32_t>(StackMgr.getTop(), Rhs);
760
0
    }
761
0
    case OpCode::I32__or: {
762
0
      ValVariant Rhs = StackMgr.pop();
763
0
      return runOrOp<uint32_t>(StackMgr.getTop(), Rhs);
764
0
    }
765
0
    case OpCode::I32__xor: {
766
0
      ValVariant Rhs = StackMgr.pop();
767
0
      return runXorOp<uint32_t>(StackMgr.getTop(), Rhs);
768
0
    }
769
0
    case OpCode::I32__shl: {
770
0
      ValVariant Rhs = StackMgr.pop();
771
0
      return runShlOp<uint32_t>(StackMgr.getTop(), Rhs);
772
0
    }
773
0
    case OpCode::I32__shr_s: {
774
0
      ValVariant Rhs = StackMgr.pop();
775
0
      return runShrOp<int32_t>(StackMgr.getTop(), Rhs);
776
0
    }
777
0
    case OpCode::I32__shr_u: {
778
0
      ValVariant Rhs = StackMgr.pop();
779
0
      return runShrOp<uint32_t>(StackMgr.getTop(), Rhs);
780
0
    }
781
0
    case OpCode::I32__rotl: {
782
0
      ValVariant Rhs = StackMgr.pop();
783
0
      return runRotlOp<uint32_t>(StackMgr.getTop(), Rhs);
784
0
    }
785
0
    case OpCode::I32__rotr: {
786
0
      ValVariant Rhs = StackMgr.pop();
787
0
      return runRotrOp<uint32_t>(StackMgr.getTop(), Rhs);
788
0
    }
789
0
    case OpCode::I64__add: {
790
0
      ValVariant Rhs = StackMgr.pop();
791
0
      return runAddOp<uint64_t>(StackMgr.getTop(), Rhs);
792
0
    }
793
0
    case OpCode::I64__sub: {
794
0
      ValVariant Rhs = StackMgr.pop();
795
0
      return runSubOp<uint64_t>(StackMgr.getTop(), Rhs);
796
0
    }
797
0
    case OpCode::I64__mul: {
798
0
      ValVariant Rhs = StackMgr.pop();
799
0
      return runMulOp<uint64_t>(StackMgr.getTop(), Rhs);
800
0
    }
801
0
    case OpCode::I64__div_s: {
802
0
      ValVariant Rhs = StackMgr.pop();
803
0
      return runDivOp<int64_t>(Instr, StackMgr.getTop(), Rhs);
804
0
    }
805
0
    case OpCode::I64__div_u: {
806
0
      ValVariant Rhs = StackMgr.pop();
807
0
      return runDivOp<uint64_t>(Instr, StackMgr.getTop(), Rhs);
808
0
    }
809
0
    case OpCode::I64__rem_s: {
810
0
      ValVariant Rhs = StackMgr.pop();
811
0
      return runRemOp<int64_t>(Instr, StackMgr.getTop(), Rhs);
812
0
    }
813
0
    case OpCode::I64__rem_u: {
814
0
      ValVariant Rhs = StackMgr.pop();
815
0
      return runRemOp<uint64_t>(Instr, StackMgr.getTop(), Rhs);
816
0
    }
817
0
    case OpCode::I64__and: {
818
0
      ValVariant Rhs = StackMgr.pop();
819
0
      return runAndOp<uint64_t>(StackMgr.getTop(), Rhs);
820
0
    }
821
0
    case OpCode::I64__or: {
822
0
      ValVariant Rhs = StackMgr.pop();
823
0
      return runOrOp<uint64_t>(StackMgr.getTop(), Rhs);
824
0
    }
825
0
    case OpCode::I64__xor: {
826
0
      ValVariant Rhs = StackMgr.pop();
827
0
      return runXorOp<uint64_t>(StackMgr.getTop(), Rhs);
828
0
    }
829
0
    case OpCode::I64__shl: {
830
0
      ValVariant Rhs = StackMgr.pop();
831
0
      return runShlOp<uint64_t>(StackMgr.getTop(), Rhs);
832
0
    }
833
0
    case OpCode::I64__shr_s: {
834
0
      ValVariant Rhs = StackMgr.pop();
835
0
      return runShrOp<int64_t>(StackMgr.getTop(), Rhs);
836
0
    }
837
0
    case OpCode::I64__shr_u: {
838
0
      ValVariant Rhs = StackMgr.pop();
839
0
      return runShrOp<uint64_t>(StackMgr.getTop(), Rhs);
840
0
    }
841
0
    case OpCode::I64__rotl: {
842
0
      ValVariant Rhs = StackMgr.pop();
843
0
      return runRotlOp<uint64_t>(StackMgr.getTop(), Rhs);
844
0
    }
845
0
    case OpCode::I64__rotr: {
846
0
      ValVariant Rhs = StackMgr.pop();
847
0
      return runRotrOp<uint64_t>(StackMgr.getTop(), Rhs);
848
0
    }
849
0
    case OpCode::F32__add: {
850
0
      ValVariant Rhs = StackMgr.pop();
851
0
      return runAddOp<float>(StackMgr.getTop(), Rhs);
852
0
    }
853
0
    case OpCode::F32__sub: {
854
0
      ValVariant Rhs = StackMgr.pop();
855
0
      return runSubOp<float>(StackMgr.getTop(), Rhs);
856
0
    }
857
0
    case OpCode::F32__mul: {
858
0
      ValVariant Rhs = StackMgr.pop();
859
0
      return runMulOp<float>(StackMgr.getTop(), Rhs);
860
0
    }
861
0
    case OpCode::F32__div: {
862
0
      ValVariant Rhs = StackMgr.pop();
863
0
      return runDivOp<float>(Instr, StackMgr.getTop(), Rhs);
864
0
    }
865
0
    case OpCode::F32__min: {
866
0
      ValVariant Rhs = StackMgr.pop();
867
0
      return runMinOp<float>(StackMgr.getTop(), Rhs);
868
0
    }
869
0
    case OpCode::F32__max: {
870
0
      ValVariant Rhs = StackMgr.pop();
871
0
      return runMaxOp<float>(StackMgr.getTop(), Rhs);
872
0
    }
873
0
    case OpCode::F32__copysign: {
874
0
      ValVariant Rhs = StackMgr.pop();
875
0
      return runCopysignOp<float>(StackMgr.getTop(), Rhs);
876
0
    }
877
0
    case OpCode::F64__add: {
878
0
      ValVariant Rhs = StackMgr.pop();
879
0
      return runAddOp<double>(StackMgr.getTop(), Rhs);
880
0
    }
881
0
    case OpCode::F64__sub: {
882
0
      ValVariant Rhs = StackMgr.pop();
883
0
      return runSubOp<double>(StackMgr.getTop(), Rhs);
884
0
    }
885
0
    case OpCode::F64__mul: {
886
0
      ValVariant Rhs = StackMgr.pop();
887
0
      return runMulOp<double>(StackMgr.getTop(), Rhs);
888
0
    }
889
0
    case OpCode::F64__div: {
890
0
      ValVariant Rhs = StackMgr.pop();
891
0
      return runDivOp<double>(Instr, StackMgr.getTop(), Rhs);
892
0
    }
893
0
    case OpCode::F64__min: {
894
0
      ValVariant Rhs = StackMgr.pop();
895
0
      return runMinOp<double>(StackMgr.getTop(), Rhs);
896
0
    }
897
0
    case OpCode::F64__max: {
898
0
      ValVariant Rhs = StackMgr.pop();
899
0
      return runMaxOp<double>(StackMgr.getTop(), Rhs);
900
0
    }
901
0
    case OpCode::F64__copysign: {
902
0
      ValVariant Rhs = StackMgr.pop();
903
0
      return runCopysignOp<double>(StackMgr.getTop(), Rhs);
904
0
    }
905
906
    // Saturating Truncation Numeric Instructions
907
0
    case OpCode::I32__trunc_sat_f32_s:
908
0
      return runTruncateSatOp<float, int32_t>(StackMgr.getTop());
909
0
    case OpCode::I32__trunc_sat_f32_u:
910
0
      return runTruncateSatOp<float, uint32_t>(StackMgr.getTop());
911
0
    case OpCode::I32__trunc_sat_f64_s:
912
0
      return runTruncateSatOp<double, int32_t>(StackMgr.getTop());
913
0
    case OpCode::I32__trunc_sat_f64_u:
914
0
      return runTruncateSatOp<double, uint32_t>(StackMgr.getTop());
915
0
    case OpCode::I64__trunc_sat_f32_s:
916
0
      return runTruncateSatOp<float, int64_t>(StackMgr.getTop());
917
0
    case OpCode::I64__trunc_sat_f32_u:
918
0
      return runTruncateSatOp<float, uint64_t>(StackMgr.getTop());
919
0
    case OpCode::I64__trunc_sat_f64_s:
920
0
      return runTruncateSatOp<double, int64_t>(StackMgr.getTop());
921
0
    case OpCode::I64__trunc_sat_f64_u:
922
0
      return runTruncateSatOp<double, uint64_t>(StackMgr.getTop());
923
924
    // SIMD Memory Instructions
925
0
    case OpCode::V128__load:
926
0
      return runLoadOp<uint128_t>(
927
0
          StackMgr,
928
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
929
0
          Instr);
930
0
    case OpCode::V128__load8x8_s:
931
0
      return runLoadExpandOp<int8_t, int16_t>(
932
0
          StackMgr,
933
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
934
0
          Instr);
935
0
    case OpCode::V128__load8x8_u:
936
0
      return runLoadExpandOp<uint8_t, uint16_t>(
937
0
          StackMgr,
938
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
939
0
          Instr);
940
0
    case OpCode::V128__load16x4_s:
941
0
      return runLoadExpandOp<int16_t, int32_t>(
942
0
          StackMgr,
943
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
944
0
          Instr);
945
0
    case OpCode::V128__load16x4_u:
946
0
      return runLoadExpandOp<uint16_t, uint32_t>(
947
0
          StackMgr,
948
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
949
0
          Instr);
950
0
    case OpCode::V128__load32x2_s:
951
0
      return runLoadExpandOp<int32_t, int64_t>(
952
0
          StackMgr,
953
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
954
0
          Instr);
955
0
    case OpCode::V128__load32x2_u:
956
0
      return runLoadExpandOp<uint32_t, uint64_t>(
957
0
          StackMgr,
958
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
959
0
          Instr);
960
0
    case OpCode::V128__load8_splat:
961
0
      return runLoadSplatOp<uint8_t>(
962
0
          StackMgr,
963
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
964
0
          Instr);
965
0
    case OpCode::V128__load16_splat:
966
0
      return runLoadSplatOp<uint16_t>(
967
0
          StackMgr,
968
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
969
0
          Instr);
970
0
    case OpCode::V128__load32_splat:
971
0
      return runLoadSplatOp<uint32_t>(
972
0
          StackMgr,
973
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
974
0
          Instr);
975
0
    case OpCode::V128__load64_splat:
976
0
      return runLoadSplatOp<uint64_t>(
977
0
          StackMgr,
978
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
979
0
          Instr);
980
0
    case OpCode::V128__load32_zero:
981
0
      return runLoadOp<uint128_t, 32>(
982
0
          StackMgr,
983
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
984
0
          Instr);
985
0
    case OpCode::V128__load64_zero:
986
0
      return runLoadOp<uint128_t, 64>(
987
0
          StackMgr,
988
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
989
0
          Instr);
990
0
    case OpCode::V128__store:
991
0
      return runStoreOp<uint128_t>(
992
0
          StackMgr,
993
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
994
0
          Instr);
995
0
    case OpCode::V128__load8_lane:
996
0
      return runLoadLaneOp<uint8_t>(
997
0
          StackMgr,
998
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
999
0
          Instr);
1000
0
    case OpCode::V128__load16_lane:
1001
0
      return runLoadLaneOp<uint16_t>(
1002
0
          StackMgr,
1003
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
1004
0
          Instr);
1005
0
    case OpCode::V128__load32_lane:
1006
0
      return runLoadLaneOp<uint32_t>(
1007
0
          StackMgr,
1008
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
1009
0
          Instr);
1010
0
    case OpCode::V128__load64_lane:
1011
0
      return runLoadLaneOp<uint64_t>(
1012
0
          StackMgr,
1013
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
1014
0
          Instr);
1015
0
    case OpCode::V128__store8_lane:
1016
0
      return runStoreLaneOp<uint8_t>(
1017
0
          StackMgr,
1018
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
1019
0
          Instr);
1020
0
    case OpCode::V128__store16_lane:
1021
0
      return runStoreLaneOp<uint16_t>(
1022
0
          StackMgr,
1023
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
1024
0
          Instr);
1025
0
    case OpCode::V128__store32_lane:
1026
0
      return runStoreLaneOp<uint32_t>(
1027
0
          StackMgr,
1028
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
1029
0
          Instr);
1030
0
    case OpCode::V128__store64_lane:
1031
0
      return runStoreLaneOp<uint64_t>(
1032
0
          StackMgr,
1033
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
1034
0
          Instr);
1035
1036
    // SIMD Const Instructions
1037
0
    case OpCode::V128__const:
1038
0
      StackMgr.push(Instr.getNum());
1039
0
      return {};
1040
1041
    // SIMD Shuffle Instructions
1042
0
    case OpCode::I8x16__shuffle: {
1043
0
      ValVariant Val2 = StackMgr.pop();
1044
0
      ValVariant &Val1 = StackMgr.getTop();
1045
0
      std::array<uint8_t, 32> Data;
1046
0
      std::array<uint8_t, 16> Result;
1047
0
      std::memcpy(&Data[0], &Val1, 16);
1048
0
      std::memcpy(&Data[16], &Val2, 16);
1049
0
      const auto V3 = Instr.getNum().get<uint128_t>();
1050
0
      for (size_t I = 0; I < 16; ++I) {
1051
0
        const uint8_t Index = static_cast<uint8_t>(V3 >> (I * 8));
1052
0
        if constexpr (Endian::native == Endian::little) {
1053
0
          Result[I] = Data[Index];
1054
        } else {
1055
          Result[15 - I] = Index < 16 ? Data[15 - Index] : Data[47 - Index];
1056
        }
1057
0
      }
1058
0
      std::memcpy(&Val1, &Result[0], 16);
1059
0
      return {};
1060
0
    }
1061
1062
    // SIMD Lane Instructions
1063
0
    case OpCode::I8x16__extract_lane_s:
1064
0
      return runExtractLaneOp<int8_t, int32_t>(StackMgr.getTop(),
1065
0
                                               Instr.getMemoryLane());
1066
0
    case OpCode::I8x16__extract_lane_u:
1067
0
      return runExtractLaneOp<uint8_t, uint32_t>(StackMgr.getTop(),
1068
0
                                                 Instr.getMemoryLane());
1069
0
    case OpCode::I16x8__extract_lane_s:
1070
0
      return runExtractLaneOp<int16_t, int32_t>(StackMgr.getTop(),
1071
0
                                                Instr.getMemoryLane());
1072
0
    case OpCode::I16x8__extract_lane_u:
1073
0
      return runExtractLaneOp<uint16_t, uint32_t>(StackMgr.getTop(),
1074
0
                                                  Instr.getMemoryLane());
1075
0
    case OpCode::I32x4__extract_lane:
1076
0
      return runExtractLaneOp<uint32_t>(StackMgr.getTop(),
1077
0
                                        Instr.getMemoryLane());
1078
0
    case OpCode::I64x2__extract_lane:
1079
0
      return runExtractLaneOp<uint64_t>(StackMgr.getTop(),
1080
0
                                        Instr.getMemoryLane());
1081
0
    case OpCode::F32x4__extract_lane:
1082
0
      return runExtractLaneOp<float>(StackMgr.getTop(), Instr.getMemoryLane());
1083
0
    case OpCode::F64x2__extract_lane:
1084
0
      return runExtractLaneOp<double>(StackMgr.getTop(), Instr.getMemoryLane());
1085
0
    case OpCode::I8x16__replace_lane: {
1086
0
      ValVariant Rhs = StackMgr.pop();
1087
0
      return runReplaceLaneOp<uint32_t, uint8_t>(StackMgr.getTop(), Rhs,
1088
0
                                                 Instr.getMemoryLane());
1089
0
    }
1090
0
    case OpCode::I16x8__replace_lane: {
1091
0
      ValVariant Rhs = StackMgr.pop();
1092
0
      return runReplaceLaneOp<uint32_t, uint16_t>(StackMgr.getTop(), Rhs,
1093
0
                                                  Instr.getMemoryLane());
1094
0
    }
1095
0
    case OpCode::I32x4__replace_lane: {
1096
0
      ValVariant Rhs = StackMgr.pop();
1097
0
      return runReplaceLaneOp<uint32_t>(StackMgr.getTop(), Rhs,
1098
0
                                        Instr.getMemoryLane());
1099
0
    }
1100
0
    case OpCode::I64x2__replace_lane: {
1101
0
      ValVariant Rhs = StackMgr.pop();
1102
0
      return runReplaceLaneOp<uint64_t>(StackMgr.getTop(), Rhs,
1103
0
                                        Instr.getMemoryLane());
1104
0
    }
1105
0
    case OpCode::F32x4__replace_lane: {
1106
0
      ValVariant Rhs = StackMgr.pop();
1107
0
      return runReplaceLaneOp<float>(StackMgr.getTop(), Rhs,
1108
0
                                     Instr.getMemoryLane());
1109
0
    }
1110
0
    case OpCode::F64x2__replace_lane: {
1111
0
      ValVariant Rhs = StackMgr.pop();
1112
0
      return runReplaceLaneOp<double>(StackMgr.getTop(), Rhs,
1113
0
                                      Instr.getMemoryLane());
1114
0
    }
1115
1116
    // SIMD Numeric Instructions
1117
#if defined(_MSC_VER) && !defined(__clang__) // MSVC
1118
    case OpCode::I8x16__swizzle: {
1119
      const ValVariant Val2 = StackMgr.pop();
1120
      ValVariant &Val1 = StackMgr.getTop();
1121
      const uint8x16_t &Index = Val2.get<uint8x16_t>();
1122
      uint8x16_t &Vector = Val1.get<uint8x16_t>();
1123
      uint8x16_t Result;
1124
      for (size_t I = 0; I < 16; ++I) {
1125
        const uint8_t SwizzleIndex = Index[I];
1126
        if (SwizzleIndex < 16) {
1127
          Result[I] = Vector[SwizzleIndex];
1128
        } else {
1129
          Result[I] = 0;
1130
        }
1131
      }
1132
      Vector = Result;
1133
      return {};
1134
    }
1135
#else
1136
0
    case OpCode::I8x16__swizzle: {
1137
0
      const ValVariant Val2 = StackMgr.pop();
1138
0
      ValVariant &Val1 = StackMgr.getTop();
1139
0
      uint8x16_t Index = Val2.get<uint8x16_t>();
1140
      if constexpr (Endian::native == Endian::big) {
1141
        Index = 15 - Index;
1142
      }
1143
0
      uint8x16_t &Vector = Val1.get<uint8x16_t>();
1144
0
      const uint8x16_t Limit = uint8x16_t{} + 16;
1145
0
      const uint8x16_t Zero = uint8x16_t{};
1146
0
      const uint8x16_t Exceed = (Index >= Limit);
1147
0
#ifdef __clang__
1148
0
      uint8x16_t Result = __builtin_shufflevector(Vector, Index);
1149
#else
1150
      uint8x16_t Result = __builtin_shuffle(Vector, Index);
1151
#endif
1152
0
      Vector = detail::vectorSelect(Exceed, Zero, Result);
1153
0
      return {};
1154
0
    }
1155
0
#endif // MSVC
1156
0
    case OpCode::I8x16__splat:
1157
0
      return runSplatOp<uint32_t, uint8_t>(StackMgr.getTop());
1158
0
    case OpCode::I16x8__splat:
1159
0
      return runSplatOp<uint32_t, uint16_t>(StackMgr.getTop());
1160
0
    case OpCode::I32x4__splat:
1161
0
      return runSplatOp<uint32_t>(StackMgr.getTop());
1162
0
    case OpCode::I64x2__splat:
1163
0
      return runSplatOp<uint64_t>(StackMgr.getTop());
1164
0
    case OpCode::F32x4__splat:
1165
0
      return runSplatOp<float>(StackMgr.getTop());
1166
0
    case OpCode::F64x2__splat:
1167
0
      return runSplatOp<double>(StackMgr.getTop());
1168
0
    case OpCode::I8x16__eq: {
1169
0
      ValVariant Rhs = StackMgr.pop();
1170
0
      return runVectorEqOp<uint8_t>(StackMgr.getTop(), Rhs);
1171
0
    }
1172
0
    case OpCode::I8x16__ne: {
1173
0
      ValVariant Rhs = StackMgr.pop();
1174
0
      return runVectorNeOp<uint8_t>(StackMgr.getTop(), Rhs);
1175
0
    }
1176
0
    case OpCode::I8x16__lt_s: {
1177
0
      ValVariant Rhs = StackMgr.pop();
1178
0
      return runVectorLtOp<int8_t>(StackMgr.getTop(), Rhs);
1179
0
    }
1180
0
    case OpCode::I8x16__lt_u: {
1181
0
      ValVariant Rhs = StackMgr.pop();
1182
0
      return runVectorLtOp<uint8_t>(StackMgr.getTop(), Rhs);
1183
0
    }
1184
0
    case OpCode::I8x16__gt_s: {
1185
0
      ValVariant Rhs = StackMgr.pop();
1186
0
      return runVectorGtOp<int8_t>(StackMgr.getTop(), Rhs);
1187
0
    }
1188
0
    case OpCode::I8x16__gt_u: {
1189
0
      ValVariant Rhs = StackMgr.pop();
1190
0
      return runVectorGtOp<uint8_t>(StackMgr.getTop(), Rhs);
1191
0
    }
1192
0
    case OpCode::I8x16__le_s: {
1193
0
      ValVariant Rhs = StackMgr.pop();
1194
0
      return runVectorLeOp<int8_t>(StackMgr.getTop(), Rhs);
1195
0
    }
1196
0
    case OpCode::I8x16__le_u: {
1197
0
      ValVariant Rhs = StackMgr.pop();
1198
0
      return runVectorLeOp<uint8_t>(StackMgr.getTop(), Rhs);
1199
0
    }
1200
0
    case OpCode::I8x16__ge_s: {
1201
0
      ValVariant Rhs = StackMgr.pop();
1202
0
      return runVectorGeOp<int8_t>(StackMgr.getTop(), Rhs);
1203
0
    }
1204
0
    case OpCode::I8x16__ge_u: {
1205
0
      ValVariant Rhs = StackMgr.pop();
1206
0
      return runVectorGeOp<uint8_t>(StackMgr.getTop(), Rhs);
1207
0
    }
1208
0
    case OpCode::I16x8__eq: {
1209
0
      ValVariant Rhs = StackMgr.pop();
1210
0
      return runVectorEqOp<uint16_t>(StackMgr.getTop(), Rhs);
1211
0
    }
1212
0
    case OpCode::I16x8__ne: {
1213
0
      ValVariant Rhs = StackMgr.pop();
1214
0
      return runVectorNeOp<uint16_t>(StackMgr.getTop(), Rhs);
1215
0
    }
1216
0
    case OpCode::I16x8__lt_s: {
1217
0
      ValVariant Rhs = StackMgr.pop();
1218
0
      return runVectorLtOp<int16_t>(StackMgr.getTop(), Rhs);
1219
0
    }
1220
0
    case OpCode::I16x8__lt_u: {
1221
0
      ValVariant Rhs = StackMgr.pop();
1222
0
      return runVectorLtOp<uint16_t>(StackMgr.getTop(), Rhs);
1223
0
    }
1224
0
    case OpCode::I16x8__gt_s: {
1225
0
      ValVariant Rhs = StackMgr.pop();
1226
0
      return runVectorGtOp<int16_t>(StackMgr.getTop(), Rhs);
1227
0
    }
1228
0
    case OpCode::I16x8__gt_u: {
1229
0
      ValVariant Rhs = StackMgr.pop();
1230
0
      return runVectorGtOp<uint16_t>(StackMgr.getTop(), Rhs);
1231
0
    }
1232
0
    case OpCode::I16x8__le_s: {
1233
0
      ValVariant Rhs = StackMgr.pop();
1234
0
      return runVectorLeOp<int16_t>(StackMgr.getTop(), Rhs);
1235
0
    }
1236
0
    case OpCode::I16x8__le_u: {
1237
0
      ValVariant Rhs = StackMgr.pop();
1238
0
      return runVectorLeOp<uint16_t>(StackMgr.getTop(), Rhs);
1239
0
    }
1240
0
    case OpCode::I16x8__ge_s: {
1241
0
      ValVariant Rhs = StackMgr.pop();
1242
0
      return runVectorGeOp<int16_t>(StackMgr.getTop(), Rhs);
1243
0
    }
1244
0
    case OpCode::I16x8__ge_u: {
1245
0
      ValVariant Rhs = StackMgr.pop();
1246
0
      return runVectorGeOp<uint16_t>(StackMgr.getTop(), Rhs);
1247
0
    }
1248
0
    case OpCode::I32x4__eq: {
1249
0
      ValVariant Rhs = StackMgr.pop();
1250
0
      return runVectorEqOp<uint32_t>(StackMgr.getTop(), Rhs);
1251
0
    }
1252
0
    case OpCode::I32x4__ne: {
1253
0
      ValVariant Rhs = StackMgr.pop();
1254
0
      return runVectorNeOp<uint32_t>(StackMgr.getTop(), Rhs);
1255
0
    }
1256
0
    case OpCode::I32x4__lt_s: {
1257
0
      ValVariant Rhs = StackMgr.pop();
1258
0
      return runVectorLtOp<int32_t>(StackMgr.getTop(), Rhs);
1259
0
    }
1260
0
    case OpCode::I32x4__lt_u: {
1261
0
      ValVariant Rhs = StackMgr.pop();
1262
0
      return runVectorLtOp<uint32_t>(StackMgr.getTop(), Rhs);
1263
0
    }
1264
0
    case OpCode::I32x4__gt_s: {
1265
0
      ValVariant Rhs = StackMgr.pop();
1266
0
      return runVectorGtOp<int32_t>(StackMgr.getTop(), Rhs);
1267
0
    }
1268
0
    case OpCode::I32x4__gt_u: {
1269
0
      ValVariant Rhs = StackMgr.pop();
1270
0
      return runVectorGtOp<uint32_t>(StackMgr.getTop(), Rhs);
1271
0
    }
1272
0
    case OpCode::I32x4__le_s: {
1273
0
      ValVariant Rhs = StackMgr.pop();
1274
0
      return runVectorLeOp<int32_t>(StackMgr.getTop(), Rhs);
1275
0
    }
1276
0
    case OpCode::I32x4__le_u: {
1277
0
      ValVariant Rhs = StackMgr.pop();
1278
0
      return runVectorLeOp<uint32_t>(StackMgr.getTop(), Rhs);
1279
0
    }
1280
0
    case OpCode::I32x4__ge_s: {
1281
0
      ValVariant Rhs = StackMgr.pop();
1282
0
      return runVectorGeOp<int32_t>(StackMgr.getTop(), Rhs);
1283
0
    }
1284
0
    case OpCode::I32x4__ge_u: {
1285
0
      ValVariant Rhs = StackMgr.pop();
1286
0
      return runVectorGeOp<uint32_t>(StackMgr.getTop(), Rhs);
1287
0
    }
1288
0
    case OpCode::I64x2__eq: {
1289
0
      ValVariant Rhs = StackMgr.pop();
1290
0
      return runVectorEqOp<uint64_t>(StackMgr.getTop(), Rhs);
1291
0
    }
1292
0
    case OpCode::I64x2__ne: {
1293
0
      ValVariant Rhs = StackMgr.pop();
1294
0
      return runVectorNeOp<uint64_t>(StackMgr.getTop(), Rhs);
1295
0
    }
1296
0
    case OpCode::I64x2__lt_s: {
1297
0
      ValVariant Rhs = StackMgr.pop();
1298
0
      return runVectorLtOp<int64_t>(StackMgr.getTop(), Rhs);
1299
0
    }
1300
0
    case OpCode::I64x2__gt_s: {
1301
0
      ValVariant Rhs = StackMgr.pop();
1302
0
      return runVectorGtOp<int64_t>(StackMgr.getTop(), Rhs);
1303
0
    }
1304
0
    case OpCode::I64x2__le_s: {
1305
0
      ValVariant Rhs = StackMgr.pop();
1306
0
      return runVectorLeOp<int64_t>(StackMgr.getTop(), Rhs);
1307
0
    }
1308
0
    case OpCode::I64x2__ge_s: {
1309
0
      ValVariant Rhs = StackMgr.pop();
1310
0
      return runVectorGeOp<int64_t>(StackMgr.getTop(), Rhs);
1311
0
    }
1312
0
    case OpCode::F32x4__eq: {
1313
0
      ValVariant Rhs = StackMgr.pop();
1314
0
      return runVectorEqOp<float>(StackMgr.getTop(), Rhs);
1315
0
    }
1316
0
    case OpCode::F32x4__ne: {
1317
0
      ValVariant Rhs = StackMgr.pop();
1318
0
      return runVectorNeOp<float>(StackMgr.getTop(), Rhs);
1319
0
    }
1320
0
    case OpCode::F32x4__lt: {
1321
0
      ValVariant Rhs = StackMgr.pop();
1322
0
      return runVectorLtOp<float>(StackMgr.getTop(), Rhs);
1323
0
    }
1324
0
    case OpCode::F32x4__gt: {
1325
0
      ValVariant Rhs = StackMgr.pop();
1326
0
      return runVectorGtOp<float>(StackMgr.getTop(), Rhs);
1327
0
    }
1328
0
    case OpCode::F32x4__le: {
1329
0
      ValVariant Rhs = StackMgr.pop();
1330
0
      return runVectorLeOp<float>(StackMgr.getTop(), Rhs);
1331
0
    }
1332
0
    case OpCode::F32x4__ge: {
1333
0
      ValVariant Rhs = StackMgr.pop();
1334
0
      return runVectorGeOp<float>(StackMgr.getTop(), Rhs);
1335
0
    }
1336
0
    case OpCode::F64x2__eq: {
1337
0
      ValVariant Rhs = StackMgr.pop();
1338
0
      return runVectorEqOp<double>(StackMgr.getTop(), Rhs);
1339
0
    }
1340
0
    case OpCode::F64x2__ne: {
1341
0
      ValVariant Rhs = StackMgr.pop();
1342
0
      return runVectorNeOp<double>(StackMgr.getTop(), Rhs);
1343
0
    }
1344
0
    case OpCode::F64x2__lt: {
1345
0
      ValVariant Rhs = StackMgr.pop();
1346
0
      return runVectorLtOp<double>(StackMgr.getTop(), Rhs);
1347
0
    }
1348
0
    case OpCode::F64x2__gt: {
1349
0
      ValVariant Rhs = StackMgr.pop();
1350
0
      return runVectorGtOp<double>(StackMgr.getTop(), Rhs);
1351
0
    }
1352
0
    case OpCode::F64x2__le: {
1353
0
      ValVariant Rhs = StackMgr.pop();
1354
0
      return runVectorLeOp<double>(StackMgr.getTop(), Rhs);
1355
0
    }
1356
0
    case OpCode::F64x2__ge: {
1357
0
      ValVariant Rhs = StackMgr.pop();
1358
0
      return runVectorGeOp<double>(StackMgr.getTop(), Rhs);
1359
0
    }
1360
0
    case OpCode::V128__not: {
1361
0
      auto &Val = StackMgr.getTop().get<uint128_t>();
1362
0
      Val = ~Val;
1363
0
      return {};
1364
0
    }
1365
0
    case OpCode::V128__and: {
1366
0
      const ValVariant Val2 = StackMgr.pop();
1367
0
      ValVariant &Val1 = StackMgr.getTop();
1368
#if defined(_MSC_VER) && !defined(__clang__) // MSVC
1369
      auto &Result = Val1.get<uint64x2_t>();
1370
      auto &Vector = Val2.get<uint64x2_t>();
1371
      Result[0] &= Vector[0];
1372
      Result[1] &= Vector[1];
1373
#else
1374
0
      Val1.get<uint64x2_t>() &= Val2.get<uint64x2_t>();
1375
0
#endif // MSVC
1376
0
      return {};
1377
0
    }
1378
0
    case OpCode::V128__andnot: {
1379
0
      const ValVariant Val2 = StackMgr.pop();
1380
0
      ValVariant &Val1 = StackMgr.getTop();
1381
#if defined(_MSC_VER) && !defined(__clang__) // MSVC
1382
      auto &Result = Val1.get<uint64x2_t>();
1383
      auto &Vector = Val2.get<uint64x2_t>();
1384
      Result[0] &= ~Vector[0];
1385
      Result[1] &= ~Vector[1];
1386
#else
1387
0
      Val1.get<uint64x2_t>() &= ~Val2.get<uint64x2_t>();
1388
0
#endif // MSVC
1389
0
      return {};
1390
0
    }
1391
0
    case OpCode::V128__or: {
1392
0
      const ValVariant Val2 = StackMgr.pop();
1393
0
      ValVariant &Val1 = StackMgr.getTop();
1394
#if defined(_MSC_VER) && !defined(__clang__) // MSVC
1395
      auto &Result = Val1.get<uint64x2_t>();
1396
      auto &Vector = Val2.get<uint64x2_t>();
1397
      Result[0] |= Vector[0];
1398
      Result[1] |= Vector[1];
1399
#else
1400
0
      Val1.get<uint64x2_t>() |= Val2.get<uint64x2_t>();
1401
0
#endif // MSVC
1402
0
      return {};
1403
0
    }
1404
0
    case OpCode::V128__xor: {
1405
0
      const ValVariant Val2 = StackMgr.pop();
1406
0
      ValVariant &Val1 = StackMgr.getTop();
1407
#if defined(_MSC_VER) && !defined(__clang__) // MSVC
1408
      auto &Result = Val1.get<uint64x2_t>();
1409
      auto &Vector = Val2.get<uint64x2_t>();
1410
      Result[0] ^= Vector[0];
1411
      Result[1] ^= Vector[1];
1412
#else
1413
0
      Val1.get<uint64x2_t>() ^= Val2.get<uint64x2_t>();
1414
0
#endif // MSVC
1415
0
      return {};
1416
0
    }
1417
0
    case OpCode::V128__bitselect: {
1418
0
      const uint64x2_t C = StackMgr.pop().get<uint64x2_t>();
1419
0
      const uint64x2_t Val2 = StackMgr.pop().get<uint64x2_t>();
1420
0
      uint64x2_t &Val1 = StackMgr.getTop().get<uint64x2_t>();
1421
#if defined(_MSC_VER) && !defined(__clang__) // MSVC
1422
      Val1[0] = (Val1[0] & C[0]) | (Val2[0] & ~C[0]);
1423
      Val1[1] = (Val1[1] & C[1]) | (Val2[1] & ~C[1]);
1424
#else
1425
0
      Val1 = (Val1 & C) | (Val2 & ~C);
1426
0
#endif // MSVC
1427
0
      return {};
1428
0
    }
1429
0
    case OpCode::V128__any_true:
1430
0
      return runVectorAnyTrueOp(StackMgr.getTop());
1431
0
    case OpCode::I8x16__abs:
1432
0
      return runVectorAbsOp<int8_t>(StackMgr.getTop());
1433
0
    case OpCode::I8x16__neg:
1434
0
      return runVectorNegOp<int8_t>(StackMgr.getTop());
1435
0
    case OpCode::I8x16__popcnt:
1436
0
      return runVectorPopcntOp(StackMgr.getTop());
1437
0
    case OpCode::I8x16__all_true:
1438
0
      return runVectorAllTrueOp<uint8_t>(StackMgr.getTop());
1439
0
    case OpCode::I8x16__bitmask:
1440
0
      return runVectorBitMaskOp<uint8_t>(StackMgr.getTop());
1441
0
    case OpCode::I8x16__narrow_i16x8_s: {
1442
0
      ValVariant Rhs = StackMgr.pop();
1443
0
      return runVectorNarrowOp<int16_t, int8_t>(StackMgr.getTop(), Rhs);
1444
0
    }
1445
0
    case OpCode::I8x16__narrow_i16x8_u: {
1446
0
      ValVariant Rhs = StackMgr.pop();
1447
0
      return runVectorNarrowOp<int16_t, uint8_t>(StackMgr.getTop(), Rhs);
1448
0
    }
1449
0
    case OpCode::I8x16__shl: {
1450
0
      ValVariant Rhs = StackMgr.pop();
1451
0
      return runVectorShlOp<uint8_t>(StackMgr.getTop(), Rhs);
1452
0
    }
1453
0
    case OpCode::I8x16__shr_s: {
1454
0
      ValVariant Rhs = StackMgr.pop();
1455
0
      return runVectorShrOp<int8_t>(StackMgr.getTop(), Rhs);
1456
0
    }
1457
0
    case OpCode::I8x16__shr_u: {
1458
0
      ValVariant Rhs = StackMgr.pop();
1459
0
      return runVectorShrOp<uint8_t>(StackMgr.getTop(), Rhs);
1460
0
    }
1461
0
    case OpCode::I8x16__add: {
1462
0
      ValVariant Rhs = StackMgr.pop();
1463
0
      return runVectorAddOp<uint8_t>(StackMgr.getTop(), Rhs);
1464
0
    }
1465
0
    case OpCode::I8x16__add_sat_s: {
1466
0
      ValVariant Rhs = StackMgr.pop();
1467
0
      return runVectorAddSatOp<int8_t>(StackMgr.getTop(), Rhs);
1468
0
    }
1469
0
    case OpCode::I8x16__add_sat_u: {
1470
0
      ValVariant Rhs = StackMgr.pop();
1471
0
      return runVectorAddSatOp<uint8_t>(StackMgr.getTop(), Rhs);
1472
0
    }
1473
0
    case OpCode::I8x16__sub: {
1474
0
      ValVariant Rhs = StackMgr.pop();
1475
0
      return runVectorSubOp<uint8_t>(StackMgr.getTop(), Rhs);
1476
0
    }
1477
0
    case OpCode::I8x16__sub_sat_s: {
1478
0
      ValVariant Rhs = StackMgr.pop();
1479
0
      return runVectorSubSatOp<int8_t>(StackMgr.getTop(), Rhs);
1480
0
    }
1481
0
    case OpCode::I8x16__sub_sat_u: {
1482
0
      ValVariant Rhs = StackMgr.pop();
1483
0
      return runVectorSubSatOp<uint8_t>(StackMgr.getTop(), Rhs);
1484
0
    }
1485
0
    case OpCode::I8x16__min_s: {
1486
0
      ValVariant Rhs = StackMgr.pop();
1487
0
      return runVectorMinOp<int8_t>(StackMgr.getTop(), Rhs);
1488
0
    }
1489
0
    case OpCode::I8x16__min_u: {
1490
0
      ValVariant Rhs = StackMgr.pop();
1491
0
      return runVectorMinOp<uint8_t>(StackMgr.getTop(), Rhs);
1492
0
    }
1493
0
    case OpCode::I8x16__max_s: {
1494
0
      ValVariant Rhs = StackMgr.pop();
1495
0
      return runVectorMaxOp<int8_t>(StackMgr.getTop(), Rhs);
1496
0
    }
1497
0
    case OpCode::I8x16__max_u: {
1498
0
      ValVariant Rhs = StackMgr.pop();
1499
0
      return runVectorMaxOp<uint8_t>(StackMgr.getTop(), Rhs);
1500
0
    }
1501
0
    case OpCode::I8x16__avgr_u: {
1502
0
      ValVariant Rhs = StackMgr.pop();
1503
0
      return runVectorAvgrOp<uint8_t, uint16_t>(StackMgr.getTop(), Rhs);
1504
0
    }
1505
0
    case OpCode::I16x8__abs:
1506
0
      return runVectorAbsOp<int16_t>(StackMgr.getTop());
1507
0
    case OpCode::I16x8__neg:
1508
0
      return runVectorNegOp<int16_t>(StackMgr.getTop());
1509
0
    case OpCode::I16x8__all_true:
1510
0
      return runVectorAllTrueOp<uint16_t>(StackMgr.getTop());
1511
0
    case OpCode::I16x8__bitmask:
1512
0
      return runVectorBitMaskOp<uint16_t>(StackMgr.getTop());
1513
0
    case OpCode::I16x8__narrow_i32x4_s: {
1514
0
      ValVariant Rhs = StackMgr.pop();
1515
0
      return runVectorNarrowOp<int32_t, int16_t>(StackMgr.getTop(), Rhs);
1516
0
    }
1517
0
    case OpCode::I16x8__narrow_i32x4_u: {
1518
0
      ValVariant Rhs = StackMgr.pop();
1519
0
      return runVectorNarrowOp<int32_t, uint16_t>(StackMgr.getTop(), Rhs);
1520
0
    }
1521
0
    case OpCode::I16x8__extend_low_i8x16_s:
1522
0
      return runVectorExtendLowOp<int8_t, int16_t>(StackMgr.getTop());
1523
0
    case OpCode::I16x8__extend_high_i8x16_s:
1524
0
      return runVectorExtendHighOp<int8_t, int16_t>(StackMgr.getTop());
1525
0
    case OpCode::I16x8__extend_low_i8x16_u:
1526
0
      return runVectorExtendLowOp<uint8_t, uint16_t>(StackMgr.getTop());
1527
0
    case OpCode::I16x8__extend_high_i8x16_u:
1528
0
      return runVectorExtendHighOp<uint8_t, uint16_t>(StackMgr.getTop());
1529
0
    case OpCode::I16x8__shl: {
1530
0
      ValVariant Rhs = StackMgr.pop();
1531
0
      return runVectorShlOp<uint16_t>(StackMgr.getTop(), Rhs);
1532
0
    }
1533
0
    case OpCode::I16x8__shr_s: {
1534
0
      ValVariant Rhs = StackMgr.pop();
1535
0
      return runVectorShrOp<int16_t>(StackMgr.getTop(), Rhs);
1536
0
    }
1537
0
    case OpCode::I16x8__shr_u: {
1538
0
      ValVariant Rhs = StackMgr.pop();
1539
0
      return runVectorShrOp<uint16_t>(StackMgr.getTop(), Rhs);
1540
0
    }
1541
0
    case OpCode::I16x8__add: {
1542
0
      ValVariant Rhs = StackMgr.pop();
1543
0
      return runVectorAddOp<uint16_t>(StackMgr.getTop(), Rhs);
1544
0
    }
1545
0
    case OpCode::I16x8__add_sat_s: {
1546
0
      ValVariant Rhs = StackMgr.pop();
1547
0
      return runVectorAddSatOp<int16_t>(StackMgr.getTop(), Rhs);
1548
0
    }
1549
0
    case OpCode::I16x8__add_sat_u: {
1550
0
      ValVariant Rhs = StackMgr.pop();
1551
0
      return runVectorAddSatOp<uint16_t>(StackMgr.getTop(), Rhs);
1552
0
    }
1553
0
    case OpCode::I16x8__sub: {
1554
0
      ValVariant Rhs = StackMgr.pop();
1555
0
      return runVectorSubOp<uint16_t>(StackMgr.getTop(), Rhs);
1556
0
    }
1557
0
    case OpCode::I16x8__sub_sat_s: {
1558
0
      ValVariant Rhs = StackMgr.pop();
1559
0
      return runVectorSubSatOp<int16_t>(StackMgr.getTop(), Rhs);
1560
0
    }
1561
0
    case OpCode::I16x8__sub_sat_u: {
1562
0
      ValVariant Rhs = StackMgr.pop();
1563
0
      return runVectorSubSatOp<uint16_t>(StackMgr.getTop(), Rhs);
1564
0
    }
1565
0
    case OpCode::I16x8__mul: {
1566
0
      ValVariant Rhs = StackMgr.pop();
1567
0
      return runVectorMulOp<uint16_t>(StackMgr.getTop(), Rhs);
1568
0
    }
1569
0
    case OpCode::I16x8__min_s: {
1570
0
      ValVariant Rhs = StackMgr.pop();
1571
0
      return runVectorMinOp<int16_t>(StackMgr.getTop(), Rhs);
1572
0
    }
1573
0
    case OpCode::I16x8__min_u: {
1574
0
      ValVariant Rhs = StackMgr.pop();
1575
0
      return runVectorMinOp<uint16_t>(StackMgr.getTop(), Rhs);
1576
0
    }
1577
0
    case OpCode::I16x8__max_s: {
1578
0
      ValVariant Rhs = StackMgr.pop();
1579
0
      return runVectorMaxOp<int16_t>(StackMgr.getTop(), Rhs);
1580
0
    }
1581
0
    case OpCode::I16x8__max_u: {
1582
0
      ValVariant Rhs = StackMgr.pop();
1583
0
      return runVectorMaxOp<uint16_t>(StackMgr.getTop(), Rhs);
1584
0
    }
1585
0
    case OpCode::I16x8__avgr_u: {
1586
0
      ValVariant Rhs = StackMgr.pop();
1587
0
      return runVectorAvgrOp<uint16_t, uint32_t>(StackMgr.getTop(), Rhs);
1588
0
    }
1589
0
    case OpCode::I16x8__extmul_low_i8x16_s: {
1590
0
      ValVariant Rhs = StackMgr.pop();
1591
0
      return runVectorExtMulLowOp<int8_t, int16_t>(StackMgr.getTop(), Rhs);
1592
0
    }
1593
0
    case OpCode::I16x8__extmul_high_i8x16_s: {
1594
0
      ValVariant Rhs = StackMgr.pop();
1595
0
      return runVectorExtMulHighOp<int8_t, int16_t>(StackMgr.getTop(), Rhs);
1596
0
    }
1597
0
    case OpCode::I16x8__extmul_low_i8x16_u: {
1598
0
      ValVariant Rhs = StackMgr.pop();
1599
0
      return runVectorExtMulLowOp<uint8_t, uint16_t>(StackMgr.getTop(), Rhs);
1600
0
    }
1601
0
    case OpCode::I16x8__extmul_high_i8x16_u: {
1602
0
      ValVariant Rhs = StackMgr.pop();
1603
0
      return runVectorExtMulHighOp<uint8_t, uint16_t>(StackMgr.getTop(), Rhs);
1604
0
    }
1605
0
    case OpCode::I16x8__q15mulr_sat_s: {
1606
0
      ValVariant Rhs = StackMgr.pop();
1607
0
      return runVectorQ15MulSatOp(StackMgr.getTop(), Rhs);
1608
0
    }
1609
0
    case OpCode::I16x8__extadd_pairwise_i8x16_s:
1610
0
      return runVectorExtAddPairwiseOp<int8_t, int16_t>(StackMgr.getTop());
1611
0
    case OpCode::I16x8__extadd_pairwise_i8x16_u:
1612
0
      return runVectorExtAddPairwiseOp<uint8_t, uint16_t>(StackMgr.getTop());
1613
0
    case OpCode::I32x4__abs:
1614
0
      return runVectorAbsOp<int32_t>(StackMgr.getTop());
1615
0
    case OpCode::I32x4__neg:
1616
0
      return runVectorNegOp<int32_t>(StackMgr.getTop());
1617
0
    case OpCode::I32x4__all_true:
1618
0
      return runVectorAllTrueOp<uint32_t>(StackMgr.getTop());
1619
0
    case OpCode::I32x4__bitmask:
1620
0
      return runVectorBitMaskOp<uint32_t>(StackMgr.getTop());
1621
0
    case OpCode::I32x4__extend_low_i16x8_s:
1622
0
      return runVectorExtendLowOp<int16_t, int32_t>(StackMgr.getTop());
1623
0
    case OpCode::I32x4__extend_high_i16x8_s:
1624
0
      return runVectorExtendHighOp<int16_t, int32_t>(StackMgr.getTop());
1625
0
    case OpCode::I32x4__extend_low_i16x8_u:
1626
0
      return runVectorExtendLowOp<uint16_t, uint32_t>(StackMgr.getTop());
1627
0
    case OpCode::I32x4__extend_high_i16x8_u:
1628
0
      return runVectorExtendHighOp<uint16_t, uint32_t>(StackMgr.getTop());
1629
0
    case OpCode::I32x4__shl: {
1630
0
      ValVariant Rhs = StackMgr.pop();
1631
0
      return runVectorShlOp<uint32_t>(StackMgr.getTop(), Rhs);
1632
0
    }
1633
0
    case OpCode::I32x4__shr_s: {
1634
0
      ValVariant Rhs = StackMgr.pop();
1635
0
      return runVectorShrOp<int32_t>(StackMgr.getTop(), Rhs);
1636
0
    }
1637
0
    case OpCode::I32x4__shr_u: {
1638
0
      ValVariant Rhs = StackMgr.pop();
1639
0
      return runVectorShrOp<uint32_t>(StackMgr.getTop(), Rhs);
1640
0
    }
1641
0
    case OpCode::I32x4__add: {
1642
0
      ValVariant Rhs = StackMgr.pop();
1643
0
      return runVectorAddOp<uint32_t>(StackMgr.getTop(), Rhs);
1644
0
    }
1645
0
    case OpCode::I32x4__sub: {
1646
0
      ValVariant Rhs = StackMgr.pop();
1647
0
      return runVectorSubOp<uint32_t>(StackMgr.getTop(), Rhs);
1648
0
    }
1649
0
    case OpCode::I32x4__mul: {
1650
0
      ValVariant Rhs = StackMgr.pop();
1651
0
      return runVectorMulOp<uint32_t>(StackMgr.getTop(), Rhs);
1652
0
    }
1653
0
    case OpCode::I32x4__min_s: {
1654
0
      ValVariant Rhs = StackMgr.pop();
1655
0
      return runVectorMinOp<int32_t>(StackMgr.getTop(), Rhs);
1656
0
    }
1657
0
    case OpCode::I32x4__min_u: {
1658
0
      ValVariant Rhs = StackMgr.pop();
1659
0
      return runVectorMinOp<uint32_t>(StackMgr.getTop(), Rhs);
1660
0
    }
1661
0
    case OpCode::I32x4__max_s: {
1662
0
      ValVariant Rhs = StackMgr.pop();
1663
0
      return runVectorMaxOp<int32_t>(StackMgr.getTop(), Rhs);
1664
0
    }
1665
0
    case OpCode::I32x4__max_u: {
1666
0
      ValVariant Rhs = StackMgr.pop();
1667
0
      return runVectorMaxOp<uint32_t>(StackMgr.getTop(), Rhs);
1668
0
    }
1669
0
    case OpCode::I32x4__extmul_low_i16x8_s: {
1670
0
      ValVariant Rhs = StackMgr.pop();
1671
0
      return runVectorExtMulLowOp<int16_t, int32_t>(StackMgr.getTop(), Rhs);
1672
0
    }
1673
0
    case OpCode::I32x4__extmul_high_i16x8_s: {
1674
0
      ValVariant Rhs = StackMgr.pop();
1675
0
      return runVectorExtMulHighOp<int16_t, int32_t>(StackMgr.getTop(), Rhs);
1676
0
    }
1677
0
    case OpCode::I32x4__extmul_low_i16x8_u: {
1678
0
      ValVariant Rhs = StackMgr.pop();
1679
0
      return runVectorExtMulLowOp<uint16_t, uint32_t>(StackMgr.getTop(), Rhs);
1680
0
    }
1681
0
    case OpCode::I32x4__extmul_high_i16x8_u: {
1682
0
      ValVariant Rhs = StackMgr.pop();
1683
0
      return runVectorExtMulHighOp<uint16_t, uint32_t>(StackMgr.getTop(), Rhs);
1684
0
    }
1685
0
    case OpCode::I32x4__extadd_pairwise_i16x8_s:
1686
0
      return runVectorExtAddPairwiseOp<int16_t, int32_t>(StackMgr.getTop());
1687
0
    case OpCode::I32x4__extadd_pairwise_i16x8_u:
1688
0
      return runVectorExtAddPairwiseOp<uint16_t, uint32_t>(StackMgr.getTop());
1689
0
    case OpCode::I64x2__abs:
1690
0
      return runVectorAbsOp<int64_t>(StackMgr.getTop());
1691
0
    case OpCode::I64x2__neg:
1692
0
      return runVectorNegOp<int64_t>(StackMgr.getTop());
1693
0
    case OpCode::I64x2__all_true:
1694
0
      return runVectorAllTrueOp<uint64_t>(StackMgr.getTop());
1695
0
    case OpCode::I64x2__bitmask:
1696
0
      return runVectorBitMaskOp<uint64_t>(StackMgr.getTop());
1697
0
    case OpCode::I64x2__extend_low_i32x4_s:
1698
0
      return runVectorExtendLowOp<int32_t, int64_t>(StackMgr.getTop());
1699
0
    case OpCode::I64x2__extend_high_i32x4_s:
1700
0
      return runVectorExtendHighOp<int32_t, int64_t>(StackMgr.getTop());
1701
0
    case OpCode::I64x2__extend_low_i32x4_u:
1702
0
      return runVectorExtendLowOp<uint32_t, uint64_t>(StackMgr.getTop());
1703
0
    case OpCode::I64x2__extend_high_i32x4_u:
1704
0
      return runVectorExtendHighOp<uint32_t, uint64_t>(StackMgr.getTop());
1705
0
    case OpCode::I64x2__shl: {
1706
0
      ValVariant Rhs = StackMgr.pop();
1707
0
      return runVectorShlOp<uint64_t>(StackMgr.getTop(), Rhs);
1708
0
    }
1709
0
    case OpCode::I64x2__shr_s: {
1710
0
      ValVariant Rhs = StackMgr.pop();
1711
0
      return runVectorShrOp<int64_t>(StackMgr.getTop(), Rhs);
1712
0
    }
1713
0
    case OpCode::I64x2__shr_u: {
1714
0
      ValVariant Rhs = StackMgr.pop();
1715
0
      return runVectorShrOp<uint64_t>(StackMgr.getTop(), Rhs);
1716
0
    }
1717
0
    case OpCode::I64x2__add: {
1718
0
      ValVariant Rhs = StackMgr.pop();
1719
0
      return runVectorAddOp<uint64_t>(StackMgr.getTop(), Rhs);
1720
0
    }
1721
0
    case OpCode::I64x2__sub: {
1722
0
      ValVariant Rhs = StackMgr.pop();
1723
0
      return runVectorSubOp<uint64_t>(StackMgr.getTop(), Rhs);
1724
0
    }
1725
0
    case OpCode::I64x2__mul: {
1726
0
      ValVariant Rhs = StackMgr.pop();
1727
0
      return runVectorMulOp<uint64_t>(StackMgr.getTop(), Rhs);
1728
0
    }
1729
0
    case OpCode::I64x2__extmul_low_i32x4_s: {
1730
0
      ValVariant Rhs = StackMgr.pop();
1731
0
      return runVectorExtMulLowOp<int32_t, int64_t>(StackMgr.getTop(), Rhs);
1732
0
    }
1733
0
    case OpCode::I64x2__extmul_high_i32x4_s: {
1734
0
      ValVariant Rhs = StackMgr.pop();
1735
0
      return runVectorExtMulHighOp<int32_t, int64_t>(StackMgr.getTop(), Rhs);
1736
0
    }
1737
0
    case OpCode::I64x2__extmul_low_i32x4_u: {
1738
0
      ValVariant Rhs = StackMgr.pop();
1739
0
      return runVectorExtMulLowOp<uint32_t, uint64_t>(StackMgr.getTop(), Rhs);
1740
0
    }
1741
0
    case OpCode::I64x2__extmul_high_i32x4_u: {
1742
0
      ValVariant Rhs = StackMgr.pop();
1743
0
      return runVectorExtMulHighOp<uint32_t, uint64_t>(StackMgr.getTop(), Rhs);
1744
0
    }
1745
0
    case OpCode::F32x4__abs:
1746
0
      return runVectorAbsOp<float>(StackMgr.getTop());
1747
0
    case OpCode::F32x4__neg:
1748
0
      return runVectorNegOp<float>(StackMgr.getTop());
1749
0
    case OpCode::F32x4__sqrt:
1750
0
      return runVectorSqrtOp<float>(StackMgr.getTop());
1751
0
    case OpCode::F32x4__add: {
1752
0
      ValVariant Rhs = StackMgr.pop();
1753
0
      return runVectorAddOp<float>(StackMgr.getTop(), Rhs);
1754
0
    }
1755
0
    case OpCode::F32x4__sub: {
1756
0
      ValVariant Rhs = StackMgr.pop();
1757
0
      return runVectorSubOp<float>(StackMgr.getTop(), Rhs);
1758
0
    }
1759
0
    case OpCode::F32x4__mul: {
1760
0
      ValVariant Rhs = StackMgr.pop();
1761
0
      return runVectorMulOp<float>(StackMgr.getTop(), Rhs);
1762
0
    }
1763
0
    case OpCode::F32x4__div: {
1764
0
      ValVariant Rhs = StackMgr.pop();
1765
0
      return runVectorDivOp<float>(StackMgr.getTop(), Rhs);
1766
0
    }
1767
0
    case OpCode::F32x4__min: {
1768
0
      ValVariant Rhs = StackMgr.pop();
1769
0
      return runVectorFMinOp<float>(StackMgr.getTop(), Rhs);
1770
0
    }
1771
0
    case OpCode::F32x4__max: {
1772
0
      ValVariant Rhs = StackMgr.pop();
1773
0
      return runVectorFMaxOp<float>(StackMgr.getTop(), Rhs);
1774
0
    }
1775
0
    case OpCode::F32x4__pmin: {
1776
0
      ValVariant Rhs = StackMgr.pop();
1777
0
      return runVectorMinOp<float>(StackMgr.getTop(), Rhs);
1778
0
    }
1779
0
    case OpCode::F32x4__pmax: {
1780
0
      ValVariant Rhs = StackMgr.pop();
1781
0
      return runVectorMaxOp<float>(StackMgr.getTop(), Rhs);
1782
0
    }
1783
0
    case OpCode::F64x2__abs:
1784
0
      return runVectorAbsOp<double>(StackMgr.getTop());
1785
0
    case OpCode::F64x2__neg:
1786
0
      return runVectorNegOp<double>(StackMgr.getTop());
1787
0
    case OpCode::F64x2__sqrt:
1788
0
      return runVectorSqrtOp<double>(StackMgr.getTop());
1789
0
    case OpCode::F64x2__add: {
1790
0
      ValVariant Rhs = StackMgr.pop();
1791
0
      return runVectorAddOp<double>(StackMgr.getTop(), Rhs);
1792
0
    }
1793
0
    case OpCode::F64x2__sub: {
1794
0
      ValVariant Rhs = StackMgr.pop();
1795
0
      return runVectorSubOp<double>(StackMgr.getTop(), Rhs);
1796
0
    }
1797
0
    case OpCode::F64x2__mul: {
1798
0
      ValVariant Rhs = StackMgr.pop();
1799
0
      return runVectorMulOp<double>(StackMgr.getTop(), Rhs);
1800
0
    }
1801
0
    case OpCode::F64x2__div: {
1802
0
      ValVariant Rhs = StackMgr.pop();
1803
0
      return runVectorDivOp<double>(StackMgr.getTop(), Rhs);
1804
0
    }
1805
0
    case OpCode::F64x2__min: {
1806
0
      ValVariant Rhs = StackMgr.pop();
1807
0
      return runVectorFMinOp<double>(StackMgr.getTop(), Rhs);
1808
0
    }
1809
0
    case OpCode::F64x2__max: {
1810
0
      ValVariant Rhs = StackMgr.pop();
1811
0
      return runVectorFMaxOp<double>(StackMgr.getTop(), Rhs);
1812
0
    }
1813
0
    case OpCode::F64x2__pmin: {
1814
0
      ValVariant Rhs = StackMgr.pop();
1815
0
      return runVectorMinOp<double>(StackMgr.getTop(), Rhs);
1816
0
    }
1817
0
    case OpCode::F64x2__pmax: {
1818
0
      ValVariant Rhs = StackMgr.pop();
1819
0
      return runVectorMaxOp<double>(StackMgr.getTop(), Rhs);
1820
0
    }
1821
0
    case OpCode::I32x4__trunc_sat_f32x4_s:
1822
0
      return runVectorTruncSatOp<float, int32_t>(StackMgr.getTop());
1823
0
    case OpCode::I32x4__trunc_sat_f32x4_u:
1824
0
      return runVectorTruncSatOp<float, uint32_t>(StackMgr.getTop());
1825
0
    case OpCode::F32x4__convert_i32x4_s:
1826
0
      return runVectorConvertOp<int32_t, float>(StackMgr.getTop());
1827
0
    case OpCode::F32x4__convert_i32x4_u:
1828
0
      return runVectorConvertOp<uint32_t, float>(StackMgr.getTop());
1829
0
    case OpCode::I32x4__trunc_sat_f64x2_s_zero:
1830
0
      return runVectorTruncSatOp<double, int32_t>(StackMgr.getTop());
1831
0
    case OpCode::I32x4__trunc_sat_f64x2_u_zero:
1832
0
      return runVectorTruncSatOp<double, uint32_t>(StackMgr.getTop());
1833
0
    case OpCode::F64x2__convert_low_i32x4_s:
1834
0
      return runVectorConvertOp<int32_t, double>(StackMgr.getTop());
1835
0
    case OpCode::F64x2__convert_low_i32x4_u:
1836
0
      return runVectorConvertOp<uint32_t, double>(StackMgr.getTop());
1837
0
    case OpCode::F32x4__demote_f64x2_zero:
1838
0
      return runVectorDemoteOp(StackMgr.getTop());
1839
0
    case OpCode::F64x2__promote_low_f32x4:
1840
0
      return runVectorPromoteOp(StackMgr.getTop());
1841
1842
#if defined(_MSC_VER) && !defined(__clang__) // MSVC
1843
    case OpCode::I32x4__dot_i16x8_s: {
1844
      using int32x8_t = SIMDArray<int32_t, 32>;
1845
      const ValVariant Val2 = StackMgr.pop();
1846
      ValVariant &Val1 = StackMgr.getTop();
1847
1848
      auto &V2 = Val2.get<int16x8_t>();
1849
      auto &V1 = Val1.get<int16x8_t>();
1850
      int32x8_t M;
1851
1852
      for (size_t I = 0; I < 8; ++I) {
1853
        M[I] = V1[I] * V2[I];
1854
      }
1855
1856
      int32x4_t Result;
1857
      for (size_t I = 0; I < 4; ++I) {
1858
        Result[I] = M[I * 2] + M[I * 2 + 1];
1859
      }
1860
      Val1.emplace<int32x4_t>(Result);
1861
      return {};
1862
    }
1863
#else
1864
0
    case OpCode::I32x4__dot_i16x8_s: {
1865
0
      using int32x8_t [[gnu::vector_size(32)]] = int32_t;
1866
0
      const ValVariant Val2 = StackMgr.pop();
1867
0
      ValVariant &Val1 = StackMgr.getTop();
1868
1869
0
      auto &V2 = Val2.get<int16x8_t>();
1870
0
      auto &V1 = Val1.get<int16x8_t>();
1871
0
      const auto M = __builtin_convertvector(V1, int32x8_t) *
1872
0
                     __builtin_convertvector(V2, int32x8_t);
1873
0
      const int32x4_t L = {M[0], M[2], M[4], M[6]};
1874
0
      const int32x4_t R = {M[1], M[3], M[5], M[7]};
1875
0
      Val1.emplace<int32x4_t>(L + R);
1876
1877
0
      return {};
1878
0
    }
1879
0
#endif // MSVC
1880
0
    case OpCode::F32x4__ceil:
1881
0
      return runVectorCeilOp<float>(StackMgr.getTop());
1882
0
    case OpCode::F32x4__floor:
1883
0
      return runVectorFloorOp<float>(StackMgr.getTop());
1884
0
    case OpCode::F32x4__trunc:
1885
0
      return runVectorTruncOp<float>(StackMgr.getTop());
1886
0
    case OpCode::F32x4__nearest:
1887
0
      return runVectorNearestOp<float>(StackMgr.getTop());
1888
0
    case OpCode::F64x2__ceil:
1889
0
      return runVectorCeilOp<double>(StackMgr.getTop());
1890
0
    case OpCode::F64x2__floor:
1891
0
      return runVectorFloorOp<double>(StackMgr.getTop());
1892
0
    case OpCode::F64x2__trunc:
1893
0
      return runVectorTruncOp<double>(StackMgr.getTop());
1894
0
    case OpCode::F64x2__nearest:
1895
0
      return runVectorNearestOp<double>(StackMgr.getTop());
1896
1897
    // Relaxed SIMD Instructions
1898
0
    case OpCode::I8x16__relaxed_swizzle: {
1899
0
      const ValVariant Val2 = StackMgr.pop();
1900
0
      ValVariant &Val1 = StackMgr.getTop();
1901
0
      uint8x16_t Index = Val2.get<uint8x16_t>();
1902
      if constexpr (Endian::native == Endian::big) {
1903
#if defined(_MSC_VER) && !defined(__clang__)
1904
        std::for_each(Index.begin(), Index.end(), [](auto &I) { I = 15 - I; });
1905
#else
1906
        Index = 15 - Index;
1907
#endif
1908
      }
1909
0
      uint8x16_t &Vector = Val1.get<uint8x16_t>();
1910
0
      uint8x16_t Result{};
1911
0
      for (size_t I = 0; I < 16; ++I) {
1912
0
        const uint8_t SwizzleIndex = Index[I];
1913
0
        if (SwizzleIndex < 16) {
1914
0
          Result[I] = Vector[SwizzleIndex];
1915
0
        } else {
1916
0
          Result[I] = 0;
1917
0
        }
1918
0
      }
1919
0
      Vector = Result;
1920
0
      return {};
1921
0
    }
1922
0
    case OpCode::I32x4__relaxed_trunc_f32x4_s:
1923
0
      return runVectorTruncSatOp<float, int32_t>(StackMgr.getTop());
1924
0
    case OpCode::I32x4__relaxed_trunc_f32x4_u:
1925
0
      return runVectorTruncSatOp<float, uint32_t>(StackMgr.getTop());
1926
0
    case OpCode::I32x4__relaxed_trunc_f64x2_s_zero:
1927
0
      return runVectorTruncSatOp<double, int32_t>(StackMgr.getTop());
1928
0
    case OpCode::I32x4__relaxed_trunc_f64x2_u_zero:
1929
0
      return runVectorTruncSatOp<double, uint32_t>(StackMgr.getTop());
1930
0
    case OpCode::F32x4__relaxed_madd: {
1931
0
      const ValVariant Val3 = StackMgr.pop();
1932
0
      const ValVariant Val2 = StackMgr.pop();
1933
0
      runVectorMulOp<float>(StackMgr.getTop(), Val2);
1934
0
      return runVectorAddOp<float>(StackMgr.getTop(), Val3);
1935
0
    }
1936
0
    case OpCode::F32x4__relaxed_nmadd: {
1937
0
      const ValVariant Val3 = StackMgr.pop();
1938
0
      const ValVariant Val2 = StackMgr.pop();
1939
0
      runVectorNegOp<float>(StackMgr.getTop());
1940
0
      runVectorMulOp<float>(StackMgr.getTop(), Val2);
1941
0
      return runVectorAddOp<float>(StackMgr.getTop(), Val3);
1942
0
    }
1943
0
    case OpCode::F64x2__relaxed_madd: {
1944
0
      const ValVariant Val3 = StackMgr.pop();
1945
0
      const ValVariant Val2 = StackMgr.pop();
1946
0
      runVectorMulOp<double>(StackMgr.getTop(), Val2);
1947
0
      return runVectorAddOp<double>(StackMgr.getTop(), Val3);
1948
0
    }
1949
0
    case OpCode::F64x2__relaxed_nmadd: {
1950
0
      const ValVariant Val3 = StackMgr.pop();
1951
0
      const ValVariant Val2 = StackMgr.pop();
1952
0
      runVectorMulOp<double>(StackMgr.getTop(), Val2);
1953
0
      runVectorNegOp<double>(StackMgr.getTop());
1954
0
      return runVectorAddOp<double>(StackMgr.getTop(), Val3);
1955
0
    }
1956
0
    case OpCode::I8x16__relaxed_laneselect: {
1957
0
      const ValVariant Mask = StackMgr.pop();
1958
0
      const ValVariant Val2 = StackMgr.pop();
1959
0
      return runVectorRelaxedLaneselectOp<uint8_t>(StackMgr.getTop(), Val2,
1960
0
                                                   Mask);
1961
0
    }
1962
0
    case OpCode::I16x8__relaxed_laneselect: {
1963
0
      const ValVariant Mask = StackMgr.pop();
1964
0
      const ValVariant Val2 = StackMgr.pop();
1965
0
      return runVectorRelaxedLaneselectOp<uint16_t>(StackMgr.getTop(), Val2,
1966
0
                                                    Mask);
1967
0
    }
1968
0
    case OpCode::I32x4__relaxed_laneselect: {
1969
0
      const ValVariant Mask = StackMgr.pop();
1970
0
      const ValVariant Val2 = StackMgr.pop();
1971
0
      return runVectorRelaxedLaneselectOp<uint32_t>(StackMgr.getTop(), Val2,
1972
0
                                                    Mask);
1973
0
    }
1974
0
    case OpCode::I64x2__relaxed_laneselect: {
1975
0
      const ValVariant Mask = StackMgr.pop();
1976
0
      const ValVariant Val2 = StackMgr.pop();
1977
0
      return runVectorRelaxedLaneselectOp<uint64_t>(StackMgr.getTop(), Val2,
1978
0
                                                    Mask);
1979
0
    }
1980
0
    case OpCode::F32x4__relaxed_min: {
1981
0
      const ValVariant Val2 = StackMgr.pop();
1982
0
      return runVectorFMinOp<float>(StackMgr.getTop(), Val2);
1983
0
    }
1984
0
    case OpCode::F32x4__relaxed_max: {
1985
0
      const ValVariant Val2 = StackMgr.pop();
1986
0
      return runVectorFMaxOp<float>(StackMgr.getTop(), Val2);
1987
0
    }
1988
0
    case OpCode::F64x2__relaxed_min: {
1989
0
      const ValVariant Val2 = StackMgr.pop();
1990
0
      return runVectorFMinOp<double>(StackMgr.getTop(), Val2);
1991
0
    }
1992
0
    case OpCode::F64x2__relaxed_max: {
1993
0
      const ValVariant Val2 = StackMgr.pop();
1994
0
      return runVectorFMaxOp<double>(StackMgr.getTop(), Val2);
1995
0
    }
1996
0
    case OpCode::I16x8__relaxed_q15mulr_s: {
1997
0
      ValVariant Rhs = StackMgr.pop();
1998
0
      return runVectorQ15MulSatOp(StackMgr.getTop(), Rhs);
1999
0
    }
2000
0
    case OpCode::I16x8__relaxed_dot_i8x16_i7x16_s: {
2001
0
      ValVariant Rhs = StackMgr.pop();
2002
0
      return runVectorRelaxedIntegerDotProductOp(StackMgr.getTop(), Rhs);
2003
0
    }
2004
0
    case OpCode::I32x4__relaxed_dot_i8x16_i7x16_add_s: {
2005
0
      ValVariant C = StackMgr.pop();
2006
0
      ValVariant Rhs = StackMgr.pop();
2007
0
      return runVectorRelaxedIntegerDotProductOpAdd(StackMgr.getTop(), Rhs, C);
2008
0
    }
2009
2010
    // Atomic Instructions
2011
0
    case OpCode::Atomic__fence:
2012
0
      return runMemoryFenceOp();
2013
0
    case OpCode::Memory__atomic__notify:
2014
0
      return runAtomicNotifyOp(
2015
0
          StackMgr,
2016
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2017
0
          Instr);
2018
0
    case OpCode::Memory__atomic__wait32:
2019
0
      return runAtomicWaitOp<int32_t>(
2020
0
          StackMgr,
2021
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2022
0
          Instr);
2023
0
    case OpCode::Memory__atomic__wait64:
2024
0
      return runAtomicWaitOp<int64_t>(
2025
0
          StackMgr,
2026
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2027
0
          Instr);
2028
0
    case OpCode::I32__atomic__load:
2029
0
      return runAtomicLoadOp<int32_t, uint32_t>(
2030
0
          StackMgr,
2031
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2032
0
          Instr);
2033
0
    case OpCode::I64__atomic__load:
2034
0
      return runAtomicLoadOp<int64_t, uint64_t>(
2035
0
          StackMgr,
2036
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2037
0
          Instr);
2038
0
    case OpCode::I32__atomic__load8_u:
2039
0
      return runAtomicLoadOp<uint32_t, uint8_t>(
2040
0
          StackMgr,
2041
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2042
0
          Instr);
2043
0
    case OpCode::I32__atomic__load16_u:
2044
0
      return runAtomicLoadOp<uint32_t, uint16_t>(
2045
0
          StackMgr,
2046
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2047
0
          Instr);
2048
0
    case OpCode::I64__atomic__load8_u:
2049
0
      return runAtomicLoadOp<uint64_t, uint8_t>(
2050
0
          StackMgr,
2051
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2052
0
          Instr);
2053
0
    case OpCode::I64__atomic__load16_u:
2054
0
      return runAtomicLoadOp<uint64_t, uint16_t>(
2055
0
          StackMgr,
2056
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2057
0
          Instr);
2058
0
    case OpCode::I64__atomic__load32_u:
2059
0
      return runAtomicLoadOp<uint64_t, uint32_t>(
2060
0
          StackMgr,
2061
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2062
0
          Instr);
2063
0
    case OpCode::I32__atomic__store:
2064
0
      return runAtomicStoreOp<int32_t, uint32_t>(
2065
0
          StackMgr,
2066
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2067
0
          Instr);
2068
0
    case OpCode::I64__atomic__store:
2069
0
      return runAtomicStoreOp<int64_t, uint64_t>(
2070
0
          StackMgr,
2071
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2072
0
          Instr);
2073
0
    case OpCode::I32__atomic__store8:
2074
0
      return runAtomicStoreOp<uint32_t, uint8_t>(
2075
0
          StackMgr,
2076
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2077
0
          Instr);
2078
0
    case OpCode::I32__atomic__store16:
2079
0
      return runAtomicStoreOp<uint32_t, uint16_t>(
2080
0
          StackMgr,
2081
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2082
0
          Instr);
2083
0
    case OpCode::I64__atomic__store8:
2084
0
      return runAtomicStoreOp<uint64_t, uint8_t>(
2085
0
          StackMgr,
2086
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2087
0
          Instr);
2088
0
    case OpCode::I64__atomic__store16:
2089
0
      return runAtomicStoreOp<uint64_t, uint16_t>(
2090
0
          StackMgr,
2091
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2092
0
          Instr);
2093
0
    case OpCode::I64__atomic__store32:
2094
0
      return runAtomicStoreOp<uint64_t, uint32_t>(
2095
0
          StackMgr,
2096
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2097
0
          Instr);
2098
0
    case OpCode::I32__atomic__rmw__add:
2099
0
      return runAtomicAddOp<int32_t, uint32_t>(
2100
0
          StackMgr,
2101
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2102
0
          Instr);
2103
0
    case OpCode::I64__atomic__rmw__add:
2104
0
      return runAtomicAddOp<int64_t, uint64_t>(
2105
0
          StackMgr,
2106
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2107
0
          Instr);
2108
0
    case OpCode::I32__atomic__rmw8__add_u:
2109
0
      return runAtomicAddOp<uint32_t, uint8_t>(
2110
0
          StackMgr,
2111
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2112
0
          Instr);
2113
0
    case OpCode::I32__atomic__rmw16__add_u:
2114
0
      return runAtomicAddOp<uint32_t, uint16_t>(
2115
0
          StackMgr,
2116
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2117
0
          Instr);
2118
0
    case OpCode::I64__atomic__rmw8__add_u:
2119
0
      return runAtomicAddOp<uint64_t, uint8_t>(
2120
0
          StackMgr,
2121
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2122
0
          Instr);
2123
0
    case OpCode::I64__atomic__rmw16__add_u:
2124
0
      return runAtomicAddOp<uint64_t, uint16_t>(
2125
0
          StackMgr,
2126
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2127
0
          Instr);
2128
0
    case OpCode::I64__atomic__rmw32__add_u:
2129
0
      return runAtomicAddOp<uint64_t, uint32_t>(
2130
0
          StackMgr,
2131
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2132
0
          Instr);
2133
0
    case OpCode::I32__atomic__rmw__sub:
2134
0
      return runAtomicSubOp<int32_t, uint32_t>(
2135
0
          StackMgr,
2136
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2137
0
          Instr);
2138
0
    case OpCode::I64__atomic__rmw__sub:
2139
0
      return runAtomicSubOp<int64_t, uint64_t>(
2140
0
          StackMgr,
2141
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2142
0
          Instr);
2143
0
    case OpCode::I32__atomic__rmw8__sub_u:
2144
0
      return runAtomicSubOp<uint32_t, uint8_t>(
2145
0
          StackMgr,
2146
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2147
0
          Instr);
2148
0
    case OpCode::I32__atomic__rmw16__sub_u:
2149
0
      return runAtomicSubOp<uint32_t, uint16_t>(
2150
0
          StackMgr,
2151
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2152
0
          Instr);
2153
0
    case OpCode::I64__atomic__rmw8__sub_u:
2154
0
      return runAtomicSubOp<uint64_t, uint8_t>(
2155
0
          StackMgr,
2156
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2157
0
          Instr);
2158
0
    case OpCode::I64__atomic__rmw16__sub_u:
2159
0
      return runAtomicSubOp<uint64_t, uint16_t>(
2160
0
          StackMgr,
2161
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2162
0
          Instr);
2163
0
    case OpCode::I64__atomic__rmw32__sub_u:
2164
0
      return runAtomicSubOp<uint64_t, uint32_t>(
2165
0
          StackMgr,
2166
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2167
0
          Instr);
2168
0
    case OpCode::I32__atomic__rmw__and:
2169
0
      return runAtomicAndOp<int32_t, uint32_t>(
2170
0
          StackMgr,
2171
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2172
0
          Instr);
2173
0
    case OpCode::I64__atomic__rmw__and:
2174
0
      return runAtomicAndOp<int64_t, uint64_t>(
2175
0
          StackMgr,
2176
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2177
0
          Instr);
2178
0
    case OpCode::I32__atomic__rmw8__and_u:
2179
0
      return runAtomicAndOp<uint32_t, uint8_t>(
2180
0
          StackMgr,
2181
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2182
0
          Instr);
2183
0
    case OpCode::I32__atomic__rmw16__and_u:
2184
0
      return runAtomicAndOp<uint32_t, uint16_t>(
2185
0
          StackMgr,
2186
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2187
0
          Instr);
2188
0
    case OpCode::I64__atomic__rmw8__and_u:
2189
0
      return runAtomicAndOp<uint64_t, uint8_t>(
2190
0
          StackMgr,
2191
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2192
0
          Instr);
2193
0
    case OpCode::I64__atomic__rmw16__and_u:
2194
0
      return runAtomicAndOp<uint64_t, uint16_t>(
2195
0
          StackMgr,
2196
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2197
0
          Instr);
2198
0
    case OpCode::I64__atomic__rmw32__and_u:
2199
0
      return runAtomicAndOp<uint64_t, uint32_t>(
2200
0
          StackMgr,
2201
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2202
0
          Instr);
2203
0
    case OpCode::I32__atomic__rmw__or:
2204
0
      return runAtomicOrOp<int32_t, uint32_t>(
2205
0
          StackMgr,
2206
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2207
0
          Instr);
2208
0
    case OpCode::I64__atomic__rmw__or:
2209
0
      return runAtomicOrOp<int64_t, uint64_t>(
2210
0
          StackMgr,
2211
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2212
0
          Instr);
2213
0
    case OpCode::I32__atomic__rmw8__or_u:
2214
0
      return runAtomicOrOp<uint32_t, uint8_t>(
2215
0
          StackMgr,
2216
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2217
0
          Instr);
2218
0
    case OpCode::I32__atomic__rmw16__or_u:
2219
0
      return runAtomicOrOp<uint32_t, uint16_t>(
2220
0
          StackMgr,
2221
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2222
0
          Instr);
2223
0
    case OpCode::I64__atomic__rmw8__or_u:
2224
0
      return runAtomicOrOp<uint64_t, uint8_t>(
2225
0
          StackMgr,
2226
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2227
0
          Instr);
2228
0
    case OpCode::I64__atomic__rmw16__or_u:
2229
0
      return runAtomicOrOp<uint64_t, uint16_t>(
2230
0
          StackMgr,
2231
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2232
0
          Instr);
2233
0
    case OpCode::I64__atomic__rmw32__or_u:
2234
0
      return runAtomicOrOp<uint64_t, uint32_t>(
2235
0
          StackMgr,
2236
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2237
0
          Instr);
2238
0
    case OpCode::I32__atomic__rmw__xor:
2239
0
      return runAtomicXorOp<int32_t, uint32_t>(
2240
0
          StackMgr,
2241
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2242
0
          Instr);
2243
0
    case OpCode::I64__atomic__rmw__xor:
2244
0
      return runAtomicXorOp<int64_t, uint64_t>(
2245
0
          StackMgr,
2246
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2247
0
          Instr);
2248
0
    case OpCode::I32__atomic__rmw8__xor_u:
2249
0
      return runAtomicXorOp<uint32_t, uint8_t>(
2250
0
          StackMgr,
2251
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2252
0
          Instr);
2253
0
    case OpCode::I32__atomic__rmw16__xor_u:
2254
0
      return runAtomicXorOp<uint32_t, uint16_t>(
2255
0
          StackMgr,
2256
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2257
0
          Instr);
2258
0
    case OpCode::I64__atomic__rmw8__xor_u:
2259
0
      return runAtomicXorOp<uint64_t, uint8_t>(
2260
0
          StackMgr,
2261
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2262
0
          Instr);
2263
0
    case OpCode::I64__atomic__rmw16__xor_u:
2264
0
      return runAtomicXorOp<uint64_t, uint16_t>(
2265
0
          StackMgr,
2266
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2267
0
          Instr);
2268
0
    case OpCode::I64__atomic__rmw32__xor_u:
2269
0
      return runAtomicXorOp<uint64_t, uint32_t>(
2270
0
          StackMgr,
2271
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2272
0
          Instr);
2273
0
    case OpCode::I32__atomic__rmw__xchg:
2274
0
      return runAtomicExchangeOp<int32_t, uint32_t>(
2275
0
          StackMgr,
2276
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2277
0
          Instr);
2278
0
    case OpCode::I64__atomic__rmw__xchg:
2279
0
      return runAtomicExchangeOp<int64_t, uint64_t>(
2280
0
          StackMgr,
2281
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2282
0
          Instr);
2283
0
    case OpCode::I32__atomic__rmw8__xchg_u:
2284
0
      return runAtomicExchangeOp<uint32_t, uint8_t>(
2285
0
          StackMgr,
2286
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2287
0
          Instr);
2288
0
    case OpCode::I32__atomic__rmw16__xchg_u:
2289
0
      return runAtomicExchangeOp<uint32_t, uint16_t>(
2290
0
          StackMgr,
2291
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2292
0
          Instr);
2293
0
    case OpCode::I64__atomic__rmw8__xchg_u:
2294
0
      return runAtomicExchangeOp<uint64_t, uint8_t>(
2295
0
          StackMgr,
2296
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2297
0
          Instr);
2298
0
    case OpCode::I64__atomic__rmw16__xchg_u:
2299
0
      return runAtomicExchangeOp<uint64_t, uint16_t>(
2300
0
          StackMgr,
2301
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2302
0
          Instr);
2303
0
    case OpCode::I64__atomic__rmw32__xchg_u:
2304
0
      return runAtomicExchangeOp<uint64_t, uint32_t>(
2305
0
          StackMgr,
2306
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2307
0
          Instr);
2308
0
    case OpCode::I32__atomic__rmw__cmpxchg:
2309
0
      return runAtomicCompareExchangeOp<int32_t, uint32_t>(
2310
0
          StackMgr,
2311
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2312
0
          Instr);
2313
0
    case OpCode::I64__atomic__rmw__cmpxchg:
2314
0
      return runAtomicCompareExchangeOp<int64_t, uint64_t>(
2315
0
          StackMgr,
2316
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2317
0
          Instr);
2318
0
    case OpCode::I32__atomic__rmw8__cmpxchg_u:
2319
0
      return runAtomicCompareExchangeOp<uint32_t, uint8_t>(
2320
0
          StackMgr,
2321
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2322
0
          Instr);
2323
0
    case OpCode::I32__atomic__rmw16__cmpxchg_u:
2324
0
      return runAtomicCompareExchangeOp<uint32_t, uint16_t>(
2325
0
          StackMgr,
2326
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2327
0
          Instr);
2328
0
    case OpCode::I64__atomic__rmw8__cmpxchg_u:
2329
0
      return runAtomicCompareExchangeOp<uint64_t, uint8_t>(
2330
0
          StackMgr,
2331
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2332
0
          Instr);
2333
0
    case OpCode::I64__atomic__rmw16__cmpxchg_u:
2334
0
      return runAtomicCompareExchangeOp<uint64_t, uint16_t>(
2335
0
          StackMgr,
2336
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2337
0
          Instr);
2338
0
    case OpCode::I64__atomic__rmw32__cmpxchg_u:
2339
0
      return runAtomicCompareExchangeOp<uint64_t, uint32_t>(
2340
0
          StackMgr,
2341
0
          *getMemInstByIdx(StackMgr.getModule(), Instr.getTargetIndex()),
2342
0
          Instr);
2343
2344
0
    default:
2345
0
      return {};
2346
0
    }
2347
0
  };
2348
2349
0
  while (PC != PCEnd) {
2350
0
    if (Stat) {
2351
0
      OpCode Code = PC->getOpCode();
2352
0
      if (Conf.getStatisticsConfigure().isInstructionCounting()) {
2353
0
        Stat->incInstrCount();
2354
0
      }
2355
      // Add cost. Note: if-else cases should be processed additionally.
2356
0
      if (Conf.getStatisticsConfigure().isCostMeasuring()) {
2357
0
        if (unlikely(!Stat->addInstrCost(Code))) {
2358
0
          const AST::Instruction &Instr = *PC;
2359
0
          spdlog::error(
2360
0
              ErrInfo::InfoInstruction(Instr.getOpCode(), Instr.getOffset()));
2361
0
          return Unexpect(ErrCode::Value::CostLimitExceeded);
2362
0
        }
2363
0
      }
2364
0
    }
2365
#if defined(_MSC_VER) && !defined(__clang__) &&                                \
2366
    __has_cpp_attribute(msvc::forceinline_calls)
2367
    [[msvc::forceinline_calls]]
2368
#endif
2369
0
    EXPECTED_TRY(Dispatch().map_error([this, &StackMgr, PC](auto E) {
2370
0
      StackTraceSize = interpreterStackTrace(StackMgr, StackTrace).size();
2371
0
      if (Conf.getRuntimeConfigure().isEnableCoredump() &&
2372
0
          E.getErrCodePhase() == WasmPhase::Execution) {
2373
0
        Coredump::generateCoredump(
2374
0
            StackMgr, PC, Conf.getRuntimeConfigure().isCoredumpWasmgdb());
2375
0
      }
2376
0
      return E;
2377
0
    }));
2378
0
    PC++;
2379
0
  }
2380
0
  return {};
2381
0
}
2382
2383
} // namespace Executor
2384
} // namespace WasmEdge