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

//
// Prints the a map of function indexes to function names. This can be
// useful for interpreting a stack trace from a production environment
// where names did not exist on the client. The map looks like this:
//
// 0:foo
// 1:bar
// 2:baz
//

#include "ir/module-utils.h"
#include "pass.h"
#include "support/file.h"
#include "wasm.h"

namespace wasm {

struct PrintFunctionMap : public Pass {
  bool modifiesBinaryenIR() override { return false; }

  void run(PassRunner* runner, Module* module) override {
    // If an argument is provided, write to that file; otherwise write to
    // stdout.
    auto outFile = runner->options.getArgumentOrDefault("symbolmap", "");
    Output output(outFile, Flags::Text);
    auto& o = output.getStream();
    Index i = 0;
    auto write = [&](Function* func) {
      o << i++ << ':' << func->name.str << '\n';
    };
    ModuleUtils::iterImportedFunctions(*module, write);
    ModuleUtils::iterDefinedFunctions(*module, write);
  }
};

Pass* createPrintFunctionMapPass() { return new PrintFunctionMap(); }

} // namespace wasm
