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

//
// A WebAssembly merger: loads multiple files, mashes them together, and emits
// the result. Unlike wasm-ld, this does not have the full semantics of native
// linkers. Instead, wasm-merge does at compile time what you can do with JS at
// runtime: connect some wasm modules together by hooking up imports to exports.
// The result of wasm-merge is a single module that behaves the same as the
// multiple original modules, but you don't need that JS to set up the
// connections between the modules any more, and DCE and inlining can help
// inside the module, etc. In other words, wasm-merge is sort of like a wasm
// bundler, where "bundler" means something similar to JS bundlers. (While JS is
// mentioned here a lot, wasm-merge could in principle also be helpful with
// optimizing other ways of connecting modules at compile time instead of
// runtime, like perhaps the component model for wasm that is in development.)
//
// The specific merging model here is to take N wasm modules, each with a given
// name:
//
//   wasm_1, wasm_2, ... , wasm_N
//   name_1, name_2, ... , name_N
//
// We resolve imports and exports using those names as we merge all the code
// into the final module. That is, if wasm_i imports "foo.bar", and wasm_j has
// name name_j == "foo" and it exports a function "bar" then wasm_i's import of
// "foo.bar" will turn into a reference to the proper item from wasm_j that
// corresponds to that export:
//
//  (module "first"
//    (import "foo" "bar" (func $foo.bar))
//    (func $other
//      (call $foo.bar)
//    )
//  )
//
//  (module "foo"
//    (func $f (export "bar")
//      ..
//    )
//  )
//
// => wasm-merge =>
//
//  (module
//    ..
//    (func $other
//      (call $f) ;; call $f directly since "foo.bar" resolved as $f
//    )
//    (func $f
//      ..
//    )
//  )
//
// We call that process "fusing" of imports to exports. Note that we don't
// bother to optimize here - we don't remove either the export or the import,
// even if we fuse - as it is simple to leave that for later optimizations
// (removing unwanted exports can be done using wasm-metadce, see
// https://github.com/WebAssembly/binaryen/wiki/Pruning-unneeded-code-in-wasm-files-with-wasm-metadce#example-pruning-exports
// ).
//
// Note that we allow "forward references" - a reference from an earlier module
// to a later one. If one instantiates the wasm modules in sequence then that is
// impossible to do, and to work around it e.g. emscripten dynamic linking
// support will add a thunk. Note that ES6 modules support such circular imports
// for JS, but they are considered annoying even there; one of the solutions to
// such import loops in JS is to merge the modules together, and similarly
// wasm-merge can help wasm build systems avoid such cycles. (Note that ES6
// module support for *wasm* is not intended to support cycles, unlike JS, and
// so avoiding cycles is important.)
//
// Despite resolving imports and exports without regard for the order of
// modules, the order does matter in one way: if the modules have start
// functions then those are called in the given order of the modules.
//
// wasm-merge works in linear time (linear in the total code in all the linked
// modules). Each input module is traversed once to fix up names before being
// merged, and at the end we traverse the entire merged module once to fuse
// imports and exports.
//
// Debugging: Set BINARYEN_PASS_DEBUG=1 in the env to get validation after each
// merging of a module (like pass-debug mode for the pass runner, this does
// expensive work after each incremental operation). This can take quadratic
// time, so we do not do it by default.
//

#include "ir/module-utils.h"
#include "ir/names.h"
#include "ir/utils.h"
#include "support/colors.h"
#include "support/file.h"
#include "wasm-builder.h"
#include "wasm-io.h"
#include "wasm-validator.h"
#include "wasm.h"

#include "tool-options.h"

using namespace wasm;

