/*
 * Copyright 2017 WebAssembly Community Group participants
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <iostream>
#include <mutex>
#include <sstream>
#include <unordered_set>

#include "ir/eh-utils.h"
#include "ir/features.h"
#include "ir/find_all.h"
#include "ir/gc-type-utils.h"
#include "ir/global-utils.h"
#include "ir/intrinsics.h"
#include "ir/local-structural-dominance.h"
#include "ir/module-utils.h"
#include "ir/stack-utils.h"
#include "ir/utils.h"
#include "support/colors.h"
#include "support/mixed_arena.h"
#include "wasm-features.h"
#include "wasm-type.h"
#include "wasm-validator.h"
#include "wasm.h"

namespace wasm {

namespace {

// Print anything that can be streamed to an ostream
template<typename T,
         typename std::enable_if<!std::is_base_of<
           Expression,
           typename std::remove_pointer<T>::type>::value>::type* = nullptr>
inline std::ostream&
printModuleComponent(T curr, std::ostringstream& stream, Module& wasm) {
  stream << curr << std::endl;
  return stream;
}

// Extra overload for Expressions, to print their contents.
inline std::ostream& printModuleComponent(Expression* curr,
                                          std::ostringstream& stream,
                                          Module& wasm) {
  if (curr) {
    // Print the full expression if we can, but avoid doing so if the output is
    // already very large. This avoids quadratic output in some cases (e.g. if
    // we have many nested expressions in each other, all of which fail to
    // validate).
    const std::ostringstream::pos_type MAX_OUTPUT = 16 * 1024;
    if (stream.tellp() < MAX_OUTPUT) {
      stream << ModuleExpression(wasm, curr) << '\n';
    } else {
      // Print something, at least.
      stream << "[not printing " << getExpressionName(curr)
             << " because output is already very large]\n";
    }
  }
  return stream;
}

// For parallel validation, we have a helper struct for coordination
struct ValidationInfo {
  Module& wasm;

  bool validateWeb;
  bool validateGlobally;
  bool quiet;

  std::atomic<bool> valid;

  // a stream of error test for each function. we print in the right order at
  // the end, for deterministic output
  // note errors are rare/unexpected, so it's ok to use a slow mutex here
  std::mutex mutex;
  std::unordered_map<Function*, std::unique_ptr<std::ostringstream>> outputs;

  ValidationInfo(Module& wasm) : wasm(wasm) { valid.store(true); }

  std::ostringstream& getStream(Function* func) {
    std::unique_lock<std::mutex> lock(mutex);
    auto iter = outputs.find(func);
    if (iter != outputs.end()) {
      return *(iter->second.get());
    }
    auto& ret = outputs[func] = std::make_unique<std::ostringstream>();
    return *ret.get();
  }

  // printing and error handling support

  template<typename T, typename S>
  std::ostream& fail(S text, T curr, Function* func) {
    valid.store(false);
    auto& stream = getStream(func);
    if (quiet) {
      return stream;
    }
    auto& ret = printFailureHeader(func);
    ret << text << ", on \n";
    return printModuleComponent(curr, ret, wasm);
  }

  std::ostringstream& printFailureHeader(Function* func) {
    auto& stream = getStream(func);
    if (quiet) {
      return stream;
    }
    Colors::red(stream);
    if (func) {
      stream << "[wasm-validator error in function ";
      Colors::green(stream);
      stream << func->name;
      Colors::red(stream);
      stream << "] ";
    } else {
      stream << "[wasm-validator error in module] ";
    }
    Colors::normal(stream);
    return stream;
  }

  // Checking utilities.

  // Returns whether the result was in fact true.
  template<typename T>
  bool shouldBeTrue(bool result,
                    T curr,
                    const char* text,
                    Function* func = nullptr) {
    if (!result) {
      fail("unexpected false: " + std::string(text), curr, func);
      return false;
    }
    return true;
  }

  // Returns whether the result was in fact false.
  template<typename T>
  bool shouldBeFalse(bool result,
                     T curr,
                     const char* text,
                     Function* func = nullptr) {
    if (result) {
      fail("unexpected true: " + std::string(text), curr, func);
      return false;
    }
    return true;
  }

  template<typename T, typename S>
  bool shouldBeEqual(
    S left, S right, T curr, const char* text, Function* func = nullptr) {
    if (left != right) {
      std::ostringstream ss;
      ss << left << " != " << right << ": " << text;
      fail(ss.str(), curr, func);
      return false;
    }
    return true;
  }

  template<typename T>
  bool shouldBeEqualOrFirstIsUnreachable(
    Type left, Type right, T curr, const char* text, Function* func = nullptr) {
    if (left != Type::unreachable && left != right) {
      std::ostringstream ss;
      ss << left << " != " << right << ": " << text;
      fail(ss.str(), curr, func);
      return false;
    }
    return true;
  }

  template<typename T, typename S>
  bool shouldBeUnequal(
    S left, S right, T curr, const char* text, Function* func = nullptr) {
    if (left == right) {
      std::ostringstream ss;
      ss << left << " == " << right << ": " << text;
      fail(ss.str(), curr, func);
      return false;
    }
    return true;
  }

  void shouldBeIntOrUnreachable(Type ty,
                                Expression* curr,
                                const char* text,
                                Function* func = nullptr) {
    if (!ty.isBasic()) {
      fail(text, curr, func);
      return;
    }
    switch (ty.getBasic()) {
      case Type::i32:
      case Type::i64:
      case Type::unreachable: {
        break;
      }
      default:
        fail(text, curr, func);
    }
  }

  // Type 'left' should be a subtype of 'right'.
  bool shouldBeSubType(Type left,
                       Type right,
                       Expression* curr,
                       const char* text,
                       Function* func = nullptr) {
    if (Type::isSubType(left, right)) {
      return true;
    }
    fail(text, curr, func);
    return false;
  }

  bool shouldBeSubTypeIgnoringShared(Type left,
                                     Type right,
                                     Expression* curr,
                                     const char* text,
                                     Function* func = nullptr) {
    assert(right.isRef() && right.getHeapType().isBasic());
    auto share = left.isRef() ? left.getHeapType().getShared() : Unshared;
    auto ht = right.getHeapType();
    auto matchedRight = Type(ht.getBasic(share), right.getNullability());
    return shouldBeSubType(left, matchedRight, curr, text, func);
  }
};

// Check that public types do not contain any exact references if custom
// descriptors is not enabled. If they did, we would erase the exactness
// during binary writing and change the public type identities.
void validateExactReferences(Module& module, ValidationInfo& info) {
  if (module.features.hasCustomDescriptors()) {
    return;
  }

  for (auto type : ModuleUtils::getExposedPublicHeapTypes(module)) {
    for (auto child : type.getTypeChildren()) {
      if (child.isExact()) {
        std::string typeName;
        if (auto it = module.typeNames.find(type);
            it != module.typeNames.end()) {
          typeName = '$' + it->second.name.toString();
        } else {
          typeName = type.toString();
        }
        info.fail("Exact reference in public type not allowed without custom "
                  "descriptors [--enable-custom-descriptors]",
                  typeName,
                  nullptr);
        break;
      }
    }
  }
}

std::string getMissingFeaturesList(Module& wasm, FeatureSet feats) {
  std::stringstream ss;
  bool first = true;
  ss << '[';
  (feats - wasm.features).iterFeatures([&](FeatureSet feat) {
    if (first) {
      first = false;
    } else {
      ss << " ";
    }
    ss << "--enable-" << feat.toString();
  });
  ss << ']';
  return ss.str();
}

struct FunctionValidator : public WalkerPass<PostWalker<FunctionValidator>> {
  bool isFunctionParallel() override { return true; }

  std::unique_ptr<Pass> create() override {
    return std::make_unique<FunctionValidator>(*getModule(), &info);
  }

  bool modifiesBinaryenIR() override { return false; }

  ValidationInfo& info;

  FunctionValidator(Module& wasm, ValidationInfo* info) : info(*info) {
    setModule(&wasm);
  }

  // Validate the entire module.
  void validate(PassRunner* runner) { run(runner, getModule()); }

  // Validate a specific expression.
  void validate(Expression* curr) { walk(curr); }

  // Validate a function.
  void validate(Function* func) { walkFunction(func); }

  // The types sent to each label on branches.
  std::unordered_map<Name, std::unordered_set<Type>> breakTypes;
  // The Tags and continuation result types used to resume at this label.
  struct ResumeInfo {
    Expression* resume;
    Tag* tag;
    Type contResult;
  };
  std::unordered_map<Name, std::vector<ResumeInfo>> resumeInfos;
  std::unordered_set<Name> delegateTargetNames;
  std::unordered_set<Name> rethrowTargetNames;

  // Binaryen IR requires that label names must be unique - IR generators must
  // ensure that
  std::unordered_set<Name> labelNames;

  void noteLabelName(Name name);

public:
  // visitors

  void validatePoppyExpression(Expression* curr);

  static void visitPoppyExpression(FunctionValidator* self,
                                   Expression** currp) {
    self->validatePoppyExpression(*currp);
  }

  static void visitPreBlock(FunctionValidator* self, Expression** currp) {
    auto* curr = (*currp)->cast<Block>();
    if (curr->name.is()) {
      self->breakTypes.try_emplace(curr->name);
    }
  }

  void visitBlock(Block* curr);
  void validateNormalBlockElements(Block* curr);
  void validatePoppyBlockElements(Block* curr);

  static void visitPreLoop(FunctionValidator* self, Expression** currp) {
    auto* curr = (*currp)->cast<Loop>();
    if (curr->name.is()) {
      self->breakTypes.try_emplace(curr->name);
    }
  }

  void visitLoop(Loop* curr);
  void visitIf(If* curr);

  static void visitPreTry(FunctionValidator* self, Expression** currp) {
    auto* curr = (*currp)->cast<Try>();
    if (curr->name.is()) {
      self->delegateTargetNames.insert(curr->name);
    }
  }

  // We remove try's label before proceeding to verify catch bodies because the
  // following is a validation failure:
  // (try $l0
  //   (do ... )
  //   (catch $e
  //     (try
  //       (do ...)
  //       (delegate $l0) ;; validation failure
  //     )
  //   )
  // )
  // Unlike branches, if delegate's target 'catch' is located above the
  // delegate, it is a validation failure.
  static void visitPreCatch(FunctionValidator* self, Expression** currp) {
    auto* curr = (*currp)->cast<Try>();
    if (curr->name.is()) {
      self->delegateTargetNames.erase(curr->name);
      self->rethrowTargetNames.insert(curr->name);
    }
  }

  // override scan to add a pre and a post check task to all nodes
  static void scan(FunctionValidator* self, Expression** currp) {
    auto* curr = *currp;
    // Treat 'Try' specially because we need to run visitPreCatch between the
    // try body and catch bodies
    if (curr->is<Try>()) {
      self->pushTask(doVisitTry, currp);
      auto& list = curr->cast<Try>()->catchBodies;
      for (int i = int(list.size()) - 1; i >= 0; i--) {
        self->pushTask(scan, &list[i]);
      }
      self->pushTask(visitPreCatch, currp);
      self->pushTask(scan, &curr->cast<Try>()->body);
      self->pushTask(visitPreTry, currp);
      return;
    }

    PostWalker<FunctionValidator>::scan(self, currp);

    if (curr->is<Block>()) {
      self->pushTask(visitPreBlock, currp);
    }
    if (curr->is<Loop>()) {
      self->pushTask(visitPreLoop, currp);
    }
    if (auto* func = self->getFunction()) {
      if (func->profile == IRProfile::Poppy) {
        self->pushTask(visitPoppyExpression, currp);
      }
    }

    // Also verify that only allowed expressions end up in the situation where
    // the expression has type unreachable but there is no unreachable child.
    // For example a Call with no unreachable child cannot be unreachable, but a
    // Break can be.
    if (curr->type == Type::unreachable) {
      switch (curr->_id) {
        case Expression::BreakId: {
          // If there is a condition, that is already validated fully in
          // visitBreak(). If there isn't a condition, then this is allowed to
          // be unreachable even without an unreachable child. Either way, we
          // can leave.
          return;
        }
        case Expression::SwitchId:
        case Expression::ReturnId:
        case Expression::UnreachableId:
        case Expression::ThrowId:
        case Expression::RethrowId:
        case Expression::ThrowRefId: {
          // These can all be unreachable without an unreachable child.
          return;
        }
        case Expression::CallId: {
          if (curr->cast<Call>()->isReturn) {
            return;
          }
          break;
        }
        case Expression::CallIndirectId: {
          if (curr->cast<CallIndirect>()->isReturn) {
            return;
          }
          break;
        }
        case Expression::CallRefId: {
          if (curr->cast<CallRef>()->isReturn) {
            return;
          }
          break;
        }
        default: {
          break;
        }
      }

      // If we reach here, then we must have an unreachable child.
      bool hasUnreachableChild = false;
      for (auto* child : ChildIterator(curr)) {
        if (child->type == Type::unreachable) {
          hasUnreachableChild = true;
          break;
        }
      }
      self->shouldBeTrue(hasUnreachableChild,
                         curr,
                         "unreachable instruction must have unreachable child");
    }
  }

  void noteBreak(Name name, Expression* value, Expression* curr);
  void noteBreak(Name name, Type valueType, Expression* curr);
  void visitBreak(Break* curr);
  void visitSwitch(Switch* curr);
  void visitCall(Call* curr);
  void visitCallIndirect(CallIndirect* curr);
  void visitConst(Const* curr);
  void visitLocalGet(LocalGet* curr);
  void visitLocalSet(LocalSet* curr);
  void visitGlobalGet(GlobalGet* curr);
  void visitGlobalSet(GlobalSet* curr);
  void visitLoad(Load* curr);
  void visitStore(Store* curr);
  void visitAtomicRMW(AtomicRMW* curr);
  void visitAtomicCmpxchg(AtomicCmpxchg* curr);
  void visitAtomicWait(AtomicWait* curr);
  void visitAtomicNotify(AtomicNotify* curr);
  void visitAtomicFence(AtomicFence* curr);
  void visitPause(Pause* curr);
  void visitSIMDExtract(SIMDExtract* curr);
  void visitSIMDReplace(SIMDReplace* curr);
  void visitSIMDShuffle(SIMDShuffle* curr);
  void visitSIMDTernary(SIMDTernary* curr);
  void visitSIMDShift(SIMDShift* curr);
  void visitSIMDLoad(SIMDLoad* curr);
  void visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr);
  void visitMemoryInit(MemoryInit* curr);
  void visitDataDrop(DataDrop* curr);
  void visitMemoryCopy(MemoryCopy* curr);
  void visitMemoryFill(MemoryFill* curr);
  void visitBinary(Binary* curr);
  void visitWideIntAddSub(WideIntAddSub* curr);
  void visitWideIntMul(WideIntMul* curr);
  void visitUnary(Unary* curr);
  void visitSelect(Select* curr);
  void visitDrop(Drop* curr);
  void visitReturn(Return* curr);
  void visitMemorySize(MemorySize* curr);
  void visitMemoryGrow(MemoryGrow* curr);
  void visitRefNull(RefNull* curr);
  void visitRefIsNull(RefIsNull* curr);
  void visitRefAs(RefAs* curr);
  void visitRefFunc(RefFunc* curr);
  void visitRefEq(RefEq* curr);
  void visitTableGet(TableGet* curr);
  void visitTableSet(TableSet* curr);
  void visitTableSize(TableSize* curr);
  void visitTableGrow(TableGrow* curr);
  void visitTableFill(TableFill* curr);
  void visitTableCopy(TableCopy* curr);
  void visitTableInit(TableInit* curr);
  void visitElemDrop(ElemDrop* curr);
  void noteDelegate(Name name, Expression* curr);
  void noteRethrow(Name name, Expression* curr);
  void visitTry(Try* curr);
  void visitTryTable(TryTable* curr);
  void visitThrow(Throw* curr);
  void visitRethrow(Rethrow* curr);
  void visitThrowRef(ThrowRef* curr);
  void visitTupleMake(TupleMake* curr);
  void visitTupleExtract(TupleExtract* curr);
  void visitCallRef(CallRef* curr);
  void visitRefI31(RefI31* curr);
  void visitI31Get(I31Get* curr);
  void visitRefTest(RefTest* curr);
  void visitRefCast(RefCast* curr);
  void visitRefGetDesc(RefGetDesc* curr);
  void visitBrOn(BrOn* curr);
  void visitStructNew(StructNew* curr);
  void visitStructGet(StructGet* curr);
  void visitStructSet(StructSet* curr);
  void visitStructRMW(StructRMW* curr);
  void visitStructCmpxchg(StructCmpxchg* curr);
  void visitArrayNew(ArrayNew* curr);
  template<typename ArrayNew> void visitArrayNewSegment(ArrayNew* curr);
  void visitArrayNewData(ArrayNewData* curr);
  void visitArrayNewElem(ArrayNewElem* curr);
  void visitArrayNewFixed(ArrayNewFixed* curr);
  void visitArrayGet(ArrayGet* curr);
  void visitArraySet(ArraySet* curr);
  void visitArrayLoad(ArrayLoad* curr);
  void visitArrayStore(ArrayStore* curr);
  void visitArrayLen(ArrayLen* curr);
  void visitArrayCopy(ArrayCopy* curr);
  void visitArrayFill(ArrayFill* curr);
  template<typename ArrayInit> void visitArrayInit(ArrayInit* curr);
  void visitArrayInitData(ArrayInitData* curr);
  void visitArrayInitElem(ArrayInitElem* curr);
  void visitArrayRMW(ArrayRMW* curr);
  void visitArrayCmpxchg(ArrayCmpxchg* curr);
  void visitStructWait(StructWait* curr);
  void visitStructNotify(StructNotify* curr);
  void visitStringNew(StringNew* curr);
  void visitStringConst(StringConst* curr);
  void visitStringMeasure(StringMeasure* curr);
  void visitStringEncode(StringEncode* curr);
  void visitStringConcat(StringConcat* curr);
  void visitStringEq(StringEq* curr);
  void visitStringTest(StringTest* curr);
  void visitStringWTF16Get(StringWTF16Get* curr);
  void visitStringSliceWTF(StringSliceWTF* curr);
  void visitContNew(ContNew* curr);
  void visitContBind(ContBind* curr);
  void visitSuspend(Suspend* curr);
  void validateResumeHandlers(Expression* curr,
                              Type contResults,
                              const ArenaVector<Name>& tags,
                              const ArenaVector<Name>& labels);
  void visitResume(Resume* curr);
  void visitResumeThrow(ResumeThrow* curr);
  void visitStackSwitch(StackSwitch* curr);

  void visitFunction(Function* curr);

  // helpers
private:
  std::ostream& getStream() { return info.getStream(getFunction()); }

  template<typename T>
  bool shouldBeTrue(bool result, T curr, const char* text) {
    return info.shouldBeTrue(result, curr, text, getFunction());
  }
  template<typename T>
  bool shouldBeFalse(bool result, T curr, const char* text) {
    return info.shouldBeFalse(result, curr, text, getFunction());
  }

  template<typename T, typename S>
  bool shouldBeEqual(S left, S right, T curr, const char* text) {
    return info.shouldBeEqual(left, right, curr, text, getFunction());
  }

  template<typename T>
  bool shouldBeEqualOrFirstIsUnreachable(Type left,
                                         Type right,
                                         T curr,
                                         const char* text) {
    return info.shouldBeEqualOrFirstIsUnreachable(
      left, right, curr, text, getFunction());
  }

  template<typename T, typename S>
  bool shouldBeUnequal(S left, S right, T curr, const char* text) {
    return info.shouldBeUnequal(left, right, curr, text, getFunction());
  }

  void shouldBeIntOrUnreachable(Type ty, Expression* curr, const char* text) {
    return info.shouldBeIntOrUnreachable(ty, curr, text, getFunction());
  }

  bool
  shouldBeSubType(Type left, Type right, Expression* curr, const char* text) {
    return info.shouldBeSubType(left, right, curr, text, getFunction());
  }

  bool shouldBeSubTypeIgnoringShared(Type left,
                                     Type right,
                                     Expression* curr,
                                     const char* text) {
    return info.shouldBeSubTypeIgnoringShared(left, right, curr, text);
  }

  void validateOffset(Address offset, Memory* mem, Expression* curr);
  void validateAlignment(
    size_t align, Type type, Index bytes, bool isAtomic, Expression* curr);
  void validateMemBytes(uint8_t bytes, Type type, Expression* curr);

  template<typename T> void validateReturnCall(T* curr) {
    shouldBeTrue(!curr->isReturn || getModule()->features.hasTailCall(),
                 curr,
                 "return_call* requires tail calls [--enable-tail-call]");
  }

  // |printable| is the expression to print in case of an error. That may differ
  // from |curr| which we are validating.
  template<typename T>
  void validateCallParamsAndResult(T* curr,
                                   HeapType sigType,
                                   Expression* printable) {
    if (!shouldBeTrue(sigType.isSignature(),
                      printable,
                      "Heap type must be a signature type")) {
      return;
    }
    auto sig = sigType.getSignature();
    if (!shouldBeTrue(curr->operands.size() == sig.params.size(),
                      printable,
                      "call* param number must match")) {
      return;
    }
    size_t i = 0;
    for (const auto& param : sig.params) {
      if (!shouldBeSubType(curr->operands[i]->type,
                           param,
                           printable,
                           "call param types must match") &&
          !info.quiet) {
        getStream() << "(on argument " << i << ")\n";
      }
      ++i;
    }
    if (curr->isReturn) {
      shouldBeEqual(curr->type,
                    Type(Type::unreachable),
                    printable,
                    "return_call* should have unreachable type");
      auto* func = getFunction();
      if (!shouldBeTrue(!!func, curr, "function not defined")) {
        return;
      }
      shouldBeSubType(
        sig.results,
        func->getResults(),
        printable,
        "return_call* callee return type must match caller return type");
    } else {
      shouldBeEqualOrFirstIsUnreachable(
        curr->type,
        sig.results,
        printable,
        "call* type must match callee return type");
    }
  }

  // In the common case, we use |curr| as |printable|.
  template<typename T>
  void validateCallParamsAndResult(T* curr, HeapType sigType) {
    validateCallParamsAndResult(curr, sigType, curr);
  }
};

void FunctionValidator::noteLabelName(Name name) {
  if (!name.is()) {
    return;
  }
  auto [_, inserted] = labelNames.insert(name);
  shouldBeTrue(
    inserted,
    name,
    "names in Binaryen IR must be unique - IR generators must ensure that");
}

void FunctionValidator::validatePoppyExpression(Expression* curr) {
  if (curr->type == Type::unreachable) {
    shouldBeTrue(StackUtils::mayBeUnreachable(curr),
                 curr,
                 "Only control flow structures and unreachable polymorphic"
                 " instructions may be unreachable in Poppy IR");
  }
  if (Properties::isControlFlowStructure(curr)) {
    // Check that control flow children (except If conditions) are blocks
    if (auto* if_ = curr->dynCast<If>()) {
      shouldBeTrue(
        if_->condition->is<Pop>(), curr, "Expected condition to be a Pop");
      shouldBeTrue(if_->ifTrue->is<Block>(),
                   curr,
                   "Expected control flow child to be a block");
      shouldBeTrue(!if_->ifFalse || if_->ifFalse->is<Block>(),
                   curr,
                   "Expected control flow child to be a block");
    } else if (!curr->is<Block>()) {
      for (auto* child : ChildIterator(curr)) {
        shouldBeTrue(child->is<Block>(),
                     curr,
                     "Expected control flow child to be a block");
      }
    }
  } else {
    // Check that all children are Pops
    for (auto* child : ChildIterator(curr)) {
      shouldBeTrue(child->is<Pop>(), curr, "Unexpected non-Pop child");
    }
  }
}

void FunctionValidator::visitBlock(Block* curr) {
  auto feats = curr->type.getFeatures();
  if (!shouldBeTrue(feats.isSubsetOf(getModule()->features),
                    curr,
                    "Block type requires additional features")) {
    getStream() << getMissingFeaturesList(*getModule(), feats) << '\n';
  }
  // if we are break'ed to, then the value must be right for us
  if (curr->name.is()) {
    noteLabelName(curr->name);
    auto iter = breakTypes.find(curr->name);
    assert(iter != breakTypes.end()); // we set it ourselves
    for (Type breakType : iter->second) {
      if (breakType == Type::none && curr->type == Type::unreachable) {
        // We allow empty breaks to unreachable blocks.
        continue;
      }

      shouldBeSubType(breakType,
                      curr->type,
                      curr,
                      "break type must be a subtype of the target block type");
    }
    breakTypes.erase(iter);
    // Check the tags of resume handlers that target this block as well.
    if (auto it = resumeInfos.find(curr->name); it != resumeInfos.end()) {
      for (const auto& [resume, tag_, contResult] : it->second) {
        // TODO: Captured structured references are a C++20 extension.
        const auto& tag = tag_;
        // The tag's params must match the block results, except for the last
        // result, which must be a continuation type whose parameters match the
        // tag's results and whose results must be matched by the resumed
        // continuation's results.
        auto printHandler = [&]() {
          if (!info.quiet) {
            getStream() << "at (on " << tag->name << ' ' << curr->name << ")\n";
          }
        };
        if (!shouldBeEqual(tag->params().size() + 1,
                           curr->type.size(),
                           resume,
                           "mismatched resume handler tag and label arities")) {
          printHandler();
          break;
        }
        for (Index i = 0; i < tag->params().size(); ++i) {
          if (!shouldBeSubType(tag->params()[i],
                               curr->type[i],
                               resume,
                               "tag type does not match label type")) {
            if (info.quiet) {
              getStream() << "at index " << i << "\n";
            }
            break;
          }
        }
        Type cont = curr->type[curr->type.size() - 1];
        if (!shouldBeTrue(cont.isContinuation(),
                          resume,
                          "resume handler branches to label that does not take "
                          "a continuation")) {
          printHandler();
          break;
        }
        auto contSig = cont.getHeapType().getContinuation().type.getSignature();
        if (!shouldBeSubType(contSig.params,
                             tag->results(),
                             resume,
                             "new continuation parameters do not match "
                             "expected suspension results")) {
          printHandler();
        }
        if (!shouldBeSubType(contResult,
                             contSig.results,
                             resume,
                             "resumed continuation results do not match new "
                             "continuation results")) {
          printHandler();
        }
      }
      resumeInfos.erase(it);
    }
  }

  auto* func = getFunction();
  if (!shouldBeTrue(!!func, curr, "function not defined")) {
    return;
  }
  switch (func->profile) {
    case IRProfile::Normal:
      validateNormalBlockElements(curr);
      break;
    case IRProfile::Poppy:
      validatePoppyBlockElements(curr);
      break;
  }
}

void FunctionValidator::validateNormalBlockElements(Block* curr) {
  if (curr->list.size() > 1) {
    for (Index i = 0; i < curr->list.size() - 1; i++) {
      if (!shouldBeTrue(
            !curr->list[i]->type.isConcrete(),
            curr,
            "non-final block elements returning a value must be dropped") &&
          !info.quiet) {
        getStream() << "(on index " << i << ":\n"
                    << curr->list[i] << "\n), type: " << curr->list[i]->type
                    << "\n";
      }
    }
  }
  if (curr->list.size() > 0) {
    auto backType = curr->list.back()->type;
    if (!curr->type.isConcrete()) {
      shouldBeFalse(backType.isConcrete(),
                    curr,
                    "if block is not returning a value, final element should "
                    "not flow out a value");
    } else {
      if (backType.isConcrete()) {
        shouldBeSubType(
          backType,
          curr->type,
          curr,
          "block with value and last element with value must match types");
      } else {
        shouldBeUnequal(
          backType,
          Type(Type::none),
          curr,
          "block with value must not have last element that is none");
      }
    }
  }
  if (curr->type.isConcrete()) {
    shouldBeTrue(
      curr->list.size() > 0, curr, "block with a value must not be empty");
  }
}

void FunctionValidator::validatePoppyBlockElements(Block* curr) {
  StackSignature blockSig;
  for (size_t i = 0; i < curr->list.size(); ++i) {
    Expression* expr = curr->list[i];
    if (!shouldBeTrue(
          !expr->is<Pop>(), expr, "Unexpected top-level pop in block")) {
      return;
    }
    StackSignature sig(expr);
    if (!shouldBeTrue(blockSig.composes(sig),
                      curr,
                      "block element has incompatible type") &&
        !info.quiet) {
      getStream() << "(on index " << i << ":\n"
                  << expr << "\n), required: " << sig.params << ", available: ";
      if (blockSig.kind == StackSignature::Polymorphic) {
        getStream() << "polymorphic, ";
      }
      getStream() << blockSig.results << "\n";
      return;
    }
    blockSig += sig;
  }
  if (curr->type == Type::unreachable) {
    shouldBeTrue(blockSig.kind == StackSignature::Polymorphic,
                 curr,
                 "unreachable block should have unreachable element");
  } else {
    if (!shouldBeTrue(
          StackSignature::isSubType(
            blockSig,
            StackSignature(Type::none, curr->type, StackSignature::Fixed)),
          curr,
          "block contents should satisfy block type") &&
        !info.quiet) {
      getStream() << "contents: " << blockSig.results
                  << (blockSig.kind == StackSignature::Polymorphic
                        ? " [polymorphic]"
                        : "")
                  << "\n"
                  << "expected: " << curr->type << "\n";
    }
  }
}

void FunctionValidator::visitLoop(Loop* curr) {
  if (curr->name.is()) {
    noteLabelName(curr->name);
    auto iter = breakTypes.find(curr->name);
    assert(iter != breakTypes.end()); // we set it ourselves
    for (Type breakType : iter->second) {
      shouldBeEqual(breakType,
                    Type(Type::none),
                    curr,
                    "breaks to a loop cannot pass a value");
    }
    breakTypes.erase(iter);
  }
  if (curr->type == Type::none) {
    shouldBeFalse(curr->body->type.isConcrete(),
                  curr,
                  "bad body for a loop that has no value");
  }

  // When there are multiple instructions within a loop, they are wrapped in a
  // Block internally, so visitBlock can take care of verification. Here we
  // check cases when there is only one instruction in a Loop.
  if (!curr->body->is<Block>()) {
    if (!curr->type.isConcrete()) {
      shouldBeFalse(curr->body->type.isConcrete(),
                    curr,
                    "if loop is not returning a value, final element should "
                    "not flow out a value");
    } else {
      shouldBeSubType(curr->body->type,
                      curr->type,
                      curr,
                      "loop with value and body must match types");
    }
  }
}

void FunctionValidator::visitIf(If* curr) {
  shouldBeTrue(curr->condition->type == Type::unreachable ||
                 curr->condition->type == Type::i32,
               curr,
               "if condition must be valid");
  if (!curr->ifFalse) {
    shouldBeFalse(curr->ifTrue->type.isConcrete(),
                  curr,
                  "if without else must not return a value in body");
    if (curr->condition->type != Type::unreachable) {
      shouldBeEqual(curr->type,
                    Type(Type::none),
                    curr,
                    "if without else and reachable condition must be none");
    }
  } else {
    if (curr->type != Type::unreachable) {
      shouldBeSubType(curr->ifTrue->type,
                      curr->type,
                      curr,
                      "returning if-else's true must have right type");
      shouldBeSubType(curr->ifFalse->type,
                      curr->type,
                      curr,
                      "returning if-else's false must have right type");
    } else {
      if (curr->condition->type == Type::unreachable) {
        shouldBeTrue(
          curr->ifTrue->type == Type::unreachable ||
            curr->ifFalse->type == Type::unreachable ||
            (curr->ifTrue->type == Type::none &&
             curr->ifFalse->type == Type::none) ||
            Type::hasLeastUpperBound(curr->ifTrue->type, curr->ifFalse->type),
          curr,
          "arms of unreachable if-else must have compatible types");
      } else {
        shouldBeEqual(curr->ifTrue->type,
                      Type(Type::unreachable),
                      curr,
                      "unreachable if-else must have unreachable true");
        shouldBeEqual(curr->ifFalse->type,
                      Type(Type::unreachable),
                      curr,
                      "unreachable if-else must have unreachable false");
      }
    }
  }
}

void FunctionValidator::noteBreak(Name name,
                                  Expression* value,
                                  Expression* curr) {
  if (value) {
    shouldBeUnequal(
      value->type, Type(Type::none), curr, "breaks must have a valid value");
  }
  noteBreak(name, value ? value->type : Type::none, curr);
}

void FunctionValidator::noteBreak(Name name, Type valueType, Expression* curr) {
  auto iter = breakTypes.find(name);
  if (!shouldBeTrue(
        iter != breakTypes.end(), curr, "all break targets must be valid")) {
    return;
  }
  iter->second.insert(valueType);
}

void FunctionValidator::visitBreak(Break* curr) {
  noteBreak(curr->name, curr->value, curr);
  if (curr->value) {
    shouldBeTrue(curr->value->type != Type::none,
                 curr,
                 "break value must not have none type");
  }
  if (curr->condition) {
    shouldBeTrue(curr->condition->type == Type::unreachable ||
                   curr->condition->type == Type::i32,
                 curr,
                 "break condition must be i32");
  }
}

void FunctionValidator::visitSwitch(Switch* curr) {
  for (auto& target : curr->targets) {
    noteBreak(target, curr->value, curr);
  }
  noteBreak(curr->default_, curr->value, curr);
  shouldBeTrue(curr->condition->type == Type::unreachable ||
                 curr->condition->type == Type::i32,
               curr,
               "br_table condition must be i32");
}

void FunctionValidator::visitCall(Call* curr) {
  validateReturnCall(curr);
  if (!info.validateGlobally) {
    return;
  }
  auto* target = getModule()->getFunctionOrNull(curr->target);
  if (!shouldBeTrue(!!target, curr, "call target must exist")) {
    return;
  }
  validateCallParamsAndResult(curr, target->type.getHeapType());

  if (Intrinsics(*getModule()).isCallWithoutEffects(curr)) {
    // call.without.effects has the specific form of the last argument being a
    // function reference, which will be called with all the previous arguments.
    // The type must be consistent with that. This, for example, is not:
    //
    //  (call $call.without.effects
    //    (i32.const 1)
    //    (.. some function reference that expects an f64 param and not i32 ..)
    //  )
    if (shouldBeTrue(!curr->operands.empty(),
                     curr,
                     "call.without.effects must have a target operand")) {
      auto* target = curr->operands.back();
      // Validate only in the case that the target is a function. If it isn't,
      // it might be unreachable (which is fine, and we can ignore this), or if
      // the call.without.effects import doesn't have a function as the last
      // parameter, then validateImports() will handle that later (and it's
      // better to emit a single error there than one per callsite here).
      if (target->type.isFunction()) {
        // Copy the original call and remove the reference. It must then match
        // the expected signature.
        struct Copy {
          std::vector<Expression*> operands;
          bool isReturn;
          Type type;
        } copy;
        for (Index i = 0; i < curr->operands.size() - 1; i++) {
          copy.operands.push_back(curr->operands[i]);
        }
        copy.isReturn = curr->isReturn;
        copy.type = curr->type;
        validateCallParamsAndResult(&copy, target->type.getHeapType(), curr);
      }
    }
  }
}

void FunctionValidator::visitCallIndirect(CallIndirect* curr) {
  validateReturnCall(curr);

  if (curr->target->type != Type::unreachable) {
    auto* table = getModule()->getTableOrNull(curr->table);
    if (shouldBeTrue(!!table, curr, "call-indirect table must exist")) {
      shouldBeEqualOrFirstIsUnreachable(
        curr->target->type,
        table->addressType,
        curr,
        "call-indirect call target must match the table index type");
      shouldBeTrue(!!table, curr, "call-indirect table must exist");
      shouldBeTrue(table->type.isFunction(),
                   curr,
                   "call-indirect table must be of function type.");
    }
  }

  validateCallParamsAndResult(curr, curr->heapType);
}

void FunctionValidator::visitConst(Const* curr) {
  shouldBeTrue(curr->type.getFeatures().isSubsetOf(getModule()->features),
               curr,
               "all used features should be allowed");
}

void FunctionValidator::visitLocalGet(LocalGet* curr) {
  shouldBeTrue(curr->type.isConcrete(),
               curr,
               "local.get must have a valid type - check what you provided "
               "when you constructed the node");
  if (shouldBeTrue(curr->index < getFunction()->getNumLocals(),
                   curr,
                   "local.get index must be small enough")) {
    shouldBeTrue(curr->type == getFunction()->getLocalType(curr->index),
                 curr,
                 "local.get must have proper type");
  }
}

void FunctionValidator::visitLocalSet(LocalSet* curr) {
  if (shouldBeTrue(curr->index < getFunction()->getNumLocals(),
                   curr,
                   "local.set index must be small enough")) {
    if (curr->value->type != Type::unreachable) {
      if (curr->type != Type::none) { // tee is ok anyhow
        shouldBeEqual(getFunction()->getLocalType(curr->index),
                      curr->type,
                      curr,
                      "local.set type must be correct");
      }
      shouldBeSubType(curr->value->type,
                      getFunction()->getLocalType(curr->index),
                      curr,
                      "local.set's value type must be correct");
    }
  }
}

void FunctionValidator::visitGlobalGet(GlobalGet* curr) {
  if (!info.validateGlobally) {
    return;
  }
  auto* global = getModule()->getGlobalOrNull(curr->name);
  if (shouldBeTrue(global, curr, "global.get name must be valid")) {
    shouldBeEqual(
      curr->type, global->type, curr, "global.get must have right type");
  }
}

void FunctionValidator::visitGlobalSet(GlobalSet* curr) {
  if (!info.validateGlobally) {
    return;
  }
  auto* global = getModule()->getGlobalOrNull(curr->name);
  if (shouldBeTrue(global,
                   curr,
                   "global.set name must be valid (and not an import; imports "
                   "can't be modified)")) {
    shouldBeTrue(global->mutable_, curr, "global.set global must be mutable");
    shouldBeSubType(curr->value->type,
                    global->type,
                    curr,
                    "global.set value must have right type");
  }
}

void FunctionValidator::visitLoad(Load* curr) {
  auto* memory = getModule()->getMemoryOrNull(curr->memory);
  shouldBeTrue(!!memory, curr, "memory.load memory must exist");
  if (curr->isAtomic()) {
    shouldBeTrue(getModule()->features.hasAtomics(),
                 curr,
                 "Atomic operations require threads [--enable-threads]");
    shouldBeTrue(curr->type == Type::i32 || curr->type == Type::i64 ||
                   curr->type == Type::unreachable,
                 curr,
                 "Atomic load should be i32 or i64");
  }
  switch (curr->order) {
    case MemoryOrder::AcqRel: {
      shouldBeTrue(getModule()->features.hasRelaxedAtomics(),
                   curr,
                   "Acquire/release operations require relaxed atomics "
                   "[--enable-relaxed-atomics]");
      break;
    }
    case MemoryOrder::Unordered:
    case MemoryOrder::SeqCst:
      break;
  }
  if (curr->type == Type::v128) {
    shouldBeTrue(getModule()->features.hasSIMD(),
                 curr,
                 "SIMD operations require SIMD [--enable-simd]");
  }
  validateMemBytes(curr->bytes, curr->type, curr);
  validateOffset(curr->offset, memory, curr);
  validateAlignment(
    curr->align, curr->type, curr->bytes, curr->isAtomic(), curr);
  shouldBeEqualOrFirstIsUnreachable(
    curr->ptr->type,
    memory->addressType,
    curr,
    "load pointer type must match memory index type");
  if (curr->isAtomic()) {
    shouldBeFalse(curr->signed_, curr, "atomic loads must be unsigned");
    shouldBeIntOrUnreachable(
      curr->type, curr, "atomic loads must be of integers");
  }
}

void FunctionValidator::visitStore(Store* curr) {
  auto* memory = getModule()->getMemoryOrNull(curr->memory);
  shouldBeTrue(!!memory, curr, "memory.store memory must exist");
  if (curr->isAtomic()) {
    shouldBeTrue(getModule()->features.hasAtomics(),
                 curr,
                 "Atomic operations require threads [--enable-threads]");
    shouldBeTrue(curr->valueType == Type::i32 || curr->valueType == Type::i64 ||
                   curr->valueType == Type::unreachable,
                 curr,
                 "Atomic store should be i32 or i64");
  }
  switch (curr->order) {
    case MemoryOrder::AcqRel: {
      shouldBeTrue(getModule()->features.hasRelaxedAtomics(),
                   curr,
                   "Acquire/release operations require relaxed atomics "
                   "[--enable-relaxed-atomics]");
      break;
    }
    case MemoryOrder::Unordered:
    case MemoryOrder::SeqCst:
      break;
  }
  if (curr->valueType == Type::v128) {
    shouldBeTrue(getModule()->features.hasSIMD(),
                 curr,
                 "SIMD operations require SIMD [--enable-simd]");
  }
  validateMemBytes(curr->bytes, curr->valueType, curr);
  validateOffset(curr->offset, memory, curr);
  validateAlignment(
    curr->align, curr->valueType, curr->bytes, curr->isAtomic(), curr);
  shouldBeEqualOrFirstIsUnreachable(
    curr->ptr->type,
    memory->addressType,
    curr,
    "store pointer must match memory index type");
  shouldBeUnequal(curr->value->type,
                  Type(Type::none),
                  curr,
                  "store value type must not be none");
  shouldBeEqualOrFirstIsUnreachable(
    curr->value->type, curr->valueType, curr, "store value type must match");
  if (curr->isAtomic()) {
    shouldBeIntOrUnreachable(
      curr->valueType, curr, "atomic stores must be of integers");
  }
}

void FunctionValidator::visitAtomicRMW(AtomicRMW* curr) {
  auto* memory = getModule()->getMemoryOrNull(curr->memory);
  shouldBeTrue(!!memory, curr, "memory.atomicRMW memory must exist");
  shouldBeTrue(getModule()->features.hasAtomics(),
               curr,
               "Atomic operations require threads [--enable-threads]");

  switch (curr->order) {
    case MemoryOrder::AcqRel: {
      shouldBeTrue(getModule()->features.hasRelaxedAtomics(),
                   curr,
                   "Acquire/release operations require relaxed atomics "
                   "[--enable-relaxed-atomics]");
      break;
    }
    // Unordered RMW should be impossible unless there's a bug in the parser.
    case MemoryOrder::Unordered: {
      shouldBeUnequal(curr->order,
                      MemoryOrder::Unordered,
                      curr,
                      "Atomic RMW can't be unordered");
      break;
    }
    case MemoryOrder::SeqCst:
      break;
  }

  validateMemBytes(curr->bytes, curr->type, curr);
  shouldBeEqualOrFirstIsUnreachable(
    curr->ptr->type,
    memory->addressType,
    curr,
    "AtomicRMW pointer type must match memory index type");
  shouldBeEqualOrFirstIsUnreachable(curr->type,
                                    curr->value->type,
                                    curr,
                                    "AtomicRMW result type must match operand");
  shouldBeIntOrUnreachable(
    curr->type, curr, "Atomic operations are only valid on int types");
}

void FunctionValidator::visitAtomicCmpxchg(AtomicCmpxchg* curr) {
  auto* memory = getModule()->getMemoryOrNull(curr->memory);
  shouldBeTrue(!!memory, curr, "memory.atomicCmpxchg memory must exist");
  shouldBeTrue(getModule()->features.hasAtomics(),
               curr,
               "Atomic operations require threads [--enable-threads]");

  switch (curr->order) {
    case MemoryOrder::AcqRel: {
      shouldBeTrue(getModule()->features.hasRelaxedAtomics(),
                   curr,
                   "Acquire/release operations require relaxed atomics "
                   "[--enable-relaxed-atomics]");
      break;
    }
    // Unordered cmpxchg should be impossible unless there's a bug in the
    // parser.
    case MemoryOrder::Unordered: {
      shouldBeUnequal(curr->order,
                      MemoryOrder::Unordered,
                      curr,
                      "Atomic cmpxchg can't be unordered");
      break;
    }
    case MemoryOrder::SeqCst:
      break;
  }

  validateMemBytes(curr->bytes, curr->type, curr);
  shouldBeEqualOrFirstIsUnreachable(
    curr->ptr->type,
    memory->addressType,
    curr,
    "cmpxchg pointer must match memory index type");
  if (curr->expected->type != Type::unreachable &&
      curr->replacement->type != Type::unreachable) {
    shouldBeEqual(curr->expected->type,
                  curr->replacement->type,
                  curr,
                  "cmpxchg operand types must match");
  }
  shouldBeEqualOrFirstIsUnreachable(curr->type,
                                    curr->expected->type,
                                    curr,
                                    "Cmpxchg result type must match expected");
  shouldBeEqualOrFirstIsUnreachable(
    curr->type,
    curr->replacement->type,
    curr,
    "Cmpxchg result type must match replacement");
  shouldBeIntOrUnreachable(curr->expected->type,
                           curr,
                           "Atomic operations are only valid on int types");
}

void FunctionValidator::visitAtomicWait(AtomicWait* curr) {
  auto* memory = getModule()->getMemoryOrNull(curr->memory);
  shouldBeTrue(!!memory, curr, "memory.atomicWait memory must exist");
  shouldBeTrue(getModule()->features.hasAtomics(),
               curr,
               "Atomic operations require threads [--enable-threads]");
  shouldBeEqualOrFirstIsUnreachable(
    curr->type, Type(Type::i32), curr, "AtomicWait must have type i32");
  shouldBeEqualOrFirstIsUnreachable(
    curr->ptr->type,
    memory->addressType,
    curr,
    "AtomicWait pointer must match memory index type");
  shouldBeIntOrUnreachable(
    curr->expected->type, curr, "AtomicWait expected type must be int");
  shouldBeEqualOrFirstIsUnreachable(
    curr->expected->type,
    curr->expectedType,
    curr,
    "AtomicWait expected type must match operand");
  shouldBeEqualOrFirstIsUnreachable(curr->timeout->type,
                                    Type(Type::i64),
                                    curr,
                                    "AtomicWait timeout type must be i64");
}

void FunctionValidator::visitAtomicNotify(AtomicNotify* curr) {
  auto* memory = getModule()->getMemoryOrNull(curr->memory);
  shouldBeTrue(!!memory, curr, "memory.atomicNotify memory must exist");
  shouldBeTrue(getModule()->features.hasAtomics(),
               curr,
               "Atomic operations require threads [--enable-threads]");
  shouldBeEqualOrFirstIsUnreachable(
    curr->type, Type(Type::i32), curr, "AtomicNotify must have type i32");
  shouldBeEqualOrFirstIsUnreachable(
    curr->ptr->type,
    memory->addressType,
    curr,
    "AtomicNotify pointer must match memory index type");
  shouldBeEqualOrFirstIsUnreachable(
    curr->notifyCount->type,
    Type(Type::i32),
    curr,
    "AtomicNotify notifyCount type must be i32");
}

void FunctionValidator::visitAtomicFence(AtomicFence* curr) {
  shouldBeTrue(getModule()->features.hasAtomics(),
               curr,
               "Atomic operations require threads [--enable-threads]");
  shouldBeTrue(curr->order == 0,
               curr,
               "Currently only sequentially consistent atomics are supported, "
               "so AtomicFence's order should be 0");
}

void FunctionValidator::visitPause(Pause* curr) {
  shouldBeTrue(getModule()->features.hasSharedEverything(),
               curr,
               "pause requires shared-everything [--enable-shared-everything]");
}

void FunctionValidator::visitSIMDExtract(SIMDExtract* curr) {
  shouldBeTrue(getModule()->features.hasSIMD(),
               curr,
               "SIMD operations require SIMD [--enable-simd]");
  shouldBeEqualOrFirstIsUnreachable(curr->vec->type,
                                    Type(Type::v128),
                                    curr,
                                    "extract_lane must operate on a v128");
  Type lane_t = Type::none;
  size_t lanes = 0;
  switch (curr->op) {
    case ExtractLaneSVecI8x16:
    case ExtractLaneUVecI8x16:
      lane_t = Type::i32;
      lanes = 16;
      break;
    case ExtractLaneSVecI16x8:
    case ExtractLaneUVecI16x8:
      lane_t = Type::i32;
      lanes = 8;
      break;
    case ExtractLaneVecI32x4:
      lane_t = Type::i32;
      lanes = 4;
      break;
    case ExtractLaneVecI64x2:
      lane_t = Type::i64;
      lanes = 2;
      break;
    case ExtractLaneVecF16x8:
      shouldBeTrue(getModule()->features.hasFP16(),
                   curr,
                   "FP16 operations require FP16 [--enable-fp16]");
      lane_t = Type::f32;
      lanes = 8;
      break;
    case ExtractLaneVecF32x4:
      lane_t = Type::f32;
      lanes = 4;
      break;
    case ExtractLaneVecF64x2:
      lane_t = Type::f64;
      lanes = 2;
      break;
  }
  shouldBeEqualOrFirstIsUnreachable(
    curr->type,
    lane_t,
    curr,
    "extract_lane must have same type as vector lane");
  shouldBeTrue(curr->index < lanes, curr, "invalid lane index");
}

void FunctionValidator::visitSIMDReplace(SIMDReplace* curr) {
  shouldBeTrue(getModule()->features.hasSIMD(),
               curr,
               "SIMD operations require SIMD [--enable-simd]");
  shouldBeEqualOrFirstIsUnreachable(
    curr->type, Type(Type::v128), curr, "replace_lane must have type v128");
  shouldBeEqualOrFirstIsUnreachable(curr->vec->type,
                                    Type(Type::v128),
                                    curr,
                                    "replace_lane must operate on a v128");
  Type lane_t = Type::none;
  size_t lanes = 0;
  switch (curr->op) {
    case ReplaceLaneVecI8x16:
      lane_t = Type::i32;
      lanes = 16;
      break;
    case ReplaceLaneVecI16x8:
      lane_t = Type::i32;
      lanes = 8;
      break;
    case ReplaceLaneVecI32x4:
      lane_t = Type::i32;
      lanes = 4;
      break;
    case ReplaceLaneVecI64x2:
      lane_t = Type::i64;
      lanes = 2;
      break;
    case ReplaceLaneVecF16x8:
      shouldBeTrue(getModule()->features.hasFP16(),
                   curr,
                   "FP16 operations require FP16 [--enable-fp16]");
      lane_t = Type::f32;
      lanes = 8;
      break;
    case ReplaceLaneVecF32x4:
      lane_t = Type::f32;
      lanes = 4;
      break;
    case ReplaceLaneVecF64x2:
      lane_t = Type::f64;
      lanes = 2;
      break;
  }
  shouldBeEqualOrFirstIsUnreachable(
    curr->value->type, lane_t, curr, "unexpected value type");
  shouldBeTrue(curr->index < lanes, curr, "invalid lane index");
}

void FunctionValidator::visitSIMDShuffle(SIMDShuffle* curr) {
  shouldBeTrue(getModule()->features.hasSIMD(),
               curr,
               "SIMD operations require SIMD [--enable-simd]");
  shouldBeEqualOrFirstIsUnreachable(
    curr->type, Type(Type::v128), curr, "i8x16.shuffle must have type v128");
  shouldBeEqualOrFirstIsUnreachable(
    curr->left->type, Type(Type::v128), curr, "expected operand of type v128");
  shouldBeEqualOrFirstIsUnreachable(
    curr->right->type, Type(Type::v128), curr, "expected operand of type v128");
  for (uint8_t index : curr->mask) {
    shouldBeTrue(index < 32, curr, "Invalid lane index in mask");
  }
}

void FunctionValidator::visitSIMDTernary(SIMDTernary* curr) {
  FeatureSet required = FeatureSet::None;
  switch (curr->op) {
    case RelaxedLaneselectI8x16:
    case RelaxedLaneselectI16x8:
    case RelaxedLaneselectI32x4:
    case RelaxedLaneselectI64x2:
    case RelaxedMaddVecF32x4:
    case RelaxedNmaddVecF32x4:
    case RelaxedMaddVecF64x2:
    case RelaxedNmaddVecF64x2:
    case RelaxedDotI8x16I7x16AddSToVecI32x4:
      required |= FeatureSet::RelaxedSIMD | FeatureSet::SIMD;
      break;
    case MaddVecF16x8:
    case NmaddVecF16x8:
      required |= FeatureSet::FP16 | FeatureSet::SIMD;
      break;
    case Bitselect:
      required |= FeatureSet::SIMD;
      break;
  }
  if (!shouldBeTrue(required.isSubsetOf(getModule()->features),
                    curr,
                    "SIMD ternary operation requires additional features")) {
    getStream() << getMissingFeaturesList(*getModule(), required) << '\n';
  }
  shouldBeEqualOrFirstIsUnreachable(
    curr->type, Type(Type::v128), curr, "SIMD ternary must have type v128");
  shouldBeEqualOrFirstIsUnreachable(
    curr->a->type, Type(Type::v128), curr, "expected operand of type v128");
  shouldBeEqualOrFirstIsUnreachable(
    curr->b->type, Type(Type::v128), curr, "expected operand of type v128");
  shouldBeEqualOrFirstIsUnreachable(
    curr->c->type, Type(Type::v128), curr, "expected operand of type v128");
}

void FunctionValidator::visitSIMDShift(SIMDShift* curr) {
  shouldBeTrue(getModule()->features.hasSIMD(),
               curr,
               "SIMD operations require SIMD [--enable-simd]");
  shouldBeEqualOrFirstIsUnreachable(
    curr->type, Type(Type::v128), curr, "vector shift must have type v128");
  shouldBeEqualOrFirstIsUnreachable(
    curr->vec->type, Type(Type::v128), curr, "expected operand of type v128");
  shouldBeEqualOrFirstIsUnreachable(curr->shift->type,
                                    Type(Type::i32),
                                    curr,
                                    "expected shift amount to have type i32");
}

void FunctionValidator::visitSIMDLoad(SIMDLoad* curr) {
  auto* memory = getModule()->getMemoryOrNull(curr->memory);
  shouldBeTrue(!!memory, curr, "memory.SIMDLoad memory must exist");
  shouldBeTrue(getModule()->features.hasSIMD(),
               curr,
               "SIMD operations require SIMD [--enable-simd]");
  shouldBeEqualOrFirstIsUnreachable(
    curr->type, Type(Type::v128), curr, "load_splat must have type v128");
  shouldBeEqualOrFirstIsUnreachable(
    curr->ptr->type,
    memory->addressType,
    curr,
    "load_splat address must match memory index type");
  Type memAlignType = Type::none;
  switch (curr->op) {
    case Load8SplatVec128:
    case Load16SplatVec128:
    case Load32SplatVec128:
    case Load32ZeroVec128:
      memAlignType = Type::i32;
      break;
    case Load64SplatVec128:
    case Load8x8SVec128:
    case Load8x8UVec128:
    case Load16x4SVec128:
    case Load16x4UVec128:
    case Load32x2SVec128:
    case Load32x2UVec128:
    case Load64ZeroVec128:
      memAlignType = Type::i64;
      break;
  }
  Index bytes = curr->getMemBytes();
  validateOffset(curr->offset, memory, curr);
  validateAlignment(curr->align, memAlignType, bytes, /*isAtomic=*/false, curr);
}

