// Copyright (c) 2019, 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.analysis;

import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexDefinition;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ResolutionResult;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.CatchHandlers.CatchHandler;
import com.android.tools.r8.ir.code.DominatorTree;
import com.android.tools.r8.ir.code.DominatorTree.Assumption;
import com.android.tools.r8.ir.code.DominatorTree.Inclusive;
import com.android.tools.r8.ir.code.FieldInstruction;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.InitClass;
import com.android.tools.r8.ir.code.InstanceGet;
import com.android.tools.r8.ir.code.InstancePut;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionIterator;
import com.android.tools.r8.ir.code.InvokeDirect;
import com.android.tools.r8.ir.code.InvokeInterface;
import com.android.tools.r8.ir.code.InvokeStatic;
import com.android.tools.r8.ir.code.InvokeSuper;
import com.android.tools.r8.ir.code.InvokeVirtual;
import com.android.tools.r8.ir.code.NewInstance;
import com.android.tools.r8.ir.code.StaticGet;
import com.android.tools.r8.ir.code.StaticPut;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;
import com.google.common.collect.Streams;
import java.util.ArrayDeque;
import java.util.BitSet;
import java.util.Deque;
import java.util.List;
import java.util.Set;

/**
 * Analysis that given an instruction determines if a given type is guaranteed to be class
 * initialized prior the given instruction.
 */
public class ClassInitializationAnalysis {

  public enum AnalysisAssumption {
    INSTRUCTION_DOES_NOT_THROW,
    NONE
  }

  public enum Query {
    DIRECTLY,
    DIRECTLY_OR_INDIRECTLY
  }

  private static final ClassInitializationAnalysis TRIVIAL =
      new ClassInitializationAnalysis() {

        @Override
        public boolean isClassDefinitelyLoadedBeforeInstruction(
            DexType type, Instruction instruction) {
          return false;
        }
      };

  private final AppView<AppInfoWithLiveness> appView;
  private final IRCode code;
  private final DexItemFactory dexItemFactory;

  private DominatorTree dominatorTree = null;
  private int markingColor = -1;

  private ClassInitializationAnalysis() {
    this.appView = null;
    this.code = null;
    this.dexItemFactory = null;
  }

  public ClassInitializationAnalysis(AppView<AppInfoWithLiveness> appView, IRCode code) {
    this.appView = appView;
    this.code = code;
    this.dexItemFactory = appView.dexItemFactory();
  }

  // Returns a trivial, conservative analysis that always returns false.
  public static ClassInitializationAnalysis trivial() {
    return TRIVIAL;
  }

  public boolean isClassDefinitelyLoadedBeforeInstruction(DexType type, Instruction instruction) {
    DexType context = code.method.holder();
    BasicBlock block = instruction.getBlock();

    // Visit the instructions in `block` prior to `instruction`.
    for (Instruction previous : block.getInstructions()) {
      if (previous == instruction) {
        break;
      }
      if (previous.definitelyTriggersClassInitialization(
          type,
          context,
          appView,
          Query.DIRECTLY_OR_INDIRECTLY,
          // The given instruction is only reached if none of the instructions in the same
          // basic block throws, so we can safely assume that they will not.
          AnalysisAssumption.INSTRUCTION_DOES_NOT_THROW)) {
        return true;
      }
    }

    if (dominatorTree == null) {
      dominatorTree = new DominatorTree(code, Assumption.MAY_HAVE_UNREACHABLE_BLOCKS);
    }

    // Visit all the instructions in all the blocks that dominate `block`.
    for (BasicBlock dominator : dominatorTree.dominatorBlocks(block, Inclusive.NO)) {
      AnalysisAssumption assumption = getAssumptionForDominator(dominator, block);
      InstructionIterator instructionIterator = dominator.iterator();
      while (instructionIterator.hasNext()) {
        Instruction previous = instructionIterator.next();
        if (previous.definitelyTriggersClassInitialization(
            type, context, appView, Query.DIRECTLY_OR_INDIRECTLY, assumption)) {
          return true;
        }
        if (dominator.hasCatchHandlers() && previous.instructionTypeCanThrow()) {
          // All of the instructions that follow the first instruction that may throw are
          // guaranteed to be non-throwing. Hence they cannot cause any class initializations.
          assert Streams.stream(instructionIterator)
              .noneMatch(Instruction::instructionTypeCanThrow);
          break;
        }
      }
    }
    return false;
  }

