// Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.code;

import com.android.tools.r8.code.InvokeCustomRange;
import com.android.tools.r8.code.InvokeDirectRange;
import com.android.tools.r8.code.InvokeInterfaceRange;
import com.android.tools.r8.code.InvokePolymorphicRange;
import com.android.tools.r8.code.InvokeStaticRange;
import com.android.tools.r8.code.InvokeSuperRange;
import com.android.tools.r8.code.InvokeVirtualRange;
import com.android.tools.r8.code.MoveResult;
import com.android.tools.r8.code.MoveResultObject;
import com.android.tools.r8.code.MoveResultWide;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItem;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexMethodHandle.MethodHandleType;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.GraphLens.MethodLookupResult;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.utils.BooleanUtils;
import java.util.List;
import java.util.Set;
import org.objectweb.asm.Opcodes;

public abstract class Invoke extends Instruction {

  private static final int NO_SUCH_DEX_INSTRUCTION = -1;

  public enum Type {
    DIRECT(com.android.tools.r8.code.InvokeDirect.OPCODE, InvokeDirectRange.OPCODE),
    INTERFACE(com.android.tools.r8.code.InvokeInterface.OPCODE, InvokeInterfaceRange.OPCODE),
    STATIC(com.android.tools.r8.code.InvokeStatic.OPCODE, InvokeStaticRange.OPCODE),
    SUPER(com.android.tools.r8.code.InvokeSuper.OPCODE, InvokeSuperRange.OPCODE),
    VIRTUAL(com.android.tools.r8.code.InvokeVirtual.OPCODE, InvokeVirtualRange.OPCODE),
    NEW_ARRAY(com.android.tools.r8.code.NewArray.OPCODE, NO_SUCH_DEX_INSTRUCTION),
    MULTI_NEW_ARRAY(NO_SUCH_DEX_INSTRUCTION, NO_SUCH_DEX_INSTRUCTION),
    CUSTOM(com.android.tools.r8.code.InvokeCustom.OPCODE, InvokeCustomRange.OPCODE),
    POLYMORPHIC(com.android.tools.r8.code.InvokePolymorphic.OPCODE, InvokePolymorphicRange.OPCODE);

    private final int dexOpcode;
    private final int dexOpcodeRange;

    Type(int dexOpcode, int dexOpcodeRange) {
      this.dexOpcode = dexOpcode;
      this.dexOpcodeRange = dexOpcodeRange;
    }

    public static Type fromCfOpcode(
        int opcode, DexMethod invokedMethod, DexClassAndMethod context, AppView<?> appView) {
      return fromCfOpcode(opcode, invokedMethod, context, appView, appView.codeLens());
    }

    public static Type fromCfOpcode(
        int opcode,
        DexMethod invokedMethod,
        DexClassAndMethod context,
        AppView<?> appView,
        GraphLens codeLens) {
      switch (opcode) {
        case Opcodes.INVOKEINTERFACE:
          return Type.INTERFACE;
        case Opcodes.INVOKESPECIAL:
          return fromInvokeSpecial(invokedMethod, context, appView, codeLens);
        case Opcodes.INVOKESTATIC:
          return Type.STATIC;
        case Opcodes.INVOKEVIRTUAL:
          return appView.dexItemFactory().polymorphicMethods.isPolymorphicInvoke(invokedMethod)
              ? Type.POLYMORPHIC
              : Type.VIRTUAL;
        default:
          throw new Unreachable("unknown CfInvoke opcode " + opcode);
      }
    }

    public static Type fromInvokeSpecial(
        DexMethod invokedMethod, DexClassAndMethod context, AppView<?> appView) {
      return fromInvokeSpecial(invokedMethod, context, appView, appView.codeLens());
    }