namespace {

// The module we'll merge into. This is a singleton and it is simple to just
// have it as a global rather than pass it around all the time.
Module merged;

// Everything we merge is accumulated into |merged|, aside from the start
// functions. To avoid incrementally adding a call each time, which can end up
// nested, we add them here and generate a series of flat calls at the end.
std::vector<Name> startFunctions;

// Name conflicts on functions etc. are resolved by renaming things in a way
// that only matters internally. Conflicting export names, however, are
// observable, and so the user must decide how they want wasm-merge to handle
// that.
enum ExportMergeMode {
  // Error on name conflicts. This is the least surprising mode, and the one
  // used by default.
  ErrorOnExportConflicts,
  // Rename conflicting exports. Later exports will get a suffix added to them
  // to make them unique. For example, this is useful if you merge several
  // modules that each have a "main" export, and it's fine if those are renamed
  // to "main", "main_1", "main_2" etc. - you'll decide when to call each of
  // those and do so at the right time.
  RenameExportConflicts,
  // Silently ignore export conflicts, that is, later exports that overlap with
  // previous ones are simply skipped. This can be useful when the first module
  // is the main program, which exports things to the outside, while other
  // modules are libraries of code that only provide things to the main module
  // but not to the outside.
  SkipExportConflicts,
} exportMergeMode = ErrorOnExportConflicts;

// Merging two modules is mostly straightforward: copy the functions etc. of the
// first module into the second, with some renaming to avoid name collisions.
// The only other thing we need to handle is the mapping of imports to exports,
// as explained earlier. The way we handle this is to first combine the modules
// into a single module, then connect imports and imports. To do that we track
// the origin of each export.
//
// For example, in the example from earlier we have this as the second module:
//
//  (module "foo"
//    (func $f (export "bar")
//      ..
//    )
//  )
//
// We will annotate that exported function as being from module "foo", so that
// we can resolve imports to "foo.bar" to it. The ExportInfo data structure
// tracks the extra info we need for exports as we go.
struct ExportInfo {
  // The name of the module this export originally appeared in, as just
  // explained.
  Name moduleName;
  // The name of the export itself, which is the basename (the export will be
  // used as module.base). This is normally just the same as export->name, but
  // we need to stash it here because exports may be renamed when merged in, if
  // there is overlap with the name of another export, and imports refer to the
  // original name.
  Name baseName;
};
std::unordered_map<Export*, ExportInfo> exportModuleMap;

// A map of [kind of thing in the module] to [old name => new name] for things
// of that kind. For example, the NameUpdates for functions is a map of old
// function names to new function names.
using NameUpdates = std::unordered_map<Name, Name>;
using KindNameUpdates = std::unordered_map<ModuleItemKind, NameUpdates>;

// Apply a set of name changes to a module.
void updateNames(Module& wasm, KindNameUpdates& kindNameUpdates) {
  if (kindNameUpdates.empty()) {
    return;
  }

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

    std::unique_ptr<Pass> create() override {
      return std::make_unique<NameMapper>(kindNameUpdates);
    }

    KindNameUpdates& kindNameUpdates;

    NameMapper(KindNameUpdates& kindNameUpdates)
      : kindNameUpdates(kindNameUpdates) {}

    void visitExpression(Expression* curr) {
#define DELEGATE_ID curr->_id

#define DELEGATE_START(id) [[maybe_unused]] auto* cast = curr->cast<id>();

#define DELEGATE_GET_FIELD(id, field) cast->field

#define DELEGATE_FIELD_TYPE(id, field)
#define DELEGATE_FIELD_HEAPTYPE(id, field)
#define DELEGATE_FIELD_CHILD(id, field)
#define DELEGATE_FIELD_OPTIONAL_CHILD(id, field)
#define DELEGATE_FIELD_INT(id, field)
#define DELEGATE_FIELD_LITERAL(id, field)
#define DELEGATE_FIELD_NAME(id, field)
#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field)
#define DELEGATE_FIELD_SCOPE_NAME_USE(id, field)
#define DELEGATE_FIELD_ADDRESS(id, field)

#define DELEGATE_FIELD_NAME_KIND(id, field, kind)                              \
  if (cast->field.is()) {                                                      \
    mapName(kind, cast->field);                                                \
  }

#include "wasm-delegations-fields.def"
    }

    // Aside from expressions, we have a few other things we need to update at
    // the module scope.
    void mapModuleFields(Module& wasm) {
      for (auto& curr : wasm.exports) {
        // skip type exports
        if (auto* name = curr->getInternalName()) {
          mapName(ModuleItemKind(curr->kind), *name);
        }
      }
      for (auto& curr : wasm.elementSegments) {
        mapName(ModuleItemKind::Table, curr->table);
      }
      for (auto& curr : wasm.dataSegments) {
        mapName(ModuleItemKind::Memory, curr->memory);
      }

      mapName(ModuleItemKind::Function, wasm.start);
    }

  private:
    Name resolveName(NameUpdates& updates, Name newName, Name oldName) {
      // Iteratively lookup the updated name.
      std::set<Name> visited;
      auto name = newName;
      while (1) {
        auto iter = updates.find(name);
        if (iter == updates.end()) {
          return name;
        }
        if (visited.contains(name)) {
          // This is a loop of imports, which means we cannot resolve a useful
          // name. Report an error.
          Fatal() << "wasm-merge: infinite loop of imports on " << oldName;
        }
        visited.insert(name);
        name = iter->second;
      }
    }

    void mapName(ModuleItemKind kind, Name& name) {
      auto iter = kindNameUpdates.find(kind);
      if (iter == kindNameUpdates.end()) {
        return;
      }
      auto& nameUpdates = iter->second;
      auto iter2 = nameUpdates.find(name);
      if (iter2 != nameUpdates.end()) {
        name = resolveName(nameUpdates, iter2->second, name);
      }
    }
  } nameMapper(kindNameUpdates);

