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

import com.android.tools.r8.cf.code.CfArithmeticBinop;
import com.android.tools.r8.cf.code.CfArrayLength;
import com.android.tools.r8.cf.code.CfArrayLoad;
import com.android.tools.r8.cf.code.CfArrayStore;
import com.android.tools.r8.cf.code.CfCheckCast;
import com.android.tools.r8.cf.code.CfCmp;
import com.android.tools.r8.cf.code.CfConstClass;
import com.android.tools.r8.cf.code.CfConstMethodHandle;
import com.android.tools.r8.cf.code.CfConstMethodType;
import com.android.tools.r8.cf.code.CfConstNull;
import com.android.tools.r8.cf.code.CfConstNumber;
import com.android.tools.r8.cf.code.CfConstString;
import com.android.tools.r8.cf.code.CfFieldInstruction;
import com.android.tools.r8.cf.code.CfFrame;
import com.android.tools.r8.cf.code.CfFrame.FrameType;
import com.android.tools.r8.cf.code.CfGoto;
import com.android.tools.r8.cf.code.CfIf;
import com.android.tools.r8.cf.code.CfIfCmp;
import com.android.tools.r8.cf.code.CfIinc;
import com.android.tools.r8.cf.code.CfInstanceOf;
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.cf.code.CfInvoke;
import com.android.tools.r8.cf.code.CfInvokeDynamic;
import com.android.tools.r8.cf.code.CfJsrRet;
import com.android.tools.r8.cf.code.CfLabel;
import com.android.tools.r8.cf.code.CfLoad;
import com.android.tools.r8.cf.code.CfLogicalBinop;
import com.android.tools.r8.cf.code.CfMonitor;
import com.android.tools.r8.cf.code.CfMultiANewArray;
import com.android.tools.r8.cf.code.CfNeg;
import com.android.tools.r8.cf.code.CfNew;
import com.android.tools.r8.cf.code.CfNewArray;
import com.android.tools.r8.cf.code.CfNop;
import com.android.tools.r8.cf.code.CfNumberConversion;
import com.android.tools.r8.cf.code.CfPosition;
import com.android.tools.r8.cf.code.CfReturn;
import com.android.tools.r8.cf.code.CfReturnVoid;
import com.android.tools.r8.cf.code.CfStackInstruction;
import com.android.tools.r8.cf.code.CfStore;
import com.android.tools.r8.cf.code.CfSwitch;
import com.android.tools.r8.cf.code.CfThrow;
import com.android.tools.r8.cf.code.CfTryCatch;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.CfCode.LocalVariableInfo;
import com.android.tools.r8.graph.JarClassFileReader.ReparseContext;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.If;
import com.android.tools.r8.ir.code.MemberType;
import com.android.tools.r8.ir.code.Monitor;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.ValueNumberGenerator;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.shaking.ProguardConfiguration;
import com.android.tools.r8.shaking.ProguardKeepAttributes;
import com.android.tools.r8.utils.InternalOptions;
import it.unimi.dsi.fastutil.ints.Int2ReferenceAVLTreeMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceSortedMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Handle;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.JSRInlinerAdapter;

public class LazyCfCode extends Code {

  private static class JsrEncountered extends RuntimeException {
    public JsrEncountered(String s) {
      super(s);
    }
  }

  public LazyCfCode(
      DexMethod method, Origin origin, ReparseContext context, JarApplicationReader application) {
    this.origin = origin;
    this.context = context;
    this.application = application;
    context.codeList.add(this);
  }

  private final Origin origin;
  private final JarApplicationReader application;
  private CfCode code;
  protected ReparseContext context;
  private boolean reachabilitySensitive = false;

  public void markReachabilitySensitive() {
    assert code == null;
    reachabilitySensitive = true;
  }

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

  @Override
  public LazyCfCode asLazyCfCode() {
    return this;
  }