  /**
   * Returns the analysis assumption to use when analyzing the instructions in the given dominator
   * block.
   *
   * <p>If the given block has no catch handlers, then we can safely assume that the instruction
   * does not throw, because execution would otherwise exit the method.
   *
   * <p>As a simple example, consider the method below. In order for the execution to get from the
   * call to A.foo() to the call to A.bar() the call A.foo() must not throw.
   *
   * <pre>
   *   public static void method() {
   *     A.foo();
   *     A.bar();
   *   }
   * </pre>
   *
   * This assumption cannot be made in the presence of intraprocedural exceptional control flow.
   * Consider the following example.
   *
   * <pre>
   *   public static void method(A instance) {
   *     try {
   *       instance.field = 42;
   *     } catch (Exception e) {
   *       A.foo();
   *       return;
   *     }
   *     A.bar();
   *   }
   * </pre>
   *
   * <p>At the call to A.foo() it is not guaranteed that the class A has been initialized, since
   * `instance` could always be null.
   *
   * <p>At the call to A.bar() it is guaranteed, since the instance field assignment succeeded.
   */
  private AnalysisAssumption getAssumptionForDominator(BasicBlock dominator, BasicBlock block) {
    if (!dominator.hasCatchHandlers()) {
      return AnalysisAssumption.INSTRUCTION_DOES_NOT_THROW;
    }

    Instruction exceptionalExit = dominator.exceptionalExit();
    if (exceptionalExit == null) {
      // The block cannot throw after all.
      return AnalysisAssumption.INSTRUCTION_DOES_NOT_THROW;
    }

    if (markingColor < 0) {
      markingColor = code.reserveMarkingColor();
      code.markTransitivePredecessors(block, markingColor);
    }

    for (CatchHandler<BasicBlock> catchHandler : dominator.getCatchHandlers()) {
      if (catchHandler.target.isMarked(markingColor)) {
        // There is a path from this catch handler to the instruction of interest, so we can't make
        // any assumptions.
        return AnalysisAssumption.NONE;
      }
    }

    // There are no paths from any of the catch handlers to the instruction of interest, so we can
    // assume that no instructions in the given block will throw (otherwise, the instruction of
    // interest will not be reached).
    return AnalysisAssumption.INSTRUCTION_DOES_NOT_THROW;
  }

  /**
   * The analysis reuses the dominator tree and basic block markings. If the underlying structure of
   * the IR changes, then this method must be called to reset the dominator tree, return the current
   * marking color, and clear all marks.
   */
  public void notifyCodeHasChanged() {
    dominatorTree = null;
    returnMarkingColor();
  }

  /** Returns the marking color, if any, and clears all marks. */
  public void finish() {
    returnMarkingColor();
  }

  private void returnMarkingColor() {
    if (markingColor >= 0) {
      code.returnMarkingColor(markingColor);
      markingColor = -1;
    }
  }

  public static class InstructionUtils {

    public static boolean forInitClass(
        InitClass instruction,
        DexType type,
        AppView<?> appView,
        Query mode,
        AnalysisAssumption assumption) {
      if (assumption == AnalysisAssumption.NONE) {
        // Class initialization may fail with ExceptionInInitializerError.
        return false;
      }
      DexClass clazz = appView.definitionFor(instruction.getClassValue());
      return clazz != null && isTypeInitializedBy(instruction, type, clazz, appView, mode);
    }

    public static boolean forInstanceGet(
        InstanceGet instruction,
        DexType type,
        AppView<?> appView,
        Query mode,
        AnalysisAssumption assumption) {
      return forInstanceGetOrPut(instruction, type, appView, mode, assumption);
    }

    public static boolean forInstancePut(
        InstancePut instruction,
        DexType type,
        AppView<?> appView,
        Query mode,
        AnalysisAssumption assumption) {
      return forInstanceGetOrPut(instruction, type, appView, mode, assumption);
    }

    private static boolean forInstanceGetOrPut(
        FieldInstruction instruction,
        DexType type,
        AppView<?> appView,
        Query mode,
        AnalysisAssumption assumption) {
      assert instruction.isInstanceGet() || instruction.isInstancePut();
      if (assumption == AnalysisAssumption.NONE) {
        Value object =
            instruction.isInstanceGet()
                ? instruction.asInstanceGet().object()
                : instruction.asInstancePut().object();
        if (object.getType().isNullable()) {
          // If the receiver is null we cannot be sure that the holder has been initialized.
          return false;
        }
      }
      DexEncodedField field = appView.appInfo().resolveField(instruction.getField());
      return field != null && isTypeInitializedBy(instruction, type, field, appView, mode);
    }

    public static boolean forInvokeDirect(
        InvokeDirect instruction,
        DexType type,
        AppView<?> appView,
        Query mode,
        AnalysisAssumption assumption) {
      if (assumption == AnalysisAssumption.NONE) {
        if (instruction.getReceiver().getType().isNullable()) {
          // If the receiver is null we cannot be sure that the holder has been initialized.
          return false;
        }
      }
      DexEncodedMethod method = appView.definitionFor(instruction.getInvokedMethod());
      return method != null && isTypeInitializedBy(instruction, type, method, appView, mode);
    }