  PassRunner runner(&wasm);
  nameMapper.run(&runner, &wasm);
  nameMapper.runOnModuleCode(&runner, &wasm);
  nameMapper.mapModuleFields(wasm);
}

// Scan an input module to find the names of the items it contains, and pick new
// names for them that do not cause conflicts with things already in the merged
// module.
void renameInputItems(Module& input) {
  // Pick the names, and apply them to the items themselves.
  // TODO Add ModuleUtils::iterAll + getValidName(kind, ..)? Then we could
  //      avoid hardcoded loops here, but it's unclear those would help
  //      anywhere else.
  KindNameUpdates kindNameUpdates;

  // Add a mapping of a name to a new name, in a particular kind. If the new
  // name is the same as the old, do nothing.
  auto maybeAdd = [&](ModuleItemKind kind, Name& name, const Name newName) {
    if (newName != name) {
      kindNameUpdates[kind][name] = newName;
      name = newName;
    }
  };

  // Given a name in the input module, and lamdbdas that query for that name in
  // both the merged and input module, return a valid name. We want a new name
  // that is not in the merged module - we cannot collide with anything already
  // there - but we must also be careful to not fix such collisions with names
  // in the input module. That is, if we have $a and $a already exists in the
  // merged module, $a_1 might be valid - but it is not valid if $a_1 is in the
  // input module, as that means it is a valid name there, with things referring
  // to it, which we would need to map. For simplicity, when fixing a collision,
  // pick a totally novel name.
  auto getValidName = [&](Name name, auto method, Index hint) {
    return Names::getValidName(
      name,
      [&](Name test) {
        // As explained above, a name is valid if it is not in the merged
        // module, and also it is either the original name in the input module
        // (no collision) or it does not appear there.
        return !(merged.*method)(test) &&
               (test == name || !(input.*method)(test));
      },
      hint);
  };

  for (auto& curr : input.functions) {
    auto name = getValidName(
      curr->name, &Module::getFunctionOrNull, merged.functions.size());
    maybeAdd(ModuleItemKind::Function, curr->name, name);
  }
  for (auto& curr : input.globals) {
    auto name =
      getValidName(curr->name, &Module::getGlobalOrNull, merged.globals.size());
    maybeAdd(ModuleItemKind::Global, curr->name, name);
  }
  for (auto& curr : input.tags) {
    auto name =
      getValidName(curr->name, &Module::getTagOrNull, merged.tags.size());
    maybeAdd(ModuleItemKind::Tag, curr->name, name);
  }
  for (auto& curr : input.elementSegments) {
    auto name = getValidName(curr->name,
                             &Module::getElementSegmentOrNull,
                             merged.elementSegments.size());
    maybeAdd(ModuleItemKind::ElementSegment, curr->name, name);
  }
  for (auto& curr : input.memories) {
    auto name = getValidName(
      curr->name, &Module::getMemoryOrNull, merged.memories.size());
    maybeAdd(ModuleItemKind::Memory, curr->name, name);
  }
  for (auto& curr : input.dataSegments) {
    auto name = getValidName(
      curr->name, &Module::getDataSegmentOrNull, merged.dataSegments.size());
    maybeAdd(ModuleItemKind::DataSegment, curr->name, name);
  }
  for (auto& curr : input.tables) {
    auto name =
      getValidName(curr->name, &Module::getTableOrNull, merged.tables.size());
    maybeAdd(ModuleItemKind::Table, curr->name, name);
  }

  // Apply the names to their uses.
  updateNames(input, kindNameUpdates);
}