  @Override
  public CfCode asCfCode() {
    if (code == null) {
      ReparseContext context = this.context;
      assert context != null;
      // The ClassCodeVisitor is in charge of setting this.context to null.
      try {
        parseCode(context, false);
      } catch (JsrEncountered e) {
        for (Code code : context.codeList) {
          code.asLazyCfCode().code = null;
          code.asLazyCfCode().context = context;
        }
        try {
          parseCode(context, true);
        } catch (JsrEncountered e1) {
          throw new Unreachable(e1);
        }
      }
      assert verifyNoReparseContext(context.owner);
    }
    assert code != null;
    return code;
  }

  public void parseCode(ReparseContext context, boolean useJsrInliner) {
    int parsingOptions = getParsingOptions(application, reachabilitySensitive);
    ClassCodeVisitor classVisitor =
        new ClassCodeVisitor(context.owner, createCodeLocator(context), application, useJsrInliner);
    new ClassReader(context.classCache).accept(classVisitor, parsingOptions);
  }

  private void setCode(CfCode code) {
    assert this.code == null;
    assert this.context != null;
    this.code = code;
    this.context = null;
  }

  @Override
  protected int computeHashCode() {
    throw new Unimplemented();
  }

  @Override
  protected boolean computeEquals(Object other) {
    throw new Unimplemented();
  }

  @Override
  public boolean isEmptyVoidMethod() {
    return asCfCode().isEmptyVoidMethod();
  }

  @Override
  public int estimatedSizeForInlining() {
    return asCfCode().estimatedSizeForInlining();
  }

  @Override
  public boolean estimatedSizeForInliningAtMost(int threshold) {
    return asCfCode().estimatedSizeForInliningAtMost(threshold);
  }

  @Override
  public IRCode buildIR(DexEncodedMethod encodedMethod, AppView<?> appView, Origin origin) {
    return asCfCode().buildIR(encodedMethod, appView, origin);
  }

  @Override
  public IRCode buildInliningIR(
      DexEncodedMethod context,
      DexEncodedMethod encodedMethod,
      AppView<?> appView,
      ValueNumberGenerator valueNumberGenerator,
      Position callerPosition,
      Origin origin) {
    return asCfCode()
        .buildInliningIR(
            context, encodedMethod, appView, valueNumberGenerator, callerPosition, origin);
  }

  @Override
  public void registerCodeReferences(DexEncodedMethod method, UseRegistry registry) {
    asCfCode().registerCodeReferences(method, registry);
  }

  @Override
  public void registerArgumentReferences(DexEncodedMethod method, ArgumentUse registry) {
    asCfCode().registerArgumentReferences(method, registry);
  }

  @Override
  public String toString() {
    return asCfCode().toString();
  }

  @Override
  public String toString(DexEncodedMethod method, ClassNameMapper naming) {
    return asCfCode().toString(method, naming);
  }

  protected BiFunction<String, String, LazyCfCode> createCodeLocator(ReparseContext context) {
    return new DefaultCodeLocator(context, application);
  }

  private static class DefaultCodeLocator implements BiFunction<String, String, LazyCfCode> {
    private final ReparseContext context;
    private final JarApplicationReader application;
    private int methodIndex = 0;

    private DefaultCodeLocator(ReparseContext context, JarApplicationReader application) {
      this.context = context;
      this.application = application;
    }

    @Override
    public LazyCfCode apply(String name, String desc) {
      return context.codeList.get(methodIndex++).asLazyCfCode();
    }
  }

  private static class ClassCodeVisitor extends ClassVisitor {

    private final DexClass clazz;
    private final BiFunction<String, String, LazyCfCode> codeLocator;
    private final JarApplicationReader application;
    private boolean usrJsrInliner;

    ClassCodeVisitor(
        DexClass clazz,
        BiFunction<String, String, LazyCfCode> codeLocator,
        JarApplicationReader application,
        boolean useJsrInliner) {
      super(InternalOptions.ASM_VERSION);
      this.clazz = clazz;
      this.codeLocator = codeLocator;
      this.application = application;
      this.usrJsrInliner = useJsrInliner;
    }