void FunctionValidator::visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {
  auto* memory = getModule()->getMemoryOrNull(curr->memory);
  shouldBeTrue(!!memory, curr, "memory.SIMDLoadStoreLane memory must exist");
  shouldBeTrue(getModule()->features.hasSIMD(),
               curr,
               "SIMD operations require SIMD [--enable-simd]");
  if (curr->isLoad()) {
    shouldBeEqualOrFirstIsUnreachable(
      curr->type, Type(Type::v128), curr, "loadX_lane must have type v128");
  } else {
    shouldBeEqualOrFirstIsUnreachable(
      curr->type, Type(Type::none), curr, "storeX_lane must have type none");
  }
  shouldBeEqualOrFirstIsUnreachable(
    curr->ptr->type,
    memory->addressType,
    curr,
    "loadX_lane or storeX_lane address must match memory index type");
  shouldBeEqualOrFirstIsUnreachable(
    curr->vec->type,
    Type(Type::v128),
    curr,
    "loadX_lane or storeX_lane vector argument must have type v128");
  size_t lanes;
  Type memAlignType = Type::none;
  switch (curr->op) {
    case Load8LaneVec128:
    case Store8LaneVec128:
      lanes = 16;
      memAlignType = Type::i32;
      break;
    case Load16LaneVec128:
    case Store16LaneVec128:
      lanes = 8;
      memAlignType = Type::i32;
      break;
    case Load32LaneVec128:
    case Store32LaneVec128:
      lanes = 4;
      memAlignType = Type::i32;
      break;
    case Load64LaneVec128:
    case Store64LaneVec128:
      lanes = 2;
      memAlignType = Type::i64;
      break;
    default:
      WASM_UNREACHABLE("Unexpected SIMDLoadStoreLane op");
  }
  Index bytes = curr->getMemBytes();
  validateOffset(curr->offset, memory, curr);
  validateAlignment(curr->align, memAlignType, bytes, /*isAtomic=*/false, curr);
  shouldBeTrue(curr->index < lanes, curr, "invalid lane index");
}