    public static boolean forInvokeInterface(
        InvokeInterface instruction,
        DexType type,
        DexType context,
        AppView<?> appView,
        Query mode,
        AnalysisAssumption assumption) {
      if (assumption == AnalysisAssumption.NONE) {
        if (instruction.getReceiver().getType().isNullable()) {
          // If the receiver is null we cannot be sure that the holder has been initialized.
          return false;
        }
      }
      if (mode == Query.DIRECTLY) {
        // We cannot ensure exactly which class is being loaded because it depends on the runtime
        // type of the receiver.
        // TODO(christofferqa): We can do better if there is a unique target.
        return false;
      }
      if (appView.appInfo().hasLiveness()) {
        DexEncodedMethod singleTarget =
            instruction.lookupSingleTarget(appView.withLiveness(), context);
        if (singleTarget != null) {
          return isTypeInitializedBy(instruction, type, singleTarget, appView, mode);
        }
      }
      DexMethod method = instruction.getInvokedMethod();
      ResolutionResult resolutionResult =
          appView.appInfo().resolveMethodOnInterface(method.holder, method);
      if (!resolutionResult.isSingleResolution()) {
        return false;
      }
      DexType holder = resolutionResult.getSingleTarget().holder();
      return appView.isSubtype(holder, type).isTrue();
    }

    public static boolean forInvokeStatic(
        InvokeStatic instruction,
        DexType type,
        DexType context,
        AppView<?> appView,
        Query mode,
        AnalysisAssumption assumption) {
      if (assumption == AnalysisAssumption.NONE) {
        // Class initialization may fail with ExceptionInInitializerError.
        return false;
      }
      DexEncodedMethod method = instruction.lookupSingleTarget(appView, context);
      return method != null && isTypeInitializedBy(instruction, type, method, appView, mode);
    }

    public static boolean forInvokeSuper(
        InvokeSuper instruction,
        DexType type,
        DexType context,
        AppView<?> appView,
        Query mode,
        AnalysisAssumption assumption) {
      if (assumption == AnalysisAssumption.NONE) {
        if (instruction.getReceiver().getType().isNullable()) {
          // If the receiver is null we cannot be sure that the holder has been initialized.
          return false;
        }
      }
      if (mode == Query.DIRECTLY) {
        // We cannot ensure exactly which class is being loaded because it depends on the runtime
        // type of the receiver.
        // TODO(christofferqa): We can do better if there is a unique target.
        return false;
      }
      if (appView.appInfo().hasLiveness()) {
        DexEncodedMethod singleTarget =
            instruction.lookupSingleTarget(appView.withLiveness(), context);
        if (singleTarget != null) {
          return isTypeInitializedBy(instruction, type, singleTarget, appView, mode);
        }
      }
      DexMethod method = instruction.getInvokedMethod();
      DexClass enclosingClass = appView.definitionFor(method.holder);
      if (enclosingClass == null) {
        return false;
      }
      DexType superType = enclosingClass.superType;
      if (superType == null) {
        return false;
      }
      ResolutionResult resolutionResult =
          appView.appInfo().resolveMethod(superType, method, instruction.itf);
      if (!resolutionResult.isSingleResolution()) {
        return false;
      }
      DexType holder = resolutionResult.getSingleTarget().holder();
      return appView.isSubtype(holder, type).isTrue();
    }

    public static boolean forInvokeVirtual(
        InvokeVirtual instruction,
        DexType type,
        DexType context,
        AppView<?> appView,
        Query mode,
        AnalysisAssumption assumption) {
      if (assumption == AnalysisAssumption.NONE) {
        if (instruction.getReceiver().getType().isNullable()) {
          // If the receiver is null we cannot be sure that the holder has been initialized.
          return false;
        }
      }
      if (mode == Query.DIRECTLY) {
        // We cannot ensure exactly which class is being loaded because it depends on the runtime
        // type of the receiver.
        // TODO(christofferqa): We can do better if there is a unique target.
        return false;
      }
      if (appView.appInfo().hasLiveness()) {
        DexEncodedMethod singleTarget =
            instruction.lookupSingleTarget(appView.withLiveness(), context);
        if (singleTarget != null) {
          return isTypeInitializedBy(instruction, type, singleTarget, appView, mode);
        }
      }
      DexMethod method = instruction.getInvokedMethod();
      ResolutionResult resolutionResult =
          appView.appInfo().resolveMethodOnClass(method.holder, method);
      if (!resolutionResult.isSingleResolution()) {
        return false;
      }
      DexType holder = resolutionResult.getSingleTarget().holder();
      return appView.isSubtype(holder, type).isTrue();
    }

