// 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.conversion;

import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexCallSite;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexMethodHandle;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.JarApplicationReader;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.code.CatchHandlers;
import com.android.tools.r8.ir.code.Cmp.Bias;
import com.android.tools.r8.ir.code.If;
import com.android.tools.r8.ir.code.Invoke;
import com.android.tools.r8.ir.code.MemberType;
import com.android.tools.r8.ir.code.Monitor;
import com.android.tools.r8.ir.code.NumericType;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.ir.code.ValueTypeConstraint;
import com.android.tools.r8.ir.conversion.IRBuilder.BlockInfo;
import com.android.tools.r8.ir.conversion.JarState.Local;
import com.android.tools.r8.ir.conversion.JarState.LocalChangeAtOffset;
import com.android.tools.r8.ir.conversion.JarState.Slot;
import com.android.tools.r8.logging.Log;
import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceSortedMap;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import java.util.function.BiConsumer;
import org.objectweb.asm.Handle;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.IincInsnNode;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.IntInsnNode;
import org.objectweb.asm.tree.InvokeDynamicInsnNode;
import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.LineNumberNode;
import org.objectweb.asm.tree.LocalVariableNode;
import org.objectweb.asm.tree.LookupSwitchInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.MultiANewArrayInsnNode;
import org.objectweb.asm.tree.TableSwitchInsnNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode;
import org.objectweb.asm.util.Textifier;
import org.objectweb.asm.util.TraceMethodVisitor;

public class JarSourceCode implements SourceCode {

  // Try-catch block wrapper containing resolved offsets.
  private static class TryCatchBlock {

    private final int handler;
    private final int start;
    private final int end;

    private final String type;

    public TryCatchBlock(TryCatchBlockNode node, JarSourceCode code) {
      this(code.getOffset(node.handler),
          code.getOffset(node.start),
          code.getOffset(node.end),
          node.type);
    }

    private TryCatchBlock(int handler, int start, int end, String type) {
      assert start < end;
      this.handler = handler;
      this.start = start;
      this.end = end;
      this.type = type;
    }

    int getStart() {
      return start;
    }

    int getEnd() {
      return end;
    }

    int getHandler() {
      return handler;
    }

    String getType() {
      return type;
    }
  }

  private static class JarStateWorklistItem {
    BlockInfo blockInfo;
    int instructionIndex;

    public JarStateWorklistItem(BlockInfo blockInfo, int instructionIndex) {
      this.blockInfo = blockInfo;
      this.instructionIndex = instructionIndex;
    }
  }

  // Various descriptors.
  private static final String INT_ARRAY_DESC = "[I";
  private static final String REFLECT_ARRAY_DESC = "Ljava/lang/reflect/Array;";
  private static final String REFLECT_ARRAY_NEW_INSTANCE_NAME = "newInstance";
  private static final String REFLECT_ARRAY_NEW_INSTANCE_DESC =
      "(Ljava/lang/Class;[I)Ljava/lang/Object;";
  private static final String POLYMORPHIC_DEFAULT_SIGNATURE_DESC =
      "([Ljava/lang/Object;)Ljava/lang/Object;";
  private static final String POLYMORPHIC_VARHANDLE_SET_SIGNATURE_DESC =
      "([Ljava/lang/Object;)V";
  private static final String POLYMORPHIC_VARHANDLE_COMPARE_AND_SET_SIGNATURE_DESC =
      "([Ljava/lang/Object;)Z";

  // Various internal names.
  public static final String INTERNAL_NAME_METHOD_HANDLE = "java/lang/invoke/MethodHandle";
  public static final String INTERNAL_NAME_VAR_HANDLE = "java/lang/invoke/VarHandle";

  // Language types.
  static final Type CLASS_TYPE = Type.getObjectType("java/lang/Class");
  static final Type STRING_TYPE = Type.getObjectType("java/lang/String");
  static final Type INT_ARRAY_TYPE = Type.getObjectType(INT_ARRAY_DESC);
  static final Type THROWABLE_TYPE = Type.getObjectType("java/lang/Throwable");
  static final Type METHOD_HANDLE_TYPE = Type.getObjectType(INTERNAL_NAME_METHOD_HANDLE);
  static final Type METHOD_TYPE_TYPE = Type.getObjectType("java/lang/invoke/MethodType");

  private static final int[] NO_TARGETS = {};

  private final JarApplicationReader application;
  private final MethodNode node;
  private final DexType clazz;
  private final List<Type> parameterTypes;
  private final LabelNode initialLabel;

  private TraceMethodVisitor printVisitor = null;

  private final JarState state;
  private AbstractInsnNode currentInstruction = null;

  // Special try-catch block for synchronized methods.
  // This block is given a negative instruction index as it is not part of the instruction stream.
  // The start range of 0 ensures that a new block will start at the first real instruction and
  // thus that the monitor-entry prelude (part of the argument block which must not have a try-catch
  // successor) is not joined with the first instruction block (which likely will have a try-catch
  // successor).
  private static final int EXCEPTIONAL_SYNC_EXIT_OFFSET = -2;
  private static final TryCatchBlock EXCEPTIONAL_SYNC_EXIT =
      new TryCatchBlock(EXCEPTIONAL_SYNC_EXIT_OFFSET, 0, Integer.MAX_VALUE, null);

  // Instruction that enters the monitor. Null if the method is not synchronized.
  private Monitor monitorEnter = null;

  // State to signal that the code currently being emitted is part of synchronization prelude/exits.
  private boolean generatingMethodSynchronization = false;

  // Current position associated with the current instruction during building.
  private Position currentPosition;

  // Canonicalized positions to lower memory usage.
  private final Int2ReferenceMap<Position> canonicalPositions = new Int2ReferenceOpenHashMap<>();

  // Synthetic position with line = 0.
  private Position preamblePosition = null;

  // Cooked position to indicate positions in synthesized code (ie, for synchronization).
  private Position syntheticPosition = null;

  private final DexMethod originalMethod;
  private final Position callerPosition;

  private boolean hasExitingInstruction = false;

  private boolean debug;

  public JarSourceCode(
      DexType clazz,
      MethodNode node,
      JarApplicationReader application,
      DexMethod originalMethod,
      Position callerPosition) {
    assert node != null;
    assert node.desc != null;
    this.node = node;
    this.application = application;
    this.originalMethod = originalMethod;
    this.clazz = clazz;
    this.callerPosition = callerPosition;
    parameterTypes = Arrays.asList(application.getArgumentTypes(node.desc));
    state = new JarState(node.maxLocals, node.localVariables, this, application);
    AbstractInsnNode first = node.instructions.getFirst();
    initialLabel = first instanceof LabelNode ? (LabelNode) first : null;
  }

  private boolean isStatic() {
    return (node.access & Opcodes.ACC_STATIC) > 0;
  }

  /**
   * Determine if we should emit monitor enter/exit instructions at method entry/exit.
   *
   * @return true if we are generating Dex and method is marked synchronized, otherwise false.
   */
  private boolean generateMethodSynchronization() {
    // When generating class files, don't treat the method specially because it is synchronized.
    // At runtime, the JVM will automatically perform the correct monitor enter/exit instructions.
    return !application.options.isGeneratingClassFiles()
        && (node.access & Opcodes.ACC_SYNCHRONIZED) > 0;
  }

  private int formalParameterCount() {
    return parameterTypes.size();
  }

  private int actualArgumentCount() {
    return isStatic() ? formalParameterCount() : formalParameterCount() + 1;
  }

  @Override
  public int instructionCount() {
    return node.instructions.size();
  }

  @Override
  public int instructionIndex(int instructionOffset) {
    return instructionOffset;
  }

  @Override
  public int instructionOffset(int instructionIndex) {
    return instructionIndex;
  }

  @Override
  public boolean verifyRegister(int register) {
    // The register set is dynamically managed by the state so we assume all values valid here.
    return true;
  }

  @Override
  public void setUp() {
    if (Log.ENABLED) {
      Log.debug(JarSourceCode.class, "Computing blocks for:\n" + toString());
    }
  }

  @Override
  public void clear() {

  }

  @Override
  public void buildPrelude(IRBuilder builder) {
    debug = builder.isDebugMode();
    currentPosition = getPreamblePosition();

    state.beginTransactionSynthetic();

    // Record types for arguments.
    Int2ReferenceMap<Type> argumentLocals = recordArgumentTypes(builder);
    IntSet initializedLocals = new IntOpenHashSet(node.localVariables.size());
    initializedLocals.addAll(argumentLocals.keySet());
    // Initialize all non-argument locals to ensure safe insertion of debug-local instructions.
    for (Object o : node.localVariables) {
      LocalVariableNode local = (LocalVariableNode) o;
      Type localType;
      switch (application.getAsmType(local.desc).getSort()) {
        case Type.OBJECT:
        case Type.ARRAY: {
          localType = JarState.NULL_TYPE;
          break;
        }
        case Type.LONG: {
          localType = Type.LONG_TYPE;
          break;
        }
        case Type.DOUBLE: {
          localType = Type.DOUBLE_TYPE;
          break;
        }
        case Type.BOOLEAN:
        case Type.CHAR:
        case Type.BYTE:
        case Type.SHORT:
        case Type.INT: {
          localType = Type.INT_TYPE;
          break;
        }
        case Type.FLOAT: {
          localType = Type.FLOAT_TYPE;
          break;
        }
        case Type.VOID:
        case Type.METHOD:
        default:
          throw new Unreachable("Invalid local variable type: " );
      }
      int localRegister = state.getLocalRegister(local.index, localType);
      if (!initializedLocals.contains(localRegister)) {
        int writeRegister = state.writeLocal(local.index, localType);
        assert writeRegister == localRegister;
        initializedLocals.add(localRegister);
      }
    }

    state.endTransaction();
    state.beginTransaction(0, true);

    // Build the actual argument instructions now that type and debug information is known
    // for arguments.
    buildArgumentInstructions(builder);

    // Add debug information for all locals at the initial label.
    for (Local local : state.getLocalsToOpen()) {
      if (!argumentLocals.containsKey(local.slot.register)) {
        builder.addDebugLocalStart(local.slot.register, local.info);
      }
    }
    state.endTransaction();

    if (generateMethodSynchronization()) {
      generatingMethodSynchronization = true;
      Type clazzType = application.getAsmType(clazz.toDescriptorString());
      int monitorRegister;
      if (isStatic()) {
        // Load the class using a temporary on the stack.
        monitorRegister = state.push(clazzType);
        state.pop();
        builder.addConstClass(monitorRegister, clazz);
      } else {
        assert actualArgumentCount() > 0;
        // The object is stored in the first local.
        monitorRegister = state.readLocal(0, clazzType).register;
      }
      // Build the monitor enter and save it for when generating exits later.
      monitorEnter = builder.addMonitor(Monitor.Type.ENTER, monitorRegister);
      generatingMethodSynchronization = false;
    }
    computeBlockEntryJarStates(builder);
    state.setBuilding();
  }

  private void buildArgumentInstructions(IRBuilder builder) {
    int argumentRegister = 0;
    if (!isStatic()) {
      Type thisType = application.getAsmType(clazz.descriptor.toString());
      Slot slot = state.readLocal(argumentRegister++, thisType);
      builder.addThisArgument(slot.register);
    }
    for (Type type : parameterTypes) {
      TypeLatticeElement typeLattice = builder.getTypeLattice(application.getType(type), true);
      Slot slot = state.readLocal(argumentRegister, type);
      if (type == Type.BOOLEAN_TYPE) {
        builder.addBooleanNonThisArgument(slot.register);
      } else {
        builder.addNonThisArgument(slot.register, typeLattice);
      }
      argumentRegister += typeLattice.requiredRegisters();
    }
    builder.flushArgumentInstructions();
  }

  private Int2ReferenceMap<Type> recordArgumentTypes(IRBuilder builder) {
    Int2ReferenceMap<Type> initializedLocals =
        new Int2ReferenceOpenHashMap<>(node.localVariables.size());
    int argumentRegister = 0;
    if (!isStatic()) {
      Type thisType = application.getAsmType(clazz.descriptor.toString());
      int register = state.writeLocal(argumentRegister++, thisType);
      initializedLocals.put(register, thisType);
    }
    for (Type type : parameterTypes) {
      int register = state.writeLocal(argumentRegister, type);
      argumentRegister += isWide(type) ? 2 : 1;
      initializedLocals.put(register, type);
    }
    return initializedLocals;
  }

  private boolean isWide(Type type) {
    return type.getSort() == Type.DOUBLE || type.getSort() == Type.LONG;
  }

