src/main/java/org/plumelib/bcelutil/StackVer.java
public VerificationResult do_stack_ver(MethodGen mg) {
    /* This code is not needed for StackVer.
    if (!myOwner.doPass3a(method_no).equals(VerificationResult.VR_OK)) {
      return VerificationResult.VR_NOTYET;
    }

    // Pass 3a ran before, so it's safe to assume the JavaClass object is
    // in the BCEL repository.
    JavaClass jc;
    try {
      jc = Repository.lookupClass(myOwner.getClassName());
    } catch (final ClassNotFoundException e) {
      // FIXME: maybe not the best way to handle this
      throw new AssertionViolatedException("Missing class: " + e, e);
    }
    */

    final ConstantPoolGen constantPoolGen = mg.getConstantPool();
    // Init Visitors
    final InstConstraintVisitor icv = new NoConstraintsVisitor();
    icv.setConstantPoolGen(constantPoolGen);

    final ExecutionVisitor ev = new ExecutionVisitor();
    ev.setConstantPoolGen(constantPoolGen);

    try {
      stack_types = new StackTypes(mg);

      icv.setMethodGen(mg);

      ////////////// DFA BEGINS HERE ////////////////
      if (!(mg.isAbstract() || mg.isNative())) { // IF mg HAS CODE (See pass 2)

        // false says don't check if jsr subroutine is covered by exception handler
        final ControlFlowGraph cfg = new ControlFlowGraph(mg, false);

        // Build the initial frame situation for this method.
        final Frame f = new Frame(mg.getMaxLocals(), mg.getMaxStack());
        if (!mg.isStatic()) {
          if (mg.getName().equals(Const.CONSTRUCTOR_NAME)) {
            Frame.setThis(new UninitializedObjectType(new ObjectType(mg.getClassName())));
            f.getLocals().set(0, Frame.getThis());
          } else {
            @SuppressWarnings("nullness") // unannotated: org.apache.bcel.verifier.structurals.Frame
            @NonNull UninitializedObjectType dummy = null;
            Frame.setThis(dummy);
            f.getLocals().set(0, new ObjectType(mg.getClassName()));
          }
        }
        final Type[] argtypes = mg.getArgumentTypes();
        int twoslotoffset = 0;
        for (int j = 0; j < argtypes.length; j++) {
          if (argtypes[j] == Type.SHORT
              || argtypes[j] == Type.BYTE
              || argtypes[j] == Type.CHAR
              || argtypes[j] == Type.BOOLEAN) {
            argtypes[j] = Type.INT;
          }
          f.getLocals().set(twoslotoffset + j + (mg.isStatic() ? 0 : 1), argtypes[j]);
          if (argtypes[j].getSize() == 2) {
            twoslotoffset++;
            f.getLocals().set(twoslotoffset + j + (mg.isStatic() ? 0 : 1), Type.UNKNOWN);
          }
        }
        circulationPump(mg, cfg, cfg.contextOf(mg.getInstructionList().getStart()), f, icv, ev);
      }
    } catch (final VerifierConstraintViolatedException ce) {
      ce.extendMessage("Constraint violated in method '" + mg + "':\n", "");
      return new VerificationResult(VerificationResult.VERIFIED_REJECTED, ce.getMessage());
    } catch (final RuntimeException re) {
      // These are internal errors

      final StringWriter sw = new StringWriter();
      final PrintWriter pw = new PrintWriter(sw);
      re.printStackTrace(pw);

      throw new AssertionViolatedException(
          "Some RuntimeException occured while verify()ing class '"
              + mg.getClassName()
              + "', method '"
              + mg
              + "'. Original RuntimeException's stack trace:\n---\n"
              + sw
              + "---\n",
          re);
    }
    return VerificationResult.VR_OK;
  }
