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

//
// WebAssembly-to-JS code translator. Converts wasm functions into
// valid JavaScript (with a somewhat asm.js-ish flavor).
//

#ifndef wasm_wasm2js_h
#define wasm_wasm2js_h

#include <cmath>
#include <numeric>

#include "abi/js.h"
#include "asm_v_wasm.h"
#include "asmjs/asmangle.h"
#include "asmjs/shared-constants.h"
#include "emscripten-optimizer/optimizer.h"
#include "ir/branch-utils.h"
#include "ir/effects.h"
#include "ir/element-utils.h"
#include "ir/find_all.h"
#include "ir/import-utils.h"
#include "ir/load-utils.h"
#include "ir/module-utils.h"
#include "ir/names.h"
#include "ir/table-utils.h"
#include "ir/utils.h"
#include "passes/passes.h"
#include "support/base64.h"
#include "support/file.h"
#include "wasm-builder.h"
#include "wasm-io.h"
#include "wasm-validator.h"
#include "wasm.h"

namespace wasm {

using namespace cashew;

static IString importObject("imports");

// Appends extra to block, flattening out if extra is a block as well
void flattenAppend(Ref ast, Ref extra) {
  int index;
  if (ast[0] == BLOCK || ast[0] == TOPLEVEL) {
    index = 1;
  } else if (ast[0] == DEFUN) {
    index = 3;
  } else {
    abort();
  }
  if (extra->isArray() && extra[0] == BLOCK) {
    for (size_t i = 0; i < extra[1]->size(); i++) {
      ast[index]->push_back(extra[1][i]);
    }
  } else {
    ast[index]->push_back(extra);
  }
}

// Appends extra to a chain of sequence elements
void sequenceAppend(Ref& ast, Ref extra) {
  if (!ast.get()) {
    ast = extra;
    return;
  }
  ast = ValueBuilder::makeSeq(ast, extra);
}

bool isTableExported(Module& wasm) {
  if (wasm.tables.empty() || wasm.tables[0]->imported()) {
    return false;
  }
  for (auto& ex : wasm.exports) {
    if (ex->kind == ExternalKind::Table &&
        *ex->getInternalName() == wasm.tables[0]->name) {
      return true;
    }
  }
  return false;
}

bool hasActiveSegments(Module& wasm) {
  for (Index i = 0; i < wasm.dataSegments.size(); i++) {
    if (!wasm.dataSegments[i]->isPassive) {
      return true;
    }
  }
  return false;
}

bool needsBufferView(Module& wasm) {
  if (wasm.memories.empty()) {
    return false;
  }

  // If there are any active segments, initActiveSegments needs access
  // to bufferView.
  if (hasActiveSegments(wasm)) {
    return true;
  }

  // The special support functions are emitted as part of the JS glue, if we
  // need them.
  bool need = false;
  ModuleUtils::iterImportedFunctions(wasm, [&](Function* import) {
    if (ABI::wasm2js::isHelper(import->base)) {
      need = true;
    }
  });
  return need;
}

IString stringToIString(std::string str) { return IString(str.c_str()); }

// Used when taking a wasm name and generating a JS identifier. Each scope here
// is used to ensure that all names have a unique name but the same wasm name
// within a scope always resolves to the same symbol.
//
// Export: Export names
// Top: The main scope which contains functions and globals
// Local: Local variables in a function.
// Label: Label identifiers in a function
enum class NameScope {
  Export,
  Top,
  Local,
  Label,
  Max,
};

//
// Wasm2JSBuilder - converts a WebAssembly module's functions into JS
//
// Wasm-to-JS is tricky because wasm doesn't distinguish
// statements and expressions, or in other words, things like `break` and `if`
// can show up in places where JS can't handle them, like inside an a loop's
// condition check. For that reason we use flat IR here.
// We do optimize it later, to allow some nesting, but we avoid
// non-JS-compatible nesting like block return values control flow in an if
// condition, etc.
//

class Wasm2JSBuilder {
public:
  struct Flags {
    // see wasm2js.cpp for details
    bool debug = false;
    bool pedantic = false;
    bool allowAsserts = false;
    bool emscripten = false;
    bool deterministic = false;
    std::string symbolsFile;
  };

  // Map data segment names to indices.
  std::unordered_map<Name, Index> dataIndices;

  Wasm2JSBuilder(Flags f, PassOptions options_) : flags(f), options(options_) {
    // We don't try to model wasm's trapping precisely - if we did, each load
    // and store would need to do a check. Given that, we can just ignore
    // implicit traps like those when optimizing. (When not optimizing, it's
    // nice to see codegen that matches wasm more precisely.)
    // It is also important to prevent the optimizer from adding new things that
    // require additional lowering, as we could hit a cycle.
    if (options.optimizeLevel > 0) {
      options.ignoreImplicitTraps = true;
      options.targetJS = true;
    }
  }

  Ref processWasm(Module* wasm, Name funcName = ASM_FUNC);
  Ref processFunction(Module* wasm, Function* func, bool standalone = false);
  Ref processStandaloneFunction(Module* wasm, Function* func) {
    return processFunction(wasm, func, true);
  }

  // The second pass on an expression: process it fully, generating
  // JS
  Ref processExpression(Expression* curr,
                        Module* m,
                        Function* func = nullptr,
                        bool standalone = false);

  Index getDataIndex(Name segment) {
    auto it = dataIndices.find(segment);
    assert(it != dataIndices.end());
    return it->second;
  }

  // Get a temp var.
  IString getTemp(Type type, Function* func) {
    IString ret;
    // TODO: handle tuples
    assert(!type.isTuple() && "Unexpected tuple type");
    if (frees[type].size() > 0) {
      ret = frees[type].back();
      frees[type].pop_back();
    } else {
      auto index = temps[type]++;
      ret = IString((std::string("wasm2js_") + type.toString() + "$" +
                     std::to_string(index))
                      .c_str());
      ret = fromName(ret, NameScope::Local);
    }
    if (func->localIndices.find(ret) == func->localIndices.end()) {
      Builder::addVar(func, ret, type);
    }
    return ret;
  }

  // Free a temp var.
  void freeTemp(Type type, IString temp) {
    // TODO: handle tuples
    assert(!type.isTuple() && "Unexpected tuple type");
    frees[type].push_back(temp);
  }

  // Generates a mangled name from `name` within the specified scope.
  //
  // The goal of this function is to ensure that all identifiers in JS ar
  // unique. Otherwise there can be clashes with locals and functions and cause
  // unwanted name shadowing.
  //
  // The returned string from this function is constant for a particular `name`
  // within a `scope`. Or in other words, the same `name` and `scope` pair will
  // always return the same result. If `scope` changes, however, the return
  // value may differ even if the same `name` is passed in.
  IString fromName(Name name, NameScope scope) {
    // TODO: checking names do not collide after mangling

    // First up check our cached of mangled names to avoid doing extra work
    // below
    auto& map = wasmNameToMangledName[(int)scope];
    auto it = map.find(name.str.data());
    if (it != map.end()) {
      return it->second;
    }
    // The mangled names in our scope.
    auto& scopeMangledNames = mangledNames[(int)scope];
    // In some cases (see below) we need to also check the Top scope.
    auto& topMangledNames = mangledNames[int(NameScope::Top)];

    // This is the first time we've seen the `name` and `scope` pair. Generate a
    // globally unique name based on `name` and then register that in our cache
    // and return it.
    //
    // Identifiers here generated are of the form `${name}_${n}` where `_${n}`
    // is omitted if `n==0` and otherwise `n` is just looped over to find the
    // next unused identifier.
    IString ret;
    for (int i = 0;; i++) {
      std::ostringstream out;
      out << name;
      if (i > 0) {
        out << "_" << i;
      }
      auto mangled = asmangle(out.str());
      ret = stringToIString(mangled);
      if (scopeMangledNames.contains(ret)) {
        // When export names collide things may be confusing, as this is
        // observable externally by the person using the JS. Report a warning.
        if (scope == NameScope::Export) {
          std::cerr << "wasm2js: warning: export names colliding: " << mangled
                    << '\n';
        }
        continue;
      }
      // The Local scope is special: a Local name must not collide with a Top
      // name, as they are in a single namespace in JS and can conflict:
      //
      // function foo(bar) {
      //   var bar = 0;
      // }
      // function bar() { ..
      if (scope == NameScope::Local && topMangledNames.contains(ret)) {
        continue;
      }
      // We found a good name, use it.
      scopeMangledNames.insert(ret);
      map[name.str.data()] = ret;
      return ret;
    }
  }

private:
  Flags flags;
  PassOptions options;

  // How many temp vars we need for each type (type => num).
  std::unordered_map<Type, Index> temps;
  // Which temp vars are currently free to use for each type (type => freelist).
  std::unordered_map<Type, std::vector<IString>> frees;

  // Mangled names cache by interned names.
  // Utilizes the usually reused underlying cstring's pointer as the key.
  std::unordered_map<const void*, IString>
    wasmNameToMangledName[(int)NameScope::Max];
  // Set of all mangled names in each scope.
  std::unordered_set<IString> mangledNames[(int)NameScope::Max];
  std::unordered_set<IString> seenModuleImports;

  // If a function is callable from outside, we'll need to cast the inputs
  // and our return value. Otherwise, internally, casts are only needed
  // on operations.
  std::unordered_set<Name> functionsCallableFromOutside;

  void ensureModuleVar(Ref ast, const Importable& imp);
  Ref getImportName(const Importable& imp);
  void addBasics(Ref ast, Module* wasm);
  void addFunctionImport(Ref ast, Function* import);
  void addGlobalImport(Ref ast, Global* import);
  void addTable(Ref ast, Module* wasm);
  void addStart(Ref ast, Module* wasm);
  void addExports(Ref ast, Module* wasm);
  void addGlobal(Ref ast, Global* global, Module* module);
  void addMemoryFuncs(Ref ast, Module* wasm);
  void addMemoryGrowFunc(Ref ast, Module* wasm);

