/*
 * Copyright 2015 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.
 */

//
// Simple WebAssembly interpreter. This operates directly (in-place) on our IR,
// and our IR is a structured form of Wasm, so this is similar to an AST
// interpreter. Operating directly on our IR makes us efficient in the
// Precompute pass, which tries to execute every bit of code.
//
// As a side benefit, interpreting the IR directly makes the code an easy way to
// understand WebAssembly semantics (see e.g. visitLoop(), which is basically
// just a simple loop).
//

#ifndef wasm_wasm_interpreter_h
#define wasm_wasm_interpreter_h

#include <cmath>
#include <iomanip>
#include <limits.h>
#include <sstream>
#include <variant>

#include "fp16.h"
#include "ir/import-utils.h"
#include "ir/intrinsics.h"
#include "ir/iteration.h"
#include "ir/memory-utils.h"
#include "ir/module-utils.h"
#include "ir/properties.h"
#include "ir/runtime-table.h"
#include "ir/table-utils.h"
#include "support/bits.h"
#include "support/safe_integer.h"
#include "support/stdckdint.h"
#include "support/string.h"
#include "wasm-builder.h"
#include "wasm-limits.h"
#include "wasm-traversal.h"
#include "wasm.h"

#if __has_feature(leak_sanitizer) || __has_feature(address_sanitizer)
#include <sanitizer/lsan_interface.h>
#endif

namespace wasm {

struct WasmException {
  Literal exn;
};
std::ostream& operator<<(std::ostream& o, const WasmException& exn);

// An exception thrown when we try to execute non-constant code, that is, code
// that we cannot properly evaluate at compile time (e.g. if it refers to an
// import, or we are optimizing and it uses relaxed SIMD).
// TODO: use a flow with a special name, as this is likely very slow
struct NonconstantException {};

// Utilities

extern Name RETURN_FLOW, RETURN_CALL_FLOW, NONCONSTANT_FLOW, SUSPEND_FLOW;

// Stuff that flows around during executing expressions: a literal, or a change
// in control flow.
class Flow {
public:
  Flow() : values() {}
  Flow(Literal value) : values{value} { assert(value.type.isConcrete()); }
  Flow(Literals& values) : values(values) {}
  Flow(Literals&& values) : values(std::move(values)) {}
  Flow(Name breakTo) : values(), breakTo(breakTo) {}
  Flow(Name breakTo, Literal value) : values{value}, breakTo(breakTo) {}
  Flow(Name breakTo, Literals&& values)
    : values(std::move(values)), breakTo(breakTo) {}
  Flow(Name breakTo, Tag* suspendTag, Literals&& values)
    : values(std::move(values)), breakTo(breakTo), suspendTag(suspendTag) {
    assert(breakTo == SUSPEND_FLOW);
  }

  Literals values;
  Name breakTo;              // if non-null, a break is going on
  Tag* suspendTag = nullptr; // if non-null, breakTo must be SUSPEND_FLOW, and
                             // this is the tag being suspended

  // A helper function for the common case where there is only one value
  const Literal& getSingleValue() {
    assert(values.size() == 1);
    return values[0];
  }

  Type getType() { return values.getType(); }

  Expression* getConstExpression(Module& module) {
    assert(values.size() > 0);
    Builder builder(module);
    return builder.makeConstantExpression(values);
  }

  // Returns true if we are breaking out of normal execution. This can be
  // because of a break/continue, or a continuation.
  bool breaking() const { return breakTo.is(); }

  void clearIf(Name target) {
    if (breakTo == target) {
      breakTo = Name{};
    }
  }

  friend std::ostream& operator<<(std::ostream& o, const Flow& flow) {
    o << "(flow " << (flow.breakTo.is() ? flow.breakTo.str : "-") << " : {";
    for (size_t i = 0; i < flow.values.size(); ++i) {
      if (i > 0) {
        o << ", ";
      }
      o << flow.values[i];
    }
    if (flow.suspendTag) {
      o << " [suspend:" << flow.suspendTag->name << ']';
    }
    o << "})";
    return o;
  }
};

struct FuncData {
  // Name of the function in the instance that defines it, if available, or
  // otherwise the internal name of a function import.
  Name name;

  // The interpreter instance this function closes over, if any. (There might
  // not be an interpreter instance if this is a host function or an import from
  // an unknown source.) This is only used for equality comparisons, as two
  // functions are equal iff they have the same name and are defined by the same
  // instance (in particular, we do *not* compare the |call| field below, which
  // is an execution detail).
  void* self;

  // A way to execute this function. We use this when it is called.
  using Call = std::function<Flow(const Literals&)>;
  Call call;

  FuncData(Name name, void* self = nullptr, Call call = {})
    : name(name), self(self), call(call) {}

  bool operator==(const FuncData& other) const {
    return name == other.name && self == other.self;
  }

  Flow doCall(const Literals& arguments) {
    assert(call);
    return call(arguments);
  }
};

// The data of a (ref exn) literal.
struct ExnData {
  const Tag* tag;
  Literals payload;

  ExnData(const Tag* tag, Literals payload) : tag(tag), payload(payload) {}
};

// Suspend/resume support.
//
// As we operate directly on our structured IR, we do not have a program counter
// (bytecode offset to execute, or such), nor can we use continuation-passing
// style. Instead, we implement suspending and resuming code in a parallel way
// to how Asyncify does so, see src/passes/Asyncify.cpp (as well as
// https://kripken.github.io/blog/wasm/2019/07/16/asyncify.html). That
// transformation modifies wasm, while we are an interpreter that executes wasm,
// but the shared idea is that to resume code we simply need to get to where we
// were when we suspended, so we have a "resuming" mode in which we walk the IR
// but do not execute normally. While resuming we basically re-wind the stack,
// using data we stashed on the side while unwinding.
//
// The key idea in this approach to suspending and resuming is that to suspend
// you want to unwind the stack - you "jump" back to some outer scope - and to
// reume, we want to rewind the stack - to get everything back exactly the way
// it was, so we can pick things back up. And, to achieve that, we really just
// need two things:
//    * To rewind the call stack. If we called foo() and then bar(), we want to
//      have foo and bar on the stack, so that when bar finishes, we return to
//      foo, etc., as if we never suspended/resumed.
//    * To have the same values as before. If we are an i32.add, and we
//      suspended in the second arm, we need to have the same value for the
//      first arm as before the suspend.
//
// Implementing these is conceptually simple:
//    * For control flow, each structure handles itself. For example, if we
//      unwind an If instruction then we note which arm of the If we unwound
//      from, and then when we re-wind we enter that proper arm. For a Block,
//      we can note the index we had executed up to, etc.
//    * For values, we just save them automatically (specific visitFoo methods
//      do not need to do anything themselves), see below on |valueStack|. (Note
//      that we do an optimization for speed that avoids using that stack unless
//      actually necessary.)
//
// Once we have those two things handled, pretty much everything else "just
// works," and 99% of instructions need no special handling at all. Even some
// instructions you might think would need custom code do not, like CallRef:
// while that instruction does a call and changes the call stack, it calls the
// value of its last child, so if we restore that child's value while resuming,
// the normal code is exactly what we want (calling that child rewinds the stack
// in exactly the right way). That is, once control flow structures know what to
// do (which is unique to each one, but trivial), and once we have values
// restored, the interpreter "wants" to return to the exact place we suspended
// at, and we just let it do that. (And when it reaches the place we suspended
// from, we do a special operation to stop resuming, and to proceed with normal
// execution, as if we never suspended.)
//
// This is not the most efficient way to pause and resume execution (a program
// counter/goto would be much faster!) but this is very simple to implement in
// our interpreter, and in a way that does not make the interpreter slower when
// not pausing/resuming. As with Asyncify, the assumption is that pauses/resumes
// are rare, and it is acceptable for them to be less efficient.
//
// Key parts of this support:
//   * |ContData| is the key data structure that represents continuations. Each
//     continuation Literal has a reference to one of these.
//   * |ContinuationStore| is state about the execution of continuations that is
//     shared between instances of the core interpreter
//     (ExpressionRunner/ModuleInstance):
//     * |continuations| is the stack of active continuations.
//     * |resuming| is set when we are in the special "resuming" mode mentioned
//       above.
//   * Inside the interpreter (ExpressionRunner/ModuleInstance):
//     * When we suspend, everything on the stack will save the necessary info
//       to recreate itself later during resume. That is done by calling
//       |pushResumeEntry|, which saves info on the continuation, and which is
//       read during resume using |popResumeEntry|.
//     * |valueStack| preserves values on the stack, so that we can save them
//       later if we suspend.
//     * When we resume, the old |valuesStack| is converted into
//       |restoredValuesMap|. When a visit() sees that we have a value to
//       restore, it simply returns it.
//     * The main suspend/resume logic is in |visit|. That handles everything
//       except for control flow structure-specific handling, which is done in
//       |visitIf| etc. (each such structure handles itself).

struct ContData {
  // The function we should execute to run this continuation.
  Literal func;

  // The continuation type.
  HeapType type;

  // The expression to resume execution at, which is where we suspended. Or, if
  // we are just starting to execute this continuation, this is nullptr (and we
  // will resume at the very start).
  Expression* resumeExpr = nullptr;

  // Information about how to resume execution, a list of instruction and data
  // that we "replay" into the value and call stacks. For convenience we split
  // this into separate entries, each one a Literals. Typically an instruction
  // will emit a single Literals for itself, or possibly a few bundles.
  std::vector<Literals> resumeInfo;

  // The arguments sent when resuming (on first execution these appear as
  // parameters to the function; on later resumes, they are returned from the
  // suspend).
  Literals resumeArguments;

  // If set, this is the tag for an exception to be thrown at the resume point
  // (from resume_throw).
  Tag* exceptionTag = nullptr;

  // If set, this is the exception ref to be thrown at the resume point (from
  // resume_throw_ref).
  Literal exception;

  // Whether we executed. Continuations are one-shot, so they may not be
  // executed a second time.
  bool executed = false;

  ContData() {}
  ContData(Literal func, HeapType type) : func(func), type(type) {}
};

// Shared execution state of a set of instantiated modules.
struct ContinuationStore {
  // The current continuations, in a stack. At the top of the stack is the
  // current continuation, i.e., the one either executing right now, or in the
  // process of unwinding or rewinding the stack.
  //
  // We must share this between all interpreter instances, because which
  // continuation is current does not depend on which instance we happen to be
  // inside (we could call an imported function from another module, and that
  // should not alter what happens when we suspend/resume).
  std::vector<std::shared_ptr<ContData>> continuations;

  // Set when we are resuming execution, that is, re-winding the stack.
  bool resuming = false;
};

// Execute an expression
template<typename SubType>
class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
  SubType* self() { return static_cast<SubType*>(this); }

protected:
  // Optional module context to search for globals and called functions. NULL if
  // we are not interested in any context.
  Module* module = nullptr;

  // Maximum depth before giving up.
  Index maxDepth;
  Index depth = 0;

  // Maximum iterations before giving up on a loop.
  Index maxLoopIterations;

  // Helper for visiting: Visit and handle breaking.
#define VISIT(flow, expr)                                                      \
  Flow flow = self()->visit(expr);                                             \
  if (flow.breaking()) {                                                       \
    return flow;                                                               \
  }

  // As above, but reuse an existing |flow|.
#define VISIT_REUSE(flow, expr)                                                \
  flow = self()->visit(expr);                                                  \
  if (flow.breaking()) {                                                       \
    return flow;                                                               \
  }

  Flow generateArguments(const ExpressionList& operands, Literals& arguments) {
    arguments.reserve(operands.size());
    for (auto expression : operands) {
      VISIT(flow, expression)
      arguments.push_back(flow.getSingleValue());
    }
    return Flow();
  }

  // As above, but for generateArguments.
#define VISIT_ARGUMENTS(flow, operands, arguments)                             \
  Flow flow = self()->generateArguments(operands, arguments);                  \
  if (flow.breaking()) {                                                       \
    return flow;                                                               \
  }

  // This small function is mainly useful to put all GCData allocations in a
  // single place. We need that because LSan reports leaks on cycles in this
  // data, as we don't have a cycle collector. Those leaks are not a serious
  // problem as Binaryen is not really used in long-running tasks, so we ignore
  // this function in LSan.
  //
  // This consumes the input |data| entirely.
  Literal makeGCData(Literals&& data,
                     Type type,
                     Literal desc = Literal::makeNull(HeapType::none)) {
    auto allocation =
      std::make_shared<GCData>(type.getHeapType(), std::move(data), desc);
#if __has_feature(leak_sanitizer) || __has_feature(address_sanitizer)
    // GC data with cycles will leak, since shared_ptrs do not handle cycles.
    // Binaryen is generally not used in long-running programs so we just ignore
    // such leaks for now.
    // TODO: Add a cycle collector?
    __lsan_ignore_object(allocation.get());
#endif
    return Literal(allocation, type.getHeapType());
  }

  // Same as makeGCData but for ExnData.
  Literal makeExnData(Tag* tag, const Literals& payload) {
    auto allocation = std::make_shared<ExnData>(tag, payload);
#if __has_feature(leak_sanitizer) || __has_feature(address_sanitizer)
    __lsan_ignore_object(allocation.get());
#endif
    return Literal(allocation);
  }

public:
  // Indicates no limit of maxDepth or maxLoopIterations.
  static const Index NO_LIMIT = 0;

  enum RelaxedBehavior {
    // Consider relaxed SIMD instructions non-constant. This is suitable for
    // optimizations, as we bake the results of optimizations into the output,
    // but relaxed operations must behave according to the host semantics, not
    // ours, so we do not want to optimize such expressions.
    NonConstant,
    // Execute relaxed SIMD instructions.
    Execute,
  };

  Literal makeFuncData(Name name, Type type) {
    // Identify the interpreter, but do not provide a way to actually call the
    // function.
    auto allocation = std::make_shared<FuncData>(name, this);
#if __has_feature(leak_sanitizer) || __has_feature(address_sanitizer)
    __lsan_ignore_object(allocation.get());
#endif
    return Literal(allocation, type);
  }

protected:
  RelaxedBehavior relaxedBehavior = RelaxedBehavior::NonConstant;

#if WASM_INTERPRETER_DEBUG
  std::string indent() {
    std::string id;
    if (auto* module = getModule()) {
      id = module->name.toString();
    }
    if (id.empty()) {
      id = std::to_string(reinterpret_cast<size_t>(this));
    }
    auto ret = '[' + id + "] ";
    for (Index i = 0; i < depth; i++) {
      ret += ' ';
    }
    return ret;
  }
#endif

  // Suspend/resume support.

  // We save the value stack, so that we can stash it if we suspend. Normally,
  // each instruction just calls visit() on its children, so the values are
  // saved in those local stack frames in an efficient manner, but also we
  // cannot scan those stack frames efficiently. Saving those values in
  // this location (in addition to the normal place) does not add significant
  // overhead (and we skip it entirely when not in a coroutine), and it is
  // trivial to use when suspending.
  //
  // Each entry here is for an instruction in the stack of executing
  // expressions, and contains all the values from its children that we have
  // seen thus far. In other words, the invariant we preserve is this: when an
  // instruction executes, the top of the stack contains the values of its
  // children, e.g.,
  //
  //  (i32.add (A) (B))
  //
  // After executing A and getting its value, valueStack looks like this:
  //
  //  [[..], ..scopes for parents of the add.., [..], [value of A]]
  //                                                  ^^^^^^^^^^^^
  //                                                  scope for the
  //                                                  add, with one
  //                                                  child so far
  //
  // Imagine that B then suspends. Then using the top of valueStack, we know the
  // value of A, and can stash it. When we resume, we just apply that value, and
  // proceed to execute B.
  std::vector<std::vector<Literals>> valueStack;

  // RAII helper for |valueStack|: Adds a scope for an instruction, where the
  // values of its children will be saved, and cleans it up later.
  struct StackValueNoter {
    ExpressionRunner* parent;

    StackValueNoter(ExpressionRunner* parent) : parent(parent) {
      parent->valueStack.emplace_back();
    }

    ~StackValueNoter() {
      assert(!parent->valueStack.empty());
      parent->valueStack.pop_back();
    }
  };

  // When we resume, we will apply the saved values from |valueStack| to this
  // map, so we can "replay" them. Whenever visit() is asked to execute an
  // expression that is in this map, then it will just return that value.
  std::unordered_map<Expression*, Literals> restoredValuesMap;

  // Shared execution state for continuations. This can be null if the
  // instance does not want to ever suspend/resume.
  std::shared_ptr<ContinuationStore> continuationStore;

  std::shared_ptr<ContData> getCurrContinuationOrNull() {
    if (!continuationStore || continuationStore->continuations.empty()) {
      return {};
    }
    return continuationStore->continuations.back();
  }

  std::shared_ptr<ContData> getCurrContinuation() {
    auto cont = getCurrContinuationOrNull();
    assert(cont);
    return cont;
  }

  void pushCurrContinuation(std::shared_ptr<ContData> cont) {
#if WASM_INTERPRETER_DEBUG
    std::cout << indent() << "push continuation\n";
#endif
    assert(continuationStore);
    return continuationStore->continuations.push_back(cont);
  }

  std::shared_ptr<ContData> popCurrContinuation() {
#if WASM_INTERPRETER_DEBUG
    std::cout << indent() << "pop continuation\n";
#endif
    assert(continuationStore);
    assert(!continuationStore->continuations.empty());
    auto cont = continuationStore->continuations.back();
    continuationStore->continuations.pop_back();
    return cont;
  }

public:
  // Clear the execution state of continuations. This is done when we trap, for
  // example, as that means all continuations are lost, and later calls to the
  // module should start from a blank slate.
  void clearContinuationStore() {
    if (continuationStore) {
#if WASM_INTERPRETER_DEBUG
      std::cout << indent() << "clear continuations\n";
#endif
      continuationStore = std::make_shared<ContinuationStore>();
    }
  }

protected:
  bool isResuming() { return continuationStore && continuationStore->resuming; }

  // Add an entry to help us resume this continuation later. Instructions call
  // this as we unwind.
  void pushResumeEntry(const Literals& entry, const char* what) {
    auto currContinuation = getCurrContinuationOrNull();
    if (!currContinuation) {
      // We are suspending outside of a continuation. This will trap as an
      // unhandled suspension when we reach the host, so we don't need to save
      // any resume entries (it would be simpler to just trap when we suspend in
      // such a situation, but spec tests want to differentiate traps from
      // suspends).
      return;
    }
#if WASM_INTERPRETER_DEBUG
    std::cout << indent() << "push resume entry [" << what << "]: " << entry
              << "\n";
#endif
    currContinuation->resumeInfo.push_back(entry);
  }

  // Fetch an entry as we resume. Instructions call this as we rewind.
  Literals popResumeEntry(const char* what) {
#if WASM_INTERPRETER_DEBUG
    std::cout << indent() << "pop resume entry [" << what << "]:\n";
#endif
    auto currContinuation = getCurrContinuation();
    assert(!currContinuation->resumeInfo.empty());
    auto entry = currContinuation->resumeInfo.back();
    currContinuation->resumeInfo.pop_back();
#if WASM_INTERPRETER_DEBUG
    std::cout << indent() << "                 => " << entry << "\n";
#endif
    return entry;
  }

public:
  ExpressionRunner(Module* module = nullptr,
                   Index maxDepth = NO_LIMIT,
                   Index maxLoopIterations = NO_LIMIT)
    : module(module), maxDepth(maxDepth), maxLoopIterations(maxLoopIterations) {
  }
  virtual ~ExpressionRunner() = default;

  void setRelaxedBehavior(RelaxedBehavior value) { relaxedBehavior = value; }

  Flow visit(Expression* curr) {
#if WASM_INTERPRETER_DEBUG
    std::cout << indent() << "visit(" << getExpressionName(curr) << ")\n";
#endif

    depth++;
    if (maxDepth != NO_LIMIT && depth > maxDepth) {
      hostLimit("interpreter recursion limit");
    }

    // Execute the instruction.
    Flow ret;
    if (!getCurrContinuationOrNull()) {
      // We are not in a continuation, so we cannot suspend/resume. Just execute
      // normally.
      ret = OverriddenVisitor<SubType, Flow>::visit(curr);
    } else {
      // We may suspend/resume.
      bool hasValue = false;
      if (isResuming()) {
        // Perhaps we have a known value to just apply here, without executing
        // the instruction.
        auto iter = restoredValuesMap.find(curr);
        if (iter != restoredValuesMap.end()) {
          ret = iter->second;
#if WASM_INTERPRETER_DEBUG
          std::cout << indent() << "consume restored value: " << ret.values
                    << '\n';
#endif
          restoredValuesMap.erase(iter);
          hasValue = true;
        }
      }
      if (!hasValue) {
        // We must execute this instruction. Set up the logic to note the values
        // of children. TODO: as an optimization, we could avoid this for
        // control flow structures, at the cost of more complexity
        StackValueNoter noter(this);

        if (Properties::isControlFlowStructure(curr)) {
          // Control flow structures have their own logic for suspend/resume.
          ret = OverriddenVisitor<SubType, Flow>::visit(curr);
        } else {
          // A general non-control-flow instruction, with generic suspend/
          // resume support implemented here.
          if (isResuming()) {
            // Some children may have executed, and we have values stashed for
            // them (see below where we suspend). Get those values, and populate
            // |restoredValuesMap| so that when visit() is called on them, we
            // can return those values rather than run them.
            auto numEntry = popResumeEntry("num executed children");
            assert(numEntry.size() == 1);
            auto num = numEntry[0].geti32();
            for (auto* child : ChildIterator(curr)) {
              if (num == 0) {
                // We have restored all the children that executed (any others
                // were not suspended, and we have no values for them).
                break;
              }
              --num;
              auto value = popResumeEntry("child value");
              restoredValuesMap[child] = value;
#if WASM_INTERPRETER_DEBUG
              std::cout << indent() << "prepare restored value: " << value
                        << '\n';
#endif
            }
          }

          // We are ready to return the right values for the children, and
          // can visit this instruction.
          ret = OverriddenVisitor<SubType, Flow>::visit(curr);

          if (ret.suspendTag) {
            // We are suspending a continuation. All we need to do for a
            // general instruction is stash the values of executed children
            // from the value stack, and their number (as we may have
            // suspended after executing only some).
            assert(!valueStack.empty());
            auto& values = valueStack.back();
            auto num = values.size();
            while (!values.empty()) {
              // TODO: std::move, &elsewhere?
              pushResumeEntry(values.back(), "child value");
              values.pop_back();
            }
            pushResumeEntry({Literal(int32_t(num))}, "num executed children");
          }
        }
      }

      // Outside the scope of StackValueNoter, the scope of our own child values
      // has been removed (we don't need those values any more). What is now on
      // the top of |valueStack| is the list of child values of our parent,
      // which is the place our own value can go, if we have one (we only save
      // values on the stack, not values sent on a break/suspend; suspending is
      // handled above).
      if (!ret.breaking() && ret.getType().isConcrete()) {
        // The value stack may be empty, if we lack a parent that needs our
        // value. That is the case when we are the toplevel expression, etc.
        if (!valueStack.empty()) {
          auto& values = valueStack.back();
          values.push_back(ret.values);
#if WASM_INTERPRETER_DEBUG
          std::cout << indent() << "added to valueStack: " << ret.values
                    << '\n';
#endif
        }
      }
    }

#ifndef NDEBUG
    if (!ret.breaking()) {
      Type type = ret.getType();
      if (type.isConcrete() || curr->type.isConcrete()) {
        if (!Type::isSubType(type, curr->type)) {
          Fatal() << "expected " << ModuleType(*module, curr->type)
                  << ", seeing " << ModuleType(*module, type) << " from\n"
                  << ModuleExpression(*module, curr) << '\n';
        }
      }
    }
#endif
    depth--;
#if WASM_INTERPRETER_DEBUG
    std::cout << indent() << "=> returning: " << ret << '\n';
#endif
    return ret;
  }

