// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/wasm/wasm-interpreter.h"
#include "src/wasm/ast-decoder.h"
#include "src/wasm/decoder.h"
#include "src/wasm/wasm-external-refs.h"
#include "src/wasm/wasm-module.h"

#include "src/base/accounting-allocator.h"
#include "src/zone-containers.h"

namespace v8 {
namespace internal {
namespace wasm {

#if DEBUG
#define TRACE(...)                                        \
  do {                                                    \
    if (FLAG_trace_wasm_interpreter) PrintF(__VA_ARGS__); \
  } while (false)
#else
#define TRACE(...)
#endif

#define FOREACH_INTERNAL_OPCODE(V) V(Breakpoint, 0xFF)

#define FOREACH_SIMPLE_BINOP(V) \
  V(I32Add, uint32_t, +)        \
  V(I32Sub, uint32_t, -)        \
  V(I32Mul, uint32_t, *)        \
  V(I32And, uint32_t, &)        \
  V(I32Ior, uint32_t, |)        \
  V(I32Xor, uint32_t, ^)        \
  V(I32Eq, uint32_t, ==)        \
  V(I32Ne, uint32_t, !=)        \
  V(I32LtU, uint32_t, <)        \
  V(I32LeU, uint32_t, <=)       \
  V(I32GtU, uint32_t, >)        \
  V(I32GeU, uint32_t, >=)       \
  V(I32LtS, int32_t, <)         \
  V(I32LeS, int32_t, <=)        \
  V(I32GtS, int32_t, >)         \
  V(I32GeS, int32_t, >=)        \
  V(I64Add, uint64_t, +)        \
  V(I64Sub, uint64_t, -)        \
  V(I64Mul, uint64_t, *)        \
  V(I64And, uint64_t, &)        \
  V(I64Ior, uint64_t, |)        \
  V(I64Xor, uint64_t, ^)        \
  V(I64Eq, uint64_t, ==)        \
  V(I64Ne, uint64_t, !=)        \
  V(I64LtU, uint64_t, <)        \
  V(I64LeU, uint64_t, <=)       \
  V(I64GtU, uint64_t, >)        \
  V(I64GeU, uint64_t, >=)       \
  V(I64LtS, int64_t, <)         \
  V(I64LeS, int64_t, <=)        \
  V(I64GtS, int64_t, >)         \
  V(I64GeS, int64_t, >=)        \
  V(F32Add, float, +)           \
  V(F32Mul, float, *)           \
  V(F32Div, float, /)           \
  V(F32Eq, float, ==)           \
  V(F32Ne, float, !=)           \
  V(F32Lt, float, <)            \
  V(F32Le, float, <=)           \
  V(F32Gt, float, >)            \
  V(F32Ge, float, >=)           \
  V(F64Add, double, +)          \
  V(F64Mul, double, *)          \
  V(F64Div, double, /)          \
  V(F64Eq, double, ==)          \
  V(F64Ne, double, !=)          \
  V(F64Lt, double, <)           \
  V(F64Le, double, <=)          \
  V(F64Gt, double, >)           \
  V(F64Ge, double, >=)

#define FOREACH_OTHER_BINOP(V) \
  V(I32DivS, int32_t)          \
  V(I32DivU, uint32_t)         \
  V(I32RemS, int32_t)          \
  V(I32RemU, uint32_t)         \
  V(I32Shl, uint32_t)          \
  V(I32ShrU, uint32_t)         \
  V(I32ShrS, int32_t)          \
  V(I64DivS, int64_t)          \
  V(I64DivU, uint64_t)         \
  V(I64RemS, int64_t)          \
  V(I64RemU, uint64_t)         \
  V(I64Shl, uint64_t)          \
  V(I64ShrU, uint64_t)         \
  V(I64ShrS, int64_t)          \
  V(I32Ror, int32_t)           \
  V(I32Rol, int32_t)           \
  V(I64Ror, int64_t)           \
  V(I64Rol, int64_t)           \
  V(F32Sub, float)             \
  V(F32Min, float)             \
  V(F32Max, float)             \
  V(F32CopySign, float)        \
  V(F64Min, double)            \
  V(F64Max, double)            \
  V(F64Sub, double)            \
  V(F64CopySign, double)       \
  V(I32AsmjsDivS, int32_t)     \
  V(I32AsmjsDivU, uint32_t)    \
  V(I32AsmjsRemS, int32_t)     \
  V(I32AsmjsRemU, uint32_t)

#define FOREACH_OTHER_UNOP(V)    \
  V(I32Clz, uint32_t)            \
  V(I32Ctz, uint32_t)            \
  V(I32Popcnt, uint32_t)         \
  V(I32Eqz, uint32_t)            \
  V(I64Clz, uint64_t)            \
  V(I64Ctz, uint64_t)            \
  V(I64Popcnt, uint64_t)         \
  V(I64Eqz, uint64_t)            \
  V(F32Abs, float)               \
  V(F32Neg, float)               \
  V(F32Ceil, float)              \
  V(F32Floor, float)             \
  V(F32Trunc, float)             \
  V(F32NearestInt, float)        \
  V(F32Sqrt, float)              \
  V(F64Abs, double)              \
  V(F64Neg, double)              \
  V(F64Ceil, double)             \
  V(F64Floor, double)            \
  V(F64Trunc, double)            \
  V(F64NearestInt, double)       \
  V(F64Sqrt, double)             \
  V(I32SConvertF32, float)       \
  V(I32SConvertF64, double)      \
  V(I32UConvertF32, float)       \
  V(I32UConvertF64, double)      \
  V(I32ConvertI64, int64_t)      \
  V(I64SConvertF32, float)       \
  V(I64SConvertF64, double)      \
  V(I64UConvertF32, float)       \
  V(I64UConvertF64, double)      \
  V(I64SConvertI32, int32_t)     \
  V(I64UConvertI32, uint32_t)    \
  V(F32SConvertI32, int32_t)     \
  V(F32UConvertI32, uint32_t)    \
  V(F32SConvertI64, int64_t)     \
  V(F32UConvertI64, uint64_t)    \
  V(F32ConvertF64, double)       \
  V(F32ReinterpretI32, int32_t)  \
  V(F64SConvertI32, int32_t)     \
  V(F64UConvertI32, uint32_t)    \
  V(F64SConvertI64, int64_t)     \
  V(F64UConvertI64, uint64_t)    \
  V(F64ConvertF32, float)        \
  V(F64ReinterpretI64, int64_t)  \
  V(I32ReinterpretF32, float)    \
  V(I64ReinterpretF64, double)   \
  V(I32AsmjsSConvertF32, float)  \
  V(I32AsmjsUConvertF32, float)  \
  V(I32AsmjsSConvertF64, double) \
  V(I32AsmjsUConvertF64, double)

static inline int32_t ExecuteI32DivS(int32_t a, int32_t b, TrapReason* trap) {
  if (b == 0) {
    *trap = kTrapDivByZero;
    return 0;
  }
  if (b == -1 && a == std::numeric_limits<int32_t>::min()) {
    *trap = kTrapDivUnrepresentable;
    return 0;
  }
  return a / b;
}

static inline uint32_t ExecuteI32DivU(uint32_t a, uint32_t b,
                                      TrapReason* trap) {
  if (b == 0) {
    *trap = kTrapDivByZero;
    return 0;
  }
  return a / b;
}

static inline int32_t ExecuteI32RemS(int32_t a, int32_t b, TrapReason* trap) {
  if (b == 0) {
    *trap = kTrapRemByZero;
    return 0;
  }
  if (b == -1) return 0;
  return a % b;
}

static inline uint32_t ExecuteI32RemU(uint32_t a, uint32_t b,
                                      TrapReason* trap) {
  if (b == 0) {
    *trap = kTrapRemByZero;
    return 0;
  }
  return a % b;
}

static inline uint32_t ExecuteI32Shl(uint32_t a, uint32_t b, TrapReason* trap) {
  return a << (b & 0x1f);
}

static inline uint32_t ExecuteI32ShrU(uint32_t a, uint32_t b,
                                      TrapReason* trap) {
  return a >> (b & 0x1f);
}

static inline int32_t ExecuteI32ShrS(int32_t a, int32_t b, TrapReason* trap) {
  return a >> (b & 0x1f);
}

static inline int64_t ExecuteI64DivS(int64_t a, int64_t b, TrapReason* trap) {
  if (b == 0) {
    *trap = kTrapDivByZero;
    return 0;
  }
  if (b == -1 && a == std::numeric_limits<int64_t>::min()) {
    *trap = kTrapDivUnrepresentable;
    return 0;
  }
  return a / b;
}

static inline uint64_t ExecuteI64DivU(uint64_t a, uint64_t b,
                                      TrapReason* trap) {
  if (b == 0) {
    *trap = kTrapDivByZero;
    return 0;
  }
  return a / b;
}

static inline int64_t ExecuteI64RemS(int64_t a, int64_t b, TrapReason* trap) {
  if (b == 0) {
    *trap = kTrapRemByZero;
    return 0;
  }
  if (b == -1) return 0;
  return a % b;
}

static inline uint64_t ExecuteI64RemU(uint64_t a, uint64_t b,
                                      TrapReason* trap) {
  if (b == 0) {
    *trap = kTrapRemByZero;
    return 0;
  }
  return a % b;
}

static inline uint64_t ExecuteI64Shl(uint64_t a, uint64_t b, TrapReason* trap) {
  return a << (b & 0x3f);
}

static inline uint64_t ExecuteI64ShrU(uint64_t a, uint64_t b,
                                      TrapReason* trap) {
  return a >> (b & 0x3f);
}

static inline int64_t ExecuteI64ShrS(int64_t a, int64_t b, TrapReason* trap) {
  return a >> (b & 0x3f);
}

static inline uint32_t ExecuteI32Ror(uint32_t a, uint32_t b, TrapReason* trap) {
  uint32_t shift = (b & 0x1f);
  return (a >> shift) | (a << (32 - shift));
}

static inline uint32_t ExecuteI32Rol(uint32_t a, uint32_t b, TrapReason* trap) {
  uint32_t shift = (b & 0x1f);
  return (a << shift) | (a >> (32 - shift));
}

static inline uint64_t ExecuteI64Ror(uint64_t a, uint64_t b, TrapReason* trap) {
  uint32_t shift = (b & 0x3f);
  return (a >> shift) | (a << (64 - shift));
}

static inline uint64_t ExecuteI64Rol(uint64_t a, uint64_t b, TrapReason* trap) {
  uint32_t shift = (b & 0x3f);
  return (a << shift) | (a >> (64 - shift));
}

static float quiet(float a) {
  static const uint32_t kSignalingBit = 1 << 22;
  uint32_t q = bit_cast<uint32_t>(std::numeric_limits<float>::quiet_NaN());
  if ((q & kSignalingBit) != 0) {
    // On some machines, the signaling bit set indicates it's a quiet NaN.
    return bit_cast<float>(bit_cast<uint32_t>(a) | kSignalingBit);
  } else {
    // On others, the signaling bit set indicates it's a signaling NaN.
    return bit_cast<float>(bit_cast<uint32_t>(a) & ~kSignalingBit);
  }
}

static double quiet(double a) {
  static const uint64_t kSignalingBit = 1ULL << 51;
  uint64_t q = bit_cast<uint64_t>(std::numeric_limits<double>::quiet_NaN());
  if ((q & kSignalingBit) != 0) {
    // On some machines, the signaling bit set indicates it's a quiet NaN.
    return bit_cast<double>(bit_cast<uint64_t>(a) | kSignalingBit);
  } else {
    // On others, the signaling bit set indicates it's a signaling NaN.
    return bit_cast<double>(bit_cast<uint64_t>(a) & ~kSignalingBit);
  }
}

static inline float ExecuteF32Sub(float a, float b, TrapReason* trap) {
  float result = a - b;
  // Some architectures (e.g. MIPS) need extra checking to preserve the payload
  // of a NaN operand.
  if (result - result != 0) {
    if (std::isnan(a)) return quiet(a);
    if (std::isnan(b)) return quiet(b);
  }
  return result;
}

static inline float ExecuteF32Min(float a, float b, TrapReason* trap) {
  if (std::isnan(a)) return quiet(a);
  if (std::isnan(b)) return quiet(b);
  return std::min(a, b);
}

static inline float ExecuteF32Max(float a, float b, TrapReason* trap) {
  if (std::isnan(a)) return quiet(a);
  if (std::isnan(b)) return quiet(b);
  return std::max(a, b);
}

static inline float ExecuteF32CopySign(float a, float b, TrapReason* trap) {
  return copysignf(a, b);
}

static inline double ExecuteF64Sub(double a, double b, TrapReason* trap) {
  double result = a - b;
  // Some architectures (e.g. MIPS) need extra checking to preserve the payload
  // of a NaN operand.
  if (result - result != 0) {
    if (std::isnan(a)) return quiet(a);
    if (std::isnan(b)) return quiet(b);
  }
  return result;
}

static inline double ExecuteF64Min(double a, double b, TrapReason* trap) {
  if (std::isnan(a)) return quiet(a);
  if (std::isnan(b)) return quiet(b);
  return std::min(a, b);
}

static inline double ExecuteF64Max(double a, double b, TrapReason* trap) {
  if (std::isnan(a)) return quiet(a);
  if (std::isnan(b)) return quiet(b);
  return std::max(a, b);
}

static inline double ExecuteF64CopySign(double a, double b, TrapReason* trap) {
  return copysign(a, b);
}

static inline int32_t ExecuteI32AsmjsDivS(int32_t a, int32_t b,
                                          TrapReason* trap) {
  if (b == 0) return 0;
  if (b == -1 && a == std::numeric_limits<int32_t>::min()) {
    return std::numeric_limits<int32_t>::min();
  }
  return a / b;
}

static inline uint32_t ExecuteI32AsmjsDivU(uint32_t a, uint32_t b,
                                           TrapReason* trap) {
  if (b == 0) return 0;
  return a / b;
}

static inline int32_t ExecuteI32AsmjsRemS(int32_t a, int32_t b,
                                          TrapReason* trap) {
  if (b == 0) return 0;
  if (b == -1) return 0;
  return a % b;
}

static inline uint32_t ExecuteI32AsmjsRemU(uint32_t a, uint32_t b,
                                           TrapReason* trap) {
  if (b == 0) return 0;
  return a % b;
}

static inline int32_t ExecuteI32AsmjsSConvertF32(float a, TrapReason* trap) {
  return DoubleToInt32(a);
}

static inline uint32_t ExecuteI32AsmjsUConvertF32(float a, TrapReason* trap) {
  return DoubleToUint32(a);
}

static inline int32_t ExecuteI32AsmjsSConvertF64(double a, TrapReason* trap) {
  return DoubleToInt32(a);
}

static inline uint32_t ExecuteI32AsmjsUConvertF64(double a, TrapReason* trap) {
  return DoubleToUint32(a);
}

static int32_t ExecuteI32Clz(uint32_t val, TrapReason* trap) {
  return base::bits::CountLeadingZeros32(val);
}

static uint32_t ExecuteI32Ctz(uint32_t val, TrapReason* trap) {
  return base::bits::CountTrailingZeros32(val);
}

static uint32_t ExecuteI32Popcnt(uint32_t val, TrapReason* trap) {
  return word32_popcnt_wrapper(&val);
}

static inline uint32_t ExecuteI32Eqz(uint32_t val, TrapReason* trap) {
  return val == 0 ? 1 : 0;
}

static int64_t ExecuteI64Clz(uint64_t val, TrapReason* trap) {
  return base::bits::CountLeadingZeros64(val);
}

static inline uint64_t ExecuteI64Ctz(uint64_t val, TrapReason* trap) {
  return base::bits::CountTrailingZeros64(val);
}

static inline int64_t ExecuteI64Popcnt(uint64_t val, TrapReason* trap) {
  return word64_popcnt_wrapper(&val);
}

static inline int32_t ExecuteI64Eqz(uint64_t val, TrapReason* trap) {
  return val == 0 ? 1 : 0;
}

static inline float ExecuteF32Abs(float a, TrapReason* trap) {
  return bit_cast<float>(bit_cast<uint32_t>(a) & 0x7fffffff);
}

static inline float ExecuteF32Neg(float a, TrapReason* trap) {
  return bit_cast<float>(bit_cast<uint32_t>(a) ^ 0x80000000);
}

static inline float ExecuteF32Ceil(float a, TrapReason* trap) {
  return ceilf(a);
}

static inline float ExecuteF32Floor(float a, TrapReason* trap) {
  return floorf(a);
}

static inline float ExecuteF32Trunc(float a, TrapReason* trap) {
  return truncf(a);
}

static inline float ExecuteF32NearestInt(float a, TrapReason* trap) {
  return nearbyintf(a);
}

static inline float ExecuteF32Sqrt(float a, TrapReason* trap) {
  return sqrtf(a);
}

static inline double ExecuteF64Abs(double a, TrapReason* trap) {
  return bit_cast<double>(bit_cast<uint64_t>(a) & 0x7fffffffffffffff);
}

static inline double ExecuteF64Neg(double a, TrapReason* trap) {
  return bit_cast<double>(bit_cast<uint64_t>(a) ^ 0x8000000000000000);
}

static inline double ExecuteF64Ceil(double a, TrapReason* trap) {
  return ceil(a);
}

static inline double ExecuteF64Floor(double a, TrapReason* trap) {
  return floor(a);
}

static inline double ExecuteF64Trunc(double a, TrapReason* trap) {
  return trunc(a);
}

static inline double ExecuteF64NearestInt(double a, TrapReason* trap) {
  return nearbyint(a);
}

static inline double ExecuteF64Sqrt(double a, TrapReason* trap) {
  return sqrt(a);
}

static int32_t ExecuteI32SConvertF32(float a, TrapReason* trap) {
  if (a < static_cast<float>(INT32_MAX) && a >= static_cast<float>(INT32_MIN)) {
    return static_cast<int32_t>(a);
  }
  *trap = kTrapFloatUnrepresentable;
  return 0;
}

static int32_t ExecuteI32SConvertF64(double a, TrapReason* trap) {
  if (a < (static_cast<double>(INT32_MAX) + 1.0) &&
      a > (static_cast<double>(INT32_MIN) - 1.0)) {
    return static_cast<int32_t>(a);
  }
  *trap = kTrapFloatUnrepresentable;
  return 0;
}

static uint32_t ExecuteI32UConvertF32(float a, TrapReason* trap) {
  if (a < (static_cast<float>(UINT32_MAX) + 1.0) && a > -1) {
    return static_cast<uint32_t>(a);
  }
  *trap = kTrapFloatUnrepresentable;
  return 0;
}

static uint32_t ExecuteI32UConvertF64(double a, TrapReason* trap) {
  if (a < (static_cast<float>(UINT32_MAX) + 1.0) && a > -1) {
    return static_cast<uint32_t>(a);
  }
  *trap = kTrapFloatUnrepresentable;
  return 0;
}

static inline uint32_t ExecuteI32ConvertI64(int64_t a, TrapReason* trap) {
  return static_cast<uint32_t>(a & 0xFFFFFFFF);
}

static int64_t ExecuteI64SConvertF32(float a, TrapReason* trap) {
  int64_t output;
  if (!float32_to_int64_wrapper(&a, &output)) {
    *trap = kTrapFloatUnrepresentable;
  }
  return output;
}

static int64_t ExecuteI64SConvertF64(double a, TrapReason* trap) {
  int64_t output;
  if (!float64_to_int64_wrapper(&a, &output)) {
    *trap = kTrapFloatUnrepresentable;
  }
  return output;
}

static uint64_t ExecuteI64UConvertF32(float a, TrapReason* trap) {
  uint64_t output;
  if (!float32_to_uint64_wrapper(&a, &output)) {
    *trap = kTrapFloatUnrepresentable;
  }
  return output;
}

static uint64_t ExecuteI64UConvertF64(double a, TrapReason* trap) {
  uint64_t output;
  if (!float64_to_uint64_wrapper(&a, &output)) {
    *trap = kTrapFloatUnrepresentable;
  }
  return output;
}

static inline int64_t ExecuteI64SConvertI32(int32_t a, TrapReason* trap) {
  return static_cast<int64_t>(a);
}

static inline int64_t ExecuteI64UConvertI32(uint32_t a, TrapReason* trap) {
  return static_cast<uint64_t>(a);
}

static inline float ExecuteF32SConvertI32(int32_t a, TrapReason* trap) {
  return static_cast<float>(a);
}

static inline float ExecuteF32UConvertI32(uint32_t a, TrapReason* trap) {
  return static_cast<float>(a);
}

static inline float ExecuteF32SConvertI64(int64_t a, TrapReason* trap) {
  float output;
  int64_to_float32_wrapper(&a, &output);
  return output;
}

static inline float ExecuteF32UConvertI64(uint64_t a, TrapReason* trap) {
  float output;
  uint64_to_float32_wrapper(&a, &output);
  return output;
}

static inline float ExecuteF32ConvertF64(double a, TrapReason* trap) {
  return static_cast<float>(a);
}

static inline float ExecuteF32ReinterpretI32(int32_t a, TrapReason* trap) {
  return bit_cast<float>(a);
}

static inline double ExecuteF64SConvertI32(int32_t a, TrapReason* trap) {
  return static_cast<double>(a);
}

static inline double ExecuteF64UConvertI32(uint32_t a, TrapReason* trap) {
  return static_cast<double>(a);
}

static inline double ExecuteF64SConvertI64(int64_t a, TrapReason* trap) {
  double output;
  int64_to_float64_wrapper(&a, &output);
  return output;
}

static inline double ExecuteF64UConvertI64(uint64_t a, TrapReason* trap) {
  double output;
  uint64_to_float64_wrapper(&a, &output);
  return output;
}

static inline double ExecuteF64ConvertF32(float a, TrapReason* trap) {
  return static_cast<double>(a);
}

static inline double ExecuteF64ReinterpretI64(int64_t a, TrapReason* trap) {
  return bit_cast<double>(a);
}

static inline int32_t ExecuteI32ReinterpretF32(float a, TrapReason* trap) {
  return bit_cast<int32_t>(a);
}

static inline int64_t ExecuteI64ReinterpretF64(double a, TrapReason* trap) {
  return bit_cast<int64_t>(a);
}

enum InternalOpcode {
#define DECL_INTERNAL_ENUM(name, value) kInternal##name = value,
  FOREACH_INTERNAL_OPCODE(DECL_INTERNAL_ENUM)
#undef DECL_INTERNAL_ENUM
};

static const char* OpcodeName(uint32_t val) {
  switch (val) {
#define DECL_INTERNAL_CASE(name, value) \
  case kInternal##name:                 \
    return "Internal" #name;
    FOREACH_INTERNAL_OPCODE(DECL_INTERNAL_CASE)
#undef DECL_INTERNAL_CASE
  }
  return WasmOpcodes::OpcodeName(static_cast<WasmOpcode>(val));
}

static const int kRunSteps = 1000;

// A helper class to compute the control transfers for each bytecode offset.
// Control transfers allow Br, BrIf, BrTable, If, Else, and End bytecodes to
// be directly executed without the need to dynamically track blocks.
class ControlTransfers : public ZoneObject {
 public:
  ControlTransferMap map_;