void copyModuleContents(Module& input, Name inputName) {
  // First, copy the regular module items (functions, globals) etc. which we
  // have proper names for, and can just copy.
  ModuleUtils::copyModuleItems(input, merged);

  // We must handle exports in a special way, as we need to note their origin
  // module as we copy them in (also, they are not importable or exportable, so
  // the ModuleUtils function above does not handle them).
  for (auto& curr : input.exports) {
    auto copy = std::make_unique<Export>(*curr);

    // Note the module origin and original name of this export, for later fusing
    // of imports to exports.
    exportModuleMap[copy.get()] = ExportInfo{inputName, curr->name};

    // An export may already exist with that name, so fix it up.
    copy->name = Names::getValidExportName(merged, copy->name);
    if (copy->name != curr->name) {
      if (exportMergeMode == ErrorOnExportConflicts) {
        Fatal() << "Export name conflict: " << curr->name << " (consider"
                << " --rename-export-conflicts or"
                << " --skip-export-conflicts)\n";
      } else if (exportMergeMode == SkipExportConflicts) {
        // Skip the addExport below us.
        continue;
      }
    }
    // Add the export.
    merged.addExport(std::move(copy));
  }

  // Start functions are accumulated till the end.
  if (input.start) {
    startFunctions.push_back(input.start);
  }

  // TODO: type names, features, debug info, custom sections, dylink info, etc.
}

void reportTypeMismatch(bool& valid, const char* kind, Importable* import) {
  valid = false;
  std::cerr << "Type mismatch when importing " << kind << " " << import->base
            << " from module " << import->module << " ($" << import->name
            << "): ";
}

// Check that the export and import limits match.
template<typename T>
void checkLimit(bool& valid, const char* kind, T* export_, T* import) {
  if (export_->initial < import->initial) {
    reportTypeMismatch(valid, kind, import);
    std::cerr << "minimal size " << export_->initial
              << " is smaller than expected minimal size " << import->initial
              << ".\n";
  }
  if (import->hasMax()) {
    if (!export_->hasMax()) {
      reportTypeMismatch(valid, kind, import);
      std::cerr << "expecting a bounded " << kind
                << " but the "
                   "imported "
                << kind << " is unbounded.\n";
    } else if (export_->max > import->max) {
      reportTypeMismatch(valid, kind, import);
      std::cerr << "maximal size " << export_->max
                << " is larger than expected maximal size " << import->max
                << ".\n";
    }
  }
}