void FunctionValidator::visitMemoryInit(MemoryInit* curr) {
  auto* memory = getModule()->getMemoryOrNull(curr->memory);
  shouldBeTrue(
    getModule()->features.hasBulkMemory(),
    curr,
    "Bulk memory operations require bulk memory [--enable-bulk-memory]");
  shouldBeEqualOrFirstIsUnreachable(
    curr->type, Type(Type::none), curr, "memory.init must have type none");
  shouldBeEqualOrFirstIsUnreachable(
    curr->dest->type,
    memory->addressType,
    curr,
    "memory.init dest must match memory index type");
  shouldBeEqualOrFirstIsUnreachable(curr->offset->type,
                                    Type(Type::i32),
                                    curr,
                                    "memory.init offset must be an i32");
  shouldBeEqualOrFirstIsUnreachable(
    curr->size->type, Type(Type::i32), curr, "memory.init size must be an i32");
  if (!shouldBeTrue(!!memory, curr, "memory.init memory must exist")) {
    return;
  }
  shouldBeTrue(getModule()->getDataSegmentOrNull(curr->segment),
               curr,
               "memory.init segment should exist");
}

void FunctionValidator::visitDataDrop(DataDrop* curr) {
  shouldBeTrue(
    getModule()->features.hasBulkMemory(),
    curr,
    "Bulk memory operations require bulk memory [--enable-bulk-memory]");
  shouldBeEqualOrFirstIsUnreachable(
    curr->type, Type(Type::none), curr, "data.drop must have type none");
  shouldBeTrue(getModule()->getDataSegmentOrNull(curr->segment),
               curr,
               "data.drop segment should exist");
}

void FunctionValidator::visitMemoryCopy(MemoryCopy* curr) {
  shouldBeTrue(getModule()->features.hasBulkMemoryOpt(),
               curr,
               "memory.copy operations require bulk memory operations "
               "[--enable-bulk-memory-opt]");
  shouldBeEqualOrFirstIsUnreachable(
    curr->type, Type(Type::none), curr, "memory.copy must have type none");
  auto* destMemory = getModule()->getMemoryOrNull(curr->destMemory);
  shouldBeTrue(!!destMemory, curr, "memory.copy destMemory must exist");
  auto* sourceMemory = getModule()->getMemoryOrNull(curr->sourceMemory);
  shouldBeTrue(!!sourceMemory, curr, "memory.copy sourceMemory must exist");
  shouldBeEqualOrFirstIsUnreachable(
    curr->dest->type,
    destMemory->addressType,
    curr,
    "memory.copy dest must match destMemory index type");
  shouldBeEqualOrFirstIsUnreachable(
    curr->source->type,
    sourceMemory->addressType,
    curr,
    "memory.copy source must match sourceMemory index type");
  shouldBeEqualOrFirstIsUnreachable(
    curr->size->type,
    destMemory->addressType,
    curr,
    "memory.copy size must match destMemory index type");
  shouldBeEqualOrFirstIsUnreachable(
    curr->size->type,
    sourceMemory->addressType,
    curr,
    "memory.copy size must match destMemory index type");
}

void FunctionValidator::visitMemoryFill(MemoryFill* curr) {
  auto* memory = getModule()->getMemoryOrNull(curr->memory);
  shouldBeTrue(
    getModule()->features.hasBulkMemoryOpt(),
    curr,
    "memory.fill operations require bulk memory [--enable-bulk-memory-opt]");
  shouldBeEqualOrFirstIsUnreachable(
    curr->type, Type(Type::none), curr, "memory.fill must have type none");
  shouldBeEqualOrFirstIsUnreachable(
    curr->dest->type,
    memory->addressType,
    curr,
    "memory.fill dest must match memory index type");
  shouldBeEqualOrFirstIsUnreachable(curr->value->type,
                                    Type(Type::i32),
                                    curr,
                                    "memory.fill value must be an i32");
  shouldBeEqualOrFirstIsUnreachable(
    curr->size->type,
    memory->addressType,
    curr,
    "memory.fill size must match memory index type");
  shouldBeTrue(!!memory, curr, "memory.fill memory must exist");
}

void FunctionValidator::validateMemBytes(uint8_t bytes,
                                         Type type,
                                         Expression* curr) {
  switch (type.getBasic()) {
    case Type::i32:
      shouldBeTrue(bytes == 1 || bytes == 2 || bytes == 4,
                   curr,
                   "expected i32 operation to touch 1, 2, or 4 bytes");
      break;
    case Type::i64:
      shouldBeTrue(bytes == 1 || bytes == 2 || bytes == 4 || bytes == 8,
                   curr,
                   "expected i64 operation to touch 1, 2, 4, or 8 bytes");
      break;
    case Type::f32:
      shouldBeTrue(bytes == 2 || bytes == 4,
                   curr,
                   "expected f32 operation to touch 2 or 4 bytes");
      break;
    case Type::f64:
      shouldBeEqual(
        bytes, uint8_t(8), curr, "expected f64 operation to touch 8 bytes");
      break;
    case Type::v128:
      shouldBeEqual(
        bytes, uint8_t(16), curr, "expected v128 operation to touch 16 bytes");
      break;
    case Type::unreachable:
      break;
    case Type::none:
      WASM_UNREACHABLE("unexpected type");
  }
}

void FunctionValidator::visitBinary(Binary* curr) {
  if (curr->left->type != Type::unreachable &&
      curr->right->type != Type::unreachable) {
    shouldBeEqual(curr->left->type,
                  curr->right->type,
                  curr,
                  "binary child types must be equal");
  }
  switch (curr->op) {
    case AddInt32:
    case SubInt32:
    case MulInt32:
    case DivSInt32:
    case DivUInt32:
    case RemSInt32:
    case RemUInt32:
    case AndInt32:
    case OrInt32:
    case XorInt32:
    case ShlInt32:
    case ShrUInt32:
    case ShrSInt32:
    case RotLInt32:
    case RotRInt32:
    case EqInt32:
    case NeInt32:
    case LtSInt32:
    case LtUInt32:
    case LeSInt32:
    case LeUInt32:
    case GtSInt32:
    case GtUInt32:
    case GeSInt32:
    case GeUInt32: {
      shouldBeEqualOrFirstIsUnreachable(
        curr->left->type, Type(Type::i32), curr, "i32 op");
      break;
    }
    case AddInt64:
    case SubInt64:
    case MulInt64:
    case DivSInt64:
    case DivUInt64:
    case RemSInt64:
    case RemUInt64:
    case AndInt64:
    case OrInt64:
    case XorInt64:
    case ShlInt64:
    case ShrUInt64:
    case ShrSInt64:
    case RotLInt64:
    case RotRInt64:
    case EqInt64:
    case NeInt64:
    case LtSInt64:
    case LtUInt64:
    case LeSInt64:
    case LeUInt64:
    case GtSInt64:
    case GtUInt64:
    case GeSInt64:
    case GeUInt64: {
      shouldBeEqualOrFirstIsUnreachable(
        curr->left->type, Type(Type::i64), curr, "i64 op");
      break;
    }
    case AddFloat32:
    case SubFloat32:
    case MulFloat32:
    case DivFloat32:
    case CopySignFloat32:
    case MinFloat32:
    case MaxFloat32:
    case EqFloat32:
    case NeFloat32:
    case LtFloat32:
    case LeFloat32:
    case GtFloat32:
    case GeFloat32: {
      shouldBeEqualOrFirstIsUnreachable(
        curr->left->type, Type(Type::f32), curr, "f32 op");
      break;
    }
    case AddFloat64:
    case SubFloat64:
    case MulFloat64:
    case DivFloat64:
    case CopySignFloat64:
    case MinFloat64:
    case MaxFloat64:
    case EqFloat64:
    case NeFloat64:
    case LtFloat64:
    case LeFloat64:
    case GtFloat64:
    case GeFloat64: {
      shouldBeEqualOrFirstIsUnreachable(
        curr->left->type, Type(Type::f64), curr, "f64 op");
      break;
    }
    case EqVecF16x8:
    case NeVecF16x8:
    case LtVecF16x8:
    case LeVecF16x8:
    case GtVecF16x8:
    case GeVecF16x8:
    case AddVecF16x8:
    case SubVecF16x8:
    case MulVecF16x8:
    case DivVecF16x8:
    case MinVecF16x8:
    case MaxVecF16x8:
    case PMinVecF16x8:
    case PMaxVecF16x8:
      shouldBeTrue(getModule()->features.hasFP16(),
                   curr,
                   "FP16 operations require FP16 [--enable-fp16]");
      [[fallthrough]];
    case EqVecI8x16:
    case NeVecI8x16:
    case LtSVecI8x16:
    case LtUVecI8x16:
    case LeSVecI8x16:
    case LeUVecI8x16:
    case GtSVecI8x16:
    case GtUVecI8x16:
    case GeSVecI8x16:
    case GeUVecI8x16:
    case EqVecI16x8:
    case NeVecI16x8:
    case LtSVecI16x8:
    case LtUVecI16x8:
    case LeSVecI16x8:
    case LeUVecI16x8:
    case GtSVecI16x8:
    case GtUVecI16x8:
    case GeSVecI16x8:
    case GeUVecI16x8:
    case EqVecI32x4:
    case NeVecI32x4:
    case LtSVecI32x4:
    case LtUVecI32x4:
    case LeSVecI32x4:
    case LeUVecI32x4:
    case GtSVecI32x4:
    case GtUVecI32x4:
    case GeSVecI32x4:
    case GeUVecI32x4:
    case EqVecI64x2:
    case NeVecI64x2:
    case LtSVecI64x2:
    case LeSVecI64x2:
    case GtSVecI64x2:
    case GeSVecI64x2:
    case EqVecF32x4:
    case NeVecF32x4:
    case LtVecF32x4:
    case LeVecF32x4:
    case GtVecF32x4:
    case GeVecF32x4:
    case EqVecF64x2:
    case NeVecF64x2:
    case LtVecF64x2:
    case LeVecF64x2:
    case GtVecF64x2:
    case GeVecF64x2:
    case AndVec128:
    case OrVec128:
    case XorVec128:
    case AndNotVec128:
    case AddVecI8x16:
    case AddSatSVecI8x16:
    case AddSatUVecI8x16:
    case SubVecI8x16:
    case SubSatSVecI8x16:
    case SubSatUVecI8x16:
    case MinSVecI8x16:
    case MinUVecI8x16:
    case MaxSVecI8x16:
    case MaxUVecI8x16:
    case AvgrUVecI8x16:
    case Q15MulrSatSVecI16x8:
    case ExtMulLowSVecI16x8:
    case ExtMulHighSVecI16x8:
    case ExtMulLowUVecI16x8:
    case ExtMulHighUVecI16x8:
    case AddVecI16x8:
    case AddSatSVecI16x8:
    case AddSatUVecI16x8:
    case SubVecI16x8:
    case SubSatSVecI16x8:
    case SubSatUVecI16x8:
    case MulVecI16x8:
    case MinSVecI16x8:
    case MinUVecI16x8:
    case MaxSVecI16x8:
    case MaxUVecI16x8:
    case AvgrUVecI16x8:
    case AddVecI32x4:
    case SubVecI32x4:
    case MulVecI32x4:
    case MinSVecI32x4:
    case MinUVecI32x4:
    case MaxSVecI32x4:
    case MaxUVecI32x4:
    case DotSVecI16x8ToVecI32x4:
    case ExtMulLowSVecI32x4:
    case ExtMulHighSVecI32x4:
    case ExtMulLowUVecI32x4:
    case ExtMulHighUVecI32x4:
    case AddVecI64x2:
    case SubVecI64x2:
    case MulVecI64x2:
    case ExtMulLowSVecI64x2:
    case ExtMulHighSVecI64x2:
    case ExtMulLowUVecI64x2:
    case ExtMulHighUVecI64x2:
    case AddVecF32x4:
    case SubVecF32x4:
    case MulVecF32x4:
    case DivVecF32x4:
    case MinVecF32x4:
    case MaxVecF32x4:
    case PMinVecF32x4:
    case PMaxVecF32x4:
    case RelaxedMinVecF32x4:
    case RelaxedMaxVecF32x4:
    case AddVecF64x2:
    case SubVecF64x2:
    case MulVecF64x2:
    case DivVecF64x2:
    case MinVecF64x2:
    case MaxVecF64x2:
    case PMinVecF64x2:
    case PMaxVecF64x2:
    case RelaxedMinVecF64x2:
    case RelaxedMaxVecF64x2:
    case NarrowSVecI16x8ToVecI8x16:
    case NarrowUVecI16x8ToVecI8x16:
    case NarrowSVecI32x4ToVecI16x8:
    case NarrowUVecI32x4ToVecI16x8:
    case SwizzleVecI8x16:
    case RelaxedSwizzleVecI8x16:
    case RelaxedQ15MulrSVecI16x8:
    case RelaxedDotI8x16I7x16SToVecI16x8: {
      shouldBeEqualOrFirstIsUnreachable(
        curr->left->type, Type(Type::v128), curr, "v128 op");
      shouldBeEqualOrFirstIsUnreachable(
        curr->right->type, Type(Type::v128), curr, "v128 op");
      break;
    }
    case InvalidBinary:
      WASM_UNREACHABLE("invliad binary op");
  }
  shouldBeTrue(Features::get(curr->op).isSubsetOf(getModule()->features),
               curr,
               "all used features should be allowed");
}