  ControlTransfers(Zone* zone, size_t locals_encoded_size, const byte* start,
                   const byte* end)
      : map_(zone) {
    // A control reference including from PC, from value depth, and whether
    // a value is explicitly passed (e.g. br/br_if/br_table with value).
    struct CRef {
      const byte* pc;
      sp_t value_depth;
      bool explicit_value;
    };

    // Represents a control flow label.
    struct CLabel : public ZoneObject {
      const byte* target;
      size_t value_depth;
      ZoneVector<CRef> refs;

      CLabel(Zone* zone, size_t v)
          : target(nullptr), value_depth(v), refs(zone) {}

      // Bind this label to the given PC.
      void Bind(ControlTransferMap* map, const byte* start, const byte* pc,
                bool expect_value) {
        DCHECK_NULL(target);
        target = pc;
        for (auto from : refs) {
          auto pcdiff = static_cast<pcdiff_t>(target - from.pc);
          auto spdiff = static_cast<spdiff_t>(from.value_depth - value_depth);
          ControlTransfer::StackAction action = ControlTransfer::kNoAction;
          if (expect_value && !from.explicit_value) {
            action = spdiff == 0 ? ControlTransfer::kPushVoid
                                 : ControlTransfer::kPopAndRepush;
          }
          pc_t offset = static_cast<size_t>(from.pc - start);
          (*map)[offset] = {pcdiff, spdiff, action};
        }
      }

      // Reference this label from the given location.
      void Ref(ControlTransferMap* map, const byte* start, CRef from) {
        DCHECK_GE(from.value_depth, value_depth);
        if (target) {
          auto pcdiff = static_cast<pcdiff_t>(target - from.pc);
          auto spdiff = static_cast<spdiff_t>(from.value_depth - value_depth);
          pc_t offset = static_cast<size_t>(from.pc - start);
          (*map)[offset] = {pcdiff, spdiff, ControlTransfer::kNoAction};
        } else {
          refs.push_back(from);
        }
      }
    };

    // An entry in the control stack.
    struct Control {
      const byte* pc;
      CLabel* end_label;
      CLabel* else_label;

      void Ref(ControlTransferMap* map, const byte* start, const byte* from_pc,
               size_t from_value_depth, bool explicit_value) {
        end_label->Ref(map, start, {from_pc, from_value_depth, explicit_value});
      }
    };

    // Compute the ControlTransfer map.
    // This works by maintaining a stack of control constructs similar to the
    // AST decoder. The {control_stack} allows matching {br,br_if,br_table}
    // bytecodes with their target, as well as determining whether the current
    // bytecodes are within the true or false block of an else.
    // The value stack depth is tracked as {value_depth} and is needed to
    // determine how many values to pop off the stack for explicit and
    // implicit control flow.

    std::vector<Control> control_stack;
    size_t value_depth = 0;
    Decoder decoder(start, end);  // for reading operands.
    const byte* pc = start + locals_encoded_size;

    while (pc < end) {
      WasmOpcode opcode = static_cast<WasmOpcode>(*pc);
      TRACE("@%td: control %s (depth = %zu)\n", (pc - start),
            WasmOpcodes::OpcodeName(opcode), value_depth);
      switch (opcode) {
        case kExprBlock: {
          TRACE("control @%td $%zu: Block\n", (pc - start), value_depth);
          CLabel* label = new (zone) CLabel(zone, value_depth);
          control_stack.push_back({pc, label, nullptr});
          break;
        }
        case kExprLoop: {
          TRACE("control @%td $%zu: Loop\n", (pc - start), value_depth);
          CLabel* label1 = new (zone) CLabel(zone, value_depth);
          CLabel* label2 = new (zone) CLabel(zone, value_depth);
          control_stack.push_back({pc, label1, nullptr});
          control_stack.push_back({pc, label2, nullptr});
          label2->Bind(&map_, start, pc, false);
          break;
        }
        case kExprIf: {
          TRACE("control @%td $%zu: If\n", (pc - start), value_depth);
          value_depth--;
          CLabel* end_label = new (zone) CLabel(zone, value_depth);
          CLabel* else_label = new (zone) CLabel(zone, value_depth);
          control_stack.push_back({pc, end_label, else_label});
          else_label->Ref(&map_, start, {pc, value_depth, false});
          break;
        }
        case kExprElse: {
          Control* c = &control_stack.back();
          TRACE("control @%td $%zu: Else\n", (pc - start), value_depth);
          c->end_label->Ref(&map_, start, {pc, value_depth, false});
          value_depth = c->end_label->value_depth;
          DCHECK_NOT_NULL(c->else_label);
          c->else_label->Bind(&map_, start, pc + 1, false);
          c->else_label = nullptr;
          break;
        }
        case kExprEnd: {
          Control* c = &control_stack.back();
          TRACE("control @%td $%zu: End\n", (pc - start), value_depth);
          if (c->end_label->target) {
            // only loops have bound labels.
            DCHECK_EQ(kExprLoop, *c->pc);
            control_stack.pop_back();
            c = &control_stack.back();
          }
          if (c->else_label) c->else_label->Bind(&map_, start, pc + 1, true);
          c->end_label->Ref(&map_, start, {pc, value_depth, false});
          c->end_label->Bind(&map_, start, pc + 1, true);
          value_depth = c->end_label->value_depth + 1;
          control_stack.pop_back();
          break;
        }
        case kExprBr: {
          BreakDepthOperand operand(&decoder, pc);
          TRACE("control @%td $%zu: Br[arity=%u, depth=%u]\n", (pc - start),
                value_depth, operand.arity, operand.depth);
          value_depth -= operand.arity;
          control_stack[control_stack.size() - operand.depth - 1].Ref(
              &map_, start, pc, value_depth, operand.arity > 0);
          value_depth++;
          break;
        }
        case kExprBrIf: {
          BreakDepthOperand operand(&decoder, pc);
          TRACE("control @%td $%zu: BrIf[arity=%u, depth=%u]\n", (pc - start),
                value_depth, operand.arity, operand.depth);
          value_depth -= (operand.arity + 1);
          control_stack[control_stack.size() - operand.depth - 1].Ref(
              &map_, start, pc, value_depth, operand.arity > 0);
          value_depth++;
          break;
        }
        case kExprBrTable: {
          BranchTableOperand operand(&decoder, pc);
          TRACE("control @%td $%zu: BrTable[arity=%u count=%u]\n", (pc - start),
                value_depth, operand.arity, operand.table_count);
          value_depth -= (operand.arity + 1);
          for (uint32_t i = 0; i < operand.table_count + 1; ++i) {
            uint32_t target = operand.read_entry(&decoder, i);
            control_stack[control_stack.size() - target - 1].Ref(
                &map_, start, pc + i, value_depth, operand.arity > 0);
          }
          value_depth++;
          break;
        }
        default: {
          value_depth = value_depth - OpcodeArity(pc, end) + 1;
          break;
        }
      }

      pc += OpcodeLength(pc, end);
    }
  }