  Wasm2JSBuilder() = delete;
  Wasm2JSBuilder(const Wasm2JSBuilder&) = delete;
  Wasm2JSBuilder& operator=(const Wasm2JSBuilder&) = delete;
};

Ref Wasm2JSBuilder::processWasm(Module* wasm, Name funcName) {
  // Scan the wasm for important things.
  for (auto& exp : wasm->exports) {
    if (exp->kind == ExternalKind::Function) {
      functionsCallableFromOutside.insert(*exp->getInternalName());
    }
  }
  ElementUtils::iterAllElementFunctionNames(
    wasm, [&](Name name) { functionsCallableFromOutside.insert(name); });

  // Collect passive data segment indices.
  for (Index i = 0; i < wasm->dataSegments.size(); ++i) {
    dataIndices[wasm->dataSegments[i]->name] = i;
  }

  // Ensure the scratch memory helpers.
  // If later on they aren't needed, we'll clean them up.
  ABI::wasm2js::ensureHelpers(wasm);

  // Process the code, and optimize if relevant.
  // First, do the lowering to a JS-friendly subset.
  {
    PassRunner runner(wasm, options);
    if (flags.emscripten) {
      runner.add("llvm-nontrapping-fptoint-lowering");
    }
    // TODO: only legalize if necessary - emscripten would already do so, and
    //       likely other toolchains. but spec test suite needs that.
    runner.add("legalize-js-interface");
    // Before lowering non-JS operations we can optimize some instructions which
    // may simplify next passes
    if (options.optimizeLevel > 0) {
      runner.add("optimize-for-js");
    }
    // First up remove as many non-JS operations we can, including things like
    // 64-bit integer multiplication/division, `f32.nearest` instructions, etc.
    // This may inject intrinsics which use i64 so it needs to be run before the
    // i64-to-i32 lowering pass.
    runner.add("remove-non-js-ops");
    // Currently the i64-to-32 lowering pass requires that `flatten` be run
    // before it to produce correct code. For some more details about this see
    // #1480
    runner.add("flatten");
    runner.add("i64-to-i32-lowering");
    runner.add("alignment-lowering");
    // Next, optimize that as best we can. This should not generate
    // non-JS-friendly things.
    if (options.optimizeLevel > 0) {
      // It is especially import to propagate constants after the lowering.
      // However, this can be a slow operation, especially after flattening;
      // some local simplification helps.
      if (options.optimizeLevel >= 3 || options.shrinkLevel >= 1) {
        runner.add("simplify-locals-nonesting");
        runner.add("precompute-propagate");
        // Avoiding reinterpretation is helped by propagation. We also run
        // it later down as default optimizations help as well.
        runner.add("avoid-reinterprets");
      }
      runner.addDefaultOptimizationPasses();
      runner.add("avoid-reinterprets");
    }
    // Finally, get the code into the flat form we need for wasm2js itself, and
    // optimize that a little in a way that keeps that property.
    runner.add("flatten");
    // Regardless of optimization level, run some simple optimizations to undo
    // some of the effects of flattening.
    runner.add("simplify-locals-notee-nostructure");
    // Some operations can be very slow if we didn't run full optimizations
    // earlier, so don't run them automatically.
    if (options.optimizeLevel > 0) {
      runner.add("remove-unused-names");
      runner.add("merge-blocks");
      runner.add("reorder-locals");
      runner.add("coalesce-locals");
    }
    runner.add("reorder-locals");
    runner.add("vacuum");
    runner.add("remove-unused-module-elements");
    // DCE at the end to make sure all IR nodes have valid types for conversion
    // to JS, and not unreachable.
    runner.add("dce");
    runner.setDebug(flags.debug);
    runner.run();
  }

  if (flags.symbolsFile.size() > 0) {
    Output out(flags.symbolsFile, wasm::Flags::Text);
    Index i = 0;
    for (auto& func : wasm->functions) {
      out.getStream() << i++ << ':' << func->name.view() << '\n';
    }
  }

#ifndef NDEBUG
  if (!WasmValidator().validate(*wasm)) {
    std::cout << *wasm << '\n';
    Fatal() << "error in validating wasm2js output";
  }
#endif

  Ref ret = ValueBuilder::makeToplevel();
  Ref asmFunc = ValueBuilder::makeFunction(funcName);
  ret[1]->push_back(asmFunc);
  ValueBuilder::appendArgumentToFunction(asmFunc, importObject);

  // add memory import
  if (!wasm->memories.empty()) {
    if (wasm->memories[0]->imported()) {
      ensureModuleVar(asmFunc[3], *wasm->memories[0]);

      // find memory and buffer in imports
      Ref theVar = ValueBuilder::makeVar();
      asmFunc[3]->push_back(theVar);
      ValueBuilder::appendToVar(
        theVar, "memory", getImportName(*wasm->memories[0]));

      // Assign `buffer = memory.buffer`
      Ref buf = ValueBuilder::makeVar();
      asmFunc[3]->push_back(buf);
      ValueBuilder::appendToVar(
        buf,
        BUFFER,
        ValueBuilder::makeDot(ValueBuilder::makeName("memory"),
                              ValueBuilder::makeName("buffer")));

      // If memory is growable, override the imported memory's grow method to
      // ensure so that when grow is called from the output it works as expected
      if (wasm->memories[0]->max > wasm->memories[0]->initial) {
        asmFunc[3]->push_back(
          ValueBuilder::makeStatement(ValueBuilder::makeBinary(
            ValueBuilder::makeDot(ValueBuilder::makeName("memory"),
                                  ValueBuilder::makeName("grow")),
            SET,
            ValueBuilder::makeName(WASM_MEMORY_GROW))));
      }
    } else {
      Ref theVar = ValueBuilder::makeVar();
      asmFunc[3]->push_back(theVar);
      ValueBuilder::appendToVar(theVar,
                                BUFFER,
                                ValueBuilder::makeNew(ValueBuilder::makeCall(
                                  ValueBuilder::makeName("ArrayBuffer"),
                                  ValueBuilder::makeInt(Address::address32_t(
                                    wasm->memories[0]->initial.addr
                                    << wasm->memories[0]->pageSizeLog2)))));
    }
  }

  // add imported tables
  ModuleUtils::iterImportedTables(*wasm, [&](Table* table) {
    ensureModuleVar(asmFunc[3], *table);
    Ref theVar = ValueBuilder::makeVar();
    asmFunc[3]->push_back(theVar);
    ValueBuilder::appendToVar(theVar, FUNCTION_TABLE, getImportName(*table));
  });

  // create heaps, etc
  addBasics(asmFunc[3], wasm);
  ModuleUtils::iterImportedFunctions(
    *wasm, [&](Function* import) { addFunctionImport(asmFunc[3], import); });
  ModuleUtils::iterImportedGlobals(
    *wasm, [&](Global* import) { addGlobalImport(asmFunc[3], import); });

  // Note the names of functions. We need to do this here as when generating
  // mangled local names we need them not to conflict with these (see fromName)
  // so we can't wait until we parse each function to note its name.
  for (auto& f : wasm->functions) {
    fromName(f->name, NameScope::Top);
  }

  // globals
  bool generateFetchHighBits = false;
  ModuleUtils::iterDefinedGlobals(*wasm, [&](Global* global) {
    addGlobal(asmFunc[3], global, wasm);
    if (flags.allowAsserts && global->name == INT64_TO_32_HIGH_BITS) {
      generateFetchHighBits = true;
    }
  });
  if (flags.emscripten) {
    asmFunc[3]->push_back(
      ValueBuilder::makeName("// EMSCRIPTEN_START_FUNCS\n"));
  }
  // functions
  ModuleUtils::iterDefinedFunctions(*wasm, [&](Function* func) {
    asmFunc[3]->push_back(processFunction(wasm, func));
  });
  if (generateFetchHighBits) {
    Builder builder(*wasm);
    asmFunc[3]->push_back(
      processFunction(wasm,
                      wasm->addFunction(builder.makeFunction(
                        WASM_FETCH_HIGH_BITS,
                        Signature(Type::none, Type::i32),
                        {},
                        builder.makeReturn(builder.makeGlobalGet(
                          INT64_TO_32_HIGH_BITS, Type::i32))))));
    wasm->addExport(new Export(
      WASM_FETCH_HIGH_BITS, ExternalKind::Function, WASM_FETCH_HIGH_BITS));
  }
  if (flags.emscripten) {
    asmFunc[3]->push_back(ValueBuilder::makeName("// EMSCRIPTEN_END_FUNCS\n"));
  }

  if (needsBufferView(*wasm)) {
    asmFunc[3]->push_back(
      ValueBuilder::makeBinary(ValueBuilder::makeName("bufferView"),
                               SET,
                               ValueBuilder::makeName(HEAPU8)));
  }
  if (hasActiveSegments(*wasm)) {
    asmFunc[3]->push_back(
      ValueBuilder::makeCall(ValueBuilder::makeName("initActiveSegments"),
                             ValueBuilder::makeName(importObject)));
  }

  addTable(asmFunc[3], wasm);
  addStart(asmFunc[3], wasm);
  addExports(asmFunc[3], wasm);
  return ret;
}

void Wasm2JSBuilder::addBasics(Ref ast, Module* wasm) {
  if (!wasm->memories.empty()) {
    // heaps, var HEAP8 = new global.Int8Array(buffer); etc
    auto addHeap = [&](IString name, IString view) {
      Ref theVar = ValueBuilder::makeVar();
      ast->push_back(theVar);
      ValueBuilder::appendToVar(theVar,
                                name,
                                ValueBuilder::makeNew(ValueBuilder::makeCall(
                                  view, ValueBuilder::makeName(BUFFER))));
    };
    addHeap(HEAP8, INT8ARRAY);
    addHeap(HEAP16, INT16ARRAY);
    addHeap(HEAP32, INT32ARRAY);
    addHeap(HEAPU8, UINT8ARRAY);
    addHeap(HEAPU16, UINT16ARRAY);
    addHeap(HEAPU32, UINT32ARRAY);
    addHeap(HEAPF32, FLOAT32ARRAY);
    addHeap(HEAPF64, FLOAT64ARRAY);
  }
  // core asm.js imports
  auto addMath = [&](IString name, IString base) {
    Ref theVar = ValueBuilder::makeVar();
    ast->push_back(theVar);
    ValueBuilder::appendToVar(
      theVar, name, ValueBuilder::makeDot(ValueBuilder::makeName(MATH), base));
  };
  addMath(MATH_IMUL, IMUL);
  addMath(MATH_FROUND, FROUND);
  addMath(MATH_ABS, ABS);
  addMath(MATH_CLZ32, CLZ32);
  addMath(MATH_MIN, MIN);
  addMath(MATH_MAX, MAX);
  addMath(MATH_FLOOR, FLOOR);
  addMath(MATH_CEIL, CEIL);
  addMath(MATH_TRUNC, TRUNC);
  addMath(MATH_SQRT, SQRT);
}

static bool needsQuoting(Name name) {
  auto mangled = asmangle(name.toString());
  return mangled != name.view();
}

void Wasm2JSBuilder::ensureModuleVar(Ref ast, const Importable& imp) {
  if (seenModuleImports.contains(imp.module)) {
    return;
  }
  Ref theVar = ValueBuilder::makeVar();
  ast->push_back(theVar);
  Ref rhs;
  if (needsQuoting(imp.module)) {
    rhs = ValueBuilder::makeSub(ValueBuilder::makeName(importObject),
                                ValueBuilder::makeString(imp.module));
  } else {
    rhs = ValueBuilder::makeDot(ValueBuilder::makeName(importObject),
                                ValueBuilder::makeName(imp.module));
  }

  ValueBuilder::appendToVar(theVar, fromName(imp.module, NameScope::Top), rhs);
  seenModuleImports.insert(imp.module);
}

Ref Wasm2JSBuilder::getImportName(const Importable& imp) {
  if (needsQuoting(imp.base)) {
    return ValueBuilder::makeSub(
      ValueBuilder::makeName(fromName(imp.module, NameScope::Top)),
      ValueBuilder::makeString(imp.base));
  } else {
    return ValueBuilder::makeDot(
      ValueBuilder::makeName(fromName(imp.module, NameScope::Top)),
      ValueBuilder::makeName(imp.base));
  }
}

void Wasm2JSBuilder::addFunctionImport(Ref ast, Function* import) {
  // The scratch memory helpers are emitted in the glue, see code and comments
  // below.
  if (ABI::wasm2js::isHelper(import->base)) {
    return;
  }
  ensureModuleVar(ast, *import);
  Ref theVar = ValueBuilder::makeVar();
  ast->push_back(theVar);
  ValueBuilder::appendToVar(
    theVar, fromName(import->name, NameScope::Top), getImportName(*import));
}

void Wasm2JSBuilder::addGlobalImport(Ref ast, Global* import) {
  ensureModuleVar(ast, *import);
  Ref theVar = ValueBuilder::makeVar();
  ast->push_back(theVar);
  Ref value = getImportName(*import);
  if (import->type == Type::i32) {
    value = makeJsCoercion(value, JS_INT);
  }
  ValueBuilder::appendToVar(
    theVar, fromName(import->name, NameScope::Top), value);
}

void Wasm2JSBuilder::addTable(Ref ast, Module* wasm) {
  if (wasm->tables.size() == 0) {
    return;
  }

  bool perElementInit = false;

  // Emit a simple flat table as a JS array literal. Otherwise,
  // emit assignments separately for each index.
  Ref theArray = ValueBuilder::makeArray();
  for (auto& table : wasm->tables) {
    if (!table->type.isFunction()) {
      Fatal() << "wasm2js doesn't support non-function tables\n";
    }

    if (!table->imported()) {
      TableUtils::FlatTable flat(*wasm, *table);
      if (flat.valid) {
        for (auto& name : flat.names) {
          if (name.is()) {
            name = fromName(name, NameScope::Top);
          } else {
            name = NULL_;
          }
          ValueBuilder::appendToArray(theArray, ValueBuilder::makeName(name));
        }
      } else {
        perElementInit = true;
        Ref initial =
          ValueBuilder::makeInt(Address::address32_t(table->initial.addr));
        theArray = ValueBuilder::makeNew(
          ValueBuilder::makeCall(IString("Array"), initial));
      }
    } else {
      perElementInit = true;
    }

    if (isTableExported(*wasm)) {
      // If the table is exported use a fake WebAssembly.Table object
      // We don't handle the case where a table is both imported and exported.
      if (table->imported()) {
        Fatal() << "wasm2js doesn't support a table that is both imported and "
                   "exported\n";
      }
      Ref theVar = ValueBuilder::makeVar();
      ast->push_back(theVar);

      Ref table = ValueBuilder::makeCall(IString("Table"), theArray);
      ValueBuilder::appendToVar(theVar, FUNCTION_TABLE, table);
    } else if (!table->imported()) {
      // Otherwise if the table is internal (neither imported not exported).
      // Just use a plain array in this case, avoiding the Table.
      Ref theVar = ValueBuilder::makeVar();
      ast->push_back(theVar);
      ValueBuilder::appendToVar(theVar, FUNCTION_TABLE, theArray);
    }

    if (perElementInit) {
      // TODO: optimize for size
      ModuleUtils::iterTableSegments(
        *wasm, table->name, [&](ElementSegment* segment) {
          auto offset = segment->offset;
          ElementUtils::iterElementSegmentFunctionNames(
            segment, [&](Name entry, Index i) {
              Ref index;
              if (auto* c = offset->dynCast<Const>()) {
                index = ValueBuilder::makeInt(c->value.geti32() + i);
              } else if (auto* get = offset->dynCast<GlobalGet>()) {
                index = ValueBuilder::makeBinary(
                  ValueBuilder::makeName(
                    stringToIString(asmangle(get->name.toString()))),
                  PLUS,
                  ValueBuilder::makeNum(i));
              } else {
                WASM_UNREACHABLE("unexpected expr type");
              }
              ast->push_back(
                ValueBuilder::makeStatement(ValueBuilder::makeBinary(
                  ValueBuilder::makeSub(ValueBuilder::makeName(FUNCTION_TABLE),
                                        index),
                  SET,
                  ValueBuilder::makeName(fromName(entry, NameScope::Top)))));
            });
        });
    }
  }
}

void Wasm2JSBuilder::addStart(Ref ast, Module* wasm) {
  if (wasm->start.is()) {
    ast->push_back(
      ValueBuilder::makeCall(fromName(wasm->start, NameScope::Top)));
  }
}

void Wasm2JSBuilder::addExports(Ref ast, Module* wasm) {
  Ref exports = ValueBuilder::makeObject();
  for (auto& export_ : wasm->exports) {
    switch (export_->kind) {
      case ExternalKind::Function: {
        ValueBuilder::appendToObjectWithQuotes(
          exports,
          fromName(export_->name, NameScope::Export),
          ValueBuilder::makeName(
            fromName(*export_->getInternalName(), NameScope::Top)));
        break;
      }
      case ExternalKind::Memory: {
        Ref descs = ValueBuilder::makeObject();
        Ref growDesc = ValueBuilder::makeObject();
        ValueBuilder::appendToObjectWithQuotes(
          descs, IString("grow"), growDesc);
        if (wasm->memories[0]->max > wasm->memories[0]->initial) {
          ValueBuilder::appendToObjectWithQuotes(
            growDesc,
            IString("value"),
            ValueBuilder::makeName(WASM_MEMORY_GROW));
        }
        Ref bufferDesc = ValueBuilder::makeObject();
        Ref bufferGetter = ValueBuilder::makeFunction(IString(""));
        bufferGetter[3]->push_back(
          ValueBuilder::makeReturn(ValueBuilder::makeName(BUFFER)));
        ValueBuilder::appendToObjectWithQuotes(
          bufferDesc, IString("get"), bufferGetter);
        ValueBuilder::appendToObjectWithQuotes(
          descs, IString("buffer"), bufferDesc);
        Ref memory = ValueBuilder::makeCall(
          ValueBuilder::makeDot(ValueBuilder::makeName(IString("Object")),
                                IString("create")),
          ValueBuilder::makeDot(ValueBuilder::makeName(IString("Object")),
                                IString("prototype")));
        ValueBuilder::appendToCall(memory, descs);
        ValueBuilder::appendToObjectWithQuotes(
          exports, fromName(export_->name, NameScope::Export), memory);
        break;
      }
      case ExternalKind::Table: {
        ValueBuilder::appendToObjectWithQuotes(
          exports,
          fromName(export_->name, NameScope::Export),
          ValueBuilder::makeName(FUNCTION_TABLE));
        break;
      }
      case ExternalKind::Global: {
        Ref object = ValueBuilder::makeObject();

        IString identName =
          fromName(*export_->getInternalName(), NameScope::Top);

        // getter
        {
          Ref block = ValueBuilder::makeBlock();

          block[1]->push_back(
            ValueBuilder::makeReturn(ValueBuilder::makeName(identName)));

          ValueBuilder::appendToObjectAsGetter(object, IString("value"), block);
        }

        // setter
        {
          std::ostringstream buffer;
          buffer << '_' << identName;
          auto setterParam = stringToIString(buffer.str());

          auto block = ValueBuilder::makeBlock();

          block[1]->push_back(
            ValueBuilder::makeBinary(ValueBuilder::makeName(identName),
                                     SET,
                                     ValueBuilder::makeName(setterParam)));

          ValueBuilder::appendToObjectAsSetter(
            object, IString("value"), setterParam, block);
        }

        ValueBuilder::appendToObjectWithQuotes(
          exports, fromName(export_->name, NameScope::Export), object);

        break;
      }
      case ExternalKind::Tag:
      case ExternalKind::Invalid:
        Fatal() << "unsupported export type: " << export_->name << "\n";
    }
  }
  if (!wasm->memories.empty()) {
    addMemoryFuncs(ast, wasm);
  }
  ast->push_back(
    ValueBuilder::makeStatement(ValueBuilder::makeReturn(exports)));
}

void Wasm2JSBuilder::addGlobal(Ref ast, Global* global, Module* module) {
  Ref theVar = ValueBuilder::makeVar();
  ast->push_back(theVar);
  Ref init = processExpression(global->init, module);
  ValueBuilder::appendToVar(
    theVar, fromName(global->name, NameScope::Top), init);
}

Ref Wasm2JSBuilder::processFunction(Module* m,
                                    Function* func,
                                    bool standaloneFunction) {
  if (standaloneFunction) {
    // We are only printing a function, not a whole module. Prepare it for
    // translation now (if there were a module, we'd have done this for all
    // functions in parallel, earlier).
    PassRunner runner(m);
    // We only run a subset of all passes here. TODO: create a full valid module
    // for each assertion body.
    runner.add("flatten");
    runner.add("simplify-locals-notee-nostructure");
    runner.add("reorder-locals");
    runner.add("remove-unused-names");
    runner.add("vacuum");
    runner.runOnFunction(func);
  }

  // We process multiple functions from a single Wasm2JSBuilder instance, so
  // clean up the function-specific local state before each function.
  frees.clear();
  temps.clear();

  // We will be symbolically referring to all variables in the function, so make
  // sure that everything has a name and it's unique.
  Names::ensureNames(func);
  Ref ret = ValueBuilder::makeFunction(fromName(func->name, NameScope::Top));
  // arguments
  bool needCoercions = options.optimizeLevel == 0 || standaloneFunction ||
                       functionsCallableFromOutside.contains(func->name);
  for (Index i = 0; i < func->getNumParams(); i++) {
    IString name = fromName(func->getLocalNameOrGeneric(i), NameScope::Local);
    ValueBuilder::appendArgumentToFunction(ret, name);
    if (needCoercions) {
      auto jsType = wasmToJsType(func->getLocalType(i));
      if (needsJsCoercion(jsType)) {
        ret[3]->push_back(ValueBuilder::makeStatement(ValueBuilder::makeBinary(
          ValueBuilder::makeName(name),
          SET,
          makeJsCoercion(ValueBuilder::makeName(name), jsType))));
      }
    }
  }
  Ref theVar = ValueBuilder::makeVar();
  size_t theVarIndex = ret[3]->size();
  ret[3]->push_back(theVar);
  // body
  flattenAppend(ret,
                processExpression(func->body, m, func, standaloneFunction));
  // vars, including new temp vars
  for (Index i = func->getVarIndexBase(); i < func->getNumLocals(); i++) {
    ValueBuilder::appendToVar(
      theVar,
      fromName(func->getLocalNameOrGeneric(i), NameScope::Local),
      makeJsCoercedZero(wasmToJsType(func->getLocalType(i))));
  }
  if (theVar[1]->size() == 0) {
    ret[3]->splice(theVarIndex, 1);
  }
  return ret;
}

Ref Wasm2JSBuilder::processExpression(Expression* curr,
                                      Module* m,
                                      Function* func,
                                      bool standaloneFunction) {
  // Switches are tricky to handle - in wasm they often come with
  // massively-nested "towers" of blocks, which if naively translated
  // to JS may exceed parse recursion limits of VMs. Therefore even when
  // not optimizing we work hard to emit minimal and minimally-nested
  // switches.
  // We do so by pre-scanning for br_tables and noting which of their
  // targets can be hoisted up into them, e.g.
  //
  // (block $a
  //  (block $b
  //   (block $c
  //    (block $d
  //     (block $e
  //      (br_table $a $b $c $d $e (..))
  //     )
  //     ;; code X (for block $e)
  //     ;; implicit fallthrough - can be done in the switch too
  //    )
  //    ;; code Y
  //    (br $c) ;; branch which is identical to a fallthrough
  //   )
  //   ;; code Z
  //   (br $a) ;; skip some blocks - can't do this in a switch!
  //  )
  //  ;; code W
  // )
  //
  // Every branch we see is a potential hazard - all targets must not
  // be optimized into the switch, since they must be reached normally,
  // unless they happen to be right after us, in which case it's just
  // a fallthrough anyhow.
  struct SwitchProcessor : public ExpressionStackWalker<SwitchProcessor> {
    // A list of expressions we don't need to emit, as we are handling them
    // in another way.
    std::set<Expression*> unneededExpressions;

    struct SwitchCase {
      Name target;
      std::vector<Expression*> code;
      SwitchCase(Name target) : target(target) {}
    };

    // The switch cases we found that we can hoist up.
    std::map<Switch*, std::vector<SwitchCase>> hoistedSwitchCases;

    void visitSwitch(Switch* brTable) {
      Index i = expressionStack.size() - 1;
      assert(expressionStack[i] == brTable);
      // A set of names we must stop at, since we've seen branches to them.
      std::set<Name> namesBranchedTo;
      while (1) {
        // Stop if we are at the top level.
        if (i == 0) {
          break;
        }
        i--;
        auto* child = expressionStack[i + 1];
        auto* curr = expressionStack[i];
        // Stop if the current node is not a block with the child in the
        // first position, i.e., the classic switch pattern.
        auto* block = curr->dynCast<Block>();
        if (!block || block->list[0] != child) {
          break;
        }
        // Ignore the case of a name-less block for simplicity (merge-blocks
        // would have removed it).
        if (!block->name.is()) {
          break;
        }
        // If we have already seen this block, stop here.
        if (unneededExpressions.contains(block)) {
          // XXX FIXME we should probably abort the entire optimization
          break;
        }
        auto& list = block->list;
        if (child == brTable) {
          // Nothing more to do here (we can in fact skip any code til
          // the parent block).
          continue;
        }
        // Ok, we are a block and our child in the first position is a
        // block, and the neither is branched to - unless maybe the child
        // branches to the parent, check that. Note how we treat the
        // final element which may be a break that is a fallthrough.
        Expression* unneededBr = nullptr;
        for (Index j = 1; j < list.size(); j++) {
          auto* item = list[j];
          auto newBranches = BranchUtils::getExitingBranches(item);
          if (auto* br = item->dynCast<Break>()) {
            if (j == list.size() - 1) {
              if (!br->condition && br->name == block->name) {
                // This is a natural, unnecessary-to-emit fallthrough.
                unneededBr = br;
                break;
              }
            }
          }
          namesBranchedTo.insert(newBranches.begin(), newBranches.end());
        }
        if (namesBranchedTo.contains(block->name)) {
          break;
        }
        // We can move code after the child (reached by branching on the
        // child) into the switch.
        auto* childBlock = child->cast<Block>();
        hoistedSwitchCases[brTable].emplace_back(childBlock->name);
        SwitchCase& case_ = hoistedSwitchCases[brTable].back();
        for (Index j = 1; j < list.size(); j++) {
          auto* item = list[j];
          if (item != unneededBr) {
            case_.code.push_back(item);
          }
        }
        list.resize(1);
        // Finally, mark the block as unneeded outside the switch.
        unneededExpressions.insert(childBlock);
      }
    }
  };

  struct ExpressionProcessor
    : public OverriddenVisitor<ExpressionProcessor, Ref> {
    Wasm2JSBuilder* parent;
    IString result; // TODO: remove
    Function* func;
    Module* module;
    bool standaloneFunction;

    SwitchProcessor switchProcessor;

    ExpressionProcessor(Wasm2JSBuilder* parent,
                        Module* m,
                        Function* func,
                        bool standaloneFunction)
      : parent(parent), func(func), module(m),
        standaloneFunction(standaloneFunction) {}

    Ref process(Expression* curr) {
      switchProcessor.walk(curr);
      return visit(curr, NO_RESULT);
    }

    // A scoped temporary variable.
    struct ScopedTemp {
      Wasm2JSBuilder* parent;
      Type type;
      IString temp; // TODO: switch to indexes; avoid names
      bool needFree;
      // @param possible if provided, this is a variable we can use as our temp.
      //                 it has already been allocated in a higher scope, and we
      //                 can just assign to it as our result is going there
      //                 anyhow.
      ScopedTemp(Type type,
                 Wasm2JSBuilder* parent,
                 Function* func,
                 IString possible = NO_RESULT)
        : parent(parent), type(type) {
        assert(possible != EXPRESSION_RESULT);
        if (possible == NO_RESULT) {
          temp = parent->getTemp(type, func);
          needFree = true;
        } else {
          temp = possible;
          needFree = false;
        }
      }
      ~ScopedTemp() {
        if (needFree) {
          parent->freeTemp(type, temp);
        }
      }

      IString getName() { return temp; }
      Ref getAstName() { return ValueBuilder::makeName(temp); }
    };

    Ref visit(Expression* curr, IString nextResult) {
      IString old = result;
      result = nextResult;
      Ref ret = OverriddenVisitor::visit(curr);
      // keep it consistent for the rest of this frame, which may call visit on
      // multiple children
      result = old;
      return ret;
    }

    Ref visit(Expression* curr, ScopedTemp& temp) {
      return visit(curr, temp.temp);
    }

    Ref visitAndAssign(Expression* curr, IString result) {
      assert(result != NO_RESULT);
      Ref ret = visit(curr, result);
      return ValueBuilder::makeStatement(
        ValueBuilder::makeBinary(ValueBuilder::makeName(result), SET, ret));
    }

    Ref visitAndAssign(Expression* curr, ScopedTemp& temp) {
      return visitAndAssign(curr, temp.getName());
    }

    // Expressions with control flow turn into a block, which we must
    // then handle, even if we are an expression.
    bool isBlock(Ref ast) { return !!ast && ast->isArray() && ast[0] == BLOCK; }

    Ref blockify(Ref ast) {
      if (isBlock(ast)) {
        return ast;
      }
      Ref ret = ValueBuilder::makeBlock();
      ret[1]->push_back(ValueBuilder::makeStatement(ast));
      return ret;
    }

    // Breaks to the top of a loop should be emitted as continues, to that
    // loop's main label
    std::unordered_set<Name> continueLabels;

    IString fromName(Name name, NameScope scope) {
      return parent->fromName(name, scope);
    }

    // Visitors

    Ref visitBlock(Block* curr) {
      if (switchProcessor.unneededExpressions.contains(curr)) {
        // We have had our tail hoisted into a switch that is nested in our
        // first position, so we don't need to emit that code again, or
        // ourselves in fact.
        return visit(curr->list[0], NO_RESULT);
      }
      Ref ret = ValueBuilder::makeBlock();
      size_t size = curr->list.size();
      for (size_t i = 0; i < size; i++) {
        flattenAppend(
          ret, ValueBuilder::makeStatement(visit(curr->list[i], NO_RESULT)));
      }
      if (curr->name.is()) {
        ret =
          ValueBuilder::makeLabel(fromName(curr->name, NameScope::Label), ret);
      }
      return ret;
    }

    Ref visitIf(If* curr) {
      Ref condition = visit(curr->condition, EXPRESSION_RESULT);
      Ref ifTrue = visit(curr->ifTrue, NO_RESULT);
      Ref ifFalse;
      if (curr->ifFalse) {
        ifFalse = visit(curr->ifFalse, NO_RESULT);
      }
      return ValueBuilder::makeIf(condition, ifTrue, ifFalse); // simple if
    }

    Ref visitLoop(Loop* curr) {
      Name asmLabel = curr->name;
      if (!asmLabel) {
        // This loop has no label, so it cannot be continued to. We can just
        // emit the body.
        return visit(curr->body, result);
      }
      continueLabels.insert(asmLabel);
      Ref body = visit(curr->body, result);
      // if we can reach the end of the block, we must leave the while (1) loop
      if (curr->body->type != Type::unreachable) {
        assert(curr->body->type == Type::none); // flat IR
        body = blockify(body);
        flattenAppend(
          body, ValueBuilder::makeBreak(fromName(asmLabel, NameScope::Label)));
      }
      Ref ret = ValueBuilder::makeWhile(ValueBuilder::makeInt(1), body);
      return ValueBuilder::makeLabel(fromName(asmLabel, NameScope::Label), ret);
    }

    Ref makeBreakOrContinue(Name name) {
      if (continueLabels.contains(name)) {
        return ValueBuilder::makeContinue(fromName(name, NameScope::Label));
      } else {
        return ValueBuilder::makeBreak(fromName(name, NameScope::Label));
      }
    }

    Ref visitBreak(Break* curr) {
      if (curr->condition) {
        // we need an equivalent to an if here, so use that code
        Break fakeBreak = *curr;
        fakeBreak.condition = nullptr;
        If fakeIf;
        fakeIf.condition = curr->condition;
        fakeIf.ifTrue = &fakeBreak;
        return visit(&fakeIf, result);
      }
      return makeBreakOrContinue(curr->name);
    }

    Expression* defaultBody = nullptr; // default must be last in asm.js

    Ref visitSwitch(Switch* curr) {
      // Even without optimizations, we work hard here to emit minimal and
      // especially minimally-nested code, since otherwise we may get block
      // nesting of a size that JS engines can't handle.
      Ref condition = visit(curr->condition, EXPRESSION_RESULT);
      Ref theSwitch =
        ValueBuilder::makeSwitch(makeJsCoercion(condition, JS_INT));
      // First, group the switch targets.
      std::map<Name, std::vector<Index>> targetIndexes;
      for (size_t i = 0; i < curr->targets.size(); i++) {
        targetIndexes[curr->targets[i]].push_back(i);
      }
      // Emit first any hoisted groups.
      auto& hoistedCases = switchProcessor.hoistedSwitchCases[curr];
      std::set<Name> emittedTargets;
      bool hoistedEndsWithUnreachable = false;
      for (auto& case_ : hoistedCases) {
        auto target = case_.target;
        auto& code = case_.code;
        emittedTargets.insert(target);
        if (target != curr->default_) {
          auto& indexes = targetIndexes[target];
          for (auto i : indexes) {
            ValueBuilder::appendCaseToSwitch(theSwitch,
                                             ValueBuilder::makeNum(i));
          }
        } else {
          ValueBuilder::appendDefaultToSwitch(theSwitch);
        }
        for (auto* c : code) {
          ValueBuilder::appendCodeToSwitch(
            theSwitch, blockify(visit(c, NO_RESULT)), false);
          hoistedEndsWithUnreachable = c->type == Type::unreachable;
        }
      }
      // After the hoisted cases, if any remain we must make sure not to
      // fall through into them. If no code was hoisted, this is unnecessary,
      // and if the hoisted code ended with an unreachable it also is not
      // necessary.
      bool stoppedFurtherFallthrough = false;
      auto stopFurtherFallthrough = [&]() {
        if (!stoppedFurtherFallthrough && !hoistedCases.empty() &&
            !hoistedEndsWithUnreachable) {
          stoppedFurtherFallthrough = true;
          ValueBuilder::appendCodeToSwitch(
            theSwitch, blockify(ValueBuilder::makeBreak(IString())), false);
        }
      };

      // Emit any remaining groups by just emitting branches to their code,
      // which will appear outside the switch.
      for (auto& [target, indexes] : targetIndexes) {
        if (emittedTargets.contains(target)) {
          continue;
        }
        stopFurtherFallthrough();
        if (target != curr->default_) {
          for (auto i : indexes) {
            ValueBuilder::appendCaseToSwitch(theSwitch,
                                             ValueBuilder::makeNum(i));
          }
          ValueBuilder::appendCodeToSwitch(
            theSwitch, blockify(makeBreakOrContinue(target)), false);
        } else {
          // For the group going to the same place as the default, we can just
          // emit the default itself, which we do at the end.
        }
      }
      // TODO: if the group the default is in is not the largest, we can turn
      // the largest into
      //       the default by using a local and a check on the range
      if (!emittedTargets.contains(curr->default_)) {
        stopFurtherFallthrough();
        ValueBuilder::appendDefaultToSwitch(theSwitch);
        ValueBuilder::appendCodeToSwitch(
          theSwitch, blockify(makeBreakOrContinue(curr->default_)), false);
      }
      return theSwitch;
    }

    Ref visitCall(Call* curr) {
      if (curr->isReturn) {
        Fatal() << "tail calls not yet supported in wasm2js";
      }
      Ref theCall =
        ValueBuilder::makeCall(fromName(curr->target, NameScope::Top));
      // For wasm => wasm calls, we don't need coercions. TODO: even imports
      // might be safe?
      bool needCoercions = parent->options.optimizeLevel == 0 ||
                           standaloneFunction ||
                           module->getFunction(curr->target)->imported();
      for (auto operand : curr->operands) {
        auto value = visit(operand, EXPRESSION_RESULT);
        if (needCoercions) {
          value = makeJsCoercion(value, wasmToJsType(operand->type));
        }
        theCall[2]->push_back(value);
      }
      if (needCoercions) {
        theCall = makeJsCoercion(theCall, wasmToJsType(curr->type));
      }
      return theCall;
    }

    Ref visitCallIndirect(CallIndirect* curr) {
      if (curr->isReturn) {
        Fatal() << "tail calls not yet supported in wasm2js";
      }
      // If the target has effects that interact with the operands, we must
      // reorder it to the start.
      bool mustReorder = false;
      EffectAnalyzer targetEffects(parent->options, *module, curr->target);
      if (targetEffects.hasAnything()) {
        for (auto* operand : curr->operands) {
          if (targetEffects.invalidates(
                EffectAnalyzer(parent->options, *module, operand))) {
            mustReorder = true;
            break;
          }
        }
      }
      // Ensure the function pointer is a number. In general in wasm2js we are
      // ok with true/false being present, as they are immediately cast to a
      // number anyhow on their use. However, FUNCTION_TABLE[true] is *not* the
      // same as FUNCTION_TABLE[1], so we must cast. This is a rare exception
      // because FUNCTION_TABLE is just a normal JS object, not a typed array
      // or a mathematical operation (all of which coerce to a number for us).
      auto target = visit(curr->target, EXPRESSION_RESULT);
      target = makeJsCoercion(target, JS_INT);
      if (mustReorder) {
        Ref ret;
        ScopedTemp idx(Type::i32, parent, func);
        std::vector<ScopedTemp*> temps; // TODO: utility class, with destructor?
        for (auto* operand : curr->operands) {
          temps.push_back(new ScopedTemp(operand->type, parent, func));
          IString temp = temps.back()->temp;
          sequenceAppend(ret, visitAndAssign(operand, temp));
        }
        sequenceAppend(ret,
                       ValueBuilder::makeBinary(
                         ValueBuilder::makeName(idx.getName()), SET, target));
        Ref theCall = ValueBuilder::makeCall(ValueBuilder::makeSub(
          ValueBuilder::makeName(FUNCTION_TABLE), idx.getAstName()));
        for (size_t i = 0; i < temps.size(); i++) {
          IString temp = temps[i]->temp;
          auto& operand = curr->operands[i];
          theCall[2]->push_back(makeJsCoercion(ValueBuilder::makeName(temp),
                                               wasmToJsType(operand->type)));
        }
        theCall = makeJsCoercion(theCall, wasmToJsType(curr->type));
        sequenceAppend(ret, theCall);
        for (auto temp : temps) {
          delete temp;
        }
        return ret;
      } else {
        // Target has no side effects, emit simple code
        Ref theCall = ValueBuilder::makeCall(ValueBuilder::makeSub(
          ValueBuilder::makeName(FUNCTION_TABLE), target));
        for (auto* operand : curr->operands) {
          theCall[2]->push_back(visit(operand, EXPRESSION_RESULT));
        }
        theCall = makeJsCoercion(theCall, wasmToJsType(curr->type));
        return theCall;
      }
    }

    // TODO: remove
    Ref makeSetVar(Expression* curr,
                   Expression* value,
                   Name name,
                   NameScope scope) {
      return ValueBuilder::makeBinary(
        ValueBuilder::makeName(fromName(name, scope)),
        SET,
        visit(value, EXPRESSION_RESULT));
    }

    Ref visitLocalGet(LocalGet* curr) {
      return ValueBuilder::makeName(
        fromName(func->getLocalNameOrGeneric(curr->index), NameScope::Local));
    }

    Ref visitLocalSet(LocalSet* curr) {
      return makeSetVar(curr,
                        curr->value,
                        func->getLocalNameOrGeneric(curr->index),
                        NameScope::Local);
    }

    Ref visitGlobalGet(GlobalGet* curr) {
      return ValueBuilder::makeName(fromName(curr->name, NameScope::Top));
    }

    Ref visitGlobalSet(GlobalSet* curr) {
      return makeSetVar(curr, curr->value, curr->name, NameScope::Top);
    }

    Ref visitLoad(Load* curr) {
      // Unaligned loads and stores must have been fixed up already.
      assert(curr->align == 0 || curr->align == curr->bytes);
      // normal load
      Ref ptr = makePointer(curr->ptr, curr->offset);
      Ref ret;
      switch (curr->type.getBasic()) {
        case Type::i32: {
          switch (curr->bytes) {
            case 1:
              ret = ValueBuilder::makeSub(
                ValueBuilder::makeName(
                  LoadUtils::isSignRelevant(curr) && curr->signed_ ? HEAP8
                                                                   : HEAPU8),
                ValueBuilder::makePtrShift(ptr, 0));
              break;
            case 2:
              ret = ValueBuilder::makeSub(
                ValueBuilder::makeName(
                  LoadUtils::isSignRelevant(curr) && curr->signed_ ? HEAP16
                                                                   : HEAPU16),
                ValueBuilder::makePtrShift(ptr, 1));
              break;
            case 4:
              ret = ValueBuilder::makeSub(ValueBuilder::makeName(HEAP32),
                                          ValueBuilder::makePtrShift(ptr, 2));
              break;
            default: {
              Fatal() << "Unhandled number of bytes in i32 load: "
                      << curr->bytes;
            }
          }
          break;
        }
        case Type::f32:
          ret = ValueBuilder::makeSub(ValueBuilder::makeName(HEAPF32),
                                      ValueBuilder::makePtrShift(ptr, 2));
          break;
        case Type::f64:
          ret = ValueBuilder::makeSub(ValueBuilder::makeName(HEAPF64),
                                      ValueBuilder::makePtrShift(ptr, 3));
          break;
        default: {
          Fatal() << "Unhandled type in load: " << curr->type;
        }
      }
      if (curr->isAtomic()) {
        Ref call = ValueBuilder::makeCall(
          ValueBuilder::makeDot(ValueBuilder::makeName(ATOMICS), LOAD));
        ValueBuilder::appendToCall(call, ret[1]);
        ValueBuilder::appendToCall(call, ret[2]);
        ret = call;
      }
      // Coercions are not actually needed, as if the user reads beyond valid
      // memory, it's undefined behavior anyhow, and so we don't care much about
      // slowness of undefined values etc.
      bool needCoercions =
        parent->options.optimizeLevel == 0 || standaloneFunction;
      if (needCoercions) {
        ret = makeJsCoercion(ret, wasmToJsType(curr->type));
      }
      return ret;
    }

    Ref visitStore(Store* curr) {
      if (!module->memories.empty() &&
          module->memories[0]->initial < module->memories[0]->max &&
          curr->type != Type::unreachable) {
        // In JS, if memory grows then it is dangerous to write
        //  HEAP[f()] = ..
        // or
        //  HEAP[..] = f()
        // since if the call swaps HEAP (in a growth operation) then
        // we will not actually write to the new version (since the
        // semantics of JS mean we already looked at HEAP and have
        // decided where to assign to).
        if (!FindAll<Call>(curr->ptr).list.empty() ||
            !FindAll<Call>(curr->value).list.empty() ||
            !FindAll<CallIndirect>(curr->ptr).list.empty() ||
            !FindAll<CallIndirect>(curr->value).list.empty() ||
            !FindAll<MemoryGrow>(curr->ptr).list.empty() ||
            !FindAll<MemoryGrow>(curr->value).list.empty()) {
          Ref ret;
          ScopedTemp ptr(Type::i32, parent, func);
          sequenceAppend(ret, visitAndAssign(curr->ptr, ptr));
          ScopedTemp value(curr->value->type, parent, func);
          sequenceAppend(ret, visitAndAssign(curr->value, value));
          LocalGet getPtr;
          getPtr.index = func->getLocalIndex(ptr.getName());
          getPtr.type = Type::i32;
          LocalGet getValue;
          getValue.index = func->getLocalIndex(value.getName());
          getValue.type = curr->value->type;
          Store fakeStore = *curr;
          fakeStore.ptr = &getPtr;
          fakeStore.value = &getValue;
          sequenceAppend(ret, visitStore(&fakeStore));
          return ret;
        }
      }
      // FIXME if memory growth, store ptr cannot contain a function call
      //       also other stores to memory, check them, all makeSub's
      // Unaligned loads and stores must have been fixed up already.
      assert(curr->align == 0 || curr->align == curr->bytes);
      // normal store
      Ref ptr = makePointer(curr->ptr, curr->offset);
      Ref value = visit(curr->value, EXPRESSION_RESULT);
      Ref ret;
      switch (curr->valueType.getBasic()) {
        case Type::i32: {
          switch (curr->bytes) {
            case 1:
              ret = ValueBuilder::makeSub(ValueBuilder::makeName(HEAP8),
                                          ValueBuilder::makePtrShift(ptr, 0));
              break;
            case 2:
              ret = ValueBuilder::makeSub(ValueBuilder::makeName(HEAP16),
                                          ValueBuilder::makePtrShift(ptr, 1));
              break;
            case 4:
              ret = ValueBuilder::makeSub(ValueBuilder::makeName(HEAP32),
                                          ValueBuilder::makePtrShift(ptr, 2));
              break;
            default:
              abort();
          }
          break;
        }
        case Type::f32:
          ret = ValueBuilder::makeSub(ValueBuilder::makeName(HEAPF32),
                                      ValueBuilder::makePtrShift(ptr, 2));
          break;
        case Type::f64:
          ret = ValueBuilder::makeSub(ValueBuilder::makeName(HEAPF64),
                                      ValueBuilder::makePtrShift(ptr, 3));
          break;
        default: {
          Fatal() << "Unhandled type in store: " << curr->valueType;
        }
      }
      if (curr->isAtomic()) {
        Ref call = ValueBuilder::makeCall(
          ValueBuilder::makeDot(ValueBuilder::makeName(ATOMICS), STORE));
        ValueBuilder::appendToCall(call, ret[1]);
        ValueBuilder::appendToCall(call, ret[2]);
        ValueBuilder::appendToCall(call, value);
        return call;
      }
      return ValueBuilder::makeBinary(ret, SET, value);
    }

    Ref visitDrop(Drop* curr) { return visit(curr->value, NO_RESULT); }

    Ref visitConst(Const* curr) {
      switch (curr->type.getBasic()) {
        case Type::i32:
          return ValueBuilder::makeInt(curr->value.geti32());
        // An i64 argument translates to two actual arguments to asm.js
        // functions, so we do a bit of a hack here to get our one `Ref` to look
        // like two function arguments.
        case Type::i64: {
          auto lo = (unsigned)curr->value.geti64();
          auto hi = (unsigned)(curr->value.geti64() >> 32);
          std::ostringstream out;
          out << lo << "," << hi;
          std::string os = out.str();
          IString name(os.c_str());
          return ValueBuilder::makeName(name);
        }
        case Type::f32: {
          Ref ret = ValueBuilder::makeCall(MATH_FROUND);
          Const fake;
          fake.value = Literal(double(curr->value.getf32()));
          fake.type = Type::f64;
          ret[2]->push_back(visitConst(&fake));
          return ret;
        }
        case Type::f64: {
          double d = curr->value.getf64();
          if (d == 0 && std::signbit(d)) { // negative zero
            return ValueBuilder::makeUnary(
              PLUS,
              ValueBuilder::makeUnary(MINUS, ValueBuilder::makeDouble(0)));
          }
          return ValueBuilder::makeUnary(
            PLUS, ValueBuilder::makeDouble(curr->value.getf64()));
        }
        default:
          Fatal() << "unknown const type";
      }
    }

    Ref visitUnary(Unary* curr) {
      // normal unary
      switch (curr->type.getBasic()) {
        case Type::i32: {
          switch (curr->op) {
            case ClzInt32: {
              return ValueBuilder::makeCall(
                MATH_CLZ32, visit(curr->value, EXPRESSION_RESULT));
            }
            case CtzInt32:
            case PopcntInt32: {
              WASM_UNREACHABLE("i32 unary should have been removed");
            }
            case EqZInt32: {
              // XXX !x does change the type to bool, which is correct, but may
              // be slower?
              return ValueBuilder::makeUnary(
                L_NOT, visit(curr->value, EXPRESSION_RESULT));
            }
            case ReinterpretFloat32: {
              ABI::wasm2js::ensureHelpers(module,
                                          ABI::wasm2js::SCRATCH_STORE_F32);
              ABI::wasm2js::ensureHelpers(module,
                                          ABI::wasm2js::SCRATCH_LOAD_I32);

              Ref store =
                ValueBuilder::makeCall(ABI::wasm2js::SCRATCH_STORE_F32,
                                       visit(curr->value, EXPRESSION_RESULT));
              // 32-bit scratch memory uses index 2, so that it does not
              // conflict with indexes 0, 1 which are used for 64-bit, see
              // comment where |scratchBuffer| is defined.
              Ref load = ValueBuilder::makeCall(ABI::wasm2js::SCRATCH_LOAD_I32,
                                                ValueBuilder::makeInt(2));
              return ValueBuilder::makeSeq(store, load);
            }
            // generate (~~expr), what Emscripten does
            case TruncSFloat32ToInt32:
            case TruncSFloat64ToInt32:
            case TruncSatSFloat32ToInt32:
            case TruncSatSFloat64ToInt32: {
              return ValueBuilder::makeUnary(
                B_NOT,
                ValueBuilder::makeUnary(B_NOT,
                                        visit(curr->value, EXPRESSION_RESULT)));
            }
            // generate (~~expr >>> 0), what Emscripten does
            case TruncUFloat32ToInt32:
            case TruncUFloat64ToInt32:
            case TruncSatUFloat32ToInt32:
            case TruncSatUFloat64ToInt32: {
              return ValueBuilder::makeBinary(
                ValueBuilder::makeUnary(
                  B_NOT,
                  ValueBuilder::makeUnary(
                    B_NOT, visit(curr->value, EXPRESSION_RESULT))),
                TRSHIFT,
                ValueBuilder::makeNum(0));
            }
            case ExtendS8Int32: {
              return ValueBuilder::makeBinary(
                ValueBuilder::makeBinary(visit(curr->value, EXPRESSION_RESULT),
                                         LSHIFT,
                                         ValueBuilder::makeNum(24)),
                RSHIFT,
                ValueBuilder::makeNum(24));
            }
            case ExtendS16Int32: {
              return ValueBuilder::makeBinary(
                ValueBuilder::makeBinary(visit(curr->value, EXPRESSION_RESULT),
                                         LSHIFT,
                                         ValueBuilder::makeNum(16)),
                RSHIFT,
                ValueBuilder::makeNum(16));
            }
            default:
              WASM_UNREACHABLE("unhandled unary");
          }
        }
        case Type::f32:
        case Type::f64: {
          Ref ret;
          switch (curr->op) {
            case NegFloat32:
            case NegFloat64:
              ret = ValueBuilder::makeUnary(
                MINUS, visit(curr->value, EXPRESSION_RESULT));
              break;
            case AbsFloat32:
            case AbsFloat64:
              ret = ValueBuilder::makeCall(
                MATH_ABS, visit(curr->value, EXPRESSION_RESULT));
              break;
            case CeilFloat32:
            case CeilFloat64:
              ret = ValueBuilder::makeCall(
                MATH_CEIL, visit(curr->value, EXPRESSION_RESULT));
              break;
            case FloorFloat32:
            case FloorFloat64:
              ret = ValueBuilder::makeCall(
                MATH_FLOOR, visit(curr->value, EXPRESSION_RESULT));
              break;
            case TruncFloat32:
            case TruncFloat64:
              ret = ValueBuilder::makeCall(
                MATH_TRUNC, visit(curr->value, EXPRESSION_RESULT));
              break;
            case SqrtFloat32:
            case SqrtFloat64:
              ret = ValueBuilder::makeCall(
                MATH_SQRT, visit(curr->value, EXPRESSION_RESULT));
              break;
            case PromoteFloat32:
              return makeJsCoercion(visit(curr->value, EXPRESSION_RESULT),
                                    JS_DOUBLE);
            case DemoteFloat64:
              return makeJsCoercion(visit(curr->value, EXPRESSION_RESULT),
                                    JS_FLOAT);
            case ReinterpretInt32: {
              ABI::wasm2js::ensureHelpers(module,
                                          ABI::wasm2js::SCRATCH_STORE_I32);
              ABI::wasm2js::ensureHelpers(module,
                                          ABI::wasm2js::SCRATCH_LOAD_F32);

              // 32-bit scratch memory uses index 2, so that it does not
              // conflict with indexes 0, 1 which are used for 64-bit, see
              // comment where |scratchBuffer| is defined.
              Ref store =
                ValueBuilder::makeCall(ABI::wasm2js::SCRATCH_STORE_I32,
                                       ValueBuilder::makeNum(2),
                                       visit(curr->value, EXPRESSION_RESULT));
              Ref load = ValueBuilder::makeCall(ABI::wasm2js::SCRATCH_LOAD_F32);
              return ValueBuilder::makeSeq(store, load);
            }
            // Coerce the integer to a float as emscripten does
            case ConvertSInt32ToFloat32:
              return makeJsCoercion(
                makeJsCoercion(visit(curr->value, EXPRESSION_RESULT), JS_INT),
                JS_FLOAT);
            case ConvertSInt32ToFloat64:
              return makeJsCoercion(
                makeJsCoercion(visit(curr->value, EXPRESSION_RESULT), JS_INT),
                JS_DOUBLE);

            // Generate (expr >>> 0), followed by a coercion
            case ConvertUInt32ToFloat32:
              return makeJsCoercion(
                ValueBuilder::makeBinary(visit(curr->value, EXPRESSION_RESULT),
                                         TRSHIFT,
                                         ValueBuilder::makeInt(0)),
                JS_FLOAT);
            case ConvertUInt32ToFloat64:
              return makeJsCoercion(
                ValueBuilder::makeBinary(visit(curr->value, EXPRESSION_RESULT),
                                         TRSHIFT,
                                         ValueBuilder::makeInt(0)),
                JS_DOUBLE);
            // TODO: more complex unary conversions
            case NearestFloat32:
            case NearestFloat64:
              WASM_UNREACHABLE(
                "operation should have been removed in previous passes");

            default:
              WASM_UNREACHABLE("unhandled unary float operator");
          }
          if (curr->type == Type::f32) { // doubles need much less coercing
            return makeJsCoercion(ret, JS_FLOAT);
          }
          return ret;
        }
        default: {
          Fatal() << "Unhandled type in unary: " << *curr;
        }
      }
    }

    Ref visitBinary(Binary* curr) {
      // normal binary
      Ref left = visit(curr->left, EXPRESSION_RESULT);
      Ref right = visit(curr->right, EXPRESSION_RESULT);
      Ref ret;
      switch (curr->type.getBasic()) {
        case Type::i32: {
          switch (curr->op) {
            case AddInt32:
              ret = ValueBuilder::makeBinary(left, PLUS, right);
              break;
            case SubInt32:
              ret = ValueBuilder::makeBinary(left, MINUS, right);
              break;
            case MulInt32: {
              if (curr->type == Type::i32) {
                // TODO: when one operand is a small int, emit a multiply
                return ValueBuilder::makeCall(MATH_IMUL, left, right);
              } else {
                return ValueBuilder::makeBinary(left, MUL, right);
              }
            }
            case DivSInt32:
              ret = ValueBuilder::makeBinary(makeSigning(left, JS_SIGNED),
                                             DIV,
                                             makeSigning(right, JS_SIGNED));
              break;
            case DivUInt32:
              ret = ValueBuilder::makeBinary(makeSigning(left, JS_UNSIGNED),
                                             DIV,
                                             makeSigning(right, JS_UNSIGNED));
              break;
            case RemSInt32:
              ret = ValueBuilder::makeBinary(makeSigning(left, JS_SIGNED),
                                             MOD,
                                             makeSigning(right, JS_SIGNED));
              break;
            case RemUInt32:
              ret = ValueBuilder::makeBinary(makeSigning(left, JS_UNSIGNED),
                                             MOD,
                                             makeSigning(right, JS_UNSIGNED));
              break;
            case AndInt32:
              ret = ValueBuilder::makeBinary(left, AND, right);
              break;
            case OrInt32:
              ret = ValueBuilder::makeBinary(left, OR, right);
              break;
            case XorInt32:
              ret = ValueBuilder::makeBinary(left, XOR, right);
              break;
            case ShlInt32:
              ret = ValueBuilder::makeBinary(left, LSHIFT, right);
              break;
            case ShrUInt32:
              ret = ValueBuilder::makeBinary(left, TRSHIFT, right);
              break;
            case ShrSInt32:
              ret = ValueBuilder::makeBinary(left, RSHIFT, right);
              break;
            case EqInt32: {
              return ValueBuilder::makeBinary(makeSigning(left, JS_SIGNED),
                                              EQ,
                                              makeSigning(right, JS_SIGNED));
            }
            case NeInt32: {
              return ValueBuilder::makeBinary(makeSigning(left, JS_SIGNED),
                                              NE,
                                              makeSigning(right, JS_SIGNED));
            }
            case LtSInt32:
              return ValueBuilder::makeBinary(makeSigning(left, JS_SIGNED),
                                              LT,
                                              makeSigning(right, JS_SIGNED));
            case LtUInt32:
              return ValueBuilder::makeBinary(makeSigning(left, JS_UNSIGNED),
                                              LT,
                                              makeSigning(right, JS_UNSIGNED));
            case LeSInt32:
              return ValueBuilder::makeBinary(makeSigning(left, JS_SIGNED),
                                              LE,
                                              makeSigning(right, JS_SIGNED));
            case LeUInt32:
              return ValueBuilder::makeBinary(makeSigning(left, JS_UNSIGNED),
                                              LE,
                                              makeSigning(right, JS_UNSIGNED));
            case GtSInt32:
              return ValueBuilder::makeBinary(makeSigning(left, JS_SIGNED),
                                              GT,
                                              makeSigning(right, JS_SIGNED));
            case GtUInt32:
              return ValueBuilder::makeBinary(makeSigning(left, JS_UNSIGNED),
                                              GT,
                                              makeSigning(right, JS_UNSIGNED));
            case GeSInt32:
              return ValueBuilder::makeBinary(makeSigning(left, JS_SIGNED),
                                              GE,
                                              makeSigning(right, JS_SIGNED));
            case GeUInt32:
              return ValueBuilder::makeBinary(makeSigning(left, JS_UNSIGNED),
                                              GE,
                                              makeSigning(right, JS_UNSIGNED));
            case EqFloat32:
            case EqFloat64:
              return ValueBuilder::makeBinary(left, EQ, right);
            case NeFloat32:
            case NeFloat64:
              return ValueBuilder::makeBinary(left, NE, right);
            case GeFloat32:
            case GeFloat64:
              return ValueBuilder::makeBinary(left, GE, right);
            case GtFloat32:
            case GtFloat64:
              return ValueBuilder::makeBinary(left, GT, right);
            case LeFloat32:
            case LeFloat64:
              return ValueBuilder::makeBinary(left, LE, right);
            case LtFloat32:
            case LtFloat64:
              return ValueBuilder::makeBinary(left, LT, right);
            case RotLInt32:
            case RotRInt32:
              WASM_UNREACHABLE("should be removed already");
            default:
              WASM_UNREACHABLE("unhandled i32 binary operator");
          }
          break;
        }
        case Type::f32:
        case Type::f64:
          switch (curr->op) {
            case AddFloat32:
            case AddFloat64:
              ret = ValueBuilder::makeBinary(left, PLUS, right);
              break;
            case SubFloat32:
            case SubFloat64:
              ret = ValueBuilder::makeBinary(left, MINUS, right);
              break;
            case MulFloat32:
            case MulFloat64:
              ret = ValueBuilder::makeBinary(left, MUL, right);
              break;
            case DivFloat32:
            case DivFloat64:
              ret = ValueBuilder::makeBinary(left, DIV, right);
              break;
            case MinFloat32:
            case MinFloat64:
              ret = ValueBuilder::makeCall(MATH_MIN, left, right);
              break;
            case MaxFloat32:
            case MaxFloat64:
              ret = ValueBuilder::makeCall(MATH_MAX, left, right);
              break;
            case CopySignFloat32:
            case CopySignFloat64:
            default:
              Fatal() << "Unhandled binary float operator: ";
          }
          if (curr->type == Type::f32) {
            return makeJsCoercion(ret, JS_FLOAT);
          }
          return ret;
        default:
          Fatal() << "Unhandled type in binary: " << *curr;
      }
      return makeJsCoercion(ret, wasmToJsType(curr->type));
    }

    Ref visitWideIntAddSub(WideIntAddSub* curr) {
      WASM_UNREACHABLE("wide arithmetic is not supported by wasm2js");
    }

    Ref visitWideIntMul(WideIntMul* curr) {
      WASM_UNREACHABLE("wide arithmetic is not supported by wasm2js");
    }

    Ref visitSelect(Select* curr) {
      // If the condition has effects that interact with the operands, we must
      // reorder it to the start. We must also use locals if the values have
      // side effects, as a JS conditional does not visit both sides.
      bool useLocals = false;
      EffectAnalyzer conditionEffects(
        parent->options, *module, curr->condition);
      EffectAnalyzer ifTrueEffects(parent->options, *module, curr->ifTrue);
      EffectAnalyzer ifFalseEffects(parent->options, *module, curr->ifFalse);
      if (conditionEffects.invalidates(ifTrueEffects) ||
          conditionEffects.invalidates(ifFalseEffects) ||
          ifTrueEffects.hasSideEffects() || ifFalseEffects.hasSideEffects()) {
        useLocals = true;
      }
      if (useLocals) {
        ScopedTemp tempIfTrue(curr->type, parent, func),
          tempIfFalse(curr->type, parent, func),
          tempCondition(Type::i32, parent, func);
        Ref ifTrue = visit(curr->ifTrue, EXPRESSION_RESULT);
        Ref ifFalse = visit(curr->ifFalse, EXPRESSION_RESULT);
        Ref condition = visit(curr->condition, EXPRESSION_RESULT);
        return ValueBuilder::makeSeq(
          ValueBuilder::makeBinary(tempIfTrue.getAstName(), SET, ifTrue),
          ValueBuilder::makeSeq(
            ValueBuilder::makeBinary(tempIfFalse.getAstName(), SET, ifFalse),
            ValueBuilder::makeSeq(
              ValueBuilder::makeBinary(
                tempCondition.getAstName(), SET, condition),
              ValueBuilder::makeConditional(tempCondition.getAstName(),
                                            tempIfTrue.getAstName(),
                                            tempIfFalse.getAstName()))));
      } else {
        // Simple case without reordering.
        return ValueBuilder::makeConditional(
          visit(curr->condition, EXPRESSION_RESULT),
          visit(curr->ifTrue, EXPRESSION_RESULT),
          visit(curr->ifFalse, EXPRESSION_RESULT));
      }
    }

    Ref visitReturn(Return* curr) {
      if (!curr->value) {
        return ValueBuilder::makeReturn(Ref());
      }
      Ref val = visit(curr->value, EXPRESSION_RESULT);
      bool needCoercion =
        parent->options.optimizeLevel == 0 || standaloneFunction ||
        parent->functionsCallableFromOutside.contains(func->name);
      if (needCoercion) {
        val = makeJsCoercion(val, wasmToJsType(curr->value->type));
      }
      return ValueBuilder::makeReturn(val);
    }

    Ref visitMemorySize(MemorySize* curr) {
      return ValueBuilder::makeCall(WASM_MEMORY_SIZE);
    }

    Ref visitMemoryGrow(MemoryGrow* curr) {
      if (!module->memories.empty() &&
          module->memories[0]->max > module->memories[0]->initial) {
        return ValueBuilder::makeCall(
          WASM_MEMORY_GROW,
          makeJsCoercion(visit(curr->delta, EXPRESSION_RESULT),
                         wasmToJsType(curr->delta->type)));
      } else {
        ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TRAP);
        return ValueBuilder::makeCall(ABI::wasm2js::TRAP);
      }
    }

    Ref visitNop(Nop* curr) { return ValueBuilder::makeToplevel(); }
    Ref visitUnreachable(Unreachable* curr) {
      ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TRAP);
      return ValueBuilder::makeCall(ABI::wasm2js::TRAP);
    }