  private void computeBlockEntryJarStates(IRBuilder builder) {
    hasExitingInstruction = false;
    Int2ReferenceSortedMap<BlockInfo> CFG = builder.getCFG();
    Queue<JarStateWorklistItem> worklist = new LinkedList<>();
    BlockInfo entry = CFG.get(IRBuilder.INITIAL_BLOCK_OFFSET);
    if (CFG.get(0) != null) {
      entry = CFG.get(0);
    }
    worklist.add(new JarStateWorklistItem(entry, 0));
    state.recordStateForTarget(0);
    for (JarStateWorklistItem item = worklist.poll(); item != null; item = worklist.poll()) {
      state.restoreState(item.instructionIndex);
      state.beginTransactionAtBlockStart(item.instructionIndex);
      state.endTransaction();
      // Iterate each of the instructions in the block to compute the outgoing JarState.
      int instCount = instructionCount();
      int blockEnd = item.instructionIndex + 1;
      while (blockEnd < instCount && !CFG.containsKey(blockEnd)) {
        blockEnd += 1;
      }
      for (int i = item.instructionIndex; i < blockEnd; ++i) {
        boolean hasNextInstruction = i + 1 != blockEnd;
        state.beginTransaction(i + 1, hasNextInstruction);
        AbstractInsnNode insn = getInstruction(i);
        updateState(insn);
        state.endTransaction();
        if (!hasNextInstruction) {
          hasExitingInstruction |=
              isReturn(insn) || (isThrow(insn) && item.blockInfo.exceptionalSuccessors.isEmpty());
        }
      }
      // At the end of the current block, propagate the state to all successors and add the ones
      // that changed to the worklist.
      item.blockInfo.normalSuccessors.iterator().forEachRemaining((Integer offset) -> {
        if (state.recordStateForTarget(offset)) {
          if (offset >= 0) {
            worklist.add(new JarStateWorklistItem(CFG.get(offset.intValue()), offset));
          }
        }
      });
      item.blockInfo.exceptionalSuccessors.iterator().forEachRemaining((Integer offset) -> {
        if (state.recordStateForExceptionalTarget(offset)) {
          if (offset >= 0) {
            worklist.add(new JarStateWorklistItem(CFG.get(offset.intValue()), offset));
          }
        }
      });
    }
    state.restoreState(0);
  }

  @Override
  public void buildPostlude(IRBuilder builder) {
    if (generateMethodSynchronization()) {
      generatingMethodSynchronization = true;
      buildMonitorExit(builder);
      generatingMethodSynchronization = false;
    }
  }

  private void buildExceptionalPostlude(IRBuilder builder) {
    assert generateMethodSynchronization();
    generatingMethodSynchronization = true;
    currentPosition = getExceptionalExitPosition();
    buildMonitorExit(builder);
    builder.addThrow(getMoveExceptionRegister());
    generatingMethodSynchronization = false;
  }

  private void buildMonitorExit(IRBuilder builder) {
    assert generatingMethodSynchronization;
    builder.add(new Monitor(Monitor.Type.EXIT, monitorEnter.inValues().get(0)));
  }

  @Override
  public void buildBlockTransfer(
      IRBuilder builder, int predecessorOffset, int successorOffset, boolean isExceptional) {
    assert currentInstruction == null || predecessorOffset == getOffset(currentInstruction);
    currentInstruction = null;
    if (predecessorOffset == IRBuilder.INITIAL_BLOCK_OFFSET
        || successorOffset == EXCEPTIONAL_SYNC_EXIT_OFFSET) {
      return;
    }
    // The transfer has not yet taken place, so the current position is that of the predecessor,
    // except for exceptional edges where the transfer has already taken place.
    currentPosition =
        getCanonicalDebugPositionAtOffset(isExceptional ? successorOffset : predecessorOffset);

    LocalChangeAtOffset localChange = state.getLocalChange(predecessorOffset, successorOffset);
    if (!isExceptional) {
      for (Local toClose : localChange.getLocalsToClose()) {
        builder.addDebugLocalEnd(toClose.slot.register, toClose.info);
      }
    }
    for (Local toOpen : localChange.getLocalsToOpen()) {
      builder.addDebugLocalStart(toOpen.slot.register, toOpen.info);
    }

    // If there are no explicit exits from the method (ie, this method is a loop without an explict
    // return or an unhandled throw) then we cannot guarantee that a local live in a successor will
    // ensure it is marked as such (via an explict 'end' marker) and thus be live in predecessors.
    // In this case we insert an 'end' point on all explicit goto instructions ensuring that any
    // back-edge will explicitly keep locals live at that point.
    if (!hasExitingInstruction && getInstruction(predecessorOffset).getOpcode() == Opcodes.GOTO) {
      assert !isExceptional;
      for (Local local : localChange.getLocalsToPreserve()) {
        builder.addDebugLocalEnd(local.slot.register, local.info);
      }
    }
  }

  @Override
  public void buildInstruction(
      IRBuilder builder, int instructionIndex, boolean firstBlockInstruction) {
    if (instructionIndex == EXCEPTIONAL_SYNC_EXIT_OFFSET) {
      buildExceptionalPostlude(builder);
      return;
    }
    AbstractInsnNode insn = getInstruction(instructionIndex);
    currentInstruction = insn;
    assert verifyExceptionEdgesAreRecorded(insn);

    // If a new block is starting here, we restore the computed JarState.
    // current position needs to be compute only for the first instruction of a block, thereafter
    // current position will be updated by LineNumberNode into this block.
    if (firstBlockInstruction || instructionIndex == 0) {
      state.restoreState(instructionIndex);
      currentPosition = getCanonicalDebugPositionAtOffset(instructionIndex);
    }

    String preInstructionState = "";
    if (Log.ENABLED) {
      preInstructionState = state.toString();
    }

    boolean hasNextInstruction =
        instructionIndex + 1 != instructionCount()
            && !builder.getCFG().containsKey(instructionIndex + 1);
    state.beginTransaction(instructionIndex + 1, hasNextInstruction);
    if (hasNextInstruction) {
      // Explicitly end all locals ending at this point.
      for (Local local : state.getLocalsToClose()) {
        builder.addDebugLocalEnd(local.slot.register, local.info);
      }
    }
    build(insn, builder);
    // If the block continues past this instruction then local state should be updated.
    if (hasNextInstruction) {
      // Ensure starts of locals starting at this point.
      for (Local local : state.getLocalsToOpen()) {
        builder.addDebugLocalStart(local.slot.register, local.info);
      }
    }
    state.endTransaction();

    if (Log.ENABLED && !(insn instanceof LineNumberNode)) {
      int offset = getOffset(insn);
      if (insn instanceof LabelNode) {
        Log.debug(getClass(), "\n%4d: %s",
            offset, instructionToString(insn).replace('\n', ' '));
      } else {
        Log.debug(getClass(), "\n%4d: %s          pre:  %s\n          post: %s",
            offset, instructionToString(insn), preInstructionState, state);
      }
    }

    currentInstruction = null;
  }

  private boolean verifyExceptionEdgesAreRecorded(AbstractInsnNode insn) {
    if (canThrow(insn)) {
      for (TryCatchBlock tryCatchBlock : getTryHandlers(insn)) {
        assert tryCatchBlock.getHandler() == EXCEPTIONAL_SYNC_EXIT_OFFSET
            || state.hasState(tryCatchBlock.getHandler());
      }
    }
    return true;
  }

  @Override
  public void resolveAndBuildSwitch(int value, int fallthroughOffset,
      int payloadOffset, IRBuilder builder) {
    throw new Unreachable();
  }

  @Override
  public void resolveAndBuildNewArrayFilledData(int arrayRef, int payloadOffset,
      IRBuilder builder) {
    throw new Unreachable();
  }

  @Override
  public DebugLocalInfo getIncomingLocalAtBlock(int register, int blockOffset) {
    return blockOffset == EXCEPTIONAL_SYNC_EXIT_OFFSET
        ? null
        : state.getIncomingLocalAtBlock(register, blockOffset);
  }

  @Override
  public DebugLocalInfo getIncomingLocal(int register) {
    return generatingMethodSynchronization ? null : state.getIncomingLocalInfoForRegister(register);
  }

  @Override
  public DebugLocalInfo getOutgoingLocal(int register) {
    return generatingMethodSynchronization ? null : state.getOutgoingLocalInfoForRegister(register);
  }

  @Override
  public CatchHandlers<Integer> getCurrentCatchHandlers() {
    if (generatingMethodSynchronization) {
      return null;
    }
    List<TryCatchBlock> tryCatchBlocks = getTryHandlers(currentInstruction);
    if (tryCatchBlocks.isEmpty()) {
      return null;
    }
    // TODO(zerny): Compute this more efficiently.
    return new CatchHandlers<>(
        getTryHandlerGuards(tryCatchBlocks),
        getTryHandlerOffsets(tryCatchBlocks));
  }

  @Override
  public int getMoveExceptionRegister(int instructionIndex) {
    return getMoveExceptionRegister();
  }

  // In classfiles the register is always on top of stack.
  private int getMoveExceptionRegister() {
    return state.startOfStack;
  }

  @Override
  public boolean verifyCurrentInstructionCanThrow() {
    return generatingMethodSynchronization || canThrow(currentInstruction);
  }

  @Override
  public boolean verifyLocalInScope(DebugLocalInfo local) {
    for (Local open : state.getLocals()) {
      if (open.info != null && open.info.name == local.name) {
        return true;
      }
    }
    return false;
  }

  private AbstractInsnNode getInstruction(int index) {
    return node.instructions.get(index);
  }

  private static boolean isReturn(AbstractInsnNode insn) {
    return Opcodes.IRETURN <= insn.getOpcode() && insn.getOpcode() <= Opcodes.RETURN;
  }

  private static boolean isSwitch(AbstractInsnNode insn) {
    return Opcodes.TABLESWITCH == insn.getOpcode() || insn.getOpcode() == Opcodes.LOOKUPSWITCH;
  }

  private static boolean isThrow(AbstractInsnNode insn) {
    return Opcodes.ATHROW == insn.getOpcode();
  }

  private static boolean isControlFlowInstruction(AbstractInsnNode insn) {
    return isReturn(insn) || isThrow(insn) || isSwitch(insn) || (insn instanceof JumpInsnNode)
        || insn.getOpcode() == Opcodes.RET;
  }

  private boolean canThrow(AbstractInsnNode insn) {
    switch (insn.getOpcode()) {
      case Opcodes.AALOAD:
      case Opcodes.AASTORE:
      case Opcodes.ANEWARRAY:
        // ARETURN does not throw in its dex image.
      case Opcodes.ARRAYLENGTH:
      case Opcodes.ATHROW:
      case Opcodes.BALOAD:
      case Opcodes.BASTORE:
      case Opcodes.CALOAD:
      case Opcodes.CASTORE:
      case Opcodes.CHECKCAST:
      case Opcodes.DALOAD:
      case Opcodes.DASTORE:
        // DRETURN does not throw in its dex image.
      case Opcodes.FALOAD:
      case Opcodes.FASTORE:
        // FRETURN does not throw in its dex image.
      case Opcodes.GETFIELD:
      case Opcodes.GETSTATIC:
      case Opcodes.IALOAD:
      case Opcodes.IASTORE:
      case Opcodes.IDIV:
      case Opcodes.INSTANCEOF:
      case Opcodes.INVOKEDYNAMIC:
      case Opcodes.INVOKEINTERFACE:
      case Opcodes.INVOKESPECIAL:
      case Opcodes.INVOKESTATIC:
      case Opcodes.INVOKEVIRTUAL:
      case Opcodes.IREM:
        // IRETURN does not throw in its dex image.
      case Opcodes.LALOAD:
      case Opcodes.LASTORE:
      case Opcodes.LDIV:
      case Opcodes.LREM:
        // LRETURN does not throw in its dex image.
      case Opcodes.MONITORENTER:
      case Opcodes.MONITOREXIT:
      case Opcodes.MULTIANEWARRAY:
      case Opcodes.NEW:
      case Opcodes.NEWARRAY:
      case Opcodes.PUTFIELD:
      case Opcodes.PUTSTATIC:
        // RETURN does not throw in its dex image.
      case Opcodes.SALOAD:
      case Opcodes.SASTORE:
        return true;
      case Opcodes.LDC: {
        // const-class and const-string* may throw in dex.
        LdcInsnNode ldc = (LdcInsnNode) insn;
          return (ldc.cst instanceof String && !application.options.isGeneratingClassFiles())
              || ldc.cst instanceof Type
              || ldc.cst instanceof Handle;
      }
      default:
        return false;
    }
  }

  @Override
  public int traceInstruction(int index, IRBuilder builder) {
    AbstractInsnNode insn = getInstruction(index);
    // Exit early on no-op instructions.
    if (insn instanceof LabelNode || insn instanceof LineNumberNode) {
      return -1;
    }
    // If this instruction exits, close this block.
    if (isReturn(insn)) {
      return index;
    }
    // For each target ensure a basic block and close this block.
    int[] targets = getTargets(insn);
    if (targets != NO_TARGETS) {
      assert !canThrow(insn);
      for (int target : targets) {
        builder.ensureNormalSuccessorBlock(index, target);
      }
      return index;
    }
    if (canThrow(insn)) {
      List<TryCatchBlock> tryCatchBlocks = getTryHandlers(insn);
      if (!tryCatchBlocks.isEmpty()) {
        Set<Integer> seenHandlerOffsets = new HashSet<>();
        for (TryCatchBlock tryCatchBlock : tryCatchBlocks) {
          // Ensure the block starts at the start of the try-range (don't enqueue, not a target).
          builder.ensureBlockWithoutEnqueuing(tryCatchBlock.getStart());
          // Add edge to exceptional successor (only one edge for each unique successor).
          int handler = tryCatchBlock.getHandler();
          if (!seenHandlerOffsets.contains(handler)) {
            seenHandlerOffsets.add(handler);
            builder.ensureExceptionalSuccessorBlock(index, handler);
          }
        }
        // Edge to normal successor if any (fallthrough).
        if (!isThrow(insn)) {
          builder.ensureNormalSuccessorBlock(index, getOffset(insn.getNext()));
        }
        return index;
      }
      // If the throwable instruction is "throw" it closes the block.
      return isThrow(insn) ? index : -1;
    }
    // This instruction does not close the block.
    return -1;
  }

