/*
 * 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(), false); }

// 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(),
                    false);
      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.count(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.count(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.str << '\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 * Memory::kPageSize)))));
    }
  }

  // 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.str;
}

void Wasm2JSBuilder::ensureModuleVar(Ref ast, const Importable& imp) {
  if (seenModuleImports.count(imp.module) > 0) {
    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.count(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.count(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.count(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.count(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.count(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.count(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.count(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(), false);
          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 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.count(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 visitStructNotify(StructNotify* 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 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(
    makeJsCoercion(ValueBuilder::makeBinary(
                     ValueBuilder::makeDot(ValueBuilder::makeName(BUFFER),
                                           IString("byteLength")),
                     DIV,
                     ValueBuilder::makeInt(Memory::kPageSize)),
                   JsType::JS_INT)));
  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::makeInt(Memory::kMaxSize32)));
  // 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::makeCall(MATH_IMUL,
                             ValueBuilder::makeName(IString("newPages")),
                             ValueBuilder::makeInt(Memory::kPageSize)))));

  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.count(base) && baseModuleMap[base] != module) {
      Fatal() << "the name " << base << " cannot be imported from "
              << "two different modules yet";
    }
    baseModuleMap[base] = module;
    if (seenModules.count(module) == 0) {
      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 * Memory::kPageSize << ");\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.count(import->module) > 0) {
      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.count(import->module) > 0) {
      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