  // Gets the module this runner is operating on.
  Module* getModule() { return module; }

  Flow visitBlock(Block* curr) {
    // special-case Block, because Block nesting (in their first element) can be
    // incredibly deep
    std::vector<Block*> stack;
    stack.push_back(curr);
    while (curr->list.size() > 0 && curr->list[0]->is<Block>()) {
      curr = curr->list[0]->cast<Block>();
      stack.push_back(curr);
    }

    // Suspend/resume support.
    auto suspend = [&](Index blockIndex) {
      Literals entry;
      // To return to the same place when we resume, we add an entry with two
      // pieces of information: the index in the stack of blocks, and the index
      // in the block.
      entry.push_back(Literal(uint32_t(stack.size())));
      entry.push_back(Literal(uint32_t(blockIndex)));
      pushResumeEntry(entry, "block");
    };
    Index blockIndex = 0;
    if (isResuming()) {
      auto entry = popResumeEntry("block");
      assert(entry.size() == 2);
      Index stackIndex = entry[0].geti32();
      blockIndex = entry[1].geti32();
      assert(stack.size() > stackIndex);
      stack.resize(stackIndex + 1);
    }

    Flow flow;
    auto* top = stack.back();
    while (stack.size() > 0) {
      curr = stack.back();
      stack.pop_back();
      if (flow.breaking()) {
        flow.clearIf(curr->name);
        continue;
      }
      auto& list = curr->list;
      for (size_t i = blockIndex; i < list.size(); i++) {
        if (curr != top && i == 0) {
          // one of the block recursions we already handled
          continue;
        }
        flow = visit(list[i]);
        if (flow.suspendTag) {
          suspend(i);
          return flow;
        }
        if (flow.breaking()) {
          flow.clearIf(curr->name);
          break;
        }
      }
      // If there was a value here, we only need it for the top iteration.
      blockIndex = 0;
    }
    return flow;
  }
  Flow visitIf(If* curr) {
    // Suspend/resume support.
    auto suspend = [&](Index resumeIndex) {
      // To return to the same place when we resume, we stash an index:
      //   0 - suspended in the condition
      //   1 - suspended in the ifTrue arm
      //   2 - suspended in the ifFalse arm
      pushResumeEntry({Literal(int32_t(resumeIndex))}, "if");
    };
    Index resumeIndex = -1;
    if (isResuming()) {
      auto entry = popResumeEntry("if");
      assert(entry.size() == 1);
      resumeIndex = entry[0].geti32();
    }

    Flow flow;
    // The value of the if's condition (whether to take the ifTrue arm or not).
    Index condition;

    if (isResuming() && resumeIndex > 0) {
      // We are resuming into one of the arms. Just set the right condition.
      condition = (resumeIndex == 1);
    } else {
      // We are executing normally, or we are resuming into the condition.
      // Either way, enter the condition.
      flow = visit(curr->condition);
      if (flow.suspendTag) {
        suspend(0);
        return flow;
      }
      if (flow.breaking()) {
        return flow;
      }
      condition = flow.getSingleValue().geti32();
    }

    if (condition) {
      flow = visit(curr->ifTrue);
    } else {
      if (curr->ifFalse) {
        flow = visit(curr->ifFalse);
      } else {
        flow = Flow();
      }
    }
    if (flow.suspendTag) {
      suspend(condition ? 1 : 2);
      return flow;
    }
    return flow;
  }
  Flow visitLoop(Loop* curr) {
    // NB: No special support is need for suspend/resume.
    Index loopCount = 0;
    while (1) {
      Flow flow = visit(curr->body);
      if (flow.breaking()) {
        if (flow.breakTo == curr->name) {
          if (maxLoopIterations != NO_LIMIT &&
              ++loopCount >= maxLoopIterations) {
            return Flow(NONCONSTANT_FLOW);
          }
          continue; // lol
        }
      }
      // loop does not loop automatically, only continue achieves that
      return flow;
    }
  }
  Flow visitBreak(Break* curr) {
    bool condition = true;
    Flow flow;
    if (curr->value) {
      VISIT_REUSE(flow, curr->value);
    }
    if (curr->condition) {
      VISIT(conditionFlow, curr->condition)
      condition = conditionFlow.getSingleValue().getInteger() != 0;
      if (!condition) {
        return flow;
      }
    }
    flow.breakTo = curr->name;
    return flow;
  }
  Flow visitSwitch(Switch* curr) {
    Flow flow;
    Literals values;
    if (curr->value) {
      VISIT_REUSE(flow, curr->value);
      values = flow.values;
    }
    VISIT_REUSE(flow, curr->condition);
    int64_t index = flow.getSingleValue().getInteger();
    Name target = curr->default_;
    if (index >= 0 && (size_t)index < curr->targets.size()) {
      target = curr->targets[(size_t)index];
    }
    flow.breakTo = target;
    flow.values = values;
    return flow;
  }

  Flow visitConst(Const* curr) {
    return Flow(curr->value); // heh
  }

  // Unary and Binary nodes, the core math computations. We mostly just
  // delegate to the Literal::* methods, except we handle traps here.