public VerificationResult do_stack_ver(MethodGen mg) {
    /* This code is not needed for StackVer.
    if (!myOwner.doPass3a(method_no).equals(VerificationResult.VR_OK)) {
      return VerificationResult.VR_NOTYET;
    }

    // Pass 3a ran before, so it's safe to assume the JavaClass object is
    // in the BCEL repository.
    JavaClass jc;
    try {
      jc = Repository.lookupClass(myOwner.getClassName());
    } catch (final ClassNotFoundException e) {
      // FIXME: maybe not the best way to handle this
      throw new AssertionViolatedException("Missing class: " + e, e);
    }
    */

    final ConstantPoolGen constantPoolGen = mg.getConstantPool();
    // Init Visitors
    final InstConstraintVisitor icv = new NoConstraintsVisitor();
    icv.setConstantPoolGen(constantPoolGen);

    final ExecutionVisitor ev = new ExecutionVisitor();
    ev.setConstantPoolGen(constantPoolGen);

    try {
      stack_types = new StackTypes(mg);

      icv.setMethodGen(mg);

      ////////////// DFA BEGINS HERE ////////////////
      if (!(mg.isAbstract() || mg.isNative())) { // IF mg HAS CODE (See pass 2)

        // false says don't check if jsr subroutine is covered by exception handler
        final ControlFlowGraph cfg = new ControlFlowGraph(mg, false);

        // Build the initial frame situation for this method.
        final Frame f = new Frame(mg.getMaxLocals(), mg.getMaxStack());
        if (!mg.isStatic()) {
          if (mg.getName().equals(Const.CONSTRUCTOR_NAME)) {
            Frame.setThis(new UninitializedObjectType(new ObjectType(mg.getClassName())));
            f.getLocals().set(0, Frame.getThis());
          } else {
            @SuppressWarnings("nullness") // unannotated: org.apache.bcel.verifier.structurals.Frame
            @NonNull UninitializedObjectType dummy = null;
            Frame.setThis(dummy);
            f.getLocals().set(0, new ObjectType(mg.getClassName()));
          }
        }
        final Type[] argtypes = mg.getArgumentTypes();
        int twoslotoffset = 0;
        for (int j = 0; j < argtypes.length; j++) {
          if (argtypes[j] == Type.SHORT
              || argtypes[j] == Type.BYTE
              || argtypes[j] == Type.CHAR
              || argtypes[j] == Type.BOOLEAN) {
            argtypes[j] = Type.INT;
          }
          f.getLocals().set(twoslotoffset + j + (mg.isStatic() ? 0 : 1), argtypes[j]);
          if (argtypes[j].getSize() == 2) {
            twoslotoffset++;
            f.getLocals().set(twoslotoffset + j + (mg.isStatic() ? 0 : 1), Type.UNKNOWN);
          }
        }
        circulationPump(mg, cfg, cfg.contextOf(mg.getInstructionList().getStart()), f, icv, ev);
      }
    } catch (final VerifierConstraintViolatedException ce) {
      ce.extendMessage("Constraint violated in method '" + mg + "':\n", "");
      return new VerificationResult(VerificationResult.VERIFIED_REJECTED, ce.getMessage());
    } catch (final RuntimeException re) {
      // These are internal errors

      final StringWriter sw = new StringWriter();
      final PrintWriter pw = new PrintWriter(sw);
      re.printStackTrace(pw);

      throw new AssertionViolatedException(
          "Some RuntimeException occured while verify()ing class '"
              + mg.getClassName()
              + "', method '"
              + mg
              + "'. Original RuntimeException's stack trace:\n---\n"
              + sw
              + "---\n",
          re);
    }
    return VerificationResult.VR_OK;
  }
Pass 3b implements the data flow analysis as described in the Java Virtual Machine
Specification, Second Edition. Later versions will use LocalVariablesInfo objects to verify if
the verifier-inferred types and the class file's debug information (LocalVariables attributes)
match [TODO].

@param mg MethodGen for the method to be verified
@return the VerificationResult
@see org.apache.bcel.verifier.statics.LocalVariablesInfo
@see org.apache.bcel.verifier.statics.Pass2Verifier#getLocalVariablesInfo(int)