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

//
// Pass that supports potentially-trapping wasm operations.
// For example, integer division traps when dividing by zero, so this pass
// generates a check and replaces the result with zero in that case.
//

#include "asmjs/shared-constants.h"
#include "ir/trapping.h"
#include "mixed_arena.h"
#include "pass.h"
#include "support/name.h"
#include "wasm-builder.h"
#include "wasm-type.h"
#include "wasm.h"

namespace wasm {

Name I64S_REM("i64s-rem");
Name I64U_REM("i64u-rem");
Name I64S_DIV("i64s-div");
Name I64U_DIV("i64u-div");

static Expression* ensureDouble(Expression* expr, MixedArena& allocator) {
  if (expr->type == Type::f32) {
    auto conv = allocator.alloc<Unary>();
    conv->op = PromoteFloat32;
    conv->value = expr;
    conv->type = Type::f64;
    return conv;
  }
  assert(expr->type == Type::f64);
  return expr;
}

Name getBinaryFuncName(Binary* curr) {
  switch (curr->op) {
    case RemSInt32:
      return I32S_REM;
    case RemUInt32:
      return I32U_REM;
    case DivSInt32:
      return I32S_DIV;
    case DivUInt32:
      return I32U_DIV;
    case RemSInt64:
      return I64S_REM;
    case RemUInt64:
      return I64U_REM;
    case DivSInt64:
      return I64S_DIV;
    case DivUInt64:
      return I64U_DIV;
    default:
      return Name();
  }
}

Name getUnaryFuncName(Unary* curr) {
  switch (curr->op) {
    case TruncSFloat32ToInt32:
      return F32_TO_INT;
    case TruncUFloat32ToInt32:
      return F32_TO_UINT;
    case TruncSFloat32ToInt64:
      return F32_TO_INT64;
    case TruncUFloat32ToInt64:
      return F32_TO_UINT64;
    case TruncSFloat64ToInt32:
      return F64_TO_INT;
    case TruncUFloat64ToInt32:
      return F64_TO_UINT;
    case TruncSFloat64ToInt64:
      return F64_TO_INT64;
    case TruncUFloat64ToInt64:
      return F64_TO_UINT64;
    default:
      return Name();
  }
}

bool isTruncOpSigned(UnaryOp op) {
  switch (op) {
    case TruncUFloat32ToInt32:
    case TruncUFloat32ToInt64:
    case TruncUFloat64ToInt32:
    case TruncUFloat64ToInt64:
      return false;
    default:
      return true;
  }
}

Function* generateBinaryFunc(Module& wasm, Binary* curr) {
  BinaryOp op = curr->op;
  Type type = curr->type;
  bool isI64 = type == Type::i64;
  Builder builder(wasm);
  Expression* result = builder.makeBinary(
    op, builder.makeLocalGet(0, type), builder.makeLocalGet(1, type));
  BinaryOp divSIntOp = isI64 ? DivSInt64 : DivSInt32;
  UnaryOp eqZOp = isI64 ? EqZInt64 : EqZInt32;
  Literal minLit = isI64 ? Literal(std::numeric_limits<int64_t>::min())
                         : Literal(std::numeric_limits<int32_t>::min());
  Literal zeroLit = isI64 ? Literal(int64_t(0)) : Literal(int32_t(0));
  if (op == divSIntOp) {
    // guard against signed division overflow
    BinaryOp eqOp = isI64 ? EqInt64 : EqInt32;
    Literal negLit = isI64 ? Literal(int64_t(-1)) : Literal(int32_t(-1));
    result = builder.makeIf(
      builder.makeBinary(
        AndInt32,
        builder.makeBinary(
          eqOp, builder.makeLocalGet(0, type), builder.makeConst(minLit)),
        builder.makeBinary(
          eqOp, builder.makeLocalGet(1, type), builder.makeConst(negLit))),
      builder.makeConst(zeroLit),
      result);
  }
  auto funcSig = Signature({type, type}, type);
  auto func = Builder::makeFunction(getBinaryFuncName(curr), funcSig, {});
  func->body =
    builder.makeIf(builder.makeUnary(eqZOp, builder.makeLocalGet(1, type)),
                   builder.makeConst(zeroLit),
                   result);
  // TODO: use unique_ptr properly and do not release ownership.
  return func.release();
}

template<typename IntType, typename FloatType>
void makeClampLimitLiterals(Literal& iMin, Literal& fMin, Literal& fMax) {
  IntType minVal = std::numeric_limits<IntType>::min();
  IntType maxVal = std::numeric_limits<IntType>::max();
  iMin = Literal(minVal);
  fMin = Literal(FloatType(minVal) - 1);
  fMax = Literal(FloatType(maxVal) + 1);
}

Function* generateUnaryFunc(Module& wasm, Unary* curr) {
  Type type = curr->value->type;
  Type retType = curr->type;
  UnaryOp truncOp = curr->op;
  bool isF64 = type == Type::f64;

  Builder builder(wasm);

  BinaryOp leOp = isF64 ? LeFloat64 : LeFloat32;
  BinaryOp geOp = isF64 ? GeFloat64 : GeFloat32;
  BinaryOp neOp = isF64 ? NeFloat64 : NeFloat32;

  Literal iMin, fMin, fMax;
  switch (truncOp) {
    case TruncSFloat32ToInt32:
      makeClampLimitLiterals<int32_t, float>(iMin, fMin, fMax);
      break;
    case TruncUFloat32ToInt32:
      makeClampLimitLiterals<uint32_t, float>(iMin, fMin, fMax);
      break;
    case TruncSFloat32ToInt64:
      makeClampLimitLiterals<int64_t, float>(iMin, fMin, fMax);
      break;
    case TruncUFloat32ToInt64:
      makeClampLimitLiterals<uint64_t, float>(iMin, fMin, fMax);
      break;
    case TruncSFloat64ToInt32:
      makeClampLimitLiterals<int32_t, double>(iMin, fMin, fMax);
      break;
    case TruncUFloat64ToInt32:
      makeClampLimitLiterals<uint32_t, double>(iMin, fMin, fMax);
      break;
    case TruncSFloat64ToInt64:
      makeClampLimitLiterals<int64_t, double>(iMin, fMin, fMax);
      break;
    case TruncUFloat64ToInt64:
      makeClampLimitLiterals<uint64_t, double>(iMin, fMin, fMax);
      break;
    default:
      WASM_UNREACHABLE("unexpected op");
  }

  auto func =
    Builder::makeFunction(getUnaryFuncName(curr), Signature(type, retType), {});
  func->body = builder.makeUnary(truncOp, builder.makeLocalGet(0, type));
  // too small XXX this is different than asm.js, which does frem. here we
  // clamp, which is much simpler/faster, and similar to native builds
  func->body = builder.makeIf(builder.makeBinary(leOp,
                                                 builder.makeLocalGet(0, type),
                                                 builder.makeConst(fMin)),
                              builder.makeConst(iMin),
                              func->body);
  // too big XXX see above
  func->body = builder.makeIf(
    builder.makeBinary(
      geOp, builder.makeLocalGet(0, type), builder.makeConst(fMax)),
    // NB: min here as well. anything out of range => to the min
    builder.makeConst(iMin),
    func->body);
  // nan
  func->body = builder.makeIf(
    builder.makeBinary(
      neOp, builder.makeLocalGet(0, type), builder.makeLocalGet(0, type)),
    // NB: min here as well. anything invalid => to the min
    builder.makeConst(iMin),
    func->body);
  // TODO: use unique_ptr properly and do not release ownership.
  return func.release();
}

void ensureBinaryFunc(Binary* curr,
                      Module& wasm,
                      TrappingFunctionContainer& trappingFunctions) {
  Name name = getBinaryFuncName(curr);
  if (trappingFunctions.hasFunction(name)) {
    return;
  }
  trappingFunctions.addFunction(generateBinaryFunc(wasm, curr));
}

void ensureUnaryFunc(Unary* curr,
                     Module& wasm,
                     TrappingFunctionContainer& trappingFunctions) {
  Name name = getUnaryFuncName(curr);
  if (trappingFunctions.hasFunction(name)) {
    return;
  }
  trappingFunctions.addFunction(generateUnaryFunc(wasm, curr));
}

void ensureF64ToI64JSImport(TrappingFunctionContainer& trappingFunctions) {
  if (trappingFunctions.hasImport(F64_TO_INT)) {
    return;
  }

  // f64-to-int = asm2wasm.f64-to-int;
  auto import = new Function;
  import->name = F64_TO_INT;
  import->module = ASM2WASM;
  import->base = F64_TO_INT;
  import->type = Signature(Type::f64, Type::i32);
  trappingFunctions.addImport(import);
}

Expression* makeTrappingBinary(Binary* curr,
                               TrappingFunctionContainer& trappingFunctions) {
  Name name = getBinaryFuncName(curr);
  if (!name.is() || trappingFunctions.getMode() == TrapMode::Allow) {
    return curr;
  }

  // the wasm operation might trap if done over 0, so generate a safe call
  Type type = curr->type;
  Module& wasm = trappingFunctions.getModule();
  Builder builder(wasm);
  ensureBinaryFunc(curr, wasm, trappingFunctions);
  return builder.makeCall(name, {curr->left, curr->right}, type);
}

Expression* makeTrappingUnary(Unary* curr,
                              TrappingFunctionContainer& trappingFunctions) {
  Name name = getUnaryFuncName(curr);
  TrapMode mode = trappingFunctions.getMode();
  if (!name.is() || mode == TrapMode::Allow) {
    return curr;
  }

  Module& wasm = trappingFunctions.getModule();
  Builder builder(wasm);
  // WebAssembly traps on float-to-int overflows, but asm.js wouldn't, so we
  // must do something We can handle this in one of two ways: clamping, which is
  // fast, or JS, which is precisely like JS but in order to do that we do a
  // slow ffi If i64, there is no "JS" way to handle this, as no i64s in JS, so
  // always clamp if we don't allow traps asm.js doesn't have unsigned
  // f64-to-int, so just use the signed one.
  if (curr->type != Type::i64 && mode == TrapMode::JS) {
    // WebAssembly traps on float-to-int overflows, but asm.js wouldn't, so we
    // must emulate that
    ensureF64ToI64JSImport(trappingFunctions);
    Expression* f64Value = ensureDouble(curr->value, wasm.allocator);
    return builder.makeCall(F64_TO_INT, {f64Value}, Type::i32);
  }

  ensureUnaryFunc(curr, wasm, trappingFunctions);
  return builder.makeCall(name, {curr->value}, curr->type);
}

struct TrapModePass : public WalkerPass<PostWalker<TrapModePass>> {
public:
  // Needs to be non-parallel so that visitModule gets called after visiting
  // each node in the module, so we can add the functions that we created.
  bool isFunctionParallel() override { return false; }

  TrapModePass(TrapMode mode) : mode(mode) { assert(mode != TrapMode::Allow); }

  Pass* create() override { return new TrapModePass(mode); }

  void visitUnary(Unary* curr) {
    replaceCurrent(makeTrappingUnary(curr, *trappingFunctions));
  }

  void visitBinary(Binary* curr) {
    replaceCurrent(makeTrappingBinary(curr, *trappingFunctions));
  }

  void visitModule(Module* curr) { trappingFunctions->addToModule(); }

  void doWalkModule(Module* module) {
    trappingFunctions = make_unique<TrappingFunctionContainer>(mode, *module);
    super::doWalkModule(module);
  }

private:
  TrapMode mode;
  // Need to defer adding generated functions because adding functions while
  // iterating over existing functions causes problems.
  std::unique_ptr<TrappingFunctionContainer> trappingFunctions;
};

Pass* createTrapModeClamp() { return new TrapModePass(TrapMode::Clamp); }

Pass* createTrapModeJS() { return new TrapModePass(TrapMode::JS); }

} // namespace wasm
