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

//
// Instruments all indirect calls so that they work even if a function
// pointer was cast incorrectly. For example, if you cast an int (int, float)
// to an int (int, float, int) and call it natively, on most archs it will
// happen to work, ignoring the extra param, whereas in wasm it will trap.
// When porting code that relies on such casts working (like e.g. Python),
// this pass may be useful. It sets a new "ABI" for indirect calls, in which
// they all return an i64 and they have a fixed number of i64 params, and
// the pass converts everything to go through that.
//
// This should work even with dynamic linking, however, the number of
// params must be identical, i.e., the "ABI" must match.

#include <asm_v_wasm.h>
#include <ir/literal-utils.h>
#include <pass.h>
#include <wasm-builder.h>
#include <wasm-emscripten.h>
#include <wasm.h>

namespace wasm {

// This should be enough for everybody. (As described above, we need this
// to match when dynamically linking, and also dynamic linking is why we
// can't just detect this automatically in the module we see.)
static const int NUM_PARAMS = 16;

// Converts a value to the ABI type of i64.
static Expression* toABI(Expression* value, Module* module) {
  Builder builder(*module);
  switch (value->type) {
    case i32: {
      value = builder.makeUnary(ExtendUInt32, value);
      break;
    }
    case i64: {
      // already good
      break;
    }
    case f32: {
      value = builder.makeUnary(ExtendUInt32,
                                builder.makeUnary(ReinterpretFloat32, value));
      break;
    }
    case f64: {
      value = builder.makeUnary(ReinterpretFloat64, value);
      break;
    }
    case v128: {
      WASM_UNREACHABLE("v128 not implemented yet");
    }
    case anyref: {
      WASM_UNREACHABLE("anyref cannot be converted to i64");
    }
    case exnref: {
      WASM_UNREACHABLE("exnref cannot be converted to i64");
    }
    case none: {
      // the value is none, but we need a value here
      value = builder.makeSequence(value, LiteralUtils::makeZero(i64, *module));
      break;
    }
    case unreachable: {
      // can leave it, the call isn't taken anyhow
      break;
    }
  }
  return value;
}

// Converts a value from the ABI type of i64 to the expected type
static Expression* fromABI(Expression* value, Type type, Module* module) {
  Builder builder(*module);
  switch (type) {
    case i32: {
      value = builder.makeUnary(WrapInt64, value);
      break;
    }
    case i64: {
      // already good
      break;
    }
    case f32: {
      value = builder.makeUnary(ReinterpretInt32,
                                builder.makeUnary(WrapInt64, value));
      break;
    }
    case f64: {
      value = builder.makeUnary(ReinterpretInt64, value);
      break;
    }
    case v128: {
      WASM_UNREACHABLE("v128 not implemented yet");
    }
    case anyref: {
      WASM_UNREACHABLE("anyref cannot be converted from i64");
    }
    case exnref: {
      WASM_UNREACHABLE("exnref cannot be converted from i64");
    }
    case none: {
      value = builder.makeDrop(value);
    }
    case unreachable: {
      // can leave it, the call isn't taken anyhow
      break;
    }
  }
  return value;
}

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

  Pass* create() override { return new ParallelFuncCastEmulation(ABIType); }

  ParallelFuncCastEmulation(Name ABIType) : ABIType(ABIType) {}

  void visitCallIndirect(CallIndirect* curr) {
    if (curr->operands.size() > NUM_PARAMS) {
      Fatal() << "FuncCastEmulation::NUM_PARAMS needs to be at least "
              << curr->operands.size();
    }
    for (Expression*& operand : curr->operands) {
      operand = toABI(operand, getModule());
    }
    // Add extra operands as needed.
    while (curr->operands.size() < NUM_PARAMS) {
      curr->operands.push_back(LiteralUtils::makeZero(i64, *getModule()));
    }
    // Set the new types
    curr->fullType = ABIType;
    auto oldType = curr->type;
    curr->type = i64;
    curr->finalize(); // may be unreachable
    // Fix up return value
    replaceCurrent(fromABI(curr, oldType, getModule()));
  }

private:
  // the name of a type for a call with the right params and return
  Name ABIType;
};

struct FuncCastEmulation : public Pass {
  void run(PassRunner* runner, Module* module) override {
    // we just need the one ABI function type for all indirect calls
    std::string sig = "j";
    for (Index i = 0; i < NUM_PARAMS; i++) {
      sig += 'j';
    }
    ABIType = ensureFunctionType(sig, module)->name;
    // Add a way for JS to call into the table (as our i64 ABI means an i64
    // is returned when there is a return value, which JS engines will fail on),
    // using dynCalls
    EmscriptenGlueGenerator generator(*module);
    generator.generateDynCallThunks();
    // Add a thunk for each function in the table, and do the call through it.
    std::unordered_map<Name, Name> funcThunks;
    for (auto& segment : module->table.segments) {
      for (auto& name : segment.data) {
        auto iter = funcThunks.find(name);
        if (iter == funcThunks.end()) {
          auto thunk = makeThunk(name, module);
          funcThunks[name] = thunk;
          name = thunk;
        } else {
          name = iter->second;
        }
      }
    }
    // update call_indirects
    ParallelFuncCastEmulation(ABIType).run(runner, module);
  }

private:
  // the name of a type for a call with the right params and return
  Name ABIType;

  // Creates a thunk for a function, casting args and return value as needed.
  Name makeThunk(Name name, Module* module) {
    Name thunk = std::string("byn$fpcast-emu$") + name.str;
    if (module->getFunctionOrNull(thunk)) {
      Fatal() << "FuncCastEmulation::makeThunk seems a thunk name already in "
                 "use. Was the pass already run on this code?";
    }
    // The item in the table may be a function or a function import.
    auto* func = module->getFunction(name);
    std::vector<Type>& params = func->params;
    Type type = func->result;
    Builder builder(*module);
    std::vector<Expression*> callOperands;
    for (Index i = 0; i < params.size(); i++) {
      callOperands.push_back(
        fromABI(builder.makeLocalGet(i, i64), params[i], module));
    }
    auto* call = builder.makeCall(name, callOperands, type);
    std::vector<Type> thunkParams;
    for (Index i = 0; i < NUM_PARAMS; i++) {
      thunkParams.push_back(i64);
    }
    auto* thunkFunc = builder.makeFunction(thunk,
                                           std::move(thunkParams),
                                           i64,
                                           {}, // no vars
                                           toABI(call, module));
    thunkFunc->type = ABIType;
    module->addFunction(thunkFunc);
    return thunk;
  }
};

Pass* createFuncCastEmulationPass() { return new FuncCastEmulation(); }

} // namespace wasm