  ControlTransfer Lookup(pc_t from) {
    auto result = map_.find(from);
    if (result == map_.end()) {
      V8_Fatal(__FILE__, __LINE__, "no control target for pc %zu", from);
    }
    return result->second;
  }
};

// Code and metadata needed to execute a function.
struct InterpreterCode {
  const WasmFunction* function;  // wasm function
  AstLocalDecls locals;          // local declarations
  const byte* orig_start;        // start of original code
  const byte* orig_end;          // end of original code
  byte* start;                   // start of (maybe altered) code
  byte* end;                     // end of (maybe altered) code
  ControlTransfers* targets;     // helper for control flow.

  const byte* at(pc_t pc) { return start + pc; }
};

// The main storage for interpreter code. It maps {WasmFunction} to the
// metadata needed to execute each function.
class CodeMap {
 public:
  Zone* zone_;
  const WasmModule* module_;
  ZoneVector<InterpreterCode> interpreter_code_;

  CodeMap(const WasmModule* module, Zone* zone)
      : zone_(zone), module_(module), interpreter_code_(zone) {
    if (module == nullptr) return;
    for (size_t i = 0; i < module->functions.size(); ++i) {
      const WasmFunction* function = &module->functions[i];
      const byte* code_start =
          module->module_start + function->code_start_offset;
      const byte* code_end = module->module_start + function->code_end_offset;
      AddFunction(function, code_start, code_end);
    }
  }