    @Override
    public MethodVisitor visitMethod(
        int access, String name, String desc, String signature, String[] exceptions) {
      MethodAccessFlags flags = JarClassFileReader.createMethodAccessFlags(name, access);
      if (!flags.isAbstract() && !flags.isNative()) {
        LazyCfCode code = codeLocator.apply(name, desc);
        if (code != null) {
          DexMethod method = application.getMethod(clazz.type, name, desc);
          MethodCodeVisitor methodVisitor = new MethodCodeVisitor(application, method, code);
          if (!usrJsrInliner) {
            return methodVisitor;
          }
          return new JSRInlinerAdapter(methodVisitor, access, name, desc, signature, exceptions);
        }
      }
      return null;
    }
  }

  private static class MethodCodeVisitor extends MethodVisitor {
    private final JarApplicationReader application;
    private final DexItemFactory factory;
    private int maxStack;
    private int maxLocals;
    private List<CfInstruction> instructions;
    private List<CfTryCatch> tryCatchRanges;
    private List<LocalVariableInfo> localVariables;
    private final Map<DebugLocalInfo, DebugLocalInfo> canonicalDebugLocalInfo = new HashMap<>();
    private Map<Label, CfLabel> labelMap;
    private final LazyCfCode code;
    private final DexMethod method;

    MethodCodeVisitor(JarApplicationReader application, DexMethod method, LazyCfCode code) {
      super(InternalOptions.ASM_VERSION);
      assert code != null;
      this.application = application;
      this.factory = application.getFactory();
      this.code = code;
      this.method = method;
    }

    @Override
    public void visitCode() {
      maxStack = 0;
      maxLocals = 0;
      instructions = new ArrayList<>();
      tryCatchRanges = new ArrayList<>();
      localVariables = new ArrayList<>();
      labelMap = new IdentityHashMap<>();
    }

    @Override
    public void visitEnd() {
      code.setCode(
          new CfCode(
              method.holder, maxStack, maxLocals, instructions, tryCatchRanges, localVariables));
    }

    @Override
    public void visitFrame(
        int frameType, int nLocals, Object[] localTypes, int nStack, Object[] stackTypes) {
      assert frameType == Opcodes.F_NEW;
      Int2ReferenceSortedMap<FrameType> parsedLocals = parseLocals(nLocals, localTypes);
      List<FrameType> parsedStack = parseStack(nStack, stackTypes);
      instructions.add(new CfFrame(parsedLocals, parsedStack));
    }

    private Int2ReferenceSortedMap<FrameType> parseLocals(int typeCount, Object[] asmTypes) {
      Int2ReferenceSortedMap<FrameType> types = new Int2ReferenceAVLTreeMap<>();
      int i = 0;
      for (int j = 0; j < typeCount; j++) {
        Object localType = asmTypes[j];
        FrameType value = getFrameType(localType);
        types.put(i++, value);
        if (value.isWide()) {
          i++;
        }
      }
      return types;
    }

    private List<FrameType> parseStack(int nStack, Object[] stackTypes) {
      List<FrameType> dexStack = new ArrayList<>(nStack);
      for (int i = 0; i < nStack; i++) {
        dexStack.add(getFrameType(stackTypes[i]));
      }
      return dexStack;
    }

    private FrameType getFrameType(Object localType) {
      if (localType instanceof Label) {
        return FrameType.uninitializedNew(getLabel((Label) localType));
      } else if (localType == Opcodes.UNINITIALIZED_THIS) {
        return FrameType.uninitializedThis();
      } else if (localType == null || localType == Opcodes.TOP) {
        return FrameType.top();
      } else {
        return FrameType.initialized(parseAsmType(localType));
      }
    }

    private CfLabel getLabel(Label label) {
      return labelMap.computeIfAbsent(label, l -> new CfLabel());
    }

    private DexType parseAsmType(Object local) {
      assert local != null && local != Opcodes.TOP;
      if (local == Opcodes.INTEGER) {
        return factory.intType;
      } else if (local == Opcodes.FLOAT) {
        return factory.floatType;
      } else if (local == Opcodes.LONG) {
        return factory.longType;
      } else if (local == Opcodes.DOUBLE) {
        return factory.doubleType;
      } else if (local == Opcodes.NULL) {
        return DexItemFactory.nullValueType;
      } else if (local instanceof String) {
        return createTypeFromInternalType((String) local);
      } else {
        throw new Unreachable("Unexpected ASM type: " + local);
      }
    }

