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

#ifndef wasm_stack_h
#define wasm_stack_h

#include "ir/branch-utils.h"
#include "pass.h"
#include "wasm-binary.h"
#include "wasm-traversal.h"
#include "wasm.h"

namespace wasm {

// Stack IR: an IR that represents code at the wasm binary format level,
// that is, a stack machine. Binaryen IR is *almost* identical to this,
// but as documented in README.md, there are a few differences, intended
// to make Binaryen IR fast and flexible for maximal optimization. Stack
// IR, on the other hand, is designed to optimize a few final things that
// can only really be done when modeling the stack machine format precisely.

// Currently the benefits of Stack IR are minor, less than 1% reduction in
// code size. For that reason it is just a secondary IR, run optionally
// after the main IR has been optimized. However, if we improve Stack IR
// optimizations to a point where they have a significant impact, it's
// possible that could motivate investigating replacing the main IR with Stack
// IR (so that we have just a single IR).

// A StackIR instance (see wasm.h) contains a linear sequence of
// stack instructions. This representation is very simple: just a single vector
// of all instructions, in order.
//  * nullptr is allowed in the vector, representing something to skip.
//    This is useful as a common thing optimizations do is remove instructions,
//    so this way we can do so without compacting the vector all the time.

// Direct writing binaryen IR to binary is fast. Otherwise, StackIRGenerator
// lets you optimize the Stack IR before emitting stack IR to binary (but the
// cost is that the extra IR in the middle makes things 20% slower than emitting
// binaryen IR to binary directly).

// A Stack IR instruction. Most just directly reflect a Binaryen IR node,
// but we need extra ones for certain things.
class StackInst {
public:
  StackInst(MixedArena&) {}

  enum Op {
    Basic,      // an instruction directly corresponding to a non-control-flow
                // Binaryen IR node
    BlockBegin, // the beginning of a block
    BlockEnd,   // the ending of a block
    IfBegin,    // the beginning of a if
    IfElse,     // the else of a if
    IfEnd,      // the ending of a if
    LoopBegin,  // the beginning of a loop
    LoopEnd,    // the ending of a loop
    TryBegin,   // the beginning of a try
    Catch,      // the catch within a try
    TryEnd      // the ending of a try
  } op;

  Expression* origin; // the expression this originates from

  // the type - usually identical to the origin type, but e.g. wasm has no
  // unreachable blocks, they must be none
  Type type;
};

class BinaryInstWriter : public OverriddenVisitor<BinaryInstWriter> {
public:
  BinaryInstWriter(WasmBinaryWriter& parent,
                   BufferWithRandomAccess& o,
                   Function* func,
                   bool sourceMap)
    : parent(parent), o(o), func(func), sourceMap(sourceMap) {}

  void visit(Expression* curr) {
    if (func && !sourceMap) {
      parent.writeDebugLocation(curr, func);
    }
    OverriddenVisitor<BinaryInstWriter>::visit(curr);
    if (func && !sourceMap) {
      parent.writeDebugLocationEnd(curr, func);
    }
  }

