summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/interp/binary-reader-interp.cc (renamed from src/binary-reader-interp.cc)5
-rw-r--r--src/interp/binary-reader-interp.h (renamed from src/binary-reader-interp.h)0
-rw-r--r--src/interp/interp-disassemble.cc609
-rw-r--r--src/interp/interp-internal.h94
-rw-r--r--src/interp/interp-trace.cc713
-rw-r--r--src/interp/interp.cc (renamed from src/interp.cc)1333
-rw-r--r--src/interp/interp.h (renamed from src/interp.h)13
-rw-r--r--src/test-interp.cc4
-rw-r--r--src/tools/spectest-interp.cc4
-rw-r--r--src/tools/wasm-interp.cc4
10 files changed, 1429 insertions, 1350 deletions
diff --git a/src/binary-reader-interp.cc b/src/interp/binary-reader-interp.cc
index cfc32dba..7533954f 100644
--- a/src/binary-reader-interp.cc
+++ b/src/interp/binary-reader-interp.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "src/binary-reader-interp.h"
+#include "src/interp/binary-reader-interp.h"
#include <cassert>
#include <cinttypes>
@@ -25,7 +25,8 @@
#include "src/binary-reader-nop.h"
#include "src/cast.h"
#include "src/feature.h"
-#include "src/interp.h"
+#include "src/interp/interp.h"
+#include "src/interp/interp-internal.h"
#include "src/stream.h"
#include "src/type-checker.h"
diff --git a/src/binary-reader-interp.h b/src/interp/binary-reader-interp.h
index 767b9479..767b9479 100644
--- a/src/binary-reader-interp.h
+++ b/src/interp/binary-reader-interp.h
diff --git a/src/interp/interp-disassemble.cc b/src/interp/interp-disassemble.cc
new file mode 100644
index 00000000..dfb82c3a
--- /dev/null
+++ b/src/interp/interp-disassemble.cc
@@ -0,0 +1,609 @@
+/*
+ * Copyright 2018 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/interp/interp.h"
+
+#include <cinttypes>
+
+#include "src/cast.h"
+#include "src/interp/interp-internal.h"
+
+namespace wabt {
+namespace interp {
+
+void Environment::Disassemble(Stream* stream,
+ IstreamOffset from,
+ IstreamOffset to) {
+ /* TODO(binji): mark function entries */
+ /* TODO(binji): track value stack size */
+ if (from >= istream_->data.size()) {
+ return;
+ }
+ to = std::min<IstreamOffset>(to, istream_->data.size());
+ const uint8_t* istream = istream_->data.data();
+ const uint8_t* pc = &istream[from];
+
+ while (static_cast<IstreamOffset>(pc - istream) < to) {
+ stream->Writef("%4" PRIzd "| ", pc - istream);
+
+ Opcode opcode = ReadOpcode(&pc);
+ assert(!opcode.IsInvalid());
+ switch (opcode) {
+ case Opcode::Select:
+ case Opcode::V128BitSelect:
+ stream->Writef("%s %%[-3], %%[-2], %%[-1]\n", opcode.GetName());
+ break;
+
+ case Opcode::Br:
+ stream->Writef("%s @%u\n", opcode.GetName(), ReadU32(&pc));
+ break;
+
+ case Opcode::BrIf:
+ stream->Writef("%s @%u, %%[-1]\n", opcode.GetName(), ReadU32(&pc));
+ break;
+
+ case Opcode::BrTable: {
+ Index num_targets = ReadU32(&pc);
+ IstreamOffset table_offset = ReadU32(&pc);
+ stream->Writef("%s %%[-1], $#%" PRIindex ", table:$%u\n",
+ opcode.GetName(), num_targets, table_offset);
+ break;
+ }
+
+ case Opcode::Nop:
+ case Opcode::Return:
+ case Opcode::Unreachable:
+ case Opcode::Drop:
+ stream->Writef("%s\n", opcode.GetName());
+ break;
+
+ case Opcode::MemorySize: {
+ Index memory_index = ReadU32(&pc);
+ stream->Writef("%s $%" PRIindex "\n", opcode.GetName(), memory_index);
+ break;
+ }
+
+ case Opcode::I32Const:
+ stream->Writef("%s $%u\n", opcode.GetName(), ReadU32(&pc));
+ break;
+
+ case Opcode::I64Const:
+ stream->Writef("%s $%" PRIu64 "\n", opcode.GetName(), ReadU64(&pc));
+ break;
+
+ case Opcode::F32Const:
+ stream->Writef("%s $%g\n", opcode.GetName(),
+ Bitcast<float>(ReadU32(&pc)));
+ break;
+
+ case Opcode::F64Const:
+ stream->Writef("%s $%g\n", opcode.GetName(),
+ Bitcast<double>(ReadU64(&pc)));
+ break;
+
+ case Opcode::GetLocal:
+ case Opcode::GetGlobal:
+ stream->Writef("%s $%u\n", opcode.GetName(), ReadU32(&pc));
+ break;
+
+ case Opcode::SetLocal:
+ case Opcode::SetGlobal:
+ case Opcode::TeeLocal:
+ stream->Writef("%s $%u, %%[-1]\n", opcode.GetName(), ReadU32(&pc));
+ break;
+
+ case Opcode::Call:
+ case Opcode::ReturnCall:
+ stream->Writef("%s @%u\n", opcode.GetName(), ReadU32(&pc));
+ break;
+
+ case Opcode::CallIndirect:
+ case Opcode::ReturnCallIndirect: {
+ Index table_index = ReadU32(&pc);
+ stream->Writef("%s $%" PRIindex ":%u, %%[-1]\n", opcode.GetName(),
+ table_index, ReadU32(&pc));
+ break;
+ }
+
+ case Opcode::InterpCallHost:
+ stream->Writef("%s $%u\n", opcode.GetName(), ReadU32(&pc));
+ break;
+
+ case Opcode::I32AtomicLoad:
+ case Opcode::I64AtomicLoad:
+ case Opcode::I32AtomicLoad8U:
+ case Opcode::I32AtomicLoad16U:
+ case Opcode::I64AtomicLoad8U:
+ case Opcode::I64AtomicLoad16U:
+ case Opcode::I64AtomicLoad32U:
+ case Opcode::I32Load8S:
+ case Opcode::I32Load8U:
+ case Opcode::I32Load16S:
+ case Opcode::I32Load16U:
+ case Opcode::I64Load8S:
+ case Opcode::I64Load8U:
+ case Opcode::I64Load16S:
+ case Opcode::I64Load16U:
+ case Opcode::I64Load32S:
+ case Opcode::I64Load32U:
+ case Opcode::I32Load:
+ case Opcode::I64Load:
+ case Opcode::F32Load:
+ case Opcode::F64Load:
+ case Opcode::V128Load: {
+ Index memory_index = ReadU32(&pc);
+ stream->Writef("%s $%" PRIindex ":%%[-1]+$%u\n", opcode.GetName(),
+ memory_index, ReadU32(&pc));
+ break;
+ }
+
+ case Opcode::AtomicWake:
+ case Opcode::I32AtomicStore:
+ case Opcode::I64AtomicStore:
+ case Opcode::I32AtomicStore8:
+ case Opcode::I32AtomicStore16:
+ case Opcode::I64AtomicStore8:
+ case Opcode::I64AtomicStore16:
+ case Opcode::I64AtomicStore32:
+ case Opcode::I32AtomicRmwAdd:
+ case Opcode::I64AtomicRmwAdd:
+ case Opcode::I32AtomicRmw8UAdd:
+ case Opcode::I32AtomicRmw16UAdd:
+ case Opcode::I64AtomicRmw8UAdd:
+ case Opcode::I64AtomicRmw16UAdd:
+ case Opcode::I64AtomicRmw32UAdd:
+ case Opcode::I32AtomicRmwSub:
+ case Opcode::I64AtomicRmwSub:
+ case Opcode::I32AtomicRmw8USub:
+ case Opcode::I32AtomicRmw16USub:
+ case Opcode::I64AtomicRmw8USub:
+ case Opcode::I64AtomicRmw16USub:
+ case Opcode::I64AtomicRmw32USub:
+ case Opcode::I32AtomicRmwAnd:
+ case Opcode::I64AtomicRmwAnd:
+ case Opcode::I32AtomicRmw8UAnd:
+ case Opcode::I32AtomicRmw16UAnd:
+ case Opcode::I64AtomicRmw8UAnd:
+ case Opcode::I64AtomicRmw16UAnd:
+ case Opcode::I64AtomicRmw32UAnd:
+ case Opcode::I32AtomicRmwOr:
+ case Opcode::I64AtomicRmwOr:
+ case Opcode::I32AtomicRmw8UOr:
+ case Opcode::I32AtomicRmw16UOr:
+ case Opcode::I64AtomicRmw8UOr:
+ case Opcode::I64AtomicRmw16UOr:
+ case Opcode::I64AtomicRmw32UOr:
+ case Opcode::I32AtomicRmwXor:
+ case Opcode::I64AtomicRmwXor:
+ case Opcode::I32AtomicRmw8UXor:
+ case Opcode::I32AtomicRmw16UXor:
+ case Opcode::I64AtomicRmw8UXor:
+ case Opcode::I64AtomicRmw16UXor:
+ case Opcode::I64AtomicRmw32UXor:
+ case Opcode::I32AtomicRmwXchg:
+ case Opcode::I64AtomicRmwXchg:
+ case Opcode::I32AtomicRmw8UXchg:
+ case Opcode::I32AtomicRmw16UXchg:
+ case Opcode::I64AtomicRmw8UXchg:
+ case Opcode::I64AtomicRmw16UXchg:
+ case Opcode::I64AtomicRmw32UXchg:
+ case Opcode::I32Store8:
+ case Opcode::I32Store16:
+ case Opcode::I32Store:
+ case Opcode::I64Store8:
+ case Opcode::I64Store16:
+ case Opcode::I64Store32:
+ case Opcode::I64Store:
+ case Opcode::F32Store:
+ case Opcode::F64Store:
+ case Opcode::V128Store: {
+ Index memory_index = ReadU32(&pc);
+ stream->Writef("%s $%" PRIindex ":%%[-2]+$%u, %%[-1]\n",
+ opcode.GetName(), memory_index, ReadU32(&pc));
+ break;
+ }
+
+ case Opcode::I32AtomicWait:
+ case Opcode::I64AtomicWait:
+ case Opcode::I32AtomicRmwCmpxchg:
+ case Opcode::I64AtomicRmwCmpxchg:
+ case Opcode::I32AtomicRmw8UCmpxchg:
+ case Opcode::I32AtomicRmw16UCmpxchg:
+ case Opcode::I64AtomicRmw8UCmpxchg:
+ case Opcode::I64AtomicRmw16UCmpxchg:
+ case Opcode::I64AtomicRmw32UCmpxchg: {
+ Index memory_index = ReadU32(&pc);
+ stream->Writef("%s $%" PRIindex ":%%[-3]+$%u, %%[-2], %%[-1]\n",
+ opcode.GetName(), memory_index, ReadU32(&pc));
+ break;
+ }
+
+ case Opcode::I32Add:
+ case Opcode::I32Sub:
+ case Opcode::I32Mul:
+ case Opcode::I32DivS:
+ case Opcode::I32DivU:
+ case Opcode::I32RemS:
+ case Opcode::I32RemU:
+ case Opcode::I32And:
+ case Opcode::I32Or:
+ case Opcode::I32Xor:
+ case Opcode::I32Shl:
+ case Opcode::I32ShrU:
+ case Opcode::I32ShrS:
+ case Opcode::I32Eq:
+ case Opcode::I32Ne:
+ case Opcode::I32LtS:
+ case Opcode::I32LeS:
+ case Opcode::I32LtU:
+ case Opcode::I32LeU:
+ case Opcode::I32GtS:
+ case Opcode::I32GeS:
+ case Opcode::I32GtU:
+ case Opcode::I32GeU:
+ case Opcode::I32Rotr:
+ case Opcode::I32Rotl:
+ case Opcode::F32Add:
+ case Opcode::F32Sub:
+ case Opcode::F32Mul:
+ case Opcode::F32Div:
+ case Opcode::F32Min:
+ case Opcode::F32Max:
+ case Opcode::F32Copysign:
+ case Opcode::F32Eq:
+ case Opcode::F32Ne:
+ case Opcode::F32Lt:
+ case Opcode::F32Le:
+ case Opcode::F32Gt:
+ case Opcode::F32Ge:
+ case Opcode::I64Add:
+ case Opcode::I64Sub:
+ case Opcode::I64Mul:
+ case Opcode::I64DivS:
+ case Opcode::I64DivU:
+ case Opcode::I64RemS:
+ case Opcode::I64RemU:
+ case Opcode::I64And:
+ case Opcode::I64Or:
+ case Opcode::I64Xor:
+ case Opcode::I64Shl:
+ case Opcode::I64ShrU:
+ case Opcode::I64ShrS:
+ case Opcode::I64Eq:
+ case Opcode::I64Ne:
+ case Opcode::I64LtS:
+ case Opcode::I64LeS:
+ case Opcode::I64LtU:
+ case Opcode::I64LeU:
+ case Opcode::I64GtS:
+ case Opcode::I64GeS:
+ case Opcode::I64GtU:
+ case Opcode::I64GeU:
+ case Opcode::I64Rotr:
+ case Opcode::I64Rotl:
+ case Opcode::F64Add:
+ case Opcode::F64Sub:
+ case Opcode::F64Mul:
+ case Opcode::F64Div:
+ case Opcode::F64Min:
+ case Opcode::F64Max:
+ case Opcode::F64Copysign:
+ case Opcode::F64Eq:
+ case Opcode::F64Ne:
+ case Opcode::F64Lt:
+ case Opcode::F64Le:
+ case Opcode::F64Gt:
+ case Opcode::F64Ge:
+ case Opcode::I8X16Add:
+ case Opcode::I16X8Add:
+ case Opcode::I32X4Add:
+ case Opcode::I64X2Add:
+ case Opcode::I8X16Sub:
+ case Opcode::I16X8Sub:
+ case Opcode::I32X4Sub:
+ case Opcode::I64X2Sub:
+ case Opcode::I8X16Mul:
+ case Opcode::I16X8Mul:
+ case Opcode::I32X4Mul:
+ case Opcode::I8X16AddSaturateS:
+ case Opcode::I8X16AddSaturateU:
+ case Opcode::I16X8AddSaturateS:
+ case Opcode::I16X8AddSaturateU:
+ case Opcode::I8X16SubSaturateS:
+ case Opcode::I8X16SubSaturateU:
+ case Opcode::I16X8SubSaturateS:
+ case Opcode::I16X8SubSaturateU:
+ case Opcode::I8X16Shl:
+ case Opcode::I16X8Shl:
+ case Opcode::I32X4Shl:
+ case Opcode::I64X2Shl:
+ case Opcode::I8X16ShrS:
+ case Opcode::I8X16ShrU:
+ case Opcode::I16X8ShrS:
+ case Opcode::I16X8ShrU:
+ case Opcode::I32X4ShrS:
+ case Opcode::I32X4ShrU:
+ case Opcode::I64X2ShrS:
+ case Opcode::I64X2ShrU:
+ case Opcode::V128And:
+ case Opcode::V128Or:
+ case Opcode::V128Xor:
+ case Opcode::I8X16Eq:
+ case Opcode::I16X8Eq:
+ case Opcode::I32X4Eq:
+ case Opcode::F32X4Eq:
+ case Opcode::F64X2Eq:
+ case Opcode::I8X16Ne:
+ case Opcode::I16X8Ne:
+ case Opcode::I32X4Ne:
+ case Opcode::F32X4Ne:
+ case Opcode::F64X2Ne:
+ case Opcode::I8X16LtS:
+ case Opcode::I8X16LtU:
+ case Opcode::I16X8LtS:
+ case Opcode::I16X8LtU:
+ case Opcode::I32X4LtS:
+ case Opcode::I32X4LtU:
+ case Opcode::F32X4Lt:
+ case Opcode::F64X2Lt:
+ case Opcode::I8X16LeS:
+ case Opcode::I8X16LeU:
+ case Opcode::I16X8LeS:
+ case Opcode::I16X8LeU:
+ case Opcode::I32X4LeS:
+ case Opcode::I32X4LeU:
+ case Opcode::F32X4Le:
+ case Opcode::F64X2Le:
+ case Opcode::I8X16GtS:
+ case Opcode::I8X16GtU:
+ case Opcode::I16X8GtS:
+ case Opcode::I16X8GtU:
+ case Opcode::I32X4GtS:
+ case Opcode::I32X4GtU:
+ case Opcode::F32X4Gt:
+ case Opcode::F64X2Gt:
+ case Opcode::I8X16GeS:
+ case Opcode::I8X16GeU:
+ case Opcode::I16X8GeS:
+ case Opcode::I16X8GeU:
+ case Opcode::I32X4GeS:
+ case Opcode::I32X4GeU:
+ case Opcode::F32X4Ge:
+ case Opcode::F64X2Ge:
+ case Opcode::F32X4Min:
+ case Opcode::F64X2Min:
+ case Opcode::F32X4Max:
+ case Opcode::F64X2Max:
+ case Opcode::F32X4Add:
+ case Opcode::F64X2Add:
+ case Opcode::F32X4Sub:
+ case Opcode::F64X2Sub:
+ case Opcode::F32X4Div:
+ case Opcode::F64X2Div:
+ case Opcode::F32X4Mul:
+ case Opcode::F64X2Mul:
+ stream->Writef("%s %%[-2], %%[-1]\n", opcode.GetName());
+ break;
+
+ case Opcode::I32Clz:
+ case Opcode::I32Ctz:
+ case Opcode::I32Popcnt:
+ case Opcode::I32Eqz:
+ case Opcode::I64Clz:
+ case Opcode::I64Ctz:
+ case Opcode::I64Popcnt:
+ case Opcode::I64Eqz:
+ case Opcode::F32Abs:
+ case Opcode::F32Neg:
+ case Opcode::F32Ceil:
+ case Opcode::F32Floor:
+ case Opcode::F32Trunc:
+ case Opcode::F32Nearest:
+ case Opcode::F32Sqrt:
+ case Opcode::F64Abs:
+ case Opcode::F64Neg:
+ case Opcode::F64Ceil:
+ case Opcode::F64Floor:
+ case Opcode::F64Trunc:
+ case Opcode::F64Nearest:
+ case Opcode::F64Sqrt:
+ case Opcode::I32TruncSF32:
+ case Opcode::I32TruncUF32:
+ case Opcode::I64TruncSF32:
+ case Opcode::I64TruncUF32:
+ case Opcode::F64PromoteF32:
+ case Opcode::I32ReinterpretF32:
+ case Opcode::I32TruncSF64:
+ case Opcode::I32TruncUF64:
+ case Opcode::I64TruncSF64:
+ case Opcode::I64TruncUF64:
+ case Opcode::F32DemoteF64:
+ case Opcode::I64ReinterpretF64:
+ case Opcode::I32WrapI64:
+ case Opcode::F32ConvertSI64:
+ case Opcode::F32ConvertUI64:
+ case Opcode::F64ConvertSI64:
+ case Opcode::F64ConvertUI64:
+ case Opcode::F64ReinterpretI64:
+ case Opcode::I64ExtendSI32:
+ case Opcode::I64ExtendUI32:
+ case Opcode::F32ConvertSI32:
+ case Opcode::F32ConvertUI32:
+ case Opcode::F32ReinterpretI32:
+ case Opcode::F64ConvertSI32:
+ case Opcode::F64ConvertUI32:
+ case Opcode::I32TruncSSatF32:
+ case Opcode::I32TruncUSatF32:
+ case Opcode::I64TruncSSatF32:
+ case Opcode::I64TruncUSatF32:
+ case Opcode::I32TruncSSatF64:
+ case Opcode::I32TruncUSatF64:
+ case Opcode::I64TruncSSatF64:
+ case Opcode::I64TruncUSatF64:
+ case Opcode::I32Extend16S:
+ case Opcode::I32Extend8S:
+ case Opcode::I64Extend16S:
+ case Opcode::I64Extend32S:
+ case Opcode::I64Extend8S:
+ case Opcode::I8X16Splat:
+ case Opcode::I16X8Splat:
+ case Opcode::I32X4Splat:
+ case Opcode::I64X2Splat:
+ case Opcode::F32X4Splat:
+ case Opcode::F64X2Splat:
+ case Opcode::I8X16Neg:
+ case Opcode::I16X8Neg:
+ case Opcode::I32X4Neg:
+ case Opcode::I64X2Neg:
+ case Opcode::V128Not:
+ case Opcode::I8X16AnyTrue:
+ case Opcode::I16X8AnyTrue:
+ case Opcode::I32X4AnyTrue:
+ case Opcode::I64X2AnyTrue:
+ case Opcode::I8X16AllTrue:
+ case Opcode::I16X8AllTrue:
+ case Opcode::I32X4AllTrue:
+ case Opcode::I64X2AllTrue:
+ case Opcode::F32X4Neg:
+ case Opcode::F64X2Neg:
+ case Opcode::F32X4Abs:
+ case Opcode::F64X2Abs:
+ case Opcode::F32X4Sqrt:
+ case Opcode::F64X2Sqrt:
+ case Opcode::F32X4ConvertSI32X4:
+ case Opcode::F32X4ConvertUI32X4:
+ case Opcode::F64X2ConvertSI64X2:
+ case Opcode::F64X2ConvertUI64X2:
+ case Opcode::I32X4TruncSF32X4Sat:
+ case Opcode::I32X4TruncUF32X4Sat:
+ case Opcode::I64X2TruncSF64X2Sat:
+ case Opcode::I64X2TruncUF64X2Sat:
+ stream->Writef("%s %%[-1]\n", opcode.GetName());
+ break;
+
+ case Opcode::I8X16ExtractLaneS:
+ case Opcode::I8X16ExtractLaneU:
+ case Opcode::I16X8ExtractLaneS:
+ case Opcode::I16X8ExtractLaneU:
+ case Opcode::I32X4ExtractLane:
+ case Opcode::I64X2ExtractLane:
+ case Opcode::F32X4ExtractLane:
+ case Opcode::F64X2ExtractLane: {
+ stream->Writef("%s %%[-1] : (Lane imm: %d)\n", opcode.GetName(),
+ ReadU8(&pc));
+ break;
+ }
+
+ case Opcode::I8X16ReplaceLane:
+ case Opcode::I16X8ReplaceLane:
+ case Opcode::I32X4ReplaceLane:
+ case Opcode::I64X2ReplaceLane:
+ case Opcode::F32X4ReplaceLane:
+ case Opcode::F64X2ReplaceLane: {
+ stream->Writef("%s %%[-1], %%[-2] : (Lane imm: %d)\n",
+ opcode.GetName(), ReadU8(&pc));
+ break;
+ }
+
+ case Opcode::V8X16Shuffle:
+ stream->Writef(
+ "%s %%[-2], %%[-1] : (Lane imm: $0x%08x 0x%08x 0x%08x 0x%08x )\n",
+ opcode.GetName(), ReadU32(&pc), ReadU32(&pc), ReadU32(&pc),
+ ReadU32(&pc));
+ break;
+
+ case Opcode::MemoryGrow: {
+ Index memory_index = ReadU32(&pc);
+ stream->Writef("%s $%" PRIindex ":%%[-1]\n", opcode.GetName(),
+ memory_index);
+ break;
+ }
+
+ case Opcode::InterpAlloca:
+ stream->Writef("%s $%u\n", opcode.GetName(), ReadU32(&pc));
+ break;
+
+ case Opcode::InterpBrUnless:
+ stream->Writef("%s @%u, %%[-1]\n", opcode.GetName(), ReadU32(&pc));
+ break;
+
+ case Opcode::InterpDropKeep: {
+ uint32_t drop = ReadU32(&pc);
+ uint32_t keep = ReadU32(&pc);
+ stream->Writef("%s $%u $%u\n", opcode.GetName(), drop, keep);
+ break;
+ }
+
+ case Opcode::InterpData: {
+ uint32_t num_bytes = ReadU32(&pc);
+ stream->Writef("%s $%u\n", opcode.GetName(), num_bytes);
+ /* for now, the only reason this is emitted is for br_table, so display
+ * it as a list of table entries */
+ if (num_bytes % WABT_TABLE_ENTRY_SIZE == 0) {
+ Index num_entries = num_bytes / WABT_TABLE_ENTRY_SIZE;
+ for (Index i = 0; i < num_entries; ++i) {
+ stream->Writef("%4" PRIzd "| ", pc - istream);
+ IstreamOffset offset;
+ uint32_t drop;
+ uint32_t keep;
+ ReadTableEntryAt(pc, &offset, &drop, &keep);
+ stream->Writef(" entry %" PRIindex
+ ": offset: %u drop: %u keep: %u\n",
+ i, offset, drop, keep);
+ pc += WABT_TABLE_ENTRY_SIZE;
+ }
+ } else {
+ /* just skip those data bytes */
+ pc += num_bytes;
+ }
+
+ break;
+ }
+
+ case Opcode::V128Const: {
+ stream->Writef("%s $0x%08x 0x%08x 0x%08x 0x%08x\n", opcode.GetName(),
+ ReadU32(&pc), ReadU32(&pc), ReadU32(&pc), ReadU32(&pc));
+
+ break;
+ }
+ // The following opcodes are either never generated or should never be
+ // executed.
+ case Opcode::Block:
+ case Opcode::Catch:
+ case Opcode::Else:
+ case Opcode::End:
+ case Opcode::If:
+ case Opcode::IfExcept:
+ case Opcode::Invalid:
+ case Opcode::Loop:
+ case Opcode::Rethrow:
+ case Opcode::Throw:
+ case Opcode::Try:
+ WABT_UNREACHABLE;
+ break;
+ }
+ }
+}
+
+void Environment::DisassembleModule(Stream* stream, Module* module) {
+ assert(!module->is_host);
+ auto* defined_module = cast<DefinedModule>(module);
+ Disassemble(stream, defined_module->istream_start,
+ defined_module->istream_end);
+}
+
+} // namespace interp
+} // namespace wabt
diff --git a/src/interp/interp-internal.h b/src/interp/interp-internal.h
new file mode 100644
index 00000000..f983d0b2
--- /dev/null
+++ b/src/interp/interp-internal.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2018 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace wabt {
+namespace interp {
+
+// A table entry has the following packed layout:
+//
+// struct {
+// IstreamOffset offset;
+// uint32_t drop_count;
+// uint32_t keep_count;
+// };
+#define WABT_TABLE_ENTRY_SIZE \
+ (sizeof(IstreamOffset) + sizeof(uint32_t) + sizeof(uint32_t))
+#define WABT_TABLE_ENTRY_OFFSET_OFFSET 0
+#define WABT_TABLE_ENTRY_DROP_OFFSET sizeof(IstreamOffset)
+#define WABT_TABLE_ENTRY_KEEP_OFFSET (sizeof(IstreamOffset) + sizeof(uint32_t))
+
+template <typename T>
+inline T ReadUxAt(const uint8_t* pc) {
+ T result;
+ memcpy(&result, pc, sizeof(T));
+ return result;
+}
+
+template <typename T>
+inline T ReadUx(const uint8_t** pc) {
+ T result = ReadUxAt<T>(*pc);
+ *pc += sizeof(T);
+ return result;
+}
+
+inline uint8_t ReadU8At(const uint8_t* pc) {
+ return ReadUxAt<uint8_t>(pc);
+}
+
+inline uint8_t ReadU8(const uint8_t** pc) {
+ return ReadUx<uint8_t>(pc);
+}
+
+inline uint32_t ReadU32At(const uint8_t* pc) {
+ return ReadUxAt<uint32_t>(pc);
+}
+
+inline uint32_t ReadU32(const uint8_t** pc) {
+ return ReadUx<uint32_t>(pc);
+}
+
+inline uint64_t ReadU64At(const uint8_t* pc) {
+ return ReadUxAt<uint64_t>(pc);
+}
+
+inline uint64_t ReadU64(const uint8_t** pc) {
+ return ReadUx<uint64_t>(pc);
+}
+
+inline v128 ReadV128At(const uint8_t* pc) {
+ return ReadUxAt<v128>(pc);
+}
+
+inline v128 ReadV128(const uint8_t** pc) {
+ return ReadUx<v128>(pc);
+}
+
+inline Opcode ReadOpcode(const uint8_t** pc) {
+ uint32_t value = ReadU32(pc);
+ return Opcode(static_cast<Opcode::Enum>(value));
+}
+
+inline void ReadTableEntryAt(const uint8_t* pc,
+ IstreamOffset* out_offset,
+ uint32_t* out_drop,
+ uint32_t* out_keep) {
+ *out_offset = ReadU32At(pc + WABT_TABLE_ENTRY_OFFSET_OFFSET);
+ *out_drop = ReadU32At(pc + WABT_TABLE_ENTRY_DROP_OFFSET);
+ *out_keep = ReadU32At(pc + WABT_TABLE_ENTRY_KEEP_OFFSET);
+}
+
+} // namespace interp
+} // namespace wabt
diff --git a/src/interp/interp-trace.cc b/src/interp/interp-trace.cc
new file mode 100644
index 00000000..15c3714b
--- /dev/null
+++ b/src/interp/interp-trace.cc
@@ -0,0 +1,713 @@
+/*
+ * Copyright 2018 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/interp/interp.h"
+
+#include <cinttypes>
+
+#include "src/interp/interp-internal.h"
+
+namespace wabt {
+namespace interp {
+
+void Thread::Trace(Stream* stream) {
+ const uint8_t* istream = GetIstream();
+ const uint8_t* pc = &istream[pc_];
+
+ stream->Writef("#%u. %4" PRIzd ": V:%-3u| ", call_stack_top_, pc - istream,
+ value_stack_top_);
+
+ Opcode opcode = ReadOpcode(&pc);
+ assert(!opcode.IsInvalid());
+ switch (opcode) {
+ case Opcode::Select:
+ // TODO(binji): We don't know the type here so we can't display the value
+ // to the user. This used to display the full 64-bit value, but that
+ // will potentially display garbage if the value is 32-bit.
+ stream->Writef("%s %u, %%[-2], %%[-1]\n", opcode.GetName(), Pick(3).i32);
+ break;
+
+ case Opcode::Br:
+ stream->Writef("%s @%u\n", opcode.GetName(), ReadU32At(pc));
+ break;
+
+ case Opcode::BrIf:
+ stream->Writef("%s @%u, %u\n", opcode.GetName(), ReadU32At(pc),
+ Top().i32);
+ break;
+
+ case Opcode::BrTable: {
+ Index num_targets = ReadU32At(pc);
+ IstreamOffset table_offset = ReadU32At(pc + 4);
+ uint32_t key = Top().i32;
+ stream->Writef("%s %u, $#%" PRIindex ", table:$%u\n", opcode.GetName(),
+ key, num_targets, table_offset);
+ break;
+ }
+
+ case Opcode::Nop:
+ case Opcode::Return:
+ case Opcode::Unreachable:
+ case Opcode::Drop:
+ stream->Writef("%s\n", opcode.GetName());
+ break;
+
+ case Opcode::MemorySize: {
+ Index memory_index = ReadU32(&pc);
+ stream->Writef("%s $%" PRIindex "\n", opcode.GetName(), memory_index);
+ break;
+ }
+
+ case Opcode::I32Const:
+ stream->Writef("%s $%u\n", opcode.GetName(), ReadU32At(pc));
+ break;
+
+ case Opcode::I64Const:
+ stream->Writef("%s $%" PRIu64 "\n", opcode.GetName(), ReadU64At(pc));
+ break;
+
+ case Opcode::F32Const:
+ stream->Writef("%s $%g\n", opcode.GetName(),
+ Bitcast<float>(ReadU32At(pc)));
+ break;
+
+ case Opcode::F64Const:
+ stream->Writef("%s $%g\n", opcode.GetName(),
+ Bitcast<double>(ReadU64At(pc)));
+ break;
+
+ case Opcode::GetLocal:
+ case Opcode::GetGlobal:
+ stream->Writef("%s $%u\n", opcode.GetName(), ReadU32At(pc));
+ break;
+
+ case Opcode::SetLocal:
+ case Opcode::SetGlobal:
+ case Opcode::TeeLocal:
+ stream->Writef("%s $%u, %u\n", opcode.GetName(), ReadU32At(pc),
+ Top().i32);
+ break;
+
+ case Opcode::Call:
+ case Opcode::ReturnCall:
+ stream->Writef("%s @%u\n", opcode.GetName(), ReadU32At(pc));
+ break;
+
+ case Opcode::CallIndirect:
+ case Opcode::ReturnCallIndirect:
+ stream->Writef("%s $%u, %u\n", opcode.GetName(), ReadU32At(pc),
+ Top().i32);
+ break;
+
+ case Opcode::InterpCallHost:
+ stream->Writef("%s $%u\n", opcode.GetName(), ReadU32At(pc));
+ break;
+
+ case Opcode::I32AtomicLoad8U:
+ case Opcode::I32AtomicLoad16U:
+ case Opcode::I32AtomicLoad:
+ case Opcode::I64AtomicLoad8U:
+ case Opcode::I64AtomicLoad16U:
+ case Opcode::I64AtomicLoad32U:
+ case Opcode::I64AtomicLoad:
+ case Opcode::I32Load8S:
+ case Opcode::I32Load8U:
+ case Opcode::I32Load16S:
+ case Opcode::I32Load16U:
+ case Opcode::I64Load8S:
+ case Opcode::I64Load8U:
+ case Opcode::I64Load16S:
+ case Opcode::I64Load16U:
+ case Opcode::I64Load32S:
+ case Opcode::I64Load32U:
+ case Opcode::I32Load:
+ case Opcode::I64Load:
+ case Opcode::F32Load:
+ case Opcode::F64Load:
+ case Opcode::V128Load: {
+ Index memory_index = ReadU32(&pc);
+ stream->Writef("%s $%" PRIindex ":%u+$%u\n", opcode.GetName(),
+ memory_index, Top().i32, ReadU32At(pc));
+ break;
+ }
+
+ case Opcode::AtomicWake:
+ case Opcode::I32AtomicStore:
+ case Opcode::I32AtomicStore8:
+ case Opcode::I32AtomicStore16:
+ case Opcode::I32AtomicRmw8UAdd:
+ case Opcode::I32AtomicRmw16UAdd:
+ case Opcode::I32AtomicRmwAdd:
+ case Opcode::I32AtomicRmw8USub:
+ case Opcode::I32AtomicRmw16USub:
+ case Opcode::I32AtomicRmwSub:
+ case Opcode::I32AtomicRmw8UAnd:
+ case Opcode::I32AtomicRmw16UAnd:
+ case Opcode::I32AtomicRmwAnd:
+ case Opcode::I32AtomicRmw8UOr:
+ case Opcode::I32AtomicRmw16UOr:
+ case Opcode::I32AtomicRmwOr:
+ case Opcode::I32AtomicRmw8UXor:
+ case Opcode::I32AtomicRmw16UXor:
+ case Opcode::I32AtomicRmwXor:
+ case Opcode::I32AtomicRmw8UXchg:
+ case Opcode::I32AtomicRmw16UXchg:
+ case Opcode::I32AtomicRmwXchg:
+ case Opcode::I32Store8:
+ case Opcode::I32Store16:
+ case Opcode::I32Store: {
+ Index memory_index = ReadU32(&pc);
+ stream->Writef("%s $%" PRIindex ":%u+$%u, %u\n", opcode.GetName(),
+ memory_index, Pick(2).i32, ReadU32At(pc), Pick(1).i32);
+ break;
+ }
+
+ case Opcode::I32AtomicRmwCmpxchg:
+ case Opcode::I32AtomicRmw8UCmpxchg:
+ case Opcode::I32AtomicRmw16UCmpxchg: {
+ Index memory_index = ReadU32(&pc);
+ stream->Writef("%s $%" PRIindex ":%u+$%u, %u, %u\n", opcode.GetName(),
+ memory_index, Pick(3).i32, ReadU32At(pc), Pick(2).i32,
+ Pick(1).i32);
+ break;
+ }
+
+ case Opcode::I64AtomicStore8:
+ case Opcode::I64AtomicStore16:
+ case Opcode::I64AtomicStore32:
+ case Opcode::I64AtomicStore:
+ case Opcode::I64AtomicRmw8UAdd:
+ case Opcode::I64AtomicRmw16UAdd:
+ case Opcode::I64AtomicRmw32UAdd:
+ case Opcode::I64AtomicRmwAdd:
+ case Opcode::I64AtomicRmw8USub:
+ case Opcode::I64AtomicRmw16USub:
+ case Opcode::I64AtomicRmw32USub:
+ case Opcode::I64AtomicRmwSub:
+ case Opcode::I64AtomicRmw8UAnd:
+ case Opcode::I64AtomicRmw16UAnd:
+ case Opcode::I64AtomicRmw32UAnd:
+ case Opcode::I64AtomicRmwAnd:
+ case Opcode::I64AtomicRmw8UOr:
+ case Opcode::I64AtomicRmw16UOr:
+ case Opcode::I64AtomicRmw32UOr:
+ case Opcode::I64AtomicRmwOr:
+ case Opcode::I64AtomicRmw8UXor:
+ case Opcode::I64AtomicRmw16UXor:
+ case Opcode::I64AtomicRmw32UXor:
+ case Opcode::I64AtomicRmwXor:
+ case Opcode::I64AtomicRmw8UXchg:
+ case Opcode::I64AtomicRmw16UXchg:
+ case Opcode::I64AtomicRmw32UXchg:
+ case Opcode::I64AtomicRmwXchg:
+ case Opcode::I64Store8:
+ case Opcode::I64Store16:
+ case Opcode::I64Store32:
+ case Opcode::I64Store: {
+ Index memory_index = ReadU32(&pc);
+ stream->Writef("%s $%" PRIindex ":%u+$%u, %" PRIu64 "\n",
+ opcode.GetName(), memory_index, Pick(2).i32, ReadU32At(pc),
+ Pick(1).i64);
+ break;
+ }
+
+ case Opcode::I32AtomicWait: {
+ Index memory_index = ReadU32(&pc);
+ stream->Writef("%s $%" PRIindex ":%u+$%u, %u, %" PRIu64 "\n",
+ opcode.GetName(), memory_index, Pick(3).i32, ReadU32At(pc),
+ Pick(2).i32, Pick(1).i64);
+ break;
+ }
+
+ case Opcode::I64AtomicWait:
+ case Opcode::I64AtomicRmwCmpxchg:
+ case Opcode::I64AtomicRmw8UCmpxchg:
+ case Opcode::I64AtomicRmw16UCmpxchg:
+ case Opcode::I64AtomicRmw32UCmpxchg: {
+ Index memory_index = ReadU32(&pc);
+ stream->Writef("%s $%" PRIindex ":%u+$%u, %" PRIu64 ", %" PRIu64 "\n",
+ opcode.GetName(), memory_index, Pick(3).i32, ReadU32At(pc),
+ Pick(2).i64, Pick(1).i64);
+ break;
+ }
+
+ case Opcode::F32Store: {
+ Index memory_index = ReadU32(&pc);
+ stream->Writef("%s $%" PRIindex ":%u+$%u, %g\n", opcode.GetName(),
+ memory_index, Pick(2).i32, ReadU32At(pc),
+ Bitcast<float>(Pick(1).f32_bits));
+ break;
+ }
+
+ case Opcode::F64Store: {
+ Index memory_index = ReadU32(&pc);
+ stream->Writef("%s $%" PRIindex ":%u+$%u, %g\n", opcode.GetName(),
+ memory_index, Pick(2).i32, ReadU32At(pc),
+ Bitcast<double>(Pick(1).f64_bits));
+ break;
+ }
+
+ case Opcode::V128Store: {
+ Index memory_index = ReadU32(&pc);
+ stream->Writef("%s $%" PRIindex ":%u+$%u, $0x%08x 0x%08x 0x%08x 0x%08x\n",
+ opcode.GetName(), memory_index, Pick(2).i32, ReadU32At(pc),
+ Pick(1).v128_bits.v[0], Pick(1).v128_bits.v[1],
+ Pick(1).v128_bits.v[2], Pick(1).v128_bits.v[3]);
+ break;
+ }
+
+ case Opcode::MemoryGrow: {
+ Index memory_index = ReadU32(&pc);
+ stream->Writef("%s $%" PRIindex ":%u\n", opcode.GetName(), memory_index,
+ Top().i32);
+ break;
+ }
+
+ case Opcode::I32Add:
+ case Opcode::I32Sub:
+ case Opcode::I32Mul:
+ case Opcode::I32DivS:
+ case Opcode::I32DivU:
+ case Opcode::I32RemS:
+ case Opcode::I32RemU:
+ case Opcode::I32And:
+ case Opcode::I32Or:
+ case Opcode::I32Xor:
+ case Opcode::I32Shl:
+ case Opcode::I32ShrU:
+ case Opcode::I32ShrS:
+ case Opcode::I32Eq:
+ case Opcode::I32Ne:
+ case Opcode::I32LtS:
+ case Opcode::I32LeS:
+ case Opcode::I32LtU:
+ case Opcode::I32LeU:
+ case Opcode::I32GtS:
+ case Opcode::I32GeS:
+ case Opcode::I32GtU:
+ case Opcode::I32GeU:
+ case Opcode::I32Rotr:
+ case Opcode::I32Rotl:
+ stream->Writef("%s %u, %u\n", opcode.GetName(), Pick(2).i32, Pick(1).i32);
+ break;
+
+ case Opcode::I32Clz:
+ case Opcode::I32Ctz:
+ case Opcode::I32Popcnt:
+ case Opcode::I32Eqz:
+ case Opcode::I32Extend16S:
+ case Opcode::I32Extend8S:
+ case Opcode::I8X16Splat:
+ case Opcode::I16X8Splat:
+ case Opcode::I32X4Splat:
+ stream->Writef("%s %u\n", opcode.GetName(), Top().i32);
+ break;
+
+ case Opcode::I64Add:
+ case Opcode::I64Sub:
+ case Opcode::I64Mul:
+ case Opcode::I64DivS:
+ case Opcode::I64DivU:
+ case Opcode::I64RemS:
+ case Opcode::I64RemU:
+ case Opcode::I64And:
+ case Opcode::I64Or:
+ case Opcode::I64Xor:
+ case Opcode::I64Shl:
+ case Opcode::I64ShrU:
+ case Opcode::I64ShrS:
+ case Opcode::I64Eq:
+ case Opcode::I64Ne:
+ case Opcode::I64LtS:
+ case Opcode::I64LeS:
+ case Opcode::I64LtU:
+ case Opcode::I64LeU:
+ case Opcode::I64GtS:
+ case Opcode::I64GeS:
+ case Opcode::I64GtU:
+ case Opcode::I64GeU:
+ case Opcode::I64Rotr:
+ case Opcode::I64Rotl:
+ stream->Writef("%s %" PRIu64 ", %" PRIu64 "\n", opcode.GetName(),
+ Pick(2).i64, Pick(1).i64);
+ break;
+
+ case Opcode::I64Clz:
+ case Opcode::I64Ctz:
+ case Opcode::I64Popcnt:
+ case Opcode::I64Eqz:
+ case Opcode::I64Extend16S:
+ case Opcode::I64Extend32S:
+ case Opcode::I64Extend8S:
+ case Opcode::I64X2Splat:
+ stream->Writef("%s %" PRIu64 "\n", opcode.GetName(), Top().i64);
+ break;
+
+ case Opcode::F32Add:
+ case Opcode::F32Sub:
+ case Opcode::F32Mul:
+ case Opcode::F32Div:
+ case Opcode::F32Min:
+ case Opcode::F32Max:
+ case Opcode::F32Copysign:
+ case Opcode::F32Eq:
+ case Opcode::F32Ne:
+ case Opcode::F32Lt:
+ case Opcode::F32Le:
+ case Opcode::F32Gt:
+ case Opcode::F32Ge:
+ stream->Writef("%s %g, %g\n", opcode.GetName(),
+ Bitcast<float>(Pick(2).i32), Bitcast<float>(Pick(1).i32));
+ break;
+
+ case Opcode::F32Abs:
+ case Opcode::F32Neg:
+ case Opcode::F32Ceil:
+ case Opcode::F32Floor:
+ case Opcode::F32Trunc:
+ case Opcode::F32Nearest:
+ case Opcode::F32Sqrt:
+ case Opcode::F32X4Splat:
+ stream->Writef("%s %g\n", opcode.GetName(), Bitcast<float>(Top().i32));
+ break;
+
+ case Opcode::F64Add:
+ case Opcode::F64Sub:
+ case Opcode::F64Mul:
+ case Opcode::F64Div:
+ case Opcode::F64Min:
+ case Opcode::F64Max:
+ case Opcode::F64Copysign:
+ case Opcode::F64Eq:
+ case Opcode::F64Ne:
+ case Opcode::F64Lt:
+ case Opcode::F64Le:
+ case Opcode::F64Gt:
+ case Opcode::F64Ge:
+ stream->Writef("%s %g, %g\n", opcode.GetName(),
+ Bitcast<double>(Pick(2).i64),
+ Bitcast<double>(Pick(1).i64));
+ break;
+
+ case Opcode::F64Abs:
+ case Opcode::F64Neg:
+ case Opcode::F64Ceil:
+ case Opcode::F64Floor:
+ case Opcode::F64Trunc:
+ case Opcode::F64Nearest:
+ case Opcode::F64Sqrt:
+ case Opcode::F64X2Splat:
+ stream->Writef("%s %g\n", opcode.GetName(), Bitcast<double>(Top().i64));
+ break;
+
+ case Opcode::I32TruncSF32:
+ case Opcode::I32TruncUF32:
+ case Opcode::I64TruncSF32:
+ case Opcode::I64TruncUF32:
+ case Opcode::F64PromoteF32:
+ case Opcode::I32ReinterpretF32:
+ case Opcode::I32TruncSSatF32:
+ case Opcode::I32TruncUSatF32:
+ case Opcode::I64TruncSSatF32:
+ case Opcode::I64TruncUSatF32:
+ stream->Writef("%s %g\n", opcode.GetName(), Bitcast<float>(Top().i32));
+ break;
+
+ case Opcode::I32TruncSF64:
+ case Opcode::I32TruncUF64:
+ case Opcode::I64TruncSF64:
+ case Opcode::I64TruncUF64:
+ case Opcode::F32DemoteF64:
+ case Opcode::I64ReinterpretF64:
+ case Opcode::I32TruncSSatF64:
+ case Opcode::I32TruncUSatF64:
+ case Opcode::I64TruncSSatF64:
+ case Opcode::I64TruncUSatF64:
+ stream->Writef("%s %g\n", opcode.GetName(), Bitcast<double>(Top().i64));
+ break;
+
+ case Opcode::I32WrapI64:
+ case Opcode::F32ConvertSI64:
+ case Opcode::F32ConvertUI64:
+ case Opcode::F64ConvertSI64:
+ case Opcode::F64ConvertUI64:
+ case Opcode::F64ReinterpretI64:
+ stream->Writef("%s %" PRIu64 "\n", opcode.GetName(), Top().i64);
+ break;
+
+ case Opcode::I64ExtendSI32:
+ case Opcode::I64ExtendUI32:
+ case Opcode::F32ConvertSI32:
+ case Opcode::F32ConvertUI32:
+ case Opcode::F32ReinterpretI32:
+ case Opcode::F64ConvertSI32:
+ case Opcode::F64ConvertUI32:
+ stream->Writef("%s %u\n", opcode.GetName(), Top().i32);
+ break;
+
+ case Opcode::InterpAlloca:
+ stream->Writef("%s $%u\n", opcode.GetName(), ReadU32At(pc));
+ break;
+
+ case Opcode::InterpBrUnless:
+ stream->Writef("%s @%u, %u\n", opcode.GetName(), ReadU32At(pc),
+ Top().i32);
+ break;
+
+ case Opcode::InterpDropKeep:
+ stream->Writef("%s $%u $%u\n", opcode.GetName(), ReadU32At(pc),
+ ReadU32At(pc + 4));
+ break;
+
+ case Opcode::V128Const: {
+ stream->Writef("%s $0x%08x 0x%08x 0x%08x 0x%08x\n", opcode.GetName(),
+ ReadU32At(pc), ReadU32At(pc + 4), ReadU32At(pc + 8),
+ ReadU32At(pc + 12));
+ break;
+ }
+
+ case Opcode::I8X16Neg:
+ case Opcode::I16X8Neg:
+ case Opcode::I32X4Neg:
+ case Opcode::I64X2Neg:
+ case Opcode::V128Not:
+ case Opcode::I8X16AnyTrue:
+ case Opcode::I16X8AnyTrue:
+ case Opcode::I32X4AnyTrue:
+ case Opcode::I64X2AnyTrue:
+ case Opcode::I8X16AllTrue:
+ case Opcode::I16X8AllTrue:
+ case Opcode::I32X4AllTrue:
+ case Opcode::I64X2AllTrue:
+ case Opcode::F32X4Neg:
+ case Opcode::F64X2Neg:
+ case Opcode::F32X4Abs:
+ case Opcode::F64X2Abs:
+ case Opcode::F32X4Sqrt:
+ case Opcode::F64X2Sqrt:
+ case Opcode::F32X4ConvertSI32X4:
+ case Opcode::F32X4ConvertUI32X4:
+ case Opcode::F64X2ConvertSI64X2:
+ case Opcode::F64X2ConvertUI64X2:
+ case Opcode::I32X4TruncSF32X4Sat:
+ case Opcode::I32X4TruncUF32X4Sat:
+ case Opcode::I64X2TruncSF64X2Sat:
+ case Opcode::I64X2TruncUF64X2Sat: {
+ stream->Writef("%s $0x%08x 0x%08x 0x%08x 0x%08x\n", opcode.GetName(),
+ Top().v128_bits.v[0], Top().v128_bits.v[1],
+ Top().v128_bits.v[2], Top().v128_bits.v[3]);
+ break;
+ }
+
+ case Opcode::V128BitSelect:
+ stream->Writef(
+ "%s $0x%08x %08x %08x %08x $0x%08x %08x %08x %08x $0x%08x %08x %08x "
+ "%08x\n",
+ opcode.GetName(), Pick(3).v128_bits.v[0], Pick(3).v128_bits.v[1],
+ Pick(3).v128_bits.v[2], Pick(3).v128_bits.v[3],
+ Pick(2).v128_bits.v[0], Pick(2).v128_bits.v[1],
+ Pick(2).v128_bits.v[2], Pick(2).v128_bits.v[3],
+ Pick(1).v128_bits.v[0], Pick(1).v128_bits.v[1],
+ Pick(1).v128_bits.v[2], Pick(1).v128_bits.v[3]);
+ break;
+
+ case Opcode::I8X16ExtractLaneS:
+ case Opcode::I8X16ExtractLaneU:
+ case Opcode::I16X8ExtractLaneS:
+ case Opcode::I16X8ExtractLaneU:
+ case Opcode::I32X4ExtractLane:
+ case Opcode::I64X2ExtractLane:
+ case Opcode::F32X4ExtractLane:
+ case Opcode::F64X2ExtractLane: {
+ stream->Writef("%s : LaneIdx %d From $0x%08x 0x%08x 0x%08x 0x%08x\n",
+ opcode.GetName(), ReadU8At(pc), Top().v128_bits.v[0],
+ Top().v128_bits.v[1], Top().v128_bits.v[2],
+ Top().v128_bits.v[3]);
+ break;
+ }
+
+ case Opcode::I8X16ReplaceLane:
+ case Opcode::I16X8ReplaceLane:
+ case Opcode::I32X4ReplaceLane: {
+ stream->Writef(
+ "%s : Set %u to LaneIdx %d In $0x%08x 0x%08x 0x%08x 0x%08x\n",
+ opcode.GetName(), Pick(1).i32, ReadU8At(pc), Pick(2).v128_bits.v[0],
+ Pick(2).v128_bits.v[1], Pick(2).v128_bits.v[2],
+ Pick(2).v128_bits.v[3]);
+ break;
+ }
+ case Opcode::I64X2ReplaceLane: {
+ stream->Writef("%s : Set %" PRIu64
+ " to LaneIdx %d In $0x%08x 0x%08x 0x%08x 0x%08x\n",
+ opcode.GetName(), Pick(1).i64, ReadU8At(pc),
+ Pick(2).v128_bits.v[0], Pick(2).v128_bits.v[1],
+ Pick(2).v128_bits.v[2], Pick(2).v128_bits.v[3]);
+ break;
+ }
+ case Opcode::F32X4ReplaceLane: {
+ stream->Writef(
+ "%s : Set %g to LaneIdx %d In $0x%08x 0x%08x 0x%08x 0x%08x\n",
+ opcode.GetName(), Bitcast<float>(Pick(1).f32_bits), ReadU8At(pc),
+ Pick(2).v128_bits.v[0], Pick(2).v128_bits.v[1],
+ Pick(2).v128_bits.v[2], Pick(2).v128_bits.v[3]);
+
+ break;
+ }
+ case Opcode::F64X2ReplaceLane: {
+ stream->Writef(
+ "%s : Set %g to LaneIdx %d In $0x%08x 0x%08x 0x%08x 0x%08x\n",
+ opcode.GetName(), Bitcast<double>(Pick(1).f64_bits), ReadU8At(pc),
+ Pick(2).v128_bits.v[0], Pick(2).v128_bits.v[1],
+ Pick(2).v128_bits.v[2], Pick(2).v128_bits.v[3]);
+ break;
+ }
+
+ case Opcode::V8X16Shuffle:
+ stream->Writef(
+ "%s $0x%08x %08x %08x %08x $0x%08x %08x %08x %08x : with lane imm: "
+ "$0x%08x %08x %08x %08x\n",
+ opcode.GetName(), Pick(2).v128_bits.v[0], Pick(2).v128_bits.v[1],
+ Pick(2).v128_bits.v[2], Pick(2).v128_bits.v[3],
+ Pick(1).v128_bits.v[0], Pick(1).v128_bits.v[1],
+ Pick(1).v128_bits.v[2], Pick(1).v128_bits.v[3], ReadU32At(pc),
+ ReadU32At(pc + 4), ReadU32At(pc + 8), ReadU32At(pc + 12));
+ break;
+
+ case Opcode::I8X16Add:
+ case Opcode::I16X8Add:
+ case Opcode::I32X4Add:
+ case Opcode::I64X2Add:
+ case Opcode::I8X16Sub:
+ case Opcode::I16X8Sub:
+ case Opcode::I32X4Sub:
+ case Opcode::I64X2Sub:
+ case Opcode::I8X16Mul:
+ case Opcode::I16X8Mul:
+ case Opcode::I32X4Mul:
+ case Opcode::I8X16AddSaturateS:
+ case Opcode::I8X16AddSaturateU:
+ case Opcode::I16X8AddSaturateS:
+ case Opcode::I16X8AddSaturateU:
+ case Opcode::I8X16SubSaturateS:
+ case Opcode::I8X16SubSaturateU:
+ case Opcode::I16X8SubSaturateS:
+ case Opcode::I16X8SubSaturateU:
+ case Opcode::V128And:
+ case Opcode::V128Or:
+ case Opcode::V128Xor:
+ case Opcode::I8X16Eq:
+ case Opcode::I16X8Eq:
+ case Opcode::I32X4Eq:
+ case Opcode::F32X4Eq:
+ case Opcode::F64X2Eq:
+ case Opcode::I8X16Ne:
+ case Opcode::I16X8Ne:
+ case Opcode::I32X4Ne:
+ case Opcode::F32X4Ne:
+ case Opcode::F64X2Ne:
+ case Opcode::I8X16LtS:
+ case Opcode::I8X16LtU:
+ case Opcode::I16X8LtS:
+ case Opcode::I16X8LtU:
+ case Opcode::I32X4LtS:
+ case Opcode::I32X4LtU:
+ case Opcode::F32X4Lt:
+ case Opcode::F64X2Lt:
+ case Opcode::I8X16LeS:
+ case Opcode::I8X16LeU:
+ case Opcode::I16X8LeS:
+ case Opcode::I16X8LeU:
+ case Opcode::I32X4LeS:
+ case Opcode::I32X4LeU:
+ case Opcode::F32X4Le:
+ case Opcode::F64X2Le:
+ case Opcode::I8X16GtS:
+ case Opcode::I8X16GtU:
+ case Opcode::I16X8GtS:
+ case Opcode::I16X8GtU:
+ case Opcode::I32X4GtS:
+ case Opcode::I32X4GtU:
+ case Opcode::F32X4Gt:
+ case Opcode::F64X2Gt:
+ case Opcode::I8X16GeS:
+ case Opcode::I8X16GeU:
+ case Opcode::I16X8GeS:
+ case Opcode::I16X8GeU:
+ case Opcode::I32X4GeS:
+ case Opcode::I32X4GeU:
+ case Opcode::F32X4Ge:
+ case Opcode::F64X2Ge:
+ case Opcode::F32X4Min:
+ case Opcode::F64X2Min:
+ case Opcode::F32X4Max:
+ case Opcode::F64X2Max:
+ case Opcode::F32X4Add:
+ case Opcode::F64X2Add:
+ case Opcode::F32X4Sub:
+ case Opcode::F64X2Sub:
+ case Opcode::F32X4Div:
+ case Opcode::F64X2Div:
+ case Opcode::F32X4Mul:
+ case Opcode::F64X2Mul: {
+ stream->Writef("%s $0x%08x %08x %08x %08x $0x%08x %08x %08x %08x\n",
+ opcode.GetName(), Pick(2).v128_bits.v[0],
+ Pick(2).v128_bits.v[1], Pick(2).v128_bits.v[2],
+ Pick(2).v128_bits.v[3], Pick(1).v128_bits.v[0],
+ Pick(1).v128_bits.v[1], Pick(1).v128_bits.v[2],
+ Pick(1).v128_bits.v[3]);
+ break;
+ }
+
+ case Opcode::I8X16Shl:
+ case Opcode::I16X8Shl:
+ case Opcode::I32X4Shl:
+ case Opcode::I64X2Shl:
+ case Opcode::I8X16ShrS:
+ case Opcode::I8X16ShrU:
+ case Opcode::I16X8ShrS:
+ case Opcode::I16X8ShrU:
+ case Opcode::I32X4ShrS:
+ case Opcode::I32X4ShrU:
+ case Opcode::I64X2ShrS:
+ case Opcode::I64X2ShrU: {
+ stream->Writef("%s $0x%08x %08x %08x %08x $0x%08x\n", opcode.GetName(),
+ Pick(2).v128_bits.v[0], Pick(2).v128_bits.v[1],
+ Pick(2).v128_bits.v[2], Pick(2).v128_bits.v[3],
+ Pick(1).i32);
+ break;
+ }
+
+ // The following opcodes are either never generated or should never be
+ // executed.
+ case Opcode::Block:
+ case Opcode::Catch:
+ case Opcode::Else:
+ case Opcode::End:
+ case Opcode::If:
+ case Opcode::IfExcept:
+ case Opcode::InterpData:
+ case Opcode::Invalid:
+ case Opcode::Loop:
+ case Opcode::Rethrow:
+ case Opcode::Throw:
+ case Opcode::Try:
+ WABT_UNREACHABLE;
+ break;
+ }
+}
+
+} // namespace interp
+} // namespace wabt
diff --git a/src/interp.cc b/src/interp/interp.cc
index b1e0ee89..b7753b7d 100644
--- a/src/interp.cc
+++ b/src/interp/interp.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "src/interp.h"
+#include "src/interp/interp.h"
#include <algorithm>
#include <cassert>
@@ -24,6 +24,8 @@
#include <type_traits>
#include <vector>
+#include "src/interp/interp-internal.h"
+
#include "src/cast.h"
#include "src/stream.h"
@@ -715,66 +717,6 @@ template<> v128 GetValue<v128>(Value v) { return v.v128_bits; }
#define GOTO(offset) pc = &istream[offset]
-template <typename T>
-inline T ReadUxAt(const uint8_t* pc) {
- T result;
- memcpy(&result, pc, sizeof(T));
- return result;
-}
-
-template <typename T>
-inline T ReadUx(const uint8_t** pc) {
- T result = ReadUxAt<T>(*pc);
- *pc += sizeof(T);
- return result;
-}
-
-inline uint8_t ReadU8At(const uint8_t* pc) {
- return ReadUxAt<uint8_t>(pc);
-}
-
-inline uint8_t ReadU8(const uint8_t** pc) {
- return ReadUx<uint8_t>(pc);
-}
-
-inline uint32_t ReadU32At(const uint8_t* pc) {
- return ReadUxAt<uint32_t>(pc);
-}
-
-inline uint32_t ReadU32(const uint8_t** pc) {
- return ReadUx<uint32_t>(pc);
-}
-
-inline uint64_t ReadU64At(const uint8_t* pc) {
- return ReadUxAt<uint64_t>(pc);
-}
-
-inline uint64_t ReadU64(const uint8_t** pc) {
- return ReadUx<uint64_t>(pc);
-}
-
-inline v128 ReadV128At(const uint8_t* pc) {
- return ReadUxAt<v128>(pc);
-}
-
-inline v128 ReadV128(const uint8_t** pc) {
- return ReadUx<v128>(pc);
-}
-
-inline Opcode ReadOpcode(const uint8_t** pc) {
- uint32_t value = ReadU32(pc);
- return Opcode(static_cast<Opcode::Enum>(value));
-}
-
-inline void read_table_entry_at(const uint8_t* pc,
- IstreamOffset* out_offset,
- uint32_t* out_drop,
- uint32_t* out_keep) {
- *out_offset = ReadU32At(pc + WABT_TABLE_ENTRY_OFFSET_OFFSET);
- *out_drop = ReadU32At(pc + WABT_TABLE_ENTRY_DROP_OFFSET);
- *out_keep = ReadU32At(pc + WABT_TABLE_ENTRY_KEEP_OFFSET);
-}
-
Memory* Thread::ReadMemory(const uint8_t** pc) {
Index memory_index = ReadU32(pc);
return &env_->memories_[memory_index];
@@ -1599,7 +1541,7 @@ Result Thread::Run(int num_instructions) {
IstreamOffset new_pc;
uint32_t drop_count;
uint32_t keep_count;
- read_table_entry_at(entry, &new_pc, &drop_count, &keep_count);
+ ReadTableEntryAt(entry, &new_pc, &drop_count, &keep_count);
DropKeep(drop_count, keep_count);
GOTO(new_pc);
break;
@@ -3300,1273 +3242,6 @@ exit_loop:
return result;
}
-void Thread::Trace(Stream* stream) {
- const uint8_t* istream = GetIstream();
- const uint8_t* pc = &istream[pc_];
-
- stream->Writef("#%u. %4" PRIzd ": V:%-3u| ", call_stack_top_, pc - istream,
- value_stack_top_);
-
- Opcode opcode = ReadOpcode(&pc);
- assert(!opcode.IsInvalid());
- switch (opcode) {
- case Opcode::Select:
- // TODO(binji): We don't know the type here so we can't display the value
- // to the user. This used to display the full 64-bit value, but that
- // will potentially display garbage if the value is 32-bit.
- stream->Writef("%s %u, %%[-2], %%[-1]\n", opcode.GetName(), Pick(3).i32);
- break;
-
- case Opcode::Br:
- stream->Writef("%s @%u\n", opcode.GetName(), ReadU32At(pc));
- break;
-
- case Opcode::BrIf:
- stream->Writef("%s @%u, %u\n", opcode.GetName(), ReadU32At(pc),
- Top().i32);
- break;
-
- case Opcode::BrTable: {
- Index num_targets = ReadU32At(pc);
- IstreamOffset table_offset = ReadU32At(pc + 4);
- uint32_t key = Top().i32;
- stream->Writef("%s %u, $#%" PRIindex ", table:$%u\n", opcode.GetName(),
- key, num_targets, table_offset);
- break;
- }
-
- case Opcode::Nop:
- case Opcode::Return:
- case Opcode::Unreachable:
- case Opcode::Drop:
- stream->Writef("%s\n", opcode.GetName());
- break;
-
- case Opcode::MemorySize: {
- Index memory_index = ReadU32(&pc);
- stream->Writef("%s $%" PRIindex "\n", opcode.GetName(), memory_index);
- break;
- }
-
- case Opcode::I32Const:
- stream->Writef("%s $%u\n", opcode.GetName(), ReadU32At(pc));
- break;
-
- case Opcode::I64Const:
- stream->Writef("%s $%" PRIu64 "\n", opcode.GetName(), ReadU64At(pc));
- break;
-
- case Opcode::F32Const:
- stream->Writef("%s $%g\n", opcode.GetName(),
- Bitcast<float>(ReadU32At(pc)));
- break;
-
- case Opcode::F64Const:
- stream->Writef("%s $%g\n", opcode.GetName(),
- Bitcast<double>(ReadU64At(pc)));
- break;
-
- case Opcode::GetLocal:
- case Opcode::GetGlobal:
- stream->Writef("%s $%u\n", opcode.GetName(), ReadU32At(pc));
- break;
-
- case Opcode::SetLocal:
- case Opcode::SetGlobal:
- case Opcode::TeeLocal:
- stream->Writef("%s $%u, %u\n", opcode.GetName(), ReadU32At(pc),
- Top().i32);
- break;
-
- case Opcode::Call:
- case Opcode::ReturnCall:
- stream->Writef("%s @%u\n", opcode.GetName(), ReadU32At(pc));
- break;
-
- case Opcode::CallIndirect:
- case Opcode::ReturnCallIndirect:
- stream->Writef("%s $%u, %u\n", opcode.GetName(), ReadU32At(pc),
- Top().i32);
- break;
-
- case Opcode::InterpCallHost:
- stream->Writef("%s $%u\n", opcode.GetName(), ReadU32At(pc));
- break;
-
- case Opcode::I32AtomicLoad8U:
- case Opcode::I32AtomicLoad16U:
- case Opcode::I32AtomicLoad:
- case Opcode::I64AtomicLoad8U:
- case Opcode::I64AtomicLoad16U:
- case Opcode::I64AtomicLoad32U:
- case Opcode::I64AtomicLoad:
- case Opcode::I32Load8S:
- case Opcode::I32Load8U:
- case Opcode::I32Load16S:
- case Opcode::I32Load16U:
- case Opcode::I64Load8S:
- case Opcode::I64Load8U:
- case Opcode::I64Load16S:
- case Opcode::I64Load16U:
- case Opcode::I64Load32S:
- case Opcode::I64Load32U:
- case Opcode::I32Load:
- case Opcode::I64Load:
- case Opcode::F32Load:
- case Opcode::F64Load:
- case Opcode::V128Load: {
- Index memory_index = ReadU32(&pc);
- stream->Writef("%s $%" PRIindex ":%u+$%u\n", opcode.GetName(),
- memory_index, Top().i32, ReadU32At(pc));
- break;
- }
-
- case Opcode::AtomicWake:
- case Opcode::I32AtomicStore:
- case Opcode::I32AtomicStore8:
- case Opcode::I32AtomicStore16:
- case Opcode::I32AtomicRmw8UAdd:
- case Opcode::I32AtomicRmw16UAdd:
- case Opcode::I32AtomicRmwAdd:
- case Opcode::I32AtomicRmw8USub:
- case Opcode::I32AtomicRmw16USub:
- case Opcode::I32AtomicRmwSub:
- case Opcode::I32AtomicRmw8UAnd:
- case Opcode::I32AtomicRmw16UAnd:
- case Opcode::I32AtomicRmwAnd:
- case Opcode::I32AtomicRmw8UOr:
- case Opcode::I32AtomicRmw16UOr:
- case Opcode::I32AtomicRmwOr:
- case Opcode::I32AtomicRmw8UXor:
- case Opcode::I32AtomicRmw16UXor:
- case Opcode::I32AtomicRmwXor:
- case Opcode::I32AtomicRmw8UXchg:
- case Opcode::I32AtomicRmw16UXchg:
- case Opcode::I32AtomicRmwXchg:
- case Opcode::I32Store8:
- case Opcode::I32Store16:
- case Opcode::I32Store: {
- Index memory_index = ReadU32(&pc);
- stream->Writef("%s $%" PRIindex ":%u+$%u, %u\n", opcode.GetName(),
- memory_index, Pick(2).i32, ReadU32At(pc), Pick(1).i32);
- break;
- }
-
- case Opcode::I32AtomicRmwCmpxchg:
- case Opcode::I32AtomicRmw8UCmpxchg:
- case Opcode::I32AtomicRmw16UCmpxchg: {
- Index memory_index = ReadU32(&pc);
- stream->Writef("%s $%" PRIindex ":%u+$%u, %u, %u\n", opcode.GetName(),
- memory_index, Pick(3).i32, ReadU32At(pc), Pick(2).i32,
- Pick(1).i32);
- break;
- }
-
- case Opcode::I64AtomicStore8:
- case Opcode::I64AtomicStore16:
- case Opcode::I64AtomicStore32:
- case Opcode::I64AtomicStore:
- case Opcode::I64AtomicRmw8UAdd:
- case Opcode::I64AtomicRmw16UAdd:
- case Opcode::I64AtomicRmw32UAdd:
- case Opcode::I64AtomicRmwAdd:
- case Opcode::I64AtomicRmw8USub:
- case Opcode::I64AtomicRmw16USub:
- case Opcode::I64AtomicRmw32USub:
- case Opcode::I64AtomicRmwSub:
- case Opcode::I64AtomicRmw8UAnd:
- case Opcode::I64AtomicRmw16UAnd:
- case Opcode::I64AtomicRmw32UAnd:
- case Opcode::I64AtomicRmwAnd:
- case Opcode::I64AtomicRmw8UOr:
- case Opcode::I64AtomicRmw16UOr:
- case Opcode::I64AtomicRmw32UOr:
- case Opcode::I64AtomicRmwOr:
- case Opcode::I64AtomicRmw8UXor:
- case Opcode::I64AtomicRmw16UXor:
- case Opcode::I64AtomicRmw32UXor:
- case Opcode::I64AtomicRmwXor:
- case Opcode::I64AtomicRmw8UXchg:
- case Opcode::I64AtomicRmw16UXchg:
- case Opcode::I64AtomicRmw32UXchg:
- case Opcode::I64AtomicRmwXchg:
- case Opcode::I64Store8:
- case Opcode::I64Store16:
- case Opcode::I64Store32:
- case Opcode::I64Store: {
- Index memory_index = ReadU32(&pc);
- stream->Writef("%s $%" PRIindex ":%u+$%u, %" PRIu64 "\n",
- opcode.GetName(), memory_index, Pick(2).i32, ReadU32At(pc),
- Pick(1).i64);
- break;
- }
-
- case Opcode::I32AtomicWait: {
- Index memory_index = ReadU32(&pc);
- stream->Writef("%s $%" PRIindex ":%u+$%u, %u, %" PRIu64 "\n",
- opcode.GetName(), memory_index, Pick(3).i32, ReadU32At(pc),
- Pick(2).i32, Pick(1).i64);
- break;
- }
-
- case Opcode::I64AtomicWait:
- case Opcode::I64AtomicRmwCmpxchg:
- case Opcode::I64AtomicRmw8UCmpxchg:
- case Opcode::I64AtomicRmw16UCmpxchg:
- case Opcode::I64AtomicRmw32UCmpxchg: {
- Index memory_index = ReadU32(&pc);
- stream->Writef("%s $%" PRIindex ":%u+$%u, %" PRIu64 ", %" PRIu64 "\n",
- opcode.GetName(), memory_index, Pick(3).i32, ReadU32At(pc),
- Pick(2).i64, Pick(1).i64);
- break;
- }
-
- case Opcode::F32Store: {
- Index memory_index = ReadU32(&pc);
- stream->Writef("%s $%" PRIindex ":%u+$%u, %g\n", opcode.GetName(),
- memory_index, Pick(2).i32, ReadU32At(pc),
- Bitcast<float>(Pick(1).f32_bits));
- break;
- }
-
- case Opcode::F64Store: {
- Index memory_index = ReadU32(&pc);
- stream->Writef("%s $%" PRIindex ":%u+$%u, %g\n", opcode.GetName(),
- memory_index, Pick(2).i32, ReadU32At(pc),
- Bitcast<double>(Pick(1).f64_bits));
- break;
- }
-
- case Opcode::V128Store: {
- Index memory_index = ReadU32(&pc);
- stream->Writef("%s $%" PRIindex ":%u+$%u, $0x%08x 0x%08x 0x%08x 0x%08x\n",
- opcode.GetName(), memory_index, Pick(2).i32, ReadU32At(pc),
- Pick(1).v128_bits.v[0], Pick(1).v128_bits.v[1],
- Pick(1).v128_bits.v[2], Pick(1).v128_bits.v[3]);
- break;
- }
-
- case Opcode::MemoryGrow: {
- Index memory_index = ReadU32(&pc);
- stream->Writef("%s $%" PRIindex ":%u\n", opcode.GetName(), memory_index,
- Top().i32);
- break;
- }
-
- case Opcode::I32Add:
- case Opcode::I32Sub:
- case Opcode::I32Mul:
- case Opcode::I32DivS:
- case Opcode::I32DivU:
- case Opcode::I32RemS:
- case Opcode::I32RemU:
- case Opcode::I32And:
- case Opcode::I32Or:
- case Opcode::I32Xor:
- case Opcode::I32Shl:
- case Opcode::I32ShrU:
- case Opcode::I32ShrS:
- case Opcode::I32Eq:
- case Opcode::I32Ne:
- case Opcode::I32LtS:
- case Opcode::I32LeS:
- case Opcode::I32LtU:
- case Opcode::I32LeU:
- case Opcode::I32GtS:
- case Opcode::I32GeS:
- case Opcode::I32GtU:
- case Opcode::I32GeU:
- case Opcode::I32Rotr:
- case Opcode::I32Rotl:
- stream->Writef("%s %u, %u\n", opcode.GetName(), Pick(2).i32, Pick(1).i32);
- break;
-
- case Opcode::I32Clz:
- case Opcode::I32Ctz:
- case Opcode::I32Popcnt:
- case Opcode::I32Eqz:
- case Opcode::I32Extend16S:
- case Opcode::I32Extend8S:
- case Opcode::I8X16Splat:
- case Opcode::I16X8Splat:
- case Opcode::I32X4Splat:
- stream->Writef("%s %u\n", opcode.GetName(), Top().i32);
- break;
-
- case Opcode::I64Add:
- case Opcode::I64Sub:
- case Opcode::I64Mul:
- case Opcode::I64DivS:
- case Opcode::I64DivU:
- case Opcode::I64RemS:
- case Opcode::I64RemU:
- case Opcode::I64And:
- case Opcode::I64Or:
- case Opcode::I64Xor:
- case Opcode::I64Shl:
- case Opcode::I64ShrU:
- case Opcode::I64ShrS:
- case Opcode::I64Eq:
- case Opcode::I64Ne:
- case Opcode::I64LtS:
- case Opcode::I64LeS:
- case Opcode::I64LtU:
- case Opcode::I64LeU:
- case Opcode::I64GtS:
- case Opcode::I64GeS:
- case Opcode::I64GtU:
- case Opcode::I64GeU:
- case Opcode::I64Rotr:
- case Opcode::I64Rotl:
- stream->Writef("%s %" PRIu64 ", %" PRIu64 "\n", opcode.GetName(),
- Pick(2).i64, Pick(1).i64);
- break;
-
- case Opcode::I64Clz:
- case Opcode::I64Ctz:
- case Opcode::I64Popcnt:
- case Opcode::I64Eqz:
- case Opcode::I64Extend16S:
- case Opcode::I64Extend32S:
- case Opcode::I64Extend8S:
- case Opcode::I64X2Splat:
- stream->Writef("%s %" PRIu64 "\n", opcode.GetName(), Top().i64);
- break;
-
- case Opcode::F32Add:
- case Opcode::F32Sub:
- case Opcode::F32Mul:
- case Opcode::F32Div:
- case Opcode::F32Min:
- case Opcode::F32Max:
- case Opcode::F32Copysign:
- case Opcode::F32Eq:
- case Opcode::F32Ne:
- case Opcode::F32Lt:
- case Opcode::F32Le:
- case Opcode::F32Gt:
- case Opcode::F32Ge:
- stream->Writef("%s %g, %g\n", opcode.GetName(),
- Bitcast<float>(Pick(2).i32), Bitcast<float>(Pick(1).i32));
- break;
-
- case Opcode::F32Abs:
- case Opcode::F32Neg:
- case Opcode::F32Ceil:
- case Opcode::F32Floor:
- case Opcode::F32Trunc:
- case Opcode::F32Nearest:
- case Opcode::F32Sqrt:
- case Opcode::F32X4Splat:
- stream->Writef("%s %g\n", opcode.GetName(), Bitcast<float>(Top().i32));
- break;
-
- case Opcode::F64Add:
- case Opcode::F64Sub:
- case Opcode::F64Mul:
- case Opcode::F64Div:
- case Opcode::F64Min:
- case Opcode::F64Max:
- case Opcode::F64Copysign:
- case Opcode::F64Eq:
- case Opcode::F64Ne:
- case Opcode::F64Lt:
- case Opcode::F64Le:
- case Opcode::F64Gt:
- case Opcode::F64Ge:
- stream->Writef("%s %g, %g\n", opcode.GetName(),
- Bitcast<double>(Pick(2).i64),
- Bitcast<double>(Pick(1).i64));
- break;
-
- case Opcode::F64Abs:
- case Opcode::F64Neg:
- case Opcode::F64Ceil:
- case Opcode::F64Floor:
- case Opcode::F64Trunc:
- case Opcode::F64Nearest:
- case Opcode::F64Sqrt:
- case Opcode::F64X2Splat:
- stream->Writef("%s %g\n", opcode.GetName(), Bitcast<double>(Top().i64));
- break;
-
- case Opcode::I32TruncSF32:
- case Opcode::I32TruncUF32:
- case Opcode::I64TruncSF32:
- case Opcode::I64TruncUF32:
- case Opcode::F64PromoteF32:
- case Opcode::I32ReinterpretF32:
- case Opcode::I32TruncSSatF32:
- case Opcode::I32TruncUSatF32:
- case Opcode::I64TruncSSatF32:
- case Opcode::I64TruncUSatF32:
- stream->Writef("%s %g\n", opcode.GetName(), Bitcast<float>(Top().i32));
- break;
-
- case Opcode::I32TruncSF64:
- case Opcode::I32TruncUF64:
- case Opcode::I64TruncSF64:
- case Opcode::I64TruncUF64:
- case Opcode::F32DemoteF64:
- case Opcode::I64ReinterpretF64:
- case Opcode::I32TruncSSatF64:
- case Opcode::I32TruncUSatF64:
- case Opcode::I64TruncSSatF64:
- case Opcode::I64TruncUSatF64:
- stream->Writef("%s %g\n", opcode.GetName(), Bitcast<double>(Top().i64));
- break;
-
- case Opcode::I32WrapI64:
- case Opcode::F32ConvertSI64:
- case Opcode::F32ConvertUI64:
- case Opcode::F64ConvertSI64:
- case Opcode::F64ConvertUI64:
- case Opcode::F64ReinterpretI64:
- stream->Writef("%s %" PRIu64 "\n", opcode.GetName(), Top().i64);
- break;
-
- case Opcode::I64ExtendSI32:
- case Opcode::I64ExtendUI32:
- case Opcode::F32ConvertSI32:
- case Opcode::F32ConvertUI32:
- case Opcode::F32ReinterpretI32:
- case Opcode::F64ConvertSI32:
- case Opcode::F64ConvertUI32:
- stream->Writef("%s %u\n", opcode.GetName(), Top().i32);
- break;
-
- case Opcode::InterpAlloca:
- stream->Writef("%s $%u\n", opcode.GetName(), ReadU32At(pc));
- break;
-
- case Opcode::InterpBrUnless:
- stream->Writef("%s @%u, %u\n", opcode.GetName(), ReadU32At(pc),
- Top().i32);
- break;
-
- case Opcode::InterpDropKeep:
- stream->Writef("%s $%u $%u\n", opcode.GetName(), ReadU32At(pc),
- ReadU32At(pc + 4));
- break;
-
- case Opcode::V128Const: {
- stream->Writef("%s $0x%08x 0x%08x 0x%08x 0x%08x\n", opcode.GetName(),
- ReadU32At(pc), ReadU32At(pc + 4), ReadU32At(pc + 8),
- ReadU32At(pc + 12));
- break;
- }
-
- case Opcode::I8X16Neg:
- case Opcode::I16X8Neg:
- case Opcode::I32X4Neg:
- case Opcode::I64X2Neg:
- case Opcode::V128Not:
- case Opcode::I8X16AnyTrue:
- case Opcode::I16X8AnyTrue:
- case Opcode::I32X4AnyTrue:
- case Opcode::I64X2AnyTrue:
- case Opcode::I8X16AllTrue:
- case Opcode::I16X8AllTrue:
- case Opcode::I32X4AllTrue:
- case Opcode::I64X2AllTrue:
- case Opcode::F32X4Neg:
- case Opcode::F64X2Neg:
- case Opcode::F32X4Abs:
- case Opcode::F64X2Abs:
- case Opcode::F32X4Sqrt:
- case Opcode::F64X2Sqrt:
- case Opcode::F32X4ConvertSI32X4:
- case Opcode::F32X4ConvertUI32X4:
- case Opcode::F64X2ConvertSI64X2:
- case Opcode::F64X2ConvertUI64X2:
- case Opcode::I32X4TruncSF32X4Sat:
- case Opcode::I32X4TruncUF32X4Sat:
- case Opcode::I64X2TruncSF64X2Sat:
- case Opcode::I64X2TruncUF64X2Sat: {
- stream->Writef("%s $0x%08x 0x%08x 0x%08x 0x%08x\n", opcode.GetName(),
- Top().v128_bits.v[0], Top().v128_bits.v[1],
- Top().v128_bits.v[2], Top().v128_bits.v[3]);
- break;
- }
-
- case Opcode::V128BitSelect:
- stream->Writef(
- "%s $0x%08x %08x %08x %08x $0x%08x %08x %08x %08x $0x%08x %08x %08x "
- "%08x\n",
- opcode.GetName(), Pick(3).v128_bits.v[0], Pick(3).v128_bits.v[1],
- Pick(3).v128_bits.v[2], Pick(3).v128_bits.v[3],
- Pick(2).v128_bits.v[0], Pick(2).v128_bits.v[1],
- Pick(2).v128_bits.v[2], Pick(2).v128_bits.v[3],
- Pick(1).v128_bits.v[0], Pick(1).v128_bits.v[1],
- Pick(1).v128_bits.v[2], Pick(1).v128_bits.v[3]);
- break;
-
- case Opcode::I8X16ExtractLaneS:
- case Opcode::I8X16ExtractLaneU:
- case Opcode::I16X8ExtractLaneS:
- case Opcode::I16X8ExtractLaneU:
- case Opcode::I32X4ExtractLane:
- case Opcode::I64X2ExtractLane:
- case Opcode::F32X4ExtractLane:
- case Opcode::F64X2ExtractLane: {
- stream->Writef("%s : LaneIdx %d From $0x%08x 0x%08x 0x%08x 0x%08x\n",
- opcode.GetName(), ReadU8At(pc), Top().v128_bits.v[0],
- Top().v128_bits.v[1], Top().v128_bits.v[2],
- Top().v128_bits.v[3]);
- break;
- }
-
- case Opcode::I8X16ReplaceLane:
- case Opcode::I16X8ReplaceLane:
- case Opcode::I32X4ReplaceLane: {
- stream->Writef(
- "%s : Set %u to LaneIdx %d In $0x%08x 0x%08x 0x%08x 0x%08x\n",
- opcode.GetName(), Pick(1).i32, ReadU8At(pc), Pick(2).v128_bits.v[0],
- Pick(2).v128_bits.v[1], Pick(2).v128_bits.v[2],
- Pick(2).v128_bits.v[3]);
- break;
- }
- case Opcode::I64X2ReplaceLane: {
- stream->Writef("%s : Set %" PRIu64
- " to LaneIdx %d In $0x%08x 0x%08x 0x%08x 0x%08x\n",
- opcode.GetName(), Pick(1).i64, ReadU8At(pc),
- Pick(2).v128_bits.v[0], Pick(2).v128_bits.v[1],
- Pick(2).v128_bits.v[2], Pick(2).v128_bits.v[3]);
- break;
- }
- case Opcode::F32X4ReplaceLane: {
- stream->Writef(
- "%s : Set %g to LaneIdx %d In $0x%08x 0x%08x 0x%08x 0x%08x\n",
- opcode.GetName(), Bitcast<float>(Pick(1).f32_bits), ReadU8At(pc),
- Pick(2).v128_bits.v[0], Pick(2).v128_bits.v[1],
- Pick(2).v128_bits.v[2], Pick(2).v128_bits.v[3]);
-
- break;
- }
- case Opcode::F64X2ReplaceLane: {
- stream->Writef(
- "%s : Set %g to LaneIdx %d In $0x%08x 0x%08x 0x%08x 0x%08x\n",
- opcode.GetName(), Bitcast<double>(Pick(1).f64_bits), ReadU8At(pc),
- Pick(2).v128_bits.v[0], Pick(2).v128_bits.v[1],
- Pick(2).v128_bits.v[2], Pick(2).v128_bits.v[3]);
- break;
- }
-
- case Opcode::V8X16Shuffle:
- stream->Writef(
- "%s $0x%08x %08x %08x %08x $0x%08x %08x %08x %08x : with lane imm: "
- "$0x%08x %08x %08x %08x\n",
- opcode.GetName(), Pick(2).v128_bits.v[0], Pick(2).v128_bits.v[1],
- Pick(2).v128_bits.v[2], Pick(2).v128_bits.v[3],
- Pick(1).v128_bits.v[0], Pick(1).v128_bits.v[1],
- Pick(1).v128_bits.v[2], Pick(1).v128_bits.v[3], ReadU32At(pc),
- ReadU32At(pc + 4), ReadU32At(pc + 8), ReadU32At(pc + 12));
- break;
-
- case Opcode::I8X16Add:
- case Opcode::I16X8Add:
- case Opcode::I32X4Add:
- case Opcode::I64X2Add:
- case Opcode::I8X16Sub:
- case Opcode::I16X8Sub:
- case Opcode::I32X4Sub:
- case Opcode::I64X2Sub:
- case Opcode::I8X16Mul:
- case Opcode::I16X8Mul:
- case Opcode::I32X4Mul:
- case Opcode::I8X16AddSaturateS:
- case Opcode::I8X16AddSaturateU:
- case Opcode::I16X8AddSaturateS:
- case Opcode::I16X8AddSaturateU:
- case Opcode::I8X16SubSaturateS:
- case Opcode::I8X16SubSaturateU:
- case Opcode::I16X8SubSaturateS:
- case Opcode::I16X8SubSaturateU:
- case Opcode::V128And:
- case Opcode::V128Or:
- case Opcode::V128Xor:
- case Opcode::I8X16Eq:
- case Opcode::I16X8Eq:
- case Opcode::I32X4Eq:
- case Opcode::F32X4Eq:
- case Opcode::F64X2Eq:
- case Opcode::I8X16Ne:
- case Opcode::I16X8Ne:
- case Opcode::I32X4Ne:
- case Opcode::F32X4Ne:
- case Opcode::F64X2Ne:
- case Opcode::I8X16LtS:
- case Opcode::I8X16LtU:
- case Opcode::I16X8LtS:
- case Opcode::I16X8LtU:
- case Opcode::I32X4LtS:
- case Opcode::I32X4LtU:
- case Opcode::F32X4Lt:
- case Opcode::F64X2Lt:
- case Opcode::I8X16LeS:
- case Opcode::I8X16LeU:
- case Opcode::I16X8LeS:
- case Opcode::I16X8LeU:
- case Opcode::I32X4LeS:
- case Opcode::I32X4LeU:
- case Opcode::F32X4Le:
- case Opcode::F64X2Le:
- case Opcode::I8X16GtS:
- case Opcode::I8X16GtU:
- case Opcode::I16X8GtS:
- case Opcode::I16X8GtU:
- case Opcode::I32X4GtS:
- case Opcode::I32X4GtU:
- case Opcode::F32X4Gt:
- case Opcode::F64X2Gt:
- case Opcode::I8X16GeS:
- case Opcode::I8X16GeU:
- case Opcode::I16X8GeS:
- case Opcode::I16X8GeU:
- case Opcode::I32X4GeS:
- case Opcode::I32X4GeU:
- case Opcode::F32X4Ge:
- case Opcode::F64X2Ge:
- case Opcode::F32X4Min:
- case Opcode::F64X2Min:
- case Opcode::F32X4Max:
- case Opcode::F64X2Max:
- case Opcode::F32X4Add:
- case Opcode::F64X2Add:
- case Opcode::F32X4Sub:
- case Opcode::F64X2Sub:
- case Opcode::F32X4Div:
- case Opcode::F64X2Div:
- case Opcode::F32X4Mul:
- case Opcode::F64X2Mul: {
- stream->Writef("%s $0x%08x %08x %08x %08x $0x%08x %08x %08x %08x\n",
- opcode.GetName(), Pick(2).v128_bits.v[0],
- Pick(2).v128_bits.v[1], Pick(2).v128_bits.v[2],
- Pick(2).v128_bits.v[3], Pick(1).v128_bits.v[0],
- Pick(1).v128_bits.v[1], Pick(1).v128_bits.v[2],
- Pick(1).v128_bits.v[3]);
- break;
- }
-
- case Opcode::I8X16Shl:
- case Opcode::I16X8Shl:
- case Opcode::I32X4Shl:
- case Opcode::I64X2Shl:
- case Opcode::I8X16ShrS:
- case Opcode::I8X16ShrU:
- case Opcode::I16X8ShrS:
- case Opcode::I16X8ShrU:
- case Opcode::I32X4ShrS:
- case Opcode::I32X4ShrU:
- case Opcode::I64X2ShrS:
- case Opcode::I64X2ShrU: {
- stream->Writef("%s $0x%08x %08x %08x %08x $0x%08x\n", opcode.GetName(),
- Pick(2).v128_bits.v[0], Pick(2).v128_bits.v[1],
- Pick(2).v128_bits.v[2], Pick(2).v128_bits.v[3],
- Pick(1).i32);
- break;
- }
-
- // The following opcodes are either never generated or should never be
- // executed.
- case Opcode::Block:
- case Opcode::Catch:
- case Opcode::Else:
- case Opcode::End:
- case Opcode::If:
- case Opcode::IfExcept:
- case Opcode::InterpData:
- case Opcode::Invalid:
- case Opcode::Loop:
- case Opcode::Rethrow:
- case Opcode::Throw:
- case Opcode::Try:
- WABT_UNREACHABLE;
- break;
- }
-}
-
-void Environment::Disassemble(Stream* stream,
- IstreamOffset from,
- IstreamOffset to) {
- /* TODO(binji): mark function entries */
- /* TODO(binji): track value stack size */
- if (from >= istream_->data.size()) {
- return;
- }
- to = std::min<IstreamOffset>(to, istream_->data.size());
- const uint8_t* istream = istream_->data.data();
- const uint8_t* pc = &istream[from];
-
- while (static_cast<IstreamOffset>(pc - istream) < to) {
- stream->Writef("%4" PRIzd "| ", pc - istream);
-
- Opcode opcode = ReadOpcode(&pc);
- assert(!opcode.IsInvalid());
- switch (opcode) {
- case Opcode::Select:
- case Opcode::V128BitSelect:
- stream->Writef("%s %%[-3], %%[-2], %%[-1]\n", opcode.GetName());
- break;
-
- case Opcode::Br:
- stream->Writef("%s @%u\n", opcode.GetName(), ReadU32(&pc));
- break;
-
- case Opcode::BrIf:
- stream->Writef("%s @%u, %%[-1]\n", opcode.GetName(), ReadU32(&pc));
- break;
-
- case Opcode::BrTable: {
- Index num_targets = ReadU32(&pc);
- IstreamOffset table_offset = ReadU32(&pc);
- stream->Writef("%s %%[-1], $#%" PRIindex ", table:$%u\n",
- opcode.GetName(), num_targets, table_offset);
- break;
- }
-
- case Opcode::Nop:
- case Opcode::Return:
- case Opcode::Unreachable:
- case Opcode::Drop:
- stream->Writef("%s\n", opcode.GetName());
- break;
-
- case Opcode::MemorySize: {
- Index memory_index = ReadU32(&pc);
- stream->Writef("%s $%" PRIindex "\n", opcode.GetName(), memory_index);
- break;
- }
-
- case Opcode::I32Const:
- stream->Writef("%s $%u\n", opcode.GetName(), ReadU32(&pc));
- break;
-
- case Opcode::I64Const:
- stream->Writef("%s $%" PRIu64 "\n", opcode.GetName(), ReadU64(&pc));
- break;
-
- case Opcode::F32Const:
- stream->Writef("%s $%g\n", opcode.GetName(),
- Bitcast<float>(ReadU32(&pc)));
- break;
-
- case Opcode::F64Const:
- stream->Writef("%s $%g\n", opcode.GetName(),
- Bitcast<double>(ReadU64(&pc)));
- break;
-
- case Opcode::GetLocal:
- case Opcode::GetGlobal:
- stream->Writef("%s $%u\n", opcode.GetName(), ReadU32(&pc));
- break;
-
- case Opcode::SetLocal:
- case Opcode::SetGlobal:
- case Opcode::TeeLocal:
- stream->Writef("%s $%u, %%[-1]\n", opcode.GetName(), ReadU32(&pc));
- break;
-
- case Opcode::Call:
- case Opcode::ReturnCall:
- stream->Writef("%s @%u\n", opcode.GetName(), ReadU32(&pc));
- break;
-
- case Opcode::CallIndirect:
- case Opcode::ReturnCallIndirect: {
- Index table_index = ReadU32(&pc);
- stream->Writef("%s $%" PRIindex ":%u, %%[-1]\n", opcode.GetName(),
- table_index, ReadU32(&pc));
- break;
- }
-
- case Opcode::InterpCallHost:
- stream->Writef("%s $%u\n", opcode.GetName(), ReadU32(&pc));
- break;
-
- case Opcode::I32AtomicLoad:
- case Opcode::I64AtomicLoad:
- case Opcode::I32AtomicLoad8U:
- case Opcode::I32AtomicLoad16U:
- case Opcode::I64AtomicLoad8U:
- case Opcode::I64AtomicLoad16U:
- case Opcode::I64AtomicLoad32U:
- case Opcode::I32Load8S:
- case Opcode::I32Load8U:
- case Opcode::I32Load16S:
- case Opcode::I32Load16U:
- case Opcode::I64Load8S:
- case Opcode::I64Load8U:
- case Opcode::I64Load16S:
- case Opcode::I64Load16U:
- case Opcode::I64Load32S:
- case Opcode::I64Load32U:
- case Opcode::I32Load:
- case Opcode::I64Load:
- case Opcode::F32Load:
- case Opcode::F64Load:
- case Opcode::V128Load: {
- Index memory_index = ReadU32(&pc);
- stream->Writef("%s $%" PRIindex ":%%[-1]+$%u\n", opcode.GetName(),
- memory_index, ReadU32(&pc));
- break;
- }
-
- case Opcode::AtomicWake:
- case Opcode::I32AtomicStore:
- case Opcode::I64AtomicStore:
- case Opcode::I32AtomicStore8:
- case Opcode::I32AtomicStore16:
- case Opcode::I64AtomicStore8:
- case Opcode::I64AtomicStore16:
- case Opcode::I64AtomicStore32:
- case Opcode::I32AtomicRmwAdd:
- case Opcode::I64AtomicRmwAdd:
- case Opcode::I32AtomicRmw8UAdd:
- case Opcode::I32AtomicRmw16UAdd:
- case Opcode::I64AtomicRmw8UAdd:
- case Opcode::I64AtomicRmw16UAdd:
- case Opcode::I64AtomicRmw32UAdd:
- case Opcode::I32AtomicRmwSub:
- case Opcode::I64AtomicRmwSub:
- case Opcode::I32AtomicRmw8USub:
- case Opcode::I32AtomicRmw16USub:
- case Opcode::I64AtomicRmw8USub:
- case Opcode::I64AtomicRmw16USub:
- case Opcode::I64AtomicRmw32USub:
- case Opcode::I32AtomicRmwAnd:
- case Opcode::I64AtomicRmwAnd:
- case Opcode::I32AtomicRmw8UAnd:
- case Opcode::I32AtomicRmw16UAnd:
- case Opcode::I64AtomicRmw8UAnd:
- case Opcode::I64AtomicRmw16UAnd:
- case Opcode::I64AtomicRmw32UAnd:
- case Opcode::I32AtomicRmwOr:
- case Opcode::I64AtomicRmwOr:
- case Opcode::I32AtomicRmw8UOr:
- case Opcode::I32AtomicRmw16UOr:
- case Opcode::I64AtomicRmw8UOr:
- case Opcode::I64AtomicRmw16UOr:
- case Opcode::I64AtomicRmw32UOr:
- case Opcode::I32AtomicRmwXor:
- case Opcode::I64AtomicRmwXor:
- case Opcode::I32AtomicRmw8UXor:
- case Opcode::I32AtomicRmw16UXor:
- case Opcode::I64AtomicRmw8UXor:
- case Opcode::I64AtomicRmw16UXor:
- case Opcode::I64AtomicRmw32UXor:
- case Opcode::I32AtomicRmwXchg:
- case Opcode::I64AtomicRmwXchg:
- case Opcode::I32AtomicRmw8UXchg:
- case Opcode::I32AtomicRmw16UXchg:
- case Opcode::I64AtomicRmw8UXchg:
- case Opcode::I64AtomicRmw16UXchg:
- case Opcode::I64AtomicRmw32UXchg:
- case Opcode::I32Store8:
- case Opcode::I32Store16:
- case Opcode::I32Store:
- case Opcode::I64Store8:
- case Opcode::I64Store16:
- case Opcode::I64Store32:
- case Opcode::I64Store:
- case Opcode::F32Store:
- case Opcode::F64Store:
- case Opcode::V128Store: {
- Index memory_index = ReadU32(&pc);
- stream->Writef("%s $%" PRIindex ":%%[-2]+$%u, %%[-1]\n",
- opcode.GetName(), memory_index, ReadU32(&pc));
- break;
- }
-
- case Opcode::I32AtomicWait:
- case Opcode::I64AtomicWait:
- case Opcode::I32AtomicRmwCmpxchg:
- case Opcode::I64AtomicRmwCmpxchg:
- case Opcode::I32AtomicRmw8UCmpxchg:
- case Opcode::I32AtomicRmw16UCmpxchg:
- case Opcode::I64AtomicRmw8UCmpxchg:
- case Opcode::I64AtomicRmw16UCmpxchg:
- case Opcode::I64AtomicRmw32UCmpxchg: {
- Index memory_index = ReadU32(&pc);
- stream->Writef("%s $%" PRIindex ":%%[-3]+$%u, %%[-2], %%[-1]\n",
- opcode.GetName(), memory_index, ReadU32(&pc));
- break;
- }
-
- case Opcode::I32Add:
- case Opcode::I32Sub:
- case Opcode::I32Mul:
- case Opcode::I32DivS:
- case Opcode::I32DivU:
- case Opcode::I32RemS:
- case Opcode::I32RemU:
- case Opcode::I32And:
- case Opcode::I32Or:
- case Opcode::I32Xor:
- case Opcode::I32Shl:
- case Opcode::I32ShrU:
- case Opcode::I32ShrS:
- case Opcode::I32Eq:
- case Opcode::I32Ne:
- case Opcode::I32LtS:
- case Opcode::I32LeS:
- case Opcode::I32LtU:
- case Opcode::I32LeU:
- case Opcode::I32GtS:
- case Opcode::I32GeS:
- case Opcode::I32GtU:
- case Opcode::I32GeU:
- case Opcode::I32Rotr:
- case Opcode::I32Rotl:
- case Opcode::F32Add:
- case Opcode::F32Sub:
- case Opcode::F32Mul:
- case Opcode::F32Div:
- case Opcode::F32Min:
- case Opcode::F32Max:
- case Opcode::F32Copysign:
- case Opcode::F32Eq:
- case Opcode::F32Ne:
- case Opcode::F32Lt:
- case Opcode::F32Le:
- case Opcode::F32Gt:
- case Opcode::F32Ge:
- case Opcode::I64Add:
- case Opcode::I64Sub:
- case Opcode::I64Mul:
- case Opcode::I64DivS:
- case Opcode::I64DivU:
- case Opcode::I64RemS:
- case Opcode::I64RemU:
- case Opcode::I64And:
- case Opcode::I64Or:
- case Opcode::I64Xor:
- case Opcode::I64Shl:
- case Opcode::I64ShrU:
- case Opcode::I64ShrS:
- case Opcode::I64Eq:
- case Opcode::I64Ne:
- case Opcode::I64LtS:
- case Opcode::I64LeS:
- case Opcode::I64LtU:
- case Opcode::I64LeU:
- case Opcode::I64GtS:
- case Opcode::I64GeS:
- case Opcode::I64GtU:
- case Opcode::I64GeU:
- case Opcode::I64Rotr:
- case Opcode::I64Rotl:
- case Opcode::F64Add:
- case Opcode::F64Sub:
- case Opcode::F64Mul:
- case Opcode::F64Div:
- case Opcode::F64Min:
- case Opcode::F64Max:
- case Opcode::F64Copysign:
- case Opcode::F64Eq:
- case Opcode::F64Ne:
- case Opcode::F64Lt:
- case Opcode::F64Le:
- case Opcode::F64Gt:
- case Opcode::F64Ge:
- case Opcode::I8X16Add:
- case Opcode::I16X8Add:
- case Opcode::I32X4Add:
- case Opcode::I64X2Add:
- case Opcode::I8X16Sub:
- case Opcode::I16X8Sub:
- case Opcode::I32X4Sub:
- case Opcode::I64X2Sub:
- case Opcode::I8X16Mul:
- case Opcode::I16X8Mul:
- case Opcode::I32X4Mul:
- case Opcode::I8X16AddSaturateS:
- case Opcode::I8X16AddSaturateU:
- case Opcode::I16X8AddSaturateS:
- case Opcode::I16X8AddSaturateU:
- case Opcode::I8X16SubSaturateS:
- case Opcode::I8X16SubSaturateU:
- case Opcode::I16X8SubSaturateS:
- case Opcode::I16X8SubSaturateU:
- case Opcode::I8X16Shl:
- case Opcode::I16X8Shl:
- case Opcode::I32X4Shl:
- case Opcode::I64X2Shl:
- case Opcode::I8X16ShrS:
- case Opcode::I8X16ShrU:
- case Opcode::I16X8ShrS:
- case Opcode::I16X8ShrU:
- case Opcode::I32X4ShrS:
- case Opcode::I32X4ShrU:
- case Opcode::I64X2ShrS:
- case Opcode::I64X2ShrU:
- case Opcode::V128And:
- case Opcode::V128Or:
- case Opcode::V128Xor:
- case Opcode::I8X16Eq:
- case Opcode::I16X8Eq:
- case Opcode::I32X4Eq:
- case Opcode::F32X4Eq:
- case Opcode::F64X2Eq:
- case Opcode::I8X16Ne:
- case Opcode::I16X8Ne:
- case Opcode::I32X4Ne:
- case Opcode::F32X4Ne:
- case Opcode::F64X2Ne:
- case Opcode::I8X16LtS:
- case Opcode::I8X16LtU:
- case Opcode::I16X8LtS:
- case Opcode::I16X8LtU:
- case Opcode::I32X4LtS:
- case Opcode::I32X4LtU:
- case Opcode::F32X4Lt:
- case Opcode::F64X2Lt:
- case Opcode::I8X16LeS:
- case Opcode::I8X16LeU:
- case Opcode::I16X8LeS:
- case Opcode::I16X8LeU:
- case Opcode::I32X4LeS:
- case Opcode::I32X4LeU:
- case Opcode::F32X4Le:
- case Opcode::F64X2Le:
- case Opcode::I8X16GtS:
- case Opcode::I8X16GtU:
- case Opcode::I16X8GtS:
- case Opcode::I16X8GtU:
- case Opcode::I32X4GtS:
- case Opcode::I32X4GtU:
- case Opcode::F32X4Gt:
- case Opcode::F64X2Gt:
- case Opcode::I8X16GeS:
- case Opcode::I8X16GeU:
- case Opcode::I16X8GeS:
- case Opcode::I16X8GeU:
- case Opcode::I32X4GeS:
- case Opcode::I32X4GeU:
- case Opcode::F32X4Ge:
- case Opcode::F64X2Ge:
- case Opcode::F32X4Min:
- case Opcode::F64X2Min:
- case Opcode::F32X4Max:
- case Opcode::F64X2Max:
- case Opcode::F32X4Add:
- case Opcode::F64X2Add:
- case Opcode::F32X4Sub:
- case Opcode::F64X2Sub:
- case Opcode::F32X4Div:
- case Opcode::F64X2Div:
- case Opcode::F32X4Mul:
- case Opcode::F64X2Mul:
- stream->Writef("%s %%[-2], %%[-1]\n", opcode.GetName());
- break;
-
- case Opcode::I32Clz:
- case Opcode::I32Ctz:
- case Opcode::I32Popcnt:
- case Opcode::I32Eqz:
- case Opcode::I64Clz:
- case Opcode::I64Ctz:
- case Opcode::I64Popcnt:
- case Opcode::I64Eqz:
- case Opcode::F32Abs:
- case Opcode::F32Neg:
- case Opcode::F32Ceil:
- case Opcode::F32Floor:
- case Opcode::F32Trunc:
- case Opcode::F32Nearest:
- case Opcode::F32Sqrt:
- case Opcode::F64Abs:
- case Opcode::F64Neg:
- case Opcode::F64Ceil:
- case Opcode::F64Floor:
- case Opcode::F64Trunc:
- case Opcode::F64Nearest:
- case Opcode::F64Sqrt:
- case Opcode::I32TruncSF32:
- case Opcode::I32TruncUF32:
- case Opcode::I64TruncSF32:
- case Opcode::I64TruncUF32:
- case Opcode::F64PromoteF32:
- case Opcode::I32ReinterpretF32:
- case Opcode::I32TruncSF64:
- case Opcode::I32TruncUF64:
- case Opcode::I64TruncSF64:
- case Opcode::I64TruncUF64:
- case Opcode::F32DemoteF64:
- case Opcode::I64ReinterpretF64:
- case Opcode::I32WrapI64:
- case Opcode::F32ConvertSI64:
- case Opcode::F32ConvertUI64:
- case Opcode::F64ConvertSI64:
- case Opcode::F64ConvertUI64:
- case Opcode::F64ReinterpretI64:
- case Opcode::I64ExtendSI32:
- case Opcode::I64ExtendUI32:
- case Opcode::F32ConvertSI32:
- case Opcode::F32ConvertUI32:
- case Opcode::F32ReinterpretI32:
- case Opcode::F64ConvertSI32:
- case Opcode::F64ConvertUI32:
- case Opcode::I32TruncSSatF32:
- case Opcode::I32TruncUSatF32:
- case Opcode::I64TruncSSatF32:
- case Opcode::I64TruncUSatF32:
- case Opcode::I32TruncSSatF64:
- case Opcode::I32TruncUSatF64:
- case Opcode::I64TruncSSatF64:
- case Opcode::I64TruncUSatF64:
- case Opcode::I32Extend16S:
- case Opcode::I32Extend8S:
- case Opcode::I64Extend16S:
- case Opcode::I64Extend32S:
- case Opcode::I64Extend8S:
- case Opcode::I8X16Splat:
- case Opcode::I16X8Splat:
- case Opcode::I32X4Splat:
- case Opcode::I64X2Splat:
- case Opcode::F32X4Splat:
- case Opcode::F64X2Splat:
- case Opcode::I8X16Neg:
- case Opcode::I16X8Neg:
- case Opcode::I32X4Neg:
- case Opcode::I64X2Neg:
- case Opcode::V128Not:
- case Opcode::I8X16AnyTrue:
- case Opcode::I16X8AnyTrue:
- case Opcode::I32X4AnyTrue:
- case Opcode::I64X2AnyTrue:
- case Opcode::I8X16AllTrue:
- case Opcode::I16X8AllTrue:
- case Opcode::I32X4AllTrue:
- case Opcode::I64X2AllTrue:
- case Opcode::F32X4Neg:
- case Opcode::F64X2Neg:
- case Opcode::F32X4Abs:
- case Opcode::F64X2Abs:
- case Opcode::F32X4Sqrt:
- case Opcode::F64X2Sqrt:
- case Opcode::F32X4ConvertSI32X4:
- case Opcode::F32X4ConvertUI32X4:
- case Opcode::F64X2ConvertSI64X2:
- case Opcode::F64X2ConvertUI64X2:
- case Opcode::I32X4TruncSF32X4Sat:
- case Opcode::I32X4TruncUF32X4Sat:
- case Opcode::I64X2TruncSF64X2Sat:
- case Opcode::I64X2TruncUF64X2Sat:
- stream->Writef("%s %%[-1]\n", opcode.GetName());
- break;
-
- case Opcode::I8X16ExtractLaneS:
- case Opcode::I8X16ExtractLaneU:
- case Opcode::I16X8ExtractLaneS:
- case Opcode::I16X8ExtractLaneU:
- case Opcode::I32X4ExtractLane:
- case Opcode::I64X2ExtractLane:
- case Opcode::F32X4ExtractLane:
- case Opcode::F64X2ExtractLane: {
- stream->Writef("%s %%[-1] : (Lane imm: %d)\n", opcode.GetName(),
- ReadU8(&pc));
- break;
- }
-
- case Opcode::I8X16ReplaceLane:
- case Opcode::I16X8ReplaceLane:
- case Opcode::I32X4ReplaceLane:
- case Opcode::I64X2ReplaceLane:
- case Opcode::F32X4ReplaceLane:
- case Opcode::F64X2ReplaceLane: {
- stream->Writef("%s %%[-1], %%[-2] : (Lane imm: %d)\n",
- opcode.GetName(), ReadU8(&pc));
- break;
- }
-
- case Opcode::V8X16Shuffle:
- stream->Writef(
- "%s %%[-2], %%[-1] : (Lane imm: $0x%08x 0x%08x 0x%08x 0x%08x )\n",
- opcode.GetName(), ReadU32(&pc), ReadU32(&pc), ReadU32(&pc),
- ReadU32(&pc));
- break;
-
- case Opcode::MemoryGrow: {
- Index memory_index = ReadU32(&pc);
- stream->Writef("%s $%" PRIindex ":%%[-1]\n", opcode.GetName(),
- memory_index);
- break;
- }
-
- case Opcode::InterpAlloca:
- stream->Writef("%s $%u\n", opcode.GetName(), ReadU32(&pc));
- break;
-
- case Opcode::InterpBrUnless:
- stream->Writef("%s @%u, %%[-1]\n", opcode.GetName(), ReadU32(&pc));
- break;
-
- case Opcode::InterpDropKeep: {
- uint32_t drop = ReadU32(&pc);
- uint32_t keep = ReadU32(&pc);
- stream->Writef("%s $%u $%u\n", opcode.GetName(), drop, keep);
- break;
- }
-
- case Opcode::InterpData: {
- uint32_t num_bytes = ReadU32(&pc);
- stream->Writef("%s $%u\n", opcode.GetName(), num_bytes);
- /* for now, the only reason this is emitted is for br_table, so display
- * it as a list of table entries */
- if (num_bytes % WABT_TABLE_ENTRY_SIZE == 0) {
- Index num_entries = num_bytes / WABT_TABLE_ENTRY_SIZE;
- for (Index i = 0; i < num_entries; ++i) {
- stream->Writef("%4" PRIzd "| ", pc - istream);
- IstreamOffset offset;
- uint32_t drop;
- uint32_t keep;
- read_table_entry_at(pc, &offset, &drop, &keep);
- stream->Writef(" entry %" PRIindex
- ": offset: %u drop: %u keep: %u\n",
- i, offset, drop, keep);
- pc += WABT_TABLE_ENTRY_SIZE;
- }
- } else {
- /* just skip those data bytes */
- pc += num_bytes;
- }
-
- break;
- }
-
- case Opcode::V128Const: {
- stream->Writef("%s $0x%08x 0x%08x 0x%08x 0x%08x\n", opcode.GetName(),
- ReadU32(&pc), ReadU32(&pc), ReadU32(&pc), ReadU32(&pc));
-
- break;
- }
- // The following opcodes are either never generated or should never be
- // executed.
- case Opcode::Block:
- case Opcode::Catch:
- case Opcode::Else:
- case Opcode::End:
- case Opcode::If:
- case Opcode::IfExcept:
- case Opcode::Invalid:
- case Opcode::Loop:
- case Opcode::Rethrow:
- case Opcode::Throw:
- case Opcode::Try:
- WABT_UNREACHABLE;
- break;
- }
- }
-}
-
-void Environment::DisassembleModule(Stream* stream, Module* module) {
- assert(!module->is_host);
- auto* defined_module = cast<DefinedModule>(module);
- Disassemble(stream, defined_module->istream_start,
- defined_module->istream_end);
-}
-
Executor::Executor(Environment* env,
Stream* trace_stream,
const Thread::Options& options)
diff --git a/src/interp.h b/src/interp/interp.h
index 1d39b223..fadb72c0 100644
--- a/src/interp.h
+++ b/src/interp/interp.h
@@ -82,19 +82,6 @@ enum class Result {
typedef uint32_t IstreamOffset;
static const IstreamOffset kInvalidIstreamOffset = ~0;
-// A table entry has the following packed layout:
-//
-// struct {
-// IstreamOffset offset;
-// uint32_t drop_count;
-// uint32_t keep_count;
-// };
-#define WABT_TABLE_ENTRY_SIZE \
- (sizeof(IstreamOffset) + sizeof(uint32_t) + sizeof(uint32_t))
-#define WABT_TABLE_ENTRY_OFFSET_OFFSET 0
-#define WABT_TABLE_ENTRY_DROP_OFFSET sizeof(IstreamOffset)
-#define WABT_TABLE_ENTRY_KEEP_OFFSET (sizeof(IstreamOffset) + sizeof(uint32_t))
-
struct FuncSignature {
FuncSignature() = default;
FuncSignature(std::vector<Type> param_types, std::vector<Type> result_types);
diff --git a/src/test-interp.cc b/src/test-interp.cc
index 0928ef03..10010cf6 100644
--- a/src/test-interp.cc
+++ b/src/test-interp.cc
@@ -23,9 +23,9 @@
#include <vector>
#include "src/binary-reader.h"
-#include "src/binary-reader-interp.h"
#include "src/cast.h"
-#include "src/interp.h"
+#include "src/interp/binary-reader-interp.h"
+#include "src/interp/interp.h"
#include "src/make-unique.h"
using namespace wabt;
diff --git a/src/tools/spectest-interp.cc b/src/tools/spectest-interp.cc
index 22becce2..928a6110 100644
--- a/src/tools/spectest-interp.cc
+++ b/src/tools/spectest-interp.cc
@@ -23,12 +23,12 @@
#include <string>
#include <vector>
-#include "src/binary-reader-interp.h"
#include "src/binary-reader.h"
#include "src/cast.h"
#include "src/error-formatter.h"
#include "src/feature.h"
-#include "src/interp.h"
+#include "src/interp/binary-reader-interp.h"
+#include "src/interp/interp.h"
#include "src/literal.h"
#include "src/option-parser.h"
#include "src/resolve-names.h"
diff --git a/src/tools/wasm-interp.cc b/src/tools/wasm-interp.cc
index 0bcd05f1..cb5808d8 100644
--- a/src/tools/wasm-interp.cc
+++ b/src/tools/wasm-interp.cc
@@ -23,12 +23,12 @@
#include <string>
#include <vector>
-#include "src/binary-reader-interp.h"
#include "src/binary-reader.h"
#include "src/cast.h"
#include "src/error-formatter.h"
#include "src/feature.h"
-#include "src/interp.h"
+#include "src/interp/binary-reader-interp.h"
+#include "src/interp/interp.h"
#include "src/literal.h"
#include "src/option-parser.h"
#include "src/resolve-names.h"