void FunctionValidator::visitUnary(Unary* curr) {
  shouldBeUnequal(curr->value->type,
                  Type(Type::none),
                  curr,
                  "unaries must not receive a none as their input");
  if (curr->value->type == Type::unreachable) {
    return; // nothing to check
  }
  switch (curr->op) {
    case ClzInt32:
    case CtzInt32:
    case PopcntInt32: {
      shouldBeEqual(curr->value->type,
                    Type(Type::i32),
                    curr,
                    "i32 unary value type must be correct");
      break;
    }
    case ClzInt64:
    case CtzInt64:
    case PopcntInt64: {
      shouldBeEqual(curr->value->type,
                    Type(Type::i64),
                    curr,
                    "i64 unary value type must be correct");
      break;
    }
    case NegFloat32:
    case AbsFloat32:
    case CeilFloat32:
    case FloorFloat32:
    case TruncFloat32:
    case NearestFloat32:
    case SqrtFloat32: {
      shouldBeEqual(curr->value->type,
                    Type(Type::f32),
                    curr,
                    "f32 unary value type must be correct");
      break;
    }
    case NegFloat64:
    case AbsFloat64:
    case CeilFloat64:
    case FloorFloat64:
    case TruncFloat64:
    case NearestFloat64:
    case SqrtFloat64: {
      shouldBeEqual(curr->value->type,
                    Type(Type::f64),
                    curr,
                    "f64 unary value type must be correct");
      break;
    }
    case EqZInt32: {
      shouldBeTrue(
        curr->value->type == Type::i32, curr, "i32.eqz input must be i32");
      break;
    }
    case EqZInt64: {
      shouldBeTrue(curr->value->type == Type(Type::i64),
                   curr,
                   "i64.eqz input must be i64");
      break;
    }
    case ExtendSInt32:
    case ExtendUInt32:
    case ExtendS8Int32:
    case ExtendS16Int32: {
      shouldBeEqual(curr->value->type,
                    Type(Type::i32),
                    curr,
                    "extend type must be correct");
      break;
    }
    case ExtendS8Int64:
    case ExtendS16Int64:
    case ExtendS32Int64: {
      shouldBeEqual(curr->value->type,
                    Type(Type::i64),
                    curr,
                    "extend type must be correct");
      break;
    }
    case WrapInt64: {
      shouldBeEqual(
        curr->value->type, Type(Type::i64), curr, "wrap type must be correct");
      break;
    }
    case TruncSFloat32ToInt32:
    case TruncSFloat32ToInt64:
    case TruncUFloat32ToInt32:
    case TruncUFloat32ToInt64: {
      shouldBeEqual(
        curr->value->type, Type(Type::f32), curr, "trunc type must be correct");
      break;
    }
    case TruncSatSFloat32ToInt32:
    case TruncSatSFloat32ToInt64:
    case TruncSatUFloat32ToInt32:
    case TruncSatUFloat32ToInt64: {
      shouldBeEqual(
        curr->value->type, Type(Type::f32), curr, "trunc type must be correct");
      break;
    }
    case TruncSFloat64ToInt32:
    case TruncSFloat64ToInt64:
    case TruncUFloat64ToInt32:
    case TruncUFloat64ToInt64: {
      shouldBeEqual(
        curr->value->type, Type(Type::f64), curr, "trunc type must be correct");
      break;
    }
    case TruncSatSFloat64ToInt32:
    case TruncSatSFloat64ToInt64:
    case TruncSatUFloat64ToInt32:
    case TruncSatUFloat64ToInt64: {
      shouldBeEqual(
        curr->value->type, Type(Type::f64), curr, "trunc type must be correct");
      break;
    }
    case ReinterpretFloat32: {
      shouldBeEqual(curr->value->type,
                    Type(Type::f32),
                    curr,
                    "reinterpret/f32 type must be correct");
      break;
    }
    case ReinterpretFloat64: {
      shouldBeEqual(curr->value->type,
                    Type(Type::f64),
                    curr,
                    "reinterpret/f64 type must be correct");
      break;
    }
    case ConvertUInt32ToFloat32:
    case ConvertUInt32ToFloat64:
    case ConvertSInt32ToFloat32:
    case ConvertSInt32ToFloat64: {
      shouldBeEqual(curr->value->type,
                    Type(Type::i32),
                    curr,
                    "convert type must be correct");
      break;
    }
    case ConvertUInt64ToFloat32:
    case ConvertUInt64ToFloat64:
    case ConvertSInt64ToFloat32:
    case ConvertSInt64ToFloat64: {
      shouldBeEqual(curr->value->type,
                    Type(Type::i64),
                    curr,
                    "convert type must be correct");
      break;
    }
    case PromoteFloat32: {
      shouldBeEqual(curr->value->type,
                    Type(Type::f32),
                    curr,
                    "promote type must be correct");
      break;
    }
    case DemoteFloat64: {
      shouldBeEqual(curr->value->type,
                    Type(Type::f64),
                    curr,
                    "demote type must be correct");
      break;
    }
    case ReinterpretInt32: {
      shouldBeEqual(curr->value->type,
                    Type(Type::i32),
                    curr,
                    "reinterpret/i32 type must be correct");
      break;
    }
    case ReinterpretInt64: {
      shouldBeEqual(curr->value->type,
                    Type(Type::i64),
                    curr,
                    "reinterpret/i64 type must be correct");
      break;
    }
    case SplatVecI8x16:
    case SplatVecI16x8:
    case SplatVecI32x4:
      shouldBeEqual(
        curr->type, Type(Type::v128), curr, "expected splat to have v128 type");
      shouldBeEqual(
        curr->value->type, Type(Type::i32), curr, "expected i32 splat value");
      break;
    case SplatVecI64x2:
      shouldBeEqual(
        curr->type, Type(Type::v128), curr, "expected splat to have v128 type");
      shouldBeEqual(
        curr->value->type, Type(Type::i64), curr, "expected i64 splat value");
      break;
    case SplatVecF16x8:
      shouldBeTrue(getModule()->features.hasFP16(),
                   curr,
                   "FP16 operations require FP16 [--enable-fp16]");
      [[fallthrough]];
    case SplatVecF32x4:
      shouldBeEqual(
        curr->type, Type(Type::v128), curr, "expected splat to have v128 type");
      shouldBeEqual(
        curr->value->type, Type(Type::f32), curr, "expected f32 splat value");
      break;
    case SplatVecF64x2:
      shouldBeEqual(
        curr->type, Type(Type::v128), curr, "expected splat to have v128 type");
      shouldBeEqual(
        curr->value->type, Type(Type::f64), curr, "expected f64 splat value");
      break;
    case AbsVecF16x8:
    case NegVecF16x8:
    case SqrtVecF16x8:
    case CeilVecF16x8:
    case FloorVecF16x8:
    case TruncVecF16x8:
    case NearestVecF16x8:
      shouldBeTrue(getModule()->features.hasFP16(),
                   curr,
                   "FP16 operations require FP16 [--enable-fp16]");
      [[fallthrough]];
    case NotVec128:
    case PopcntVecI8x16:
    case AbsVecI8x16:
    case AbsVecI16x8:
    case AbsVecI32x4:
    case AbsVecI64x2:
    case NegVecI8x16:
    case NegVecI16x8:
    case NegVecI32x4:
    case NegVecI64x2:
    case AbsVecF32x4:
    case NegVecF32x4:
    case SqrtVecF32x4:
    case CeilVecF32x4:
    case FloorVecF32x4:
    case TruncVecF32x4:
    case NearestVecF32x4:
    case AbsVecF64x2:
    case NegVecF64x2:
    case SqrtVecF64x2:
    case CeilVecF64x2:
    case FloorVecF64x2:
    case TruncVecF64x2:
    case NearestVecF64x2:
    case ExtAddPairwiseSVecI8x16ToI16x8:
    case ExtAddPairwiseUVecI8x16ToI16x8:
    case ExtAddPairwiseSVecI16x8ToI32x4:
    case ExtAddPairwiseUVecI16x8ToI32x4:
    case TruncSatSVecF32x4ToVecI32x4:
    case TruncSatUVecF32x4ToVecI32x4:
    case ConvertSVecI32x4ToVecF32x4:
    case ConvertUVecI32x4ToVecF32x4:
    case ExtendLowSVecI8x16ToVecI16x8:
    case ExtendHighSVecI8x16ToVecI16x8:
    case ExtendLowUVecI8x16ToVecI16x8:
    case ExtendHighUVecI8x16ToVecI16x8:
    case ExtendLowSVecI16x8ToVecI32x4:
    case ExtendHighSVecI16x8ToVecI32x4:
    case ExtendLowUVecI16x8ToVecI32x4:
    case ExtendHighUVecI16x8ToVecI32x4:
    case ExtendLowSVecI32x4ToVecI64x2:
    case ExtendHighSVecI32x4ToVecI64x2:
    case ExtendLowUVecI32x4ToVecI64x2:
    case ExtendHighUVecI32x4ToVecI64x2:
    case ConvertLowSVecI32x4ToVecF64x2:
    case ConvertLowUVecI32x4ToVecF64x2:
    case TruncSatZeroSVecF64x2ToVecI32x4:
    case TruncSatZeroUVecF64x2ToVecI32x4:
    case DemoteZeroVecF64x2ToVecF32x4:
    case PromoteLowVecF32x4ToVecF64x2:
    case PromoteLowVecF16x8ToVecF32x4:
    case DemoteZeroVecF32x4ToVecF16x8:
    case DemoteZeroVecF64x2ToVecF16x8:
    case RelaxedTruncSVecF32x4ToVecI32x4:
    case RelaxedTruncUVecF32x4ToVecI32x4:
    case RelaxedTruncZeroSVecF64x2ToVecI32x4:
    case RelaxedTruncZeroUVecF64x2ToVecI32x4:
    case TruncSatSVecF16x8ToVecI16x8:
    case TruncSatUVecF16x8ToVecI16x8:
    case ConvertSVecI16x8ToVecF16x8:
    case ConvertUVecI16x8ToVecF16x8:
      shouldBeEqual(curr->type, Type(Type::v128), curr, "expected v128 type");
      shouldBeEqual(
        curr->value->type, Type(Type::v128), curr, "expected v128 operand");
      break;
    case AnyTrueVec128:
    case AllTrueVecI8x16:
    case AllTrueVecI16x8:
    case AllTrueVecI32x4:
    case AllTrueVecI64x2:
    case BitmaskVecI8x16:
    case BitmaskVecI16x8:
    case BitmaskVecI32x4:
    case BitmaskVecI64x2:
      shouldBeEqual(curr->type, Type(Type::i32), curr, "expected i32 type");
      shouldBeEqual(
        curr->value->type, Type(Type::v128), curr, "expected v128 operand");
      break;
    case InvalidUnary:
      WASM_UNREACHABLE("invalid unary op");
  }
  shouldBeTrue(Features::get(curr->op).isSubsetOf(getModule()->features),
               curr,
               "all used features should be allowed");
}

void FunctionValidator::visitSelect(Select* curr) {
  shouldBeUnequal(
    curr->ifFalse->type, Type(Type::none), curr, "select right must be valid");
  shouldBeUnequal(
    curr->type, Type(Type::none), curr, "select type must be valid");
  shouldBeTrue(curr->condition->type == Type::unreachable ||
                 curr->condition->type == Type::i32,
               curr,
               "select condition must be valid");
  if (curr->ifTrue->type != Type::unreachable) {
    shouldBeFalse(
      curr->ifTrue->type.isTuple(), curr, "select value may not be a tuple");
  }
  if (curr->ifFalse->type != Type::unreachable) {
    shouldBeFalse(
      curr->ifFalse->type.isTuple(), curr, "select value may not be a tuple");
  }
  if (curr->type != Type::unreachable) {
    shouldBeTrue(Type::isSubType(curr->ifTrue->type, curr->type),
                 curr,
                 "select's left expression must be subtype of select's type");
    shouldBeTrue(Type::isSubType(curr->ifFalse->type, curr->type),
                 curr,
                 "select's right expression must be subtype of select's type");
  }
}

void FunctionValidator::visitWideIntAddSub(WideIntAddSub* curr) {
  shouldBeTrue(getModule()->features.hasWideArithmetic(),
               curr,
               "i64.add128 / i64.sub128 require wide arithmetic "
               "[--enable-wide-arithmetic]");

  for (auto* operand :
       {curr->leftLow, curr->leftHigh, curr->rightLow, curr->rightHigh}) {
    shouldBeEqualOrFirstIsUnreachable(operand->type,
                                      Type(Type::i64),
                                      curr,
                                      "wide binary child types must be i64");
  }
}

void FunctionValidator::visitWideIntMul(WideIntMul* curr) {
  shouldBeTrue(getModule()->features.hasWideArithmetic(),
               curr,
               "i64.mul_wide_s / i64.mul_wide_u require wide arithmetic "
               "[--enable-wide-arithmetic]");

  for (auto* operand : {curr->left, curr->right}) {
    shouldBeEqualOrFirstIsUnreachable(operand->type,
                                      Type(Type::i64),
                                      curr,
                                      "wide binary child types must be i64");
  }
}

void FunctionValidator::visitDrop(Drop* curr) {
  shouldBeTrue(curr->value->type.isConcrete() ||
                 curr->value->type == Type::unreachable,
               curr,
               "can only drop a valid value");
  if (curr->value->type.isTuple()) {
    shouldBeTrue(getModule()->features.hasMultivalue(),
                 curr,
                 "Tuples drops are not allowed unless multivalue is enabled");
  }
}

void FunctionValidator::visitReturn(Return* curr) {
  auto* func = getFunction();
  if (!shouldBeTrue(!!func, curr, "return must be within a function")) {
    return;
  }
  auto results = func->getResults();
  if (results.isConcrete()) {
    if (!shouldBeTrue(
          curr->value, curr, "concrete return should have a value")) {
      return;
    }
    shouldBeSubType(
      curr->value->type,
      results,
      curr,
      "return value should be a subtype of the function result type");
  } else {
    shouldBeTrue(!curr->value, curr, "return should not have a value");
  }
}

void FunctionValidator::visitMemorySize(MemorySize* curr) {
  auto* memory = getModule()->getMemoryOrNull(curr->memory);
  shouldBeTrue(!!memory, curr, "memory.size memory must exist");
}

void FunctionValidator::visitMemoryGrow(MemoryGrow* curr) {
  auto* memory = getModule()->getMemoryOrNull(curr->memory);
  shouldBeTrue(!!memory, curr, "memory.grow memory must exist");
  shouldBeEqualOrFirstIsUnreachable(curr->delta->type,
                                    memory->addressType,
                                    curr,
                                    "memory.grow must match memory index type");
}

void FunctionValidator::visitRefNull(RefNull* curr) {
  // If we are not in a function, this is a global location like a table. We
  // allow RefNull there as we represent tables that way regardless of what
  // features are enabled.
  auto feats = curr->type.getFeatures();
  if (!shouldBeTrue(!getFunction() || feats.isSubsetOf(getModule()->features),
                    curr,
                    "ref.null requires additional features ")) {
    getStream() << getMissingFeaturesList(*getModule(), feats) << '\n';
  }
  if (!shouldBeTrue(
        curr->type.isNullable(), curr, "ref.null types must be nullable")) {
    return;
  }
  shouldBeTrue(
    curr->type.isNull(), curr, "ref.null must have a bottom heap type");
}

void FunctionValidator::visitRefIsNull(RefIsNull* curr) {
  shouldBeTrue(
    getModule()->features.hasReferenceTypes(),
    curr,
    "ref.is_null requires reference-types [--enable-reference-types]");
  shouldBeTrue(curr->value->type == Type::unreachable ||
                 curr->value->type.isRef(),
               curr->value,
               "ref.is_null's argument should be a reference type");
}

void FunctionValidator::visitRefAs(RefAs* curr) {
  if (curr->value->type != Type::unreachable &&
      !shouldBeTrue(
        curr->value->type.isRef(), curr, "ref.as value must be reference")) {
    return;
  }
  switch (curr->op) {
    case RefAsNonNull: {
      shouldBeTrue(
        getModule()->features.hasReferenceTypes(),
        curr,
        "ref.as requires reference-types [--enable-reference-types]");
      break;
    }
    case AnyConvertExtern: {
      shouldBeTrue(getModule()->features.hasGC(),
                   curr,
                   "any.convert_extern requries GC [--enable-gc]");
      if (curr->type == Type::unreachable) {
        return;
      }
      shouldBeSubTypeIgnoringShared(
        curr->value->type,
        Type(HeapType::ext, Nullable),
        curr->value,
        "any.convert_extern value should be an externref");
      break;
    }
    case ExternConvertAny: {
      shouldBeTrue(getModule()->features.hasGC(),
                   curr,
                   "extern.convert_any requries GC [--enable-gc]");
      if (curr->type == Type::unreachable) {
        return;
      }
      shouldBeSubTypeIgnoringShared(
        curr->value->type,
        Type(HeapType::any, Nullable),
        curr->value,
        "extern.convert_any value should be an anyref");
      break;
    }
  }
}

void FunctionValidator::visitRefFunc(RefFunc* curr) {
  // If we are not in a function, this is a global location like a table. We
  // allow RefFunc there as we represent tables that way regardless of what
  // features are enabled.
  shouldBeTrue(!getFunction() || getModule()->features.hasReferenceTypes(),
               curr,
               "ref.func requires reference-types [--enable-reference-types]");
  if (!shouldBeTrue(curr->type.isNonNullable(),
                    curr,
                    "ref.func should have a non-nullable reference type")) {
    return;
  }
  if (!shouldBeTrue(curr->type.isSignature(),
                    curr,
                    "ref.func must have a function reference type")) {
    return;
  }
  if (!info.validateGlobally) {
    return;
  }
  auto* func = getModule()->getFunctionOrNull(curr->func);
  if (!shouldBeTrue(!!func, curr, "function argument of ref.func must exist")) {
    return;
  }
  shouldBeEqual(curr->type,
                func->type,
                curr,
                "function reference type must match referenced function type");
}

void FunctionValidator::visitRefEq(RefEq* curr) {
  Type eqref = Type(HeapType::eq, Nullable);
  shouldBeTrue(
    getModule()->features.hasGC(), curr, "ref.eq requires gc [--enable-gc]");
  shouldBeSubTypeIgnoringShared(
    curr->left->type,
    eqref,
    curr->left,
    "ref.eq's left argument should be a subtype of eqref");
  shouldBeSubTypeIgnoringShared(
    curr->right->type,
    eqref,
    curr->right,
    "ref.eq's right argument should be a subtype of eqref");
  if (curr->left->type.isRef() && curr->right->type.isRef()) {
    shouldBeEqual(curr->left->type.getHeapType().getShared(),
                  curr->right->type.getHeapType().getShared(),
                  curr,
                  "ref.eq operands must have the same shareability");
  }
}

void FunctionValidator::visitTableGet(TableGet* curr) {
  shouldBeTrue(getModule()->features.hasReferenceTypes(),
               curr,
               "table.get requires reference types [--enable-reference-types]");
  auto* table = getModule()->getTableOrNull(curr->table);
  if (shouldBeTrue(!!table, curr, "table.get table must exist")) {
    if (curr->type != Type::unreachable) {
      shouldBeEqual(curr->type,
                    table->type,
                    curr,
                    "table.get must have same type as table.");
    }
    shouldBeEqualOrFirstIsUnreachable(
      curr->index->type,
      table->addressType,
      curr,
      "table.get index must match the table index type.");
  }
}

void FunctionValidator::visitTableSet(TableSet* curr) {
  shouldBeTrue(getModule()->features.hasReferenceTypes(),
               curr,
               "table.set requires reference types [--enable-reference-types]");
  auto* table = getModule()->getTableOrNull(curr->table);
  if (shouldBeTrue(!!table, curr, "table.set table must exist")) {
    if (curr->type != Type::unreachable) {
      shouldBeSubType(curr->value->type,
                      table->type,
                      curr,
                      "table.set value must have right type");
    }
    shouldBeEqualOrFirstIsUnreachable(
      curr->index->type,
      table->addressType,
      curr,
      "table.set index must match the table index type.");
  }
}

void FunctionValidator::visitTableSize(TableSize* curr) {
  shouldBeTrue(
    getModule()->features.hasReferenceTypes(),
    curr,
    "table.size requires reference types [--enable-reference-types]");
  auto* table = getModule()->getTableOrNull(curr->table);
  shouldBeTrue(!!table, curr, "table.size table must exist");
}

void FunctionValidator::visitTableGrow(TableGrow* curr) {
  shouldBeTrue(
    getModule()->features.hasReferenceTypes(),
    curr,
    "table.grow requires reference types [--enable-reference-types]");
  auto* table = getModule()->getTableOrNull(curr->table);
  if (shouldBeTrue(!!table, curr, "table.grow table must exist") &&
      curr->type != Type::unreachable) {
    shouldBeSubType(curr->value->type,
                    table->type,
                    curr,
                    "table.grow value must have right type");
    shouldBeEqual(curr->delta->type,
                  table->addressType,
                  curr,
                  "table.grow must match table index type");
  }
}

void FunctionValidator::visitTableFill(TableFill* curr) {
  shouldBeTrue(getModule()->features.hasBulkMemory() &&
                 getModule()->features.hasReferenceTypes(),
               curr,
               "table.fill requires bulk-memory [--enable-bulk-memory] and "
               "reference-types [--enable-reference-types]");
  auto* table = getModule()->getTableOrNull(curr->table);
  if (shouldBeTrue(!!table, curr, "table.fill table must exist")) {
    shouldBeSubType(curr->value->type,
                    table->type,
                    curr,
                    "table.fill value must have right type");
    shouldBeEqualOrFirstIsUnreachable(
      curr->dest->type,
      table->addressType,
      curr,
      "table.fill dest must match table index type");
    shouldBeEqualOrFirstIsUnreachable(
      curr->size->type,
      table->addressType,
      curr,
      "table.fill size must match table index type");
  }
}