  InterpreterCode* FindCode(const WasmFunction* function) {
    if (function->func_index < interpreter_code_.size()) {
      InterpreterCode* code = &interpreter_code_[function->func_index];
      DCHECK_EQ(function, code->function);
      return code;
    }
    return nullptr;
  }

  InterpreterCode* GetCode(uint32_t function_index) {
    CHECK_LT(function_index, interpreter_code_.size());
    return Preprocess(&interpreter_code_[function_index]);
  }

  InterpreterCode* GetIndirectCode(uint32_t indirect_index) {
    if (indirect_index >= module_->function_table.size()) return nullptr;
    uint32_t index = module_->function_table[indirect_index];
    if (index >= interpreter_code_.size()) return nullptr;
    return GetCode(index);
  }

  InterpreterCode* Preprocess(InterpreterCode* code) {
    if (code->targets == nullptr && code->start) {
      // Compute the control targets map and the local declarations.
      CHECK(DecodeLocalDecls(code->locals, code->start, code->end));
      code->targets =
          new (zone_) ControlTransfers(zone_, code->locals.decls_encoded_size,
                                       code->orig_start, code->orig_end);
    }
    return code;
  }

  int AddFunction(const WasmFunction* function, const byte* code_start,
                  const byte* code_end) {
    InterpreterCode code = {
        function, AstLocalDecls(zone_),          code_start,
        code_end, const_cast<byte*>(code_start), const_cast<byte*>(code_end),
        nullptr};

    DCHECK_EQ(interpreter_code_.size(), function->func_index);
    interpreter_code_.push_back(code);
    return static_cast<int>(interpreter_code_.size()) - 1;
  }