  void visitBlock(Block* curr);
  void visitIf(If* curr);
  void visitLoop(Loop* curr);
  void visitBreak(Break* curr);
  void visitSwitch(Switch* curr);
  void visitCall(Call* curr);
  void visitCallIndirect(CallIndirect* 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 visitSIMDExtract(SIMDExtract* curr);
  void visitSIMDReplace(SIMDReplace* curr);
  void visitSIMDShuffle(SIMDShuffle* curr);
  void visitSIMDTernary(SIMDTernary* curr);
  void visitSIMDShift(SIMDShift* curr);
  void visitSIMDLoad(SIMDLoad* curr);
  void visitMemoryInit(MemoryInit* curr);
  void visitDataDrop(DataDrop* curr);
  void visitMemoryCopy(MemoryCopy* curr);
  void visitMemoryFill(MemoryFill* curr);
  void visitConst(Const* curr);
  void visitUnary(Unary* curr);
  void visitBinary(Binary* curr);
  void visitSelect(Select* curr);
  void visitReturn(Return* curr);
  void visitHost(Host* curr);
  void visitRefNull(RefNull* curr);
  void visitRefIsNull(RefIsNull* curr);
  void visitRefFunc(RefFunc* curr);
  void visitTry(Try* curr);
  void visitThrow(Throw* curr);
  void visitRethrow(Rethrow* curr);
  void visitBrOnExn(BrOnExn* curr);
  void visitNop(Nop* curr);
  void visitUnreachable(Unreachable* curr);
  void visitDrop(Drop* curr);
  void visitPush(Push* curr);
  void visitPop(Pop* curr);

  void emitIfElse(If* curr);
  void emitCatch(Try* curr);
  // emit an end at the end of a block/loop/if/try
  void emitScopeEnd(Expression* curr);
  // emit an end at the end of a function
  void emitFunctionEnd();
  void emitUnreachable();
  void mapLocalsAndEmitHeader();

private:
  void emitMemoryAccess(size_t alignment, size_t bytes, uint32_t offset);
  int32_t getBreakIndex(Name name);

  WasmBinaryWriter& parent;
  BufferWithRandomAccess& o;
  Function* func = nullptr;
  bool sourceMap;

  std::vector<Name> breakStack;

  // type => number of locals of that type in the compact form
  std::map<Type, size_t> numLocalsByType;
  // (local index, tuple index) => binary local index
  std::map<std::pair<Index, Index>, size_t> mappedLocals;
};

// Takes binaryen IR and converts it to something else (binary or stack IR)
template<typename SubType>
class BinaryenIRWriter : public OverriddenVisitor<BinaryenIRWriter<SubType>> {
public:
  BinaryenIRWriter(Function* func) : func(func) {}

  void write();

  // visits a node, emitting the proper code for it
  void visit(Expression* curr);