    private DexType createTypeFromInternalType(String local) {
      assert local.indexOf('.') == -1;
      return factory.createType(Type.getObjectType(local).getDescriptor());
    }

    @Override
    public void visitInsn(int opcode) {
      switch (opcode) {
        case Opcodes.NOP:
          instructions.add(new CfNop());
          break;
        case Opcodes.ACONST_NULL:
          instructions.add(new CfConstNull());
          break;
        case Opcodes.ICONST_M1:
        case Opcodes.ICONST_0:
        case Opcodes.ICONST_1:
        case Opcodes.ICONST_2:
        case Opcodes.ICONST_3:
        case Opcodes.ICONST_4:
        case Opcodes.ICONST_5:
          instructions.add(new CfConstNumber(opcode - Opcodes.ICONST_0, ValueType.INT));
          break;
        case Opcodes.LCONST_0:
        case Opcodes.LCONST_1:
          instructions.add(new CfConstNumber(opcode - Opcodes.LCONST_0, ValueType.LONG));
          break;
        case Opcodes.FCONST_0:
        case Opcodes.FCONST_1:
        case Opcodes.FCONST_2:
          instructions.add(
              new CfConstNumber(
                  Float.floatToRawIntBits(opcode - Opcodes.FCONST_0), ValueType.FLOAT));
          break;
        case Opcodes.DCONST_0:
        case Opcodes.DCONST_1:
          instructions.add(
              new CfConstNumber(
                  Double.doubleToRawLongBits(opcode - Opcodes.DCONST_0), ValueType.DOUBLE));
          break;
        case Opcodes.IALOAD:
        case Opcodes.LALOAD:
        case Opcodes.FALOAD:
        case Opcodes.DALOAD:
        case Opcodes.AALOAD:
        case Opcodes.BALOAD:
        case Opcodes.CALOAD:
        case Opcodes.SALOAD:
          instructions.add(new CfArrayLoad(getMemberTypeForOpcode(opcode)));
          break;
        case Opcodes.IASTORE:
        case Opcodes.LASTORE:
        case Opcodes.FASTORE:
        case Opcodes.DASTORE:
        case Opcodes.AASTORE:
        case Opcodes.BASTORE:
        case Opcodes.CASTORE:
        case Opcodes.SASTORE:
          instructions.add(new CfArrayStore(getMemberTypeForOpcode(opcode)));
          break;
        case Opcodes.POP:
        case Opcodes.POP2:
        case Opcodes.DUP:
        case Opcodes.DUP_X1:
        case Opcodes.DUP_X2:
        case Opcodes.DUP2:
        case Opcodes.DUP2_X1:
        case Opcodes.DUP2_X2:
        case Opcodes.SWAP:
          instructions.add(CfStackInstruction.fromAsm(opcode));
          break;
        case Opcodes.IADD:
        case Opcodes.LADD:
        case Opcodes.FADD:
        case Opcodes.DADD:
        case Opcodes.ISUB:
        case Opcodes.LSUB:
        case Opcodes.FSUB:
        case Opcodes.DSUB:
        case Opcodes.IMUL:
        case Opcodes.LMUL:
        case Opcodes.FMUL:
        case Opcodes.DMUL:
        case Opcodes.IDIV:
        case Opcodes.LDIV:
        case Opcodes.FDIV:
        case Opcodes.DDIV:
        case Opcodes.IREM:
        case Opcodes.LREM:
        case Opcodes.FREM:
        case Opcodes.DREM:
          instructions.add(CfArithmeticBinop.fromAsm(opcode));
          break;
        case Opcodes.INEG:
        case Opcodes.LNEG:
        case Opcodes.FNEG:
        case Opcodes.DNEG:
          instructions.add(CfNeg.fromAsm(opcode));
          break;
        case Opcodes.ISHL:
        case Opcodes.LSHL:
        case Opcodes.ISHR:
        case Opcodes.LSHR:
        case Opcodes.IUSHR:
        case Opcodes.LUSHR:
        case Opcodes.IAND:
        case Opcodes.LAND:
        case Opcodes.IOR:
        case Opcodes.LOR:
        case Opcodes.IXOR:
        case Opcodes.LXOR:
          instructions.add(CfLogicalBinop.fromAsm(opcode));
          break;
        case Opcodes.I2L:
        case Opcodes.I2F:
        case Opcodes.I2D:
        case Opcodes.L2I:
        case Opcodes.L2F:
        case Opcodes.L2D:
        case Opcodes.F2I:
        case Opcodes.F2L:
        case Opcodes.F2D:
        case Opcodes.D2I:
        case Opcodes.D2L:
        case Opcodes.D2F:
        case Opcodes.I2B:
        case Opcodes.I2C:
        case Opcodes.I2S:
          instructions.add(CfNumberConversion.fromAsm(opcode));
          break;
        case Opcodes.LCMP:
        case Opcodes.FCMPL:
        case Opcodes.FCMPG:
        case Opcodes.DCMPL:
        case Opcodes.DCMPG:
          instructions.add(CfCmp.fromAsm(opcode));
          break;
        case Opcodes.IRETURN:
          instructions.add(new CfReturn(ValueType.INT));
          break;
        case Opcodes.LRETURN:
          instructions.add(new CfReturn(ValueType.LONG));
          break;
        case Opcodes.FRETURN:
          instructions.add(new CfReturn(ValueType.FLOAT));
          break;
        case Opcodes.DRETURN:
          instructions.add(new CfReturn(ValueType.DOUBLE));
          break;
        case Opcodes.ARETURN:
          instructions.add(new CfReturn(ValueType.OBJECT));
          break;
        case Opcodes.RETURN:
          instructions.add(new CfReturnVoid());
          break;
        case Opcodes.ARRAYLENGTH:
          instructions.add(new CfArrayLength());
          break;
        case Opcodes.ATHROW:
          instructions.add(new CfThrow());
          break;
        case Opcodes.MONITORENTER:
          instructions.add(new CfMonitor(Monitor.Type.ENTER));
          break;
        case Opcodes.MONITOREXIT:
          instructions.add(new CfMonitor(Monitor.Type.EXIT));
          break;
        default:
          throw new Unreachable("Unknown instruction");
      }
    }