  bool SetFunctionCode(const WasmFunction* function, const byte* start,
                       const byte* end) {
    InterpreterCode* code = FindCode(function);
    if (code == nullptr) return false;
    code->targets = nullptr;
    code->orig_start = start;
    code->orig_end = end;
    code->start = const_cast<byte*>(start);
    code->end = const_cast<byte*>(end);
    Preprocess(code);
    return true;
  }
};

// Responsible for executing code directly.
class ThreadImpl : public WasmInterpreter::Thread {
 public:
  ThreadImpl(Zone* zone, CodeMap* codemap, WasmModuleInstance* instance)
      : codemap_(codemap),
        instance_(instance),
        stack_(zone),
        frames_(zone),
        state_(WasmInterpreter::STOPPED),
        break_pc_(kInvalidPc),
        trap_reason_(kTrapCount) {}

  virtual ~ThreadImpl() {}

  //==========================================================================
  // Implementation of public interface for WasmInterpreter::Thread.
  //==========================================================================

  virtual WasmInterpreter::State state() { return state_; }

  virtual void PushFrame(const WasmFunction* function, WasmVal* args) {
    InterpreterCode* code = codemap()->FindCode(function);
    CHECK_NOT_NULL(code);
    frames_.push_back({code, 0, 0, stack_.size()});
    for (size_t i = 0; i < function->sig->parameter_count(); ++i) {
      stack_.push_back(args[i]);
    }
    frames_.back().ret_pc = InitLocals(code);
    TRACE("  => PushFrame(#%u @%zu)\n", code->function->func_index,
          frames_.back().ret_pc);
  }

  virtual WasmInterpreter::State Run() {
    do {
      TRACE("  => Run()\n");
      if (state_ == WasmInterpreter::STOPPED ||
          state_ == WasmInterpreter::PAUSED) {
        state_ = WasmInterpreter::RUNNING;
        Execute(frames_.back().code, frames_.back().ret_pc, kRunSteps);
      }
    } while (state_ == WasmInterpreter::STOPPED);
    return state_;
  }

  virtual WasmInterpreter::State Step() {
    TRACE("  => Step()\n");
    if (state_ == WasmInterpreter::STOPPED ||
        state_ == WasmInterpreter::PAUSED) {
      state_ = WasmInterpreter::RUNNING;
      Execute(frames_.back().code, frames_.back().ret_pc, 1);
    }
    return state_;
  }

  virtual void Pause() { UNIMPLEMENTED(); }

  virtual void Reset() {
    TRACE("----- RESET -----\n");
    stack_.clear();
    frames_.clear();
    state_ = WasmInterpreter::STOPPED;
    trap_reason_ = kTrapCount;
  }

  virtual int GetFrameCount() { return static_cast<int>(frames_.size()); }

  virtual const WasmFrame* GetFrame(int index) {
    UNIMPLEMENTED();
    return nullptr;
  }

  virtual WasmFrame* GetMutableFrame(int index) {
    UNIMPLEMENTED();
    return nullptr;
  }

  virtual WasmVal GetReturnValue() {
    if (state_ == WasmInterpreter::TRAPPED) return WasmVal(0xdeadbeef);
    CHECK_EQ(WasmInterpreter::FINISHED, state_);
    CHECK_EQ(1, stack_.size());
    return stack_[0];
  }

  virtual pc_t GetBreakpointPc() { return break_pc_; }

  bool Terminated() {
    return state_ == WasmInterpreter::TRAPPED ||
           state_ == WasmInterpreter::FINISHED;
  }

 private:
  // Entries on the stack of functions being evaluated.
  struct Frame {
    InterpreterCode* code;
    pc_t call_pc;
    pc_t ret_pc;
    sp_t sp;

    // Limit of parameters.
    sp_t plimit() { return sp + code->function->sig->parameter_count(); }
    // Limit of locals.
    sp_t llimit() { return plimit() + code->locals.total_local_count; }
  };

  CodeMap* codemap_;
  WasmModuleInstance* instance_;
  ZoneVector<WasmVal> stack_;
  ZoneVector<Frame> frames_;
  WasmInterpreter::State state_;
  pc_t break_pc_;
  TrapReason trap_reason_;

  CodeMap* codemap() { return codemap_; }
  WasmModuleInstance* instance() { return instance_; }
  const WasmModule* module() { return instance_->module; }

  void DoTrap(TrapReason trap, pc_t pc) {
    state_ = WasmInterpreter::TRAPPED;
    trap_reason_ = trap;
    CommitPc(pc);
  }

  // Push a frame with arguments already on the stack.
  void PushFrame(InterpreterCode* code, pc_t call_pc, pc_t ret_pc) {
    CHECK_NOT_NULL(code);
    DCHECK(!frames_.empty());
    frames_.back().call_pc = call_pc;
    frames_.back().ret_pc = ret_pc;
    size_t arity = code->function->sig->parameter_count();
    DCHECK_GE(stack_.size(), arity);
    // The parameters will overlap the arguments already on the stack.
    frames_.push_back({code, 0, 0, stack_.size() - arity});
    frames_.back().ret_pc = InitLocals(code);
    TRACE("  => push func#%u @%zu\n", code->function->func_index,
          frames_.back().ret_pc);
  }

  pc_t InitLocals(InterpreterCode* code) {
    for (auto p : code->locals.local_types) {
      WasmVal val;
      switch (p.first) {
        case kAstI32:
          val = WasmVal(static_cast<int32_t>(0));
          break;
        case kAstI64:
          val = WasmVal(static_cast<int64_t>(0));
          break;
        case kAstF32:
          val = WasmVal(static_cast<float>(0));
          break;
        case kAstF64:
          val = WasmVal(static_cast<double>(0));
          break;
        default:
          UNREACHABLE();
          break;
      }
      stack_.insert(stack_.end(), p.second, val);
    }
    return code->locals.decls_encoded_size;
  }

  void CommitPc(pc_t pc) {
    if (!frames_.empty()) {
      frames_.back().ret_pc = pc;
    }
  }

  bool SkipBreakpoint(InterpreterCode* code, pc_t pc) {
    if (pc == break_pc_) {
      break_pc_ = kInvalidPc;
      return true;
    }
    return false;
  }

  bool DoReturn(InterpreterCode** code, pc_t* pc, pc_t* limit, WasmVal val) {
    DCHECK_GT(frames_.size(), 0u);
    stack_.resize(frames_.back().sp);
    frames_.pop_back();
    if (frames_.size() == 0) {
      // A return from the top frame terminates the execution.
      state_ = WasmInterpreter::FINISHED;
      stack_.clear();
      stack_.push_back(val);
      TRACE("  => finish\n");
      return false;
    } else {
      // Return to caller frame.
      Frame* top = &frames_.back();
      *code = top->code;
      *pc = top->ret_pc;
      *limit = top->code->end - top->code->start;
      if (top->code->start[top->call_pc] == kExprCallIndirect ||
          (top->code->orig_start &&
           top->code->orig_start[top->call_pc] == kExprCallIndirect)) {
        // UGLY: An indirect call has the additional function index on the
        // stack.
        stack_.pop_back();
      }
      TRACE("  => pop func#%u @%zu\n", (*code)->function->func_index, *pc);

      stack_.push_back(val);
      return true;
    }
  }

  void DoCall(InterpreterCode* target, pc_t* pc, pc_t ret_pc, pc_t* limit) {
    PushFrame(target, *pc, ret_pc);
    *pc = frames_.back().ret_pc;
    *limit = target->end - target->start;
  }

  // Adjust the program counter {pc} and the stack contents according to the
  // code's precomputed control transfer map. Returns the different between
  // the new pc and the old pc.
  int DoControlTransfer(InterpreterCode* code, pc_t pc) {
    auto target = code->targets->Lookup(pc);
    switch (target.action) {
      case ControlTransfer::kNoAction:
        TRACE("  action [sp-%u]\n", target.spdiff);
        PopN(target.spdiff);
        break;
      case ControlTransfer::kPopAndRepush: {
        WasmVal val = Pop();
        TRACE("  action [pop x, sp-%u, push x]\n", target.spdiff - 1);
        DCHECK_GE(target.spdiff, 1u);
        PopN(target.spdiff - 1);
        Push(pc, val);
        break;
      }
      case ControlTransfer::kPushVoid:
        TRACE("  action [sp-%u, push void]\n", target.spdiff);
        PopN(target.spdiff);
        Push(pc, WasmVal());
        break;
    }
    return target.pcdiff;
  }