void FunctionValidator::visitTableCopy(TableCopy* curr) {
  shouldBeTrue(getModule()->features.hasBulkMemory(),
               curr,
               "table.copy requires bulk-memory [--enable-bulk-memory]");
  auto* sourceTable = getModule()->getTableOrNull(curr->sourceTable);
  auto* destTable = getModule()->getTableOrNull(curr->destTable);
  if (shouldBeTrue(!!sourceTable, curr, "table.copy source table must exist") &&
      shouldBeTrue(!!destTable, curr, "table.copy dest table must exist")) {
    shouldBeSubType(sourceTable->type,
                    destTable->type,
                    curr,
                    "table.copy source must have right type for dest");
  }
  shouldBeEqualOrFirstIsUnreachable(curr->dest->type,
                                    destTable->addressType,
                                    curr,
                                    "table.copy dest must be valid");
  shouldBeEqualOrFirstIsUnreachable(curr->source->type,
                                    sourceTable->addressType,
                                    curr,
                                    "table.copy source must be valid");
  Type sizeType =
    sourceTable->is64() && destTable->is64() ? Type::i64 : Type::i32;
  shouldBeEqualOrFirstIsUnreachable(
    curr->size->type, sizeType, curr, "table.copy size must be valid");
}

void FunctionValidator::visitTableInit(TableInit* curr) {
  shouldBeTrue(getModule()->features.hasBulkMemory(),
               curr,
               "table.init requires bulk-memory [--enable-bulk-memory]");
  auto* segment = getModule()->getElementSegment(curr->segment);
  auto* table = getModule()->getTableOrNull(curr->table);
  if (shouldBeTrue(!!segment, curr, "table.init segment must exist") &&
      shouldBeTrue(!!table, curr, "table.init table must exist")) {
    shouldBeSubType(segment->type,
                    table->type,
                    curr,
                    "table.init source must have right type for dest");
  }
  shouldBeEqualOrFirstIsUnreachable(curr->dest->type,
                                    table->addressType,
                                    curr,
                                    "table.init dest must be valid");
  shouldBeEqualOrFirstIsUnreachable(curr->offset->type,
                                    Type(Type::i32),
                                    curr,
                                    "table.init offset must be valid");
  shouldBeEqualOrFirstIsUnreachable(
    curr->size->type, Type(Type::i32), curr, "table.init size must be valid");
}

void FunctionValidator::visitElemDrop(ElemDrop* curr) {
  shouldBeTrue(getModule()->features.hasBulkMemory(),
               curr,
               "elem.drop requires bulk-memory [--enable-bulk-memory]");
  auto* segment = getModule()->getElementSegment(curr->segment);
  shouldBeTrue(!!segment, curr, "elem.drop segment must exist");
}

void FunctionValidator::noteDelegate(Name name, Expression* curr) {
  if (name != DELEGATE_CALLER_TARGET) {
    shouldBeTrue(delegateTargetNames.contains(name),
                 curr,
                 "all delegate targets must be valid");
  }
}

void FunctionValidator::noteRethrow(Name name, Expression* curr) {
  shouldBeTrue(rethrowTargetNames.contains(name),
               curr,
               "all rethrow targets must be valid");
}

void FunctionValidator::visitTry(Try* curr) {
  shouldBeTrue(getModule()->features.hasExceptionHandling(),
               curr,
               "try requires exception-handling [--enable-exception-handling]");
  if (curr->name.is()) {
    noteLabelName(curr->name);
  }
  if (curr->type != Type::unreachable) {
    shouldBeSubType(curr->body->type,
                    curr->type,
                    curr->body,
                    "try's type does not match try body's type");
    for (auto catchBody : curr->catchBodies) {
      shouldBeSubType(catchBody->type,
                      curr->type,
                      catchBody,
                      "try's type does not match catch's body type");
    }
  } else {
    shouldBeEqual(curr->body->type,
                  Type(Type::unreachable),
                  curr,
                  "unreachable try-catch must have unreachable try body");
    for (auto catchBody : curr->catchBodies) {
      shouldBeEqual(catchBody->type,
                    Type(Type::unreachable),
                    curr,
                    "unreachable try-catch must have unreachable catch body");
    }
  }
  shouldBeTrue(curr->catchBodies.size() - curr->catchTags.size() <= 1,
               curr,
               "the number of catch blocks and tags do not match");

  shouldBeFalse(curr->isCatch() && curr->isDelegate(),
                curr,
                "try cannot have both catch and delegate at the same time");

  for (Index i = 0; i < curr->catchTags.size(); i++) {
    Name tagName = curr->catchTags[i];
    auto* tag = getModule()->getTagOrNull(tagName);
    if (!shouldBeTrue(tag != nullptr, curr, "")) {
      getStream() << "tag name is invalid: " << tagName << "\n";
    } else if (!shouldBeEqual(tag->results(), Type(Type::none), curr, "")) {
      getStream()
        << "catch's tag (" << tagName
        << ") has result values, which is not allowed for exception handling";
    } else {
      auto* catchBody = curr->catchBodies[i];
      auto pops = EHUtils::findPops(catchBody);
      if (tag->params() == Type::none) {
        if (!shouldBeTrue(pops.empty(), curr, "")) {
          getStream() << "catch's tag (" << tagName
                      << ") doesn't have any params, but there are pops";
        }
      } else {
        if (shouldBeTrue(pops.size() == 1, curr, "")) {
          auto* pop = *pops.begin();
          if (!shouldBeSubType(tag->params(), pop->type, curr, "")) {
            getStream()
              << "catch's tag (" << tagName
              << ")'s pop doesn't have the same type as the tag's params";
          }
          if (!shouldBeTrue(
                EHUtils::containsValidDanglingPop(catchBody), curr, "")) {
            getStream() << "catch's body (" << tagName
                        << ")'s pop's location is not valid";
          }
        } else {
          getStream() << "catch's tag (" << tagName
                      << ") has params, so there should be a single pop within "
                         "the catch body";
        }
      }
    }
  }

  if (curr->hasCatchAll()) {
    auto* catchAllBody = curr->catchBodies.back();
    shouldBeTrue(EHUtils::findPops(catchAllBody).empty(),
                 curr,
                 "catch_all's body should not have pops");
  }

  if (curr->isDelegate()) {
    noteDelegate(curr->delegateTarget, curr);
  }

  rethrowTargetNames.erase(curr->name);
}

void FunctionValidator::visitTryTable(TryTable* curr) {
  shouldBeTrue(
    getModule()->features.hasExceptionHandling(),
    curr,
    "try_table requires exception-handling [--enable-exception-handling]");
  if (curr->type != Type::unreachable) {
    shouldBeSubType(curr->body->type,
                    curr->type,
                    curr->body,
                    "try_table's type does not match try_table body's type");
  }

  shouldBeEqual(curr->catchTags.size(),
                curr->catchDests.size(),
                curr,
                "the number of catch tags and catch destinations do not match");
  shouldBeEqual(curr->catchTags.size(),
                curr->catchRefs.size(),
                curr,
                "the number of catch tags and catch refs do not match");
  shouldBeEqual(curr->catchTags.size(),
                curr->sentTypes.size(),
                curr,
                "the number of catch tags and sent types do not match");

  const char* invalidSentTypeMsg = "invalid catch sent type information";
  Type exnref = Type(HeapType::exn, NonNullable);
  for (Index i = 0; i < curr->catchTags.size(); i++) {
    auto sentType = curr->sentTypes[i];
    size_t tagTypeSize;

    Name tagName = curr->catchTags[i];
    if (!tagName) { // catch_all or catch_all_ref
      tagTypeSize = 0;
    } else { // catch or catch_ref
      // Check tag validity
      auto* tag = getModule()->getTagOrNull(tagName);
      if (!shouldBeTrue(tag != nullptr, curr, "")) {
        getStream() << "catch's tag name is invalid: " << tagName << "\n";
      } else if (!shouldBeEqual(tag->results(), Type(Type::none), curr, "")) {
        getStream()
          << "catch's tag (" << tagName
          << ") has result values, which is not allowed for exception handling";
      }

      // tagType and sentType should be the same (except for the possible exnref
      // at the end of sentType)
      auto tagType = tag->params();
      tagTypeSize = tagType.size();
      for (Index j = 0; j < tagType.size(); j++) {
        shouldBeEqual(tagType[j], sentType[j], curr, invalidSentTypeMsg);
      }
    }

    // If this is catch_ref or catch_all_ref, sentType.size() should be
    // tagType.size() + 1 because there is an exrnef tacked at the end. If
    // this is catch/catch_all, the two sizes should be the same.
    if (curr->catchRefs[i]) {
      if (shouldBeTrue(
            sentType.size() == tagTypeSize + 1, curr, invalidSentTypeMsg)) {
        shouldBeEqual(
          sentType[sentType.size() - 1], exnref, curr, invalidSentTypeMsg);
      }
    } else {
      shouldBeTrue(sentType.size() == tagTypeSize, curr, invalidSentTypeMsg);
    }

    // Note catch destinations with sent types
    noteBreak(curr->catchDests[i], curr->sentTypes[i], curr);
  }
}

void FunctionValidator::visitThrow(Throw* curr) {
  shouldBeTrue(
    getModule()->features.hasExceptionHandling(),
    curr,
    "throw requires exception-handling [--enable-exception-handling]");
  shouldBeEqual(curr->type,
                Type(Type::unreachable),
                curr,
                "throw's type must be unreachable");
  if (!info.validateGlobally) {
    return;
  }
  auto* tag = getModule()->getTagOrNull(curr->tag);
  if (!shouldBeTrue(!!tag, curr, "throw's tag must exist")) {
    return;
  }
  shouldBeEqual(
    tag->results(),
    Type(Type::none),
    curr,
    "tags with result types must not be used for exception handling");
  if (!shouldBeEqual(curr->operands.size(),
                     tag->params().size(),
                     curr,
                     "tag's param numbers must match")) {
    return;
  }
  size_t i = 0;
  for (const auto& param : tag->params()) {
    if (!shouldBeSubType(curr->operands[i]->type,
                         param,
                         curr->operands[i],
                         "tag param types must match") &&
        !info.quiet) {
      getStream() << "(on argument " << i << ")\n";
    }
    ++i;
  }
}

void FunctionValidator::visitRethrow(Rethrow* curr) {
  shouldBeTrue(
    getModule()->features.hasExceptionHandling(),
    curr,
    "rethrow requires exception-handling [--enable-exception-handling]");
  shouldBeEqual(curr->type,
                Type(Type::unreachable),
                curr,
                "rethrow's type must be unreachable");
  noteRethrow(curr->target, curr);
}

void FunctionValidator::visitTupleMake(TupleMake* curr) {
  shouldBeTrue(getModule()->features.hasMultivalue(),
               curr,
               "Tuples are not allowed unless multivalue is enabled");
  shouldBeTrue(
    curr->operands.size() > 1, curr, "tuple.make must have multiple operands");
  std::vector<Type> types;
  for (auto* op : curr->operands) {
    if (op->type == Type::unreachable) {
      shouldBeTrue(
        curr->type == Type::unreachable,
        curr,
        "If tuple.make has an unreachable operand, it must be unreachable");
      return;
    }
    types.push_back(op->type);
  }
  shouldBeSubType(Type(types),
                  curr->type,
                  curr,
                  "Type of tuple.make does not match types of its operands");
}

void FunctionValidator::visitThrowRef(ThrowRef* curr) {
  Type exnref = Type(HeapType::exn, Nullable);
  shouldBeSubType(curr->exnref->type,
                  exnref,
                  curr,
                  "throw_ref's argument should be a subtype of exnref");
}

void FunctionValidator::visitTupleExtract(TupleExtract* curr) {
  shouldBeTrue(getModule()->features.hasMultivalue(),
               curr,
               "Tuples are not allowed unless multivalue is enabled");
  if (curr->tuple->type == Type::unreachable) {
    shouldBeTrue(
      curr->type == Type::unreachable,
      curr,
      "If tuple.extract has an unreachable operand, it must be unreachable");
  } else {
    bool inBounds = curr->index < curr->tuple->type.size();
    shouldBeTrue(inBounds, curr, "tuple.extract index out of bounds");
    if (inBounds) {
      shouldBeSubType(
        curr->tuple->type[curr->index],
        curr->type,
        curr,
        "tuple.extract type does not match the type of the extracted element");
    }
  }
}

void FunctionValidator::visitCallRef(CallRef* curr) {
  validateReturnCall(curr);
  shouldBeTrue(
    getModule()->features.hasGC(), curr, "call_ref requires gc [--enable-gc]");
  if (curr->target->type == Type::unreachable ||
      (curr->target->type.isRef() &&
       curr->target->type.getHeapType().isMaybeShared(HeapType::nofunc))) {
    return;
  }
  if (shouldBeTrue(curr->target->type.isFunction(),
                   curr,
                   "call_ref target must be a function reference")) {
    validateCallParamsAndResult(curr, curr->target->type.getHeapType());
  }
}

void FunctionValidator::visitRefI31(RefI31* curr) {
  shouldBeTrue(
    getModule()->features.hasGC(), curr, "ref.i31 requires gc [--enable-gc]");
  shouldBeSubType(curr->value->type,
                  Type::i32,
                  curr->value,
                  "ref.i31's argument should be i32");

  if (curr->type == Type::unreachable) {
    return;
  }

  if (!shouldBeTrue(curr->type.isNonNullable(),
                    curr,
                    "ref.i31 should have a non-nullable reference type")) {
    return;
  }
  auto heapType = curr->type.getHeapType();
  if (!shouldBeTrue(heapType.isBasic() &&
                      heapType.getBasic(Unshared) == HeapType::i31,
                    curr,
                    "ref.i31 should have an i31 reference type")) {
    return;
  }
  if (heapType.isShared()) {
    shouldBeTrue(
      getModule()->features.hasSharedEverything(),
      curr,
      "ref.i31_shared requires shared-everything [--enable-shared-everything]");
  }
}

void FunctionValidator::visitI31Get(I31Get* curr) {
  shouldBeTrue(getModule()->features.hasGC(),
               curr,
               "i31.get_s/u requires gc [--enable-gc]");
  shouldBeSubTypeIgnoringShared(curr->i31->type,
                                Type(HeapType::i31, Nullable),
                                curr->i31,
                                "i31.get_s/u's argument should be i31ref");
}

void FunctionValidator::visitRefTest(RefTest* curr) {
  shouldBeTrue(
    getModule()->features.hasGC(), curr, "ref.test requires gc [--enable-gc]");

  shouldBeTrue(
    curr->castType.isCastable(), curr, "ref.test cannot cast to invalid type");

  if (curr->ref->type == Type::unreachable) {
    return;
  }
  if (!shouldBeTrue(
        curr->ref->type.isRef(), curr, "ref.test ref must have ref type")) {
    return;
  }
  if (!shouldBeTrue(
        curr->castType.isRef(), curr, "ref.test target must have ref type")) {
    return;
  }
  shouldBeEqual(
    HeapType(curr->castType.getHeapType().getTop()),
    HeapType(curr->ref->type.getHeapType().getTop()),
    curr,
    "ref.test target type and ref type must have a common supertype");

  // If custom descriptors is not enabled, only trivial and null-checking exact
  // casts are allowed, i.e. those where the operand is also exact and has the
  // same heap type, but may differ in nullability. The result of these trivial
  // exact casts does not change when the types are made inexact during binary
  // writing.
  if (!getModule()->features.hasCustomDescriptors()) {
    shouldBeTrue(curr->castType.isInexact() || curr->castType.with(Nullable) ==
                                                 curr->ref->type.with(Nullable),
                 curr,
                 "ref.test of exact type requires custom descriptors "
                 "[--enable-custom-descriptors]");
  }

  shouldBeTrue(
    curr->ref->type.isCastable(), curr, "ref.test cannot cast invalid type");
}

void FunctionValidator::visitRefCast(RefCast* curr) {
  shouldBeTrue(
    getModule()->features.hasGC(), curr, "ref.cast requires gc [--enable-gc]");

  // Require descriptors to be valid even if the ref is unreachable.
  if (curr->desc && curr->desc->type != Type::unreachable) {
    auto descType = curr->desc->type;
    bool isNull = descType.isNull();
    bool isDescriptor =
      descType.isRef() && descType.getHeapType().getDescribedType();
    shouldBeTrue(isNull || isDescriptor,
                 curr,
                 "ref.cast_desc_eq descriptor must be a descriptor reference");
  }

  if (curr->type == Type::unreachable) {
    return;
  }
  if (!shouldBeTrue(
        curr->ref->type.isRef(), curr, "ref.cast ref must have ref type")) {
    return;
  }
  // Also error (more generically) on i32 and anything else invalid here.
  if (!shouldBeTrue(curr->type.isRef(), curr, "ref.cast must have ref type")) {
    return;
  }
  shouldBeEqual(
    HeapType(curr->type.getHeapType().getTop()),
    HeapType(curr->ref->type.getHeapType().getTop()),
    curr,
    "ref.cast target type and ref type must have a common supertype");
  // We should never have a nullable cast of a non-nullable reference, since
  // that unnecessarily loses type information.
  shouldBeTrue(curr->ref->type.isNullable() || curr->type.isNonNullable(),
               curr,
               "ref.cast null of non-nullable references are not allowed");

  // See comment about exactness on visitRefTest.
  if (!getModule()->features.hasCustomDescriptors()) {
    shouldBeTrue(curr->type.isInexact() ||
                   curr->type.with(Nullable) == curr->ref->type.with(Nullable),
                 curr,
                 "ref.cast to exact type requires custom descriptors "
                 "[--enable-custom-descriptors]");
  }

  shouldBeTrue(
    curr->ref->type.isCastable(), curr, "ref.cast cannot cast invalid type");
  shouldBeTrue(
    curr->type.isCastable(), curr, "ref.cast cannot cast to invalid type");

  if (!curr->desc) {
    return;
  }

  shouldBeTrue(getModule()->features.hasCustomDescriptors(),
               curr,
               "ref.cast_desc_eq requires custom descriptors "
               "[--enable-custom-descriptors]");
  if (!shouldBeTrue(curr->desc && curr->desc->type.isRef(),
                    curr,
                    "ref.cast_desc_eq descriptor must have ref type")) {
    return;
  }
  auto descriptor = curr->desc->type.getHeapType();
  if (descriptor.isBottom()) {
    return;
  }

  auto described = descriptor.getDescribedType();
  assert(described && "already checked descriptor");
  shouldBeEqual(*described,
                curr->type.getHeapType(),
                curr,
                "ref.cast_desc_eq cast type should be described by descriptor");
  shouldBeEqual(
    curr->type.getExactness(),
    curr->desc->type.getExactness(),
    curr,
    "ref.cast_desc_eq cast exactness should match descriptor exactness");
}

void FunctionValidator::visitRefGetDesc(RefGetDesc* curr) {
  shouldBeTrue(
    getModule()->features.hasCustomDescriptors(),
    curr,
    "ref.get_desc requires custom descriptors [--enable-custom-descriptors]");
}

void FunctionValidator::visitBrOn(BrOn* curr) {
  shouldBeTrue(
    getModule()->features.hasGC(), curr, "br_on* requires gc [--enable-gc]");

  if (curr->op != BrOnNull && curr->op != BrOnNonNull) {
    // Common validation for all br_on_cast*
    if (!shouldBeTrue(curr->castType.isRef(),
                      curr,
                      "br_on_cast* must have reference cast type")) {
      return;
    }
    if (curr->ref->type != Type::unreachable) {
      shouldBeEqual(
        HeapType(curr->castType.getHeapType().getTop()),
        HeapType(curr->ref->type.getHeapType().getTop()),
        curr,
        "br_on_cast* target type and ref type must have a common supertype");
    }
    shouldBeTrue(
      curr->castType.isCastable(), curr, "br_on cannot cast to invalid type");
  }

  if (curr->ref->type == Type::unreachable) {
    return;
  }
  if (!shouldBeTrue(
        curr->ref->type.isRef(), curr, "br_on* ref must have ref type")) {
    return;
  }
  switch (curr->op) {
    case BrOnNull:
    case BrOnNonNull:
      shouldBeEqual(curr->castType,
                    Type(Type::none),
                    curr,
                    "non-cast br_on* must not set castType field");
      break;
    case BrOnCastDescEq:
    case BrOnCastDescEqFail: {
      shouldBeTrue(getModule()->features.hasCustomDescriptors(),
                   curr,
                   "br_on_cast_desc_eq* requires custom descriptors "
                   "[--enable-custom-descriptors]");
      if (!shouldBeTrue(curr->desc && curr->desc->type.isRef(),
                        curr,
                        "br_on_cast_desc_eq* descriptor must have ref type")) {
        return;
      }
      auto descriptor = curr->desc->type.getHeapType();
      if (!descriptor.isBottom()) {
        auto described = descriptor.getDescribedType();
        if (!shouldBeTrue(
              bool(described),
              curr,
              "br_on_cast_desc_eq* descriptor should have a described type")) {
          return;
        }
        shouldBeEqual(
          *described,
          curr->castType.getHeapType(),
          curr,
          "br_on_cast_desc_eq* cast type should be described by descriptor");
        shouldBeEqual(curr->castType.getExactness(),
                      curr->desc->type.getExactness(),
                      curr,
                      "br_on_cast_desc_eq* cast exactness should match "
                      "descriptor exactness");
        shouldBeTrue(curr->ref->type.isNullable() ||
                       curr->castType.isNonNullable(),
                     curr,
                     "br_on_cast_desc_eq* with non-nullable ref should have "
                     "non-nullable cast type");
      }
      break;
    }
    case BrOnCast:
    case BrOnCastFail: {
      shouldBeSubType(
        curr->castType,
        curr->ref->type,
        curr,
        "br_on_cast* target type must be a subtype of its input type");
      // See comment about exactness on visitRefTest.
      if (!getModule()->features.hasCustomDescriptors()) {
        shouldBeTrue(curr->castType.isInexact() ||
                       curr->castType.with(Nullable) ==
                         curr->ref->type.with(Nullable),
                     curr,
                     "br_on_cast* to exact type requires custom descriptors "
                     "[--enable-custom-descriptors]");
      }
      shouldBeTrue(
        curr->ref->type.isCastable(), curr, "br_on cannot cast invalid type");
      break;
    }
  }
  noteBreak(curr->name, curr->getSentType(), curr);
}