// Find pairs of matching imports and exports, and make uses of the import refer
// to the exported item (which has been merged into the module).
void fuseImportsAndExports(const PassOptions& options) {
  // First, scan the exports and build a map. We build a map of [module name] to
  // [export name => internal name]. For example, consider this module:
  //
  //  (module "module_A"
  //    (func $foo (export "bar"))
  //  )
  //
  // Then the ModuleExportMap will be:
  //
  //  {
  //    "module_A": {
  //      "bar": "foo";
  //    }
  //  }
  //
  using ModuleExportMap = std::unordered_map<Name, NameUpdates>;

  // A map of ModuleExportMaps, one per item kind (one for functions, one for
  // globals, etc.).
  using KindModuleExportMaps =
    std::unordered_map<ExternalKind, ModuleExportMap>;
  KindModuleExportMaps kindModuleExportMaps;

  for (auto& ex : merged.exports) {
    // skip type exports
    if (auto* name = ex->getInternalName()) {
      assert(exportModuleMap.contains(ex.get()));
      ExportInfo& exportInfo = exportModuleMap[ex.get()];
      kindModuleExportMaps[ex->kind][exportInfo.moduleName]
                          [exportInfo.baseName] = *name;
    }
  }

  // Find all the imports and see which have corresponding exports, which means
  // there is an internal item we can refer to. We build up a map of the names
  // that we should update.
  KindNameUpdates kindNameUpdates;
  ModuleUtils::iterImportable(merged, [&](ExternalKind kind, Importable* curr) {
    if (curr->imported()) {
      auto internalName = kindModuleExportMaps[kind][curr->module][curr->base];
      if (internalName.is()) {
        // We found something to fuse! Add it to the maps for renaming.
        kindNameUpdates[ModuleItemKind(kind)][curr->name] = internalName;
      }
    }
  });

  if (options.validate) {
    // Make sure that the export types match the import types.
    bool valid = true;
    ModuleUtils::iterImportedFunctions(merged, [&](Function* import) {
      auto internalName = kindModuleExportMaps[ExternalKind::Function]
                                              [import->module][import->base];
      if (internalName.is()) {
        auto* export_ = merged.getFunction(internalName);
        // TODO: use Type subtyping when exactness handling is complete.
        if (!HeapType::isSubType(export_->type.getHeapType(),
                                 import->type.getHeapType())) {
          reportTypeMismatch(valid, "function", import);
          std::cerr << "type " << export_->type << " is not a subtype of "
                    << import->type << ".\n";
        }
      }
    });
    ModuleUtils::iterImportedTables(merged, [&](Table* import) {
      auto internalName =
        kindModuleExportMaps[ExternalKind::Table][import->module][import->base];
      if (internalName.is()) {
        auto* export_ = merged.getTable(internalName);
        checkLimit(valid, "table", export_, import);
        if (export_->type != import->type) {
          reportTypeMismatch(valid, "table", import);
          std::cerr << "export type " << export_->type
                    << " is different from import type " << import->type
                    << ".\n";
        }
      }
    });
    ModuleUtils::iterImportedMemories(merged, [&](Memory* import) {
      auto internalName = kindModuleExportMaps[ExternalKind::Memory]
                                              [import->module][import->base];
      if (internalName.is()) {
        auto* export_ = merged.getMemory(internalName);
        if (export_->is64() != import->is64()) {
          reportTypeMismatch(valid, "memory", import);
          std::cerr << "index type should match.\n";
        }
        checkLimit(valid, "memory", export_, import);
      }
    });
    ModuleUtils::iterImportedGlobals(merged, [&](Global* import) {
      auto internalName = kindModuleExportMaps[ExternalKind::Global]
                                              [import->module][import->base];
      if (internalName.is()) {
        auto* export_ = merged.getGlobal(internalName);
        if (export_->mutable_ != import->mutable_) {
          reportTypeMismatch(valid, "global", import);
          std::cerr << "mutability should match.\n";
        }
        if (export_->mutable_ && export_->type != import->type) {
          reportTypeMismatch(valid, "global", import);
          std::cerr << "export type " << export_->type
                    << " is different from import type " << import->type
                    << ".\n";
        }
        if (!export_->mutable_ &&
            !Type::isSubType(export_->type, import->type)) {
          reportTypeMismatch(valid, "global", import);
          std::cerr << "type " << export_->type << " is not a subtype of "
                    << import->type << ".\n";
        }
      }
    });
    ModuleUtils::iterImportedTags(merged, [&](Tag* import) {
      auto internalName =
        kindModuleExportMaps[ExternalKind::Tag][import->module][import->base];
      if (internalName.is()) {
        auto* export_ = merged.getTag(internalName);
        if (export_->type != import->type) {
          reportTypeMismatch(valid, "tag", import);
          std::cerr << "export type " << export_->type
                    << " is different from import type " << import->type
                    << ".\n";
        }
      }
    });
    if (!valid) {
      Fatal() << "import/export mismatches";
    }
  }

  // Update the things we found.
  updateNames(merged, kindNameUpdates);
}