    // Atomics

    struct HeapAndPointer {
      Ref heap;
      Ref ptr;
    };

    HeapAndPointer
    getHeapAndAdjustedPointer(Index bytes, Expression* ptr, Index offset) {
      IString heap;
      Ref adjustedPtr = makePointer(ptr, offset);
      switch (bytes) {
        case 1:
          heap = HEAP8;
          break;
        case 2:
          heap = HEAP16;
          adjustedPtr = ValueBuilder::makePtrShift(adjustedPtr, 1);
          break;
        case 4:
          heap = HEAP32;
          adjustedPtr = ValueBuilder::makePtrShift(adjustedPtr, 2);
          break;
        default: {
          WASM_UNREACHABLE("unimp");
        }
      }
      return {ValueBuilder::makeName(heap), adjustedPtr};
    }

    Ref visitAtomicRMW(AtomicRMW* curr) {
      auto hap =
        getHeapAndAdjustedPointer(curr->bytes, curr->ptr, curr->offset);
      IString target;
      switch (curr->op) {
        case RMWAdd:
          target = IString("add");
          break;
        case RMWSub:
          target = IString("sub");
          break;
        case RMWAnd:
          target = IString("and");
          break;
        case RMWOr:
          target = IString("or");
          break;
        case RMWXor:
          target = IString("xor");
          break;
        case RMWXchg:
          target = IString("exchange");
          break;
        default:
          WASM_UNREACHABLE("unimp");
      }
      Ref call = ValueBuilder::makeCall(
        ValueBuilder::makeDot(ValueBuilder::makeName(ATOMICS), target));
      ValueBuilder::appendToCall(call, hap.heap);
      ValueBuilder::appendToCall(call, hap.ptr);
      ValueBuilder::appendToCall(call, visit(curr->value, EXPRESSION_RESULT));
      return call;
    }