  Flow visitUnary(Unary* curr) {
    VISIT(flow, curr->value)
    Literal value = flow.getSingleValue();
    switch (curr->op) {
      case ClzInt32:
      case ClzInt64:
        return value.countLeadingZeroes();
      case CtzInt32:
      case CtzInt64:
        return value.countTrailingZeroes();
      case PopcntInt32:
      case PopcntInt64:
        return value.popCount();
      case EqZInt32:
      case EqZInt64:
        return value.eqz();
      case ReinterpretInt32:
        return value.castToF32();
      case ReinterpretInt64:
        return value.castToF64();
      case ExtendSInt32:
        return value.extendToSI64();
      case ExtendUInt32:
        return value.extendToUI64();
      case WrapInt64:
        return value.wrapToI32();
      case ConvertUInt32ToFloat32:
      case ConvertUInt64ToFloat32:
        return value.convertUIToF32();
      case ConvertUInt32ToFloat64:
      case ConvertUInt64ToFloat64:
        return value.convertUIToF64();
      case ConvertSInt32ToFloat32:
      case ConvertSInt64ToFloat32:
        return value.convertSIToF32();
      case ConvertSInt32ToFloat64:
      case ConvertSInt64ToFloat64:
        return value.convertSIToF64();
      case ExtendS8Int32:
      case ExtendS8Int64:
        return value.extendS8();
      case ExtendS16Int32:
      case ExtendS16Int64:
        return value.extendS16();
      case ExtendS32Int64:
        return value.extendS32();
      case NegFloat32:
      case NegFloat64:
        return value.neg();
      case AbsFloat32:
      case AbsFloat64:
        return value.abs();
      case CeilFloat32:
      case CeilFloat64:
        return value.ceil();
      case FloorFloat32:
      case FloorFloat64:
        return value.floor();
      case TruncFloat32:
      case TruncFloat64:
        return value.trunc();
      case NearestFloat32:
      case NearestFloat64:
        return value.nearbyint();
      case SqrtFloat32:
      case SqrtFloat64:
        return value.sqrt();
      case TruncSFloat32ToInt32:
      case TruncSFloat64ToInt32:
      case TruncSFloat32ToInt64:
      case TruncSFloat64ToInt64:
        return truncSFloat(curr, value);
      case TruncUFloat32ToInt32:
      case TruncUFloat64ToInt32:
      case TruncUFloat32ToInt64:
      case TruncUFloat64ToInt64:
        return truncUFloat(curr, value);
      case TruncSatSFloat32ToInt32:
      case TruncSatSFloat64ToInt32:
        return value.truncSatToSI32();
      case TruncSatSFloat32ToInt64:
      case TruncSatSFloat64ToInt64:
        return value.truncSatToSI64();
      case TruncSatUFloat32ToInt32:
      case TruncSatUFloat64ToInt32:
        return value.truncSatToUI32();
      case TruncSatUFloat32ToInt64:
      case TruncSatUFloat64ToInt64:
        return value.truncSatToUI64();
      case ReinterpretFloat32:
        return value.castToI32();
      case PromoteFloat32:
        return value.extendToF64();
      case ReinterpretFloat64:
        return value.castToI64();
      case DemoteFloat64:
        return value.demote();
      case SplatVecI8x16:
        return value.splatI8x16();
      case SplatVecI16x8:
        return value.splatI16x8();
      case SplatVecI32x4:
        return value.splatI32x4();
      case SplatVecI64x2:
        return value.splatI64x2();
      case SplatVecF16x8:
        return value.splatF16x8();
      case SplatVecF32x4:
        return value.splatF32x4();
      case SplatVecF64x2:
        return value.splatF64x2();
      case NotVec128:
        return value.notV128();
      case AnyTrueVec128:
        return value.anyTrueV128();
      case AbsVecI8x16:
        return value.absI8x16();
      case NegVecI8x16:
        return value.negI8x16();
      case AllTrueVecI8x16:
        return value.allTrueI8x16();
      case BitmaskVecI8x16:
        return value.bitmaskI8x16();
      case PopcntVecI8x16:
        return value.popcntI8x16();
      case AbsVecI16x8:
        return value.absI16x8();
      case NegVecI16x8:
        return value.negI16x8();
      case AllTrueVecI16x8:
        return value.allTrueI16x8();
      case BitmaskVecI16x8:
        return value.bitmaskI16x8();
      case AbsVecI32x4:
        return value.absI32x4();
      case NegVecI32x4:
        return value.negI32x4();
      case AllTrueVecI32x4:
        return value.allTrueI32x4();
      case BitmaskVecI32x4:
        return value.bitmaskI32x4();
      case AbsVecI64x2:
        return value.absI64x2();
      case NegVecI64x2:
        return value.negI64x2();
      case AllTrueVecI64x2:
        return value.allTrueI64x2();
      case BitmaskVecI64x2:
        return value.bitmaskI64x2();
      case AbsVecF16x8:
        return value.absF16x8();
      case NegVecF16x8:
        return value.negF16x8();
      case SqrtVecF16x8:
        return value.sqrtF16x8();
      case CeilVecF16x8:
        return value.ceilF16x8();
      case FloorVecF16x8:
        return value.floorF16x8();
      case TruncVecF16x8:
        return value.truncF16x8();
      case NearestVecF16x8:
        return value.nearestF16x8();
      case AbsVecF32x4:
        return value.absF32x4();
      case NegVecF32x4:
        return value.negF32x4();
      case SqrtVecF32x4:
        return value.sqrtF32x4();
      case CeilVecF32x4:
        return value.ceilF32x4();
      case FloorVecF32x4:
        return value.floorF32x4();
      case TruncVecF32x4:
        return value.truncF32x4();
      case NearestVecF32x4:
        return value.nearestF32x4();
      case AbsVecF64x2:
        return value.absF64x2();
      case NegVecF64x2:
        return value.negF64x2();
      case SqrtVecF64x2:
        return value.sqrtF64x2();
      case CeilVecF64x2:
        return value.ceilF64x2();
      case FloorVecF64x2:
        return value.floorF64x2();
      case TruncVecF64x2:
        return value.truncF64x2();
      case NearestVecF64x2:
        return value.nearestF64x2();
      case ExtAddPairwiseSVecI8x16ToI16x8:
        return value.extAddPairwiseToSI16x8();
      case ExtAddPairwiseUVecI8x16ToI16x8:
        return value.extAddPairwiseToUI16x8();
      case ExtAddPairwiseSVecI16x8ToI32x4:
        return value.extAddPairwiseToSI32x4();
      case ExtAddPairwiseUVecI16x8ToI32x4:
        return value.extAddPairwiseToUI32x4();
      case RelaxedTruncSVecF32x4ToVecI32x4:
        // TODO: We could do this only if the actual values are in the relaxed
        //       range.
        if (relaxedBehavior == RelaxedBehavior::NonConstant) {
          return NONCONSTANT_FLOW;
        }
        [[fallthrough]];
      case TruncSatSVecF32x4ToVecI32x4:
        return value.truncSatToSI32x4();
      case RelaxedTruncUVecF32x4ToVecI32x4:
        if (relaxedBehavior == RelaxedBehavior::NonConstant) {
          return NONCONSTANT_FLOW;
        }
        [[fallthrough]];
      case TruncSatUVecF32x4ToVecI32x4:
        return value.truncSatToUI32x4();
      case ConvertSVecI32x4ToVecF32x4:
        return value.convertSToF32x4();
      case ConvertUVecI32x4ToVecF32x4:
        return value.convertUToF32x4();
      case ExtendLowSVecI8x16ToVecI16x8:
        return value.extendLowSToI16x8();
      case ExtendHighSVecI8x16ToVecI16x8:
        return value.extendHighSToI16x8();
      case ExtendLowUVecI8x16ToVecI16x8:
        return value.extendLowUToI16x8();
      case ExtendHighUVecI8x16ToVecI16x8:
        return value.extendHighUToI16x8();
      case ExtendLowSVecI16x8ToVecI32x4:
        return value.extendLowSToI32x4();
      case ExtendHighSVecI16x8ToVecI32x4:
        return value.extendHighSToI32x4();
      case ExtendLowUVecI16x8ToVecI32x4:
        return value.extendLowUToI32x4();
      case ExtendHighUVecI16x8ToVecI32x4:
        return value.extendHighUToI32x4();
      case ExtendLowSVecI32x4ToVecI64x2:
        return value.extendLowSToI64x2();
      case ExtendHighSVecI32x4ToVecI64x2:
        return value.extendHighSToI64x2();
      case ExtendLowUVecI32x4ToVecI64x2:
        return value.extendLowUToI64x2();
      case ExtendHighUVecI32x4ToVecI64x2:
        return value.extendHighUToI64x2();
      case ConvertLowSVecI32x4ToVecF64x2:
        return value.convertLowSToF64x2();
      case ConvertLowUVecI32x4ToVecF64x2:
        return value.convertLowUToF64x2();
      case RelaxedTruncZeroSVecF64x2ToVecI32x4:
        if (relaxedBehavior == RelaxedBehavior::NonConstant) {
          return NONCONSTANT_FLOW;
        }
        [[fallthrough]];
      case TruncSatZeroSVecF64x2ToVecI32x4:
        return value.truncSatZeroSToI32x4();
      case RelaxedTruncZeroUVecF64x2ToVecI32x4:
        if (relaxedBehavior == RelaxedBehavior::NonConstant) {
          return NONCONSTANT_FLOW;
        }
        [[fallthrough]];
      case TruncSatZeroUVecF64x2ToVecI32x4:
        return value.truncSatZeroUToI32x4();
      case DemoteZeroVecF64x2ToVecF32x4:
        return value.demoteZeroToF32x4();
      case PromoteLowVecF32x4ToVecF64x2:
        return value.promoteLowToF64x2();
      case TruncSatSVecF16x8ToVecI16x8:
        return value.truncSatToSI16x8();
      case TruncSatUVecF16x8ToVecI16x8:
        return value.truncSatToUI16x8();
      case ConvertSVecI16x8ToVecF16x8:
        return value.convertSToF16x8();
      case ConvertUVecI16x8ToVecF16x8:
        return value.convertUToF16x8();
      case InvalidUnary:
        WASM_UNREACHABLE("invalid unary op");
    }
    WASM_UNREACHABLE("invalid op");
  }
  Flow visitBinary(Binary* curr) {
    VISIT(flow, curr->left)
    Literal left = flow.getSingleValue();
    VISIT_REUSE(flow, curr->right)
    Literal right = flow.getSingleValue();
    assert(curr->left->type.isConcrete() ? left.type == curr->left->type
                                         : true);
    assert(curr->right->type.isConcrete() ? right.type == curr->right->type
                                          : true);
    switch (curr->op) {
      case AddInt32:
      case AddInt64:
      case AddFloat32:
      case AddFloat64:
        return left.add(right);
      case SubInt32:
      case SubInt64:
      case SubFloat32:
      case SubFloat64:
        return left.sub(right);
      case MulInt32:
      case MulInt64:
      case MulFloat32:
      case MulFloat64:
        return left.mul(right);
      case DivSInt32: {
        if (right.getInteger() == 0) {
          trap("i32.div_s by 0");
        }
        if (left.getInteger() == std::numeric_limits<int32_t>::min() &&
            right.getInteger() == -1) {
          trap("i32.div_s overflow"); // signed division overflow
        }
        return left.divS(right);
      }
      case DivUInt32: {
        if (right.getInteger() == 0) {
          trap("i32.div_u by 0");
        }
        return left.divU(right);
      }
      case RemSInt32: {
        if (right.getInteger() == 0) {
          trap("i32.rem_s by 0");
        }
        if (left.getInteger() == std::numeric_limits<int32_t>::min() &&
            right.getInteger() == -1) {
          return Literal(int32_t(0));
        }
        return left.remS(right);
      }
      case RemUInt32: {
        if (right.getInteger() == 0) {
          trap("i32.rem_u by 0");
        }
        return left.remU(right);
      }
      case DivSInt64: {
        if (right.getInteger() == 0) {
          trap("i64.div_s by 0");
        }
        if (left.getInteger() == LLONG_MIN && right.getInteger() == -1LL) {
          trap("i64.div_s overflow"); // signed division overflow
        }
        return left.divS(right);
      }
      case DivUInt64: {
        if (right.getInteger() == 0) {
          trap("i64.div_u by 0");
        }
        return left.divU(right);
      }
      case RemSInt64: {
        if (right.getInteger() == 0) {
          trap("i64.rem_s by 0");
        }
        if (left.getInteger() == LLONG_MIN && right.getInteger() == -1LL) {
          return Literal(int64_t(0));
        }
        return left.remS(right);
      }
      case RemUInt64: {
        if (right.getInteger() == 0) {
          trap("i64.rem_u by 0");
        }
        return left.remU(right);
      }
      case DivFloat32:
      case DivFloat64:
        return left.div(right);
      case AndInt32:
      case AndInt64:
        return left.and_(right);
      case OrInt32:
      case OrInt64:
        return left.or_(right);
      case XorInt32:
      case XorInt64:
        return left.xor_(right);
      case ShlInt32:
      case ShlInt64:
        return left.shl(right);
      case ShrUInt32:
      case ShrUInt64:
        return left.shrU(right);
      case ShrSInt32:
      case ShrSInt64:
        return left.shrS(right);
      case RotLInt32:
      case RotLInt64:
        return left.rotL(right);
      case RotRInt32:
      case RotRInt64:
        return left.rotR(right);

      case EqInt32:
      case EqInt64:
      case EqFloat32:
      case EqFloat64:
        return left.eq(right);
      case NeInt32:
      case NeInt64:
      case NeFloat32:
      case NeFloat64:
        return left.ne(right);
      case LtSInt32:
      case LtSInt64:
        return left.ltS(right);
      case LtUInt32:
      case LtUInt64:
        return left.ltU(right);
      case LeSInt32:
      case LeSInt64:
        return left.leS(right);
      case LeUInt32:
      case LeUInt64:
        return left.leU(right);
      case GtSInt32:
      case GtSInt64:
        return left.gtS(right);
      case GtUInt32:
      case GtUInt64:
        return left.gtU(right);
      case GeSInt32:
      case GeSInt64:
        return left.geS(right);
      case GeUInt32:
      case GeUInt64:
        return left.geU(right);
      case LtFloat32:
      case LtFloat64:
        return left.lt(right);
      case LeFloat32:
      case LeFloat64:
        return left.le(right);
      case GtFloat32:
      case GtFloat64:
        return left.gt(right);
      case GeFloat32:
      case GeFloat64:
        return left.ge(right);

      case CopySignFloat32:
      case CopySignFloat64:
        return left.copysign(right);
      case MinFloat32:
      case MinFloat64:
        return left.min(right);
      case MaxFloat32:
      case MaxFloat64:
        return left.max(right);

      case EqVecI8x16:
        return left.eqI8x16(right);
      case NeVecI8x16:
        return left.neI8x16(right);
      case LtSVecI8x16:
        return left.ltSI8x16(right);
      case LtUVecI8x16:
        return left.ltUI8x16(right);
      case GtSVecI8x16:
        return left.gtSI8x16(right);
      case GtUVecI8x16:
        return left.gtUI8x16(right);
      case LeSVecI8x16:
        return left.leSI8x16(right);
      case LeUVecI8x16:
        return left.leUI8x16(right);
      case GeSVecI8x16:
        return left.geSI8x16(right);
      case GeUVecI8x16:
        return left.geUI8x16(right);
      case EqVecI16x8:
        return left.eqI16x8(right);
      case NeVecI16x8:
        return left.neI16x8(right);
      case LtSVecI16x8:
        return left.ltSI16x8(right);
      case LtUVecI16x8:
        return left.ltUI16x8(right);
      case GtSVecI16x8:
        return left.gtSI16x8(right);
      case GtUVecI16x8:
        return left.gtUI16x8(right);
      case LeSVecI16x8:
        return left.leSI16x8(right);
      case LeUVecI16x8:
        return left.leUI16x8(right);
      case GeSVecI16x8:
        return left.geSI16x8(right);
      case GeUVecI16x8:
        return left.geUI16x8(right);
      case EqVecI32x4:
        return left.eqI32x4(right);
      case NeVecI32x4:
        return left.neI32x4(right);
      case LtSVecI32x4:
        return left.ltSI32x4(right);
      case LtUVecI32x4:
        return left.ltUI32x4(right);
      case GtSVecI32x4:
        return left.gtSI32x4(right);
      case GtUVecI32x4:
        return left.gtUI32x4(right);
      case LeSVecI32x4:
        return left.leSI32x4(right);
      case LeUVecI32x4:
        return left.leUI32x4(right);
      case GeSVecI32x4:
        return left.geSI32x4(right);
      case GeUVecI32x4:
        return left.geUI32x4(right);
      case EqVecI64x2:
        return left.eqI64x2(right);
      case NeVecI64x2:
        return left.neI64x2(right);
      case LtSVecI64x2:
        return left.ltSI64x2(right);
      case GtSVecI64x2:
        return left.gtSI64x2(right);
      case LeSVecI64x2:
        return left.leSI64x2(right);
      case GeSVecI64x2:
        return left.geSI64x2(right);
      case EqVecF16x8:
        return left.eqF16x8(right);
      case NeVecF16x8:
        return left.neF16x8(right);
      case LtVecF16x8:
        return left.ltF16x8(right);
      case GtVecF16x8:
        return left.gtF16x8(right);
      case LeVecF16x8:
        return left.leF16x8(right);
      case GeVecF16x8:
        return left.geF16x8(right);
      case EqVecF32x4:
        return left.eqF32x4(right);
      case NeVecF32x4:
        return left.neF32x4(right);
      case LtVecF32x4:
        return left.ltF32x4(right);
      case GtVecF32x4:
        return left.gtF32x4(right);
      case LeVecF32x4:
        return left.leF32x4(right);
      case GeVecF32x4:
        return left.geF32x4(right);
      case EqVecF64x2:
        return left.eqF64x2(right);
      case NeVecF64x2:
        return left.neF64x2(right);
      case LtVecF64x2:
        return left.ltF64x2(right);
      case GtVecF64x2:
        return left.gtF64x2(right);
      case LeVecF64x2:
        return left.leF64x2(right);
      case GeVecF64x2:
        return left.geF64x2(right);

      case AndVec128:
        return left.andV128(right);
      case OrVec128:
        return left.orV128(right);
      case XorVec128:
        return left.xorV128(right);
      case AndNotVec128:
        return left.andV128(right.notV128());

      case AddVecI8x16:
        return left.addI8x16(right);
      case AddSatSVecI8x16:
        return left.addSaturateSI8x16(right);
      case AddSatUVecI8x16:
        return left.addSaturateUI8x16(right);
      case SubVecI8x16:
        return left.subI8x16(right);
      case SubSatSVecI8x16:
        return left.subSaturateSI8x16(right);
      case SubSatUVecI8x16:
        return left.subSaturateUI8x16(right);
      case MinSVecI8x16:
        return left.minSI8x16(right);
      case MinUVecI8x16:
        return left.minUI8x16(right);
      case MaxSVecI8x16:
        return left.maxSI8x16(right);
      case MaxUVecI8x16:
        return left.maxUI8x16(right);
      case AvgrUVecI8x16:
        return left.avgrUI8x16(right);
      case AddVecI16x8:
        return left.addI16x8(right);
      case AddSatSVecI16x8:
        return left.addSaturateSI16x8(right);
      case AddSatUVecI16x8:
        return left.addSaturateUI16x8(right);
      case SubVecI16x8:
        return left.subI16x8(right);
      case SubSatSVecI16x8:
        return left.subSaturateSI16x8(right);
      case SubSatUVecI16x8:
        return left.subSaturateUI16x8(right);
      case MulVecI16x8:
        return left.mulI16x8(right);
      case MinSVecI16x8:
        return left.minSI16x8(right);
      case MinUVecI16x8:
        return left.minUI16x8(right);
      case MaxSVecI16x8:
        return left.maxSI16x8(right);
      case MaxUVecI16x8:
        return left.maxUI16x8(right);
      case AvgrUVecI16x8:
        return left.avgrUI16x8(right);
      case RelaxedQ15MulrSVecI16x8:
        if (relaxedBehavior == RelaxedBehavior::NonConstant) {
          return NONCONSTANT_FLOW;
        }
        [[fallthrough]];
      case Q15MulrSatSVecI16x8:
        return left.q15MulrSatSI16x8(right);
      case ExtMulLowSVecI16x8:
        return left.extMulLowSI16x8(right);
      case ExtMulHighSVecI16x8:
        return left.extMulHighSI16x8(right);
      case ExtMulLowUVecI16x8:
        return left.extMulLowUI16x8(right);
      case ExtMulHighUVecI16x8:
        return left.extMulHighUI16x8(right);
      case AddVecI32x4:
        return left.addI32x4(right);
      case SubVecI32x4:
        return left.subI32x4(right);
      case MulVecI32x4:
        return left.mulI32x4(right);
      case MinSVecI32x4:
        return left.minSI32x4(right);
      case MinUVecI32x4:
        return left.minUI32x4(right);
      case MaxSVecI32x4:
        return left.maxSI32x4(right);
      case MaxUVecI32x4:
        return left.maxUI32x4(right);
      case DotSVecI16x8ToVecI32x4:
        return left.dotSI16x8toI32x4(right);
      case ExtMulLowSVecI32x4:
        return left.extMulLowSI32x4(right);
      case ExtMulHighSVecI32x4:
        return left.extMulHighSI32x4(right);
      case ExtMulLowUVecI32x4:
        return left.extMulLowUI32x4(right);
      case ExtMulHighUVecI32x4:
        return left.extMulHighUI32x4(right);
      case AddVecI64x2:
        return left.addI64x2(right);
      case SubVecI64x2:
        return left.subI64x2(right);
      case MulVecI64x2:
        return left.mulI64x2(right);
      case ExtMulLowSVecI64x2:
        return left.extMulLowSI64x2(right);
      case ExtMulHighSVecI64x2:
        return left.extMulHighSI64x2(right);
      case ExtMulLowUVecI64x2:
        return left.extMulLowUI64x2(right);
      case ExtMulHighUVecI64x2:
        return left.extMulHighUI64x2(right);

      case AddVecF16x8:
        return left.addF16x8(right);
      case SubVecF16x8:
        return left.subF16x8(right);
      case MulVecF16x8:
        return left.mulF16x8(right);
      case DivVecF16x8:
        return left.divF16x8(right);
      case MinVecF16x8:
        return left.minF16x8(right);
      case MaxVecF16x8:
        return left.maxF16x8(right);
      case PMinVecF16x8:
        return left.pminF16x8(right);
      case PMaxVecF16x8:
        return left.pmaxF16x8(right);

      case AddVecF32x4:
        return left.addF32x4(right);
      case SubVecF32x4:
        return left.subF32x4(right);
      case MulVecF32x4:
        return left.mulF32x4(right);
      case DivVecF32x4:
        return left.divF32x4(right);
      case RelaxedMinVecF32x4:
        if (relaxedBehavior == RelaxedBehavior::NonConstant) {
          return NONCONSTANT_FLOW;
        }
        [[fallthrough]];
      case MinVecF32x4:
        return left.minF32x4(right);
      case RelaxedMaxVecF32x4:
        if (relaxedBehavior == RelaxedBehavior::NonConstant) {
          return NONCONSTANT_FLOW;
        }
        [[fallthrough]];
      case MaxVecF32x4:
        return left.maxF32x4(right);
      case PMinVecF32x4:
        return left.pminF32x4(right);
      case PMaxVecF32x4:
        return left.pmaxF32x4(right);
      case AddVecF64x2:
        return left.addF64x2(right);
      case SubVecF64x2:
        return left.subF64x2(right);
      case MulVecF64x2:
        return left.mulF64x2(right);
      case DivVecF64x2:
        return left.divF64x2(right);
      case RelaxedMinVecF64x2:
        if (relaxedBehavior == RelaxedBehavior::NonConstant) {
          return NONCONSTANT_FLOW;
        }
        [[fallthrough]];
      case MinVecF64x2:
        return left.minF64x2(right);
      case RelaxedMaxVecF64x2:
        if (relaxedBehavior == RelaxedBehavior::NonConstant) {
          return NONCONSTANT_FLOW;
        }
        [[fallthrough]];
      case MaxVecF64x2:
        return left.maxF64x2(right);
      case PMinVecF64x2:
        return left.pminF64x2(right);
      case PMaxVecF64x2:
        return left.pmaxF64x2(right);

      case NarrowSVecI16x8ToVecI8x16:
        return left.narrowSToI8x16(right);
      case NarrowUVecI16x8ToVecI8x16:
        return left.narrowUToI8x16(right);
      case NarrowSVecI32x4ToVecI16x8:
        return left.narrowSToI16x8(right);
      case NarrowUVecI32x4ToVecI16x8:
        return left.narrowUToI16x8(right);

      case RelaxedSwizzleVecI8x16:
        if (relaxedBehavior == RelaxedBehavior::NonConstant) {
          return NONCONSTANT_FLOW;
        }
        [[fallthrough]];
      case SwizzleVecI8x16:
        return left.swizzleI8x16(right);

      case DotI8x16I7x16SToVecI16x8:
        return left.dotSI8x16toI16x8(right);

      case InvalidBinary:
        WASM_UNREACHABLE("invalid binary op");
    }
    WASM_UNREACHABLE("invalid op");
  }
  Flow visitSIMDExtract(SIMDExtract* curr) {
    VISIT(flow, curr->vec)
    Literal vec = flow.getSingleValue();
    switch (curr->op) {
      case ExtractLaneSVecI8x16:
        return vec.extractLaneSI8x16(curr->index);
      case ExtractLaneUVecI8x16:
        return vec.extractLaneUI8x16(curr->index);
      case ExtractLaneSVecI16x8:
        return vec.extractLaneSI16x8(curr->index);
      case ExtractLaneUVecI16x8:
        return vec.extractLaneUI16x8(curr->index);
      case ExtractLaneVecI32x4:
        return vec.extractLaneI32x4(curr->index);
      case ExtractLaneVecI64x2:
        return vec.extractLaneI64x2(curr->index);
      case ExtractLaneVecF16x8:
        return vec.extractLaneF16x8(curr->index);
      case ExtractLaneVecF32x4:
        return vec.extractLaneF32x4(curr->index);
      case ExtractLaneVecF64x2:
        return vec.extractLaneF64x2(curr->index);
    }
    WASM_UNREACHABLE("invalid op");
  }
  Flow visitSIMDReplace(SIMDReplace* curr) {
    VISIT(flow, curr->vec)
    Literal vec = flow.getSingleValue();
    VISIT_REUSE(flow, curr->value);
    Literal value = flow.getSingleValue();
    switch (curr->op) {
      case ReplaceLaneVecI8x16:
        return vec.replaceLaneI8x16(value, curr->index);
      case ReplaceLaneVecI16x8:
        return vec.replaceLaneI16x8(value, curr->index);
      case ReplaceLaneVecI32x4:
        return vec.replaceLaneI32x4(value, curr->index);
      case ReplaceLaneVecI64x2:
        return vec.replaceLaneI64x2(value, curr->index);
      case ReplaceLaneVecF16x8:
        return vec.replaceLaneF16x8(value, curr->index);
      case ReplaceLaneVecF32x4:
        return vec.replaceLaneF32x4(value, curr->index);
      case ReplaceLaneVecF64x2:
        return vec.replaceLaneF64x2(value, curr->index);
    }
    WASM_UNREACHABLE("invalid op");
  }
  Flow visitSIMDShuffle(SIMDShuffle* curr) {
    VISIT(flow, curr->left)
    Literal left = flow.getSingleValue();
    VISIT_REUSE(flow, curr->right);
    Literal right = flow.getSingleValue();
    return left.shuffleV8x16(right, curr->mask);
  }
  Flow visitSIMDTernary(SIMDTernary* curr) {
    VISIT(flow, curr->a)
    Literal a = flow.getSingleValue();
    VISIT_REUSE(flow, curr->b);
    Literal b = flow.getSingleValue();
    VISIT_REUSE(flow, curr->c);
    Literal c = flow.getSingleValue();
    switch (curr->op) {
      case Bitselect:
      case LaneselectI8x16:
      case LaneselectI16x8:
      case LaneselectI32x4:
      case LaneselectI64x2:
        return c.bitselectV128(a, b);

      case RelaxedMaddVecF16x8:
        if (relaxedBehavior == RelaxedBehavior::NonConstant) {
          return NONCONSTANT_FLOW;
        }
        return a.relaxedMaddF16x8(b, c);
      case RelaxedNmaddVecF16x8:
        if (relaxedBehavior == RelaxedBehavior::NonConstant) {
          return NONCONSTANT_FLOW;
        }
        return a.relaxedNmaddF16x8(b, c);
      case RelaxedMaddVecF32x4:
        if (relaxedBehavior == RelaxedBehavior::NonConstant) {
          return NONCONSTANT_FLOW;
        }
        return a.relaxedMaddF32x4(b, c);
      case RelaxedNmaddVecF32x4:
        if (relaxedBehavior == RelaxedBehavior::NonConstant) {
          return NONCONSTANT_FLOW;
        }
        return a.relaxedNmaddF32x4(b, c);
      case RelaxedMaddVecF64x2:
        if (relaxedBehavior == RelaxedBehavior::NonConstant) {
          return NONCONSTANT_FLOW;
        }
        return a.relaxedMaddF64x2(b, c);
      case RelaxedNmaddVecF64x2:
        if (relaxedBehavior == RelaxedBehavior::NonConstant) {
          return NONCONSTANT_FLOW;
        }
        return a.relaxedNmaddF64x2(b, c);
      case DotI8x16I7x16AddSToVecI32x4:
        if (relaxedBehavior == RelaxedBehavior::NonConstant) {
          return NONCONSTANT_FLOW;
        }
        return a.dotSI8x16toI16x8Add(b, c);
    }
    WASM_UNREACHABLE("invalid op");
  }
  Flow visitSIMDShift(SIMDShift* curr) {
    VISIT(flow, curr->vec)
    Literal vec = flow.getSingleValue();
    VISIT_REUSE(flow, curr->shift);
    Literal shift = flow.getSingleValue();
    switch (curr->op) {
      case ShlVecI8x16:
        return vec.shlI8x16(shift);
      case ShrSVecI8x16:
        return vec.shrSI8x16(shift);
      case ShrUVecI8x16:
        return vec.shrUI8x16(shift);
      case ShlVecI16x8:
        return vec.shlI16x8(shift);
      case ShrSVecI16x8:
        return vec.shrSI16x8(shift);
      case ShrUVecI16x8:
        return vec.shrUI16x8(shift);
      case ShlVecI32x4:
        return vec.shlI32x4(shift);
      case ShrSVecI32x4:
        return vec.shrSI32x4(shift);
      case ShrUVecI32x4:
        return vec.shrUI32x4(shift);
      case ShlVecI64x2:
        return vec.shlI64x2(shift);
      case ShrSVecI64x2:
        return vec.shrSI64x2(shift);
      case ShrUVecI64x2:
        return vec.shrUI64x2(shift);
    }
    WASM_UNREACHABLE("invalid op");
  }
  Flow visitSelect(Select* curr) {
    VISIT(ifTrue, curr->ifTrue)
    VISIT(ifFalse, curr->ifFalse)
    VISIT(condition, curr->condition)
    return condition.getSingleValue().geti32() ? ifTrue : ifFalse; // ;-)
  }
  Flow visitDrop(Drop* curr) {
    VISIT(value, curr->value)
    return Flow();
  }
  Flow visitReturn(Return* curr) {
    Flow flow;
    if (curr->value) {
      VISIT_REUSE(flow, curr->value);
    }
    flow.breakTo = RETURN_FLOW;
    return flow;
  }
  Flow visitNop(Nop* curr) { return Flow(); }
  Flow visitUnreachable(Unreachable* curr) {
    trap("unreachable");
    WASM_UNREACHABLE("unreachable");
  }

  Literal truncSFloat(Unary* curr, Literal value) {
    double val = value.getFloat();
    if (std::isnan(val)) {
      trap("truncSFloat of nan");
    }
    if (curr->type == Type::i32) {
      if (value.type == Type::f32) {
        if (!isInRangeI32TruncS(value.reinterpreti32())) {
          trap("i32.truncSFloat overflow");
        }
      } else {
        if (!isInRangeI32TruncS(value.reinterpreti64())) {
          trap("i32.truncSFloat overflow");
        }
      }
      return Literal(int32_t(val));
    } else {
      if (value.type == Type::f32) {
        if (!isInRangeI64TruncS(value.reinterpreti32())) {
          trap("i64.truncSFloat overflow");
        }
      } else {
        if (!isInRangeI64TruncS(value.reinterpreti64())) {
          trap("i64.truncSFloat overflow");
        }
      }
      return Literal(int64_t(val));
    }
  }