// Things may have been imported using supertypes, which means they can get
// refined after merging.
void updateTypes(Module& wasm) {
  struct Updater : public WalkerPass<PostWalker<Updater>> {
    bool isFunctionParallel() override { return true; }

    std::unique_ptr<Pass> create() override {
      return std::make_unique<Updater>();
    }

    void visitGlobalGet(GlobalGet* curr) {
      curr->type = getModule()->getGlobal(curr->name)->type;
    }

    void visitCall(Call* curr) {
      if (curr->type != Type::unreachable) {
        curr->type = getModule()
                       ->getFunction(curr->target)
                       ->type.getHeapType()
                       .getSignature()
                       .results;
      }
    }

    void visitRefFunc(RefFunc* curr) { curr->finalize(*getModule()); }

    void visitFunction(Function* curr) {
      ReFinalize().walkFunctionInModule(curr, getModule());
    }
  } updater;

  PassRunner runner(&wasm);
  updater.run(&runner, &wasm);
  updater.runOnModuleCode(&runner, &wasm);
}

// Merge the start functions, keeping the order. We add a new function that
// calls them in sequence (leaving proper inlining, including handling of
// control flow etc., to the optimizer).
void mergeStartFunctions() {
  if (startFunctions.empty()) {
    return;
  }

  if (startFunctions.size() == 1) {
    // Avoid adding a call here.
    merged.start = startFunctions[0];
    return;
  }

  auto combinedName =
    Names::getValidFunctionName(merged, "merged.start.combined");
  Builder builder(merged);
  std::vector<Expression*> calls;
  for (auto start : startFunctions) {
    calls.push_back(builder.makeCall(start, {}, Type::none));
  }
  auto* body = builder.makeBlock(calls);
  auto combined = builder.makeFunction(
    combinedName, Signature(Type::none, Type::none), {}, body);
  merged.addFunction(std::move(combined));
  merged.start = combinedName;
}

// Merges an input module into an existing target module. The input module can
// be modified, as it will no longer be needed (so it is intentionally not
// marked as const here).
void mergeInto(Module& input, Name inputName) {
  // Rename things in the input module so that there are no conflicts with names
  // in the merged module. We do so in place for efficiency.
  renameInputItems(input);

  // The input module's items can now be copied into the target module safely,
  // as names will not conflict.
  copyModuleContents(input, inputName);
}

} // anonymous namespace