    private static MemberType getMemberTypeForOpcode(int opcode) {
      switch (opcode) {
        case Opcodes.IALOAD:
        case Opcodes.IASTORE:
          return MemberType.INT;
        case Opcodes.FALOAD:
        case Opcodes.FASTORE:
          return MemberType.FLOAT;
        case Opcodes.LALOAD:
        case Opcodes.LASTORE:
          return MemberType.LONG;
        case Opcodes.DALOAD:
        case Opcodes.DASTORE:
          return MemberType.DOUBLE;
        case Opcodes.AALOAD:
        case Opcodes.AASTORE:
          return MemberType.OBJECT;
        case Opcodes.BALOAD:
        case Opcodes.BASTORE:
          return MemberType.BOOLEAN_OR_BYTE;
        case Opcodes.CALOAD:
        case Opcodes.CASTORE:
          return MemberType.CHAR;
        case Opcodes.SALOAD:
        case Opcodes.SASTORE:
          return MemberType.SHORT;
        default:
          throw new Unreachable("Unexpected array opcode " + opcode);
      }
    }

    @Override
    public void visitIntInsn(int opcode, int operand) {
      switch (opcode) {
        case Opcodes.SIPUSH:
        case Opcodes.BIPUSH:
          instructions.add(new CfConstNumber(operand, ValueType.INT));
          break;
        case Opcodes.NEWARRAY:
          instructions.add(
              new CfNewArray(factory.createArrayType(1, arrayTypeDesc(operand, factory))));
          break;
        default:
          throw new Unreachable("Unexpected int opcode " + opcode);
      }
    }

    private static DexType arrayTypeDesc(int arrayTypeCode, DexItemFactory factory) {
      switch (arrayTypeCode) {
        case Opcodes.T_BOOLEAN:
          return factory.booleanType;
        case Opcodes.T_CHAR:
          return factory.charType;
        case Opcodes.T_FLOAT:
          return factory.floatType;
        case Opcodes.T_DOUBLE:
          return factory.doubleType;
        case Opcodes.T_BYTE:
          return factory.byteType;
        case Opcodes.T_SHORT:
          return factory.shortType;
        case Opcodes.T_INT:
          return factory.intType;
        case Opcodes.T_LONG:
          return factory.longType;
        default:
          throw new Unreachable("Unexpected array-type code " + arrayTypeCode);
      }
    }