    public static Type fromInvokeSpecial(
        DexMethod invokedMethod,
        DexClassAndMethod context,
        AppView<?> appView,
        GraphLens codeLens) {
      if (invokedMethod.isInstanceInitializer(appView.dexItemFactory())) {
        return Type.DIRECT;
      }

      GraphLens graphLens = appView.graphLens();
      DexMethod originalContext =
          graphLens.getOriginalMethodSignature(context.getReference(), codeLens);
      if (invokedMethod.getHolderType() != originalContext.getHolderType()) {
        return Type.SUPER;
      }

      MethodLookupResult lookupResult =
          graphLens.lookupMethod(invokedMethod, context.getReference(), Type.DIRECT);
      if (lookupResult.getType().isVirtual()) {
        // This method has been publicized. The original invoke-type is DIRECT.
        return Type.DIRECT;
      }

      DexEncodedMethod definition = context.getHolder().lookupMethod(lookupResult.getReference());
      if (definition == null) {
        return Type.SUPER;
      }

      // If the definition was moved to the current context from a super class due to vertical class
      // merging, then this used to be an invoke-super.
      DexType originalHolderOfDefinition =
          graphLens.getOriginalMethodSignature(definition.getReference(), codeLens).getHolderType();
      if (originalHolderOfDefinition != originalContext.getHolderType()) {
        return Type.SUPER;
      }

      boolean originalContextIsInterface =
          context.getHolder().isInterface()
              || (appView.hasVerticallyMergedClasses()
                  && appView
                      .verticallyMergedClasses()
                      .hasInterfaceBeenMergedIntoSubtype(originalContext.getHolderType()));
      if (originalContextIsInterface) {
        // On interfaces invoke-special should be mapped to invoke-super if the invoke-special
        // instruction is used to target a default interface method.
        if (definition.belongsToVirtualPool()) {
          return Type.SUPER;
        }
      } else {
        // Due to desugaring of invoke-special instructions that target virtual methods, this should
        // never target a virtual method.
        assert definition.isPrivate() || lookupResult.getType().isVirtual();
      }

      return Type.DIRECT;
    }

    public int getCfOpcode() {
      switch (this) {
        case DIRECT:
          return Opcodes.INVOKESPECIAL;
        case INTERFACE:
          return Opcodes.INVOKEINTERFACE;
        case POLYMORPHIC:
          return Opcodes.INVOKEVIRTUAL;
        case STATIC:
          return Opcodes.INVOKESTATIC;
        case SUPER:
          return Opcodes.INVOKESPECIAL;
        case VIRTUAL:
          return Opcodes.INVOKEVIRTUAL;
        case NEW_ARRAY:
        case MULTI_NEW_ARRAY:
        default:
          throw new Unreachable();
      }
    }

    public int getDexOpcode() {
      assert dexOpcode >= 0;
      return dexOpcode;
    }

    public int getDexOpcodeRange() {
      assert dexOpcodeRange >= 0;
      return dexOpcodeRange;
    }

    public boolean isDirect() {
      return this == DIRECT;
    }

    public boolean isInterface() {
      return this == INTERFACE;
    }

    public boolean isStatic() {
      return this == STATIC;
    }

    public boolean isSuper() {
      return this == SUPER;
    }

    public boolean isVirtual() {
      return this == VIRTUAL;
    }

    public MethodHandleType toMethodHandle(DexMethod targetMethod) {
      switch (this) {
        case STATIC:
          return MethodHandleType.INVOKE_STATIC;
        case VIRTUAL:
          return MethodHandleType.INVOKE_INSTANCE;
        case DIRECT:
          if (targetMethod.name.toString().equals("<init>")) {
            return MethodHandleType.INVOKE_CONSTRUCTOR;
          } else {
            return MethodHandleType.INVOKE_DIRECT;
          }
        case INTERFACE:
          return MethodHandleType.INVOKE_INTERFACE;
        case SUPER:
          return MethodHandleType.INVOKE_SUPER;
        default:
          throw new Unreachable(
              "Conversion to method handle with unexpected invoke type: " + this);
      }
    }
  }

  protected Invoke(Value result, List<Value> arguments) {
    super(result, arguments);
  }

  @Deprecated
  public static Invoke create(
      Type type, DexItem target, DexProto proto, Value result, List<Value> arguments) {
    return create(type, target, proto, result, arguments, false);
  }