    Ref visitAtomicCmpxchg(AtomicCmpxchg* curr) {
      auto hap =
        getHeapAndAdjustedPointer(curr->bytes, curr->ptr, curr->offset);
      Ref expected = visit(curr->expected, EXPRESSION_RESULT);
      Ref replacement = visit(curr->replacement, EXPRESSION_RESULT);
      Ref call = ValueBuilder::makeCall(ValueBuilder::makeDot(
        ValueBuilder::makeName(ATOMICS), COMPARE_EXCHANGE));
      ValueBuilder::appendToCall(call, hap.heap);
      ValueBuilder::appendToCall(call, hap.ptr);
      ValueBuilder::appendToCall(call, expected);
      ValueBuilder::appendToCall(call, replacement);
      return makeJsCoercion(call, wasmToJsType(curr->type));
    }

    Ref visitAtomicWait(AtomicWait* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }

    Ref visitAtomicNotify(AtomicNotify* curr) {
      Ref call = ValueBuilder::makeCall(ValueBuilder::makeDot(
        ValueBuilder::makeName(ATOMICS), IString("notify")));
      ValueBuilder::appendToCall(call, ValueBuilder::makeName(HEAP32));
      ValueBuilder::appendToCall(
        call,
        ValueBuilder::makePtrShift(makePointer(curr->ptr, curr->offset), 2));
      ValueBuilder::appendToCall(
        call,
        makeSigning(visit(curr->notifyCount, EXPRESSION_RESULT), JS_UNSIGNED));
      return call;
    }