    @Override
    public void visitVarInsn(int opcode, int var) {
      ValueType type;
      switch (opcode) {
        case Opcodes.ILOAD:
        case Opcodes.ISTORE:
          type = ValueType.INT;
          break;
        case Opcodes.FLOAD:
        case Opcodes.FSTORE:
          type = ValueType.FLOAT;
          break;
        case Opcodes.LLOAD:
        case Opcodes.LSTORE:
          type = ValueType.LONG;
          break;
        case Opcodes.DLOAD:
        case Opcodes.DSTORE:
          type = ValueType.DOUBLE;
          break;
        case Opcodes.ALOAD:
        case Opcodes.ASTORE:
          type = ValueType.OBJECT;
          break;
        case Opcodes.RET:
          {
            instructions.add(new CfJsrRet(var));
            return;
          }
        default:
          throw new Unreachable("Unexpected VarInsn opcode: " + opcode);
      }
      if (Opcodes.ILOAD <= opcode && opcode <= Opcodes.ALOAD) {
        instructions.add(new CfLoad(type, var));
      } else {
        instructions.add(new CfStore(type, var));
      }
    }

    @Override
    public void visitTypeInsn(int opcode, String typeName) {
      DexType type = factory.createType(Type.getObjectType(typeName).getDescriptor());
      switch (opcode) {
        case Opcodes.NEW:
          instructions.add(new CfNew(type));
          break;
        case Opcodes.ANEWARRAY:
          instructions.add(new CfNewArray(factory.createArrayType(1, type)));
          break;
        case Opcodes.CHECKCAST:
          instructions.add(new CfCheckCast(type));
          break;
        case Opcodes.INSTANCEOF:
          instructions.add(new CfInstanceOf(type));
          break;
        default:
          throw new Unreachable("Unexpected TypeInsn opcode: " + opcode);
      }
    }

    @Override
    public void visitFieldInsn(int opcode, String owner, String name, String desc) {
      DexField field =
          factory.createField(createTypeFromInternalType(owner), factory.createType(desc), name);
      // TODO(mathiasr): Don't require CfFieldInstruction::declaringField. It is needed for proper
      // renaming in the backend, but it is not available here in the frontend.
      instructions.add(new CfFieldInstruction(opcode, field, field));
    }

    @Override
    public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
      DexMethod method = application.getMethod(owner, name, desc);
      instructions.add(new CfInvoke(opcode, method, itf));
    }