    public static boolean forNewInstance(
        NewInstance instruction,
        DexType type,
        AppView<?> appView,
        Query mode,
        AnalysisAssumption assumption) {
      if (assumption == AnalysisAssumption.NONE) {
        // Instruction may throw.
        return false;
      }
      DexClass clazz = appView.definitionFor(instruction.clazz);
      return clazz != null && isTypeInitializedBy(instruction, type, clazz, appView, mode);
    }

    public static boolean forStaticGet(
        StaticGet instruction,
        DexType type,
        AppView<?> appView,
        Query mode,
        AnalysisAssumption assumption) {
      return forStaticGetOrPut(instruction, type, appView, mode, assumption);
    }

    public static boolean forStaticPut(
        StaticPut instruction,
        DexType type,
        AppView<?> appView,
        Query mode,
        AnalysisAssumption assumption) {
      return forStaticGetOrPut(instruction, type, appView, mode, assumption);
    }

    private static boolean forStaticGetOrPut(
        FieldInstruction instruction,
        DexType type,
        AppView<?> appView,
        Query mode,
        AnalysisAssumption assumption) {
      assert instruction.isStaticGet() || instruction.isStaticPut();
      if (assumption == AnalysisAssumption.NONE) {
        // Class initialization may fail with ExceptionInInitializerError.
        return false;
      }
      DexEncodedField field = appView.appInfo().resolveField(instruction.getField());
      return field != null && isTypeInitializedBy(instruction, type, field, appView, mode);
    }

    private static boolean isTypeInitializedBy(
        Instruction instruction,
        DexType typeToBeInitialized,
        DexDefinition definition,
        AppView<?> appView,
        Query mode) {
      if (mode == Query.DIRECTLY) {
        if (definition.isDexClass()) {
          return definition.asDexClass().type == typeToBeInitialized;
        }
        if (definition.isDexEncodedMember()) {
          return definition.asDexEncodedMember().toReference().holder == typeToBeInitialized;
        }
        throw new Unreachable();
      }

      Set<DexType> visited = Sets.newIdentityHashSet();
      Deque<DexType> worklist = new ArrayDeque<>();

      if (definition.isDexClass()) {
        DexClass clazz = definition.asDexClass();
        enqueue(clazz.type, visited, worklist);
      } else if (definition.isDexEncodedField()) {
        DexEncodedField field = definition.asDexEncodedField();
        enqueue(field.holder(), visited, worklist);
      } else if (definition.isDexEncodedMethod()) {
        assert instruction.isInvokeMethod();
        DexEncodedMethod method = definition.asDexEncodedMethod();
        enqueue(method.holder(), visited, worklist);
        enqueueInitializedClassesOnNormalExit(method, instruction.inValues(), visited, worklist);
      } else {
        assert false;
      }

      while (!worklist.isEmpty()) {
        DexType typeKnownToBeInitialized = worklist.removeFirst();
        assert visited.contains(typeKnownToBeInitialized);

        if (appView.isSubtype(typeKnownToBeInitialized, typeToBeInitialized).isTrue()) {
          return true;
        }

        DexClass clazz = appView.definitionFor(typeKnownToBeInitialized);
        if (clazz != null) {
          DexEncodedMethod classInitializer = clazz.getClassInitializer();
          if (classInitializer != null) {
            enqueueInitializedClassesOnNormalExit(
                classInitializer, ImmutableList.of(), visited, worklist);
          }
        }
      }

      return false;
    }

    private static void enqueue(DexType type, Set<DexType> visited, Deque<DexType> worklist) {
      if (type.isClassType() && visited.add(type)) {
        worklist.add(type);
      }
    }

    private static void enqueueInitializedClassesOnNormalExit(
        DexEncodedMethod method,
        List<Value> arguments,
        Set<DexType> visited,
        Deque<DexType> worklist) {
      for (DexType type : method.getOptimizationInfo().getInitializedClassesOnNormalExit()) {
        enqueue(type, visited, worklist);
      }
      // If an invoke to an instance method succeeds, then the receiver must be non-null, which
      // implies that the type of the receiver must be initialized.
      if (!method.isStatic()) {
        assert arguments.size() > 0;
        TypeElement type = arguments.get(0).getType();
        if (type.isClassType()) {
          enqueue(type.asClassType().getClassType(), visited, worklist);
        }
      }
      // If an invoke to a method succeeds, and the method would have thrown and exception if the
      // i'th argument was null, then the i'th argument must be non-null, which implies that the
      // type of the i'th argument must be initialized.
      BitSet nonNullParamOrThrowFacts = method.getOptimizationInfo().getNonNullParamOrThrow();
      if (nonNullParamOrThrowFacts != null) {
        for (int i = 0; i < arguments.size(); i++) {
          if (nonNullParamOrThrowFacts.get(i)) {
            TypeElement type = arguments.get(i).getType();
            if (type.isClassType()) {
              enqueue(type.asClassType().getClassType(), visited, worklist);
            }
          }
        }
      }
    }
  }
}