  void visitBlock(Block* curr);
  void visitIf(If* curr);
  void visitLoop(Loop* curr);
  void visitBreak(Break* curr);
  void visitSwitch(Switch* curr);
  void visitCall(Call* curr);
  void visitCallIndirect(CallIndirect* 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 visitSIMDExtract(SIMDExtract* curr);
  void visitSIMDReplace(SIMDReplace* curr);
  void visitSIMDShuffle(SIMDShuffle* curr);
  void visitSIMDTernary(SIMDTernary* curr);
  void visitSIMDShift(SIMDShift* curr);
  void visitSIMDLoad(SIMDLoad* curr);
  void visitMemoryInit(MemoryInit* curr);
  void visitDataDrop(DataDrop* curr);
  void visitMemoryCopy(MemoryCopy* curr);
  void visitMemoryFill(MemoryFill* curr);
  void visitConst(Const* curr);
  void visitUnary(Unary* curr);
  void visitBinary(Binary* curr);
  void visitSelect(Select* curr);
  void visitReturn(Return* curr);
  void visitHost(Host* curr);
  void visitRefNull(RefNull* curr);
  void visitRefIsNull(RefIsNull* curr);
  void visitRefFunc(RefFunc* curr);
  void visitTry(Try* curr);
  void visitThrow(Throw* curr);
  void visitRethrow(Rethrow* curr);
  void visitBrOnExn(BrOnExn* curr);
  void visitNop(Nop* curr);
  void visitUnreachable(Unreachable* curr);
  void visitDrop(Drop* curr);
  void visitPush(Push* curr);
  void visitPop(Pop* curr);

protected:
  Function* func = nullptr;

private:
  void emit(Expression* curr) { static_cast<SubType*>(this)->emit(curr); }
  void emitHeader() { static_cast<SubType*>(this)->emitHeader(); }
  void emitIfElse(If* curr) { static_cast<SubType*>(this)->emitIfElse(curr); }
  void emitCatch(Try* curr) { static_cast<SubType*>(this)->emitCatch(curr); }
  void emitScopeEnd(Expression* curr) {
    static_cast<SubType*>(this)->emitScopeEnd(curr);
  }
  void emitFunctionEnd() { static_cast<SubType*>(this)->emitFunctionEnd(); }
  void emitUnreachable() { static_cast<SubType*>(this)->emitUnreachable(); }
  void emitDebugLocation(Expression* curr) {
    static_cast<SubType*>(this)->emitDebugLocation(curr);
  }
  void visitPossibleBlockContents(Expression* curr);
};

template<typename SubType> void BinaryenIRWriter<SubType>::write() {
  assert(func && "BinaryenIRWriter: function is not set");
  emitHeader();
  visitPossibleBlockContents(func->body);
  emitFunctionEnd();
}

// emits a node, but if it is a block with no name, emit a list of its contents
template<typename SubType>
void BinaryenIRWriter<SubType>::visitPossibleBlockContents(Expression* curr) {
  auto* block = curr->dynCast<Block>();
  if (!block || BranchUtils::BranchSeeker::has(block, block->name)) {
    visit(curr);
    return;
  }
  for (auto* child : block->list) {
    visit(child);
  }
  if (block->type == Type::unreachable &&
      block->list.back()->type != Type::unreachable) {
    // similar to in visitBlock, here we could skip emitting the block itself,
    // but must still end the 'block' (the contents, really) with an unreachable
    emitUnreachable();
  }
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visit(Expression* curr) {
  emitDebugLocation(curr);
  OverriddenVisitor<BinaryenIRWriter>::visit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitBlock(Block* curr) {
  auto visitChildren = [this](Block* curr, Index from) {
    auto& list = curr->list;
    while (from < list.size()) {
      visit(list[from++]);
    }
  };

  auto afterChildren = [this](Block* curr) {
    if (curr->type == Type::unreachable) {
      // an unreachable block is one that cannot be exited. We cannot encode
      // this directly in wasm, where blocks must be none,i32,i64,f32,f64. Since
      // the block cannot be exited, we can emit an unreachable at the end, and
      // that will always be valid, and then the block is ok as a none
      emitUnreachable();
    }
    emitScopeEnd(curr);
    if (curr->type == Type::unreachable) {
      // and emit an unreachable *outside* the block too, so later things can
      // pop anything
      emitUnreachable();
    }
  };

  // Handle very deeply nested blocks in the first position efficiently,
  // avoiding heavy recursion. We only start to do this if we see it will help
  // us (to avoid allocation of the vector).
  if (!curr->list.empty() && curr->list[0]->is<Block>()) {
    std::vector<Block*> parents;
    Block* child;
    while (!curr->list.empty() && (child = curr->list[0]->dynCast<Block>())) {
      parents.push_back(curr);
      emit(curr);
      curr = child;
    }
    // Emit the current block, which does not have a block as a child in the
    // first position.
    emit(curr);
    visitChildren(curr, 0);
    afterChildren(curr);
    // Finish the later parts of all the parent blocks.
    while (!parents.empty()) {
      auto* parent = parents.back();
      parents.pop_back();
      visitChildren(parent, 1);
      afterChildren(parent);
    }
    return;
  }
  // Simple case of not having a nested block in the first position.
  emit(curr);
  visitChildren(curr, 0);
  afterChildren(curr);
}

template<typename SubType> void BinaryenIRWriter<SubType>::visitIf(If* curr) {
  visit(curr->condition);
  if (curr->condition->type == Type::unreachable) {
    // this if-else is unreachable because of the condition, i.e., the condition
    // does not exit. So don't emit the if (but do consume the condition)
    emitUnreachable();
    return;
  }
  emit(curr);
  visitPossibleBlockContents(curr->ifTrue);

  if (curr->ifFalse) {
    emitIfElse(curr);
    visitPossibleBlockContents(curr->ifFalse);
  }

  emitScopeEnd(curr);
  if (curr->type == Type::unreachable) {
    // we already handled the case of the condition being unreachable.
    // otherwise, we may still be unreachable, if we are an if-else with both
    // sides unreachable. wasm does not allow this to be emitted directly, so we
    // must do something more. we could do better, but for now we emit an extra
    // unreachable instruction after the if, so it is not consumed itself,
    assert(curr->ifFalse);
    emitUnreachable();
  }
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitLoop(Loop* curr) {
  emit(curr);
  visitPossibleBlockContents(curr->body);
  if (curr->type == Type::unreachable) {
    // we emitted a loop without a return type, and the body might be block
    // contents, so ensure it is not consumed
    emitUnreachable();
  }
  emitScopeEnd(curr);
  if (curr->type == Type::unreachable) {
    // we emitted a loop without a return type, so it must not be consumed
    emitUnreachable();
  }
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitBreak(Break* curr) {
  if (curr->value) {
    visit(curr->value);
  }
  if (curr->condition) {
    visit(curr->condition);
  }
  emit(curr);
  if (curr->condition && curr->type == Type::unreachable) {
    // a br_if is normally none or emits a value. if it is unreachable, then
    // either the condition or the value is unreachable, which is extremely
    // rare, and may require us to make the stack polymorphic (if the block we
    // branch to has a value, we may lack one as we are not a reachable branch;
    // the wasm spec on the other hand does presume the br_if emits a value of
    // the right type, even if it popped unreachable)
    emitUnreachable();
  }
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitSwitch(Switch* curr) {
  if (curr->value) {
    visit(curr->value);
  }
  visit(curr->condition);
  if (!BranchUtils::isBranchReachable(curr)) {
    // if the branch is not reachable, then it's dangerous to emit it, as wasm
    // type checking rules are different, especially in unreachable code. so
    // just don't emit that unreachable code.
    emitUnreachable();
    return;
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitCall(Call* curr) {
  for (auto* operand : curr->operands) {
    visit(operand);
  }

  // For non-control-flow value-returning instructions, if the type of an
  // expression is unreachable, we emit an unreachable and don't emit the
  // instruction itself. If we don't emit an unreachable, instructions that
  // follow can have a validation failure in wasm binary format. For example:
  // [unreachable] (f32.add
  // [unreachable]   (i32.eqz
  // [unreachable]     (unreachable)
  //                 )
  //                 ...
  //               )
  // This is a valid prgram in binaryen IR, because the unreachable type
  // propagates out of an expression, making both i32.eqz and f32.add
  // unreachable. But in binary format, this becomes:
  // unreachable
  // i32.eqz
  // f32.add       ;; validation failure; it takes an i32!
  // And here f32.add causes validation failure in wasm validation. So in this
  // case we add an unreachable to prevent following instructions to consume
  // the current value (here i32.eqz).
  //
  // The same applies for other expressions.
  if (curr->type == Type::unreachable && !curr->isReturn) {
    emitUnreachable();
    return;
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitCallIndirect(CallIndirect* curr) {
  for (auto* operand : curr->operands) {
    visit(operand);
  }
  visit(curr->target);
  if (curr->type == Type::unreachable && !curr->isReturn) {
    emitUnreachable();
    return;
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitLocalGet(LocalGet* curr) {
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitLocalSet(LocalSet* curr) {
  visit(curr->value);
  if (curr->isTee() && curr->type == Type::unreachable) {
    emitUnreachable();
    return;
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitGlobalGet(GlobalGet* curr) {
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitGlobalSet(GlobalSet* curr) {
  visit(curr->value);
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitLoad(Load* curr) {
  visit(curr->ptr);
  if (curr->type == Type::unreachable) {
    emitUnreachable();
    return;
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitStore(Store* curr) {
  visit(curr->ptr);
  visit(curr->value);
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitAtomicRMW(AtomicRMW* curr) {
  visit(curr->ptr);
  visit(curr->value);
  if (curr->type == Type::unreachable) {
    emitUnreachable();
    return;
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitAtomicCmpxchg(AtomicCmpxchg* curr) {
  visit(curr->ptr);
  visit(curr->expected);
  visit(curr->replacement);
  if (curr->type == Type::unreachable) {
    emitUnreachable();
    return;
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitAtomicWait(AtomicWait* curr) {
  visit(curr->ptr);
  visit(curr->expected);
  visit(curr->timeout);
  if (curr->type == Type::unreachable) {
    emitUnreachable();
    return;
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitAtomicNotify(AtomicNotify* curr) {
  visit(curr->ptr);
  visit(curr->notifyCount);
  if (curr->type == Type::unreachable) {
    emitUnreachable();
    return;
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitAtomicFence(AtomicFence* curr) {
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitSIMDExtract(SIMDExtract* curr) {
  visit(curr->vec);
  if (curr->type == Type::unreachable) {
    emitUnreachable();
    return;
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitSIMDReplace(SIMDReplace* curr) {
  visit(curr->vec);
  visit(curr->value);
  if (curr->type == Type::unreachable) {
    emitUnreachable();
    return;
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitSIMDShuffle(SIMDShuffle* curr) {
  visit(curr->left);
  visit(curr->right);
  if (curr->type == Type::unreachable) {
    emitUnreachable();
    return;
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitSIMDTernary(SIMDTernary* curr) {
  visit(curr->a);
  visit(curr->b);
  visit(curr->c);
  if (curr->type == Type::unreachable) {
    emitUnreachable();
    return;
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitSIMDShift(SIMDShift* curr) {
  visit(curr->vec);
  visit(curr->shift);
  if (curr->type == Type::unreachable) {
    emitUnreachable();
    return;
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitSIMDLoad(SIMDLoad* curr) {
  visit(curr->ptr);
  if (curr->type == Type::unreachable) {
    emitUnreachable();
    return;
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitMemoryInit(MemoryInit* curr) {
  visit(curr->dest);
  visit(curr->offset);
  visit(curr->size);
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitDataDrop(DataDrop* curr) {
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitMemoryCopy(MemoryCopy* curr) {
  visit(curr->dest);
  visit(curr->source);
  visit(curr->size);
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitMemoryFill(MemoryFill* curr) {
  visit(curr->dest);
  visit(curr->value);
  visit(curr->size);
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitConst(Const* curr) {
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitUnary(Unary* curr) {
  visit(curr->value);
  if (curr->type == Type::unreachable) {
    emitUnreachable();
    return;
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitBinary(Binary* curr) {
  visit(curr->left);
  visit(curr->right);
  if (curr->type == Type::unreachable) {
    emitUnreachable();
    return;
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitSelect(Select* curr) {
  visit(curr->ifTrue);
  visit(curr->ifFalse);
  visit(curr->condition);
  if (curr->type == Type::unreachable) {
    emitUnreachable();
    return;
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitReturn(Return* curr) {
  if (curr->value) {
    visit(curr->value);
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitHost(Host* curr) {
  switch (curr->op) {
    case MemorySize: {
      break;
    }
    case MemoryGrow: {
      visit(curr->operands[0]);
      break;
    }
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitRefNull(RefNull* curr) {
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitRefIsNull(RefIsNull* curr) {
  visit(curr->value);
  if (curr->type == Type::unreachable) {
    emitUnreachable();
    return;
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitRefFunc(RefFunc* curr) {
  if (curr->type == Type::unreachable) {
    emitUnreachable();
    return;
  }
  emit(curr);
}

template<typename SubType> void BinaryenIRWriter<SubType>::visitTry(Try* curr) {
  emit(curr);
  visitPossibleBlockContents(curr->body);
  emitCatch(curr);
  visitPossibleBlockContents(curr->catchBody);
  emitScopeEnd(curr);
  if (curr->type == Type::unreachable) {
    emitUnreachable();
  }
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitThrow(Throw* curr) {
  for (auto* operand : curr->operands) {
    visit(operand);
  }
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitRethrow(Rethrow* curr) {
  visit(curr->exnref);
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitBrOnExn(BrOnExn* curr) {
  visit(curr->exnref);
  emit(curr);
  if (curr->type == Type::unreachable) {
    emitUnreachable();
  }
}

template<typename SubType> void BinaryenIRWriter<SubType>::visitNop(Nop* curr) {
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitUnreachable(Unreachable* curr) {
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitDrop(Drop* curr) {
  visit(curr->value);
  emit(curr);
}

template<typename SubType>
void BinaryenIRWriter<SubType>::visitPush(Push* curr) {
  visit(curr->value);
  emit(curr);
}

template<typename SubType> void BinaryenIRWriter<SubType>::visitPop(Pop* curr) {
  emit(curr);
}

// Binaryen IR to binary writer
class BinaryenIRToBinaryWriter
  : public BinaryenIRWriter<BinaryenIRToBinaryWriter> {
public:
  BinaryenIRToBinaryWriter(WasmBinaryWriter& parent,
                           BufferWithRandomAccess& o,
                           Function* func = nullptr,
                           bool sourceMap = false)
    : BinaryenIRWriter<BinaryenIRToBinaryWriter>(func), parent(parent),
      writer(parent, o, func, sourceMap), sourceMap(sourceMap) {}

  void visit(Expression* curr) {
    BinaryenIRWriter<BinaryenIRToBinaryWriter>::visit(curr);
  }

  void emit(Expression* curr) { writer.visit(curr); }
  void emitHeader() {
    if (func->prologLocation.size()) {
      parent.writeDebugLocation(*func->prologLocation.begin());
    }
    writer.mapLocalsAndEmitHeader();
  }
  void emitIfElse(If* curr) { writer.emitIfElse(curr); }
  void emitCatch(Try* curr) { writer.emitCatch(curr); }
  void emitScopeEnd(Expression* curr) { writer.emitScopeEnd(curr); }
  void emitFunctionEnd() {
    if (func->epilogLocation.size()) {
      parent.writeDebugLocation(*func->epilogLocation.begin());
    }
    writer.emitFunctionEnd();
  }
  void emitUnreachable() { writer.emitUnreachable(); }
  void emitDebugLocation(Expression* curr) {
    if (sourceMap) {
      parent.writeDebugLocation(curr, func);
    }
  }

private:
  WasmBinaryWriter& parent;
  BinaryInstWriter writer;
  bool sourceMap = false;
};

// Binaryen IR to stack IR converter
// Queues the expressions linearly in Stack IR (SIR)
class StackIRGenerator : public BinaryenIRWriter<StackIRGenerator> {
public:
  StackIRGenerator(MixedArena& allocator, Function* func)
    : BinaryenIRWriter<StackIRGenerator>(func), allocator(allocator) {}

  void emit(Expression* curr);
  void emitScopeEnd(Expression* curr);
  void emitHeader() {}
  void emitIfElse(If* curr) {
    stackIR.push_back(makeStackInst(StackInst::IfElse, curr));
  }
  void emitCatch(Try* curr) {
    stackIR.push_back(makeStackInst(StackInst::Catch, curr));
  }
  void emitFunctionEnd() {}
  void emitUnreachable() {
    stackIR.push_back(makeStackInst(Builder(allocator).makeUnreachable()));
  }
  void emitDebugLocation(Expression* curr) {}

  StackIR& getStackIR() { return stackIR; }

private:
  StackInst* makeStackInst(StackInst::Op op, Expression* origin);
  StackInst* makeStackInst(Expression* origin) {
    return makeStackInst(StackInst::Basic, origin);
  }

  MixedArena& allocator;
  StackIR stackIR; // filled in write()
};

// Stack IR to binary writer
class StackIRToBinaryWriter {
public:
  StackIRToBinaryWriter(WasmBinaryWriter& parent,
                        BufferWithRandomAccess& o,
                        Function* func)
    : writer(parent, o, func, false /* sourceMap */), func(func) {}

  void write();

private:
  BinaryInstWriter writer;
  Function* func;
};

} // namespace wasm

#endif // wasm_stack_h