  private List<TryCatchBlock> getPotentialTryHandlers(AbstractInsnNode insn) {
    int offset = getOffset(insn);
    return getPotentialTryHandlers(offset);
  }

  private boolean tryBlockRelevant(TryCatchBlockNode tryHandler, int offset) {
    int start = getOffset(tryHandler.start);
    int end = getOffset(tryHandler.end);
    return start <= offset && offset < end;
  }

  private List<TryCatchBlock> getPotentialTryHandlers(int offset) {
    List<TryCatchBlock> handlers = new ArrayList<>();
    for (int i = 0; i < node.tryCatchBlocks.size(); i++) {
      TryCatchBlockNode tryBlock = (TryCatchBlockNode) node.tryCatchBlocks.get(i);
      if (tryBlockRelevant(tryBlock, offset)) {
        handlers.add(new TryCatchBlock(tryBlock, this));
      }
    }
    return handlers;
  }

  private List<TryCatchBlock> getTryHandlers(AbstractInsnNode insn) {
    List<TryCatchBlock> handlers = new ArrayList<>();
    Set<String> seen = new HashSet<>();
    // The try-catch blocks are ordered by precedence.
    for (TryCatchBlock tryCatchBlock : getPotentialTryHandlers(insn)) {
      if (tryCatchBlock.getType() == null) {
        handlers.add(tryCatchBlock);
        return handlers;
      }
      if (!seen.contains(tryCatchBlock.getType())) {
        seen.add(tryCatchBlock.getType());
        handlers.add(tryCatchBlock);
      }
    }
    if (generateMethodSynchronization()) {
      // Add synchronized exceptional exit for synchronized-method instructions without a default.
      assert handlers.isEmpty() || handlers.get(handlers.size() - 1).getType() != null;
      handlers.add(EXCEPTIONAL_SYNC_EXIT);
    }
    return handlers;
  }

  private List<Integer> getTryHandlerOffsets(List<TryCatchBlock> tryCatchBlocks) {
    List<Integer> offsets = new ArrayList<>();
    for (TryCatchBlock tryCatchBlock : tryCatchBlocks) {
      offsets.add(tryCatchBlock.getHandler());
    }
    return offsets;
  }

  private List<DexType> getTryHandlerGuards(List<TryCatchBlock> tryCatchBlocks) {
    List<DexType> guards = new ArrayList<>();
    for (TryCatchBlock tryCatchBlock : tryCatchBlocks) {
      guards.add(tryCatchBlock.getType() == null
          ? DexItemFactory.catchAllType
          : application.getTypeFromName(tryCatchBlock.getType()));

    }
    return guards;
  }

  int getOffset(AbstractInsnNode insn) {
    return node.instructions.indexOf(insn);
  }

  private int[] getTargets(AbstractInsnNode insn) {
    switch (insn.getType()) {
      case AbstractInsnNode.TABLESWITCH_INSN: {
        TableSwitchInsnNode switchInsn = (TableSwitchInsnNode) insn;
        return getSwitchTargets(switchInsn.dflt, switchInsn.labels);
      }
      case AbstractInsnNode.LOOKUPSWITCH_INSN: {
        LookupSwitchInsnNode switchInsn = (LookupSwitchInsnNode) insn;
        return getSwitchTargets(switchInsn.dflt, switchInsn.labels);
      }
      case AbstractInsnNode.JUMP_INSN: {
        return getJumpTargets((JumpInsnNode) insn);
      }
      case AbstractInsnNode.VAR_INSN: {
        return getVarTargets((VarInsnNode) insn);
      }
      default:
        return NO_TARGETS;
    }
  }

  private int[] getSwitchTargets(LabelNode dflt, List labels) {
    int[] targets = new int[1 + labels.size()];
    targets[0] = getOffset(dflt);
    for (int i = 1; i < targets.length; i++) {
      targets[i] = getOffset((LabelNode) labels.get(i - 1));
    }
    return targets;
  }

  private int[] getJumpTargets(JumpInsnNode jump) {
    switch (jump.getOpcode()) {
      case Opcodes.IFEQ:
      case Opcodes.IFNE:
      case Opcodes.IFLT:
      case Opcodes.IFGE:
      case Opcodes.IFGT:
      case Opcodes.IFLE:
      case Opcodes.IF_ICMPEQ:
      case Opcodes.IF_ICMPNE:
      case Opcodes.IF_ICMPLT:
      case Opcodes.IF_ICMPGE:
      case Opcodes.IF_ICMPGT:
      case Opcodes.IF_ICMPLE:
      case Opcodes.IF_ACMPEQ:
      case Opcodes.IF_ACMPNE:
      case Opcodes.IFNULL:
      case Opcodes.IFNONNULL:
        return new int[]{getOffset(jump.label), getOffset(jump.getNext())};
      case Opcodes.GOTO:
        return new int[]{getOffset(jump.label)};
      case Opcodes.JSR: {
        throw new Unreachable("JSR should be handled by the ASM jsr inliner");
      }
      default:
        throw new Unreachable("Unexpected opcode in jump instruction: " + jump);
    }
  }

  private int[] getVarTargets(VarInsnNode insn) {
    if (insn.getOpcode() == Opcodes.RET) {
      throw new Unreachable("RET should be handled by the ASM jsr inliner");
    }
    return NO_TARGETS;
  }

  // Type conversion helpers.

  private static ValueType valueType(Type type) {
    switch (type.getSort()) {
      case Type.ARRAY:
      case Type.OBJECT:
        return ValueType.OBJECT;
      case Type.BOOLEAN:
      case Type.BYTE:
      case Type.SHORT:
      case Type.CHAR:
      case Type.INT:
        return ValueType.INT;
      case Type.FLOAT:
        return ValueType.FLOAT;
      case Type.LONG:
        return ValueType.LONG;
      case Type.DOUBLE:
        return ValueType.DOUBLE;
      case Type.VOID:
        // Illegal. Throws in fallthrough.
      default:
        throw new Unreachable("Invalid type in valueType: " + type);
    }
  }

  private static MemberType memberType(Type type) {
    switch (type.getSort()) {
      case Type.ARRAY:
      case Type.OBJECT:
        return MemberType.OBJECT;
      case Type.BOOLEAN:
        return MemberType.BOOLEAN;
      case Type.BYTE:
        return MemberType.BYTE;
      case Type.SHORT:
        return MemberType.SHORT;
      case Type.CHAR:
        return MemberType.CHAR;
      case Type.INT:
        return MemberType.INT;
      case Type.FLOAT:
        return MemberType.FLOAT;
      case Type.LONG:
        return MemberType.LONG;
      case Type.DOUBLE:
        return MemberType.DOUBLE;
      case Type.VOID:
        // Illegal. Throws in fallthrough.
      default:
        throw new Unreachable("Invalid type in memberType: " + type);
    }
  }

  private MemberType memberType(String fieldDesc) {
    return memberType(application.getAsmType(fieldDesc));
  }

  private static NumericType numericType(Type type) {
    switch (type.getSort()) {
      case Type.BYTE:
        return NumericType.BYTE;
      case Type.CHAR:
        return NumericType.CHAR;
      case Type.SHORT:
        return NumericType.SHORT;
      case Type.INT:
        return NumericType.INT;
      case Type.LONG:
        return NumericType.LONG;
      case Type.FLOAT:
        return NumericType.FLOAT;
      case Type.DOUBLE:
        return NumericType.DOUBLE;
      default:
        throw new Unreachable("Invalid type in numericType: " + type);
    }
  }

  private Invoke.Type invokeType(MethodInsnNode method) {
    switch (method.getOpcode()) {
      case Opcodes.INVOKEVIRTUAL:
        if (isCallToPolymorphicSignatureMethod(method.owner, method.name)) {
          return Invoke.Type.POLYMORPHIC;
        }
        return Invoke.Type.VIRTUAL;
      case Opcodes.INVOKESTATIC:
        return Invoke.Type.STATIC;
      case Opcodes.INVOKEINTERFACE:
        return Invoke.Type.INTERFACE;
      case Opcodes.INVOKESPECIAL: {
        // This is actually incorrect unless the input was verified. The spec says that it has
        // invoke super semantics, if the type is a supertype of the current class. If it is the
        // same or a subtype, it has invoke direct semantics. The latter case is illegal, so we
        // map it to a super call here. In R8, we abort at a later stage (see.
        // See also <a href=
        // "https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.invokespecial"
        // </a> for invokespecial dispatch and <a href="https://docs.oracle.com/javase/specs/jvms/"
        // "se7/html/jvms-4.html#jvms-4.10.1.9.invokespecial"</a> for verification requirements. In
        // particular, the requirement
        //   isAssignable(class(CurrentClassName, L), class(MethodClassName, L)).
        DexType owner = application.getTypeFromName(method.owner);
        if (owner == clazz || method.name.equals(Constants.INSTANCE_INITIALIZER_NAME)) {
          return Invoke.Type.DIRECT;
        } else {
          return Invoke.Type.SUPER;
        }
      }
      default:
        throw new Unreachable("Unexpected MethodInsnNode opcode: " + method.getOpcode());
    }
  }

  private Type makeArrayType(Type elementType) {
    return application.getAsmObjectType("[" + elementType.getDescriptor());
  }

  private static String arrayTypeDesc(int arrayTypeCode) {
    switch (arrayTypeCode) {
      case Opcodes.T_BOOLEAN:
        return "[Z";
      case Opcodes.T_CHAR:
        return "[C";
      case Opcodes.T_FLOAT:
        return "[F";
      case Opcodes.T_DOUBLE:
        return "[D";
      case Opcodes.T_BYTE:
        return "[B";
      case Opcodes.T_SHORT:
        return "[S";
      case Opcodes.T_INT:
        return "[I";
      case Opcodes.T_LONG:
        return "[J";
      default:
        throw new Unreachable("Unexpected array-type code " + arrayTypeCode);
    }
  }

  private static Type getArrayElementTypeForOpcode(int opcode) {
    switch (opcode) {
      case Opcodes.IALOAD:
      case Opcodes.IASTORE:
        return Type.INT_TYPE;
      case Opcodes.FALOAD:
      case Opcodes.FASTORE:
        return Type.FLOAT_TYPE;
      case Opcodes.LALOAD:
      case Opcodes.LASTORE:
        return Type.LONG_TYPE;
      case Opcodes.DALOAD:
      case Opcodes.DASTORE:
        return Type.DOUBLE_TYPE;
      case Opcodes.AALOAD:
      case Opcodes.AASTORE:
        return JarState.NULL_TYPE; // We might not know the type.
      case Opcodes.BALOAD:
      case Opcodes.BASTORE:
        return Type.BYTE_TYPE; // We don't distinguish byte and boolean.
      case Opcodes.CALOAD:
      case Opcodes.CASTORE:
        return Type.CHAR_TYPE;
      case Opcodes.SALOAD:
      case Opcodes.SASTORE:
        return Type.SHORT_TYPE;
      default:
        throw new Unreachable("Unexpected array opcode " + opcode);
    }
  }