  void Execute(InterpreterCode* code, pc_t pc, int max) {
    Decoder decoder(code->start, code->end);
    pc_t limit = code->end - code->start;
    while (true) {
      if (max-- <= 0) {
        // Maximum number of instructions reached.
        state_ = WasmInterpreter::PAUSED;
        return CommitPc(pc);
      }

      if (pc >= limit) {
        // Fell off end of code; do an implicit return.
        TRACE("@%-3zu: ImplicitReturn\n", pc);
        WasmVal val = PopArity(code->function->sig->return_count());
        if (!DoReturn(&code, &pc, &limit, val)) return;
        decoder.Reset(code->start, code->end);
        continue;
      }

      const char* skip = "        ";
      int len = 1;
      byte opcode = code->start[pc];
      byte orig = opcode;
      if (opcode == kInternalBreakpoint) {
        orig = code->orig_start[pc];
        if (SkipBreakpoint(code, pc)) {
          // skip breakpoint by switching on original code.
          skip = "[skip]  ";
        } else {
          state_ = WasmInterpreter::PAUSED;
          TRACE("@%-3zu: [break] %-24s:", pc,
                WasmOpcodes::OpcodeName(static_cast<WasmOpcode>(orig)));
          TraceValueStack();
          TRACE("\n");
          break_pc_ = pc;
          return CommitPc(pc);
        }
      }

      USE(skip);
      TRACE("@%-3zu: %s%-24s:", pc, skip,
            WasmOpcodes::OpcodeName(static_cast<WasmOpcode>(orig)));
      TraceValueStack();
      TRACE("\n");

      switch (orig) {
        case kExprNop:
          Push(pc, WasmVal());
          break;
        case kExprBlock:
        case kExprLoop: {
          // Do nothing.
          break;
        }
        case kExprIf: {
          WasmVal cond = Pop();
          bool is_true = cond.to<uint32_t>() != 0;
          if (is_true) {
            // fall through to the true block.
            TRACE("  true => fallthrough\n");
          } else {
            len = DoControlTransfer(code, pc);
            TRACE("  false => @%zu\n", pc + len);
          }
          break;
        }
        case kExprElse: {
          len = DoControlTransfer(code, pc);
          TRACE("  end => @%zu\n", pc + len);
          break;
        }
        case kExprSelect: {
          WasmVal cond = Pop();
          WasmVal fval = Pop();
          WasmVal tval = Pop();
          Push(pc, cond.to<int32_t>() != 0 ? tval : fval);
          break;
        }
        case kExprBr: {
          BreakDepthOperand operand(&decoder, code->at(pc));
          WasmVal val = PopArity(operand.arity);
          len = DoControlTransfer(code, pc);
          TRACE("  br => @%zu\n", pc + len);
          if (operand.arity > 0) Push(pc, val);
          break;
        }
        case kExprBrIf: {
          BreakDepthOperand operand(&decoder, code->at(pc));
          WasmVal cond = Pop();
          WasmVal val = PopArity(operand.arity);
          bool is_true = cond.to<uint32_t>() != 0;
          if (is_true) {
            len = DoControlTransfer(code, pc);
            TRACE("  br_if => @%zu\n", pc + len);
            if (operand.arity > 0) Push(pc, val);
          } else {
            TRACE("  false => fallthrough\n");
            len = 1 + operand.length;
            Push(pc, WasmVal());
          }
          break;
        }
        case kExprBrTable: {
          BranchTableOperand operand(&decoder, code->at(pc));
          uint32_t key = Pop().to<uint32_t>();
          WasmVal val = PopArity(operand.arity);
          if (key >= operand.table_count) key = operand.table_count;
          len = DoControlTransfer(code, pc + key) + key;
          TRACE("  br[%u] => @%zu\n", key, pc + len);
          if (operand.arity > 0) Push(pc, val);
          break;
        }
        case kExprReturn: {
          ReturnArityOperand operand(&decoder, code->at(pc));
          WasmVal val = PopArity(operand.arity);
          if (!DoReturn(&code, &pc, &limit, val)) return;
          decoder.Reset(code->start, code->end);
          continue;
        }
        case kExprUnreachable: {
          DoTrap(kTrapUnreachable, pc);
          return CommitPc(pc);
        }
        case kExprEnd: {
          len = DoControlTransfer(code, pc);
          DCHECK_EQ(1, len);
          break;
        }
        case kExprI8Const: {
          ImmI8Operand operand(&decoder, code->at(pc));
          Push(pc, WasmVal(operand.value));
          len = 1 + operand.length;
          break;
        }
        case kExprI32Const: {
          ImmI32Operand operand(&decoder, code->at(pc));
          Push(pc, WasmVal(operand.value));
          len = 1 + operand.length;
          break;
        }
        case kExprI64Const: {
          ImmI64Operand operand(&decoder, code->at(pc));
          Push(pc, WasmVal(operand.value));
          len = 1 + operand.length;
          break;
        }
        case kExprF32Const: {
          ImmF32Operand operand(&decoder, code->at(pc));
          Push(pc, WasmVal(operand.value));
          len = 1 + operand.length;
          break;
        }
        case kExprF64Const: {
          ImmF64Operand operand(&decoder, code->at(pc));
          Push(pc, WasmVal(operand.value));
          len = 1 + operand.length;
          break;
        }
        case kExprGetLocal: {
          LocalIndexOperand operand(&decoder, code->at(pc));
          Push(pc, stack_[frames_.back().sp + operand.index]);
          len = 1 + operand.length;
          break;
        }
        case kExprSetLocal: {
          LocalIndexOperand operand(&decoder, code->at(pc));
          WasmVal val = Pop();
          stack_[frames_.back().sp + operand.index] = val;
          Push(pc, val);
          len = 1 + operand.length;
          break;
        }
        case kExprCallFunction: {
          CallFunctionOperand operand(&decoder, code->at(pc));
          InterpreterCode* target = codemap()->GetCode(operand.index);
          DoCall(target, &pc, pc + 1 + operand.length, &limit);
          code = target;
          decoder.Reset(code->start, code->end);
          continue;
        }
        case kExprCallIndirect: {
          CallIndirectOperand operand(&decoder, code->at(pc));
          size_t index = stack_.size() - operand.arity - 1;
          DCHECK_LT(index, stack_.size());
          uint32_t table_index = stack_[index].to<uint32_t>();
          if (table_index >= module()->function_table.size()) {
            return DoTrap(kTrapFuncInvalid, pc);
          }
          uint16_t function_index = module()->function_table[table_index];
          InterpreterCode* target = codemap()->GetCode(function_index);
          DCHECK(target);
          if (target->function->sig_index != operand.index) {
            return DoTrap(kTrapFuncSigMismatch, pc);
          }

          DoCall(target, &pc, pc + 1 + operand.length, &limit);
          code = target;
          decoder.Reset(code->start, code->end);
          continue;
        }
        case kExprCallImport: {
          UNIMPLEMENTED();
          break;
        }
        case kExprLoadGlobal: {
          GlobalIndexOperand operand(&decoder, code->at(pc));
          const WasmGlobal* global = &module()->globals[operand.index];
          byte* ptr = instance()->globals_start + global->offset;
          MachineType type = global->type;
          WasmVal val;
          if (type == MachineType::Int8()) {
            val =
                WasmVal(static_cast<int32_t>(*reinterpret_cast<int8_t*>(ptr)));
          } else if (type == MachineType::Uint8()) {
            val =
                WasmVal(static_cast<int32_t>(*reinterpret_cast<uint8_t*>(ptr)));
          } else if (type == MachineType::Int16()) {
            val =
                WasmVal(static_cast<int32_t>(*reinterpret_cast<int16_t*>(ptr)));
          } else if (type == MachineType::Uint16()) {
            val = WasmVal(
                static_cast<int32_t>(*reinterpret_cast<uint16_t*>(ptr)));
          } else if (type == MachineType::Int32()) {
            val = WasmVal(*reinterpret_cast<int32_t*>(ptr));
          } else if (type == MachineType::Uint32()) {
            val = WasmVal(*reinterpret_cast<uint32_t*>(ptr));
          } else if (type == MachineType::Int64()) {
            val = WasmVal(*reinterpret_cast<int64_t*>(ptr));
          } else if (type == MachineType::Uint64()) {
            val = WasmVal(*reinterpret_cast<uint64_t*>(ptr));
          } else if (type == MachineType::Float32()) {
            val = WasmVal(*reinterpret_cast<float*>(ptr));
          } else if (type == MachineType::Float64()) {
            val = WasmVal(*reinterpret_cast<double*>(ptr));
          } else {
            UNREACHABLE();
          }
          Push(pc, val);
          len = 1 + operand.length;
          break;
        }
        case kExprStoreGlobal: {
          GlobalIndexOperand operand(&decoder, code->at(pc));
          const WasmGlobal* global = &module()->globals[operand.index];
          byte* ptr = instance()->globals_start + global->offset;
          MachineType type = global->type;
          WasmVal val = Pop();
          if (type == MachineType::Int8()) {
            *reinterpret_cast<int8_t*>(ptr) =
                static_cast<int8_t>(val.to<int32_t>());
          } else if (type == MachineType::Uint8()) {
            *reinterpret_cast<uint8_t*>(ptr) =
                static_cast<uint8_t>(val.to<uint32_t>());
          } else if (type == MachineType::Int16()) {
            *reinterpret_cast<int16_t*>(ptr) =
                static_cast<int16_t>(val.to<int32_t>());
          } else if (type == MachineType::Uint16()) {
            *reinterpret_cast<uint16_t*>(ptr) =
                static_cast<uint16_t>(val.to<uint32_t>());
          } else if (type == MachineType::Int32()) {
            *reinterpret_cast<int32_t*>(ptr) = val.to<int32_t>();
          } else if (type == MachineType::Uint32()) {
            *reinterpret_cast<uint32_t*>(ptr) = val.to<uint32_t>();
          } else if (type == MachineType::Int64()) {
            *reinterpret_cast<int64_t*>(ptr) = val.to<int64_t>();
          } else if (type == MachineType::Uint64()) {
            *reinterpret_cast<uint64_t*>(ptr) = val.to<uint64_t>();
          } else if (type == MachineType::Float32()) {
            *reinterpret_cast<float*>(ptr) = val.to<float>();
          } else if (type == MachineType::Float64()) {
            *reinterpret_cast<double*>(ptr) = val.to<double>();
          } else {
            UNREACHABLE();
          }
          Push(pc, val);
          len = 1 + operand.length;
          break;
        }

#define LOAD_CASE(name, ctype, mtype)                                    \
  case kExpr##name: {                                                    \
    MemoryAccessOperand operand(&decoder, code->at(pc));                 \
    uint32_t index = Pop().to<uint32_t>();                               \
    size_t effective_mem_size = instance()->mem_size - sizeof(mtype);    \
    if (operand.offset > effective_mem_size ||                           \
        index > (effective_mem_size - operand.offset)) {                 \
      return DoTrap(kTrapMemOutOfBounds, pc);                            \
    }                                                                    \
    byte* addr = instance()->mem_start + operand.offset + index;         \
    WasmVal result(static_cast<ctype>(ReadUnalignedValue<mtype>(addr))); \
    Push(pc, result);                                                    \
    len = 1 + operand.length;                                            \
    break;                                                               \
  }

          LOAD_CASE(I32LoadMem8S, int32_t, int8_t);
          LOAD_CASE(I32LoadMem8U, int32_t, uint8_t);
          LOAD_CASE(I32LoadMem16S, int32_t, int16_t);
          LOAD_CASE(I32LoadMem16U, int32_t, uint16_t);
          LOAD_CASE(I64LoadMem8S, int64_t, int8_t);
          LOAD_CASE(I64LoadMem8U, int64_t, uint8_t);
          LOAD_CASE(I64LoadMem16S, int64_t, int16_t);
          LOAD_CASE(I64LoadMem16U, int64_t, uint16_t);
          LOAD_CASE(I64LoadMem32S, int64_t, int32_t);
          LOAD_CASE(I64LoadMem32U, int64_t, uint32_t);
          LOAD_CASE(I32LoadMem, int32_t, int32_t);
          LOAD_CASE(I64LoadMem, int64_t, int64_t);
          LOAD_CASE(F32LoadMem, float, float);
          LOAD_CASE(F64LoadMem, double, double);
#undef LOAD_CASE

#define STORE_CASE(name, ctype, mtype)                                     \
  case kExpr##name: {                                                      \
    MemoryAccessOperand operand(&decoder, code->at(pc));                   \
    WasmVal val = Pop();                                                   \
    uint32_t index = Pop().to<uint32_t>();                                 \
    size_t effective_mem_size = instance()->mem_size - sizeof(mtype);      \
    if (operand.offset > effective_mem_size ||                             \
        index > (effective_mem_size - operand.offset)) {                   \
      return DoTrap(kTrapMemOutOfBounds, pc);                              \
    }                                                                      \
    byte* addr = instance()->mem_start + operand.offset + index;           \
    WriteUnalignedValue<mtype>(addr, static_cast<mtype>(val.to<ctype>())); \
    Push(pc, val);                                                         \
    len = 1 + operand.length;                                              \
    break;                                                                 \
  }

          STORE_CASE(I32StoreMem8, int32_t, int8_t);
          STORE_CASE(I32StoreMem16, int32_t, int16_t);
          STORE_CASE(I64StoreMem8, int64_t, int8_t);
          STORE_CASE(I64StoreMem16, int64_t, int16_t);
          STORE_CASE(I64StoreMem32, int64_t, int32_t);
          STORE_CASE(I32StoreMem, int32_t, int32_t);
          STORE_CASE(I64StoreMem, int64_t, int64_t);
          STORE_CASE(F32StoreMem, float, float);
          STORE_CASE(F64StoreMem, double, double);
#undef STORE_CASE

#define ASMJS_LOAD_CASE(name, ctype, mtype, defval)                 \
  case kExpr##name: {                                               \
    uint32_t index = Pop().to<uint32_t>();                          \
    ctype result;                                                   \
    if (index >= (instance()->mem_size - sizeof(mtype))) {          \
      result = defval;                                              \
    } else {                                                        \
      byte* addr = instance()->mem_start + index;                   \
      /* TODO(titzer): alignment for asmjs load mem? */             \
      result = static_cast<ctype>(*reinterpret_cast<mtype*>(addr)); \
    }                                                               \
    Push(pc, WasmVal(result));                                      \
    break;                                                          \
  }
          ASMJS_LOAD_CASE(I32AsmjsLoadMem8S, int32_t, int8_t, 0);
          ASMJS_LOAD_CASE(I32AsmjsLoadMem8U, int32_t, uint8_t, 0);
          ASMJS_LOAD_CASE(I32AsmjsLoadMem16S, int32_t, int16_t, 0);
          ASMJS_LOAD_CASE(I32AsmjsLoadMem16U, int32_t, uint16_t, 0);
          ASMJS_LOAD_CASE(I32AsmjsLoadMem, int32_t, int32_t, 0);
          ASMJS_LOAD_CASE(F32AsmjsLoadMem, float, float,
                          std::numeric_limits<float>::quiet_NaN());
          ASMJS_LOAD_CASE(F64AsmjsLoadMem, double, double,
                          std::numeric_limits<double>::quiet_NaN());
#undef ASMJS_LOAD_CASE

#define ASMJS_STORE_CASE(name, ctype, mtype)                                   \
  case kExpr##name: {                                                          \
    WasmVal val = Pop();                                                       \
    uint32_t index = Pop().to<uint32_t>();                                     \
    if (index < (instance()->mem_size - sizeof(mtype))) {                      \
      byte* addr = instance()->mem_start + index;                              \
      /* TODO(titzer): alignment for asmjs store mem? */                       \
      *(reinterpret_cast<mtype*>(addr)) = static_cast<mtype>(val.to<ctype>()); \
    }                                                                          \
    Push(pc, val);                                                             \
    break;                                                                     \
  }