void FunctionValidator::visitStructNew(StructNew* curr) {
  shouldBeTrue(getModule()->features.hasGC(),
               curr,
               "struct.new requires gc [--enable-gc]");
  if (curr->type == Type::unreachable) {
    return;
  }
  if (!shouldBeTrue(curr->type.isNonNullable(),
                    curr,
                    "struct.new should have a non-nullable reference type")) {
    return;
  }
  shouldBeTrue(curr->type.isExact(), curr, "struct.new should be exact");
  auto heapType = curr->type.getHeapType();
  if (!shouldBeTrue(
        heapType.isStruct(), curr, "struct.new heap type must be struct")) {
    return;
  }
  const auto& fields = heapType.getStruct().fields;
  if (curr->isWithDefault()) {
    shouldBeTrue(curr->operands.empty(),
                 curr,
                 "struct.new_with_default should have no operands");
    // All the fields must be defaultable.
    for (const auto& field : fields) {
      shouldBeTrue(field.type.isDefaultable(),
                   field,
                   "struct.new_with_default value type must be defaultable");
    }
  } else {
    if (shouldBeEqual(curr->operands.size(),
                      fields.size(),
                      curr,
                      "struct.new must have the right number of operands")) {
      // All the fields must have the proper type.
      for (Index i = 0; i < fields.size(); i++) {
        if (!Type::isSubType(curr->operands[i]->type, fields[i].type)) {
          info.fail("struct.new operand " + std::to_string(i) +
                      " must have proper type",
                    curr,
                    getFunction());
        }
      }
    }
  }

  auto descType = curr->type.getHeapType().getDescriptorType();
  if (!descType) {
    shouldBeFalse(curr->desc,
                  curr,
                  "struct.new of type without descriptor should lack one");
  } else {
    if (!shouldBeTrue(
          curr->desc,
          curr,
          "struct.new of type with descriptor requires descriptor operand")) {
      return;
    }
    shouldBeSubType(curr->desc->type,
                    Type(*descType, Nullable, Exact),
                    curr,
                    "struct.new descriptor operand should have proper type");
  }
}

void FunctionValidator::visitStructGet(StructGet* curr) {
  shouldBeTrue(getModule()->features.hasGC(),
               curr,
               "struct.get requires gc [--enable-gc]");
  if (curr->order != MemoryOrder::Unordered) {
    shouldBeTrue(getModule()->features.hasSharedEverything(),
                 curr,
                 "struct.atomic.get requires shared-everything "
                 "[--enable-shared-everything]");
    shouldBeTrue(getModule()->features.hasAtomics(),
                 curr,
                 "struct.atomic.get requires threads [--enable-threads]");
  }
  if (curr->type == Type::unreachable || curr->ref->type.isNull()) {
    return;
  }
  if (!shouldBeTrue(curr->ref->type.isStruct(),
                    curr->ref,
                    "struct.get ref must be a struct")) {
    return;
  }
  const auto& fields = curr->ref->type.getHeapType().getStruct().fields;
  shouldBeTrue(curr->index < fields.size(), curr, "bad struct.get field");
  auto field = fields[curr->index];
  // If the type is not packed, it must be marked internally as unsigned, by
  // convention.
  if (field.type != Type::i32 || field.packedType == Field::NotPacked) {
    shouldBeFalse(curr->signed_, curr, "non-packed get cannot be signed");
  }
  if (curr->ref->type == Type::unreachable) {
    return;
  }
  shouldBeEqual(
    curr->type, field.type, curr, "struct.get must have the proper type");
}

void FunctionValidator::visitStructSet(StructSet* curr) {
  shouldBeTrue(getModule()->features.hasGC(),
               curr,
               "struct.set requires gc [--enable-gc]");
  if (curr->order != MemoryOrder::Unordered) {
    shouldBeTrue(getModule()->features.hasSharedEverything(),
                 curr,
                 "struct.atomic.set requires shared-everything "
                 "[--enable-shared-everything]");
    shouldBeTrue(getModule()->features.hasAtomics(),
                 curr,
                 "struct.atomic.set requires threads [--enable-threads]");
  }
  if (curr->ref->type == Type::unreachable) {
    return;
  }
  if (!shouldBeTrue(curr->ref->type.isRef(),
                    curr->ref,
                    "struct.set ref must be a reference type")) {
    return;
  }
  auto type = curr->ref->type.getHeapType();
  if (type.isMaybeShared(HeapType::none)) {
    return;
  }
  if (!shouldBeTrue(
        type.isStruct(), curr->ref, "struct.set ref must be a struct")) {
    return;
  }
  const auto& fields = type.getStruct().fields;
  if (!shouldBeTrue(
        curr->index < fields.size(), curr, "bad struct.get field")) {
    return;
  }
  auto& field = fields[curr->index];
  shouldBeSubType(curr->value->type,
                  field.type,
                  curr,
                  "struct.set value must have the proper type");
  shouldBeEqual(
    field.mutable_, Mutable, curr, "struct.set field must be mutable");
}

void FunctionValidator::visitStructRMW(StructRMW* curr) {
  FeatureSet expected =
    FeatureSet::GC | FeatureSet::Atomics | FeatureSet::SharedEverything;
  if (!shouldBeTrue(expected.isSubsetOf(getModule()->features),
                    curr,
                    "struct.atomic.rmw requires additional features ")) {
    getStream() << getMissingFeaturesList(*getModule(), expected) << '\n';
  }
  if (curr->ref->type == Type::unreachable) {
    return;
  }
  if (!shouldBeTrue(curr->ref->type.isRef(),
                    curr->ref,
                    "struct.atomic.rmw ref must be a reference type")) {
    return;
  }
  auto type = curr->ref->type.getHeapType();
  if (type.isMaybeShared(HeapType::none)) {
    return;
  }
  if (!shouldBeTrue(
        type.isStruct(), curr->ref, "struct.atomic.rmw ref must be a struct")) {
    return;
  }
  const auto& fields = type.getStruct().fields;
  if (!shouldBeTrue(
        curr->index < fields.size(), curr, "bad struct.atomic.rmw field")) {
    return;
  }
  auto& field = fields[curr->index];
  shouldBeEqual(
    field.mutable_, Mutable, curr, "struct.atomic.rmw field must be mutable");
  shouldBeFalse(
    field.isPacked(), curr, "struct.atomic.rmw field must not be packed");
  bool isAny =
    field.type.isRef() &&
    Type::isSubType(
      field.type,
      Type(HeapTypes::any.getBasic(field.type.getHeapType().getShared()),
           Nullable));
  if (!shouldBeTrue(field.type == Type::i32 || field.type == Type::i64 ||
                      (isAny && curr->op == RMWXchg),
                    curr,
                    "struct.atomic.rmw field type invalid for operation")) {
    return;
  }
  shouldBeSubType(curr->value->type,
                  field.type,
                  curr,
                  "struct.atomic.rmw value must have the proper type");
}

void FunctionValidator::visitStructCmpxchg(StructCmpxchg* curr) {
  FeatureSet expected =
    FeatureSet::GC | FeatureSet::Atomics | FeatureSet::SharedEverything;
  if (!shouldBeTrue(expected.isSubsetOf(getModule()->features),
                    curr,
                    "struct.atomic.rmw requires additional features ")) {
    getStream() << getMissingFeaturesList(*getModule(), expected) << '\n';
  }
  if (curr->ref->type == Type::unreachable) {
    return;
  }
  if (!shouldBeTrue(curr->ref->type.isRef(),
                    curr->ref,
                    "struct.atomic.rmw ref must be a reference type")) {
    return;
  }
  auto type = curr->ref->type.getHeapType();
  if (type.isMaybeShared(HeapType::none)) {
    return;
  }
  if (!shouldBeTrue(
        type.isStruct(), curr->ref, "struct.atomic.rmw ref must be a struct")) {
    return;
  }
  const auto& fields = type.getStruct().fields;
  if (!shouldBeTrue(
        curr->index < fields.size(), curr, "bad struct.atomic.rmw field")) {
    return;
  }
  auto& field = fields[curr->index];
  shouldBeEqual(
    field.mutable_, Mutable, curr, "struct.atomic.rmw field must be mutable");
  shouldBeFalse(
    field.isPacked(), curr, "struct.atomic.rmw field must not be packed");

  Type expectedExpectedType;
  if (field.type == Type::i32) {
    expectedExpectedType = Type::i32;
  } else if (field.type == Type::i64) {
    expectedExpectedType = Type::i64;
  } else if (field.type.isRef()) {
    expectedExpectedType = Type(
      HeapTypes::eq.getBasic(field.type.getHeapType().getShared()), Nullable);
    shouldBeSubType(field.type,
                    expectedExpectedType,
                    curr,
                    "struct.atomic.rmw field type invalid for operation");
  } else {
    shouldBeTrue(
      false, curr, "struct.atomic.rmw field type invalid for operation");
    return;
  }
  shouldBeSubType(
    curr->expected->type,
    expectedExpectedType,
    curr,
    "struct.atomic.rmw.cmpxchg expected value must have the proper type");
  shouldBeSubType(
    curr->replacement->type,
    field.type,
    curr,
    "struct.atomic.rmw.cmpxchg replacement value must have the proper type");
}

void FunctionValidator::visitStructWait(StructWait* curr) {
  shouldBeTrue(
    !getModule() || getModule()->features.hasSharedEverything(),
    curr,
    "struct.wait requires shared-everything [--enable-shared-everything]");

  shouldBeEqual(curr->expected->type,
                Type(Type::BasicType::i32),
                curr,
                "struct.wait expected must be an i32");
  shouldBeEqual(curr->timeout->type,
                Type(Type::BasicType::i64),
                curr,
                "struct.wait timeout must be an i64");

  // Checks to the ref argument's type are done in IRBuilder where we have the
  // type annotation immediate available. We check that
  // * The reference arg is a subtype of the type immediate
  // * The index immediate is a valid field index of the type immediate (and
  // thus valid for the reference's type too)
  // * The index points to a packed waitqueue field
}

void FunctionValidator::visitStructNotify(StructNotify* curr) {
  shouldBeTrue(
    !getModule() || getModule()->features.hasSharedEverything(),
    curr,
    "struct.notify requires shared-everything [--enable-shared-everything]");

  shouldBeEqual(curr->count->type,
                Type(Type::BasicType::i32),
                curr,
                "struct.notify count must be an i32");

  // Checks to the ref argument's type are done in IRBuilder where we have the
  // type annotation immediate available. We check that
  // * The reference arg is a subtype of the type immediate
  // * The index immediate is a valid field index of the type immediate (and
  // thus valid for the reference's type too)
  // * The index points to a packed waitqueue field
}

void FunctionValidator::visitArrayNew(ArrayNew* curr) {
  shouldBeTrue(
    getModule()->features.hasGC(), curr, "array.new requires gc [--enable-gc]");
  shouldBeEqualOrFirstIsUnreachable(
    curr->size->type, Type(Type::i32), curr, "array.new size must be an i32");
  if (curr->type == Type::unreachable) {
    return;
  }
  if (!shouldBeTrue(curr->type.isNonNullable(),
                    curr,
                    "array.new should have a non-nullable reference type")) {
    return;
  }
  shouldBeTrue(curr->type.isExact(), curr, "array.new* should be exact");
  auto heapType = curr->type.getHeapType();
  if (!shouldBeTrue(
        heapType.isArray(), curr, "array.new heap type must be array")) {
    return;
  }
  const auto& element = heapType.getArray().element;
  if (curr->isWithDefault()) {
    shouldBeTrue(
      !curr->init, curr, "array.new_with_default should have no init");
    // The element must be defaultable.
    shouldBeTrue(element.type.isDefaultable(),
                 element,
                 "array.new_with_default value type must be defaultable");
  } else {
    shouldBeTrue(!!curr->init, curr, "array.new should have an init");
    // The inits must have the proper type.
    shouldBeSubType(curr->init->type,
                    element.type,
                    curr,
                    "array.new init must have proper type");
  }
}

template<typename ArrayNew>
void FunctionValidator::visitArrayNewSegment(ArrayNew* curr) {
  shouldBeTrue(getModule()->features.hasGC(),
               curr,
               "array.new_{data, elem} requires gc [--enable-gc]");
  shouldBeEqualOrFirstIsUnreachable(
    curr->offset->type,
    Type(Type::i32),
    curr,
    "array.new_{data, elem} offset must be an i32");
  shouldBeEqualOrFirstIsUnreachable(
    curr->size->type,
    Type(Type::i32),
    curr,
    "array.new_{data, elem} size must be an i32");
  if (curr->type == Type::unreachable) {
    return;
  }
  if (!shouldBeTrue(
        curr->type.isRef(),
        curr,
        "array.new_{data, elem} type should be an array reference")) {
    return;
  }
  shouldBeTrue(
    curr->type.isExact(), curr, "array.new_{data, elem} should be exact");
  auto heapType = curr->type.getHeapType();
  if (!shouldBeTrue(
        heapType.isArray(),
        curr,
        "array.new_{data, elem} type should be an array reference")) {
    return;
  }
}

void FunctionValidator::visitArrayNewData(ArrayNewData* curr) {
  visitArrayNewSegment(curr);

  shouldBeTrue(
    getModule()->features.hasBulkMemory(),
    curr,
    "Data segment operations require bulk memory [--enable-bulk-memory]");
  if (!shouldBeTrue(getModule()->getDataSegment(curr->segment),
                    curr,
                    "array.new_data segment should exist")) {
    return;
  }

  auto field = GCTypeUtils::getField(curr->type);
  if (!field) {
    // A bottom type, or unreachable.
    return;
  }
  shouldBeTrue(field->type.isNumber(),
               curr,
               "array.new_data result element type should be numeric");
}

void FunctionValidator::visitArrayNewElem(ArrayNewElem* curr) {
  visitArrayNewSegment(curr);

  if (!shouldBeTrue(getModule()->getElementSegment(curr->segment),
                    curr,
                    "array.new_elem segment should exist")) {
    return;
  }

  auto field = GCTypeUtils::getField(curr->type);
  if (!field) {
    // A bottom type, or unreachable.
    return;
  }
  shouldBeSubType(getModule()->getElementSegment(curr->segment)->type,
                  field->type,
                  curr,
                  "array.new_elem segment type should be a subtype of the "
                  "result element type");
}

void FunctionValidator::visitArrayNewFixed(ArrayNewFixed* curr) {
  shouldBeTrue(getModule()->features.hasGC(),
               curr,
               "array.new_fixed requires gc [--enable-gc]");
  if (curr->type == Type::unreachable) {
    return;
  }
  shouldBeTrue(curr->type.isExact(), curr, "array.new_fixed should be exact");
  auto heapType = curr->type.getHeapType();
  if (!shouldBeTrue(
        heapType.isArray(), curr, "array.new_fixed heap type must be array")) {
    return;
  }
  const auto& element = heapType.getArray().element;
  for (auto* value : curr->values) {
    shouldBeSubType(value->type,
                    element.type,
                    curr,
                    "array.new_fixed value must have proper type");
  }
}

void FunctionValidator::visitArrayGet(ArrayGet* curr) {
  shouldBeTrue(
    getModule()->features.hasGC(), curr, "array.get requires gc [--enable-gc]");
  shouldBeEqualOrFirstIsUnreachable(
    curr->index->type, Type(Type::i32), curr, "array.get index must be an i32");
  const char* mustBeArray =
    "array.get target should be a specific array reference";
  if (curr->type == Type::unreachable ||
      !shouldBeTrue(curr->ref->type.isRef(), curr, mustBeArray) ||
      curr->ref->type.getHeapType().isBottom() ||
      !shouldBeTrue(curr->ref->type.isArray(), curr, mustBeArray)) {
    return;
  }
  auto heapType = curr->ref->type.getHeapType();
  const auto& element = heapType.getArray().element;
  // If the type is not packed, it must be marked internally as unsigned, by
  // convention.
  if (element.type != Type::i32 || element.packedType == Field::NotPacked) {
    shouldBeFalse(curr->signed_, curr, "non-packed get cannot be signed");
  }
  shouldBeEqual(
    curr->type, element.type, curr, "array.get must have the proper type");
}

void FunctionValidator::visitArraySet(ArraySet* curr) {
  shouldBeTrue(
    getModule()->features.hasGC(), curr, "array.set requires gc [--enable-gc]");
  shouldBeEqualOrFirstIsUnreachable(
    curr->index->type, Type(Type::i32), curr, "array.set index must be an i32");
  if (curr->type == Type::unreachable) {
    return;
  }
  const char* mustBeArray = "array.set target should be an array reference";
  if (curr->type == Type::unreachable ||
      !shouldBeTrue(curr->ref->type.isRef(), curr, mustBeArray) ||
      curr->ref->type.getHeapType().isBottom() ||
      !shouldBeTrue(curr->ref->type.isArray(), curr, mustBeArray)) {
    return;
  }
  const auto& element = curr->ref->type.getHeapType().getArray().element;
  shouldBeSubType(curr->value->type,
                  element.type,
                  curr,
                  "array.set must have the proper type");
  shouldBeTrue(element.mutable_, curr, "array.set type must be mutable");
}

void FunctionValidator::visitArrayLoad(ArrayLoad* curr) {
  shouldBeTrue(getModule()->features.hasMultibyte(),
               curr,
               "array.load requires multibyte [--enable-multibyte]");
  shouldBeEqualOrFirstIsUnreachable(curr->index->type,
                                    Type(Type::i32),
                                    curr,
                                    "array load index must be an i32");
  if (curr->type == Type::unreachable) {
    return;
  }
  const char* mustBeArray = "array load target should be an array reference";
  if (curr->type == Type::unreachable ||
      !shouldBeTrue(curr->ref->type.isRef(), curr, mustBeArray) ||
      curr->ref->type.getHeapType().isBottom() ||
      !shouldBeTrue(curr->ref->type.isArray(), curr, mustBeArray)) {
    return;
  }

  auto heapType = curr->ref->type.getHeapType();
  const auto& element = heapType.getArray().element;
  shouldBeTrue(
    element.packedType == Field::i8, curr, "array load type must be i8");
}

void FunctionValidator::visitArrayStore(ArrayStore* curr) {
  shouldBeTrue(getModule()->features.hasMultibyte(),
               curr,
               "array.store requires multibyte [--enable-multibyte]");
  shouldBeEqualOrFirstIsUnreachable(curr->index->type,
                                    Type(Type::i32),
                                    curr,
                                    "array store index must be an i32");
  if (curr->type == Type::unreachable) {
    return;
  }
  const char* mustBeArray = "array store target should be an array reference";
  if (curr->type == Type::unreachable ||
      !shouldBeTrue(curr->ref->type.isRef(), curr, mustBeArray) ||
      curr->ref->type.getHeapType().isBottom() ||
      !shouldBeTrue(curr->ref->type.isArray(), curr, mustBeArray)) {
    return;
  }

  auto heapType = curr->ref->type.getHeapType();
  const auto& element = heapType.getArray().element;
  shouldBeTrue(
    element.packedType == Field::i8, curr, "array store type must be i8");
  shouldBeTrue(element.mutable_, curr, "array store type must be mutable");
}

void FunctionValidator::visitArrayLen(ArrayLen* curr) {
  shouldBeTrue(
    getModule()->features.hasGC(), curr, "array.len requires gc [--enable-gc]");
  shouldBeEqualOrFirstIsUnreachable(
    curr->type, Type(Type::i32), curr, "array.len result must be an i32");
  shouldBeSubTypeIgnoringShared(
    curr->ref->type,
    Type(HeapType::array, Nullable),
    curr,
    "array.len argument must be an array reference");
}

void FunctionValidator::visitArrayCopy(ArrayCopy* curr) {
  shouldBeTrue(getModule()->features.hasGC(),
               curr,
               "array.copy requires gc [--enable-gc]");
  shouldBeEqualOrFirstIsUnreachable(curr->srcIndex->type,
                                    Type(Type::i32),
                                    curr,
                                    "array.copy src index must be an i32");
  shouldBeEqualOrFirstIsUnreachable(curr->destIndex->type,
                                    Type(Type::i32),
                                    curr,
                                    "array.copy dest index must be an i32");
  if (curr->type == Type::unreachable) {
    return;
  }
  if (!shouldBeTrue(curr->srcRef->type.isRef(),
                    curr,
                    "array.copy source should be a reference")) {
    return;
  }
  if (!shouldBeTrue(curr->destRef->type.isRef(),
                    curr,
                    "array.copy destination should be a reference")) {
    return;
  }
  auto srcHeapType = curr->srcRef->type.getHeapType();
  auto destHeapType = curr->destRef->type.getHeapType();
  // Normally both types need to be references to specific arrays, but if either
  // of the types are bottom, we don't further constrain the other at all
  // because this will be emitted as an unreachable.
  if (srcHeapType.isBottom() || destHeapType.isBottom()) {
    return;
  }
  if (!shouldBeTrue(srcHeapType.isArray(),
                    curr,
                    "array.copy source should be an array reference")) {
    return;
  }
  if (!shouldBeTrue(destHeapType.isArray(),
                    curr,
                    "array.copy destination should be an array reference")) {
    return;
  }
  const auto& srcElement = srcHeapType.getArray().element;
  const auto& destElement = destHeapType.getArray().element;
  shouldBeSubType(srcElement.type,
                  destElement.type,
                  curr,
                  "array.copy must have the proper types");
  shouldBeEqual(srcElement.packedType,
                destElement.packedType,
                curr,
                "array.copy types must match");
  shouldBeTrue(
    destElement.mutable_, curr, "array.copy destination must be mutable");
}

void FunctionValidator::visitArrayFill(ArrayFill* curr) {
  shouldBeTrue(getModule()->features.hasGC(),
               curr,
               "array.fill requires gc [--enable-gc]");
  shouldBeEqualOrFirstIsUnreachable(curr->index->type,
                                    Type(Type::i32),
                                    curr,
                                    "array.fill index must be an i32");
  shouldBeEqualOrFirstIsUnreachable(
    curr->size->type, Type(Type::i32), curr, "array.fill size must be an i32");
  const char* mustBeArray =
    "array.fill destination should be an array reference";
  if (curr->type == Type::unreachable ||
      !shouldBeTrue(curr->ref->type.isRef(), curr, mustBeArray) ||
      curr->ref->type.getHeapType().isBottom() ||
      !shouldBeTrue(curr->ref->type.isArray(), curr, mustBeArray)) {
    return;
  }
  auto heapType = curr->ref->type.getHeapType();
  auto element = heapType.getArray().element;
  shouldBeSubType(curr->value->type,
                  element.type,
                  curr,
                  "array.fill value must match destination element type");
  shouldBeTrue(
    element.mutable_, curr, "array.fill destination must be mutable");
}

template<typename ArrayInit>
void FunctionValidator::visitArrayInit(ArrayInit* curr) {
  shouldBeTrue(getModule()->features.hasGC(),
               curr,
               "array.init_* requires gc [--enable-gc]");
  shouldBeEqualOrFirstIsUnreachable(curr->index->type,
                                    Type(Type::i32),
                                    curr,
                                    "array.init_* index must be an i32");
  shouldBeEqualOrFirstIsUnreachable(curr->offset->type,
                                    Type(Type::i32),
                                    curr,
                                    "array.init_* offset must be an i32");
  shouldBeEqualOrFirstIsUnreachable(curr->size->type,
                                    Type(Type::i32),
                                    curr,
                                    "array.init_* size must be an i32");
  const char* mustBeArray =
    "array.init_* destination must be an array reference";
  if (curr->type == Type::unreachable ||
      !shouldBeTrue(curr->ref->type.isRef(), curr, mustBeArray) ||
      curr->ref->type.getHeapType().isBottom() ||
      !shouldBeTrue(curr->ref->type.isArray(), curr, mustBeArray)) {
    return;
  }
  auto heapType = curr->ref->type.getHeapType();
  auto element = heapType.getArray().element;
  shouldBeTrue(
    element.mutable_, curr, "array.init_* destination must be mutable");
}