  Literal truncUFloat(Unary* curr, Literal value) {
    double val = value.getFloat();
    if (std::isnan(val)) {
      trap("truncUFloat of nan");
    }
    if (curr->type == Type::i32) {
      if (value.type == Type::f32) {
        if (!isInRangeI32TruncU(value.reinterpreti32())) {
          trap("i32.truncUFloat overflow");
        }
      } else {
        if (!isInRangeI32TruncU(value.reinterpreti64())) {
          trap("i32.truncUFloat overflow");
        }
      }
      return Literal(uint32_t(val));
    } else {
      if (value.type == Type::f32) {
        if (!isInRangeI64TruncU(value.reinterpreti32())) {
          trap("i64.truncUFloat overflow");
        }
      } else {
        if (!isInRangeI64TruncU(value.reinterpreti64())) {
          trap("i64.truncUFloat overflow");
        }
      }
      return Literal(uint64_t(val));
    }
  }
  Flow visitAtomicFence(AtomicFence* curr) {
    // Wasm currently supports only sequentially consistent atomics, in which
    // case atomic_fence can be lowered to nothing.
    return Flow();
  }
  Flow visitPause(Pause* curr) { return Flow(); }
  Flow visitTupleMake(TupleMake* curr) {
    Literals arguments;
    VISIT_ARGUMENTS(flow, curr->operands, arguments);
    for (auto arg : arguments) {
      assert(arg.type.isConcrete());
      flow.values.push_back(arg);
    }
    return flow;
  }
  Flow visitTupleExtract(TupleExtract* curr) {
    VISIT(flow, curr->tuple)
    assert(flow.values.size() > curr->index);
    return Flow(flow.values[curr->index]);
  }
  Flow visitLocalGet(LocalGet* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitLocalSet(LocalSet* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitGlobalGet(GlobalGet* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitGlobalSet(GlobalSet* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitCall(Call* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitCallIndirect(CallIndirect* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitLoad(Load* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitStore(Store* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitMemorySize(MemorySize* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitMemoryGrow(MemoryGrow* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitMemoryInit(MemoryInit* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitDataDrop(DataDrop* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitMemoryCopy(MemoryCopy* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitMemoryFill(MemoryFill* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitAtomicRMW(AtomicRMW* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitAtomicCmpxchg(AtomicCmpxchg* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitAtomicWait(AtomicWait* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitAtomicNotify(AtomicNotify* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitSIMDLoad(SIMDLoad* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitSIMDLoadSplat(SIMDLoad* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitSIMDLoadExtend(SIMDLoad* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitSIMDLoadZero(SIMDLoad* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {
    WASM_UNREACHABLE("unimp");
  }
  Flow visitPop(Pop* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitCallRef(CallRef* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitRefNull(RefNull* curr) {
    return Literal::makeNull(curr->type.getHeapType());
  }
  Flow visitRefIsNull(RefIsNull* curr) {
    VISIT(flow, curr->value)
    const auto& value = flow.getSingleValue();
    return Literal(int32_t(value.isNull()));
  }
  Flow visitRefFunc(RefFunc* curr) {
    // The type may differ from the type in the IR: An imported function may
    // have a more refined type than it was imported as. Imports are handled in
    // subclasses.
    auto* func = self()->getModule()->getFunction(curr->func);
    if (func->imported()) {
      return NONCONSTANT_FLOW;
    }
    // This is a defined function, so the type of the reference matches the
    // actual function.
    return self()->makeFuncData(curr->func, curr->type);
  }
  Flow visitRefEq(RefEq* curr) {
    VISIT(flow, curr->left)
    auto left = flow.getSingleValue();
    VISIT_REUSE(flow, curr->right);
    auto right = flow.getSingleValue();
    return Literal(int32_t(left == right));
  }
  Flow visitTableGet(TableGet* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitTableSet(TableSet* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitTableSize(TableSize* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitTableGrow(TableGrow* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitTableFill(TableFill* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitTableCopy(TableCopy* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitTableInit(TableInit* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitElemDrop(ElemDrop* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitTry(Try* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitTryTable(TryTable* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitThrow(Throw* curr) {
    // Single-module implementation. This is used from Precompute, for example.
    // It is overriden in ModuleRunner to add logic for finding the proper
    // imported tag (which single-module cases don't care about).
    Literals arguments;
    VISIT_ARGUMENTS(flow, curr->operands, arguments);
    auto* tag = self()->getModule()->getTag(curr->tag);
    if (tag->imported()) {
      // The same tag can be imported twice, so by looking at only the current
      // module we can't tell if two tags are the same or not.
      return NONCONSTANT_FLOW;
    }
    throwException(WasmException{self()->makeExnData(tag, arguments)});
    WASM_UNREACHABLE("throw");
  }
  Flow visitRethrow(Rethrow* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitThrowRef(ThrowRef* curr) {
    VISIT(flow, curr->exnref)
    const auto& exnref = flow.getSingleValue();
    if (exnref.isNull()) {
      trap("null ref");
    }
    assert(exnref.isExn());
    throwException(WasmException{exnref});
    WASM_UNREACHABLE("throw");
  }
  Flow visitRefI31(RefI31* curr) {
    VISIT(flow, curr->value)
    const auto& value = flow.getSingleValue();
    return Literal::makeI31(value.geti32(),
                            curr->type.getHeapType().getShared());
  }
  Flow visitI31Get(I31Get* curr) {
    VISIT(flow, curr->i31)
    const auto& value = flow.getSingleValue();
    if (value.isNull()) {
      trap("null ref");
    }
    return Literal(value.geti31(curr->signed_));
  }

  // Helper for ref.test, ref.cast, and br_on_cast, which share almost all their
  // logic except for what they return.
  struct Cast {
    // The control flow that preempts the cast.
    struct Breaking : Flow {
      Breaking(Flow breaking) : Flow(breaking) {}
    };
    // The result of the successful cast.
    struct Success : Literal {
      Success(Literal result) : Literal(result) {}
    };
    // The input to a failed cast.
    struct Failure : Literal {
      Failure(Literal original) : Literal(original) {}
    };

    std::variant<Breaking, Success, Failure> state;

    template<class T> Cast(T state) : state(state) {}
    Flow* getBreaking() { return std::get_if<Breaking>(&state); }
    Literal* getSuccess() { return std::get_if<Success>(&state); }
    Literal* getFailure() { return std::get_if<Failure>(&state); }
  };

  template<typename T> Cast doCast(T* curr) {
    Flow ref = self()->visit(curr->ref);
    if (ref.breaking()) {
      return typename Cast::Breaking{ref};
    }
    Literal val = ref.getSingleValue();
    Type castType = curr->getCastType();
    if (Type::isSubType(val.type, castType)) {
      return typename Cast::Success{val};
    } else {
      return typename Cast::Failure{val};
    }
  }
  template<typename T> Cast doDescCast(T* curr) {
    Flow ref = self()->visit(curr->ref);
    if (ref.breaking()) {
      return typename Cast::Breaking{ref};
    }
    Flow desc = self()->visit(curr->desc);
    if (desc.breaking()) {
      return typename Cast::Breaking{desc};
    }
    auto expected = desc.getSingleValue().getGCData();
    if (!expected) {
      trap("null descriptor");
    }
    Literal val = ref.getSingleValue();
    if (!val.isData() && !val.isNull()) {
      // For example, i31ref.
      return typename Cast::Failure{val};
    }
    auto data = val.getGCData();
    if (!data) {
      // Check whether null is allowed.
      if (curr->getCastType().isNullable()) {
        return typename Cast::Success{val};
      } else {
        return typename Cast::Failure{val};
      }
    }
    // The cast succeeds if we have the expected descriptor.
    if (data->desc.getGCData() == expected) {
      return typename Cast::Success{val};
    } else {
      return typename Cast::Failure{val};
    }
  }

  Flow visitRefTest(RefTest* curr) {
    auto cast = doCast(curr);
    if (auto* breaking = cast.getBreaking()) {
      return *breaking;
    } else {
      return Literal(int32_t(bool(cast.getSuccess())));
    }
  }
  Flow visitRefCast(RefCast* curr) {
    auto cast = curr->desc ? doDescCast(curr) : doCast(curr);
    if (auto* breaking = cast.getBreaking()) {
      return *breaking;
    } else if (auto* result = cast.getSuccess()) {
      return *result;
    }
    assert(cast.getFailure());
    trap("cast error");
    WASM_UNREACHABLE("unreachable");
  }
  Flow visitRefGetDesc(RefGetDesc* curr) {
    VISIT(ref, curr->ref)
    auto data = ref.getSingleValue().getGCData();
    if (!data) {
      trap("null ref");
    }
    return data->desc;
  }
  Flow visitBrOn(BrOn* curr) {
    // BrOnCast* uses the casting infrastructure, so handle them first.
    switch (curr->op) {
      case BrOnCast:
      case BrOnCastFail:
      case BrOnCastDescEq:
      case BrOnCastDescEqFail: {
        auto cast = curr->desc ? doDescCast(curr) : doCast(curr);
        if (auto* breaking = cast.getBreaking()) {
          return *breaking;
        } else if (auto* original = cast.getFailure()) {
          if (curr->op == BrOnCast || curr->op == BrOnCastDescEq) {
            return *original;
          } else {
            return Flow(curr->name, *original);
          }
        } else {
          auto* result = cast.getSuccess();
          assert(result);
          if (curr->op == BrOnCast || curr->op == BrOnCastDescEq) {
            return Flow(curr->name, *result);
          } else {
            return *result;
          }
        }
      }
      case BrOnNull:
      case BrOnNonNull: {
        // Otherwise we are just checking for null.
        VISIT(flow, curr->ref)
        const auto& value = flow.getSingleValue();
        if (curr->op == BrOnNull) {
          // BrOnNull does not propagate the value if it takes the branch.
          if (value.isNull()) {
            return Flow(curr->name);
          }
          // If the branch is not taken, we return the non-null value.
          return {value};
        } else {
          // BrOnNonNull does not return a value if it does not take the branch.
          if (value.isNull()) {
            return Flow();
          }
          // If the branch is taken, we send the non-null value.
          return Flow(curr->name, value);
        }
      }
    }
    WASM_UNREACHABLE("unexpected op");
  }
  Flow visitStructNew(StructNew* curr) {
    if (curr->type == Type::unreachable) {
      // We cannot proceed to compute the heap type, as there isn't one. Just
      // find why we are unreachable, and stop there.
      for (auto* operand : curr->operands) {
        VISIT(value, operand)
      }
      if (curr->desc) {
        VISIT(value, curr->desc)
      }
      WASM_UNREACHABLE("unreachable but no unreachable child");
    }
    auto heapType = curr->type.getHeapType();
    const auto& fields = heapType.getStruct().fields;
    Literals data(fields.size());
    for (Index i = 0; i < fields.size(); i++) {
      auto& field = fields[i];
      if (curr->isWithDefault()) {
        data[i] = Literal::makeZero(field.type);
      } else {
        VISIT(value, curr->operands[i])
        data[i] = truncateForPacking(value.getSingleValue(), field);
      }
    }
    if (!curr->desc) {
      return makeGCData(std::move(data), curr->type);
    }
    VISIT(desc, curr->desc)
    if (desc.getSingleValue().isNull()) {
      trap("null descriptor");
    }
    return makeGCData(std::move(data), curr->type, desc.getSingleValue());
  }
  Flow visitStructGet(StructGet* curr) {
    VISIT(ref, curr->ref)
    auto data = ref.getSingleValue().getGCData();
    if (!data) {
      trap("null ref");
    }
    auto field = curr->ref->type.getHeapType().getStruct().fields[curr->index];
    return extendForPacking(data->values[curr->index], field, curr->signed_);
  }
  Flow visitStructSet(StructSet* curr) {
    VISIT(ref, curr->ref)
    VISIT(value, curr->value)
    auto data = ref.getSingleValue().getGCData();
    if (!data) {
      trap("null ref");
    }
    auto field = curr->ref->type.getHeapType().getStruct().fields[curr->index];
    data->values[curr->index] =
      truncateForPacking(value.getSingleValue(), field);
    return Flow();
  }

  Flow visitStructRMW(StructRMW* curr) {
    VISIT(ref, curr->ref)
    VISIT(value, curr->value)
    auto data = ref.getSingleValue().getGCData();
    if (!data) {
      trap("null ref");
    }
    auto& field = data->values[curr->index];
    auto oldVal = field;
    auto newVal = value.getSingleValue();
    switch (curr->op) {
      case RMWAdd:
        field = field.add(newVal);
        break;
      case RMWSub:
        field = field.sub(newVal);
        break;
      case RMWAnd:
        field = field.and_(newVal);
        break;
      case RMWOr:
        field = field.or_(newVal);
        break;
      case RMWXor:
        field = field.xor_(newVal);
        break;
      case RMWXchg:
        field = newVal;
        break;
    }
    return oldVal;
  }

  Flow visitStructCmpxchg(StructCmpxchg* curr) {
    VISIT(ref, curr->ref)
    VISIT(expected, curr->expected)
    VISIT(replacement, curr->replacement)
    auto data = ref.getSingleValue().getGCData();
    if (!data) {
      trap("null ref");
    }
    auto& field = data->values[curr->index];
    auto oldVal = field;
    if (field == expected.getSingleValue()) {
      field = replacement.getSingleValue();
    }
    return oldVal;
  }

  // Arbitrary deterministic limit on size. If we need to allocate a Literals
  // vector that takes around 1-2GB of memory then we are likely to hit memory
  // limits on 32-bit machines, and in particular on wasm32 VMs that do not
  // have 4GB support, so give up there.
  static const Index DataLimit = (1 << 30) / sizeof(Literal);

  Flow visitArrayNew(ArrayNew* curr) {
    Flow init;
    if (!curr->isWithDefault()) {
      VISIT_REUSE(init, curr->init);
    }
    VISIT(size, curr->size)
    if (curr->type == Type::unreachable) {
      // We cannot proceed to compute the heap type, as there isn't one. Just
      // visit the unreachable child, and stop there.
      auto init = self()->visit(curr->init);
      assert(init.breaking());
      return init;
    }
    auto heapType = curr->type.getHeapType();
    const auto& element = heapType.getArray().element;
    Index num = size.getSingleValue().geti32();
    if (num >= DataLimit) {
      hostLimit("allocation failure");
    }
    Literals data(num);
    if (curr->isWithDefault()) {
      auto zero = Literal::makeZero(element.type);
      for (Index i = 0; i < num; i++) {
        data[i] = zero;
      }
    } else {
      auto field = curr->type.getHeapType().getArray().element;
      auto value = truncateForPacking(init.getSingleValue(), field);
      for (Index i = 0; i < num; i++) {
        data[i] = value;
      }
    }
    return makeGCData(std::move(data), curr->type);
  }
  Flow visitArrayNewData(ArrayNewData* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitArrayNewElem(ArrayNewElem* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitArrayNewFixed(ArrayNewFixed* curr) {
    Index num = curr->values.size();
    if (num >= DataLimit) {
      hostLimit("allocation failure");
    }
    if (curr->type == Type::unreachable) {
      // We cannot proceed to compute the heap type, as there isn't one. Just
      // find why we are unreachable, and stop there.
      for (auto* value : curr->values) {
        VISIT(result, value)
      }
      WASM_UNREACHABLE("unreachable but no unreachable child");
    }
    auto heapType = curr->type.getHeapType();
    auto field = heapType.getArray().element;
    Literals data(num);
    for (Index i = 0; i < num; i++) {
      VISIT(value, curr->values[i])
      data[i] = truncateForPacking(value.getSingleValue(), field);
    }
    return makeGCData(std::move(data), curr->type);
  }
  Flow visitArrayGet(ArrayGet* curr) {
    VISIT(ref, curr->ref)
    VISIT(index, curr->index)
    auto data = ref.getSingleValue().getGCData();
    if (!data) {
      trap("null ref");
    }
    Index i = index.getSingleValue().geti32();
    if (i >= data->values.size()) {
      trap("array oob");
    }
    auto field = curr->ref->type.getHeapType().getArray().element;
    return extendForPacking(data->values[i], field, curr->signed_);
  }
  Flow visitArraySet(ArraySet* curr) {
    VISIT(ref, curr->ref)
    VISIT(index, curr->index)
    VISIT(value, curr->value)
    auto data = ref.getSingleValue().getGCData();
    if (!data) {
      trap("null ref");
    }
    Index i = index.getSingleValue().geti32();
    if (i >= data->values.size()) {
      trap("array oob");
    }
    auto field = curr->ref->type.getHeapType().getArray().element;
    data->values[i] = truncateForPacking(value.getSingleValue(), field);
    return Flow();
  }
  Flow visitArrayLen(ArrayLen* curr) {
    VISIT(ref, curr->ref)
    auto data = ref.getSingleValue().getGCData();
    if (!data) {
      trap("null ref");
    }
    return Literal(int32_t(data->values.size()));
  }
  Flow visitArrayCopy(ArrayCopy* curr) {
    VISIT(destRef, curr->destRef)
    VISIT(destIndex, curr->destIndex)
    VISIT(srcRef, curr->srcRef)
    VISIT(srcIndex, curr->srcIndex)
    VISIT(length, curr->length)
    auto destData = destRef.getSingleValue().getGCData();
    if (!destData) {
      trap("null ref");
    }
    auto srcData = srcRef.getSingleValue().getGCData();
    if (!srcData) {
      trap("null ref");
    }
    size_t destVal = destIndex.getSingleValue().getUnsigned();
    size_t srcVal = srcIndex.getSingleValue().getUnsigned();
    size_t lengthVal = length.getSingleValue().getUnsigned();
    if (destVal + lengthVal > destData->values.size()) {
      trap("oob");
    }
    if (srcVal + lengthVal > srcData->values.size()) {
      trap("oob");
    }
    std::vector<Literal> copied;
    copied.resize(lengthVal);
    for (size_t i = 0; i < lengthVal; i++) {
      copied[i] = srcData->values[srcVal + i];
    }
    for (size_t i = 0; i < lengthVal; i++) {
      destData->values[destVal + i] = copied[i];
    }
    return Flow();
  }
  Flow visitArrayFill(ArrayFill* curr) {
    VISIT(ref, curr->ref)
    VISIT(index, curr->index)
    VISIT(value, curr->value)
    VISIT(size, curr->size)
    auto data = ref.getSingleValue().getGCData();
    if (!data) {
      trap("null ref");
    }
    size_t indexVal = index.getSingleValue().getUnsigned();
    Literal fillVal = value.getSingleValue();
    size_t sizeVal = size.getSingleValue().getUnsigned();

    auto field = curr->ref->type.getHeapType().getArray().element;
    fillVal = truncateForPacking(fillVal, field);

    size_t arraySize = data->values.size();
    if (indexVal > arraySize || sizeVal > arraySize ||
        indexVal + sizeVal > arraySize || indexVal + sizeVal < indexVal) {
      trap("out of bounds array access in array.fill");
    }
    for (size_t i = 0; i < sizeVal; ++i) {
      data->values[indexVal + i] = fillVal;
    }
    return {};
  }
  Flow visitArrayInitData(ArrayInitData* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitArrayInitElem(ArrayInitElem* curr) { WASM_UNREACHABLE("unimp"); }
  Flow visitArrayRMW(ArrayRMW* curr) {
    VISIT(ref, curr->ref)
    VISIT(index, curr->index)
    VISIT(value, curr->value)
    auto data = ref.getSingleValue().getGCData();
    if (!data) {
      trap("null ref");
    }
    size_t indexVal = index.getSingleValue().getUnsigned();
    auto& field = data->values[indexVal];
    auto oldVal = field;
    auto newVal = value.getSingleValue();
    switch (curr->op) {
      case RMWAdd:
        field = field.add(newVal);
        break;
      case RMWSub:
        field = field.sub(newVal);
        break;
      case RMWAnd:
        field = field.and_(newVal);
        break;
      case RMWOr:
        field = field.or_(newVal);
        break;
      case RMWXor:
        field = field.xor_(newVal);
        break;
      case RMWXchg:
        field = newVal;
        break;
    }
    return oldVal;
  }

  Flow visitArrayCmpxchg(ArrayCmpxchg* curr) {
    VISIT(ref, curr->ref)
    VISIT(index, curr->index)
    VISIT(expected, curr->expected)
    VISIT(replacement, curr->replacement)
    auto data = ref.getSingleValue().getGCData();
    if (!data) {
      trap("null ref");
    }
    size_t indexVal = index.getSingleValue().getUnsigned();
    auto& field = data->values[indexVal];
    auto oldVal = field;
    if (field == expected.getSingleValue()) {
      field = replacement.getSingleValue();
    }
    return oldVal;
  }
  Flow visitRefAs(RefAs* curr) {
    VISIT(flow, curr->value)
    const auto& value = flow.getSingleValue();
    switch (curr->op) {
      case RefAsNonNull:
        if (value.isNull()) {
          trap("null ref");
        }
        return value;
      case AnyConvertExtern:
        return value.internalize();
      case ExternConvertAny:
        return value.externalize();
    }
    WASM_UNREACHABLE("unimplemented ref.as_*");
  }
  Flow visitStringNew(StringNew* curr) {
    VISIT(ptr, curr->ref)
    switch (curr->op) {
      case StringNewWTF16Array: {
        VISIT(start, curr->start)
        VISIT(end, curr->end)
        auto ptrData = ptr.getSingleValue().getGCData();
        if (!ptrData) {
          trap("null ref");
        }
        const auto& ptrDataValues = ptrData->values;
        size_t startVal = start.getSingleValue().getUnsigned();
        size_t endVal = end.getSingleValue().getUnsigned();
        if (startVal > ptrDataValues.size() || endVal > ptrDataValues.size() ||
            endVal < startVal) {
          trap("array oob");
        }
        Literals contents;
        if (endVal > startVal) {
          contents.reserve(endVal - startVal);
          for (size_t i = startVal; i < endVal; i++) {
            contents.push_back(ptrDataValues[i]);
          }
        }
        return makeGCData(std::move(contents), curr->type);
      }
      case StringNewFromCodePoint: {
        uint32_t codePoint = ptr.getSingleValue().getUnsigned();
        if (codePoint > 0x10FFFF) {
          trap("invalid code point");
        }
        std::stringstream wtf16;
        String::writeWTF16CodePoint(wtf16, codePoint);
        std::string str = wtf16.str();
        return Literal(str);
      }
      default:
        // TODO: others
        return Flow(NONCONSTANT_FLOW);
    }
  }
  Flow visitStringConst(StringConst* curr) { return Literal(curr->string.str); }

  Flow visitStringMeasure(StringMeasure* curr) {
    // For now we only support JS-style strings.
    if (curr->op != StringMeasureWTF16) {
      return Flow(NONCONSTANT_FLOW);
    }

    VISIT(flow, curr->ref)
    auto value = flow.getSingleValue();
    auto data = value.getGCData();
    if (!data) {
      trap("null ref");
    }

    return Literal(int32_t(data->values.size()));
  }
  Flow visitStringConcat(StringConcat* curr) {
    VISIT(flow, curr->left)
    auto left = flow.getSingleValue();
    VISIT_REUSE(flow, curr->right);
    auto right = flow.getSingleValue();
    auto leftData = left.getGCData();
    auto rightData = right.getGCData();
    if (!leftData || !rightData) {
      trap("null ref");
    }

    auto totalSize = leftData->values.size() + rightData->values.size();
    if (totalSize >= DataLimit) {
      hostLimit("allocation failure");
    }

    Literals contents;
    contents.reserve(leftData->values.size() + rightData->values.size());
    for (Literal& l : leftData->values) {
      contents.push_back(l);
    }
    for (Literal& l : rightData->values) {
      contents.push_back(l);
    }

    return makeGCData(std::move(contents), curr->type);
  }
  Flow visitStringEncode(StringEncode* curr) {
    // For now we only support JS-style strings into arrays.
    if (curr->op != StringEncodeWTF16Array) {
      return Flow(NONCONSTANT_FLOW);
    }

    VISIT(str, curr->str)
    VISIT(array, curr->array)
    VISIT(start, curr->start)

    auto strData = str.getSingleValue().getGCData();
    auto arrayData = array.getSingleValue().getGCData();
    if (!strData || !arrayData) {
      trap("null ref");
    }
    auto startVal = start.getSingleValue().getUnsigned();
    auto& strValues = strData->values;
    auto& arrayValues = arrayData->values;
    size_t end;
    if (std::ckd_add<size_t>(&end, startVal, strValues.size()) ||
        end > arrayValues.size()) {
      trap("oob");
    }

    for (Index i = 0; i < strValues.size(); i++) {
      arrayValues[startVal + i] = strValues[i];
    }

    return Literal(int32_t(strData->values.size()));
  }
  Flow visitStringEq(StringEq* curr) {
    VISIT(flow, curr->left)
    auto left = flow.getSingleValue();
    VISIT_REUSE(flow, curr->right);
    auto right = flow.getSingleValue();
    auto leftData = left.getGCData();
    auto rightData = right.getGCData();
    int32_t result;
    switch (curr->op) {
      case StringEqEqual: {
        // They are equal if both are null, or both are non-null and equal.
        result =
          (!leftData && !rightData) ||
          (leftData && rightData && leftData->values == rightData->values);
        break;
      }
      case StringEqCompare: {
        if (!leftData || !rightData) {
          trap("null ref");
        }
        auto& leftValues = leftData->values;
        auto& rightValues = rightData->values;
        Index i = 0;
        while (1) {
          if (i == leftValues.size() && i == rightValues.size()) {
            // We reached the end, and they are equal.
            result = 0;
            break;
          } else if (i == leftValues.size()) {
            // The left string is short.
            result = -1;
            break;
          } else if (i == rightValues.size()) {
            result = 1;
            break;
          }
          auto left = leftValues[i].getInteger();
          auto right = rightValues[i].getInteger();
          if (left < right) {
            // The left character is lower.
            result = -1;
            break;
          } else if (left > right) {
            result = 1;
            break;
          } else {
            // Look further.
            i++;
          }
        }
        break;
      }
      default: {
        WASM_UNREACHABLE("bad op");
      }
    }
    return Literal(result);
  }
  Flow visitStringTest(StringTest* curr) {
    VISIT(flow, curr->ref)
    auto value = flow.getSingleValue();
    return Literal((uint32_t)value.isString());
  }
  Flow visitStringWTF16Get(StringWTF16Get* curr) {
    VISIT(ref, curr->ref)
    VISIT(pos, curr->pos)
    auto refValue = ref.getSingleValue();
    auto data = refValue.getGCData();
    if (!data) {
      trap("null ref");
    }
    auto& values = data->values;
    Index i = pos.getSingleValue().geti32();
    if (i >= values.size()) {
      trap("string oob");
    }

    return Literal(values[i].geti32());
  }
  Flow visitStringSliceWTF(StringSliceWTF* curr) {
    VISIT(ref, curr->ref)
    VISIT(start, curr->start)
    VISIT(end, curr->end)

    auto refData = ref.getSingleValue().getGCData();
    if (!refData) {
      trap("null ref");
    }
    auto& refValues = refData->values;
    auto startVal = start.getSingleValue().getUnsigned();
    auto endVal = end.getSingleValue().getUnsigned();
    endVal = std::min<size_t>(endVal, refValues.size());

    Literals contents;
    if (endVal > startVal) {
      contents.reserve(endVal - startVal);
      for (size_t i = startVal; i < endVal; i++) {
        if (i < refValues.size()) {
          contents.push_back(refValues[i]);
        }
      }
    }
    return makeGCData(std::move(contents), curr->type);
  }

  virtual void trap(std::string_view why) { WASM_UNREACHABLE("unimp"); }

  virtual void hostLimit(std::string_view why) { WASM_UNREACHABLE("unimp"); }

  virtual void throwException(const WasmException& exn) {
    WASM_UNREACHABLE("unimp");
  }

protected:
  // Truncate the value if we need to. The storage is just a list of Literals,
  // so we can't just write the value like we would to a C struct field and
  // expect it to truncate for us. Instead, we truncate so the stored value is
  // proper for the type.
  Literal truncateForPacking(Literal value, const Field& field) {
    if (field.type == Type::i32) {
      int32_t c = value.geti32();
      if (field.packedType == Field::i8) {
        value = Literal(c & 0xff);
      } else if (field.packedType == Field::i16) {
        value = Literal(c & 0xffff);
      }
    }
    return value;
  }

  Literal extendForPacking(Literal value, const Field& field, bool signed_) {
    if (field.type == Type::i32) {
      int32_t c = value.geti32();
      if (field.packedType == Field::i8) {
        // The stored value should already be truncated.
        assert(c == (c & 0xff));
        if (signed_) {
          value = Literal((c << 24) >> 24);
        }
      } else if (field.packedType == Field::i16) {
        assert(c == (c & 0xffff));
        if (signed_) {
          value = Literal((c << 16) >> 16);
        }
      }
    }
    return value;
  }

  Literal makeFromMemory(void* p, Field field) {
    switch (field.packedType) {
      case Field::not_packed:
        return Literal::makeFromMemory(p, field.type);
      case Field::i8: {
        int8_t i;
        memcpy(&i, p, sizeof(i));
        return truncateForPacking(Literal(int32_t(i)), field);
      }
      case Field::i16: {
        int16_t i;
        memcpy(&i, p, sizeof(i));
        return truncateForPacking(Literal(int32_t(i)), field);
      }
    }
    WASM_UNREACHABLE("unexpected type");
  }
};

// Execute a suspected constant expression (precompute and C-API).
template<typename SubType>
class ConstantExpressionRunner : public ExpressionRunner<SubType> {
public:
  enum FlagValues {
    // By default, just evaluate the expression, i.e. all we want to know is
    // whether it computes down to a concrete value, where it is not necessary
    // to preserve side effects like those of a `local.tee`.
    DEFAULT = 0,
    // Be very careful to preserve any side effects. For example, if we are
    // intending to replace the expression with a constant afterwards, even if
    // we can technically evaluate down to a constant, we still cannot replace
    // the expression if it also sets a local, which must be preserved in this
    // scenario so subsequent code keeps functioning.
    PRESERVE_SIDEEFFECTS = 1 << 0,
  };

  // Flags indicating special requirements, for example whether we are just
  // evaluating (default), also going to replace the expression afterwards or
  // executing in a function-parallel scenario. See FlagValues.
  using Flags = uint32_t;

  // Indicates no limit of maxDepth or maxLoopIterations.
  static const Index NO_LIMIT = 0;

protected:
  // Flags indicating special requirements. See FlagValues.
  Flags flags = FlagValues::DEFAULT;

  // Map remembering concrete local values set in the context of this flow.
  std::unordered_map<Index, Literals> localValues;
  // Map remembering concrete global values set in the context of this flow.
  std::unordered_map<Name, Literals> globalValues;

public:
  ConstantExpressionRunner(Module* module,
                           Flags flags,
                           Index maxDepth,
                           Index maxLoopIterations)
    : ExpressionRunner<SubType>(module, maxDepth, maxLoopIterations),
      flags(flags) {}

  // Sets a known local value to use.
  void setLocalValue(Index index, Literals& values) {
    assert(values.isConcrete());
    localValues[index] = values;
  }

  // Sets a known global value to use.
  void setGlobalValue(Name name, Literals& values) {
    assert(values.isConcrete());
    globalValues[name] = values;
  }

  // Returns true if we set a local or a global.
  bool hasEffectfulSets() const {
    return !localValues.empty() || !globalValues.empty();
  }

  Flow visitLocalGet(LocalGet* curr) {
    // Check if a constant value has been set in the context of this runner.
    auto iter = localValues.find(curr->index);
    if (iter != localValues.end()) {
      return Flow(iter->second);
    }
    return Flow(NONCONSTANT_FLOW);
  }
  Flow visitLocalSet(LocalSet* curr) {
    if (!(flags & FlagValues::PRESERVE_SIDEEFFECTS)) {
      // If we are evaluating and not replacing the expression, remember the
      // constant value set, if any, and see if there is a value flowing through
      // a tee.
      auto setFlow = ExpressionRunner<SubType>::visit(curr->value);
      if (!setFlow.breaking()) {
        setLocalValue(curr->index, setFlow.values);
        if (curr->type.isConcrete()) {
          assert(curr->isTee());
          return setFlow;
        }
        return Flow();
      }
    }
    return Flow(NONCONSTANT_FLOW);
  }
  Flow visitGlobalGet(GlobalGet* curr) {
    if (this->module != nullptr) {
      auto* global = this->module->getGlobal(curr->name);
      // Check if the global has an immutable value anyway
      if (!global->imported() && !global->mutable_) {
        return ExpressionRunner<SubType>::visit(global->init);
      }
    }
    // Check if a constant value has been set in the context of this runner.
    auto iter = globalValues.find(curr->name);
    if (iter != globalValues.end()) {
      return Flow(iter->second);
    }
    return Flow(NONCONSTANT_FLOW);
  }
  Flow visitGlobalSet(GlobalSet* curr) {
    if (!(flags & FlagValues::PRESERVE_SIDEEFFECTS) &&
        this->module != nullptr) {
      // If we are evaluating and not replacing the expression, remember the
      // constant value set, if any, for subsequent gets.
      assert(this->module->getGlobal(curr->name)->mutable_);
      auto setFlow = ExpressionRunner<SubType>::visit(curr->value);
      if (!setFlow.breaking()) {
        setGlobalValue(curr->name, setFlow.values);
        return Flow();
      }
    }
    return Flow(NONCONSTANT_FLOW);
  }
  Flow visitCall(Call* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitCallIndirect(CallIndirect* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitCallRef(CallRef* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitTableGet(TableGet* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitTableSet(TableSet* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitTableSize(TableSize* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitTableGrow(TableGrow* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitTableFill(TableFill* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitTableCopy(TableCopy* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitTableInit(TableInit* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitElemDrop(ElemDrop* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitLoad(Load* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitStore(Store* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitMemorySize(MemorySize* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitMemoryGrow(MemoryGrow* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitMemoryInit(MemoryInit* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitDataDrop(DataDrop* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitMemoryCopy(MemoryCopy* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitMemoryFill(MemoryFill* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitAtomicRMW(AtomicRMW* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitAtomicCmpxchg(AtomicCmpxchg* curr) {
    return Flow(NONCONSTANT_FLOW);
  }
  Flow visitAtomicWait(AtomicWait* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitAtomicNotify(AtomicNotify* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitSIMDLoad(SIMDLoad* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitSIMDLoadSplat(SIMDLoad* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitSIMDLoadExtend(SIMDLoad* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {
    return Flow(NONCONSTANT_FLOW);
  }
  Flow visitArrayNewData(ArrayNewData* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitArrayNewElem(ArrayNewElem* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitArrayCopy(ArrayCopy* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitArrayFill(ArrayFill* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitArrayInitData(ArrayInitData* curr) {
    return Flow(NONCONSTANT_FLOW);
  }
  Flow visitArrayInitElem(ArrayInitElem* curr) {
    return Flow(NONCONSTANT_FLOW);
  }
  Flow visitPop(Pop* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitTry(Try* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitTryTable(TryTable* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitRethrow(Rethrow* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitRefAs(RefAs* curr) {
    // TODO: Remove this once interpretation is implemented.
    if (curr->op == AnyConvertExtern || curr->op == ExternConvertAny) {
      return Flow(NONCONSTANT_FLOW);
    }
    return ExpressionRunner<SubType>::visitRefAs(curr);
  }
  Flow visitContNew(ContNew* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitContBind(ContBind* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitSuspend(Suspend* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitResume(Resume* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitResumeThrow(ResumeThrow* curr) { return Flow(NONCONSTANT_FLOW); }
  Flow visitStackSwitch(StackSwitch* curr) { return Flow(NONCONSTANT_FLOW); }

  void trap(std::string_view why) override { throw NonconstantException(); }

  void hostLimit(std::string_view why) override {
    throw NonconstantException();
  }

  virtual void throwException(const WasmException& exn) override {
    throw NonconstantException();
  }
};

//
// A runner for a module. Each runner contains the information to execute the
// module, such as the state of globals, and so forth, so it basically
// encapsulates an instantiation of the wasm, and implements all the interpreter
// instructions that use that info (like global.set etc.) that are not declared
// in ExpressionRunner, which just looks at a single instruction.
//
// To embed this interpreter, you need to provide an ExternalInterface instance
// (see below) which provides the embedding-specific details, that is, how to
// connect to the embedding implementation.
//
// To call into the interpreter, use callExport.
//

template<typename SubType>
class ModuleRunnerBase : public ExpressionRunner<SubType> {
public:
  //
  // You need to implement one of these to create a concrete interpreter. The
  // ExternalInterface provides embedding-specific functionality like calling
  // an imported function or accessing memory.
  //
  struct ExternalInterface {
    ExternalInterface(
      std::map<Name, std::shared_ptr<SubType>> linkedInstances = {}) {}
    virtual ~ExternalInterface() = default;
    virtual void init(Module& wasm, SubType& instance) {}
    virtual Literal getImportedFunction(Function* import) = 0;
    virtual bool growMemory(Name name, Address oldSize, Address newSize) = 0;
    virtual void trap(std::string_view why) = 0;
    virtual void hostLimit(std::string_view why) = 0;
    virtual void throwException(const WasmException& exn) = 0;

    // the default impls for load and store switch on the sizes. you can either
    // customize load/store, or the sub-functions which they call
    virtual Literal load(Load* load, Address addr, Name memory) {
      switch (load->type.getBasic()) {
        case Type::i32: {
          switch (load->bytes) {
            case 1:
              return load->signed_ ? Literal((int32_t)load8s(addr, memory))
                                   : Literal((int32_t)load8u(addr, memory));
            case 2:
              return load->signed_ ? Literal((int32_t)load16s(addr, memory))
                                   : Literal((int32_t)load16u(addr, memory));
            case 4:
              return Literal((int32_t)load32s(addr, memory));
            default:
              WASM_UNREACHABLE("invalid size");
          }
          break;
        }
        case Type::i64: {
          switch (load->bytes) {
            case 1:
              return load->signed_ ? Literal((int64_t)load8s(addr, memory))
                                   : Literal((int64_t)load8u(addr, memory));
            case 2:
              return load->signed_ ? Literal((int64_t)load16s(addr, memory))
                                   : Literal((int64_t)load16u(addr, memory));
            case 4:
              return load->signed_ ? Literal((int64_t)load32s(addr, memory))
                                   : Literal((int64_t)load32u(addr, memory));
            case 8:
              return Literal((int64_t)load64s(addr, memory));
            default:
              WASM_UNREACHABLE("invalid size");
          }
          break;
        }
        case Type::f32: {
          switch (load->bytes) {
            case 2: {
              // Convert the float16 to float32 and store the binary
              // representation.
              return Literal(bit_cast<int32_t>(
                               fp16_ieee_to_fp32_value(load16u(addr, memory))))
                .castToF32();
            }
            case 4:
              return Literal(load32u(addr, memory)).castToF32();
            default:
              WASM_UNREACHABLE("invalid size");
          }
          break;
        }
        case Type::f64:
          return Literal(load64u(addr, memory)).castToF64();
        case Type::v128:
          return Literal(load128(addr, load->memory).data());
        case Type::none:
        case Type::unreachable:
          WASM_UNREACHABLE("unexpected type");
      }
      WASM_UNREACHABLE("invalid type");
    }
    virtual void store(Store* store, Address addr, Literal value, Name memory) {
      switch (store->valueType.getBasic()) {
        case Type::i32: {
          switch (store->bytes) {
            case 1:
              store8(addr, value.geti32(), memory);
              break;
            case 2:
              store16(addr, value.geti32(), memory);
              break;
            case 4:
              store32(addr, value.geti32(), memory);
              break;
            default:
              WASM_UNREACHABLE("invalid store size");
          }
          break;
        }
        case Type::i64: {
          switch (store->bytes) {
            case 1:
              store8(addr, value.geti64(), memory);
              break;
            case 2:
              store16(addr, value.geti64(), memory);
              break;
            case 4:
              store32(addr, value.geti64(), memory);
              break;
            case 8:
              store64(addr, value.geti64(), memory);
              break;
            default:
              WASM_UNREACHABLE("invalid store size");
          }
          break;
        }
        // write floats carefully, ensuring all bits reach memory
        case Type::f32: {
          switch (store->bytes) {
            case 2: {
              float f32 = bit_cast<float>(value.reinterpreti32());
              // Convert the float32 to float16 and store the binary
              // representation.
              store16(addr, fp16_ieee_from_fp32_value(f32), memory);
              break;
            }
            case 4:
              store32(addr, value.reinterpreti32(), memory);
              break;
            default:
              WASM_UNREACHABLE("invalid store size");
          }
          break;
        }
        case Type::f64:
          store64(addr, value.reinterpreti64(), memory);
          break;
        case Type::v128:
          store128(addr, value.getv128(), memory);
          break;
        case Type::none:
        case Type::unreachable:
          WASM_UNREACHABLE("unexpected type");
      }
    }

    virtual int8_t load8s(Address addr, Name memoryName) {
      WASM_UNREACHABLE("unimp");
    }
    virtual uint8_t load8u(Address addr, Name memoryName) {
      WASM_UNREACHABLE("unimp");
    }
    virtual int16_t load16s(Address addr, Name memoryName) {
      WASM_UNREACHABLE("unimp");
    }
    virtual uint16_t load16u(Address addr, Name memoryName) {
      WASM_UNREACHABLE("unimp");
    }
    virtual int32_t load32s(Address addr, Name memoryName) {
      WASM_UNREACHABLE("unimp");
    }
    virtual uint32_t load32u(Address addr, Name memoryName) {
      WASM_UNREACHABLE("unimp");
    }
    virtual int64_t load64s(Address addr, Name memoryName) {
      WASM_UNREACHABLE("unimp");
    }
    virtual uint64_t load64u(Address addr, Name memoryName) {
      WASM_UNREACHABLE("unimp");
    }
    virtual std::array<uint8_t, 16> load128(Address addr, Name memoryName) {
      WASM_UNREACHABLE("unimp");
    }

    virtual void store8(Address addr, int8_t value, Name memoryName) {
      WASM_UNREACHABLE("unimp");
    }
    virtual void store16(Address addr, int16_t value, Name memoryName) {
      WASM_UNREACHABLE("unimp");
    }
    virtual void store32(Address addr, int32_t value, Name memoryName) {
      WASM_UNREACHABLE("unimp");
    }
    virtual void store64(Address addr, int64_t value, Name memoryName) {
      WASM_UNREACHABLE("unimp");
    }
    virtual void
    store128(Address addr, const std::array<uint8_t, 16>&, Name memoryName) {
      WASM_UNREACHABLE("unimp");
    }
  };

  SubType* self() { return static_cast<SubType*>(this); }

  // TODO: this duplicates module in ExpressionRunner, and can be removed
  Module& wasm;

  // Multivalue ABI support (see push/pop).
  std::vector<Literals> multiValues;

  // Keyed by internal name. All globals in the module, including imports.
  // `definedGlobals` contains non-imported globals. Points to `definedGlobals`
  // of this instance and other instances.
  std::unordered_map<Name, Literals*> allGlobals;

  // Like `allGlobals`. Keyed by internal name. All tables including imports.
  std::unordered_map<Name, RuntimeTable*> allTables;

  std::unordered_map<Name, Tag*> allTags;

  using CreateTableFunc = std::unique_ptr<RuntimeTable>(Literal, Table);

  ModuleRunnerBase(
    Module& wasm,
    ExternalInterface* externalInterface,
    std::shared_ptr<ImportResolver> importResolver,
    std::map<Name, std::shared_ptr<SubType>> linkedInstances_ = {},
    std::function<CreateTableFunc> createTable = {})
    : ExpressionRunner<SubType>(&wasm), wasm(wasm),
      externalInterface(externalInterface),
      linkedInstances(std::move(linkedInstances_)),
      importResolver(std::move(importResolver)),
      createTable(
        createTable != nullptr
          ? std::move(createTable)
          : static_cast<std::function<CreateTableFunc>>(
              [](Literal initial, Table t) -> std::unique_ptr<RuntimeTable> {
                return std::make_unique<RealRuntimeTable>(initial, t);
              })) {
    // Set up a single shared CurrContinuations for all these linked instances,
    // reusing one if it exists.
    std::shared_ptr<ContinuationStore> shared;
    for (auto& [_, instance] : linkedInstances) {
      if (instance->continuationStore) {
        shared = instance->continuationStore;
        break;
      }
    }
    if (!shared) {
      shared = std::make_shared<ContinuationStore>();
    }
    for (auto& [_, instance] : linkedInstances) {
      instance->continuationStore = shared;
    }
    self()->continuationStore = shared;
  }

  // Start up this instance. This must be called before doing anything else.
  // (This is separate from the constructor so that it does not occur
  // synchronously, which makes some code patterns harder to write.)
  void instantiate(bool validateImports_ = false) {
    // initialize the rest of the external interface
    externalInterface->init(wasm, *self());

    if (validateImports_) {
      validateImports();
    }

    initializeGlobals();
    initializeTables();
    initializeTags();

    initializeMemoryContents();

    // run start, if present
    if (wasm.start.is()) {
      Literals arguments;
      callFunction(wasm.start, arguments);
    }
  }

  // call an exported function
  Flow callExport(Name name, const Literals& arguments) {
    return getExportedFunction(name).getFuncData()->doCall(arguments);
  }

  Flow callExport(Name name) { return callExport(name, Literals()); }

  Literal getExportedFunction(Name name) {
    Export* export_ = wasm.getExportOrNull(name);
    if (!export_ || export_->kind != ExternalKind::Function) {
      externalInterface->trap("exported function not found");
    }
    Function* func = wasm.getFunctionOrNull(*export_->getInternalName());
    assert(func);
    if (func->imported()) {
      return externalInterface->getImportedFunction(func);
    }
    return Literal(std::make_shared<FuncData>(
                     func->name,
                     this,
                     [this, func](const Literals& arguments) -> Flow {
                       return callFunction(func->name, arguments);
                     }),
                   func->type);
  }

  Literals* getExportedGlobalOrNull(Name name) {
    Export* export_ = wasm.getExportOrNull(name);
    if (!export_ || export_->kind != ExternalKind::Global) {
      return nullptr;
    }
    Name internalName = *export_->getInternalName();
    auto iter = allGlobals.find(internalName);
    if (iter == allGlobals.end()) {
      return nullptr;
    }
    return iter->second;
  }

  RuntimeTable* getExportedTableOrNull(Name name) {
    Export* export_ = wasm.getExportOrNull(name);
    if (!export_ || export_->kind != ExternalKind::Table) {
      return nullptr;
    }
    Name internalName = *export_->getInternalName();
    auto iter = allTables.find(internalName);
    if (iter == allTables.end()) {
      return nullptr;
    }
    return iter->second;
  }

  Literals& getExportedGlobalOrTrap(Name name) {
    auto* global = getExportedGlobalOrNull(name);
    if (!global) {
      externalInterface->trap((std::stringstream()
                               << "getExportedGlobal: export " << name
                               << " not found.")
                                .str());
    }
    return *global;
  }

  Tag* getExportedTagOrNull(Name name) {
    Export* export_ = wasm.getExportOrNull(name);
    if (!export_ || export_->kind != ExternalKind::Tag) {
      return nullptr;
    }
    Name internalName = *export_->getInternalName();
    auto it = allTags.find(internalName);
    if (it == allTags.end()) {
      return nullptr;
    }
    return it->second;
  }

  Tag& getExportedTagOrTrap(Name name) {
    auto* tag = getExportedTagOrNull(name);
    if (!tag) {
      externalInterface->trap((std::stringstream() << "getExportedTag: export "
                                                   << name << " not found.")
                                .str());
    }

    return *tag;
  }

  std::string printFunctionStack() {
    std::string ret = "/== (binaryen interpreter stack trace)\n";
    for (int i = int(functionStack.size()) - 1; i >= 0; i--) {
      ret += std::string("|: ") + functionStack[i].toString() + "\n";
    }
    ret += std::string("\\==\n");
    return ret;
  }

private:
  // Globals that were defined in this module and not from an import.
  // `allGlobals` contains these values + imported globals, keyed by their
  // internal name.
  std::vector<Literals> definedGlobals;
  std::vector<std::unique_ptr<RuntimeTable>> definedTables;
  std::vector<Tag> definedTags;

  // Keep a record of call depth, to guard against excessive recursion.
  size_t callDepth = 0;

  // Function name stack. We maintain this explicitly to allow printing of
  // stack traces.
  std::vector<Name> functionStack;

  std::unordered_set<Name> droppedDataSegments;
  std::unordered_set<Name> droppedElementSegments;

  // Validates that the export that provides `importable` exists and has the
  // same kind that the import expects (`kind`).
  void validateImportKindMatches(ExternalKind kind,
                                 const Importable& importable) {
    auto it = linkedInstances.find(importable.module);
    if (it == linkedInstances.end()) {
      trap((std::stringstream()
            << "Import module " << std::quoted(importable.module.toString())
            << " doesn't exist.")
             .str());
    }
    auto* importedInstance = it->second.get();

    Export* export_ = importedInstance->wasm.getExportOrNull(importable.base);

    if (!export_) {
      trap((std::stringstream()
            << "Export " << importable.base << " doesn't exist.")
             .str());
    }
    if (export_->kind != kind) {
      trap((std::stringstream() << "Exported kind: " << export_->kind
                                << " doesn't match expected kind: " << kind)
             .str());
    }
  }

  // Trap if types don't match between all imports and their corresponding
  // exports. Imported memories and tables must also be a subtype of their
  // export.
  // TODO: we should also *resolve* the imports here e.g. by writing to
  // allGlobals / allTables etc. First finish migrating all imports here, then
  // enable this code to run in all cases e.g. ctor-eval.
  void validateImports() {
    ModuleUtils::iterImportable(
      wasm,
      [this](ExternalKind kind,
             std::variant<Function*, Memory*, Tag*, Global*, Table*> import) {
        Importable* importable = std::visit(
          [](const auto& import) -> Importable* { return import; }, import);

        // These two modules are injected implicitly to tests. We won't find any
        // import information for them.
        // TODO: remove this workaround once we have a better way of handling
        // intrinsic / spec function imports.
        if (importable->module == "binaryen-intrinsics" ||
            (importable->module == "spectest" &&
             importable->base.startsWith("print")) ||
            importable->module == "fuzzing-support") {
          return;
        }

        validateImportKindMatches(kind, *importable);

        SubType* importedInstance =
          linkedInstances.at(importable->module).get();
        Export* export_ =
          importedInstance->wasm.getExportOrNull(importable->base);

        if (auto** memory = std::get_if<Memory*>(&import)) {
          Memory exportedMemory =
            *importedInstance->wasm.getMemory(*export_->getInternalName());
          exportedMemory.initial =
            importedInstance->getMemorySize(*export_->getInternalName());

          if (!MemoryUtils::isSubType(exportedMemory, **memory)) {
            trap("Imported memory isn't compatible.");
          }
        }

        if (auto** tableDecl = std::get_if<Table*>(&import)) {
          auto* importedTable = importResolver->getTableOrNull(
            importable->importNames(), **tableDecl);
          if (!importedTable) {
            trap((std::stringstream() << "No imported table found for export "
                                      << importable->importNames())
                   .str());
          }
          if (!importedTable->isSubType(**tableDecl)) {
            trap(
              (std::stringstream()
               << "Imported table " << importedTable->getDefinition()
               << " with size " << importedTable->size()
               << " isn't compatible with import declaration: " << **tableDecl)
                .str());
          }
        }
      });
  }

  void initializeGlobals() {
    int definedGlobalCount = 0;
    ModuleUtils::iterDefinedGlobals(
      wasm, [&definedGlobalCount](auto&& _) { ++definedGlobalCount; });
    definedGlobals.reserve(definedGlobalCount);

    for (auto& global : wasm.globals) {
      if (global->imported()) {
        auto importNames = global->importNames();
        auto importedGlobal =
          importResolver->getGlobalOrNull(importNames, global->type);
        if (!importedGlobal) {
          externalInterface->trap((std::stringstream()
                                   << "Imported global " << importNames
                                   << " not found.")
                                    .str());
        }
        [[maybe_unused]] auto [_, inserted] =
          allGlobals.try_emplace(global->name, importedGlobal);
        // parsing/validation checked this already.
        assert(inserted && "Unexpected repeated global name");
      } else {
        Literals init = self()->visit(global->init).values;
        auto& definedGlobal = definedGlobals.emplace_back(std::move(init));

        [[maybe_unused]] auto [_, inserted] =
          allGlobals.try_emplace(global->name, &definedGlobal);
        // parsing/validation checked this already.
        assert(inserted && "Unexpected repeated global name");
      }
    }
  }

  void initializeTags() {
    int definedTagCount = 0;
    ModuleUtils::iterDefinedTags(
      wasm, [&definedTagCount](auto&& _) { ++definedTagCount; });
    definedTags.reserve(definedTagCount);

    for (auto& tag : wasm.tags) {
      if (tag->imported()) {
        auto importNames = tag->importNames();
        auto importedTag =
          importResolver->getTagOrNull(importNames, tag->type.getSignature());
        if (!importedTag) {
          externalInterface->trap((std::stringstream()
                                   << "Imported tag " << importNames
                                   << " not found.")
                                    .str());
        }
        [[maybe_unused]] auto [_, inserted] =
          allTags.try_emplace(tag->name, importedTag);
        // parsing/validation checked this already.
        assert(inserted && "Unexpected repeated tag name");
      } else {
        auto& definedTag = definedTags.emplace_back(*tag);

        [[maybe_unused]] auto [_, inserted] =
          allTags.try_emplace(tag->name, &definedTag);
        // parsing/validation checked this already.
        assert(inserted && "Unexpected repeated tag name");
      }
    }
  }

  void initializeTables() {
    int definedTableCount = 0;
    ModuleUtils::iterDefinedTables(
      wasm, [&definedTableCount](auto&& _) { ++definedTableCount; });
    definedTables.reserve(definedTableCount);

    for (auto& table : wasm.tables) {
      if (table->imported()) {
        auto importNames = table->importNames();
        auto* importedTable =
          importResolver->getTableOrNull(importNames, *table);
        if (!importedTable) {
          externalInterface->trap((std::stringstream()
                                   << "Imported table " << importNames
                                   << " not found.")
                                    .str());
        }
        [[maybe_unused]] auto [_, inserted] =
          allTables.try_emplace(table->name, importedTable);
        // parsing/validation checked this already.
        assert(inserted && "Unexpected repeated table name");
      } else {
        assert(table->type.isNullable() &&
               "We only support nullable tables today");

        auto null = Literal::makeNull(table->type.getHeapType());
        auto& runtimeTable =
          definedTables.emplace_back(createTable(null, *table));
        [[maybe_unused]] auto [_, inserted] =
          allTables.try_emplace(table->name, runtimeTable.get());
        assert(inserted && "Unexpected repeated table name");
      }
    }

    Const zero;
    zero.value = Literal(uint32_t(0));
    zero.finalize();

    ModuleUtils::iterActiveElementSegments(wasm, [&](ElementSegment* segment) {
      Const size;
      size.value = Literal(uint32_t(segment->data.size()));
      size.finalize();

      TableInit init;
      init.table = segment->table;
      init.segment = segment->name;
      init.dest = segment->offset;
      init.offset = &zero;
      init.size = &size;
      init.finalize();

      self()->visit(&init);

      droppedElementSegments.insert(segment->name);
    });
  }

  struct MemoryInstanceInfo {
    // The ModuleRunner instance in which the memory is defined.
    SubType* instance;
    // The external interface in which the memory is defined
    ExternalInterface* interface() { return instance->externalInterface; }
    // The name the memory has in that interface.
    Name name;
  };

  MemoryInstanceInfo getMemoryInstanceInfo(Name name) {
    auto* instance = self();
    Export* memoryExport = nullptr;
    for (auto* memory = instance->wasm.getMemory(name); memory->imported();
         memory = instance->wasm.getMemory(*memoryExport->getInternalName())) {
      instance = instance->linkedInstances.at(memory->module).get();
      memoryExport = instance->wasm.getExport(memory->base);
    }

    if (memoryExport) {
      return instance->getMemoryInstanceInfo(*memoryExport->getInternalName());
    }

    return MemoryInstanceInfo{self(), name};
  }

  void initializeMemoryContents() {
    initializeMemorySizes();

    // apply active memory segments
    for (size_t i = 0, e = wasm.dataSegments.size(); i < e; ++i) {
      auto& segment = wasm.dataSegments[i];
      if (segment->isPassive) {
        continue;
      }

      auto* memory = wasm.getMemory(segment->memory);

      Const zero;
      zero.value = Literal::makeFromInt32(0, memory->addressType);
      zero.finalize();

      Const size;
      size.value =
        Literal::makeFromInt32(segment->data.size(), memory->addressType);
      size.finalize();

      MemoryInit init;
      init.memory = segment->memory;
      init.segment = segment->name;
      init.dest = segment->offset;
      init.offset = &zero;
      init.size = &size;
      init.finalize();

      DataDrop drop;
      drop.segment = segment->name;
      drop.finalize();

      self()->visit(&init);
      self()->visit(&drop);
    }
  }

  // in pages, used to keep track of memorySize throughout the below memops
  std::unordered_map<Name, Address> memorySizes;

  void initializeMemorySizes() {
    for (auto& memory : wasm.memories) {
      memorySizes[memory->name] = memory->initial;
    }
  }

  Address getMemorySize(Name memory) {
    auto info = getMemoryInstanceInfo(memory);
    if (info.instance != self()) {
      return info.instance->getMemorySize(info.name);
    }

    auto iter = memorySizes.find(memory);
    if (iter == memorySizes.end()) {
      externalInterface->trap("getMemorySize called on non-existing memory");
    }
    return iter->second;
  }

  void setMemorySize(Name memory, Address size) {
    auto iter = memorySizes.find(memory);
    if (iter == memorySizes.end()) {
      externalInterface->trap("setMemorySize called on non-existing memory");
    }
    iter->second = size;
  }

public:
  class FunctionScope {
  public:
    std::vector<Literals> locals;
    Function* function;
    SubType& parent;

    FunctionScope* oldScope;

    FunctionScope(Function* function,
                  const Literals& arguments,
                  SubType& parent)
      : function(function), parent(parent) {
      oldScope = parent.scope;
      parent.scope = this;
      parent.callDepth++;
      parent.functionStack.push_back(function->name);
      locals.resize(function->getNumLocals());

      if (parent.isResuming() && parent.getCurrContinuation()->resumeExpr) {
        // Nothing more to do here: we are resuming execution to some
        // suspended expression (resumeExpr), so there is old locals state that
        // will be restored.
        return;
      }

      if (function->getParams().size() != arguments.size()) {
        std::cerr << "Function `" << function->name << "` expects "
                  << function->getParams().size() << " parameters, got "
                  << arguments.size() << " arguments." << std::endl;
        WASM_UNREACHABLE("invalid param count");
      }
      Type params = function->getParams();
      for (size_t i = 0; i < function->getNumLocals(); i++) {
        if (i < arguments.size()) {
          if (!Type::isSubType(arguments[i].type, params[i])) {
            std::cerr << "Function `" << function->name << "` expects type "
                      << params[i] << " for parameter " << i << ", got "
                      << arguments[i].type << "." << std::endl;
            WASM_UNREACHABLE("invalid param count");
          }
          locals[i] = {arguments[i]};
        } else {
          assert(function->isVar(i));
          locals[i] = Literal::makeZeros(function->getLocalType(i));
        }
      }
    }

    ~FunctionScope() {
      parent.scope = oldScope;
      parent.callDepth--;
      parent.functionStack.pop_back();
    }

    // The current delegate target, if delegation of an exception is in
    // progress. If no delegation is in progress, this will be an empty Name.
    // This is on a function scope because it cannot "escape" to the outside,
    // that is, a delegate target is like a branch target, it operates within
    // a function.
    Name currDelegateTarget;
  };

private:
  // This is managed in an RAII manner by the FunctionScope class.
  FunctionScope* scope = nullptr;

  // Stack of <caught exception, caught catch's try label>
  SmallVector<std::pair<WasmException, Name>, 4> exceptionStack;

protected:
  // Returns a reference to the current value of a potentially imported
  // function.
  Literal getFunction(Name name) {
    auto* inst = self();
    auto* func = inst->wasm.getFunction(name);
    if (!func->imported()) {
      return self()->makeFuncData(name, func->type);
    }
    auto iter = inst->linkedInstances.find(func->module);
    // wasm-shell builds a "spectest" module, but does *not* provide print
    // methods there. Those arrive from getImportedFunction(). So we must call
    // getImportedFunction() even if the linked instance exists, in the case
    // that it does not provide the export we want. TODO: fix wasm-shell
    if (iter == inst->linkedInstances.end() ||
        !inst->wasm.getExportOrNull(func->base)) {
      return externalInterface->getImportedFunction(func);
    }
    inst = iter->second.get();
    return inst->getExportedFunction(func->base);
  }

public:
  Flow visitCall(Call* curr) {
    Name target = curr->target;
    Literals arguments;
    VISIT_ARGUMENTS(flow, curr->operands, arguments);
    auto* func = wasm.getFunction(curr->target);
    auto funcType = func->type;
    if (Intrinsics(*self()->getModule()).isCallWithoutEffects(func)) {
      // The call.without.effects intrinsic is a call to an import that actually
      // calls the given function reference that is the final argument.
      target = arguments.back().getFunc();
      funcType = funcType.with(arguments.back().type.getHeapType());
      arguments.pop_back();
    }

    if (curr->isReturn) {
      // Return calls are represented by their arguments followed by a reference
      // to the function to be called.
      arguments.push_back(self()->makeFuncData(target, funcType));
      return Flow(RETURN_CALL_FLOW, std::move(arguments));
    }

#if WASM_INTERPRETER_DEBUG
    std::cout << self()->indent() << "(calling " << target << ")\n";
#endif
    Flow ret = callFunction(target, arguments);
#if WASM_INTERPRETER_DEBUG
    std::cout << self()->indent() << "(returned to " << scope->function->name
              << ")\n";
#endif
    return ret;
  }

  Flow visitCallIndirect(CallIndirect* curr) {
    Literals arguments;
    VISIT_ARGUMENTS(flow, curr->operands, arguments)
    VISIT(target, curr->target)

    auto index = target.getSingleValue().getUnsigned();
    Literal funcref;
    if (!self()->isResuming()) {
      // Normal execution: Load from the table.
      funcref = allTables[curr->table]->get(index);
    } else {
      // Use the stashed funcref (see below).
      auto entry = self()->popResumeEntry("call_indirect");
      assert(entry.size() == 1);
      funcref = entry[0];
    }

    if (curr->isReturn) {
      // Return calls are represented by their arguments followed by a reference
      // to the function to be called.
      if (!Type::isSubType(funcref.type, Type(curr->heapType, NonNullable))) {
        trap("cast failure in call_indirect");
      }
      arguments.push_back(funcref);
      return Flow(RETURN_CALL_FLOW, std::move(arguments));
    }

    if (funcref.isNull()) {
      trap("null target in call_indirect");
    }
    if (!funcref.isFunction()) {
      trap("non-function target in call_indirect");
    }

    // TODO: Throw a non-constant exception if the reference is to an imported
    //       function that has a supertype of the expected type.
    if (!HeapType::isSubType(funcref.type.getHeapType(), curr->heapType)) {
      trap("callIndirect: non-subtype");
    }

#if WASM_INTERPRETER_DEBUG
    std::cout << self()->indent() << "(calling table)\n";
#endif
    Flow ret = funcref.getFuncData()->doCall(arguments);
#if WASM_INTERPRETER_DEBUG
    std::cout << self()->indent() << "(returned to " << scope->function->name
              << ")\n";
#endif

    if (ret.suspendTag) {
      // Save the function reference we are calling, as when we resume we need
      // to call it - we cannot do another load from the table, which might have
      // changed.
      self()->pushResumeEntry({funcref}, "call_indirect");
    }

    return ret;
  }

  Flow visitCallRef(CallRef* curr) {
    Literals arguments;
    VISIT_ARGUMENTS(flow, curr->operands, arguments)
    VISIT(target, curr->target)
    auto targetRef = target.getSingleValue();
    if (targetRef.isNull()) {
      trap("null target in call_ref");
    }

    if (curr->isReturn) {
      // Return calls are represented by their arguments followed by a reference
      // to the function to be called.
      arguments.push_back(targetRef);
      return Flow(RETURN_CALL_FLOW, std::move(arguments));
    }

#if WASM_INTERPRETER_DEBUG
    std::cout << self()->indent() << "(calling ref " << targetRef.getFunc()
              << ")\n";
#endif
    Flow ret = targetRef.getFuncData()->doCall(arguments);
#if WASM_INTERPRETER_DEBUG
    std::cout << self()->indent() << "(returned to " << scope->function->name
              << ")\n";
#endif
    return ret;
  }

  Flow visitTableGet(TableGet* curr) {
    VISIT(index, curr->index)
    auto address = index.getSingleValue().getUnsigned();
    return allTables[curr->table]->get(address);
  }
  Flow visitTableSet(TableSet* curr) {
    VISIT(index, curr->index)
    VISIT(value, curr->value)
    auto address = index.getSingleValue().getUnsigned();

    allTables[curr->table]->set(address, value.getSingleValue());

    return Flow();
  }

  Flow visitTableSize(TableSize* curr) {
    auto* table = allTables[curr->table];
    return Literal::makeFromInt64(static_cast<int64_t>(table->size()),
                                  table->getDefinition()->addressType);
  }

  Flow visitTableGrow(TableGrow* curr) {
    VISIT(valueFlow, curr->value)
    VISIT(deltaFlow, curr->delta)

    auto* table = allTables[curr->table];
    if (auto newSize = table->grow(deltaFlow.getSingleValue().getUnsigned(),
                                   valueFlow.getSingleValue())) {
      return Literal::makeFromInt64(*newSize,
                                    table->getDefinition()->addressType);
    }

    return Literal::makeFromInt64(-1, table->getDefinition()->addressType);
  }

  Flow visitTableFill(TableFill* curr) {
    VISIT(destFlow, curr->dest)
    VISIT(valueFlow, curr->value)
    VISIT(sizeFlow, curr->size)

    auto dest = destFlow.getSingleValue().getUnsigned();
    Literal value = valueFlow.getSingleValue();
    auto size = sizeFlow.getSingleValue().getUnsigned();

    auto* table = allTables[curr->table];
    if (dest + size > table->size()) {
      trap("out of bounds table access");
    }

    for (uint64_t i = 0; i < size; i++) {
      table->set(dest + i, value);
    }
    return Flow();
  }

  Flow visitTableCopy(TableCopy* curr) {
    VISIT(dest, curr->dest)
    VISIT(source, curr->source)
    VISIT(size, curr->size)
    Address destVal(dest.getSingleValue().getUnsigned());
    Address sourceVal(source.getSingleValue().getUnsigned());
    Address sizeVal(size.getSingleValue().getUnsigned());

    auto* destTable = allTables[curr->destTable];
    auto* sourceTable = allTables[curr->sourceTable];
    if (sourceVal + sizeVal > sourceTable->size() ||
        destVal + sizeVal > destTable->size() ||
        // FIXME: better/cheaper way to detect wrapping?
        sourceVal + sizeVal < sourceVal || sourceVal + sizeVal < sizeVal ||
        destVal + sizeVal < destVal || destVal + sizeVal < sizeVal) {
      trap("out of bounds segment access in table.copy");
    }

    int64_t start = 0;
    int64_t end = sizeVal;
    int step = 1;
    // Reverse direction if source is below dest
    if (sourceVal < destVal) {
      start = int64_t(sizeVal) - 1;
      end = -1;
      step = -1;
    }
    for (int64_t i = start; i != end; i += step) {
      destTable->set(destVal + i, sourceTable->get(sourceVal + i));
    }
    return {};
  }

  Flow visitTableInit(TableInit* curr) {
    VISIT(dest, curr->dest)
    VISIT(offset, curr->offset)
    VISIT(size, curr->size)

    auto* segment = wasm.getElementSegment(curr->segment);

    Address destVal(dest.getSingleValue().getUnsigned());
    Address offsetVal(uint32_t(offset.getSingleValue().geti32()));
    Address sizeVal(uint32_t(size.getSingleValue().geti32()));

    if (offsetVal + sizeVal > 0 &&
        droppedElementSegments.count(curr->segment)) {
      trap("out of bounds segment access in table.init");
    }
    if (offsetVal + sizeVal > segment->data.size()) {
      trap("out of bounds segment access in table.init");
    }

    auto* table = allTables[curr->table];
    if (destVal + sizeVal > table->size()) {
      trap("out of bounds table access in table.init");
    }
    for (size_t i = 0; i < sizeVal; ++i) {
      // FIXME: We should not call visit() here more than once at runtime. The
      //        values in the segment should be computed once during startup,
      //        and then read here as needed. For example, if we had a
      //        struct.new here then we should not allocate a new struct each
      //        time we table.init that data.
      Literal value =
        self()->visit(segment->data[offsetVal + i]).getSingleValue();
      table->set(destVal + i, value);
    }
    return {};
  }

  Flow visitElemDrop(ElemDrop* curr) {
    ElementSegment* seg = wasm.getElementSegment(curr->segment);
    droppedElementSegments.insert(seg->name);
    return {};
  }

  Flow visitLocalGet(LocalGet* curr) {
    auto index = curr->index;
    return scope->locals[index];
  }
  Flow visitLocalSet(LocalSet* curr) {
    auto index = curr->index;
    VISIT(flow, curr->value)
    assert(curr->isTee() ? Type::isSubType(flow.getType(), curr->type) : true);
    scope->locals[index] = flow.values;
    return curr->isTee() ? flow : Flow();
  }

  Flow visitGlobalGet(GlobalGet* curr) {
    auto name = curr->name;
    return *allGlobals.at(name);
  }
  Flow visitGlobalSet(GlobalSet* curr) {
    auto name = curr->name;
    VISIT(flow, curr->value)

    *allGlobals.at(name) = flow.values;
    return Flow();
  }

  Flow visitLoad(Load* curr) {
    VISIT(flow, curr->ptr)
    auto info = getMemoryInstanceInfo(curr->memory);
    auto memorySize = info.instance->getMemorySize(info.name);
    auto addr =
      info.instance->getFinalAddress(curr, flow.getSingleValue(), memorySize);
    if (curr->isAtomic()) {
      info.instance->checkAtomicAddress(addr, curr->bytes, memorySize);
    }
    auto ret = info.interface()->load(curr, addr, info.name);
    return ret;
  }
  Flow visitStore(Store* curr) {
    VISIT(ptr, curr->ptr)
    VISIT(value, curr->value)
    auto info = getMemoryInstanceInfo(curr->memory);
    auto memorySize = info.instance->getMemorySize(info.name);
    auto addr =
      info.instance->getFinalAddress(curr, ptr.getSingleValue(), memorySize);
    if (curr->isAtomic()) {
      info.instance->checkAtomicAddress(addr, curr->bytes, memorySize);
    }
    info.interface()->store(curr, addr, value.getSingleValue(), info.name);
    return Flow();
  }

  Flow visitAtomicRMW(AtomicRMW* curr) {
    VISIT(ptr, curr->ptr)
    VISIT(value, curr->value)
    auto info = getMemoryInstanceInfo(curr->memory);
    auto memorySize = info.instance->getMemorySize(info.name);
    auto addr =
      info.instance->getFinalAddress(curr, ptr.getSingleValue(), memorySize);
    auto loaded = info.instance->doAtomicLoad(
      addr, curr->bytes, curr->type, info.name, memorySize, curr->order);
    auto computed = value.getSingleValue();
    switch (curr->op) {
      case RMWAdd:
        computed = loaded.add(computed);
        break;
      case RMWSub:
        computed = loaded.sub(computed);
        break;
      case RMWAnd:
        computed = loaded.and_(computed);
        break;
      case RMWOr:
        computed = loaded.or_(computed);
        break;
      case RMWXor:
        computed = loaded.xor_(computed);
        break;
      case RMWXchg:
        break;
    }
    info.instance->doAtomicStore(
      addr, curr->bytes, computed, info.name, memorySize);
    return loaded;
  }
  Flow visitAtomicCmpxchg(AtomicCmpxchg* curr) {
    VISIT(ptr, curr->ptr)
    VISIT(expected, curr->expected)
    VISIT(replacement, curr->replacement)
    auto info = getMemoryInstanceInfo(curr->memory);
    auto memorySize = info.instance->getMemorySize(info.name);
    auto addr =
      info.instance->getFinalAddress(curr, ptr.getSingleValue(), memorySize);
    expected = Flow(wrapToSmallerSize(expected.getSingleValue(), curr->bytes));
    auto loaded = info.instance->doAtomicLoad(
      addr, curr->bytes, curr->type, info.name, memorySize, curr->order);
    if (loaded == expected.getSingleValue()) {
      info.instance->doAtomicStore(
        addr, curr->bytes, replacement.getSingleValue(), info.name, memorySize);
    }
    return loaded;
  }
  Flow visitAtomicWait(AtomicWait* curr) {
    VISIT(ptr, curr->ptr)
    VISIT(expected, curr->expected)
    VISIT(timeout, curr->timeout)
    auto bytes = curr->expectedType.getByteSize();
    auto info = getMemoryInstanceInfo(curr->memory);
    auto memorySize = info.instance->getMemorySize(info.name);
    auto addr = info.instance->getFinalAddress(
      curr, ptr.getSingleValue(), bytes, memorySize);
    auto loaded = info.instance->doAtomicLoad(addr,
                                              bytes,
                                              curr->expectedType,
                                              info.name,
                                              memorySize,
                                              MemoryOrder::SeqCst);
    if (loaded != expected.getSingleValue()) {
      return Literal(int32_t(1)); // not equal
    }
    // TODO: Add threads support. For now, report a host limit here, as there
    //       are no other threads that can wake us up. Without such threads,
    //       we'd hang if there is no timeout, and even if there is a timeout
    //       then we can hang for a long time if it is in a loop. The only
    //       timeout value we allow here for now is 0.
    if (timeout.getSingleValue().getInteger() != 0) {
      hostLimit("threads support");
    }
    return Literal(int32_t(2)); // Timed out
  }
  Flow visitAtomicNotify(AtomicNotify* curr) {
    VISIT(ptr, curr->ptr)
    VISIT(count, curr->notifyCount)
    auto info = getMemoryInstanceInfo(curr->memory);
    auto memorySize = info.instance->getMemorySize(info.name);
    auto addr =
      info.instance->getFinalAddress(curr, ptr.getSingleValue(), 4, memorySize);
    // Just check TODO actual threads support
    info.instance->checkAtomicAddress(addr, 4, memorySize);
    return Literal(int32_t(0)); // none woken up
  }
  Flow visitSIMDLoad(SIMDLoad* curr) {
    switch (curr->op) {
      case Load8SplatVec128:
      case Load16SplatVec128:
      case Load32SplatVec128:
      case Load64SplatVec128:
        return visitSIMDLoadSplat(curr);
      case Load8x8SVec128:
      case Load8x8UVec128:
      case Load16x4SVec128:
      case Load16x4UVec128:
      case Load32x2SVec128:
      case Load32x2UVec128:
        return visitSIMDLoadExtend(curr);
      case Load32ZeroVec128:
      case Load64ZeroVec128:
        return visitSIMDLoadZero(curr);
    }
    WASM_UNREACHABLE("invalid op");
  }
  Flow visitSIMDLoadSplat(SIMDLoad* curr) {
    Load load;
    load.memory = curr->memory;
    load.type = Type::i32;
    load.bytes = curr->getMemBytes();
    load.signed_ = false;
    load.offset = curr->offset;
    load.align = curr->align;
    load.order = MemoryOrder::Unordered;
    load.ptr = curr->ptr;
    Literal (Literal::*splat)() const = nullptr;
    switch (curr->op) {
      case Load8SplatVec128:
        splat = &Literal::splatI8x16;
        break;
      case Load16SplatVec128:
        splat = &Literal::splatI16x8;
        break;
      case Load32SplatVec128:
        splat = &Literal::splatI32x4;
        break;
      case Load64SplatVec128:
        load.type = Type::i64;
        splat = &Literal::splatI64x2;
        break;
      default:
        WASM_UNREACHABLE("invalid op");
    }
    load.finalize();
    Flow flow = self()->visit(&load);
    if (flow.breaking()) {
      return flow;
    }
    return (flow.getSingleValue().*splat)();
  }
  Flow visitSIMDLoadExtend(SIMDLoad* curr) {
    VISIT(flow, curr->ptr)
    Address src(flow.getSingleValue().getUnsigned());
    auto info = getMemoryInstanceInfo(curr->memory);
    auto loadLane = [&](Address addr) {
      switch (curr->op) {
        case Load8x8SVec128:
          return Literal(int32_t(info.interface()->load8s(addr, info.name)));
        case Load8x8UVec128:
          return Literal(int32_t(info.interface()->load8u(addr, info.name)));
        case Load16x4SVec128:
          return Literal(int32_t(info.interface()->load16s(addr, info.name)));
        case Load16x4UVec128:
          return Literal(int32_t(info.interface()->load16u(addr, info.name)));
        case Load32x2SVec128:
          return Literal(int64_t(info.interface()->load32s(addr, info.name)));
        case Load32x2UVec128:
          return Literal(int64_t(info.interface()->load32u(addr, info.name)));
        default:
          WASM_UNREACHABLE("unexpected op");
      }
      WASM_UNREACHABLE("invalid op");
    };
    auto memorySize = info.instance->getMemorySize(info.name);
    auto addressType = curr->ptr->type;
    auto fillLanes = [&](auto lanes, size_t laneBytes) {
      for (auto& lane : lanes) {
        auto ptr = Literal::makeFromInt64(src, addressType);
        lane = loadLane(
          info.instance->getFinalAddress(curr, ptr, laneBytes, memorySize));
        src =
          ptr.add(Literal::makeFromInt32(laneBytes, addressType)).getUnsigned();
      }
      return Literal(lanes);
    };
    switch (curr->op) {
      case Load8x8SVec128:
      case Load8x8UVec128: {
        std::array<Literal, 8> lanes;
        return fillLanes(lanes, 1);
      }
      case Load16x4SVec128:
      case Load16x4UVec128: {
        std::array<Literal, 4> lanes;
        return fillLanes(lanes, 2);
      }
      case Load32x2SVec128:
      case Load32x2UVec128: {
        std::array<Literal, 2> lanes;
        return fillLanes(lanes, 4);
      }
      default:
        WASM_UNREACHABLE("unexpected op");
    }
    WASM_UNREACHABLE("invalid op");
  }
  Flow visitSIMDLoadZero(SIMDLoad* curr) {
    VISIT(flow, curr->ptr)
    auto info = getMemoryInstanceInfo(curr->memory);
    auto memorySize = info.instance->getMemorySize(info.name);
    Address src = info.instance->getFinalAddress(
      curr, flow.getSingleValue(), curr->getMemBytes(), memorySize);
    auto zero =
      Literal::makeZero(curr->op == Load32ZeroVec128 ? Type::i32 : Type::i64);
    if (curr->op == Load32ZeroVec128) {
      auto val = Literal(info.interface()->load32u(src, info.name));
      return Literal(std::array<Literal, 4>{{val, zero, zero, zero}});
    } else {
      auto val = Literal(info.interface()->load64u(src, info.name));
      return Literal(std::array<Literal, 2>{{val, zero}});
    }
  }
  Flow visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {
    VISIT(ptrFlow, curr->ptr)
    VISIT(vecFlow, curr->vec)
    auto info = getMemoryInstanceInfo(curr->memory);
    auto memorySize = info.instance->getMemorySize(info.name);
    Address addr = info.instance->getFinalAddress(
      curr, ptrFlow.getSingleValue(), curr->getMemBytes(), memorySize);
    Literal vec = vecFlow.getSingleValue();
    switch (curr->op) {
      case Load8LaneVec128:
      case Store8LaneVec128: {
        std::array<Literal, 16> lanes = vec.getLanesUI8x16();
        if (curr->isLoad()) {
          lanes[curr->index] =
            Literal(info.interface()->load8u(addr, info.name));
          return Literal(lanes);
        } else {
          info.interface()->store8(
            addr, lanes[curr->index].geti32(), info.name);
          return {};
        }
      }
      case Load16LaneVec128:
      case Store16LaneVec128: {
        std::array<Literal, 8> lanes = vec.getLanesUI16x8();
        if (curr->isLoad()) {
          lanes[curr->index] =
            Literal(info.interface()->load16u(addr, info.name));
          return Literal(lanes);
        } else {
          info.interface()->store16(
            addr, lanes[curr->index].geti32(), info.name);
          return {};
        }
      }
      case Load32LaneVec128:
      case Store32LaneVec128: {
        std::array<Literal, 4> lanes = vec.getLanesI32x4();
        if (curr->isLoad()) {
          lanes[curr->index] =
            Literal(info.interface()->load32u(addr, info.name));
          return Literal(lanes);
        } else {
          info.interface()->store32(
            addr, lanes[curr->index].geti32(), info.name);
          return {};
        }
      }
      case Store64LaneVec128:
      case Load64LaneVec128: {
        std::array<Literal, 2> lanes = vec.getLanesI64x2();
        if (curr->isLoad()) {
          lanes[curr->index] =
            Literal(info.interface()->load64u(addr, info.name));
          return Literal(lanes);
        } else {
          info.interface()->store64(
            addr, lanes[curr->index].geti64(), info.name);
          return {};
        }
      }
    }
    WASM_UNREACHABLE("unexpected op");
  }
  Flow visitMemorySize(MemorySize* curr) {
    auto info = getMemoryInstanceInfo(curr->memory);
    auto memorySize = info.instance->getMemorySize(info.name);
    auto* memory = info.instance->wasm.getMemory(info.name);
    return Literal::makeFromInt64(memorySize, memory->addressType);
  }
  Flow visitMemoryGrow(MemoryGrow* curr) {
    VISIT(flow, curr->delta)
    auto info = getMemoryInstanceInfo(curr->memory);
    auto memorySize = info.instance->getMemorySize(info.name);
    auto* memory = info.instance->wasm.getMemory(info.name);
    auto addressType = memory->addressType;
    auto fail = Literal::makeFromInt64(-1, addressType);
    Flow ret = Literal::makeFromInt64(memorySize, addressType);
    uint64_t delta = flow.getSingleValue().getUnsigned();
    uint64_t maxAddr = addressType == Type::i32
                         ? std::numeric_limits<uint32_t>::max()
                         : std::numeric_limits<uint64_t>::max();
    if (delta > maxAddr / Memory::kPageSize) {
      // Impossible to grow this much.
      return fail;
    }
    if (memorySize >= maxAddr - delta) {
      // Overflow.
      return fail;
    }
    auto newSize = memorySize + delta;
    if (newSize > memory->max) {
      return fail;
    }
    if (!info.interface()->growMemory(info.name,
                                      memorySize * Memory::kPageSize,
                                      newSize * Memory::kPageSize)) {
      // We failed to grow the memory in practice, even though it was valid
      // to try to do so.
      return fail;
    }
    memorySize = newSize;
    info.instance->setMemorySize(info.name, memorySize);
    return ret;
  }
  Flow visitMemoryInit(MemoryInit* curr) {
    VISIT(dest, curr->dest)
    VISIT(offset, curr->offset)
    VISIT(size, curr->size)

    auto* segment = wasm.getDataSegment(curr->segment);

    Address destVal(dest.getSingleValue().getUnsigned());
    Address offsetVal(offset.getSingleValue().getUnsigned());
    Address sizeVal(size.getSingleValue().getUnsigned());

    if (offsetVal + sizeVal > 0 && droppedDataSegments.count(curr->segment)) {
      trap("out of bounds segment access in memory.init");
    }
    if (offsetVal + sizeVal > segment->data.size()) {
      trap("out of bounds segment access in memory.init");
    }
    auto info = getMemoryInstanceInfo(curr->memory);
    auto memorySize = info.instance->getMemorySize(info.name);
    if (destVal + sizeVal > memorySize * Memory::kPageSize) {
      trap("out of bounds memory access in memory.init");
    }
    for (size_t i = 0; i < sizeVal; ++i) {
      Literal addr(destVal + i);
      info.interface()->store8(
        info.instance->getFinalAddressWithoutOffset(addr, 1, memorySize),
        segment->data[offsetVal + i],
        info.name);
    }
    return {};
  }
  Flow visitDataDrop(DataDrop* curr) {
    droppedDataSegments.insert(curr->segment);
    return {};
  }
  Flow visitMemoryCopy(MemoryCopy* curr) {
    VISIT(dest, curr->dest)
    VISIT(source, curr->source)
    VISIT(size, curr->size)
    Address destVal(dest.getSingleValue().getUnsigned());
    Address sourceVal(source.getSingleValue().getUnsigned());
    Address sizeVal(size.getSingleValue().getUnsigned());

    auto destInfo = getMemoryInstanceInfo(curr->destMemory);
    auto sourceInfo = getMemoryInstanceInfo(curr->sourceMemory);
    auto destMemorySize = destInfo.instance->getMemorySize(destInfo.name);
    auto sourceMemorySize = sourceInfo.instance->getMemorySize(sourceInfo.name);
    if (sourceVal + sizeVal > sourceMemorySize * Memory::kPageSize ||
        destVal + sizeVal > destMemorySize * Memory::kPageSize ||
        // FIXME: better/cheaper way to detect wrapping?
        sourceVal + sizeVal < sourceVal || sourceVal + sizeVal < sizeVal ||
        destVal + sizeVal < destVal || destVal + sizeVal < sizeVal) {
      trap("out of bounds segment access in memory.copy");
    }

    int64_t start = 0;
    int64_t end = sizeVal;
    int step = 1;
    // Reverse direction if source is below dest
    if (sourceVal < destVal) {
      start = int64_t(sizeVal) - 1;
      end = -1;
      step = -1;
    }
    for (int64_t i = start; i != end; i += step) {
      destInfo.interface()->store8(
        destInfo.instance->getFinalAddressWithoutOffset(
          Literal(destVal + i), 1, destMemorySize),
        sourceInfo.interface()->load8s(
          sourceInfo.instance->getFinalAddressWithoutOffset(
            Literal(sourceVal + i), 1, sourceMemorySize),
          sourceInfo.name),
        destInfo.name);
    }
    return {};
  }
  Flow visitMemoryFill(MemoryFill* curr) {
    VISIT(dest, curr->dest)
    VISIT(value, curr->value)
    VISIT(size, curr->size)
    Address destVal(dest.getSingleValue().getUnsigned());
    Address sizeVal(size.getSingleValue().getUnsigned());

    auto info = getMemoryInstanceInfo(curr->memory);
    auto memorySize = info.instance->getMemorySize(info.name);
    // FIXME: cheaper wrapping detection?
    if (destVal > memorySize * Memory::kPageSize ||
        sizeVal > memorySize * Memory::kPageSize ||
        destVal + sizeVal > memorySize * Memory::kPageSize) {
      trap("out of bounds memory access in memory.fill");
    }
    uint8_t val(value.getSingleValue().geti32());
    for (size_t i = 0; i < sizeVal; ++i) {
      info.interface()->store8(info.instance->getFinalAddressWithoutOffset(
                                 Literal(destVal + i), 1, memorySize),
                               val,
                               info.name);
    }
    return {};
  }
  Flow visitRefFunc(RefFunc* curr) {
    // Handle both imported and defined functions by finding the actual one that
    // is referred to here.
    auto func = self()->getFunction(curr->func);
    return self()->makeFuncData(curr->func, func.type);
  }
  Flow visitArrayNewData(ArrayNewData* curr) {
    VISIT(offsetFlow, curr->offset)
    VISIT(sizeFlow, curr->size)

    uint64_t offset = offsetFlow.getSingleValue().getUnsigned();
    uint64_t size = sizeFlow.getSingleValue().getUnsigned();

    auto heapType = curr->type.getHeapType();
    const auto& element = heapType.getArray().element;
    Literals contents;

    const auto& seg = *wasm.getDataSegment(curr->segment);
    auto elemBytes = element.getByteSize();

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"

    uint64_t end;
    if (std::ckd_add(&end, offset, size * elemBytes) || end > seg.data.size()) {
      trap("out of bounds segment access in array.new_data");
    }
    if (droppedDataSegments.count(curr->segment) && end > 0) {
      trap("dropped segment access in array.new_data");
    }
    contents.reserve(size);
    for (Index i = offset; i < end; i += elemBytes) {
      auto addr = (void*)&seg.data[i];
      contents.push_back(this->makeFromMemory(addr, element));
    }

#pragma GCC diagnostic pop

    return self()->makeGCData(std::move(contents), curr->type);
  }
  Flow visitArrayNewElem(ArrayNewElem* curr) {
    VISIT(offsetFlow, curr->offset)
    VISIT(sizeFlow, curr->size)

    uint64_t offset = offsetFlow.getSingleValue().getUnsigned();
    uint64_t size = sizeFlow.getSingleValue().getUnsigned();

    Literals contents;

    const auto& seg = *wasm.getElementSegment(curr->segment);
    auto end = offset + size;
    if (end > seg.data.size()) {
      trap("out of bounds segment access in array.new_elem");
    }
    if (end > 0 && droppedElementSegments.count(curr->segment)) {
      trap("out of bounds segment access in array.new_elem");
    }
    contents.reserve(size);
    for (Index i = offset; i < end; ++i) {
      auto val = self()->visit(seg.data[i]).getSingleValue();
      contents.push_back(val);
    }
    return self()->makeGCData(std::move(contents), curr->type);
  }
  Flow visitArrayInitData(ArrayInitData* curr) {
    VISIT(ref, curr->ref)
    VISIT(index, curr->index)
    VISIT(offset, curr->offset)
    VISIT(size, curr->size)
    auto data = ref.getSingleValue().getGCData();
    if (!data) {
      trap("null ref");
    }
    size_t indexVal = index.getSingleValue().getUnsigned();
    size_t offsetVal = offset.getSingleValue().getUnsigned();
    size_t sizeVal = size.getSingleValue().getUnsigned();

    size_t arraySize = data->values.size();
    if ((uint64_t)indexVal + sizeVal > arraySize) {
      trap("out of bounds array access in array.init");
    }

    Module& wasm = *self()->getModule();

    auto* seg = wasm.getDataSegment(curr->segment);
    auto elem = curr->ref->type.getHeapType().getArray().element;
    size_t elemSize = elem.getByteSize();
    uint64_t readSize = (uint64_t)sizeVal * elemSize;
    if (offsetVal + readSize > seg->data.size()) {
      trap("out of bounds segment access in array.init_data");
    }
    if (offsetVal + sizeVal > 0 && droppedDataSegments.count(curr->segment)) {
      trap("out of bounds segment access in array.init_data");
    }
    for (size_t i = 0; i < sizeVal; i++) {
      void* addr = (void*)&seg->data[offsetVal + i * elemSize];
      data->values[indexVal + i] = this->makeFromMemory(addr, elem);
    }
    return {};
  }
  Flow visitArrayInitElem(ArrayInitElem* curr) {
    VISIT(ref, curr->ref)
    VISIT(index, curr->index)
    VISIT(offset, curr->offset)
    VISIT(size, curr->size)
    auto data = ref.getSingleValue().getGCData();
    if (!data) {
      trap("null ref");
    }
    size_t indexVal = index.getSingleValue().getUnsigned();
    size_t offsetVal = offset.getSingleValue().getUnsigned();
    size_t sizeVal = size.getSingleValue().getUnsigned();

    size_t arraySize = data->values.size();
    if ((uint64_t)indexVal + sizeVal > arraySize) {
      trap("out of bounds array access in array.init");
    }

    Module& wasm = *self()->getModule();

    auto* seg = wasm.getElementSegment(curr->segment);
    auto max = (uint64_t)offsetVal + sizeVal;
    if (max > seg->data.size()) {
      trap("out of bounds segment access in array.init_elem");
    }
    if (max > 0 && droppedElementSegments.count(curr->segment)) {
      trap("out of bounds segment access in array.init_elem");
    }
    for (size_t i = 0; i < sizeVal; i++) {
      // TODO: This is not correct because it does not preserve the identity
      // of references in the table! ArrayNew suffers the same problem.
      // Fixing it will require changing how we represent segments, at least
      // in the interpreter.
      data->values[indexVal + i] = self()->visit(seg->data[i]).getSingleValue();
    }
    return {};
  }
  Flow visitTry(Try* curr) {
    assert(!self()->isResuming()); // TODO
    try {
      return self()->visit(curr->body);
    } catch (const WasmException& e) {
      // If delegation is in progress and the current try is not the target of
      // the delegation, don't handle it and just rethrow.
      if (scope->currDelegateTarget.is()) {
        if (scope->currDelegateTarget == curr->name) {
          scope->currDelegateTarget = Name{};
        } else {
          throw;
        }
      }

      auto processCatchBody = [&](Expression* catchBody) {
        // Push the current exception onto the exceptionStack in case
        // 'rethrow's use it
        exceptionStack.push_back(std::make_pair(e, curr->name));
        // We need to pop exceptionStack in either case: when the catch body
        // exits normally or when a new exception is thrown
        Flow ret;
        try {
          ret = self()->visit(catchBody);
        } catch (const WasmException&) {
          exceptionStack.pop_back();
          throw;
        }
        exceptionStack.pop_back();
        return ret;
      };

      auto exnData = e.exn.getExnData();
      for (size_t i = 0; i < curr->catchTags.size(); i++) {
        auto* tag = allTags[curr->catchTags[i]];
        if (tag == exnData->tag) {
          multiValues.push_back(exnData->payload);
          return processCatchBody(curr->catchBodies[i]);
        }
      }
      if (curr->hasCatchAll()) {
        return processCatchBody(curr->catchBodies.back());
      }
      if (curr->isDelegate()) {
        scope->currDelegateTarget = curr->delegateTarget;
      }
      // This exception is not caught by this try-catch. Rethrow it.
      throw;
    }
  }
  Flow visitTryTable(TryTable* curr) {
    try {
      return self()->visit(curr->body);
    } catch (const WasmException& e) {
      auto exnData = e.exn.getExnData();
      for (size_t i = 0; i < curr->catchTags.size(); i++) {
        auto catchTag = curr->catchTags[i];

        // note: allTags[catchTag] will be null if it's a tag that we don't know
        // about, i.e. an unimported tag.
        // We do a pointer comparison here (`tag->second == exnData->tag`)
        // because a tag just consists of a signature, and two tags may look the
        // same but have different identities, e.g. given
        // (tag $a (param i32))
        // (tag $b (param i32))
        // a catch clause for $b won't catch $a and vice versa.
        // This can also happen when a module is instantiated twice and the same
        // tag is imported from each instance. See the instance.wast spec test.
        if (auto tag = allTags.find(catchTag);
            !catchTag.is() ||
            ((tag != allTags.end()) && tag->second == exnData->tag)) {
          Flow ret;
          ret.breakTo = curr->catchDests[i];
          if (catchTag.is()) {
            for (auto item : exnData->payload) {
              ret.values.push_back(item);
            }
          }
          if (curr->catchRefs[i]) {
            ret.values.push_back(e.exn);
          }
          return ret;
        }
      }
      // This exception is not caught by this try_table. Rethrow it.
      throw;
    }
  }
  Flow visitThrow(Throw* curr) {
    Literals arguments;
    VISIT_ARGUMENTS(flow, curr->operands, arguments);
    throwException(
      WasmException{self()->makeExnData(allTags[curr->tag], arguments)});
    WASM_UNREACHABLE("throw");
  }
  Flow visitRethrow(Rethrow* curr) {
    for (int i = exceptionStack.size() - 1; i >= 0; i--) {
      if (exceptionStack[i].second == curr->target) {
        throwException(exceptionStack[i].first);
      }
    }
    WASM_UNREACHABLE("rethrow");
  }
  Flow visitPop(Pop* curr) {
    assert(!multiValues.empty());
    auto ret = multiValues.back();
    assert(Type::isSubType(ret.getType(), curr->type));
    multiValues.pop_back();
    return ret;
  }
  Flow visitContNew(ContNew* curr) {
    VISIT(funcFlow, curr->func)
    // Create a new continuation for the target function.
    auto funcValue = funcFlow.getSingleValue();
    if (funcValue.isNull()) {
      trap("null ref");
    }
    auto funcName = funcValue.getFunc();
    auto* func = self()->getModule()->getFunction(funcName);
    return Literal(std::make_shared<ContData>(
      self()->makeFuncData(funcName, func->type), curr->type.getHeapType()));
  }
  Flow visitContBind(ContBind* curr) {
    Literals arguments;
    VISIT_ARGUMENTS(flow, curr->operands, arguments)
    VISIT(cont, curr->cont)

    // Create a new continuation, copying the old but with the new type +
    // arguments.
    auto old = cont.getSingleValue().getContData();
    auto newData = *old;
    newData.type = curr->type.getHeapType();
    newData.resumeArguments = arguments;
    // We handle only the simple case of applying all parameters, for now. TODO
    assert(old->resumeArguments.empty());
    // The old one is done.
    old->executed = true;
    return Literal(std::make_shared<ContData>(newData));
  }

  void maybeThrowAfterResuming(std::shared_ptr<ContData>& currContinuation) {
    // We may throw by creating a tag, or an exnref.
    auto* tag = currContinuation->exceptionTag;
    auto exnref = currContinuation->exception.type != Type::none;
    assert(!(tag && exnref));
    if (tag) {
      // resume_throw
      throwException(WasmException{
        self()->makeExnData(tag, currContinuation->resumeArguments)});
    } else if (exnref) {
      // resume_throw_ref
      throwException(WasmException{currContinuation->exception});
    }
  }

  Flow visitSuspend(Suspend* curr) {
    // Process the arguments, whether or not we are resuming. If we are resuming
    // then we don't need these values (we sent them as part of the suspension),
    // but must still handle them, so we finish re-winding the stack.
    Literals arguments;
    VISIT_ARGUMENTS(flow, curr->operands, arguments)

    if (self()->isResuming()) {
#if WASM_INTERPRETER_DEBUG
      std::cout << self()->indent()
                << "returned to suspend; continuing normally\n";
#endif
      // This is a resume, so we have found our way back to where we
      // suspended.
      auto currContinuation = self()->getCurrContinuation();
      assert(curr == currContinuation->resumeExpr);
      // We finished resuming, and will continue from here normally.
      self()->continuationStore->resuming = false;
      // We should have consumed all the resumeInfo and all the
      // restoredValues map.
      assert(currContinuation->resumeInfo.empty());
      assert(self()->restoredValuesMap.empty());
      maybeThrowAfterResuming(currContinuation);
      return currContinuation->resumeArguments;
    }

    // We were not resuming, so this is a new suspend that we must execute.

    // Copy the continuation (the old one cannot be resumed again). Note that no
    // old one may exist, in which case we still emit a continuation, but it is
    // meaningless (it will error when it reaches the host).
    auto old = self()->getCurrContinuationOrNull();
    auto* tag = allTags[curr->tag];
    if (!old) {
      return Flow(SUSPEND_FLOW, tag, std::move(arguments));
    }
    assert(old->executed);
    // An old one exists, so we can create a proper new one. It starts out
    // empty here, and as we unwind, info will be added to it (and the function
    // to resume as well, once we find the right resume handler).
    //
    // Note we cannot update the type yet, so it will be wrong in debug
    // logging. To update it, we must find the block that receives this value,
    // which means we cannot do it here (we don't even know what that block is).
    auto new_ = std::make_shared<ContData>();

    // Switch to the new continuation, so that as we unwind, we will save the
    // information we need to resume it later in the proper place.
    self()->popCurrContinuation();
    self()->pushCurrContinuation(new_);
    // We will resume from this precise spot, when the new continuation is
    // resumed.
    new_->resumeExpr = curr;
    return Flow(SUSPEND_FLOW, tag, std::move(arguments));
  }
  template<typename T> Flow doResume(T* curr) {
    Literals arguments;
    VISIT_ARGUMENTS(flow, curr->operands, arguments)
    VISIT_REUSE(flow, curr->cont);

    // Get and execute the continuation.
    auto cont = flow.getSingleValue();
    if (cont.isNull()) {
      trap("null ref");
    }
    auto contData = cont.getContData();
    auto func = contData->func;

    // If we are resuming a nested suspend then we should just rewind the call
    // stack, and therefore do not change or test the state here.
    if (!self()->isResuming()) {
      if (contData->executed) {
        trap("continuation already executed");
      }
      contData->executed = true;

      if (contData->resumeArguments.empty()) {
        // The continuation has no bound arguments. For now, we just handle the
        // simple case of binding all of them, so that means we can just use all
        // the immediate ones here. TODO
        contData->resumeArguments = arguments;
      }
      // Fill in the continuation data. How we do this depends on whether we
      // are resume or resume_throw*.
      if (auto* resumeThrow = curr->template dynCast<ResumeThrow>()) {
        if (resumeThrow->tag) {
          // resume_throw
          contData->exceptionTag = allTags[resumeThrow->tag];
        } else {
          // resume_throw_ref
          contData->exception = arguments[0];
        }
      }

      self()->pushCurrContinuation(contData);
      self()->continuationStore->resuming = true;
#if WASM_INTERPRETER_DEBUG
      std::cout << self()->indent() << "resuming func " << func.getFunc()
                << '\n';
#endif
    }

    Flow ret = func.getFuncData()->doCall(arguments);

#if WASM_INTERPRETER_DEBUG
    if (!self()->isResuming()) {
      std::cout << self()->indent() << "finished resuming, with " << ret
                << '\n';
    }
#endif
    if (!ret.suspendTag) {
      // No suspension: the coroutine finished normally. Mark it as no longer
      // active.
      self()->popCurrContinuation();
    } else {
      // We are suspending. See if a suspension arrived that we support.
      for (size_t i = 0; i < curr->handlerTags.size(); i++) {
        auto* handlerTag = allTags[curr->handlerTags[i]];
        if (handlerTag == ret.suspendTag) {
          // Switch the flow from suspending to branching.
          ret.suspendTag = nullptr;
          ret.breakTo = curr->handlerBlocks[i];
          // We can now update the continuation type, which was wrong until now
          // (see comment in visitSuspend). The type is taken from the block we
          // branch to (which we find in a quite inefficient manner).
          struct BlockFinder : public PostWalker<BlockFinder> {
            Name target;
            Type type = Type::none;
            void visitBlock(Block* curr) {
              if (curr->name == target) {
                type = curr->type;
              }
            }
          } finder;
          finder.target = ret.breakTo;
          // We must be in a function scope.
          assert(self()->scope->function);
          finder.walk(self()->scope->function->body);
          // We must have found the type, and it must be valid.
          assert(finder.type.isConcrete());
          assert(finder.type.size() >= 1);
          // The continuation is the final value/type there.
          auto newCont = self()->getCurrContinuation();
          newCont->type = finder.type[finder.type.size() - 1].getHeapType();
          // And we can set the function to be called, to resume it from here
          // (the same function we called, that led to a suspension).
          newCont->func = contData->func;
          // Add the continuation as the final value being sent.
          ret.values.push_back(Literal(newCont));
          // We are no longer processing that continuation.
          self()->popCurrContinuation();
          return ret;
        }
      }
      // No handler worked out, keep propagating.
    }
    // No suspension; all done.
    return ret;
  }
  Flow visitResume(Resume* curr) { return doResume(curr); }
  Flow visitResumeThrow(ResumeThrow* curr) { return doResume(curr); }
  Flow visitStackSwitch(StackSwitch* curr) { return Flow(NONCONSTANT_FLOW); }

  void trap(std::string_view why) override {
    // Traps break all current continuations - they will never be resumable.
    self()->clearContinuationStore();
    externalInterface->trap(why);
  }

  void hostLimit(std::string_view why) override {
    self()->clearContinuationStore();
    externalInterface->hostLimit(why);
  }

  void throwException(const WasmException& exn) override {
    externalInterface->throwException(exn);
  }

  // Given a value, wrap it to a smaller given number of bytes.
  Literal wrapToSmallerSize(Literal value, Index bytes) {
    if (value.type == Type::i32) {
      switch (bytes) {
        case 1: {
          return value.and_(Literal(uint32_t(0xff)));
        }
        case 2: {
          return value.and_(Literal(uint32_t(0xffff)));
        }
        case 4: {
          break;
        }
        default:
          WASM_UNREACHABLE("unexpected bytes");
      }
    } else {
      assert(value.type == Type::i64);
      switch (bytes) {
        case 1: {
          return value.and_(Literal(uint64_t(0xff)));
        }
        case 2: {
          return value.and_(Literal(uint64_t(0xffff)));
        }
        case 4: {
          return value.and_(Literal(uint64_t(0xffffffffUL)));
        }
        case 8: {
          break;
        }
        default:
          WASM_UNREACHABLE("unexpected bytes");
      }
    }
    return value;
  }

  Flow callFunction(Name name, Literals arguments) {
    if (callDepth > maxDepth) {
      hostLimit("stack limit");
    }

    if (self()->isResuming()) {
      // The arguments are in the continuation data.
      auto currContinuation = self()->getCurrContinuation();
      arguments = currContinuation->resumeArguments;

      if (!currContinuation->resumeExpr) {
        // This is the first time we resume, that is, there is no suspend which
        // is the resume expression that we need to execute up to. All we need
        // to do is just start calling this function (with the arguments we've
        // set), so resuming is done. (And throw, if resume_throw.)
        self()->continuationStore->resuming = false;
        maybeThrowAfterResuming(currContinuation);
      }
    }

    Flow flow;
    std::optional<Type> resultType;

    // We may have to call multiple functions in the event of return calls.
    while (true) {
      if (self()->isResuming()) {
        // See which function to call. Re-winding the stack, we are calling the
        // function that the parent called, but the target that was called may
        // have return-called. In that case, the original target function should
        // not be called, as it was returned from, and we noted the proper
        // target during that return.
        auto entry = self()->popResumeEntry("function-target");
        assert(entry.size() == 1);
        auto func = entry[0];
        auto data = func.getFuncData();
        // We must be in the right module to do the call using that name.
        if (data->self != self()) {
          // Restore the entry to the resume stack, as the other module's
          // callFunction() will read it. Then call into the other module. This
          // sets this up as if we called into the proper module in the first
          // place.
          self()->pushResumeEntry(entry, "function-target");
          return data->doCall(arguments);
        }

        // We are in the right place, and can just call the given function.
        name = data->name;
      }

      Function* function = wasm.getFunction(name);
      assert(function);

      // Return calls can only make the result type more precise.
      if (resultType) {
        assert(Type::isSubType(function->getResults(), *resultType));
      }
      resultType = function->getResults();

      if (function->imported()) {
        // TODO: Allow imported functions to tail call as well.
        return externalInterface->getImportedFunction(function)
          .getFuncData()
          ->doCall(arguments);
      }

      FunctionScope scope(function, arguments, *self());

      if (self()->isResuming()) {
        // Restore the local state (see below for the ordering, we push/pop).
        for (Index i = 0; i < scope.locals.size(); i++) {
          auto l = scope.locals.size() - 1 - i;
          scope.locals[l] = self()->popResumeEntry("function-local");
#ifndef NDEBUG
          // Must have restored valid data. The type must match the local's
          // type, except for the case of a non-nullable local that has not yet
          // been accessed: that will contain a null (but the wasm type system
          // ensures it will not be read by code, until a non-null value is
          // assigned).
          auto value = scope.locals[l];
          auto localType = function->getLocalType(l);
          assert(Type::isSubType(value.getType(), localType) ||
                 value == Literal::makeZeros(localType));
#endif
        }
      }

#if WASM_INTERPRETER_DEBUG
      std::cout << self()->indent() << "entering " << function->name << '\n'
                << self()->indent() << " with arguments:\n";
      for (unsigned i = 0; i < arguments.size(); ++i) {
        std::cout << self()->indent() << "  $" << i << ": " << arguments[i]
                  << '\n';
      }
#endif

      flow = self()->visit(function->body);

#if WASM_INTERPRETER_DEBUG
      std::cout << self()->indent() << "exiting " << function->name << " with "
                << flow << '\n';
#endif

      if (flow.suspendTag) {
        // Save the local state.
        for (auto& local : scope.locals) {
          self()->pushResumeEntry(local, "function-local");
        }

        // Save the function we called (in the case of a return call, this is
        // not the original function that was called, and the original has been
        // returned from already; we should call the last return_called
        // function).
        auto target = self()->makeFuncData(name, function->type);
        self()->pushResumeEntry({target}, "function-target");
      }

      if (flow.breakTo != RETURN_CALL_FLOW) {
        break;
      }

      // There was a return call, so we need to call the next function before
      // returning to the caller. The flow carries the function arguments and a
      // function reference.
      auto nextData = flow.values.back().getFuncData();
      name = nextData->name;
      flow.values.pop_back();
      arguments = flow.values;

      if (nextData->self != this) {
        // This function is in another module. Call from there.
        auto other = (decltype(this))nextData->self;
        flow = other->callFunction(name, arguments);
        break;
      }
    }

    if (flow.breaking() && flow.breakTo == NONCONSTANT_FLOW) {
      throw NonconstantException();
    }

    if (flow.breakTo == RETURN_FLOW) {
      // We are no longer returning out of that function (but the value
      // remains the same).
      flow.breakTo = Name();
    }

    if (flow.breakTo != SUSPEND_FLOW) {
      // We are normally executing (not suspending), and therefore cannot still
      // be breaking, which would mean we missed our stop.
      assert(!flow.breaking() || flow.breakTo == RETURN_FLOW);
#ifndef NDEBUG
      // In normal execution, the result is the expected one.
      auto type = flow.getType();
      if (!Type::isSubType(type, *resultType)) {
        Fatal() << "calling " << name << " resulted in " << type
                << " but the function type is " << *resultType << '\n';
      }
#endif
    }

    return flow;
  }

  // The maximum call stack depth to evaluate into.
  static const Index maxDepth = 200;

protected:
  void trapIfGt(uint64_t lhs, uint64_t rhs, const char* msg) {
    if (lhs > rhs) {
      std::stringstream ss;
      ss << msg << ": " << lhs << " > " << rhs;
      externalInterface->trap(ss.str());
    }
  }

  template<class LS>
  Address
  getFinalAddress(LS* curr, Literal ptr, Index bytes, Address memorySize) {
    Address memorySizeBytes = memorySize * Memory::kPageSize;
    uint64_t addr = ptr.type == Type::i32 ? ptr.geti32() : ptr.geti64();
    trapIfGt(curr->offset, memorySizeBytes, "offset > memory");
    trapIfGt(addr, memorySizeBytes - curr->offset, "final > memory");
    addr += curr->offset;
    trapIfGt(bytes, memorySizeBytes, "bytes > memory");
    checkLoadAddress(addr, bytes, memorySize);
    return addr;
  }

  template<class LS>
  Address getFinalAddress(LS* curr, Literal ptr, Address memorySize) {
    return getFinalAddress(curr, ptr, curr->bytes, memorySize);
  }

  Address
  getFinalAddressWithoutOffset(Literal ptr, Index bytes, Address memorySize) {
    uint64_t addr = ptr.type == Type::i32 ? ptr.geti32() : ptr.geti64();
    checkLoadAddress(addr, bytes, memorySize);
    return addr;
  }

  void checkLoadAddress(Address addr, Index bytes, Address memorySize) {
    Address memorySizeBytes = memorySize * Memory::kPageSize;
    trapIfGt(addr, memorySizeBytes - bytes, "highest > memory");
  }

  void checkAtomicAddress(Address addr, Index bytes, Address memorySize) {
    checkLoadAddress(addr, bytes, memorySize);
    // Unaligned atomics trap.
    if (bytes > 1) {
      if (addr & (bytes - 1)) {
        externalInterface->trap("unaligned atomic operation");
      }
    }
  }

  Literal doAtomicLoad(Address addr,
                       Index bytes,
                       Type type,
                       Name memoryName,
                       Address memorySize,
                       MemoryOrder order) {
    if (order == MemoryOrder::Unordered) {
      Fatal() << "Expected a non-unordered MemoryOrder in doAtomicLoad";
    }
    checkAtomicAddress(addr, bytes, memorySize);
    Const ptr;
    ptr.value = Literal(int32_t(addr));
    ptr.type = Type::i32;
    Load load;
    load.bytes = bytes;
    // When an atomic loads a partial number of bytes for the type, it is
    // always an unsigned extension.
    load.signed_ = false;
    load.align = bytes;
    load.order = order;
    load.ptr = &ptr;
    load.type = type;
    load.memory = memoryName;
    return externalInterface->load(&load, addr, memoryName);
  }

  void doAtomicStore(Address addr,
                     Index bytes,
                     Literal toStore,
                     Name memoryName,
                     Address memorySize) {
    checkAtomicAddress(addr, bytes, memorySize);
    Const ptr;
    ptr.value = Literal(int32_t(addr));
    ptr.type = Type::i32;
    Const value;
    value.value = toStore;
    value.type = toStore.type;
    Store store;
    store.bytes = bytes;
    store.align = bytes;
    store.order = MemoryOrder::SeqCst;
    store.ptr = &ptr;
    store.value = &value;
    store.valueType = value.type;
    store.memory = memoryName;
    return externalInterface->store(&store, addr, toStore, memoryName);
  }

  ExternalInterface* externalInterface;
  std::map<Name, std::shared_ptr<SubType>> linkedInstances;
  std::shared_ptr<ImportResolver> importResolver;
  std::function<CreateTableFunc> createTable;
};

class ModuleRunner : public ModuleRunnerBase<ModuleRunner> {
public:
  ModuleRunner(
    Module& wasm,
    ExternalInterface* externalInterface,
    std::map<Name, std::shared_ptr<ModuleRunner>> linkedInstances = {},
    std::shared_ptr<ImportResolver> importResolver = nullptr)
    : ModuleRunnerBase(
        wasm,
        externalInterface,
        importResolver
          ? importResolver
          : std::make_shared<LinkedInstancesImportResolver<ModuleRunner>>(
              linkedInstances),
        linkedInstances) {}

  Literal makeFuncData(Name name, Type type) {
    // As the super's |makeFuncData|, but here we also provide a way to
    // actually call the function.
    auto allocation =
      std::make_shared<FuncData>(name, this, [this, name](Literals arguments) {
        return callFunction(name, arguments);
      });
#if __has_feature(leak_sanitizer) || __has_feature(address_sanitizer)
    __lsan_ignore_object(allocation.get());
#endif
    return Literal(allocation, type);
  }
};

} // namespace wasm

#endif // wasm_wasm_interpreter_h