    @Override
    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
      DexCallSite callSite =
          DexCallSite.fromAsmInvokeDynamic(application, method.holder, name, desc, bsm, bsmArgs);
      instructions.add(new CfInvokeDynamic(callSite));
    }

    @Override
    public void visitJumpInsn(int opcode, Label label) {
      CfLabel target = getLabel(label);
      if (Opcodes.IFEQ <= opcode && opcode <= Opcodes.IF_ACMPNE) {
        if (opcode <= Opcodes.IFLE) {
          // IFEQ, IFNE, IFLT, IFGE, IFGT, or IFLE.
          instructions.add(new CfIf(ifType(opcode), ValueType.INT, target));
        } else {
          // IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, or
          // IF_ACMPNE.
          ValueType valueType;
          if (opcode <= Opcodes.IF_ICMPLE) {
            valueType = ValueType.INT;
          } else {
            valueType = ValueType.OBJECT;
          }
          instructions.add(new CfIfCmp(ifType(opcode), valueType, target));
        }
      } else {
        // GOTO, JSR, IFNULL or IFNONNULL.
        switch (opcode) {
          case Opcodes.GOTO:
            instructions.add(new CfGoto(target));
            break;
          case Opcodes.IFNULL:
          case Opcodes.IFNONNULL:
            If.Type type = opcode == Opcodes.IFNULL ? If.Type.EQ : If.Type.NE;
            instructions.add(new CfIf(type, ValueType.OBJECT, target));
            break;
          case Opcodes.JSR:
            throw new JsrEncountered("JSR should be handled by the ASM jsr inliner");
          default:
            throw new Unreachable("Unexpected JumpInsn opcode: " + opcode);
        }
      }
    }

    private static If.Type ifType(int opcode) {
      switch (opcode) {
        case Opcodes.IFEQ:
        case Opcodes.IF_ICMPEQ:
        case Opcodes.IF_ACMPEQ:
          return If.Type.EQ;
        case Opcodes.IFNE:
        case Opcodes.IF_ICMPNE:
        case Opcodes.IF_ACMPNE:
          return If.Type.NE;
        case Opcodes.IFLT:
        case Opcodes.IF_ICMPLT:
          return If.Type.LT;
        case Opcodes.IFGE:
        case Opcodes.IF_ICMPGE:
          return If.Type.GE;
        case Opcodes.IFGT:
        case Opcodes.IF_ICMPGT:
          return If.Type.GT;
        case Opcodes.IFLE:
        case Opcodes.IF_ICMPLE:
          return If.Type.LE;
        default:
          throw new Unreachable("Unexpected If instruction opcode: " + opcode);
      }
    }

    @Override
    public void visitLabel(Label label) {
      instructions.add(getLabel(label));
    }

    @Override
    public void visitLdcInsn(Object cst) {
      if (cst instanceof Type) {
        Type type = (Type) cst;
        if (type.getSort() == Type.METHOD) {
          DexProto proto = application.getProto(type.getDescriptor());
          instructions.add(new CfConstMethodType(proto));
        } else {
          instructions.add(new CfConstClass(factory.createType(type.getDescriptor())));
        }
      } else if (cst instanceof String) {
        instructions.add(new CfConstString(factory.createString((String) cst)));
      } else if (cst instanceof Long) {
        instructions.add(new CfConstNumber((Long) cst, ValueType.LONG));
      } else if (cst instanceof Double) {
        long l = Double.doubleToRawLongBits((Double) cst);
        instructions.add(new CfConstNumber(l, ValueType.DOUBLE));
      } else if (cst instanceof Integer) {
        instructions.add(new CfConstNumber((Integer) cst, ValueType.INT));
      } else if (cst instanceof Float) {
        long i = Float.floatToRawIntBits((Float) cst);
        instructions.add(new CfConstNumber(i, ValueType.FLOAT));
      } else if (cst instanceof Handle) {
        instructions.add(
            new CfConstMethodHandle(
                DexMethodHandle.fromAsmHandle((Handle) cst, application, method.holder)));
      } else {
        throw new CompilationError("Unsupported constant: " + cst.toString());
      }
    }

    @Override
    public void visitIincInsn(int var, int increment) {
      instructions.add(new CfIinc(var, increment));
    }

    @Override
    public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
      assert max == min + labels.length - 1;
      ArrayList<CfLabel> targets = new ArrayList<>(labels.length);
      for (Label label : labels) {
        targets.add(getLabel(label));
      }
      instructions.add(new CfSwitch(CfSwitch.Kind.TABLE, getLabel(dflt), new int[] {min}, targets));
    }

    @Override
    public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
      ArrayList<CfLabel> targets = new ArrayList<>(labels.length);
      for (Label label : labels) {
        targets.add(getLabel(label));
      }
      instructions.add(new CfSwitch(CfSwitch.Kind.LOOKUP, getLabel(dflt), keys, targets));
    }

    @Override
    public void visitMultiANewArrayInsn(String desc, int dims) {
      if (!application.options.isGeneratingDex()) {
        instructions.add(new CfMultiANewArray(factory.createType(desc), dims));
        return;
      }
      // When generating DEX code a multianewarray is desugared to a reflective creation.
      // The stack transformation is:
      //   ..., count1, ..., countN (where N = dims)
      //   ->
      //   ..., arrayref(of type : desc)
      //
      // This is unfolded to a call to java.lang.reflect.Array.newInstance to the same effect:
      // ..., count1, ..., countN
      visitLdcInsn(dims);
      // ..., count1, ..., countN, dims
      visitIntInsn(Opcodes.NEWARRAY, Opcodes.T_INT);
      // ..., count1, ..., countN, dim-array
      for (int i = dims - 1; i >= 0; i--) {
        visitInsn(Opcodes.DUP_X1);
        // ..., count1, ..., dim-array, countN, dim-array
        visitInsn(Opcodes.SWAP);
        // ..., count1, ..., dim-array, dim-array, countN
        visitLdcInsn(i);
        // ..., count1, ..., dim-array, dim-array, countN, index
        visitInsn(Opcodes.SWAP);
        // ..., count1, ..., dim-array, dim-array, index, countN
        visitInsn(Opcodes.IASTORE);
        // ..., count1, ..., dim-array
      }
      visitLdcInsn(Type.getType(desc.substring(dims)));
      // ..., dim-array, dim-member-type
      visitInsn(Opcodes.SWAP);
      // ..., dim-member-type, dim-array
      visitMethodInsn(
          Opcodes.INVOKESTATIC,
          "java/lang/reflect/Array",
          "newInstance",
          "(Ljava/lang/Class;[I)Ljava/lang/Object;",
          false);
      // ..., ref
      visitTypeInsn(Opcodes.CHECKCAST, desc);
      // ..., arrayref(of type : desc)
    }

    @Override
    public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
      List<DexType> guards =
          Collections.singletonList(
              type == null ? factory.throwableType : createTypeFromInternalType(type));
      List<CfLabel> targets = Collections.singletonList(getLabel(handler));
      tryCatchRanges.add(new CfTryCatch(getLabel(start), getLabel(end), guards, targets));
    }

    @Override
    public void visitLocalVariable(
        String name, String desc, String signature, Label start, Label end, int index) {
      DebugLocalInfo debugLocalInfo =
          canonicalize(
              new DebugLocalInfo(
                  factory.createString(name),
                  factory.createType(desc),
                  signature == null ? null : factory.createString(signature)));
      localVariables.add(
          new LocalVariableInfo(index, debugLocalInfo, getLabel(start), getLabel(end)));
    }

    private DebugLocalInfo canonicalize(DebugLocalInfo debugLocalInfo) {
      return canonicalDebugLocalInfo.computeIfAbsent(debugLocalInfo, o -> debugLocalInfo);
    }

    @Override
    public void visitLineNumber(int line, Label start) {
      instructions.add(new CfPosition(getLabel(start), new Position(line, null, method, null)));
    }

    @Override
    public void visitMaxs(int maxStack, int maxLocals) {
      assert maxStack >= 0;
      assert maxLocals >= 0;
      this.maxStack = maxStack;
      this.maxLocals = maxLocals;
    }
  }

  private static int getParsingOptions(
      JarApplicationReader application, boolean reachabilitySensitive) {
    int parsingOptions =
        application.options.testing.readInputStackMaps
            ? ClassReader.EXPAND_FRAMES
            : ClassReader.SKIP_FRAMES;

    ProguardConfiguration configuration = application.options.getProguardConfiguration();
    if (configuration != null && !configuration.isKeepParameterNames()) {
      ProguardKeepAttributes keep =
          application.options.getProguardConfiguration().getKeepAttributes();
      if (!application.options.getProguardConfiguration().isKeepParameterNames()
          && !keep.localVariableTable
          && !keep.localVariableTypeTable
          && !keep.lineNumberTable
          && !reachabilitySensitive) {
        parsingOptions |= ClassReader.SKIP_DEBUG;
      }
    }
    return parsingOptions;
  }

  private static boolean verifyNoReparseContext(DexClass owner) {
    for (DexEncodedMethod method : owner.virtualMethods()) {
      Code code = method.getCode();
      assert code == null || !(code instanceof LazyCfCode) || ((LazyCfCode) code).context == null;
    }
    for (DexEncodedMethod method : owner.directMethods()) {
      Code code = method.getCode();
      assert code == null || !(code instanceof LazyCfCode) || ((LazyCfCode) code).context == null;
    }
    return true;
  }

  @Override
  public Int2ReferenceMap<DebugLocalInfo> collectParameterInfo(
      DexEncodedMethod encodedMethod, AppView<?> appView) {
    return asCfCode().collectParameterInfo(encodedMethod, appView);
  }
}