    Ref visitAtomicFence(AtomicFence* curr) {
      // Sequentially consistent fences can be lowered to no operation
      return ValueBuilder::makeToplevel();
    }

    // TODOs

    Ref visitPause(Pause* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }

    Ref visitSIMDExtract(SIMDExtract* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitSIMDReplace(SIMDReplace* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitSIMDShuffle(SIMDShuffle* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitSIMDTernary(SIMDTernary* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitSIMDShift(SIMDShift* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitSIMDLoad(SIMDLoad* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitMemoryInit(MemoryInit* curr) {
      ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::MEMORY_INIT);
      return ValueBuilder::makeCall(
        ABI::wasm2js::MEMORY_INIT,
        ValueBuilder::makeNum(parent->getDataIndex(curr->segment)),
        visit(curr->dest, EXPRESSION_RESULT),
        visit(curr->offset, EXPRESSION_RESULT),
        visit(curr->size, EXPRESSION_RESULT));
    }
    Ref visitDataDrop(DataDrop* curr) {
      ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::DATA_DROP);
      return ValueBuilder::makeCall(
        ABI::wasm2js::DATA_DROP,
        ValueBuilder::makeNum(parent->getDataIndex(curr->segment)));
    }
    Ref visitMemoryCopy(MemoryCopy* curr) {
      ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::MEMORY_COPY);
      return ValueBuilder::makeCall(ABI::wasm2js::MEMORY_COPY,
                                    visit(curr->dest, EXPRESSION_RESULT),
                                    visit(curr->source, EXPRESSION_RESULT),
                                    visit(curr->size, EXPRESSION_RESULT));
    }
    Ref visitMemoryFill(MemoryFill* curr) {
      ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::MEMORY_FILL);
      return ValueBuilder::makeCall(ABI::wasm2js::MEMORY_FILL,
                                    visit(curr->dest, EXPRESSION_RESULT),
                                    visit(curr->value, EXPRESSION_RESULT),
                                    visit(curr->size, EXPRESSION_RESULT));
    }
    Ref visitRefNull(RefNull* curr) { return ValueBuilder::makeName(NULL_); }
    Ref visitRefIsNull(RefIsNull* curr) {
      return ValueBuilder::makeBinary(visit(curr->value, EXPRESSION_RESULT),
                                      EQ,
                                      ValueBuilder::makeName(NULL_));
    }
    Ref visitRefFunc(RefFunc* curr) {
      return ValueBuilder::makeName(fromName(curr->func, NameScope::Top));
    }
    Ref visitRefEq(RefEq* curr) {
      return ValueBuilder::makeBinary(visit(curr->left, EXPRESSION_RESULT),
                                      EQ,
                                      visit(curr->right, EXPRESSION_RESULT));
    }
    Ref visitTableGet(TableGet* curr) {
      return ValueBuilder::makeSub(ValueBuilder::makeName(FUNCTION_TABLE),
                                   visit(curr->index, EXPRESSION_RESULT));
    }
    Ref visitTableSet(TableSet* curr) {
      auto sub = ValueBuilder::makeSub(ValueBuilder::makeName(FUNCTION_TABLE),
                                       visit(curr->index, EXPRESSION_RESULT));
      auto value = visit(curr->value, EXPRESSION_RESULT);
      return ValueBuilder::makeBinary(sub, SET, value);
    }
    Ref visitTableSize(TableSize* curr) {
      return ValueBuilder::makeDot(ValueBuilder::makeName(FUNCTION_TABLE),
                                   ValueBuilder::makeName(LENGTH));
    }
    Ref visitTableGrow(TableGrow* curr) {
      ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TABLE_GROW);
      // Also ensure fill, as grow calls fill internally.
      ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TABLE_FILL);
      return ValueBuilder::makeCall(ABI::wasm2js::TABLE_GROW,
                                    visit(curr->value, EXPRESSION_RESULT),
                                    visit(curr->delta, EXPRESSION_RESULT));
    }
    Ref visitTableFill(TableFill* curr) {
      ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TABLE_FILL);
      return ValueBuilder::makeCall(ABI::wasm2js::TABLE_FILL,
                                    visit(curr->dest, EXPRESSION_RESULT),
                                    visit(curr->value, EXPRESSION_RESULT),
                                    visit(curr->size, EXPRESSION_RESULT));
    }
    Ref visitTableCopy(TableCopy* curr) {
      ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TABLE_COPY);
      return ValueBuilder::makeCall(ABI::wasm2js::TABLE_COPY,
                                    visit(curr->dest, EXPRESSION_RESULT),
                                    visit(curr->source, EXPRESSION_RESULT),
                                    visit(curr->size, EXPRESSION_RESULT));
    }
    Ref visitTableInit(TableInit* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitElemDrop(ElemDrop* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitTry(Try* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitTryTable(TryTable* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitThrow(Throw* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitRethrow(Rethrow* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitThrowRef(ThrowRef* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitPop(Pop* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitTupleMake(TupleMake* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitTupleExtract(TupleExtract* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitRefI31(RefI31* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitI31Get(I31Get* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitCallRef(CallRef* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitRefTest(RefTest* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitRefCast(RefCast* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitRefGetDesc(RefGetDesc* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitBrOn(BrOn* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitStructNew(StructNew* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitStructGet(StructGet* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitStructSet(StructSet* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitStructRMW(StructRMW* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitStructCmpxchg(StructCmpxchg* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitStructWait(StructWait* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitWaitqueueNew(WaitqueueNew* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitWaitqueueNotify(WaitqueueNotify* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitArrayNew(ArrayNew* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitArrayNewData(ArrayNewData* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitArrayNewElem(ArrayNewElem* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitArrayNewFixed(ArrayNewFixed* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitArrayGet(ArrayGet* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitArraySet(ArraySet* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitArrayLoad(ArrayLoad* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitArrayStore(ArrayStore* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitArrayLen(ArrayLen* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitArrayCopy(ArrayCopy* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitArrayFill(ArrayFill* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitArrayInitData(ArrayInitData* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitArrayInitElem(ArrayInitElem* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitArrayRMW(ArrayRMW* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitArrayCmpxchg(ArrayCmpxchg* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitStringNew(StringNew* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitStringConst(StringConst* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitStringMeasure(StringMeasure* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitStringEncode(StringEncode* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitStringConcat(StringConcat* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitStringEq(StringEq* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitStringTest(StringTest* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitStringWTF16Get(StringWTF16Get* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitStringSliceWTF(StringSliceWTF* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitRefAs(RefAs* curr) {
      // TODO: support others
      assert(curr->op == RefAsNonNull);

      // value || trap()
      ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TRAP);
      return ValueBuilder::makeBinary(
        visit(curr->value, EXPRESSION_RESULT),
        IString("||"),
        ValueBuilder::makeCall(ABI::wasm2js::TRAP));
    }

    Ref visitContNew(ContNew* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitContBind(ContBind* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitSuspend(Suspend* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitResume(Resume* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitResumeThrow(ResumeThrow* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }
    Ref visitStackSwitch(StackSwitch* curr) {
      unimplemented(curr);
      WASM_UNREACHABLE("unimp");
    }

  private:
    Ref makePointer(Expression* ptr, Address offset) {
      auto ret = visit(ptr, EXPRESSION_RESULT);
      if (offset) {
        ret = makeJsCoercion(
          ValueBuilder::makeBinary(ret, PLUS, ValueBuilder::makeNum(offset)),
          JS_INT);
      }
      return ret;
    }

    void unimplemented(Expression* curr) {
      Fatal() << "wasm2js cannot convert " << *curr;
    }
  };

  return ExpressionProcessor(this, m, func, standaloneFunction).process(curr);
}

void Wasm2JSBuilder::addMemoryFuncs(Ref ast, Module* wasm) {
  Ref memorySizeFunc = ValueBuilder::makeFunction(WASM_MEMORY_SIZE);
  memorySizeFunc[3]->push_back(
    ValueBuilder::makeReturn(ValueBuilder::makeBinary(
      ValueBuilder::makeDot(ValueBuilder::makeName(BUFFER),
                            IString("byteLength")),
      RSHIFT,
      ValueBuilder::makeInt(wasm->memories[0]->pageSizeLog2))));
  ast->push_back(memorySizeFunc);

  if (!wasm->memories.empty() &&
      wasm->memories[0]->max > wasm->memories[0]->initial) {
    addMemoryGrowFunc(ast, wasm);
  }
}

void Wasm2JSBuilder::addMemoryGrowFunc(Ref ast, Module* wasm) {
  Ref memoryGrowFunc = ValueBuilder::makeFunction(WASM_MEMORY_GROW);
  ValueBuilder::appendArgumentToFunction(memoryGrowFunc, IString("pagesToAdd"));

  memoryGrowFunc[3]->push_back(
    ValueBuilder::makeStatement(ValueBuilder::makeBinary(
      ValueBuilder::makeName(IString("pagesToAdd")),
      SET,
      makeJsCoercion(ValueBuilder::makeName(IString("pagesToAdd")),
                     JsType::JS_INT))));

  Ref oldPages = ValueBuilder::makeVar();
  memoryGrowFunc[3]->push_back(oldPages);
  ValueBuilder::appendToVar(
    oldPages,
    IString("oldPages"),
    makeJsCoercion(ValueBuilder::makeCall(WASM_MEMORY_SIZE), JsType::JS_INT));

  Ref newPages = ValueBuilder::makeVar();
  memoryGrowFunc[3]->push_back(newPages);
  ValueBuilder::appendToVar(
    newPages,
    IString("newPages"),
    makeJsCoercion(
      ValueBuilder::makeBinary(ValueBuilder::makeName(IString("oldPages")),
                               PLUS,
                               ValueBuilder::makeName(IString("pagesToAdd"))),
      JsType::JS_INT));

  Ref block = ValueBuilder::makeBlock();
  Ref condition = ValueBuilder::makeBinary(
    ValueBuilder::makeBinary(ValueBuilder::makeName(IString("oldPages")),
                             LT,
                             ValueBuilder::makeName(IString("newPages"))),
    IString("&&"),
    ValueBuilder::makeBinary(
      ValueBuilder::makeName(IString("newPages")),
      LT,
      ValueBuilder::makeNum(wasm->memories[0]->maxSize32())));
  // Also enforce the module's declared memory maximum, if one exists.
  if (!wasm->memories.empty() && wasm->memories[0]->hasMax()) {
    condition = ValueBuilder::makeBinary(
      condition,
      IString("&&"),
      ValueBuilder::makeBinary(ValueBuilder::makeName(IString("newPages")),
                               LE,
                               ValueBuilder::makeInt(static_cast<uint32_t>(
                                 wasm->memories[0]->max.addr))));
  }
  memoryGrowFunc[3]->push_back(ValueBuilder::makeIf(condition, block, NULL));

  Ref newBuffer = ValueBuilder::makeVar();
  ValueBuilder::appendToBlock(block, newBuffer);
  ValueBuilder::appendToVar(
    newBuffer,
    IString("newBuffer"),
    ValueBuilder::makeNew(ValueBuilder::makeCall(
      ARRAY_BUFFER,
      ValueBuilder::makeBinary(
        ValueBuilder::makeName(IString("newPages")),
        LSHIFT,
        ValueBuilder::makeInt(wasm->memories[0]->pageSizeLog2)))));

  Ref newHEAP8 = ValueBuilder::makeVar();
  ValueBuilder::appendToBlock(block, newHEAP8);
  ValueBuilder::appendToVar(newHEAP8,
                            IString("newHEAP8"),
                            ValueBuilder::makeNew(ValueBuilder::makeCall(
                              ValueBuilder::makeName(INT8ARRAY),
                              ValueBuilder::makeName(IString("newBuffer")))));

  ValueBuilder::appendToBlock(
    block,
    ValueBuilder::makeCall(
      ValueBuilder::makeDot(ValueBuilder::makeName(IString("newHEAP8")),
                            IString("set")),
      ValueBuilder::makeName(HEAP8)));

  auto setHeap = [&](IString name, IString view) {
    ValueBuilder::appendToBlock(
      block,
      ValueBuilder::makeBinary(
        ValueBuilder::makeName(name),
        SET,
        ValueBuilder::makeNew(ValueBuilder::makeCall(
          ValueBuilder::makeName(view),
          ValueBuilder::makeName(IString("newBuffer"))))));
  };

  setHeap(HEAP8, INT8ARRAY);
  setHeap(HEAP16, INT16ARRAY);
  setHeap(HEAP32, INT32ARRAY);
  setHeap(HEAPU8, UINT8ARRAY);
  setHeap(HEAPU16, UINT16ARRAY);
  setHeap(HEAPU32, UINT32ARRAY);
  setHeap(HEAPF32, FLOAT32ARRAY);
  setHeap(HEAPF64, FLOAT64ARRAY);

  ValueBuilder::appendToBlock(
    block,
    ValueBuilder::makeBinary(ValueBuilder::makeName(BUFFER),
                             SET,
                             ValueBuilder::makeName(IString("newBuffer"))));

  // apply the changes to the memory import
  if (!wasm->memories.empty() && wasm->memories[0]->imported()) {
    ValueBuilder::appendToBlock(
      block,
      ValueBuilder::makeBinary(
        ValueBuilder::makeDot(ValueBuilder::makeName("memory"),
                              ValueBuilder::makeName(BUFFER)),
        SET,
        ValueBuilder::makeName(BUFFER)));
  }

  if (needsBufferView(*wasm)) {
    ValueBuilder::appendToBlock(
      block,
      ValueBuilder::makeBinary(ValueBuilder::makeName("bufferView"),
                               SET,
                               ValueBuilder::makeName(HEAPU8)));
  }

  memoryGrowFunc[3]->push_back(
    ValueBuilder::makeReturn(ValueBuilder::makeName(IString("oldPages"))));

  ast->push_back(memoryGrowFunc);
}

// Wasm2JSBuilder emits the core of the module - the functions etc. that would
// be the asm.js function in an asm.js world. This class emits the rest of the
// "glue" around that.
class Wasm2JSGlue {
public:
  Wasm2JSGlue(Module& wasm,
              Output& out,
              Wasm2JSBuilder::Flags flags,
              Name moduleName)
    : wasm(wasm), out(out), flags(flags), moduleName(moduleName) {}

  void emitPre();
  void emitPost();

private:
  Module& wasm;
  Output& out;
  Wasm2JSBuilder::Flags flags;
  Name moduleName;

  void emitPreEmscripten();
  void emitPreES6();
  void emitPostEmscripten();
  void emitPostES6();

  void emitMemory();
  void emitSpecialSupport();
};

void Wasm2JSGlue::emitPre() {
  if (flags.emscripten) {
    emitPreEmscripten();
  } else {
    emitPreES6();
  }

  if (isTableExported(wasm)) {
    out << "function Table(ret) {\n";
    if (wasm.tables[0]->initial == wasm.tables[0]->max) {
      out << "  // grow method not included; table is not growable\n";
    } else {
      out << "  ret.grow = function(by) {\n"
          << "    var old = this.length;\n"
          << "    this.length = this.length + by;\n"
          << "    return old;\n"
          << "  };\n";
    }
    out << "  ret.set = function(i, func) {\n"
        << "    this[i] = func;\n"
        << "  };\n"
        << "  ret.get = function(i) {\n"
        << "    return this[i];\n"
        << "  };\n"
        << "  return ret;\n"
        << "}\n\n";
  }

  emitMemory();
  emitSpecialSupport();
}

void Wasm2JSGlue::emitPreEmscripten() {
  out << "function instantiate(info) {\n";
}

void Wasm2JSGlue::emitPreES6() {
  std::unordered_map<Name, Name> baseModuleMap;
  std::unordered_set<Name> seenModules;

  auto noteImport = [&](Name module, Name base) {
    // Right now codegen requires a flat namespace going into the module,
    // meaning we don't support importing the same name from multiple namespaces
    // yet.
    if (baseModuleMap.contains(base) && baseModuleMap[base] != module) {
      Fatal() << "the name " << base << " cannot be imported from "
              << "two different modules yet";
    }
    baseModuleMap[base] = module;
    if (!seenModules.contains(module)) {
      out << "import * as " << asmangle(module.toString()) << " from '"
          << module << "';\n";
      seenModules.insert(module);
    }
  };

  ImportInfo imports(wasm);

  ModuleUtils::iterImportedGlobals(
    wasm, [&](Global* import) { noteImport(import->module, import->base); });
  ModuleUtils::iterImportedTables(
    wasm, [&](Table* import) { noteImport(import->module, import->base); });
  ModuleUtils::iterImportedFunctions(wasm, [&](Function* import) {
    // The special helpers are emitted in the glue, see code and comments
    // below.
    if (ABI::wasm2js::isHelper(import->base)) {
      return;
    }
    noteImport(import->module, import->base);
  });

  out << '\n';
}

void Wasm2JSGlue::emitPost() {
  if (flags.emscripten) {
    emitPostEmscripten();
  } else {
    emitPostES6();
  }
}

void Wasm2JSGlue::emitPostEmscripten() {
  out << "  return asmFunc(info);\n}\n";
}

void Wasm2JSGlue::emitPostES6() {
  // Create an initial `ArrayBuffer` and populate it with static data.
  // Currently we use base64 encoding to encode static data and we decode it at
  // instantiation time.
  //
  // Note that the translation here expects that the lower values of this memory
  // can be used for conversions, so make sure there's at least one page.
  if (!wasm.memories.empty() && wasm.memories[0]->imported()) {
    out << "var mem" << moduleName.str << " = new ArrayBuffer("
        << (wasm.memories[0]->initial.addr << wasm.memories[0]->pageSizeLog2)
        << ");\n";
  }

  // Actually invoke the `asmFunc` generated function, passing in all global
  // values followed by all imports
  out << "var ret" << moduleName.str << " = " << moduleName.str << "({\n";

  std::unordered_set<Name> seenModules;

  ModuleUtils::iterImportedFunctions(wasm, [&](Function* import) {
    // The special helpers are emitted in the glue, see code and comments
    // below.
    if (ABI::wasm2js::isHelper(import->base)) {
      return;
    }
    if (seenModules.contains(import->module)) {
      return;
    }
    out << "  \"" << import->module
        << "\": " << asmangle(import->module.toString()) << ",\n";
    seenModules.insert(import->module);
  });

  ModuleUtils::iterImportedMemories(wasm, [&](Memory* import) {
    // The special helpers are emitted in the glue, see code and comments
    // below.
    if (ABI::wasm2js::isHelper(import->base)) {
      return;
    }
    out << "  \"" << import->module << "\": {\n";
    out << "    " << asmangle(import->base.toString()) << ": { buffer : mem"
        << moduleName.str << " }\n";
    out << "  },\n";
  });

  ModuleUtils::iterImportedTables(wasm, [&](Table* import) {
    // The special helpers are emitted in the glue, see code and comments
    // below.
    if (ABI::wasm2js::isHelper(import->base)) {
      return;
    }
    if (seenModules.contains(import->module)) {
      return;
    }
    out << "  \"" << import->module
        << "\": " << asmangle(import->module.toString()) << ",\n";
    seenModules.insert(import->module);
  });

  out << "});\n";

  if (flags.allowAsserts) {
    return;
  }

  // And now that we have our returned instance, export all our functions
  // that are hanging off it.
  for (auto& exp : wasm.exports) {
    switch (exp->kind) {
      case ExternalKind::Function:
      case ExternalKind::Global:
      case ExternalKind::Memory:
        break;

      // Exported globals and function tables aren't supported yet
      default:
        continue;
    }
    out << "export var " << asmangle(exp->name.toString()) << " = ret"
        << moduleName << "." << asmangle(exp->name.toString()) << ";\n";
  }
}

void Wasm2JSGlue::emitMemory() {
  if (needsBufferView(wasm)) {
    // Create a helper bufferView to access the buffer if we need one. We use it
    // for creating memory segments if we have any (we may not if the segments
    // are shipped in a side .mem file, for example), and also in bulk memory
    // operations.
    // This will get assigned during `asmFunc` (and potentially re-assigned
    // during __wasm_memory_grow).
    // TODO: We should probably just share a single HEAPU8 var.
    out << "  var bufferView;\n";
  }

  // If there are no memory segments, we don't need to emit any support code for
  // segment creation.
  if (wasm.dataSegments.empty()) {
    return;
  }

  // If we have passive memory segments, we need to store those.
  for (auto& seg : wasm.dataSegments) {
    if (seg->isPassive) {
      out << "  var memorySegments = {};\n";
      break;
    }
  }

  out <<
    R"(  var base64ReverseLookup = new Uint8Array(123/*'z'+1*/);
  for (var i = 25; i >= 0; --i) {
    base64ReverseLookup[48+i] = 52+i; // '0-9'
    base64ReverseLookup[65+i] = i; // 'A-Z'
    base64ReverseLookup[97+i] = 26+i; // 'a-z'
  }
  base64ReverseLookup[43] = 62; // '+'
  base64ReverseLookup[47] = 63; // '/'
  /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */
  function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {
    var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');
    for (; i < bLength; i += 4) {
      b1 = base64ReverseLookup[b64.charCodeAt(i+1)];
      b2 = base64ReverseLookup[b64.charCodeAt(i+2)];
      uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;
      if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;
      if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];
    })";
  if (wasm.features.hasBulkMemory()) {
    // Passive segments in bulk memory are initialized into new arrays that are
    // passed into here, and we need to return them.
    out << R"(
    return uint8Array;)";
  }
  out << R"(
  }
)";

  for (Index i = 0; i < wasm.dataSegments.size(); i++) {
    auto& seg = wasm.dataSegments[i];
    if (seg->isPassive) {
      // Fancy passive segments are decoded into typed arrays on the side, for
      // later copying.
      out << "memorySegments[" << i
          << "] = base64DecodeToExistingUint8Array(new Uint8Array("
          << seg->data.size() << ")"
          << ", 0, \"" << base64Encode(seg->data) << "\");\n";
    }
  }

  if (hasActiveSegments(wasm)) {
    auto globalOffset = [&](const DataSegment& segment) {
      if (auto* c = segment.offset->dynCast<Const>()) {
        return std::to_string(c->value.getInteger());
      }
      if (auto* get = segment.offset->dynCast<GlobalGet>()) {
        auto internalName = get->name;
        auto importedGlobal = wasm.getGlobal(internalName);
        return std::string("imports['") + importedGlobal->module.toString() +
               "']['" + importedGlobal->base.toString() + "']";
      }
      Fatal() << "non-constant offsets aren't supported yet\n";
    };

    out << "function initActiveSegments(imports) {\n";
    for (Index i = 0; i < wasm.dataSegments.size(); i++) {
      auto& seg = wasm.dataSegments[i];
      if (!seg->isPassive) {
        // Plain active segments are decoded directly into the main memory.
        out << "  base64DecodeToExistingUint8Array(bufferView, "
            << globalOffset(*seg) << ", \"" << base64Encode(seg->data)
            << "\");\n";
      }
    }
    out << "}\n";
  }
}

void Wasm2JSGlue::emitSpecialSupport() {
  // The special support functions are emitted as part of the JS glue, if we
  // need them.
  bool need = false;
  bool needScratch = false;
  ModuleUtils::iterImportedFunctions(wasm, [&](Function* import) {
    if (ABI::wasm2js::isHelper(import->base)) {
      need = true;
    }
    if (import->base == ABI::wasm2js::SCRATCH_STORE_I32 ||
        import->base == ABI::wasm2js::SCRATCH_LOAD_I32 ||
        import->base == ABI::wasm2js::SCRATCH_STORE_F32 ||
        import->base == ABI::wasm2js::SCRATCH_LOAD_F32 ||
        import->base == ABI::wasm2js::SCRATCH_STORE_F64 ||
        import->base == ABI::wasm2js::SCRATCH_LOAD_F64) {
      needScratch = true;
    }
  });
  if (!need) {
    return;
  }

  // Scratch memory uses 3 indexes, each referring to 4 bytes. Indexes 0, 1 are
  // used for 64-bit operations, while 2 is for 32-bit. These operations need
  // separate indexes because we need to handle the case where the optimizer
  // reorders a 32-bit reinterpret in between a 64-bit's split-out parts.
  // That situation can occur because the 64-bit reinterpret was split up into
  // pieces early, in the 64-bit lowering pass, while the 32-bit reinterprets
  // are lowered only at the very end, and until then the optimizer sees wasm
  // reinterprets which have no side effects (but they will have the side effect
  // of altering scratch memory). That is, conceptual code like this:
  //
  //   a = reinterpret_64(b)
  //   x = reinterpret_32(y)
  //
  // turns into
  //
  //   scratch_write(b)
  //   a_low = scratch_read(0)
  //   a_high = scratch_read(1)
  //   x = reinterpret_32(y)
  //
  // (Note how the single wasm instruction for a 64-bit reinterpret turns into
  // multiple operations. We have to do such splitting, because in JS we will
  // have to have separate operations to receive each 32-bit chunk anyhow. A
  // *32*-bit reinterpret *could* be a single function, but given we have the
  // separate functions anyhow for the 64-bit case, it's more compact to reuse
  // those.)
  // At this point, the scratch_* functions look like they have side effects to
  // the optimizer (which is true, as they modify scratch memory), but the
  // reinterpret_32 is still a normal wasm instruction without side effects, so
  // the optimizer might do this:
  //
  //   scratch_write(b)
  //   a_low = scratch_read(0)
  //   x = reinterpret_32(y)    ;; this moved one line up
  //   a_high = scratch_read(1)
  //
  // When we do lower the reinterpret_32 into JS, we get:
  //
  //   scratch_write(b)
  //   a_low = scratch_read(0)
  //   scratch_write(y)
  //   x = scratch_read()
  //   a_high = scratch_read(1)
  //
  // The second write occurs before the first's values have been read, so they
  // interfere.
  //
  // There isn't a problem with reordering 32-bit reinterprets with each other
  // as each is lowered into a pair of write+read in JS (after the wasm
  // optimizer runs), so they are guaranteed to be adjacent (and a JS optimizer
  // that runs later will handle that ok since they are calls, which can always
  // have side effects).
  if (needScratch) {
    out << R"(
  var scratchBuffer = new ArrayBuffer(16);
  var i32ScratchView = new Int32Array(scratchBuffer);
  var f32ScratchView = new Float32Array(scratchBuffer);
  var f64ScratchView = new Float64Array(scratchBuffer);
  )";
  }

  ModuleUtils::iterImportedFunctions(wasm, [&](Function* import) {
    if (!ABI::wasm2js::isHelper(import->base)) {
      return;
    }
    if (import->base == ABI::wasm2js::SCRATCH_STORE_I32) {
      out << R"(
  function wasm2js_scratch_store_i32(index, value) {
    i32ScratchView[index] = value;
  }
      )";
    } else if (import->base == ABI::wasm2js::SCRATCH_LOAD_I32) {
      out << R"(
  function wasm2js_scratch_load_i32(index) {
    return i32ScratchView[index];
  }
      )";
    } else if (import->base == ABI::wasm2js::SCRATCH_STORE_F32) {
      out << R"(
  function wasm2js_scratch_store_f32(value) {
    f32ScratchView[2] = value;
  }
      )";
    } else if (import->base == ABI::wasm2js::SCRATCH_LOAD_F32) {
      out << R"(
  function wasm2js_scratch_load_f32() {
    return f32ScratchView[2];
  }
      )";
    } else if (import->base == ABI::wasm2js::SCRATCH_STORE_F64) {
      out << R"(
  function wasm2js_scratch_store_f64(value) {
    f64ScratchView[0] = value;
  }
      )";
    } else if (import->base == ABI::wasm2js::SCRATCH_LOAD_F64) {
      out << R"(
  function wasm2js_scratch_load_f64() {
    return f64ScratchView[0];
  }
      )";
    } else if (import->base == ABI::wasm2js::MEMORY_INIT) {
      out << R"(
  function wasm2js_memory_init(segment, dest, offset, size) {
    // TODO: traps on invalid things
    bufferView.set(memorySegments[segment].subarray(offset, offset + size), dest);
  }
      )";
    } else if (import->base == ABI::wasm2js::MEMORY_FILL) {
      out << R"(
  function wasm2js_memory_fill(dest, value, size) {
    dest = dest >>> 0;
    size = size >>> 0;
    if (dest + size > bufferView.length) throw "trap: invalid memory.fill";
    bufferView.fill(value, dest, dest + size);
  }
      )";
    } else if (import->base == ABI::wasm2js::MEMORY_COPY) {
      out << R"(
  function wasm2js_memory_copy(dest, source, size) {
    // TODO: traps on invalid things
    bufferView.copyWithin(dest, source, source + size);
  }
      )";
    } else if (import->base == ABI::wasm2js::TABLE_GROW) {
      out << R"(
  function wasm2js_table_grow(value, delta) {
    // TODO: traps on invalid things
    var oldSize = FUNCTION_TABLE.length;
    FUNCTION_TABLE.length = oldSize + delta;
    if (newSize > oldSize) {
      __wasm_table_fill(oldSize, value, delta)
    }
    return oldSize;
  }
      )";
    } else if (import->base == ABI::wasm2js::TABLE_FILL) {
      out << R"(
  function __wasm_table_fill(dest, value, size) {
    // TODO: traps on invalid things
    for (var i = 0; i < size; i++) {
      FUNCTION_TABLE[dest + i] = value;
    }
  }
      )";
    } else if (import->base == ABI::wasm2js::TABLE_COPY) {
      out << R"(
  function __wasm_table_copy(dest, source, size) {
    // TODO: traps on invalid things
    for (var i = 0; i < size; i++) {
      FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i];
    }
  }
      )";
    } else if (import->base == ABI::wasm2js::DATA_DROP) {
      out << R"(
  function wasm2js_data_drop(segment) {
    // TODO: traps on invalid things
    memorySegments[segment] = new Uint8Array(0);
  }
      )";
    } else if (import->base == ABI::wasm2js::ATOMIC_WAIT_I32) {
      out << R"(
  function wasm2js_atomic_wait_i32(offset, ptr, expected, timeoutLow, timeoutHigh) {
    ptr = (ptr + offset) >> 2;
    var timeout = Infinity;
    if (timeoutHigh >= 0) {
      // Convert from nanoseconds to milliseconds
      // Taken from convertI32PairToI53 in emscripten's library_int53.js
      timeout = ((timeoutLow >>> 0) / 1e6) + timeoutHigh * (4294967296 / 1e6);
    }
    var view = new Int32Array(bufferView.buffer); // TODO cache
    var result = Atomics.wait(view, ptr, expected, timeout);
    if (result == 'ok') return 0;
    if (result == 'not-equal') return 1;
    if (result == 'timed-out') return 2;
    throw 'bad result ' + result;
  }
      )";
    } else if (import->base == ABI::wasm2js::ATOMIC_RMW_I64) {
      out << R"(
  function wasm2js_atomic_rmw_i64(op, bytes, offset, ptr, valueLow, valueHigh) {
    // TODO: support bytes=1, 2, 4 as well as 8.
    var view = new BigInt64Array(bufferView.buffer); // TODO cache
    ptr = (ptr + offset) >> 3;
    var value = BigInt(valueLow >>> 0) | (BigInt(valueHigh >>> 0) << BigInt(32));
    var result;
    switch (op) {
      case 0: { // Add
        result = Atomics.add(view, ptr, value);
        break;
      }
      case 1: { // Sub
        result = Atomics.sub(view, ptr, value);
        break;
      }
      case 2: { // And
        result = Atomics.and(view, ptr, value);
        break;
      }
      case 3: { // Or
        result = Atomics.or(view, ptr, value);
        break;
      }
      case 4: { // Xor
        result = Atomics.xor(view, ptr, value);
        break;
      }
      case 5: { // Xchg
        result = Atomics.exchange(view, ptr, value);
        break;
      }
      default: throw 'bad op';
    }
    var low = Number(result & BigInt(0xffffffff)) | 0;
    var high = Number((result >> BigInt(32)) & BigInt(0xffffffff)) | 0;
    stashedBits = high;
    return low;
  }
      )";
    } else if (import->base == ABI::wasm2js::GET_STASHED_BITS) {
      out << R"(
  var stashedBits = 0;

  function wasm2js_get_stashed_bits() {
    return stashedBits;
  }
      )";
    } else if (import->base == ABI::wasm2js::TRAP) {
      out << "function wasm2js_trap() { throw new Error('abort'); }\n";
    } else {
      WASM_UNREACHABLE("bad helper function");
    }
  });

  out << '\n';
}

} // namespace wasm

#endif // wasm_wasm2js_h
