protected void init()

in asm-util/src/main/java/org/objectweb/asm/util/CheckFrameAnalyzer.java [118:218]


  protected void init(final String owner, final MethodNode method) throws AnalyzerException {
    insnList = method.instructions;
    currentLocals = Type.getArgumentsAndReturnSizes(method.desc) >> 2;
    if ((method.access & Opcodes.ACC_STATIC) != 0) {
      currentLocals -= 1;
    }

    Frame<V>[] frames = getFrames();
    Frame<V> currentFrame = frames[0];
    expandFrames(owner, method, currentFrame);
    for (int insnIndex = 0; insnIndex < insnList.size(); ++insnIndex) {
      Frame<V> oldFrame = frames[insnIndex];

      // Simulate the execution of this instruction.
      AbstractInsnNode insnNode = null;
      try {
        insnNode = method.instructions.get(insnIndex);
        int insnOpcode = insnNode.getOpcode();
        int insnType = insnNode.getType();

        if (insnType == AbstractInsnNode.LABEL
            || insnType == AbstractInsnNode.LINE
            || insnType == AbstractInsnNode.FRAME) {
          checkFrame(insnIndex + 1, oldFrame, /* requireFrame = */ false);
        } else {
          currentFrame.init(oldFrame).execute(insnNode, interpreter);

          if (insnNode instanceof JumpInsnNode) {
            if (insnOpcode == JSR) {
              throw new AnalyzerException(insnNode, "JSR instructions are unsupported");
            }
            JumpInsnNode jumpInsn = (JumpInsnNode) insnNode;
            int targetInsnIndex = insnList.indexOf(jumpInsn.label);
            checkFrame(targetInsnIndex, currentFrame, /* requireFrame = */ true);
            if (insnOpcode == GOTO) {
              endControlFlow(insnIndex);
            } else {
              checkFrame(insnIndex + 1, currentFrame, /* requireFrame = */ false);
            }
          } else if (insnNode instanceof LookupSwitchInsnNode) {
            LookupSwitchInsnNode lookupSwitchInsn = (LookupSwitchInsnNode) insnNode;
            int targetInsnIndex = insnList.indexOf(lookupSwitchInsn.dflt);
            checkFrame(targetInsnIndex, currentFrame, /* requireFrame = */ true);
            for (int i = 0; i < lookupSwitchInsn.labels.size(); ++i) {
              LabelNode label = lookupSwitchInsn.labels.get(i);
              targetInsnIndex = insnList.indexOf(label);
              currentFrame.initJumpTarget(insnOpcode, label);
              checkFrame(targetInsnIndex, currentFrame, /* requireFrame = */ true);
            }
            endControlFlow(insnIndex);
          } else if (insnNode instanceof TableSwitchInsnNode) {
            TableSwitchInsnNode tableSwitchInsn = (TableSwitchInsnNode) insnNode;
            int targetInsnIndex = insnList.indexOf(tableSwitchInsn.dflt);
            currentFrame.initJumpTarget(insnOpcode, tableSwitchInsn.dflt);
            checkFrame(targetInsnIndex, currentFrame, /* requireFrame = */ true);
            newControlFlowEdge(insnIndex, targetInsnIndex);
            for (int i = 0; i < tableSwitchInsn.labels.size(); ++i) {
              LabelNode label = tableSwitchInsn.labels.get(i);
              currentFrame.initJumpTarget(insnOpcode, label);
              targetInsnIndex = insnList.indexOf(label);
              checkFrame(targetInsnIndex, currentFrame, /* requireFrame = */ true);
            }
            endControlFlow(insnIndex);
          } else if (insnOpcode == RET) {
            throw new AnalyzerException(insnNode, "RET instructions are unsupported");
          } else if (insnOpcode != ATHROW && (insnOpcode < IRETURN || insnOpcode > RETURN)) {
            checkFrame(insnIndex + 1, currentFrame, /* requireFrame = */ false);
          } else {
            endControlFlow(insnIndex);
          }
        }

        List<TryCatchBlockNode> insnHandlers = getHandlers(insnIndex);
        if (insnHandlers != null) {
          for (TryCatchBlockNode tryCatchBlock : insnHandlers) {
            Type catchType;
            if (tryCatchBlock.type == null) {
              catchType = Type.getObjectType("java/lang/Throwable");
            } else {
              catchType = Type.getObjectType(tryCatchBlock.type);
            }
            Frame<V> handler = newFrame(oldFrame);
            handler.clearStack();
            handler.push(interpreter.newExceptionValue(tryCatchBlock, handler, catchType));
            checkFrame(insnList.indexOf(tryCatchBlock.handler), handler, /* requireFrame = */ true);
          }
        }

        if (!hasNextJvmInsnOrFrame(insnIndex)) {
          break;
        }
      } catch (AnalyzerException e) {
        throw new AnalyzerException(
            e.node, "Error at instruction " + insnIndex + ": " + e.getMessage(), e);
      } catch (RuntimeException e) {
        // DontCheck(IllegalCatch): can't be fixed, for backward compatibility.
        throw new AnalyzerException(
            insnNode, "Error at instruction " + insnIndex + ": " + e.getMessage(), e);
      }
    }
  }