void FunctionValidator::visitArrayInitData(ArrayInitData* curr) {
  visitArrayInit(curr);

  shouldBeTrue(
    getModule()->features.hasBulkMemory(),
    curr,
    "Data segment operations require bulk memory [--enable-bulk-memory]");
  shouldBeTrue(getModule()->getDataSegmentOrNull(curr->segment),
               curr,
               "array.init_data segment must exist");

  auto field = GCTypeUtils::getField(curr->ref->type);
  if (!field) {
    // A bottom type, or unreachable.
    return;
  }
  shouldBeTrue(field->type.isNumber(),
               curr,
               "array.init_data destination must be numeric");
}

void FunctionValidator::visitArrayInitElem(ArrayInitElem* curr) {
  visitArrayInit(curr);

  auto* seg = getModule()->getElementSegmentOrNull(curr->segment);
  if (!shouldBeTrue(seg, curr, "array.init_elem segment must exist")) {
    return;
  }

  auto field = GCTypeUtils::getField(curr->ref->type);
  if (!field) {
    // A bottom type, or unreachable.
    return;
  }

  shouldBeSubType(seg->type,
                  field->type,
                  curr,
                  "array.init_elem segment type must match destination type");
}

void FunctionValidator::visitArrayRMW(ArrayRMW* curr) {
  FeatureSet expected =
    FeatureSet::GC | FeatureSet::Atomics | FeatureSet::SharedEverything;
  if (!shouldBeTrue(expected.isSubsetOf(getModule()->features),
                    curr,
                    "array.atomic.rmw requires additional features ")) {
    getStream() << getMissingFeaturesList(*getModule(), expected) << '\n';
  }
  if (curr->ref->type == Type::unreachable) {
    return;
  }
  if (!shouldBeTrue(curr->ref->type.isRef(),
                    curr->ref,
                    "array.atomic.rmw ref must be a reference type")) {
    return;
  }
  auto type = curr->ref->type.getHeapType();
  if (type.isMaybeShared(HeapType::none)) {
    return;
  }
  if (!shouldBeTrue(
        type.isArray(), curr->ref, "array.atomic.rmw ref must be a array")) {
    return;
  }
  const auto& element = type.getArray().element;
  shouldBeEqual(element.mutable_,
                Mutable,
                curr,
                "array.atomic.rmw element must be mutable");
  shouldBeFalse(
    element.isPacked(), curr, "array.atomic.rmw element must not be packed");
  bool isAny =
    element.type.isRef() &&
    Type::isSubType(
      element.type,
      Type(HeapTypes::any.getBasic(element.type.getHeapType().getShared()),
           Nullable));
  if (!shouldBeTrue(element.type == Type::i32 || element.type == Type::i64 ||
                      (isAny && curr->op == RMWXchg),
                    curr,
                    "array.atomic.rmw element type invalid for operation")) {
    return;
  }
  shouldBeSubType(curr->value->type,
                  element.type,
                  curr,
                  "array.atomic.rmw value must have the proper type");
}

void FunctionValidator::visitArrayCmpxchg(ArrayCmpxchg* curr) {
  FeatureSet expected =
    FeatureSet::GC | FeatureSet::Atomics | FeatureSet::SharedEverything;
  if (!shouldBeTrue(expected.isSubsetOf(getModule()->features),
                    curr,
                    "array.atomic.rmw requires additional features ")) {
    getStream() << getMissingFeaturesList(*getModule(), expected) << '\n';
  }
  if (curr->ref->type == Type::unreachable) {
    return;
  }
  if (!shouldBeTrue(curr->ref->type.isRef(),
                    curr->ref,
                    "array.atomic.rmw ref must be a reference type")) {
    return;
  }
  auto type = curr->ref->type.getHeapType();
  if (type.isMaybeShared(HeapType::none)) {
    return;
  }
  if (!shouldBeTrue(
        type.isArray(), curr->ref, "array.atomic.rmw ref must be a array")) {
    return;
  }
  const auto& element = type.getArray().element;
  shouldBeEqual(element.mutable_,
                Mutable,
                curr,
                "array.atomic.rmw element must be mutable");
  shouldBeFalse(
    element.isPacked(), curr, "array.atomic.rmw element must not be packed");

  Type expectedExpectedType;
  if (element.type == Type::i32) {
    expectedExpectedType = Type::i32;
  } else if (element.type == Type::i64) {
    expectedExpectedType = Type::i64;
  } else if (element.type.isRef()) {
    expectedExpectedType = Type(
      HeapTypes::eq.getBasic(element.type.getHeapType().getShared()), Nullable);
    shouldBeSubType(element.type,
                    expectedExpectedType,
                    curr,
                    "array.atomic.rmw element type invalid for operation");
  } else {
    shouldBeTrue(
      false, curr, "array.atomic.rmw element type invalid for operation");
    return;
  }
  shouldBeSubType(
    curr->expected->type,
    expectedExpectedType,
    curr,
    "array.atomic.rmw.cmpxchg expected value must have the proper type");
  shouldBeSubType(
    curr->replacement->type,
    element.type,
    curr,
    "array.atomic.rmw.cmpxchg replacement value must have the proper type");
}

void FunctionValidator::visitStringNew(StringNew* curr) {
  shouldBeTrue(!getModule() || getModule()->features.hasStrings(),
               curr,
               "string operations require strings [--enable-strings]");

  switch (curr->op) {
    case StringNewLossyUTF8Array:
    case StringNewWTF16Array: {
      auto refType = curr->ref->type;
      if (refType == Type::unreachable) {
        return;
      }
      if (!shouldBeTrue(
            refType.isRef(), curr, "string.new input must have array type")) {
        return;
      }
      if (curr->op == StringNewLossyUTF8Array) {
        shouldBeSubType(
          refType,
          Type(HeapTypes::getMutI8Array(), Nullable),
          curr,
          "string.new_lossy_utf8_array input must have proper i8 array type");
      } else {
        assert(curr->op == StringNewWTF16Array);
        shouldBeSubType(
          refType,
          Type(HeapTypes::getMutI16Array(), Nullable),
          curr,
          "string.new_wtf16_array input must have proper i16 array type");
      }
      shouldBeEqualOrFirstIsUnreachable(curr->start->type,
                                        Type(Type::i32),
                                        curr,
                                        "string.new start must be i32");
      shouldBeEqualOrFirstIsUnreachable(
        curr->end->type, Type(Type::i32), curr, "string.new end must be i32");
      return;
    }
    case StringNewFromCodePoint:
      shouldBeEqualOrFirstIsUnreachable(
        curr->ref->type,
        Type(Type::i32),
        curr,
        "string.from_code_point code point must be i32");
      shouldBeTrue(
        !curr->start, curr, "string.from_code_point should not have start");
      shouldBeTrue(
        !curr->end, curr, "string.from_code_point should not have end");
      return;
  }
  WASM_UNREACHABLE("unexpected op");
}

void FunctionValidator::visitStringConst(StringConst* curr) {
  shouldBeTrue(!getModule() || getModule()->features.hasStrings(),
               curr,
               "string operations require strings [--enable-strings]");
}

void FunctionValidator::visitStringMeasure(StringMeasure* curr) {
  shouldBeTrue(!getModule() || getModule()->features.hasStrings(),
               curr,
               "string operations require strings [--enable-strings]");
}

void FunctionValidator::visitStringEncode(StringEncode* curr) {
  shouldBeTrue(!getModule() || getModule()->features.hasStrings(),
               curr,
               "string operations require strings [--enable-strings]");
  shouldBeSubTypeIgnoringShared(curr->str->type,
                                Type(HeapType::ext, Nullable),
                                curr,
                                "string.encode input should be an externref");
  switch (curr->op) {
    case StringEncodeLossyUTF8Array:
      shouldBeSubType(
        curr->array->type,
        Type(HeapTypes::getMutI8Array(), Nullable),
        curr,
        "string.encode_lossy_utf8_array should have mutable i8 array");
      break;
    case StringEncodeWTF16Array: {
      shouldBeSubType(
        curr->array->type,
        Type(HeapTypes::getMutI16Array(), Nullable),
        curr,
        "string.encode_wtf16_array should have mutable i16 array");
      break;
    }
  }
  shouldBeSubType(curr->start->type,
                  Type(Type::i32),
                  curr,
                  "string.encode start should be an i32");
}

void FunctionValidator::visitStringConcat(StringConcat* curr) {
  shouldBeTrue(!getModule() || getModule()->features.hasStrings(),
               curr,
               "string operations require strings [--enable-strings]");
}

void FunctionValidator::visitStringEq(StringEq* curr) {
  shouldBeTrue(!getModule() || getModule()->features.hasStrings(),
               curr,
               "string operations require strings [--enable-strings]");
}

void FunctionValidator::visitStringTest(StringTest* curr) {
  shouldBeTrue(!getModule() || getModule()->features.hasStrings(),
               curr,
               "string operations require strings [--enable-strings]");
}

void FunctionValidator::visitStringWTF16Get(StringWTF16Get* curr) {
  shouldBeTrue(!getModule() || getModule()->features.hasStrings(),
               curr,
               "string operations require strings [--enable-strings]");
}

void FunctionValidator::visitStringSliceWTF(StringSliceWTF* curr) {
  shouldBeTrue(!getModule() || getModule()->features.hasStrings(),
               curr,
               "string operations require strings [--enable-strings]");
}

void FunctionValidator::visitContNew(ContNew* curr) {
  shouldBeTrue(!getModule() || getModule()->features.hasStackSwitching(),
               curr,
               "cont.new requires stack-switching [--enable-stack-switching]");

  if (curr->type == Type::unreachable) {
    return;
  }

  if (!shouldBeTrue(curr->type.isNonNullable(),
                    curr,
                    "cont.new should have a non-nullable reference type")) {
    return;
  }
  shouldBeTrue(curr->type.isExact(), curr, "cont.new should be exact");

  if (!shouldBeTrue(curr->type.isRef() &&
                      curr->type.getHeapType().isContinuation(),
                    curr,
                    "cont.new must be annotated with a continuation type")) {
    return;
  }

  auto cont = curr->type.getHeapType().getContinuation();
  assert(cont.type.isSignature());

  shouldBeTrue(curr->func->type.isRef() &&
                 HeapType::isSubType(curr->func->type.getHeapType(), cont.type),
               curr,
               "cont.new function reference must be a subtype");
}

void FunctionValidator::visitContBind(ContBind* curr) {
  if (!shouldBeTrue(
        !getModule() || getModule()->features.hasStackSwitching(),
        curr,
        "cont.bind requires stack-switching [--enable-stack-switching]")) {
    return;
  }

  if (curr->cont->type == Type::unreachable ||
      curr->type == Type::unreachable) {
    return;
  }

  if (!shouldBeTrue(
        curr->cont->type.isRef(), curr, "the input type must be a reference")) {
    return;
  }
  auto inType = curr->cont->type.getHeapType();

  if (!shouldBeTrue(inType.isMaybeShared(HeapType::nocont) ||
                      inType.isContinuation(),
                    curr,
                    "the input type must be a continuation type")) {
    return;
  }

  if (!shouldBeTrue(
        curr->type.isRef() && curr->type.isNonNullable() &&
          curr->type.isExact(),
        curr,
        "the output type must be a non-nullable, exact reference")) {
    return;
  }
  auto outType = curr->type.getHeapType();

  if (!shouldBeTrue(outType.isContinuation(),
                    curr,
                    "the output type must be a continuation type")) {
    return;
  }

  if (inType.isBottom()) {
    return;
  }

  auto sigIn = inType.getContinuation().type.getSignature();
  auto sigOut = outType.getContinuation().type.getSignature();

  if (!shouldBeTrue(curr->operands.size() <= sigIn.params.size(),
                    curr,
                    "too many arguments for cont.bind")) {
    return;
  }

  size_t numBound = curr->operands.size();
  size_t numRemaining = sigIn.params.size() - numBound;

  if (!shouldBeEqual(numRemaining,
                     sigOut.params.size(),
                     curr,
                     "result continuation parameter count mismatch")) {
    return;
  }

  for (size_t i = 0; i < numBound; ++i) {
    if (!shouldBeSubType(curr->operands[i]->type,
                         sigIn.params[i],
                         curr,
                         "cont.bind argument type mismatch")) {
      if (!info.quiet) {
        getStream() << "(at index " << i << ")\n";
      }
    }
  }

  for (size_t i = 0; i < numRemaining; ++i) {
    if (!shouldBeSubType(sigOut.params[i],
                         sigIn.params[numBound + i],
                         curr,
                         "result continuation parameter type mismatch")) {
      if (!info.quiet) {
        getStream() << "(at index " << i << ")\n";
      }
    }
  }

  shouldBeSubType(sigIn.results,
                  sigOut.results,
                  curr,
                  "result continuation result type mismatch");
}

void FunctionValidator::visitSuspend(Suspend* curr) {
  if (!shouldBeTrue(
        !getModule() || getModule()->features.hasStackSwitching(),
        curr,
        "suspend requires stack-switching [--enable-stack-switching]")) {
    return;
  }

  auto* tag = getModule()->getTagOrNull(curr->tag);
  if (!shouldBeTrue(!!tag, curr, "suspend tag must exist")) {
    return;
  }

  auto sig = tag->type.getSignature();
  if (!shouldBeTrue(curr->operands.size() == sig.params.size(),
                    curr,
                    "suspend argument count mismatch")) {
    return;
  }

  for (size_t i = 0; i < sig.params.size(); ++i) {
    if (!shouldBeSubType(curr->operands[i]->type,
                         sig.params[i],
                         curr,
                         "suspend argument type mismatch")) {
      if (!info.quiet) {
        getStream() << "(at index " << i << ")\n";
      }
    }
  }

  shouldBeEqualOrFirstIsUnreachable(
    curr->type, sig.results, curr, "suspend result type mismatch");
}

void FunctionValidator::validateResumeHandlers(
  Expression* curr,
  Type contResults,
  const ArenaVector<Name>& tags,
  const ArenaVector<Name>& labels) {
  for (size_t i = 0; i < tags.size(); ++i) {
    auto* tag = getModule()->getTagOrNull(tags[i]);
    if (!shouldBeTrue(!!tag, curr, "resume handler tag must exist")) {
      continue;
    }
    auto tagSig = tag->type.getSignature();

    if (labels[i]) {
      // (on $tag $label)
      // label must accept [t1_tag* (ref $ct_handler)]
      // and $ct_handler must be cont [t2_tag*] -> [sig.results]
      // But we cannot check this here because we do not know what type the
      // block named $label expects. Save the tag to check when we visit the
      // block later.
      if (!shouldBeTrue(breakTypes.contains(labels[i]),
                        curr,
                        "all resume targets must be valid")) {
        return;
      }
      resumeInfos[labels[i]].push_back({curr, tag, contResults});
    } else {
      // (on $tag switch)
      // tag must be [] -> [t*] where t* are the continuation results.
      if (shouldBeTrue(tagSig.params.size() == 0,
                       curr,
                       "switch handler tag must have no parameters")) {
        // NB: Intentionally not checking subtypes here.
        shouldBeEqual(tagSig.results,
                      contResults,
                      curr,
                      "switch handler tag results mismatch");
      }
    }
  }
}

void FunctionValidator::visitResume(Resume* curr) {
  if (!shouldBeTrue(
        !getModule() || getModule()->features.hasStackSwitching(),
        curr,
        "resume requires stack-switching [--enable-stack-switching]")) {
    return;
  }

  if (curr->cont->type == Type::unreachable) {
    return;
  }

  if (!shouldBeTrue(curr->cont->type.isRef(),
                    curr,
                    "resume continuation must be a reference")) {
    return;
  }

  auto type = curr->cont->type.getHeapType();
  if (type.isMaybeShared(HeapType::nocont)) {
    return;
  }

  if (!shouldBeTrue(
        type.isContinuation(),
        curr,
        "resume continuation must have a defined continuation type")) {
    return;
  }

  auto sig = type.getContinuation().type.getSignature();

  if (!shouldBeTrue(curr->operands.size() == sig.params.size(),
                    curr,
                    "resume argument count mismatch")) {
    return;
  }

  for (Index i = 0; i < sig.params.size(); ++i) {
    if (!shouldBeSubType(curr->operands[i]->type,
                         sig.params[i],
                         curr,
                         "resume argument type mismatch")) {
      if (!info.quiet) {
        getStream() << "(at index " << i << ")\n";
      }
    }
  }

  shouldBeEqualOrFirstIsUnreachable(
    curr->type, sig.results, curr, "resume result type mismatch");

  validateResumeHandlers(
    curr, sig.results, curr->handlerTags, curr->handlerBlocks);
}

void FunctionValidator::visitResumeThrow(ResumeThrow* curr) {
  if (!shouldBeTrue(!getModule() ||
                      (getModule()->features.hasExceptionHandling() &&
                       getModule()->features.hasStackSwitching()),
                    curr,
                    "resume_throw requires exception handling "
                    "[--enable-exception-handling] and stack-switching "
                    "[--enable-stack-switching]")) {
    return;
  }

  if (curr->cont->type == Type::unreachable) {
    return;
  }

  if (!shouldBeTrue(curr->cont->type.isRef(),
                    curr,
                    "resume_throw continuation must be a reference")) {
    return;
  }

  auto type = curr->cont->type.getHeapType();
  if (type.isMaybeShared(HeapType::nocont)) {
    return;
  }

  if (!shouldBeTrue(
        type.isContinuation(),
        curr,
        "resume_throw continuation must have a defined continuation type")) {
    return;
  }

  if (curr->tag) {
    // Normal resume_throw
    auto* tag = getModule()->getTagOrNull(curr->tag);
    if (!shouldBeTrue(!!tag, curr, "resume_throw exception tag must exist")) {
      return;
    }
    if (!shouldBeTrue(tag->type.getSignature().results == Type::none,
                      curr,
                      "resume_throw tag must have no results")) {
      return;
    }
    if (!shouldBeTrue(curr->operands.size() ==
                        tag->type.getSignature().params.size(),
                      curr,
                      "resume_throw operand count mismatch")) {
      return;
    }
    for (size_t i = 0; i < tag->type.getSignature().params.size(); ++i) {
      if (!shouldBeSubType(curr->operands[i]->type,
                           tag->type.getSignature().params[i],
                           curr,
                           "resume_throw operand type mismatch")) {
        if (!info.quiet) {
          getStream() << "(at index " << i << ")\n";
        }
      }
    }
  } else {
    // resume_throw_ref
    Type exnref = Type(HeapType::exn, Nullable);
    if (shouldBeEqual(curr->operands.size(),
                      size_t(1),
                      curr,
                      "resume_throw_ref must have a single exnref operand")) {
      shouldBeSubType(curr->operands[0]->type,
                      exnref,
                      curr,
                      "resume_throw_ref must receive exnref");
    }
  }

  auto sig = type.getContinuation().type.getSignature();

  shouldBeEqualOrFirstIsUnreachable(
    curr->type, sig.results, curr, "resume_throw result type mismatch");

  validateResumeHandlers(
    curr, sig.results, curr->handlerTags, curr->handlerBlocks);
}

void FunctionValidator::visitStackSwitch(StackSwitch* curr) {
  if (!shouldBeTrue(
        !getModule() || getModule()->features.hasStackSwitching(),
        curr,
        "switch requires stack-switching [--enable-stack-switching]")) {
    return;
  }

  auto* tag = getModule()->getTagOrNull(curr->tag);
  if (!shouldBeTrue(!!tag, curr, "switch tag must exist")) {
    return;
  }

  if (curr->cont->type == Type::unreachable) {
    return;
  }

  if (!shouldBeTrue(curr->cont->type.isRef(),
                    curr,
                    "switch continuation must be a reference")) {
    return;
  }

  auto type = curr->cont->type.getHeapType();
  if (type.isMaybeShared(HeapType::nocont)) {
    return;
  }

  if (!shouldBeTrue(
        type.isContinuation(),
        curr,
        "switch continuation must have a defined continuation type")) {
    return;
  }

  auto sig1 = type.getContinuation().type.getSignature();

  // sig1 should be [t1* (ref null $ct2)] -> [te1*]
  if (!shouldBeTrue(sig1.params.size() >= 1,
                    curr,
                    "switch continuation must have at least one parameter (for "
                    "the next continuation)")) {
    return;
  }

  Type ct2Type = sig1.params[sig1.params.size() - 1];
  if (!shouldBeTrue(
        ct2Type.isContinuation(),
        curr,
        "the last parameter of the switch continuation must be a continuation "
        "type")) {
    return;
  }

  auto sig2 = ct2Type.getHeapType().getContinuation().type.getSignature();

  // check operands (t1*)
  size_t numT1 = sig1.params.size() - 1;
  if (!shouldBeTrue(curr->operands.size() == numT1,
                    curr,
                    "switch argument count mismatch")) {
    return;
  }
  for (size_t i = 0; i < numT1; ++i) {
    if (!shouldBeSubType(curr->operands[i]->type,
                         sig1.params[i],
                         curr,
                         "switch argument type mismatch")) {
      if (!info.quiet) {
        getStream() << "(at index " << i << ")\n";
      }
    }
  }

  auto tagSig = tag->type.getSignature();
  if (!shouldBeTrue(tagSig.params.size() == 0,
                    curr,
                    "switch tag must have no parameters")) {
    return;
  }

  // te1* <: t*
  shouldBeSubType(sig1.results,
                  tagSig.results,
                  curr,
                  "switch continuation result type mismatch");

  // t* <: te2*
  shouldBeSubType(
    tagSig.results, sig2.results, curr, "switch tag result type mismatch");

  // curr->type == t2*
  // NB: Intentionally not doing a subtype check here.
  shouldBeEqualOrFirstIsUnreachable(
    curr->type, sig2.params, curr, "switch result type mismatch");
}

void FunctionValidator::visitFunction(Function* curr) {
  FeatureSet features;
  // Check for things like having a rec group with GC enabled. The type we're
  // checking is a reference type even if this an MVP function type, so ignore
  // the reference types feature here.
  features |= (curr->type.getFeatures() & ~FeatureSet::ReferenceTypes);
  for (const auto& param : curr->getParams()) {
    features |= param.getFeatures();
    shouldBeTrue(param.isConcrete(), curr, "params must be concretely typed");
  }
  for (const auto& result : curr->getResults()) {
    features |= result.getFeatures();
    shouldBeTrue(result.isConcrete(), curr, "results must be concretely typed");
  }
  for (const auto& var : curr->vars) {
    features |= var.getFeatures();
  }
  shouldBeTrue(features.isSubsetOf(getModule()->features),
               curr->name,
               "all used types should be allowed");

  if (curr->imported()) {
    shouldBeTrue(
      curr->type.isInexact() || getModule()->features.hasCustomDescriptors(),
      curr->name,
      "exact imports require custom descriptors [--enable-custom-descriptors]");
  } else {
    shouldBeTrue(
      curr->type.isExact(), curr->name, "defined function should be exact");
  }

  // validate optional local names
  std::unordered_set<Name> seen;
  for (auto& pair : curr->localNames) {
    Name name = pair.second;
    shouldBeTrue(seen.insert(name).second, name, "local names must be unique");
  }

  if (curr->body) {
    if (curr->getResults().isTuple()) {
      shouldBeTrue(getModule()->features.hasMultivalue(),
                   curr->body,
                   "Multivalue function results (multivalue is not enabled)");
    }
    if (curr->profile == IRProfile::Poppy) {
      shouldBeTrue(
        curr->body->is<Block>(), curr->body, "Function body must be a block");
    }
    // if function has no result, it is ignored
    // if body is unreachable, it might be e.g. a return
    shouldBeSubType(curr->body->type,
                    curr->getResults(),
                    curr->body,
                    "function body type must match, if function returns");

    if (getModule()->features.hasGC()) {
      // If we have non-nullable locals, verify that local.get are valid.
      LocalStructuralDominance info(curr, *getModule());
      for (auto index : info.nonDominatingIndices) {
        auto localType = curr->getLocalType(index);
        for (auto type : localType) {
          shouldBeTrue(!type.isNonNullable(),
                       index,
                       "non-nullable local's sets must dominate gets");
        }
      }
    }

    // Assert that we finished with a clean state after processing the body's
    // expressions, and reset the state for next time. Note that we use some of
    // this state in the above validations, so this must appear last.
    assert(breakTypes.empty());
    assert(resumeInfos.empty());
    assert(delegateTargetNames.empty());
    assert(rethrowTargetNames.empty());
    labelNames.clear();
  }
}

