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

//
// DebugLocationPropagation aim to pass debug location from parents or
// previous siblings to expression which has no debug location. This is
// useful for compilers that use Binaryen API to generate WebAssembly modules.
//

#include "pass.h"
#include "wasm-traversal.h"
#include "wasm.h"
#include <cassert>
#include <unordered_map>

namespace wasm {

struct DebugLocationPropagation
  : WalkerPass<PostWalker<DebugLocationPropagation>> {

  // The top element of this stack is the previous sibling or parent of the
  // current expression in `doPrevisit`. To maintain this invariant, expressions
  // are only popped once we are done visiting their parents.
  ExpressionStack expressionStack;

  using Super = WalkerPass<PostWalker<DebugLocationPropagation>>;
  bool isFunctionParallel() override { return true; }
  bool modifiesBinaryenIR() override { return false; }
  bool requiresNonNullableLocalFixups() override { return false; }
  void runOnFunction(Module* module, Function* func) override {
    if (!func->debugLocations.empty()) {
      Super::runOnFunction(module, func);
    }
  }

  Expression* getPrevious() {
    if (expressionStack.empty()) {
      return nullptr;
    }
    assert(expressionStack.size() >= 1);
    return expressionStack[expressionStack.size() - 1];
  }

  static void doPreVisit(DebugLocationPropagation* self, Expression** currp) {
    auto* curr = *currp;
    auto& locs = self->getFunction()->debugLocations;
    auto& expressionStack = self->expressionStack;
    if (locs.find(curr) == locs.end()) {
      // No debug location, see if we should inherit one.
      if (auto* previous = self->getPrevious()) {
        if (auto it = locs.find(previous); it != locs.end()) {
          locs[curr] = it->second;
        }
      } else if (self->getFunction()->prologLocation) {
        // Instructions may inherit their locations from the function
        // prolog.
        locs[curr] = *self->getFunction()->prologLocation;
      }
    }
    expressionStack.push_back(curr);
  }

  static void doPostVisit(DebugLocationPropagation* self, Expression** currp) {
    auto& exprStack = self->expressionStack;
    while (exprStack.back() != *currp) {
      // pop all the child expressions and keep current expression in stack.
      exprStack.pop_back();
    }
    // the stack should never be empty
    assert(!exprStack.empty());
  }

  static void scan(DebugLocationPropagation* self, Expression** currp) {
    self->pushTask(DebugLocationPropagation::doPostVisit, currp);

    PostWalker<DebugLocationPropagation>::scan(self, currp);

    self->pushTask(DebugLocationPropagation::doPreVisit, currp);
  }

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

Pass* createDebugLocationPropagationPass() {
  return new DebugLocationPropagation();
}

} // namespace wasm
