// 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.cf.LoadStoreHelper;
import com.android.tools.r8.cf.TypeVerificationHelper;
import com.android.tools.r8.cf.code.CfNewUnboxedEnum;
import com.android.tools.r8.code.DexNewUnboxedEnumInstance;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.VerifyTypesHelper;
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.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
import com.android.tools.r8.ir.optimize.InliningConstraints;
import com.android.tools.r8.ir.optimize.enums.EnumUnboxerImpl;

/**
 * Special instruction used by {@link EnumUnboxerImpl}.
 *
 * <p>When applying the enum unboxer to the application, we move the class initializer of each
 * unboxed enum to its utility class, and change each {@link NewInstance} instruction that
 * instantiates the unboxed enum into a {@link NewUnboxedEnumInstance} that holds the ordinal of the
 * enum instance.
 *
 * <p>The {@link NewUnboxedEnumInstance} is an instruction that produces an (initialized) instance
 * of the unboxed enum, i.e., the out-type is a non-nullable class type. This is important for the
 * code to type check until lens code rewriting, which replaces the {@link NewUnboxedEnumInstance}
 * instructions by {@link ConstNumber} instructions.
 *
 * <p>Note: The {@link NewUnboxedEnumInstance} is only used from {@link EnumUnboxerImpl#unboxEnums}
 * until the execution of the {@link com.android.tools.r8.ir.conversion.PostMethodProcessor}. There
 * should be no instances of {@link NewUnboxedEnumInstance} (nor {@link CfNewUnboxedEnum}, {@link
 * DexNewUnboxedEnumInstance}) after IR processing has finished.
 */
public class NewUnboxedEnumInstance extends Instruction {

  public final DexType clazz;
  private final int ordinal;

  public NewUnboxedEnumInstance(DexType clazz, int ordinal, Value dest) {
    super(dest);
    assert clazz != null;
    this.clazz = clazz;
    this.ordinal = ordinal;
  }

  public int getOrdinal() {
    return ordinal;
  }

  public DexType getType() {
    return clazz;
  }

  @Override
  public int opcode() {
    return Opcodes.NEW_UNBOXED_ENUM_INSTANCE;
  }

  @Override
  public <T> T accept(InstructionVisitor<T> visitor) {
    return visitor.visit(this);
  }

  @Override
  public void buildDex(DexBuilder builder) {
    int dest = builder.allocatedRegister(outValue(), getNumber());
    builder.add(this, new DexNewUnboxedEnumInstance(dest, clazz, ordinal));
  }

  @Override
  public String toString() {
    return super.toString() + " " + clazz;
  }

  @Override
  public boolean identicalNonValueNonPositionParts(Instruction other) {
    return other.isNewUnboxedEnumInstance() && other.asNewUnboxedEnumInstance().clazz == clazz;
  }

  @Override
  public int maxInValueRegister() {
    assert false : "NewUnboxedEnumInstance has no register arguments";
    return 0;
  }

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

  @Override
  public boolean instructionTypeCanThrow() {
    // Depending on how this instruction is lowered to CF/DEX the instruction type may throw. If we
    // lower the instruction to a const-number, then it can't throw, but if we lower it to something
    // that triggers the class initialization of the enum utility class, then it could throw.
    return true;
  }

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

  @Override
  public NewUnboxedEnumInstance asNewUnboxedEnumInstance() {
    return this;
  }

  @Override
  public ConstraintWithTarget inliningConstraint(
      InliningConstraints inliningConstraints, ProgramMethod context) {
    return inliningConstraints.forNewUnboxedEnumInstance(clazz, context);
  }

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

  @Override
  public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
    helper.storeOutValue(this, it);
  }

  @Override
  public void buildCf(CfBuilder builder) {
    builder.add(new CfNewUnboxedEnum(clazz, ordinal));
  }

  @Override
  public DexType computeVerificationType(AppView<?> appView, TypeVerificationHelper helper) {
    return clazz;
  }

  @Override
  public TypeElement evaluate(AppView<?> appView) {
    return TypeElement.fromDexType(clazz, Nullability.definitelyNotNull(), appView);
  }

  @Override
  public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
    // Conservatively return true.
    return true;
  }

  @Override
  public boolean verifyTypes(AppView<?> appView, VerifyTypesHelper verifyTypesHelper) {
    TypeElement type = getOutType();
    assert type.isClassType();
    assert type.asClassType().getClassType() == clazz || appView.options().testing.allowTypeErrors;
    assert type.isDefinitelyNotNull();
    return true;
  }
}