          ASMJS_STORE_CASE(I32AsmjsStoreMem8, int32_t, int8_t);
          ASMJS_STORE_CASE(I32AsmjsStoreMem16, int32_t, int16_t);
          ASMJS_STORE_CASE(I32AsmjsStoreMem, int32_t, int32_t);
          ASMJS_STORE_CASE(F32AsmjsStoreMem, float, float);
          ASMJS_STORE_CASE(F64AsmjsStoreMem, double, double);
#undef ASMJS_STORE_CASE

        case kExprMemorySize: {
          Push(pc, WasmVal(static_cast<uint32_t>(instance()->mem_size)));
          break;
        }
#define EXECUTE_SIMPLE_BINOP(name, ctype, op)             \
  case kExpr##name: {                                     \
    WasmVal rval = Pop();                                 \
    WasmVal lval = Pop();                                 \
    WasmVal result(lval.to<ctype>() op rval.to<ctype>()); \
    Push(pc, result);                                     \
    break;                                                \
  }
          FOREACH_SIMPLE_BINOP(EXECUTE_SIMPLE_BINOP)
#undef EXECUTE_SIMPLE_BINOP

#define EXECUTE_OTHER_BINOP(name, ctype)              \
  case kExpr##name: {                                 \
    TrapReason trap = kTrapCount;                     \
    volatile ctype rval = Pop().to<ctype>();          \
    volatile ctype lval = Pop().to<ctype>();          \
    WasmVal result(Execute##name(lval, rval, &trap)); \
    if (trap != kTrapCount) return DoTrap(trap, pc);  \
    Push(pc, result);                                 \
    break;                                            \
  }
          FOREACH_OTHER_BINOP(EXECUTE_OTHER_BINOP)
#undef EXECUTE_OTHER_BINOP

#define EXECUTE_OTHER_UNOP(name, ctype)              \
  case kExpr##name: {                                \
    TrapReason trap = kTrapCount;                    \
    volatile ctype val = Pop().to<ctype>();          \
    WasmVal result(Execute##name(val, &trap));       \
    if (trap != kTrapCount) return DoTrap(trap, pc); \
    Push(pc, result);                                \
    break;                                           \
  }
          FOREACH_OTHER_UNOP(EXECUTE_OTHER_UNOP)
#undef EXECUTE_OTHER_UNOP