  private static boolean isCompatibleArrayElementType(int opcode, Type type) {
    switch (opcode) {
      case Opcodes.IALOAD:
      case Opcodes.IASTORE:
        return Slot.isCompatible(type, Type.INT_TYPE);
      case Opcodes.FALOAD:
      case Opcodes.FASTORE:
        return Slot.isCompatible(type, Type.FLOAT_TYPE);
      case Opcodes.LALOAD:
      case Opcodes.LASTORE:
        return Slot.isCompatible(type, Type.LONG_TYPE);
      case Opcodes.DALOAD:
      case Opcodes.DASTORE:
        return Slot.isCompatible(type, Type.DOUBLE_TYPE);
      case Opcodes.AALOAD:
      case Opcodes.AASTORE:
        return Slot.isCompatible(type, JarState.REFERENCE_TYPE);
      case Opcodes.BALOAD:
      case Opcodes.BASTORE:
        return Slot.isCompatible(type, Type.BYTE_TYPE)
            || Slot.isCompatible(type, Type.BOOLEAN_TYPE);
      case Opcodes.CALOAD:
      case Opcodes.CASTORE:
        return Slot.isCompatible(type, Type.CHAR_TYPE);
      case Opcodes.SALOAD:
      case Opcodes.SASTORE:
        return Slot.isCompatible(type, Type.SHORT_TYPE);
      default:
        throw new Unreachable("Unexpected array 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);
    }
  }

  private static Type opType(int opcode) {
    switch (opcode) {
      case Opcodes.IADD:
      case Opcodes.ISUB:
      case Opcodes.IMUL:
      case Opcodes.IDIV:
      case Opcodes.IREM:
      case Opcodes.INEG:
      case Opcodes.ISHL:
      case Opcodes.ISHR:
      case Opcodes.IUSHR:
        return Type.INT_TYPE;
      case Opcodes.LADD:
      case Opcodes.LSUB:
      case Opcodes.LMUL:
      case Opcodes.LDIV:
      case Opcodes.LREM:
      case Opcodes.LNEG:
      case Opcodes.LSHL:
      case Opcodes.LSHR:
      case Opcodes.LUSHR:
        return Type.LONG_TYPE;
      case Opcodes.FADD:
      case Opcodes.FSUB:
      case Opcodes.FMUL:
      case Opcodes.FDIV:
      case Opcodes.FREM:
      case Opcodes.FNEG:
        return Type.FLOAT_TYPE;
      case Opcodes.DADD:
      case Opcodes.DSUB:
      case Opcodes.DMUL:
      case Opcodes.DDIV:
      case Opcodes.DREM:
      case Opcodes.DNEG:
        return Type.DOUBLE_TYPE;
      default:
        throw new Unreachable("Unexpected opcode " + opcode);
    }
  }

  // State updating procedures.

  private void updateState(AbstractInsnNode insn) {
    switch (insn.getType()) {
      case AbstractInsnNode.INSN:
        updateState((InsnNode) insn);
        break;
      case AbstractInsnNode.INT_INSN:
        updateState((IntInsnNode) insn);
        break;
      case AbstractInsnNode.VAR_INSN:
        updateState((VarInsnNode) insn);
        break;
      case AbstractInsnNode.TYPE_INSN:
        updateState((TypeInsnNode) insn);
        break;
      case AbstractInsnNode.FIELD_INSN:
        updateState((FieldInsnNode) insn);
        break;
      case AbstractInsnNode.METHOD_INSN:
        updateState((MethodInsnNode) insn);
        break;
      case AbstractInsnNode.INVOKE_DYNAMIC_INSN:
        updateState((InvokeDynamicInsnNode) insn);
        break;
      case AbstractInsnNode.JUMP_INSN:
        updateState((JumpInsnNode) insn);
        break;
      case AbstractInsnNode.LABEL:
        updateState((LabelNode) insn);
        break;
      case AbstractInsnNode.LDC_INSN:
        updateState((LdcInsnNode) insn);
        break;
      case AbstractInsnNode.IINC_INSN:
        updateState((IincInsnNode) insn);
        break;
      case AbstractInsnNode.TABLESWITCH_INSN:
        updateState((TableSwitchInsnNode) insn);
        break;
      case AbstractInsnNode.LOOKUPSWITCH_INSN:
        updateState((LookupSwitchInsnNode) insn);
        break;
      case AbstractInsnNode.MULTIANEWARRAY_INSN:
        updateState((MultiANewArrayInsnNode) insn);
        break;
      case AbstractInsnNode.LINE:
        updateState((LineNumberNode) insn);
        break;
      default:
        throw new Unreachable("Unexpected instruction " + insn);
    }
  }

  private void updateState(InsnNode insn) {
    int opcode = insn.getOpcode();
    switch (opcode) {
      case Opcodes.NOP:
        // Intentionally left empty.
        break;
      case Opcodes.ACONST_NULL:
        state.push(JarState.NULL_TYPE);
        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:
        state.push(Type.INT_TYPE);
        break;
      case Opcodes.LCONST_0:
      case Opcodes.LCONST_1:
        state.push(Type.LONG_TYPE);
        break;
      case Opcodes.FCONST_0:
      case Opcodes.FCONST_1:
      case Opcodes.FCONST_2:
        state.push(Type.FLOAT_TYPE);
        break;
      case Opcodes.DCONST_0:
      case Opcodes.DCONST_1:
        state.push(Type.DOUBLE_TYPE);
        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: {
        state.pop();
        Type elementType = state.pop(JarState.ARRAY_TYPE).getArrayElementType();
        if (elementType == null) {
          // We propagate the byte-or-bool type, which will then get resolved to an
          // actual type if we have a concrete byte type or bool type on another flow edge.
          elementType = (Opcodes.BALOAD == opcode)
              ? JarState.BYTE_OR_BOOL_TYPE
              : getArrayElementTypeForOpcode(opcode);
        }
        state.push(elementType);
        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: {
        state.pop();
        state.pop();
        state.pop();
        break;
      }
      case Opcodes.POP: {
        Slot value = state.pop();
        value.isCategory1();
        break;
      }
      case Opcodes.POP2: {
        Slot value = state.pop();
        if (value.isCategory1()) {
          Slot value2 = state.pop();
          assert value2.isCategory1();
        }
        break;
      }
      case Opcodes.DUP: {
        Slot value = state.peek();
        assert value.isCategory1();
        state.push(value.type);
        break;
      }
      case Opcodes.DUP_X1: {
        // Stack transformation: ..., v2, v1 -> ..., v1, v2, v1
        Slot value1 = state.pop();
        Slot value2 = state.pop();
        assert value1.isCategory1() && value2.isCategory1();
        int stack2 = state.push(value1.type);
        int stack1 = state.push(value2.type);
        state.push(value1.type);
        assert value2.register == stack2;
        assert value1.register == stack1;
        break;
      }
      case Opcodes.DUP_X2: {
        Slot value1 = state.pop();
        Slot value2 = state.pop();
        assert value1.isCategory1();
        if (value2.isCategory1()) {
          Slot value3 = state.pop();
          assert value3.isCategory1();
          // Stack transformation: ..., v3, v2, v1 -> ..., v1, v3, v2, v1
          updateStateForDupOneBelowTwo(value3, value2, value1);
        } else {
          // Stack transformation: ..., w2, v1 -> ..., v1, w2, v1
          updateStateForDupOneBelowOne(value2, value1);
        }
        break;
      }
      case Opcodes.DUP2: {
        Slot value1 = state.pop();
        if (value1.isCategory1()) {
          Slot value2 = state.pop();
          // Stack transformation: ..., v2, v1 -> ..., v2, v1, v2, v1
          assert value2.isCategory1();
          state.push(value2.type);
          state.push(value1.type);
          state.push(value2.type);
          state.push(value1.type);
        } else {
          // Stack transformation: ..., w1 -> ..., w1, w1
          state.push(value1.type);
          state.push(value1.type);
        }
        break;
      }
      case Opcodes.DUP2_X1: {
        Slot value1 = state.pop();
        Slot value2 = state.pop();
        assert value2.isCategory1();
        if (value1.isCategory1()) {
          // Stack transformation: ..., v3, v2, v1 -> v2, v1, v3, v2, v1
          Slot value3 = state.pop();
          assert value3.isCategory1();
          updateStateForDupTwoBelowOne(value3, value2, value1);
        } else {
          // Stack transformation: ..., v2, w1 -> ..., w1, v2, w1
          updateStateForDupOneBelowOne(value2, value1);
        }
        break;
      }
      case Opcodes.DUP2_X2: {
        Slot value1 = state.pop();
        Slot value2 = state.pop();
        if (!value1.isCategory1() && !value2.isCategory1()) {
          // State transformation: ..., w2, w1 -> w1, w2, w1
          updateStateForDupOneBelowOne(value2, value1);
        } else {
          Slot value3 = state.pop();
          if (!value1.isCategory1()) {
            assert value2.isCategory1();
            assert value3.isCategory1();
            // State transformation: ..., v3, v2, w1 -> w1, v3, v2, w1
            updateStateForDupOneBelowTwo(value3, value2, value1);
          } else if (!value3.isCategory1()) {
            assert value1.isCategory1();
            assert value2.isCategory1();
            // State transformation: ..., w3, v2, v1 -> v2, v1, w3, v2, v1
            updateStateForDupTwoBelowOne(value3, value2, value1);
          } else {
            Slot value4 = state.pop();
            assert value1.isCategory1();
            assert value2.isCategory1();
            assert value3.isCategory1();
            assert value4.isCategory1();
            // State transformation: ..., v4, v3, v2, v1 -> v2, v1, v4, v3, v2, v1
            updateStateForDupTwoBelowTwo(value4, value3, value2, value1);
          }
        }
        break;
      }
      case Opcodes.SWAP: {
        Slot value1 = state.pop();
        Slot value2 = state.pop();
        assert value1.isCategory1() && value2.isCategory1();
        state.push(value1.type);
        state.push(value2.type);
        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: {
        Type type = opType(opcode);
        state.pop();
        state.pop();
        state.push(type);
        break;
      }
      case Opcodes.INEG:
      case Opcodes.LNEG:
      case Opcodes.FNEG:
      case Opcodes.DNEG: {
        Type type = opType(opcode);
        state.pop();
        state.push(type);
        break;
      }
      case Opcodes.ISHL:
      case Opcodes.LSHL:
      case Opcodes.ISHR:
      case Opcodes.LSHR:
      case Opcodes.IUSHR:
      case Opcodes.LUSHR: {
        Type type = opType(opcode);
        state.pop();
        state.pop();
        state.push(type);
        break;
      }
      case Opcodes.IAND:
      case Opcodes.LAND: {
        Type type = opcode == Opcodes.IAND ? Type.INT_TYPE : Type.LONG_TYPE;
        state.pop();
        state.pop();
        state.push(type);
        break;
      }
      case Opcodes.IOR:
      case Opcodes.LOR: {
        Type type = opcode == Opcodes.IOR ? Type.INT_TYPE : Type.LONG_TYPE;
        state.pop();
        state.pop();
        state.push(type);
        break;
      }
      case Opcodes.IXOR:
      case Opcodes.LXOR: {
        Type type = opcode == Opcodes.IXOR ? Type.INT_TYPE : Type.LONG_TYPE;
        state.pop();
        state.pop();
        state.push(type);
        break;
      }
      case Opcodes.I2L:
        updateStateForConversion(Type.INT_TYPE, Type.LONG_TYPE);
        break;
      case Opcodes.I2F:
        updateStateForConversion(Type.INT_TYPE, Type.FLOAT_TYPE);
        break;
      case Opcodes.I2D:
        updateStateForConversion(Type.INT_TYPE, Type.DOUBLE_TYPE);
        break;
      case Opcodes.L2I:
        updateStateForConversion(Type.LONG_TYPE, Type.INT_TYPE);
        break;
      case Opcodes.L2F:
        updateStateForConversion(Type.LONG_TYPE, Type.FLOAT_TYPE);
        break;
      case Opcodes.L2D:
        updateStateForConversion(Type.LONG_TYPE, Type.DOUBLE_TYPE);
        break;
      case Opcodes.F2I:
        updateStateForConversion(Type.FLOAT_TYPE, Type.INT_TYPE);
        break;
      case Opcodes.F2L:
        updateStateForConversion(Type.FLOAT_TYPE, Type.LONG_TYPE);
        break;
      case Opcodes.F2D:
        updateStateForConversion(Type.FLOAT_TYPE, Type.DOUBLE_TYPE);
        break;
      case Opcodes.D2I:
        updateStateForConversion(Type.DOUBLE_TYPE, Type.INT_TYPE);
        break;
      case Opcodes.D2L:
        updateStateForConversion(Type.DOUBLE_TYPE, Type.LONG_TYPE);
        break;
      case Opcodes.D2F:
        updateStateForConversion(Type.DOUBLE_TYPE, Type.FLOAT_TYPE);
        break;
      case Opcodes.I2B:
        updateStateForConversion(Type.INT_TYPE, Type.BYTE_TYPE);
        break;
      case Opcodes.I2C:
        updateStateForConversion(Type.INT_TYPE, Type.CHAR_TYPE);
        break;
      case Opcodes.I2S:
        updateStateForConversion(Type.INT_TYPE, Type.SHORT_TYPE);
        break;
      case Opcodes.LCMP: {
        state.pop();
        state.pop();
        state.push(Type.INT_TYPE);
        break;
      }
      case Opcodes.FCMPL:
      case Opcodes.FCMPG: {
        state.pop();
        state.pop();
        state.push(Type.INT_TYPE);
        break;
      }
      case Opcodes.DCMPL:
      case Opcodes.DCMPG: {
        state.pop();
        state.pop();
        state.push(Type.INT_TYPE);
        break;
      }
      case Opcodes.IRETURN: {
        state.pop();
        break;
      }
      case Opcodes.LRETURN: {
        state.pop();
        break;
      }
      case Opcodes.FRETURN: {
        state.pop();
        break;
      }
      case Opcodes.DRETURN: {
        state.pop();
        break;
      }
      case Opcodes.ARETURN: {
        state.pop(JarState.REFERENCE_TYPE);
        break;
      }
      case Opcodes.RETURN: {
        break;
      }
      case Opcodes.ARRAYLENGTH: {
        state.pop(JarState.ARRAY_TYPE);
        state.push(Type.INT_TYPE);
        break;
      }
      case Opcodes.ATHROW: {
        state.pop(JarState.OBJECT_TYPE);
        break;
      }
      case Opcodes.MONITORENTER: {
        state.pop(JarState.REFERENCE_TYPE);
        break;
      }
      case Opcodes.MONITOREXIT: {
        state.pop(JarState.REFERENCE_TYPE);
        break;
      }
      default:
        throw new Unreachable("Unexpected Insn opcode: " + insn.getOpcode());
    }
  }

  private void updateStateForDupOneBelowTwo(Slot value3, Slot value2, Slot value1) {
    state.push(value1.type);
    state.push(value3.type);
    state.push(value2.type);
    state.push(value1.type);
  }

  private void updateStateForDupOneBelowOne(Slot value2, Slot value1) {
    state.push(value1.type);
    state.push(value2.type);
    state.push(value1.type);
  }

  private void updateStateForDupTwoBelowOne(Slot value3, Slot value2, Slot value1) {
    state.push(value2.type);
    state.push(value1.type);
    state.push(value3.type);
    state.push(value2.type);
    state.push(value1.type);
  }

  private void updateStateForDupTwoBelowTwo(Slot value4, Slot value3, Slot value2, Slot value1) {
    state.push(value2.type);
    state.push(value1.type);
    state.push(value4.type);
    state.push(value3.type);
    state.push(value2.type);
    state.push(value1.type);
  }

  private void updateState(IntInsnNode insn) {
    switch (insn.getOpcode()) {
      case Opcodes.BIPUSH:
      case Opcodes.SIPUSH: {
        state.push(Type.INT_TYPE);
        break;
      }
      case Opcodes.NEWARRAY: {
        String desc = arrayTypeDesc(insn.operand);
        Type type = application.getAsmType(desc);
        state.pop();
        state.push(type);
        break;
      }
      default:
        throw new Unreachable("Unexpected IntInsn opcode: " + insn.getOpcode());
    }
  }

  private void updateState(VarInsnNode insn) {
    int opcode = insn.getOpcode();
    Type expectedType;
    switch (opcode) {
      case Opcodes.ILOAD:
      case Opcodes.ISTORE:
        expectedType = Type.INT_TYPE;
        break;
      case Opcodes.FLOAD:
      case Opcodes.FSTORE:
        expectedType = Type.FLOAT_TYPE;
        break;
      case Opcodes.LLOAD:
      case Opcodes.LSTORE:
        expectedType = Type.LONG_TYPE;
        break;
      case Opcodes.DLOAD:
      case Opcodes.DSTORE:
        expectedType = Type.DOUBLE_TYPE;
        break;
      case Opcodes.ALOAD:
      case Opcodes.ASTORE:
        expectedType = JarState.REFERENCE_TYPE;
        break;
      case Opcodes.RET: {
        throw new Unreachable("RET should be handled by the ASM jsr inliner");
      }
      default:
        throw new Unreachable("Unexpected VarInsn opcode: " + insn.getOpcode());
    }
    if (Opcodes.ILOAD <= opcode && opcode <= Opcodes.ALOAD) {
      Slot src = state.readLocal(insn.var, expectedType);
      state.push(src.type);
    } else {
      assert Opcodes.ISTORE <= opcode && opcode <= Opcodes.ASTORE;
      Slot slot = state.pop();
      if (slot.type == JarState.NULL_TYPE && expectedType != JarState.REFERENCE_TYPE) {
        state.writeLocal(insn.var, expectedType);
      } else {
        state.writeLocal(insn.var, slot.type);
      }
    }
  }

  private void updateState(TypeInsnNode insn) {
    Type type = application.getAsmObjectType(insn.desc);
    switch (insn.getOpcode()) {
      case Opcodes.NEW: {
        state.push(type);
        break;
      }
      case Opcodes.ANEWARRAY: {
        Type arrayType = makeArrayType(type);
        state.pop();
        state.push(arrayType);
        break;
      }
      case Opcodes.CHECKCAST: {
        // Pop the top value and push it back on with the checked type.
        state.pop(type);
        state.push(type);
        break;
      }
      case Opcodes.INSTANCEOF: {
        state.pop(JarState.REFERENCE_TYPE);
        state.push(Type.INT_TYPE);
        break;
      }
      default:
        throw new Unreachable("Unexpected TypeInsn opcode: " + insn.getOpcode());
    }

  }

  private void updateState(FieldInsnNode insn) {
    Type type = application.getAsmType(insn.desc);
    switch (insn.getOpcode()) {
      case Opcodes.GETSTATIC:
        state.push(type);
        break;
      case Opcodes.PUTSTATIC:
        state.pop();
        break;
      case Opcodes.GETFIELD: {
        state.pop(JarState.OBJECT_TYPE);
        state.push(type);
        break;
      }
      case Opcodes.PUTFIELD: {
        state.pop();
        state.pop(JarState.OBJECT_TYPE);
        break;
      }
      default:
        throw new Unreachable("Unexpected FieldInsn opcode: " + insn.getOpcode());
    }
  }

  private void updateState(MethodInsnNode insn) {
    updateStateForInvoke(insn.desc, insn.getOpcode() != Opcodes.INVOKESTATIC);
  }

  private void updateState(InvokeDynamicInsnNode insn) {
    updateStateForInvoke(insn.desc, false /* receiver passed explicitly */);
  }

  private void updateStateForInvoke(String desc, boolean implicitReceiver) {
    // Pop arguments.
    state.popReverse(application.getArgumentCount(desc));
    // Pop implicit receiver if needed.
    if (implicitReceiver) {
      state.pop();
    }
    // Push return value if needed.
    Type returnType = application.getReturnType(desc);
    if (returnType != Type.VOID_TYPE) {
      state.push(returnType);
    }
  }

  private void updateState(JumpInsnNode insn) {
    int[] targets = getTargets(insn);
    int opcode = insn.getOpcode();
    if (Opcodes.IFEQ <= opcode && opcode <= Opcodes.IF_ACMPNE) {
      assert targets.length == 2;
      if (opcode <= Opcodes.IFLE) {
        state.pop();
      } else {
        state.pop();
        state.pop();
      }
    } else {
      switch (opcode) {
        case Opcodes.GOTO: {
          assert targets.length == 1;
          break;
        }
        case Opcodes.IFNULL:
        case Opcodes.IFNONNULL: {
          state.pop();
          break;
        }
        case Opcodes.JSR: {
          throw new Unreachable("JSR should be handled by the ASM jsr inliner");
        }
        default:
          throw new Unreachable("Unexpected JumpInsn opcode: " + insn.getOpcode());
      }
    }
  }

  private void updateState(LabelNode insn) {
    // Intentionally empty.
  }

  private void updateState(LdcInsnNode insn) {
    if (insn.cst instanceof Type) {
      Type type = (Type) insn.cst;
      state.push(type);
    } else if (insn.cst instanceof String) {
      state.push(STRING_TYPE);
    } else if (insn.cst instanceof Long) {
      state.push(Type.LONG_TYPE);
    } else if (insn.cst instanceof Double) {
      state.push(Type.DOUBLE_TYPE);
    } else if (insn.cst instanceof Integer) {
      state.push(Type.INT_TYPE);
    } else if (insn.cst instanceof Float) {
      state.push(Type.FLOAT_TYPE);
    } else if (insn.cst instanceof Handle) {
      state.push(METHOD_HANDLE_TYPE);
    } else {
      throw new CompilationError("Unsupported constant: " + insn.cst.toString());
    }
  }

  private void updateState(IincInsnNode insn) {
    state.readLocal(insn.var, Type.INT_TYPE);
  }

  private void updateState(TableSwitchInsnNode insn) {
    state.pop();
  }

  private void updateState(LookupSwitchInsnNode insn) {
    state.pop();
  }

  private void updateState(MultiANewArrayInsnNode insn) {
    // Type of the full array.
    Type arrayType = application.getAsmObjectType(insn.desc);
    state.popReverse(insn.dims, Type.INT_TYPE);
    state.push(arrayType);
  }

  private void updateState(LineNumberNode insn) {
    // Intentionally empty.
  }

  private void updateStateForConversion(Type from, Type to) {
    state.pop();
    state.push(to);
  }

  // IR instruction building procedures.

  private void build(AbstractInsnNode insn, IRBuilder builder) {
    switch (insn.getType()) {
      case AbstractInsnNode.INSN:
        build((InsnNode) insn, builder);
        break;
      case AbstractInsnNode.INT_INSN:
        build((IntInsnNode) insn, builder);
        break;
      case AbstractInsnNode.VAR_INSN:
        build((VarInsnNode) insn, builder);
        break;
      case AbstractInsnNode.TYPE_INSN:
        build((TypeInsnNode) insn, builder);
        break;
      case AbstractInsnNode.FIELD_INSN:
        build((FieldInsnNode) insn, builder);
        break;
      case AbstractInsnNode.METHOD_INSN:
        build((MethodInsnNode) insn, builder);
        break;
      case AbstractInsnNode.INVOKE_DYNAMIC_INSN:
        build((InvokeDynamicInsnNode) insn, builder);
        break;
      case AbstractInsnNode.JUMP_INSN:
        build((JumpInsnNode) insn, builder);
        break;
      case AbstractInsnNode.LABEL:
        build((LabelNode) insn, builder);
        break;
      case AbstractInsnNode.LDC_INSN:
        build((LdcInsnNode) insn, builder);
        break;
      case AbstractInsnNode.IINC_INSN:
        build((IincInsnNode) insn, builder);
        break;
      case AbstractInsnNode.TABLESWITCH_INSN:
        build((TableSwitchInsnNode) insn, builder);
        break;
      case AbstractInsnNode.LOOKUPSWITCH_INSN:
        build((LookupSwitchInsnNode) insn, builder);
        break;
      case AbstractInsnNode.MULTIANEWARRAY_INSN:
        build((MultiANewArrayInsnNode) insn, builder);
        break;
      case AbstractInsnNode.LINE:
        build((LineNumberNode) insn, builder);
        break;
      default:
        throw new Unreachable("Unexpected instruction " + insn);
    }
  }

  private void processLocalVariablesAtExit(AbstractInsnNode insn, IRBuilder builder) {
    assert isReturn(insn) || isThrow(insn);
    // Read all locals live at exit to ensure liveness.
    for (Local local : state.getLocals()) {
      if (local.info != null) {
        builder.addDebugLocalEnd(local.slot.register, local.info);
      }
    }
  }

  private void build(InsnNode insn, IRBuilder builder) {
    int opcode = insn.getOpcode();
    switch (opcode) {
      case Opcodes.NOP:
        // Intentionally left empty.
        break;
      case Opcodes.ACONST_NULL:
        builder.addNullConst(state.push(JarState.NULL_TYPE));
        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:
        builder.addIntConst(state.push(Type.INT_TYPE), opcode - Opcodes.ICONST_0);
        break;
      case Opcodes.LCONST_0:
      case Opcodes.LCONST_1:
        builder.addLongConst(state.push(Type.LONG_TYPE), opcode - Opcodes.LCONST_0);
        break;
      case Opcodes.FCONST_0:
      case Opcodes.FCONST_1:
      case Opcodes.FCONST_2:
        builder.addFloatConst(state.push(Type.FLOAT_TYPE),
            Float.floatToRawIntBits(opcode - Opcodes.FCONST_0));
        break;
      case Opcodes.DCONST_0:
      case Opcodes.DCONST_1:
        builder.addDoubleConst(state.push(Type.DOUBLE_TYPE),
            Double.doubleToRawLongBits(opcode - Opcodes.DCONST_0));
        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: {
        Slot index = state.pop(Type.INT_TYPE);
        Slot array = state.pop(JarState.ARRAY_TYPE);
        Type elementType = array.getArrayElementType();
        if (elementType == null) {
          elementType = getArrayElementTypeForOpcode(opcode);
        }
        int dest = state.push(elementType);
        assert isCompatibleArrayElementType(opcode, elementType);
        builder.addArrayGet(memberType(elementType), dest, array.register, index.register);
        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: {
        Slot value = state.pop();
        Slot index = state.pop(Type.INT_TYPE);
        Slot array = state.pop(JarState.ARRAY_TYPE);
        Type elementType = array.getArrayElementType();
        if (elementType == null) {
          elementType = getArrayElementTypeForOpcode(opcode);
        }
        assert isCompatibleArrayElementType(opcode, elementType);
        assert isCompatibleArrayElementType(opcode, value.type);
        builder.addArrayPut(
            memberType(elementType), value.register, array.register, index.register);
        break;
      }
      case Opcodes.POP: {
        Slot value = state.pop();
        assert value.isCategory1();
        break;
      }
      case Opcodes.POP2: {
        Slot value = state.pop();
        if (value.isCategory1()) {
          Slot value2 = state.pop();
          assert value2.isCategory1();
        }
        break;
      }
      case Opcodes.DUP: {
        Slot value = state.peek();
        assert value.isCategory1();
        int copy = state.push(value.type);
        builder.addMove(valueType(value.type), copy, value.register);
        break;
      }
      case Opcodes.DUP_X1: {
        // Stack transformation: ..., v2, v1 -> ..., v1, v2, v1
        Slot value1 = state.pop();
        Slot value2 = state.pop();
        assert value1.isCategory1() && value2.isCategory1();
        int stack2 = state.push(value1.type);
        int stack1 = state.push(value2.type);
        int stack0 = state.push(value1.type);
        assert value2.register == stack2;
        assert value1.register == stack1;
        // stack0 is new top-of-stack.
        builder.addMove(valueType(value1.type), stack0, stack1);
        builder.addMove(valueType(value2.type), stack1, stack2);
        builder.addMove(valueType(value1.type), stack2, stack0);
        break;
      }
      case Opcodes.DUP_X2: {
        Slot value1 = state.pop();
        Slot value2 = state.pop();
        assert value1.isCategory1();
        if (value2.isCategory1()) {
          Slot value3 = state.pop();
          assert value3.isCategory1();
          // Stack transformation: ..., v3, v2, v1 -> ..., v1, v3, v2, v1
          dupOneBelowTwo(value3, value2, value1, builder);
        } else {
          // Stack transformation: ..., w2, v1 -> ..., v1, w2, v1
          dupOneBelowOne(value2, value1, builder);
        }
        break;
      }
      case Opcodes.DUP2: {
        Slot value1 = state.pop();
        if (value1.isCategory1()) {
          Slot value2 = state.pop();
          // Stack transformation: ..., v2, v1 -> ..., v2, v1, v2, v1
          assert value2.isCategory1();
          state.push(value2.type);
          state.push(value1.type);
          int copy2 = state.push(value2.type);
          int copy1 = state.push(value1.type);
          builder.addMove(valueType(value1.type), copy1, value1.register);
          builder.addMove(valueType(value2.type), copy2, value2.register);
        } else {
          // Stack transformation: ..., w1 -> ..., w1, w1
          state.push(value1.type);
          int copy1 = state.push(value1.type);
          builder.addMove(valueType(value1.type), copy1, value1.register);
        }
        break;
      }
      case Opcodes.DUP2_X1: {
        Slot value1 = state.pop();
        Slot value2 = state.pop();
        assert value2.isCategory1();
        if (value1.isCategory1()) {
          // Stack transformation: ..., v3, v2, v1 -> v2, v1, v3, v2, v1
          Slot value3 = state.pop();
          assert value3.isCategory1();
          dupTwoBelowOne(value3, value2, value1, builder);
        } else {
          // Stack transformation: ..., v2, w1 -> ..., w1, v2, w1
          dupOneBelowOne(value2, value1, builder);
        }
        break;
      }
      case Opcodes.DUP2_X2: {
        Slot value1 = state.pop();
        Slot value2 = state.pop();
        if (!value1.isCategory1() && !value2.isCategory1()) {
          // State transformation: ..., w2, w1 -> w1, w2, w1
          dupOneBelowOne(value2, value1, builder);
        } else {
          Slot value3 = state.pop();
          if (!value1.isCategory1()) {
            assert value2.isCategory1();
            assert value3.isCategory1();
            // State transformation: ..., v3, v2, w1 -> w1, v3, v2, w1
            dupOneBelowTwo(value3, value2, value1, builder);
          } else if (!value3.isCategory1()) {
            assert value1.isCategory1();
            assert value2.isCategory1();
            // State transformation: ..., w3, v2, v1 -> v2, v1, w3, v2, v1
            dupTwoBelowOne(value3, value2, value1, builder);
          } else {
            Slot value4 = state.pop();
            assert value1.isCategory1();
            assert value2.isCategory1();
            assert value3.isCategory1();
            assert value4.isCategory1();
            // State transformation: ..., v4, v3, v2, v1 -> v2, v1, v4, v3, v2, v1
            dupTwoBelowTwo(value4, value3, value2, value1, builder);
          }
        }
        break;
      }
      case Opcodes.SWAP: {
        Slot value1 = state.pop();
        Slot value2 = state.pop();
        assert value1.isCategory1() && value2.isCategory1();
        state.push(value1.type);
        state.push(value2.type);
        int tmp = state.push(value1.type);
        builder.addMove(valueType(value1.type), tmp, value1.register);
        builder.addMove(valueType(value2.type), value1.register, value2.register);
        builder.addMove(valueType(value1.type), value2.register, tmp);
        state.pop(); // Remove temp.
        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: {
        Type type = opType(opcode);
        NumericType numericType = numericType(type);
        int right = state.pop(type).register;
        int left = state.pop(type).register;
        int dest = state.push(type);
        if (opcode <= Opcodes.DADD) {
          builder.addAdd(numericType, dest, left, right);
        } else if (opcode <= Opcodes.DSUB) {
          builder.addSub(numericType, dest, left, right);
        } else if (opcode <= Opcodes.DMUL) {
          builder.addMul(numericType, dest, left, right);
        } else if (opcode <= Opcodes.DDIV) {
          builder.addDiv(numericType, dest, left, right);
        } else {
          assert Opcodes.IREM <= opcode && opcode <= Opcodes.DREM;
          builder.addRem(numericType, dest, left, right);
        }
        break;
      }
      case Opcodes.INEG:
      case Opcodes.LNEG:
      case Opcodes.FNEG:
      case Opcodes.DNEG: {
        Type type = opType(opcode);
        NumericType numericType = numericType(type);
        int value = state.pop(type).register;
        int dest = state.push(type);
        builder.addNeg(numericType, dest, value);
        break;
      }
      case Opcodes.ISHL:
      case Opcodes.LSHL:
      case Opcodes.ISHR:
      case Opcodes.LSHR:
      case Opcodes.IUSHR:
      case Opcodes.LUSHR: {
        Type type = opType(opcode);
        NumericType numericType = numericType(type);
        int right = state.pop(Type.INT_TYPE).register;
        int left = state.pop(type).register;
        int dest = state.push(type);
        if (opcode <= Opcodes.LSHL) {
          builder.addShl(numericType, dest, left, right);
        } else if (opcode <= Opcodes.LSHR) {
          builder.addShr(numericType, dest, left, right);
        } else {
          assert opcode == Opcodes.IUSHR || opcode == Opcodes.LUSHR;
          builder.addUshr(numericType, dest, left, right);
        }
        break;
      }
      case Opcodes.IAND:
      case Opcodes.LAND: {
        Type type = opcode == Opcodes.IAND ? Type.INT_TYPE : Type.LONG_TYPE;
        int right = state.pop(type).register;
        int left = state.pop(type).register;
        int dest = state.push(type);
        builder.addAnd(numericType(type), dest, left, right);
        break;
      }
      case Opcodes.IOR:
      case Opcodes.LOR: {
        Type type = opcode == Opcodes.IOR ? Type.INT_TYPE : Type.LONG_TYPE;
        int right = state.pop(type).register;
        int left = state.pop(type).register;
        int dest = state.push(type);
        builder.addOr(numericType(type), dest, left, right);
        break;
      }
      case Opcodes.IXOR:
      case Opcodes.LXOR: {
        Type type = opcode == Opcodes.IXOR ? Type.INT_TYPE : Type.LONG_TYPE;
        int right = state.pop(type).register;
        int left = state.pop(type).register;
        int dest = state.push(type);
        builder.addXor(numericType(type), dest, left, right);
        break;
      }
      case Opcodes.I2L:
        buildConversion(Type.INT_TYPE, Type.LONG_TYPE, builder);
        break;
      case Opcodes.I2F:
        buildConversion(Type.INT_TYPE, Type.FLOAT_TYPE, builder);
        break;
      case Opcodes.I2D:
        buildConversion(Type.INT_TYPE, Type.DOUBLE_TYPE, builder);
        break;
      case Opcodes.L2I:
        buildConversion(Type.LONG_TYPE, Type.INT_TYPE, builder);
        break;
      case Opcodes.L2F:
        buildConversion(Type.LONG_TYPE, Type.FLOAT_TYPE, builder);
        break;
      case Opcodes.L2D:
        buildConversion(Type.LONG_TYPE, Type.DOUBLE_TYPE, builder);
        break;
      case Opcodes.F2I:
        buildConversion(Type.FLOAT_TYPE, Type.INT_TYPE, builder);
        break;
      case Opcodes.F2L:
        buildConversion(Type.FLOAT_TYPE, Type.LONG_TYPE, builder);
        break;
      case Opcodes.F2D:
        buildConversion(Type.FLOAT_TYPE, Type.DOUBLE_TYPE, builder);
        break;
      case Opcodes.D2I:
        buildConversion(Type.DOUBLE_TYPE, Type.INT_TYPE, builder);
        break;
      case Opcodes.D2L:
        buildConversion(Type.DOUBLE_TYPE, Type.LONG_TYPE, builder);
        break;
      case Opcodes.D2F:
        buildConversion(Type.DOUBLE_TYPE, Type.FLOAT_TYPE, builder);
        break;
      case Opcodes.I2B:
        buildConversion(Type.INT_TYPE, Type.BYTE_TYPE, builder);
        break;
      case Opcodes.I2C:
        buildConversion(Type.INT_TYPE, Type.CHAR_TYPE, builder);
        break;
      case Opcodes.I2S:
        buildConversion(Type.INT_TYPE, Type.SHORT_TYPE, builder);
        break;
      case Opcodes.LCMP: {
        Slot right = state.pop(Type.LONG_TYPE);
        Slot left = state.pop(Type.LONG_TYPE);
        int dest = state.push(Type.INT_TYPE);
        builder.addCmp(NumericType.LONG, Bias.NONE, dest, left.register, right.register);
        break;
      }
      case Opcodes.FCMPL:
      case Opcodes.FCMPG: {
        Slot right = state.pop(Type.FLOAT_TYPE);
        Slot left = state.pop(Type.FLOAT_TYPE);
        int dest = state.push(Type.INT_TYPE);
        Bias bias = opcode == Opcodes.FCMPL ? Bias.LT : Bias.GT;
        builder.addCmp(NumericType.FLOAT, bias, dest, left.register, right.register);
        break;
      }
      case Opcodes.DCMPL:
      case Opcodes.DCMPG: {
        Slot right = state.pop(Type.DOUBLE_TYPE);
        Slot left = state.pop(Type.DOUBLE_TYPE);
        int dest = state.push(Type.INT_TYPE);
        Bias bias = opcode == Opcodes.DCMPL ? Bias.LT : Bias.GT;
        builder.addCmp(NumericType.DOUBLE, bias, dest, left.register, right.register);
        break;
      }
      case Opcodes.IRETURN: {
        Slot value = state.pop(Type.INT_TYPE);
        addReturn(insn, ValueTypeConstraint.INT, value.register, builder);
        break;
      }
      case Opcodes.LRETURN: {
        Slot value = state.pop(Type.LONG_TYPE);
        addReturn(insn, ValueTypeConstraint.LONG, value.register, builder);
        break;
      }
      case Opcodes.FRETURN: {
        Slot value = state.pop(Type.FLOAT_TYPE);
        addReturn(insn, ValueTypeConstraint.FLOAT, value.register, builder);
        break;
      }
      case Opcodes.DRETURN: {
        Slot value = state.pop(Type.DOUBLE_TYPE);
        addReturn(insn, ValueTypeConstraint.DOUBLE, value.register, builder);
        break;
      }
      case Opcodes.ARETURN: {
        Slot obj = state.pop(JarState.REFERENCE_TYPE);
        addReturn(insn, ValueTypeConstraint.OBJECT, obj.register, builder);
        break;
      }
      case Opcodes.RETURN: {
        addReturn(insn, null, -1, builder);
        break;
      }
      case Opcodes.ARRAYLENGTH: {
        Slot array = state.pop(JarState.ARRAY_TYPE);
        int dest = state.push(Type.INT_TYPE);
        builder.addArrayLength(dest, array.register);
        break;
      }
      case Opcodes.ATHROW: {
        Slot object = state.pop(JarState.OBJECT_TYPE);
        addThrow(insn, object.register, builder);
        break;
      }
      case Opcodes.MONITORENTER: {
        Slot object = state.pop(JarState.REFERENCE_TYPE);
        builder.addMonitor(Monitor.Type.ENTER, object.register);
        break;
      }
      case Opcodes.MONITOREXIT: {
        Slot object = state.pop(JarState.REFERENCE_TYPE);
        builder.addMonitor(Monitor.Type.EXIT, object.register);
        break;
      }
      default:
        throw new Unreachable("Unexpected Insn opcode: " + insn.getOpcode());
    }
  }

  private boolean isExitingThrow(InsnNode insn) {
    List<TryCatchBlock> handlers = getTryHandlers(insn);
    if (handlers.isEmpty()) {
      return true;
    }
    if (!generateMethodSynchronization() || handlers.size() > 1) {
      return false;
    }
    return handlers.get(0) == EXCEPTIONAL_SYNC_EXIT;
  }

  private void addThrow(InsnNode insn, int register, IRBuilder builder) {
    if (isExitingThrow(insn)) {
      processLocalVariablesAtExit(insn, builder);
    } else {
      int offset = getOffset(insn);
      Int2ReferenceSortedMap<BlockInfo> cfg = builder.getCFG();
      BlockInfo info = cfg.get(cfg.headMap(offset + 1).lastIntKey());
      assert info.normalSuccessors.isEmpty();
      assert !info.exceptionalSuccessors.isEmpty();
      Int2ReferenceMap<DebugLocalInfo> ending = new Int2ReferenceOpenHashMap<>();
      for (int successorOffset : info.exceptionalSuccessors) {
        if (successorOffset == EXCEPTIONAL_SYNC_EXIT_OFFSET) {
          // TODO(zerny): It would likely be beneficial to keep locals live until the exit from the
          // exceptional sync exit block.
          continue;
        }
        LocalChangeAtOffset localChange = state.getLocalChange(offset, successorOffset);
        for (Local localEnd : localChange.getLocalsToClose()) {
          ending.put(localEnd.slot.register, localEnd.info);
        }
      }
      ending.forEach(builder::addDebugLocalEnd);
    }
    builder.addThrow(register);
  }

  private void addReturn(
      InsnNode insn, ValueTypeConstraint constraint, int register, IRBuilder builder) {
    processLocalVariablesAtExit(insn, builder);
    if (constraint == null) {
      assert register == -1;
      builder.addReturn();
    } else {
      builder.addReturn(register);
    }
  }

  private void dupOneBelowTwo(Slot value3, Slot value2, Slot value1, IRBuilder builder) {
    int stack3 = state.push(value1.type);
    int stack2 = state.push(value3.type);
    int stack1 = state.push(value2.type);
    int stack0 = state.push(value1.type);
    assert value3.register == stack3;
    assert value2.register == stack2;
    assert value1.register == stack1;
    builder.addMove(valueType(value1.type), stack0, stack1);
    builder.addMove(valueType(value2.type), stack1, stack2);
    builder.addMove(valueType(value3.type), stack2, stack3);
    builder.addMove(valueType(value1.type), stack3, stack0);
  }

  private void dupOneBelowOne(Slot value2, Slot value1, IRBuilder builder) {
    int stack2 = state.push(value1.type);
    int stack1 = state.push(value2.type);
    int stack0 = state.push(value1.type);
    assert value2.register == stack2;
    assert value1.register == stack1;
    builder.addMove(valueType(value1.type), stack0, stack1);
    builder.addMove(valueType(value2.type), stack1, stack2);
    builder.addMove(valueType(value1.type), stack2, stack0);
  }

  private void dupTwoBelowOne(Slot value3, Slot value2, Slot value1, IRBuilder builder) {
    int stack4 = state.push(value2.type);
    int stack3 = state.push(value1.type);
    int stack2 = state.push(value3.type);
    int stack1 = state.push(value2.type);
    int stack0 = state.push(value1.type);
    assert value3.register == stack4;
    assert value2.register == stack3;
    assert value1.register == stack2;
    builder.addMove(valueType(value1.type), stack0, stack2);
    builder.addMove(valueType(value2.type), stack1, stack3);
    builder.addMove(valueType(value3.type), stack2, stack4);
    builder.addMove(valueType(value1.type), stack3, stack0);
    builder.addMove(valueType(value2.type), stack4, stack1);
  }

  private void dupTwoBelowTwo(Slot value4, Slot value3, Slot value2, Slot value1,
      IRBuilder builder) {
    int stack5 = state.push(value2.type);
    int stack4 = state.push(value1.type);
    int stack3 = state.push(value4.type);
    int stack2 = state.push(value3.type);
    int stack1 = state.push(value2.type);
    int stack0 = state.push(value1.type);
    assert value4.register == stack5;
    assert value3.register == stack4;
    assert value2.register == stack3;
    assert value1.register == stack2;
    builder.addMove(valueType(value1.type), stack0, stack2);
    builder.addMove(valueType(value2.type), stack1, stack3);
    builder.addMove(valueType(value3.type), stack2, stack4);
    builder.addMove(valueType(value4.type), stack3, stack5);
    builder.addMove(valueType(value1.type), stack4, stack0);
    builder.addMove(valueType(value2.type), stack5, stack1);
  }

  private void buildConversion(Type from, Type to, IRBuilder builder) {
    int source = state.pop(from).register;
    int dest = state.push(to);
    builder.addConversion(numericType(to), numericType(from), dest, source);
  }

  private void build(IntInsnNode insn, IRBuilder builder) {
    switch (insn.getOpcode()) {
      case Opcodes.BIPUSH:
      case Opcodes.SIPUSH: {
        int dest = state.push(Type.INT_TYPE);
        builder.addIntConst(dest, insn.operand);
        break;
      }
      case Opcodes.NEWARRAY: {
        String desc = arrayTypeDesc(insn.operand);
        Type type = application.getAsmType(desc);
        DexType dexType = application.getTypeFromDescriptor(desc);
        int count = state.pop(Type.INT_TYPE).register;
        int array = state.push(type);
        builder.addNewArrayEmpty(array, count, dexType);
        break;
      }
      default:
        throw new Unreachable("Unexpected IntInsn opcode: " + insn.getOpcode());
    }
  }

  private void build(VarInsnNode insn, IRBuilder builder) {
    int opcode = insn.getOpcode();
    Type expectedType;
    switch (opcode) {
      case Opcodes.ILOAD:
      case Opcodes.ISTORE:
        expectedType = Type.INT_TYPE;
        break;
      case Opcodes.FLOAD:
      case Opcodes.FSTORE:
        expectedType = Type.FLOAT_TYPE;
        break;
      case Opcodes.LLOAD:
      case Opcodes.LSTORE:
        expectedType = Type.LONG_TYPE;
        break;
      case Opcodes.DLOAD:
      case Opcodes.DSTORE:
        expectedType = Type.DOUBLE_TYPE;
        break;
      case Opcodes.ALOAD:
      case Opcodes.ASTORE:
        expectedType = JarState.REFERENCE_TYPE;
        break;
      case Opcodes.RET: {
        throw new Unreachable("RET should be handled by the ASM jsr inliner");
      }
      default:
        throw new Unreachable("Unexpected VarInsn opcode: " + insn.getOpcode());
    }
    if (Opcodes.ILOAD <= opcode && opcode <= Opcodes.ALOAD) {
      Slot src = state.readLocal(insn.var, expectedType);
      int dest = state.push(src.type);
      builder.addMove(valueType(src.type), dest, src.register);
    } else {
      assert Opcodes.ISTORE <= opcode && opcode <= Opcodes.ASTORE;
      Slot src = state.pop(expectedType);
      int dest = state.getLocalRegister(insn.var, src.type);
      builder.addMove(valueType(src.type), dest, src.register);
      state.writeLocal(insn.var, src.type);
    }
  }

  private void build(TypeInsnNode insn, IRBuilder builder) {
    Type type = application.getAsmObjectType(insn.desc);
    switch (insn.getOpcode()) {
      case Opcodes.NEW: {
        DexType dexType = application.getTypeFromName(insn.desc);
        int dest = state.push(type);
        builder.addNewInstance(dest, dexType);
        break;
      }
      case Opcodes.ANEWARRAY: {
        Type arrayType = makeArrayType(type);
        DexType dexArrayType = application.getTypeFromDescriptor(arrayType.getDescriptor());
        int count = state.pop(Type.INT_TYPE).register;
        int dest = state.push(arrayType);
        builder.addNewArrayEmpty(dest, count, dexArrayType);
        break;
      }
      case Opcodes.CHECKCAST: {
        DexType dexType = application.getTypeFromDescriptor(type.getDescriptor());
        // Pop the top value and push it back on with the checked type.
        state.pop(type);
        int object = state.push(type);
        builder.addCheckCast(object, dexType);
        break;
      }
      case Opcodes.INSTANCEOF: {
        int obj = state.pop(JarState.REFERENCE_TYPE).register;
        int dest = state.push(Type.INT_TYPE);
        DexType dexType = application.getTypeFromDescriptor(type.getDescriptor());
        builder.addInstanceOf(dest, obj, dexType);
        break;
      }
      default:
        throw new Unreachable("Unexpected TypeInsn opcode: " + insn.getOpcode());
    }
  }

  private void build(FieldInsnNode insn, IRBuilder builder) {
    DexField field = application.getField(insn.owner, insn.name, insn.desc);
    Type type = application.getAsmType(insn.desc);
    switch (insn.getOpcode()) {
      case Opcodes.GETSTATIC:
        builder.addStaticGet(state.push(type), field);
        break;
      case Opcodes.PUTSTATIC:
        builder.addStaticPut(state.pop(type).register, field);
        break;
      case Opcodes.GETFIELD: {
        Slot object = state.pop(JarState.OBJECT_TYPE);
        int dest = state.push(type);
        builder.addInstanceGet(dest, object.register, field);
        break;
      }
      case Opcodes.PUTFIELD: {
        Slot value = state.pop(type);
        Slot object = state.pop(JarState.OBJECT_TYPE);
        builder.addInstancePut(value.register, object.register, field);
        break;
      }
      default:
        throw new Unreachable("Unexpected FieldInsn opcode: " + insn.getOpcode());
    }
  }

  private void build(MethodInsnNode insn, IRBuilder builder) {
    // Resolve the target method of the invoke.
    DexMethod method = application.getMethod(insn.owner, insn.name, insn.desc);

    buildInvoke(
        insn.desc,
        application.getAsmObjectType(insn.owner),
        insn.getOpcode() != Opcodes.INVOKESTATIC,
        builder,
        (types, registers) -> {
          Invoke.Type invokeType = invokeType(insn);
          DexProto callSiteProto = null;
          DexMethod targetMethod = method;
          if (invokeType == Invoke.Type.POLYMORPHIC) {
            if (insn.owner.equals(INTERNAL_NAME_METHOD_HANDLE)) {
              targetMethod = application
                  .getMethod(insn.owner, insn.name, POLYMORPHIC_DEFAULT_SIGNATURE_DESC);
            } else if (insn.owner.equals(INTERNAL_NAME_VAR_HANDLE)) {
              switch (insn.name) {
                case "compareAndExchange":
                case "compareAndExchangeAcquire":
                case "compareAndExchangeRelease":
                case "get":
                case "getAcquire":
                case "getAndAdd":
                case "getAndAddAcquire":
                case "getAndAddRelease":
                case "getAndBitwiseAnd":
                case "getAndBitwiseAndAcquire":
                case "getAndBitwiseAndRelease":
                case "getAndBitwiseOr":
                case "getAndBitwiseOrAcquire":
                case "getAndBitwiseOrRelease":
                case "getAndBitwiseXor":
                case "getAndBitwiseXorAcquire":
                case "getAndBitwiseXorRelease":
                case "getAndSet":
                case "getAndSetAcquire":
                case "getAndSetRelease":
                case "getOpaque":
                case "getVolatile": {
                  targetMethod = application
                      .getMethod(insn.owner, insn.name, POLYMORPHIC_DEFAULT_SIGNATURE_DESC);
                  break;
                }
                case "set":
                case "setOpaque":
                case "setRelease":
                case "setVolatile": {
                  targetMethod = application
                      .getMethod(insn.owner, insn.name, POLYMORPHIC_VARHANDLE_SET_SIGNATURE_DESC);
                  break;
                }
                case "compareAndSet":
                case "weakCompareAndSet":
                case "weakCompareAndSetAcquire":
                case "weakCompareAndSetPlain":
                case "weakCompareAndSetRelease": {
                  targetMethod = application.getMethod(insn.owner, insn.name,
                      POLYMORPHIC_VARHANDLE_COMPARE_AND_SET_SIGNATURE_DESC);
                  break;
                }
                default:
                  throw new Unreachable();
              }
            } else {
              throw new Unreachable();
            }
            callSiteProto = application.getProto(insn.desc);
          }
          builder.addInvoke(invokeType, targetMethod, callSiteProto, types, registers, insn.itf);
        });
  }

  private void buildInvoke(
      String methodDesc,
      Type methodOwner,
      boolean addImplicitReceiver,
      IRBuilder builder,
      BiConsumer<List<ValueType>, List<Integer>> creator) {

    // Build the argument list of the form [owner, param1, ..., paramN].
    // The arguments are in reverse order on the stack, so we pop off the parameters here.
    Type[] parameterTypes = application.getArgumentTypes(methodDesc);
    Slot[] parameterRegisters = state.popReverse(parameterTypes.length);

    List<ValueType> types = new ArrayList<>(parameterTypes.length + 1);
    List<Integer> registers = new ArrayList<>(parameterTypes.length + 1);

    // Add receiver argument for non-static calls.
    if (addImplicitReceiver) {
      addArgument(types, registers, methodOwner, state.pop());
    }

    // The remaining arguments are the parameters of the method.
    for (int i = 0; i < parameterTypes.length; i++) {
      addArgument(types, registers, parameterTypes[i], parameterRegisters[i]);
    }

    // Create the invoke.
    creator.accept(types, registers);

    // Move the result to the "top of stack".
    Type returnType = application.getReturnType(methodDesc);
    if (returnType != Type.VOID_TYPE) {
      builder.addMoveResult(state.push(returnType));
    }
  }

  private static void addArgument(
      List<ValueType> types,
      List<Integer> registers,
      Type type,
      Slot slot) {
    assert slot.isCompatibleWith(type);
    types.add(valueType(type));
    registers.add(slot.register);
  }

  private void build(InvokeDynamicInsnNode insn, IRBuilder builder) {
    DexCallSite callSite = DexCallSite.fromAsmInvokeDynamic(insn, application, clazz);

    buildInvoke(insn.desc, null /* Not needed */,
        false /* Receiver is passed explicitly */, builder,
        (types, registers) -> builder.addInvokeCustom(callSite, types, registers));
  }

  private void build(JumpInsnNode insn, IRBuilder builder) {
    int[] targets = getTargets(insn);
    int opcode = insn.getOpcode();
    if (Opcodes.IFEQ <= opcode && opcode <= Opcodes.IF_ACMPNE) {
      assert targets.length == 2;
      if (opcode <= Opcodes.IFLE) {
        Slot value = state.pop(Type.INT_TYPE);
        builder.addIfZero(
            ifType(opcode), ValueTypeConstraint.INT, value.register, targets[0], targets[1]);
      } else {
        ValueTypeConstraint valueType;
        Type expectedType;
        if (opcode < Opcodes.IF_ACMPEQ) {
          valueType = ValueTypeConstraint.INT;
          expectedType = Type.INT_TYPE;
        } else {
          valueType = ValueTypeConstraint.OBJECT;
          expectedType = JarState.REFERENCE_TYPE;
        }
        Slot value2 = state.pop(expectedType);
        Slot value1 = state.pop(expectedType);
        builder.addIf(
            ifType(opcode), valueType, value1.register, value2.register, targets[0], targets[1]);
      }
    } else {
      switch (opcode) {
        case Opcodes.GOTO: {
          assert targets.length == 1;
          builder.addGoto(targets[0]);
          break;
        }
        case Opcodes.IFNULL:
        case Opcodes.IFNONNULL: {
          Slot value = state.pop(JarState.REFERENCE_TYPE);
          If.Type type = opcode == Opcodes.IFNULL ? If.Type.EQ : If.Type.NE;
            builder.addIfZero(
                type, ValueTypeConstraint.OBJECT, value.register, targets[0], targets[1]);
          break;
        }
        case Opcodes.JSR: {
          throw new Unreachable("JSR should be handled by the ASM jsr inliner");
        }
        default:
          throw new Unreachable("Unexpected JumpInsn opcode: " + insn.getOpcode());
      }
    }
  }

  private void build(LabelNode insn, IRBuilder builder) {
    // Intentionally empty.
  }

  private void build(LdcInsnNode insn, IRBuilder builder) {
    if (insn.cst instanceof Type) {
      Type type = (Type) insn.cst;
      if (type.getSort() == Type.METHOD) {
        int dest = state.push(METHOD_TYPE_TYPE);
        builder.addConstMethodType(dest, application.getProto(type.getDescriptor()));
      } else {
        int dest = state.push(type);
        builder.addConstClass(dest, application.getTypeFromDescriptor(type.getDescriptor()));
      }
    } else if (insn.cst instanceof String) {
      int dest = state.push(STRING_TYPE);
      builder.addConstString(dest, application.getString((String) insn.cst));
    } else if (insn.cst instanceof Long) {
      int dest = state.push(Type.LONG_TYPE);
      builder.addLongConst(dest, (Long) insn.cst);
    } else if (insn.cst instanceof Double) {
      int dest = state.push(Type.DOUBLE_TYPE);
      builder.addDoubleConst(dest, Double.doubleToRawLongBits((Double) insn.cst));
    } else if (insn.cst instanceof Integer) {
      int dest = state.push(Type.INT_TYPE);
      builder.addIntConst(dest, (Integer) insn.cst);
    } else if (insn.cst instanceof Float) {
      int dest = state.push(Type.FLOAT_TYPE);
      builder.addFloatConst(dest, Float.floatToRawIntBits((Float) insn.cst));
    } else if (insn.cst instanceof Handle) {
      Handle handle = (Handle) insn.cst;
      int dest = state.push(METHOD_HANDLE_TYPE);
      builder.addConstMethodHandle(dest, DexMethodHandle.fromAsmHandle(handle, application, clazz));
    } else {
      throw new CompilationError("Unsupported constant: " + insn.cst.toString());
    }
  }

  private void build(IincInsnNode insn, IRBuilder builder) {
    int local = state.readLocal(insn.var, Type.INT_TYPE).register;
    builder.addAddLiteral(NumericType.INT, local, local, insn.incr);
  }

  private void build(TableSwitchInsnNode insn, IRBuilder builder) {
    buildSwitch(insn.dflt, insn.labels, new int[]{insn.min}, builder);
  }

  private void build(LookupSwitchInsnNode insn, IRBuilder builder) {
    int[] keys = new int[insn.keys.size()];
    for (int i = 0; i < insn.keys.size(); i++) {
      keys[i] = (int) insn.keys.get(i);
    }
    buildSwitch(insn.dflt, insn.labels, keys, builder);
  }

  private void buildSwitch(LabelNode dflt, List labels, int[] keys,
      IRBuilder builder) {
    int index = state.pop(Type.INT_TYPE).register;
    int fallthroughOffset = getOffset(dflt);
    int[] labelOffsets = new int[labels.size()];
    for (int i = 0; i < labels.size(); i++) {
      int offset = getOffset((LabelNode) labels.get(i));
      labelOffsets[i] = offset;
    }
    builder.addSwitch(index, keys, fallthroughOffset, labelOffsets);
  }

  private void build(MultiANewArrayInsnNode insn, IRBuilder builder) {
    // Type of the full array.
    Type arrayType = application.getAsmObjectType(insn.desc);
    DexType dexArrayType = application.getType(arrayType);
    Slot[] slots = state.popReverse(insn.dims, Type.INT_TYPE);
    int[] dimensions = new int[insn.dims];
    for (int i = 0; i < insn.dims; i++) {
      dimensions[i] = slots[i].register;
    }
    if (builder.isGeneratingClassFiles()) {
      int result = state.push(arrayType);
      builder.addMultiNewArray(dexArrayType, result, dimensions);
      return;
    }
    // Type of the members. Can itself be of array type, eg, 'int[]' for 'new int[x][y][]'
    // Note that this is not the same as 'arrayType.toBaseType' as is the case in the above 'int[]'.
    DexType memberType = application.getTypeFromDescriptor(insn.desc.substring(insn.dims));
    // Push an array containing the dimensions of the desired multi-dimensional array.
    DexType dimArrayType = application.getTypeFromDescriptor(INT_ARRAY_DESC);
    builder.addInvokeNewArray(dimArrayType, insn.dims, dimensions);
    int dimensionsDestTemp = state.push(INT_ARRAY_TYPE);
    builder.addMoveResult(dimensionsDestTemp);
    // Push the class object for the member type of the array.
    int classDestTemp = state.push(CLASS_TYPE);
    builder.ensureBlockForThrowingInstruction();
    builder.addConstClass(classDestTemp, memberType);
    // Create the actual multi-dimensional array using java.lang.reflect.Array::newInstance
    DexType reflectArrayClass = application.getTypeFromDescriptor(REFLECT_ARRAY_DESC);
    DexMethod newInstance = application.getMethod(reflectArrayClass,
        REFLECT_ARRAY_NEW_INSTANCE_NAME, REFLECT_ARRAY_NEW_INSTANCE_DESC);
    List<ValueType> argumentTypes = Arrays.asList(valueType(CLASS_TYPE), valueType(INT_ARRAY_TYPE));
    List<Integer> argumentRegisters = Arrays.asList(classDestTemp, dimensionsDestTemp);
    builder.ensureBlockForThrowingInstruction();
    builder.addInvoke(Invoke.Type.STATIC, newInstance, null, argumentTypes, argumentRegisters);
    // Pop the temporaries and push the final result.
    state.pop(); // classDestTemp.
    state.pop(); // dimensionsDestTemp.
    int result = state.push(arrayType);
    builder.addMoveResult(result);
    // Insert cast check to satisfy verification.
    builder.ensureBlockForThrowingInstruction();
    builder.addCheckCast(result, dexArrayType);
  }

  private void build(LineNumberNode insn, IRBuilder builder) {
    currentPosition = getCanonicalPosition(insn.line);
    builder.addDebugPosition(currentPosition);
  }

  @Override
  public Position getCanonicalDebugPositionAtOffset(int offset) {
    if (offset == EXCEPTIONAL_SYNC_EXIT_OFFSET) {
      return getExceptionalExitPosition();
    }
    int index = instructionIndex(offset);
    if (index < 0 || instructionCount() <= index) {
      assert false;
      return getPreamblePosition();
    }
    AbstractInsnNode insn = node.instructions.get(index);
    if (insn instanceof LabelNode) {
      insn = insn.getNext();
    }
    while (insn != null && !(insn instanceof LineNumberNode)) {
      insn = insn.getPrevious();
    }
    if (insn != null) {
      LineNumberNode line = (LineNumberNode) insn;
      return getCanonicalPosition(line.line);
    }
    return getPreamblePosition();
  }

  @Override
  public Position getCurrentPosition() {
    return currentPosition;
  }

  private Position getCanonicalPosition(int line) {
    return canonicalPositions.computeIfAbsent(
        line, l -> new Position(l, null, originalMethod, callerPosition));
  }

  private Position getPreamblePosition() {
    if (preamblePosition == null) {
      preamblePosition = Position.synthetic(0, originalMethod, null);
    }
    return preamblePosition;
  }

  // If we need to emit a synthetic position for exceptional monitor exits, we try to cook up a
  // position that is not actually a valid program position, so as not to incorrectly position the
  // user on an exit that is not the actual exit being taken. Our heuristic for this is that if the
  // method has at least two positions we use the first position minus one as the synthetic exit.
  // If the method only has one position it is safe to just use that position.
  private Position getExceptionalExitPosition() {
    if (syntheticPosition == null) {
      if (debug) {
        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;
        for (Iterator it = node.instructions.iterator(); it.hasNext(); ) {
          Object insn = it.next();
          if (insn instanceof LineNumberNode) {
            LineNumberNode lineNode = (LineNumberNode) insn;
            min = Math.min(min, lineNode.line);
            max = Math.max(max, lineNode.line);
          }
        }
        syntheticPosition =
            (min == Integer.MAX_VALUE)
                ? getPreamblePosition()
                : Position.synthetic(min < max ? min - 1 : min, originalMethod, callerPosition);
      } else {
        // If in release mode we explicitly associate a synthetic none position with monitor exit.
        // This is safe as the runtime must never throw at this position because the monitor cannot
        // be null and the thread calling exit can only be the same thread that entered the monitor
        // at method entry.
        syntheticPosition = Position.syntheticNone();
      }
    }
    return syntheticPosition;
  }

  // Printing helpers.

  @Override
  public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("node.name = [").append(node.name).append("]");
    builder.append("\n");
    builder.append("node.desc = ").append(node.desc);
    builder.append("\n");
    builder.append("node.maxStack = ").append(node.maxStack);
    builder.append("\n");
    builder.append("node.maxLocals = ").append(node.maxLocals);
    builder.append("\n");
    builder.append("node.locals.size = ").append(node.localVariables.size());
    builder.append("\n");
    builder.append("node.insns.size = ").append(node.instructions.size());
    builder.append("\n");
    for (int i = 0; i < parameterTypes.size(); i++) {
      builder.append("arg ").append(i).append(", type: ").append(parameterTypes.get(i))
          .append("\n");
    }
    for (int i = 0; i < node.localVariables.size(); i++) {
      LocalVariableNode local = (LocalVariableNode) node.localVariables.get(i);
      builder.append("local ").append(i)
          .append(", name: ").append(local.name)
          .append(", desc: ").append(local.desc)
          .append(", index: ").append(local.index)
          .append(", [").append(getOffset(local.start))
          .append("..").append(getOffset(local.end))
          .append("[\n");
    }
    for (int i = 0; i < node.tryCatchBlocks.size(); i++) {
      TryCatchBlockNode tryCatchBlockNode = (TryCatchBlockNode) node.tryCatchBlocks.get(i);
      builder.append("[").append(getOffset(tryCatchBlockNode.start))
          .append("..").append(getOffset(tryCatchBlockNode.end)).append("[ ")
          .append(tryCatchBlockNode.type).append(" -> ")
          .append(getOffset(tryCatchBlockNode.handler))
          .append("\n");
    }
    for (int i = 0; i < node.instructions.size(); i++) {
      AbstractInsnNode insn = node.instructions.get(i);
      builder.append(String.format("%4d: ", i)).append(instructionToString(insn));
    }
    return builder.toString();
  }

  private String instructionToString(AbstractInsnNode insn) {
    if (printVisitor == null) {
      printVisitor = new TraceMethodVisitor(new Textifier());
    }
    insn.accept(printVisitor);
    StringWriter writer = new StringWriter();
    printVisitor.p.print(new PrintWriter(writer));
    printVisitor.p.getText().clear();
    return writer.toString();
  }

  public static boolean isCallToPolymorphicSignatureMethod(String owner, String name) {
    if (owner.equals("java/lang/invoke/MethodHandle")) {
      switch (name) {
        case "invoke":
        case "invokeExact":
          return true;
        default :
          return false;
      }
    } else if (owner.equals("java/lang/invoke/VarHandle")) {
      switch (name) {
        case "compareAndExchange":
        case "compareAndExchangeAcquire":
        case "compareAndExchangeRelease":
        case "compareAndSet":
        case "get":
        case "getAcquire":
        case "getAndAdd":
        case "getAndAddAcquire":
        case "getAndAddRelease":
        case "getAndBitwiseAnd":
        case "getAndBitwiseAndAcquire":
        case "getAndBitwiseAndRelease":
        case "getAndBitwiseOr":
        case "getAndBitwiseOrAcquire":
        case "getAndBitwiseOrRelease":
        case "getAndBitwiseXor":
        case "getAndBitwiseXorAcquire":
        case "getAndBitwiseXorRelease":
        case "getAndSet":
        case "getAndSetAcquire":
        case "getAndSetRelease":
        case "getOpaque":
        case "getVolatile":
        case "set":
        case "setOpaque":
        case "setRelease":
        case "setVolatile":
        case "weakCompareAndSet":
        case "weakCompareAndSetAcquire":
        case "weakCompareAndSetPlain":
        case "weakCompareAndSetRelease":
          return true;
        default :
          return false;
      }
    }
    return false;
  }
}