  public static Invoke create(
      Type type, DexItem target, DexProto proto, Value result, List<Value> arguments, boolean itf) {
    switch (type) {
      case DIRECT:
        return new InvokeDirect((DexMethod) target, result, arguments, itf);
      case INTERFACE:
        return new InvokeInterface((DexMethod) target, result, arguments);
      case STATIC:
        return new InvokeStatic((DexMethod) target, result, arguments, itf);
      case SUPER:
        return new InvokeSuper((DexMethod) target, result, arguments, itf);
      case VIRTUAL:
        return new InvokeVirtual((DexMethod) target, result, arguments);
      case NEW_ARRAY:
        return new InvokeNewArray((DexType) target, result, arguments);
      case MULTI_NEW_ARRAY:
        return new InvokeMultiNewArray((DexType) target, result, arguments);
      case CUSTOM:
        throw new Unreachable("Use InvokeCustom constructor instead");
      case POLYMORPHIC:
        return new InvokePolymorphic((DexMethod) target, proto, result, arguments);
    }
    throw new Unreachable("Unknown invoke type: " + type);
  }

  abstract public Type getType();

  abstract public DexType getReturnType();

  public boolean hasArguments() {
    return !arguments().isEmpty();
  }

  public boolean hasReturnTypeVoid(DexItemFactory factory) {
    return getReturnType() == factory.voidType;
  }

  public List<Value> arguments() {
    return inValues;
  }

  public Value getArgument(int index) {
    assert index < arguments().size();
    return arguments().get(index);
  }

  public Value getArgumentForParameter(int index) {
    int offset = BooleanUtils.intValue(!isInvokeStatic());
    return getArgument(index + offset);
  }

  public Value getFirstArgument() {
    return getArgument(0);
  }

  public Value getLastArgument() {
    return getArgument(arguments().size() - 1);
  }

  public int requiredArgumentRegisters() {
    int registers = 0;
    for (Value inValue : inValues) {
      registers += inValue.requiredRegisters();
    }
    return registers;
  }

  protected int argumentRegisterValue(int i, DexBuilder builder) {
    assert needsRangedInvoke(builder);
    if (i < arguments().size()) {
      // If argument values flow into ranged invokes, all the ranged invoke arguments
      // are arguments to this method in order. Therefore, we use the incoming registers
      // for the ranged invoke arguments. We know that arguments are always available there.
      // If argument reuse is allowed there is no splitting and if argument reuse is disallowed
      // the argument registers are never overwritten.
      return builder.argumentOrAllocateRegister(arguments().get(i), getNumber());
    }
    return 0;
  }

  protected int fillArgumentRegisters(DexBuilder builder, int[] registers) {
    assert !needsRangedInvoke(builder);
    int i = 0;
    for (Value value : arguments()) {
      // If one of the arguments to the invoke instruction is an argument of the enclosing method
      // that has been spilled at this location, then we need to take the argument from its
      // original input register (because the register allocator never inserts moves from an
      // argument register to a spill register). Note that this is only a problem if an argument
      // has been spilled to a register that is not the argument's original register.
      //
      // For simplicity, we just use the original input register for all arguments if the register
      // fits in 4 bits.
      int register = builder.argumentOrAllocateRegister(value, getNumber());
      if (register + value.requiredRegisters() - 1 > Constants.U4BIT_MAX) {
        register = builder.allocatedRegister(value, getNumber());
      }
      assert register + value.requiredRegisters() - 1 <= Constants.U4BIT_MAX;
      for (int j = 0; j < value.requiredRegisters(); j++) {
        assert i < 5;
        registers[i++] = register++;
      }
    }
    return i;
  }

  protected boolean argumentsConsecutive(DexBuilder builder) {
    Value value = arguments().get(0);
    int next = builder.argumentOrAllocateRegister(value, getNumber()) + value.requiredRegisters();
    for (int i = 1; i < arguments().size(); i++) {
      value = arguments().get(i);
      assert next == builder.argumentOrAllocateRegister(value, getNumber());
      next += value.requiredRegisters();
    }
    return true;
  }