int main(int argc, const char* argv[]) {
  std::vector<std::string> inputFiles;
  std::vector<std::string> inputFileNames;
  bool emitBinary = true;
  bool debugInfo = false;
  std::map<size_t, std::string> inputSourceMapFilenames;
  std::string outputSourceMapFilename;
  std::string outputSourceMapUrl;

  // We can write wasm-split manifests that can later be fed to wasm-split to
  // split the merged module back up along the lines of the original modules.
  // Map modules to their functions so we can write the manifest.
  std::string manifestFile;
  std::unordered_map<Name, std::vector<Name>> moduleFuncs;

  const std::string WasmMergeOption = "wasm-merge options";

  ToolOptions options("wasm-merge",
                      R"(Merge wasm files into one.

For example,

  wasm-merge foo.wasm foo bar.wasm bar -o merged.wasm

will read foo.wasm and bar.wasm, with names 'foo' and 'bar' respectively, so if the second imports from 'foo', we will see that as an import from the first module after the merge. The merged output will be written to merged.wasm.

Note that filenames and modules names are interleaved (which is hopefully less confusing).

Input source maps can be specified by adding an -ism option right after the module name:

  wasm-merge foo.wasm foo -ism foo.wasm.map ...)");

  options
    .add("--output",
         "-o",
         "Output file",
         WasmMergeOption,
         Options::Arguments::One,
         [](Options* o, const std::string& argument) {
           o->extra["output"] = argument;
           Colors::setEnabled(false);
         })
    .add_positional("INFILE1 NAME1 INFILE2 NAME2 [..]",
                    Options::Arguments::N,
                    [&](Options* o, const std::string& argument) {
                      if (inputFiles.size() == inputFileNames.size()) {
                        inputFiles.push_back(argument);
                      } else {
                        inputFileNames.push_back(argument);
                      }
                    })
    .add("--input-source-map",
         "-ism",
         "Consume source maps from the specified files",
         WasmMergeOption,
         Options::Arguments::N,
         [&](Options* o, const std::string& argument) {
           size_t pos = inputFiles.size();
           if (pos == 0 || pos != inputFileNames.size() ||
               inputSourceMapFilenames.contains(pos - 1)) {
             std::cerr << "Option '-ism " << argument
                       << "' should be right after the module name\n";
             exit(EXIT_FAILURE);
           }
           inputSourceMapFilenames.insert({pos - 1, argument});
         })
    .add("--output-source-map",
         "-osm",
         "Emit source map to the specified file",
         WasmMergeOption,
         Options::Arguments::One,
         [&outputSourceMapFilename](Options* o, const std::string& argument) {
           outputSourceMapFilename = argument;
         })
    .add("--output-source-map-url",
         "-osu",
         "Emit specified string as source map URL",
         WasmMergeOption,
         Options::Arguments::One,
         [&outputSourceMapUrl](Options* o, const std::string& argument) {
           outputSourceMapUrl = argument;
         })
    .add("--output-manifest",
         "",
         "Write a wasm-split manifest to the specified file. This manifest can "
         "be given to wasm-split to split the merged module along the lines of "
         "the original modules. Implies --debuginfo to preserve function names "
         "in the output module.",
         WasmMergeOption,
         Options::Arguments::One,
         [&](Options* o, const std::string& argument) {
           manifestFile = argument;
           debugInfo = true;
         })
    .add("--rename-export-conflicts",
         "-rec",
         "Rename exports to avoid conflicts (rather than error)",
         WasmMergeOption,
         Options::Arguments::Zero,
         [&](Options* o, const std::string& argument) {
           exportMergeMode = RenameExportConflicts;
         })
    .add("--skip-export-conflicts",
         "-sec",
         "Skip exports that conflict with previous ones",
         WasmMergeOption,
         Options::Arguments::Zero,
         [&](Options* o, const std::string& argument) {
           exportMergeMode = SkipExportConflicts;
         })
    .add("--emit-text",
         "-S",
         "Emit text instead of binary for the output file",
         WasmMergeOption,
         Options::Arguments::Zero,
         [&](Options* o, const std::string& argument) { emitBinary = false; })
    .add("--debuginfo",
         "-g",
         "Emit names section and debug info",
         WasmMergeOption,
         Options::Arguments::Zero,
         [&](Options* o, const std::string& arguments) { debugInfo = true; });
  options.parse(argc, argv);

  if (inputFiles.size() != inputFileNames.size()) {
    Fatal() << "Please provide an import name for each input file. "
               "In particular, the number of positional inputs must be even as "
               "each wasm binary must be followed by its name.";
  }

  // Process the inputs.
  // TODO: If the inputs are a very large number of small modules then it might
  //       make sense to parallelize this. (If so, then changing the existing
  //       parallelism above in NameMapper might make sense.)

  for (Index i = 0; i < inputFiles.size(); i++) {
    auto inputFile = inputFiles[i];
    auto inputFileName = inputFileNames[i];
    auto iter = inputSourceMapFilenames.find(i);
    auto inputSourceMapFilename =
      (iter == inputSourceMapFilenames.end()) ? "" : iter->second;

    if (options.debug) {
      std::cerr << "reading input '" << inputFile << "' as '" << inputFileName
                << "'...\n";
    }

    // For the first input, we'll just read it in directly. For later inputs,
    // we read them and then merge.
    std::unique_ptr<Module> laterInput;
    Module* currModule;
    if (i == 0) {
      currModule = &merged;
    } else {
      laterInput = std::make_unique<Module>();
      currModule = laterInput.get();
    }

    options.applyOptionsBeforeParse(*currModule);

    ModuleReader reader;
    try {
      reader.read(inputFile, *currModule, inputSourceMapFilename);
    } catch (ParseException& p) {
      p.dump(std::cerr);
      Fatal() << "error in parsing wasm input: " << inputFile;
    }

    options.applyOptionsAfterParse(*currModule);

    if (options.passOptions.validate) {
      if (!WasmValidator().validate(*currModule)) {
        std::cout << *currModule << '\n';
        Fatal() << "error in validating input: " << inputFile;
      }
    }

    if (!laterInput) {
      // This is the very first module, which we read directly into |merged|.
      // The only other operation we need to do is note the exports for later.
      for (auto& curr : merged.exports) {
        exportModuleMap[curr.get()] = ExportInfo{inputFileName, curr->name};
      }

      // Start functions are accumulated till the end.
      if (merged.start) {
        startFunctions.push_back(merged.start);
        merged.start = Name();
      }

    } else {
      // This is a later module: do a full merge.
      mergeInto(*currModule, inputFileName);

      // The functions in the module have been renamed and copied rather than
      // moved, so we can get their final names directly. (We don't need this
      // for the first module because it does not appear in the manifest.)
      if (!manifestFile.empty()) {
        auto& funcs = moduleFuncs[inputFileName];
        for (auto& func : currModule->functions) {
          if (!func->imported()) {
            funcs.push_back(func->name);
            // Even if the function name is empty, if we were to put it in the
            // output manifest, it has to be emitted in the name section.
            merged.getFunction(func->name)->hasExplicitName = true;
          }
        }
      }

      // Validate after each merged module, when we are in pass-debug mode
      // (this can be quadratic time).
      if (PassRunner::getPassDebug()) {
        std::cerr << "[WasmMerge]   merged : " << inputFile << '\n';
        if (options.passOptions.validate && !WasmValidator().validate(merged)) {
          std::cout << merged << '\n';
          Fatal() << "error in validating after: " << inputFile;
        }
      }
    }
  }

  // Fuse imports and exports now that everything is all together in the merged
  // module.
  fuseImportsAndExports(options.passOptions);

  // Update types after combing and linking everything.
  updateTypes(merged);

  // Merge the start functions, after everything else is set up.
  mergeStartFunctions();

  {
    PassRunner passRunner(&merged);
    // We might have made some globals read from others that now appear after
    // them (if the one they read was appended from a later module). Sort them
    // to fix that. TODO: we could do this only if we actually append globals
    passRunner.add("reorder-globals-always");
    // Remove unused things. This is obviously a useful optimization but it also
    // makes using the output easier: if an import was resolved by an export
    // during the merge, then that import will have no more uses and it will be
    // optimized out (while if we didn't optimize it out then instantiating the
    // module would still be forced to provide something for that import).
    passRunner.add("remove-unused-module-elements");
    passRunner.run();
  }

  // Without pass-debug mode, validate once at the very end.
  if (!PassRunner::getPassDebug() && options.passOptions.validate &&
      !WasmValidator().validate(merged)) {
    std::cout << merged << '\n';
    Fatal() << "error in validating final merged";
  }

  // Output.
  if (!manifestFile.empty()) {
    std::ofstream manifest(manifestFile);
    // Skip module 0 because it will be the primary module for the split and
    // does not need to appear in the manifest.
    for (size_t i = 1; i < inputFileNames.size(); i++) {
      auto moduleName = inputFileNames[i];
      const auto& funcs = moduleFuncs[moduleName];
      if (funcs.empty()) {
        continue;
      }

      manifest << moduleName << "\n";
      for (auto func : funcs) {
        manifest << func << "\n";
      }
      manifest << "\n";
    }
  }

  if (options.extra.contains("output")) {
    ModuleWriter writer(options.passOptions);
    writer.setBinary(emitBinary);
    writer.setDebugInfo(debugInfo);
    if (outputSourceMapFilename.size()) {
      writer.setSourceMapFilename(outputSourceMapFilename);
      writer.setSourceMapUrl(outputSourceMapUrl);
    }
    options.write(writer, merged, options.extra["output"]);
  }

  flush_and_quick_exit(0);
}