        default:
          V8_Fatal(__FILE__, __LINE__, "Unknown or unimplemented opcode #%d:%s",
                   code->start[pc], OpcodeName(code->start[pc]));
          UNREACHABLE();
      }

      pc += len;
    }
    UNREACHABLE();  // above decoding loop should run forever.
  }

  WasmVal Pop() {
    DCHECK_GT(stack_.size(), 0u);
    DCHECK_GT(frames_.size(), 0u);
    DCHECK_GT(stack_.size(), frames_.back().llimit());  // can't pop into locals
    WasmVal val = stack_.back();
    stack_.pop_back();
    return val;
  }

  void PopN(int n) {
    DCHECK_GE(stack_.size(), static_cast<size_t>(n));
    DCHECK_GT(frames_.size(), 0u);
    size_t nsize = stack_.size() - n;
    DCHECK_GE(nsize, frames_.back().llimit());  // can't pop into locals
    stack_.resize(nsize);
  }

  WasmVal PopArity(size_t arity) {
    if (arity == 0) return WasmVal();
    CHECK_EQ(1, arity);
    return Pop();
  }

  void Push(pc_t pc, WasmVal val) {
    // TODO(titzer): store PC as well?
    stack_.push_back(val);
  }

  void TraceStack(const char* phase, pc_t pc) {
    if (FLAG_trace_wasm_interpreter) {
      PrintF("%s @%zu", phase, pc);
      UNIMPLEMENTED();
      PrintF("\n");
    }
  }

  void TraceValueStack() {
    Frame* top = frames_.size() > 0 ? &frames_.back() : nullptr;
    sp_t sp = top ? top->sp : 0;
    sp_t plimit = top ? top->plimit() : 0;
    sp_t llimit = top ? top->llimit() : 0;
    if (FLAG_trace_wasm_interpreter) {
      for (size_t i = sp; i < stack_.size(); ++i) {
        if (i < plimit)
          PrintF(" p%zu:", i);
        else if (i < llimit)
          PrintF(" l%zu:", i);
        else
          PrintF(" s%zu:", i);
        WasmVal val = stack_[i];
        switch (val.type) {
          case kAstI32:
            PrintF("i32:%d", val.to<int32_t>());
            break;
          case kAstI64:
            PrintF("i64:%" PRId64 "", val.to<int64_t>());
            break;
          case kAstF32:
            PrintF("f32:%f", val.to<float>());
            break;
          case kAstF64:
            PrintF("f64:%lf", val.to<double>());
            break;
          case kAstStmt:
            PrintF("void");
            break;
          default:
            UNREACHABLE();
            break;
        }
      }
    }
  }
};

//============================================================================
// The implementation details of the interpreter.
//============================================================================
class WasmInterpreterInternals : public ZoneObject {
 public:
  WasmModuleInstance* instance_;
  CodeMap codemap_;
  ZoneVector<ThreadImpl*> threads_;

  WasmInterpreterInternals(Zone* zone, WasmModuleInstance* instance)
      : instance_(instance),
        codemap_(instance_ ? instance_->module : nullptr, zone),
        threads_(zone) {
    threads_.push_back(new ThreadImpl(zone, &codemap_, instance));
  }

  void Delete() {
    // TODO(titzer): CFI doesn't like threads in the ZoneVector.
    for (auto t : threads_) delete t;
    threads_.resize(0);
  }
};

//============================================================================
// Implementation of the public interface of the interpreter.
//============================================================================
WasmInterpreter::WasmInterpreter(WasmModuleInstance* instance,
                                 base::AccountingAllocator* allocator)
    : zone_(allocator),
      internals_(new (&zone_) WasmInterpreterInternals(&zone_, instance)) {}

WasmInterpreter::~WasmInterpreter() { internals_->Delete(); }

void WasmInterpreter::Run() { internals_->threads_[0]->Run(); }

void WasmInterpreter::Pause() { internals_->threads_[0]->Pause(); }

bool WasmInterpreter::SetBreakpoint(const WasmFunction* function, pc_t pc,
                                    bool enabled) {
  InterpreterCode* code = internals_->codemap_.FindCode(function);
  if (!code) return false;
  size_t size = static_cast<size_t>(code->end - code->start);
  // Check bounds for {pc}.
  if (pc < code->locals.decls_encoded_size || pc >= size) return false;
  // Make a copy of the code before enabling a breakpoint.
  if (enabled && code->orig_start == code->start) {
    code->start = reinterpret_cast<byte*>(zone_.New(size));
    memcpy(code->start, code->orig_start, size);
    code->end = code->start + size;
  }
  bool prev = code->start[pc] == kInternalBreakpoint;
  if (enabled) {
    code->start[pc] = kInternalBreakpoint;
  } else {
    code->start[pc] = code->orig_start[pc];
  }
  return prev;
}

bool WasmInterpreter::GetBreakpoint(const WasmFunction* function, pc_t pc) {
  InterpreterCode* code = internals_->codemap_.FindCode(function);
  if (!code) return false;
  size_t size = static_cast<size_t>(code->end - code->start);
  // Check bounds for {pc}.
  if (pc < code->locals.decls_encoded_size || pc >= size) return false;
  // Check if a breakpoint is present at that place in the code.
  return code->start[pc] == kInternalBreakpoint;
}

bool WasmInterpreter::SetTracing(const WasmFunction* function, bool enabled) {
  UNIMPLEMENTED();
  return false;
}

int WasmInterpreter::GetThreadCount() {
  return 1;  // only one thread for now.
}

WasmInterpreter::Thread* WasmInterpreter::GetThread(int id) {
  CHECK_EQ(0, id);  // only one thread for now.
  return internals_->threads_[id];
}

WasmVal WasmInterpreter::GetLocalVal(const WasmFrame* frame, int index) {
  CHECK_GE(index, 0);
  UNIMPLEMENTED();
  WasmVal none;
  none.type = kAstStmt;
  return none;
}

WasmVal WasmInterpreter::GetExprVal(const WasmFrame* frame, int pc) {
  UNIMPLEMENTED();
  WasmVal none;
  none.type = kAstStmt;
  return none;
}

void WasmInterpreter::SetLocalVal(WasmFrame* frame, int index, WasmVal val) {
  UNIMPLEMENTED();
}

void WasmInterpreter::SetExprVal(WasmFrame* frame, int pc, WasmVal val) {
  UNIMPLEMENTED();
}

size_t WasmInterpreter::GetMemorySize() {
  return internals_->instance_->mem_size;
}

WasmVal WasmInterpreter::ReadMemory(size_t offset) {
  UNIMPLEMENTED();
  return WasmVal();
}

void WasmInterpreter::WriteMemory(size_t offset, WasmVal val) {
  UNIMPLEMENTED();
}

int WasmInterpreter::AddFunctionForTesting(const WasmFunction* function) {
  return internals_->codemap_.AddFunction(function, nullptr, nullptr);
}

bool WasmInterpreter::SetFunctionCodeForTesting(const WasmFunction* function,
                                                const byte* start,
                                                const byte* end) {
  return internals_->codemap_.SetFunctionCode(function, start, end);
}

ControlTransferMap WasmInterpreter::ComputeControlTransfersForTesting(
    Zone* zone, const byte* start, const byte* end) {
  ControlTransfers targets(zone, 0, start, end);
  return targets.map_;
}

}  // namespace wasm
}  // namespace internal
}  // namespace v8