  protected void addInvokeAndMoveResult(
      com.android.tools.r8.code.Instruction instruction, DexBuilder builder) {
    if (outValue != null && outValue.needsRegister()) {
      TypeElement moveType = outValue.getType();
      int register = builder.allocatedRegister(outValue, getNumber());
      com.android.tools.r8.code.Instruction moveResult;
      if (moveType.isSinglePrimitive()) {
        moveResult = new MoveResult(register);
      } else if (moveType.isWidePrimitive()) {
        moveResult = new MoveResultWide(register);
      } else if (moveType.isReferenceType()) {
        moveResult = new MoveResultObject(register);
      } else {
        throw new Unreachable("Unexpected result type " + outType());
      }
      builder.add(this, instruction, moveResult);
    } else {
      builder.add(this, instruction);
    }
  }

  @Override
  public boolean couldIntroduceAnAlias(AppView<?> appView, Value root) {
    assert root != null && root.getType().isReferenceType();
    if (outValue == null) {
      return false;
    }
    TypeElement outType = outValue.getType();
    if (outType.isPrimitiveType()) {
      return false;
    }
    if (appView.appInfo().hasLiveness()) {
      if (outType.isClassType()
          && root.getType().isClassType()
          && appView
              .appInfo()
              .withLiveness()
              .inDifferentHierarchy(
                  outType.asClassType().getClassType(),
                  root.getType().asClassType().getClassType())) {
        return false;
      }
    }
    return outType.isReferenceType();
  }

  @Override
  public boolean instructionTypeCanThrow() {
    return true;
  }

  @Override
  public int maxInValueRegister() {
    if (arguments().size() == 1
        || requiredArgumentRegisters() > 5
        || argumentsAreConsecutiveInputArguments()) {
      return Constants.U16BIT_MAX;
    }
    return Constants.U4BIT_MAX;
  }

  private boolean argumentsAreConsecutiveInputArguments() {
    if (arguments().size() == 0) {
      return false;
    }
    Value current = arguments().get(0);
    if (!current.isArgument()) {
      return false;
    }
    for (int i = 1; i < arguments().size(); i++) {
      Value next = arguments().get(i);
      if (current.getNextConsecutive() != next) {
        return false;
      }
      current = next;
    }
    return true;
  }

  protected boolean needsRangedInvoke(DexBuilder builder) {
    if (requiredArgumentRegisters() > 5) {
      // No way around using an invoke-range instruction.
      return true;
    }
    // By using an invoke-range instruction when there is only one argument, we avoid having to
    // satisfy the constraint that the argument register(s) must fit in 4 bits.
    boolean registersGuaranteedToBeConsecutive =
        arguments().size() == 1 || argumentsAreConsecutiveInputArguments();
    if (!registersGuaranteedToBeConsecutive) {
      // No way that we will need an invoke-range.
      return false;
    }
    // If we could use an invoke-range instruction, but all the registers fit in 4 bits, then we
    // use a non-range invoke.
    assert argumentsConsecutive(builder);
    int registerStart = builder.argumentOrAllocateRegister(arguments().get(0), getNumber());
    int registerEnd = registerStart + requiredArgumentRegisters() - 1;
    return registerEnd > Constants.U4BIT_MAX;
  }

  @Override
  public int maxOutValueRegister() {
    return Constants.U8BIT_MAX;
  }

  abstract protected String getTypeString();

  @Override
  public String getInstructionName() {
    return "Invoke-" + getTypeString();
  }

  @Override
  public boolean isInvoke() {
    return true;
  }

  @Override
  public Invoke asInvoke() {
    return this;
  }

  @Override
  public TypeElement evaluate(AppView<?> appView) {
    DexType returnType = getReturnType();
    if (returnType.isVoidType()) {
      throw new Unreachable("void methods have no type.");
    }
    return TypeElement.fromDexType(returnType, Nullability.maybeNull(), appView);
  }

  @Override
  public boolean outTypeKnownToBeBoolean(Set<Phi> seen) {
    return getReturnType().isBooleanType();
  }
}