void FunctionValidator::validateOffset(Address offset,
                                       Memory* mem,
                                       Expression* curr) {
  shouldBeTrue(mem->is64() || offset <= std::numeric_limits<uint32_t>::max(),
               curr,
               "offset must be u32");
}

void FunctionValidator::validateAlignment(
  size_t align, Type type, Index bytes, bool isAtomic, Expression* curr) {
  if (isAtomic) {
    shouldBeEqual(align,
                  (size_t)bytes,
                  curr,
                  "atomic accesses must have natural alignment");
    return;
  }
  switch (align) {
    case 1:
    case 2:
    case 4:
    case 8:
    case 16:
      break;
    default: {
      info.fail("bad alignment: " + std::to_string(align), curr, getFunction());
      break;
    }
  }
  shouldBeTrue(align <= bytes, curr, "alignment must not exceed natural");
  TODO_SINGLE_COMPOUND(type);
  switch (type.getBasic()) {
    case Type::i32:
    case Type::f32: {
      shouldBeTrue(align <= 4, curr, "alignment must not exceed natural");
      break;
    }
    case Type::i64:
    case Type::f64: {
      shouldBeTrue(align <= 8, curr, "alignment must not exceed natural");
      break;
    }
    case Type::v128:
    case Type::unreachable:
      break;
    case Type::none:
      WASM_UNREACHABLE("invalid type");
  }
}

void validateBinaryenIR(Module& wasm, ValidationInfo& info) {
  struct BinaryenIRValidator
    : public PostWalker<BinaryenIRValidator,
                        UnifiedExpressionVisitor<BinaryenIRValidator>> {
    ValidationInfo& info;

    std::unordered_set<Expression*> seen;

    BinaryenIRValidator(ValidationInfo& info) : info(info) {}

    void visitExpression(Expression* curr) {
      auto scope = getFunction() ? getFunction()->name : Name("(global scope)");
      // check if a node type is 'stale', i.e., we forgot to finalize() the
      // node.
      auto oldType = curr->type;
      ReFinalizeNode().visit(curr);
      auto newType = curr->type;
      // It's ok for control flow structures to be further refinable, but all
      // other instructions must have the most-precise possible types.
      if (oldType != newType && !(Properties::isControlFlowStructure(curr) &&
                                  Type::isSubType(newType, oldType))) {
        std::ostringstream ss;
        ss << "stale type found in " << scope << " on " << curr
           << "\n(marked as " << oldType << ", should be " << newType << ")\n";
        info.fail(ss.str(), curr, getFunction());
      }
      curr->type = oldType;
      // check if a node is a duplicate - expressions must not be seen more than
      // once
      if (!seen.insert(curr).second) {
        std::ostringstream ss;
        ss << "expression seen more than once in the tree in " << scope
           << " on " << curr << '\n';
        info.fail(ss.str(), curr, getFunction());
      }
    }
  };
  BinaryenIRValidator binaryenIRValidator(info);
  binaryenIRValidator.walkModule(&wasm);
}

// Main validator class

void validateTypes(Module& module, ValidationInfo& info) {
  // Most validations belong in `validateTypeInfo` in wasm-type.cpp.
  validateExactReferences(module, info);
}

void validateImports(Module& module, ValidationInfo& info) {
  ModuleUtils::iterImportedFunctions(module, [&](Function* curr) {
    if (curr->getResults().isTuple()) {
      info.shouldBeTrue(module.features.hasMultivalue(),
                        curr->name,
                        "Imported multivalue function requires multivalue "
                        "[--enable-multivalue]");
    }
    if (info.validateWeb) {
      for (const auto& param : curr->getParams()) {
        info.shouldBeUnequal(param,
                             Type(Type::i64),
                             curr->name,
                             "Imported function must not have i64 parameters");
      }
      for (const auto& result : curr->getResults()) {
        info.shouldBeUnequal(result,
                             Type(Type::i64),
                             curr->name,
                             "Imported function must not have i64 results");
      }
    }

    if (Intrinsics(module).isCallWithoutEffects(curr)) {
      auto lastParam = curr->getParams();
      if (lastParam.isTuple()) {
        lastParam = lastParam.getTuple().back();
      }
      info.shouldBeTrue(lastParam.isFunction(),
                        curr->name,
                        "call.if.used's last param must be a function");
    }
  });
  ModuleUtils::iterImportedGlobals(module, [&](Global* curr) {
    if (!module.features.hasMutableGlobals()) {
      info.shouldBeFalse(curr->mutable_,
                         curr->name,
                         "Imported mutable global requires mutable-globals "
                         "[--enable-mutable-globals]");
    }
    info.shouldBeFalse(
      curr->type.isTuple(), curr->name, "Imported global cannot be tuple");
  });
}

void validateExports(Module& module, ValidationInfo& info) {
  for (auto& curr : module.exports) {
    if (curr->kind == ExternalKind::Function) {
      if (info.validateWeb) {
        Function* f = module.getFunction(*curr->getInternalName());
        for (const auto& param : f->getParams()) {
          info.shouldBeUnequal(
            param,
            Type(Type::i64),
            f->name,
            "Exported function must not have i64 parameters");
        }
        for (const auto& result : f->getResults()) {
          info.shouldBeUnequal(result,
                               Type(Type::i64),
                               f->name,
                               "Exported function must not have i64 results");
        }
      }
    } else if (curr->kind == ExternalKind::Global) {
      if (Global* g = module.getGlobalOrNull(*curr->getInternalName())) {
        if (!module.features.hasMutableGlobals()) {
          info.shouldBeFalse(g->mutable_,
                             g->name,
                             "Exported mutable global requires mutable-globals "
                             "[--enable-mutable-globals]");
        }
        info.shouldBeFalse(
          g->type.isTuple(), g->name, "Exported global cannot be tuple");
      }
    }
  }
  std::unordered_set<Name> exportNames;
  for (auto& exp : module.exports) {
    if (exp->kind == ExternalKind::Function) {
      Name name = *exp->getInternalName();
      info.shouldBeTrue(module.getFunctionOrNull(name),
                        name,
                        "module function exports must be found");
    } else if (exp->kind == ExternalKind::Global) {
      Name name = *exp->getInternalName();
      info.shouldBeTrue(module.getGlobalOrNull(name),
                        name,
                        "module global exports must be found");
    } else if (exp->kind == ExternalKind::Table) {
      Name name = *exp->getInternalName();
      info.shouldBeTrue(module.getTableOrNull(name),
                        name,
                        "module table exports must be found");
    } else if (exp->kind == ExternalKind::Memory) {
      Name name = *exp->getInternalName();
      info.shouldBeTrue(module.getMemoryOrNull(name),
                        name,
                        "module memory exports must be found");
    } else if (exp->kind == ExternalKind::Tag) {
      Name name = *exp->getInternalName();
      info.shouldBeTrue(
        module.getTagOrNull(name), name, "module tag exports must be found");
    } else {
      WASM_UNREACHABLE("invalid ExternalKind");
    }
    Name exportName = exp->name;
    info.shouldBeFalse(exportNames.contains(exportName),
                       exportName,
                       "module exports must be unique");
    exportNames.insert(exportName);
  }
}

void validateGlobals(Module& module, ValidationInfo& info) {
  std::unordered_set<Global*> seen;
  ModuleUtils::iterDefinedGlobals(module, [&](Global* curr) {
    info.shouldBeTrue(curr->type.getFeatures().isSubsetOf(module.features),
                      curr->name,
                      "all used types should be allowed");
    info.shouldBeTrue(
      curr->init != nullptr, curr->name, "global init must be non-null");
    assert(curr->init);
    info.shouldBeTrue(GlobalUtils::canInitializeGlobal(module, curr->init),
                      curr->name,
                      "global init must be constant");

    if (!info.shouldBeSubType(curr->init->type,
                              curr->type,
                              curr->init,
                              "global init must have correct type") &&
        !info.quiet) {
      info.getStream(nullptr) << "(on global " << curr->name << ")\n";
    }
    FunctionValidator(module, &info).validate(curr->init);
    // If GC is enabled (which means globals can refer to other non-imported
    // globals), check that globals only refer to preceeding globals.
    if (module.features.hasGC() && curr->init) {
      for (auto* get : FindAll<GlobalGet>(curr->init).list) {
        auto* global = module.getGlobalOrNull(get->name);
        info.shouldBeTrue(
          global && (seen.contains(global) || global->imported()),
          curr->init,
          "global initializer should only refer to previous globals");
      }
      seen.insert(curr);
    }
  });

  // Check that globals have allowed types.
  for (auto& g : module.globals) {
    auto globalFeats = g->type.getFeatures();
    if (!info.shouldBeTrue(
          globalFeats.isSubsetOf(module.features), g->name, "")) {
      info.getStream(nullptr)
        << "global type requires additional features "
        << getMissingFeaturesList(module, globalFeats) << '\n';
    }
  }
}

void validateMemories(Module& module, ValidationInfo& info) {
  if (module.memories.size() > 1) {
    info.shouldBeTrue(
      module.features.hasMultiMemory(),
      "memory",
      "multiple memories require multimemory [--enable-multimemory]");
  }
  for (auto& memory : module.memories) {
    if (memory->hasMax()) {
      info.shouldBeFalse(
        memory->initial > memory->max, "memory", "memory max >= initial");
    }
    if (memory->is64()) {
      info.shouldBeTrue(module.features.hasMemory64(),
                        "memory",
                        "64-bit memories require memory64 [--enable-memory64]");
      // TODO: The custom pages sizes proposals do not mention a verification
      // method when the memory64 proposal is active simultaneously; the current
      // implementation is based on spectest.
      info.shouldBeTrue(memory->initial <= memory->maxSize64(),
                        "memory",
                        "initial memory must be <= 16EB");
      info.shouldBeTrue(!memory->hasMax() || memory->max <= memory->maxSize64(),
                        "memory",
                        "max memory must be <= 16EB, or unlimited");
    } else {
      info.shouldBeTrue(memory->initial <= memory->maxSize32(),
                        "memory",
                        "initial memory must be <= 4GB");
      info.shouldBeTrue(!memory->hasMax() || memory->max <= memory->maxSize32(),
                        "memory",
                        "max memory must be <= 4GB, or unlimited");
    }
    info.shouldBeTrue(!memory->shared || memory->hasMax(),
                      "memory",
                      "shared memory must have max size");
    if (memory->shared) {
      info.shouldBeTrue(module.features.hasAtomics(),
                        "memory",
                        "shared memory requires threads [--enable-threads]");
    }

    if (memory->pageSizeLog2 != Memory::kDefaultPageSizeLog2) {
      info.shouldBeTrue(
        module.features.hasCustomPageSizes(),
        "memory",
        "custom page sizes not enabled [--enable-custom-page-sizes]");
      info.shouldBeEqual(
        Address(memory->pageSizeLog2),
        Address(0),
        "memory",
        "custom page size must be 1 Byte or 65536 Bytes (64KiB)");
    }
  }
}

void validateDataSegments(Module& module, ValidationInfo& info) {
  for (auto& segment : module.dataSegments) {
    if (segment->isPassive) {
      info.shouldBeTrue(
        module.features.hasBulkMemory(),
        segment->offset,
        "nonzero segment flags require bulk memory [--enable-bulk-memory]");
      info.shouldBeEqual(segment->offset,
                         (Expression*)nullptr,
                         segment->offset,
                         "passive segment should not have an offset");
    } else {
      auto memory = module.getMemoryOrNull(segment->memory);
      if (!info.shouldBeTrue(memory != nullptr,
                             "segment",
                             "active segment must have a valid memory name")) {
        continue;
      }
      info.shouldBeEqual(segment->offset->type,
                         memory->addressType,
                         segment->offset,
                         "segment offset must match memory index type");
      info.shouldBeTrue(
        Properties::isValidConstantExpression(module, segment->offset),
        segment->offset,
        "memory segment offset must be constant");
      FunctionValidator(module, &info).validate(segment->offset);
    }
  }
}

void validateTables(Module& module, ValidationInfo& info) {
  FunctionValidator validator(module, &info);

  if (!module.features.hasReferenceTypes()) {
    info.shouldBeTrue(module.tables.size() <= 1,
                      "table",
                      "Only 1 table definition allowed in MVP (requires "
                      "--enable-reference-types)");
    if (!module.tables.empty()) {
      auto& table = module.tables.front();
      info.shouldBeTrue(table->type == Type(HeapType::func, Nullable),
                        "table",
                        "Only funcref is valid for table type (when reference "
                        "types are disabled)");
      for (auto& segment : module.elementSegments) {
        info.shouldBeTrue(segment->table == table->name,
                          "elem",
                          "all element segments should refer to a single table "
                          "in MVP.");
        for (auto* expr : segment->data) {
          info.shouldBeTrue(
            expr->is<RefFunc>(),
            expr,
            "all table elements must be non-null funcrefs in MVP.");
          validator.validate(expr);
        }
      }
    }
  }

  auto funcref = Type(HeapType::func, Nullable);
  for (auto& table : module.tables) {
    info.shouldBeTrue(table->initial <= table->max,
                      "table",
                      "size minimum must not be greater than maximum");
    if (table->type.isNonNullable()) {
      info.shouldBeTrue(module.features.hasGC(),
                        "table",
                        "tables must have a nullable type in MVP "
                        "(requires --enable-gc).");
    }
    if (!table->imported() && table->type.isNonNullable()) {
      info.shouldBeTrue(table->init,
                        "table",
                        "module-defined tables with non-nullable types require "
                        "an initializer expression");
    }
    if (table->init) {
      info.shouldBeTrue(module.features.hasGC(),
                        "table",
                        "tables cannot have an initializer expression in MVP "
                        "(requires --enable-gc).");
      info.shouldBeSubType(
        table->init->type,
        table->type,
        table->init,
        "init expression must be a subtype of the table type");
      info.shouldBeTrue(
        Properties::isValidConstantExpression(module, table->init),
        "table",
        "table initializer value must be constant");
      validator.validate(table->init);
      // Check that no module-defined globals are referenced.
      for (auto* get : FindAll<GlobalGet>(table->init).list) {
        auto* global = module.getGlobalOrNull(get->name);
        info.shouldBeTrue(
          global && global->imported(),
          table->init,
          "table initializer may not refer to module-defined globals");
      }
    }
    auto typeFeats = table->type.getFeatures();
    if (!info.shouldBeTrue(table->type == funcref ||
                             typeFeats.isSubsetOf(module.features),
                           "table",
                           "table type requires additional features ")) {
      info.getStream(nullptr)
        << getMissingFeaturesList(module, typeFeats) << '\n';
    }
    if (table->is64()) {
      info.shouldBeTrue(module.features.hasMemory64(),
                        "memory",
                        "64-bit tables require memory64 [--enable-memory64]");
    }
  }

  for (auto& segment : module.elementSegments) {
    info.shouldBeTrue(segment->type.isRef(),
                      "elem",
                      "element segment type must be of reference type.");
    auto typeFeats = segment->type.getFeatures();
    if (!info.shouldBeTrue(
          segment->type == funcref || typeFeats.isSubsetOf(module.features),
          "elem",
          "element segment type requires additional features ")) {
      info.getStream(nullptr)
        << getMissingFeaturesList(module, typeFeats) << '\n';
    }

    bool isPassive = !segment->table.is();
    if (isPassive) {
      info.shouldBeTrue(
        !segment->offset, "elem", "passive segment should not have an offset");
    } else {
      auto table = module.getTableOrNull(segment->table);
      info.shouldBeTrue(table != nullptr,
                        "elem",
                        "element segment must have a valid table name");
      info.shouldBeTrue(
        !!segment->offset, "elem", "table segment offset must have an offset");
      info.shouldBeEqual(segment->offset->type,
                         table->addressType,
                         segment->offset,
                         "element segment offset must match table index type");
      info.shouldBeTrue(
        Properties::isValidConstantExpression(module, segment->offset),
        segment->offset,
        "table segment offset must be constant");
      info.shouldBeTrue(
        Type::isSubType(segment->type, table->type),
        "elem",
        "element segment type must be a subtype of the table type");
      validator.validate(segment->offset);
    }
    for (auto* expr : segment->data) {
      info.shouldBeTrue(Properties::isValidConstantExpression(module, expr),
                        expr,
                        "element must be a constant expression");
      info.shouldBeSubType(expr->type,
                           segment->type,
                           expr,
                           "element must be a subtype of the segment type");
      validator.validate(expr);
    }
  }
}

void validateTags(Module& module, ValidationInfo& info) {
  if (!module.tags.empty()) {
    info.shouldBeTrue(
      module.features.hasExceptionHandling(),
      module.tags[0]->name,
      "Tags require exception-handling [--enable-exception-handling]");
  }
  for (auto& curr : module.tags) {
    if (curr->results() != Type::none) {
      info.shouldBeTrue(module.features.hasStackSwitching(),
                        curr->name,
                        "Tags with result types require stack switching "
                        "feature [--enable-stack-switching]");
    }
    if (curr->params().isTuple()) {
      info.shouldBeTrue(
        module.features.hasMultivalue(),
        curr->name,
        "Multivalue tag type requires multivalue [--enable-multivalue]");
    }
    FeatureSet features;
    for (const auto& param : curr->params()) {
      features |= param.getFeatures();
      info.shouldBeTrue(param.isConcrete(),
                        curr->name,
                        "Values in a tag should have concrete types");
    }
    info.shouldBeTrue(features.isSubsetOf(module.features),
                      curr->name,
                      "all param types in tags should be allowed");
  }
}

void validateStart(Module& module, ValidationInfo& info) {
  // start
  if (module.start.is()) {
    auto func = module.getFunctionOrNull(module.start);
    if (info.shouldBeTrue(
          func != nullptr, module.start, "start must be found")) {
      info.shouldBeTrue(func->getParams() == Type::none,
                        module.start,
                        "start must have 0 params");
      info.shouldBeTrue(func->getResults() == Type::none,
                        module.start,
                        "start must not return a value");
    }
  }
}

template<typename T, typename U>
void validateModuleMap(Module& module,
                       ValidationInfo& info,
                       T& list,
                       U getter,
                       const std::string& kind) {
  // Given a list of module elements (like exports or globals), see that we can
  // get the items using the getter (getExportorNull, etc.). The getter uses the
  // lookup map internally, so this validates that they contain all items in
  // the list.
  for (auto& item : list) {
    auto* ptr = (module.*getter)(item->name);
    if (!ptr) {
      info.fail(kind + " must be found (use updateMaps)", item->name, nullptr);
    } else {
      info.shouldBeEqual(item->name,
                         ptr->name,
                         item->name,
                         "getter must return the correct item");
    }
  }

  // TODO: Also check there is nothing extraneous in the map, but that would
  //       require inspecting private fields of Module.
}

void validateModuleMaps(Module& module, ValidationInfo& info) {
  // Module maps should be up to date.
  validateModuleMap(
    module, info, module.exports, &Module::getExportOrNull, "Export");
  validateModuleMap(
    module, info, module.functions, &Module::getFunctionOrNull, "Function");
  validateModuleMap(
    module, info, module.globals, &Module::getGlobalOrNull, "Global");
  validateModuleMap(module, info, module.tags, &Module::getTagOrNull, "Tag");
  validateModuleMap(module,
                    info,
                    module.elementSegments,
                    &Module::getElementSegmentOrNull,
                    "ElementSegment");
  validateModuleMap(
    module, info, module.memories, &Module::getMemoryOrNull, "Memory");
  validateModuleMap(module,
                    info,
                    module.dataSegments,
                    &Module::getDataSegmentOrNull,
                    "DataSegment");
  validateModuleMap(
    module, info, module.tables, &Module::getTableOrNull, "Table");
}

void validateFeatures(Module& module, ValidationInfo& info) {
  if (module.features.hasGC()) {
    info.shouldBeTrue(module.features.hasReferenceTypes(),
                      module.features,
                      "--enable-gc requires --enable-reference-types");
  }
}

} // namespace

// TODO: If we want the validator to be part of libwasm rather than libpasses,
// then Using PassRunner::getPassDebug causes a circular dependence. We should
// fix that, perhaps by moving some of the pass infrastructure into libsupport.
bool WasmValidator::validate(Module& module, Flags flags) {
  ValidationInfo info(module);
  info.validateWeb = (flags & Web) != 0;
  info.validateGlobally = (flags & Globally) != 0;
  info.quiet = (flags & Quiet) != 0;

  // Parallel function validation.
  PassRunner runner(&module);
  FunctionValidator functionValidator(module, &info);
  functionValidator.validate(&runner);

  // Also validate imports, which were not covered in the parallel traversal
  // since it is a function-parallel operation.
  for (auto& func : module.functions) {
    if (func->imported()) {
      functionValidator.visitFunction(func.get());
    }
  }

  // Validate globally.
  if (info.validateGlobally) {
    validateTypes(module, info);
    validateImports(module, info);
    validateExports(module, info);
    validateGlobals(module, info);
    validateMemories(module, info);
    validateDataSegments(module, info);
    validateTables(module, info);
    validateTags(module, info);
    validateStart(module, info);
    validateModuleMaps(module, info);
    validateFeatures(module, info);
  }

  // Validate additional internal IR details when in pass-debug mode.
  if (PassRunner::getPassDebug()) {
    validateBinaryenIR(module, info);
  }

  // Print all the data.
  if (!info.valid.load() && !info.quiet) {
    for (auto& func : module.functions) {
      std::cerr << info.getStream(func.get()).str();
    }
    std::cerr << info.getStream(nullptr).str();
  }
  return info.valid.load();
}

bool WasmValidator::validate(Module& module, const PassOptions& options) {
  return validate(module, options.validateGlobally ? Globally : Minimal);
}

bool WasmValidator::validate(Function* func, Module& module, Flags flags) {
  ValidationInfo info(module);
  info.validateWeb = (flags & Web) != 0;
  info.validateGlobally = (flags & Globally) != 0;
  info.quiet = (flags & Quiet) != 0;
  FunctionValidator(module, &info).validate(func);
  // print all the data
  if (!info.valid.load() && !info.quiet) {
    std::cerr << info.getStream(func).str();
    std::cerr << info.getStream(nullptr).str();
  }
  return info.valid.load();
}

} // namespace wasm
