This is an automated email from the ASF dual-hosted git repository.

garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-bcel.git


The following commit(s) were added to refs/heads/master by this push:
     new 70c561a4 Reduce the copy-pasta fiesta.
70c561a4 is described below

commit 70c561a4771b6f8df321d32193f3f0c08adf97a8
Author: Gary Gregory <[email protected]>
AuthorDate: Wed Jul 15 13:47:29 2026 -0400

    Reduce the copy-pasta fiesta.
---
 .../structurals/InstConstraintVisitor.java         | 183 +++++----------------
 1 file changed, 42 insertions(+), 141 deletions(-)

diff --git 
a/src/main/java/org/apache/bcel/verifier/structurals/InstConstraintVisitor.java 
b/src/main/java/org/apache/bcel/verifier/structurals/InstConstraintVisitor.java
index c4119b1d..91505840 100644
--- 
a/src/main/java/org/apache/bcel/verifier/structurals/InstConstraintVisitor.java
+++ 
b/src/main/java/org/apache/bcel/verifier/structurals/InstConstraintVisitor.java
@@ -48,6 +48,7 @@ import org.apache.bcel.generic.BALOAD;
 import org.apache.bcel.generic.BASTORE;
 import org.apache.bcel.generic.BIPUSH;
 import org.apache.bcel.generic.BREAKPOINT;
+import org.apache.bcel.generic.BasicType;
 import org.apache.bcel.generic.CALOAD;
 import org.apache.bcel.generic.CASTORE;
 import org.apache.bcel.generic.CHECKCAST;
@@ -268,6 +269,18 @@ public class InstConstraintVisitor extends EmptyVisitor {
         return arrayref instanceof ArrayType;
     }
 
+    private void checkArrayElementType(final BasicType expectedElementType, 
final Instruction o, final Type peek) {
+        if (Objects.equals(peek, Type.NULL)) {
+            return;
+        }
+        if (!(peek instanceof ArrayType)) {
+            constraintViolated(o, "Stack next-to-next-to-top must be of type " 
+ expectedElementType + " but is '" + peek + "'.");
+        }
+        if (!((ArrayType) peek).isElementType(expectedElementType)) {
+            constraintViolated(o, "Stack next-to-next-to-top must be of type " 
+ expectedElementType + " but is '" + peek + "'.");
+        }
+    }
+
     private void checkTypeConstraint(final Type expected, final Instruction o, 
final int depth) {
         final Type peek = stack().peek(depth);
         if (!Objects.equals(expected, peek)) {
@@ -275,14 +288,14 @@ public class InstConstraintVisitor extends EmptyVisitor {
         }
     }
 
-    private void checkTypeFloatConstraint(final Instruction o, final int 
depth) {
-        checkTypeConstraint(Type.FLOAT, o, depth);
-    }
-
     private void checkTypeDoubleConstraint(final Instruction o, final int 
depth) {
         checkTypeConstraint(Type.DOUBLE, o, depth);
     }
 
+    private void checkTypeFloatConstraint(final Instruction o, final int 
depth) {
+        checkTypeConstraint(Type.FLOAT, o, depth);
+    }
+
     private void checkTypeIntConstraint(final Instruction o, final int depth) {
         checkTypeConstraint(Type.INT, o, depth);
     }
@@ -376,6 +389,11 @@ public class InstConstraintVisitor extends EmptyVisitor {
         this.mg = mg;
     }
 
+    /*
+     * "generic"visitXXXX methods where XXXX is an interface therefore, we 
don't know the order of visiting; but we know these methods are called before 
the
+     * visitYYYY methods below
+     */
+
     /**
      * The OperandStack we're working on.
      *
@@ -385,11 +403,6 @@ public class InstConstraintVisitor extends EmptyVisitor {
         return frame.getStack();
     }
 
-    /*
-     * "generic"visitXXXX methods where XXXX is an interface therefore, we 
don't know the order of visiting; but we know these methods are called before 
the
-     * visitYYYY methods below
-     */
-
     /** Assures value is of type INT. */
     private void valueOfInt(final Instruction o, final Type value) {
         if (!value.equals(Type.INT)) {
@@ -524,12 +537,10 @@ public class InstConstraintVisitor extends EmptyVisitor {
             if (!(peek instanceof ObjectType || peek.equals(Type.NULL))) {
                 constraintViolated(o, "The 'objectref' is not of an 
(initialized) ObjectType but of type " + peek + ".");
             }
-
             // NULL is a subclass of every class, so to speak.
             if (peek.equals(Type.NULL)) {
                 return;
             }
-
             final ObjectType exc = (ObjectType) peek;
             final ObjectType throwable = (ObjectType) 
Type.getType("Ljava/lang/Throwable;");
             if (!exc.subclassOf(throwable) && !exc.equals(throwable)) {
@@ -541,6 +552,10 @@ public class InstConstraintVisitor extends EmptyVisitor {
         }
     }
 
+    /*
+    /* "special"visitXXXX methods for one type of instruction each.
+     */
+
     /**
      * Ensures the specific preconditions of the said instruction.
      */
@@ -556,10 +571,6 @@ public class InstConstraintVisitor extends EmptyVisitor {
         }
     }
 
-    /*
-    /* "special"visitXXXX methods for one type of instruction each.
-     */
-
     /**
      * Ensures the specific preconditions of the said instruction.
      */
@@ -568,7 +579,6 @@ public class InstConstraintVisitor extends EmptyVisitor {
         final Type arrayref = stack().peek(2);
         final Type index = stack().peek(1);
         final Type value = stack().peek(0);
-
         indexOfInt(o, index);
         valueOfInt(o, value);
         if (arrayrefOfArrayType(o, arrayref)
@@ -601,7 +611,6 @@ public class InstConstraintVisitor extends EmptyVisitor {
     public void visitCALOAD(final CALOAD o) {
         final Type arrayref = stack().peek(1);
         final Type index = stack().peek(0);
-
         indexOfInt(o, index);
         if (arrayrefOfArrayType(o, arrayref) && !((ArrayType) 
arrayref).isElementType(Type.CHAR)) {
             constraintViolated(o, "The 'arrayref' does not refer to an array 
with elements of type char but to an array of type "
@@ -609,6 +618,12 @@ public class InstConstraintVisitor extends EmptyVisitor {
         }
     }
 
+    /*
+     * "generic" visitYYYY methods where YYYY is a superclass.
+     * therefore, we know the order of visiting; we know
+     * these methods are called after the visitXXXX methods above.
+     */
+
     /**
      * Ensures the specific preconditions of the said instruction.
      */
@@ -617,7 +632,6 @@ public class InstConstraintVisitor extends EmptyVisitor {
         final Type arrayref = stack().peek(2);
         final Type index = stack().peek(1);
         final Type value = stack().peek(0);
-
         indexOfInt(o, index);
         valueOfInt(o, value);
         if (arrayrefOfArrayType(o, arrayref) && !((ArrayType) 
arrayref).isElementType(Type.CHAR)) {
@@ -626,12 +640,6 @@ public class InstConstraintVisitor extends EmptyVisitor {
         }
     }
 
-    /*
-     * "generic" visitYYYY methods where YYYY is a superclass.
-     * therefore, we know the order of visiting; we know
-     * these methods are called after the visitXXXX methods above.
-     */
-
     /**
      * Ensures the specific preconditions of the said instruction.
      */
@@ -704,16 +712,7 @@ public class InstConstraintVisitor extends EmptyVisitor {
     @Override
     public void visitDALOAD(final DALOAD o) {
         indexOfInt(o, stack().peek());
-        final Type peek1 = stack().peek(1);
-        if (peek1 == Type.NULL) {
-            return;
-        }
-        if (!(peek1 instanceof ArrayType)) {
-            constraintViolated(o, "Stack next-to-top must be of type double[] 
but is '" + peek1 + "'.");
-        }
-        if (!((ArrayType) peek1).isElementType(Type.DOUBLE)) {
-            constraintViolated(o, "Stack next-to-top must be of type double[] 
but is '" + peek1 + "'.");
-        }
+        checkArrayElementType(Type.DOUBLE, o, stack().peek(1));
     }
 
     /**
@@ -723,16 +722,7 @@ public class InstConstraintVisitor extends EmptyVisitor {
     public void visitDASTORE(final DASTORE o) {
         checkTypeDoubleConstraint(o, 0);
         indexOfInt(o, stack().peek(1));
-        final Type peek2 = stack().peek(2);
-        if (peek2 == Type.NULL) {
-            return;
-        }
-        if (!(peek2 instanceof ArrayType)) {
-            constraintViolated(o, "Stack next-to-next-to-top must be of type 
double[] but is '" + peek2 + "'.");
-        }
-        if (!((ArrayType) peek2).isElementType(Type.DOUBLE)) {
-            constraintViolated(o, "Stack next-to-next-to-top must be of type 
double[] but is '" + peek2 + "'.");
-        }
+        checkArrayElementType(Type.DOUBLE, o, stack().peek(2));
     }
 
     /**
@@ -984,16 +974,7 @@ public class InstConstraintVisitor extends EmptyVisitor {
     @Override
     public void visitFALOAD(final FALOAD o) {
         indexOfInt(o, stack().peek());
-        final Type peek1 = stack().peek(1);
-        if (peek1 == Type.NULL) {
-            return;
-        }
-        if (!(peek1 instanceof ArrayType)) {
-            constraintViolated(o, "Stack next-to-top must be of type float[] 
but is '" + peek1 + "'.");
-        }
-        if (!((ArrayType) peek1).isElementType(Type.FLOAT)) {
-            constraintViolated(o, "Stack next-to-top must be of type float[] 
but is '" + peek1 + "'.");
-        }
+        checkArrayElementType(Type.FLOAT, o, stack().peek(1));
     }
 
     /**
@@ -1006,16 +987,7 @@ public class InstConstraintVisitor extends EmptyVisitor {
             constraintViolated(o, "The value at the stack top is not of type 
'float', but of type '" + peek + "'.");
         }
         indexOfInt(o, stack().peek(1));
-        final Type peek2 = stack().peek(2);
-        if (peek2 == Type.NULL) {
-            return;
-        }
-        if (!(peek2 instanceof ArrayType)) {
-            constraintViolated(o, "Stack next-to-next-to-top must be of type 
float[] but is '" + peek2 + "'.");
-        }
-        if (!((ArrayType) peek2).isElementType(Type.FLOAT)) {
-            constraintViolated(o, "Stack next-to-next-to-top must be of type 
float[] but is '" + peek2 + "'.");
-        }
+        checkArrayElementType(Type.FLOAT, o, stack().peek(2));
     }
 
     /**
@@ -1183,7 +1155,6 @@ public class InstConstraintVisitor extends EmptyVisitor {
             if (!(objectref instanceof ObjectType || objectref == Type.NULL)) {
                 constraintViolated(o, "Stack top should be an object reference 
that's not an array reference, but is '" + objectref + "'.");
             }
-
             final String fieldName = o.getFieldName(cpg);
 
             final JavaClass jc = 
Repository.lookupClass(getObjectType(o).getClassName());
@@ -1191,11 +1162,9 @@ public class InstConstraintVisitor extends EmptyVisitor {
             if (f == null) {
                 throw new AssertionViolatedException("Field '" + fieldName + 
"' not found in " + jc.getClassName());
             }
-
             if (f.isProtected()) {
                 final ObjectType classtype = getObjectType(o);
                 final ObjectType curr = 
ObjectType.getInstance(mg.getClassName());
-
                 if (classtype.equals(curr) || curr.subclassOf(classtype)) {
                     final Type t = stack().peek();
                     if (t == Type.NULL) {
@@ -1216,12 +1185,10 @@ public class InstConstraintVisitor extends EmptyVisitor 
{
                     //}
                 }
             }
-
             // TODO: Could go into Pass 3a.
             if (f.isStatic()) {
                 constraintViolated(o, "Referenced field '" + f + "' is static 
which it shouldn't be.");
             }
-
         } catch (final ClassNotFoundException e) {
             // FIXME: maybe not the best way to handle this
             throw new AssertionViolatedException("Missing class: " + e, e);
@@ -1315,15 +1282,7 @@ public class InstConstraintVisitor extends EmptyVisitor {
     @Override
     public void visitIALOAD(final IALOAD o) {
         indexOfInt(o, stack().peek());
-        if (stack().peek(1) == Type.NULL) {
-            return;
-        }
-        if (!(stack().peek(1) instanceof ArrayType)) {
-            constraintViolated(o, "Stack next-to-top must be of type int[] but 
is '" + stack().peek(1) + "'.");
-        }
-        if (!((ArrayType) stack().peek(1)).isElementType(Type.INT)) {
-            constraintViolated(o, "Stack next-to-top must be of type int[] but 
is '" + stack().peek(1) + "'.");
-        }
+        checkArrayElementType(Type.INT, o, stack().peek(1));
     }
 
     /**
@@ -1342,15 +1301,7 @@ public class InstConstraintVisitor extends EmptyVisitor {
     public void visitIASTORE(final IASTORE o) {
         checkTypeIntConstraint(o, 0);
         indexOfInt(o, stack().peek(1));
-        if (stack().peek(2) == Type.NULL) {
-            return;
-        }
-        if (!(stack().peek(2) instanceof ArrayType)) {
-            constraintViolated(o, "Stack next-to-next-to-top must be of type 
int[] but is '" + stack().peek(2) + "'.");
-        }
-        if (!((ArrayType) stack().peek(2)).isElementType(Type.INT)) {
-            constraintViolated(o, "Stack next-to-next-to-top must be of type 
int[] but is '" + stack().peek(2) + "'.");
-        }
+        checkArrayElementType(Type.INT, o, stack().peek(2));
     }
 
     /**
@@ -1379,12 +1330,10 @@ public class InstConstraintVisitor extends EmptyVisitor 
{
             constraintViolated(o, "The value at the stack top is not of a 
ReferenceType, but of type '" + stack().peek() + "'.");
         }
         // referenceTypeIsInitialized(o, (ReferenceType) (stack().peek()) );
-
         if (!(stack().peek(1) instanceof ReferenceType)) {
             constraintViolated(o, "The value at the stack next-to-top is not 
of a ReferenceType, but of type '" + stack().peek(1) + "'.");
         }
         // referenceTypeIsInitialized(o, (ReferenceType) (stack().peek(1)) );
-
     }
 
     /**
@@ -1535,7 +1484,6 @@ public class InstConstraintVisitor extends EmptyVisitor {
         if (locals().maxLocals() <= (o.getType(cpg).getSize() == 1 ? 
o.getIndex() : o.getIndex() + 1)) {
             constraintViolated(o, "The 'index' is not a valid index into the 
local variable array.");
         }
-
         indexOfInt(o, locals().get(o.getIndex()));
     }
 
@@ -1629,7 +1577,6 @@ public class InstConstraintVisitor extends EmptyVisitor {
     @Override
     public void visitINVOKEINTERFACE(final INVOKEINTERFACE o) {
         // Method is not native, otherwise pass 3 would not happen.
-
         final int count = o.getCount();
         if (count == 0) {
             constraintViolated(o, "The 'count' argument must not be 0.");
@@ -1637,9 +1584,7 @@ public class InstConstraintVisitor extends EmptyVisitor {
         // It is a ConstantInterfaceMethodref, Pass 3a made it sure.
         // TODO: Do we want to do anything with it?
         // ConstantInterfaceMethodref cimr = (ConstantInterfaceMethodref) 
(cpg.getConstant(o.getIndex()));
-
         // the o.getClassType(cpg) type has passed pass 2; see 
visitLoadClass(o).
-
         final Type t = o.getType(cpg);
         if (t instanceof ObjectType) {
             final String name = ((ObjectType) t).getClassName();
@@ -1649,10 +1594,8 @@ public class InstConstraintVisitor extends EmptyVisitor {
                 constraintViolated(o, "Class '" + name + "' is referenced, but 
cannot be loaded and resolved: '" + vr + "'.");
             }
         }
-
         final Type[] argTypes = o.getArgumentTypes(cpg);
         final int argCount = argTypes.length;
-
         for (int i = argCount - 1; i >= 0; i--) {
             final Type fromStack = stack().peek(argCount - 1 - i); // 0 to 
argCount - 1
             Type fromDesc = argTypes[i];
@@ -1675,7 +1618,6 @@ public class InstConstraintVisitor extends EmptyVisitor {
                 }
             }
         }
-
         Type objRef = stack().peek(argCount);
         if (objRef == Type.NULL) {
             return;
@@ -1691,7 +1633,6 @@ public class InstConstraintVisitor extends EmptyVisitor {
                 objRef = GENERIC_ARRAY;
             }
         }
-
         // String objRefClassName = ((ObjectType) objRef).getClassName();
         // String theInterface = o.getClassName(cpg);
         // TODO: This can only be checked if we're using Staerk-et-al's "set 
of object types"
@@ -1699,7 +1640,6 @@ public class InstConstraintVisitor extends EmptyVisitor {
         // if ( ! Repository.implementationOf(objRefClassName, theInterface) ) 
{
         // constraintViolated(o, "The 'objRef' item '" + objRef + "' does not 
implement '" + theInterface + "' as expected.");
         // }
-
         int countedCount = 1; // 1 for the objectref
         for (int i = 0; i < argCount; i++) {
             countedCount += argTypes[i].getSize();
@@ -1719,7 +1659,6 @@ public class InstConstraintVisitor extends EmptyVisitor {
                 constraintViolated(o, "Class '" + name + "' is referenced, but 
cannot be loaded and resolved: '" + vr + "'.");
             }
         }
-
         final Type[] argtypes = o.getArgumentTypes(cpg);
         final int nargs = argtypes.length;
 
@@ -1762,9 +1701,7 @@ public class InstConstraintVisitor extends EmptyVisitor {
                         + " during a backwards branch, or in a local variable 
in code protected by an exception handler."
                         + " Please see The Java Virtual Machine Specification, 
Second Edition, 4.9.4 (pages 147 and 148) for details.");
             }
-
             // the o.getClassType(cpg) type has passed pass 2; see 
visitLoadClass(o).
-
             final int nargs = visitInvokeInternals(o);
             Type objref = stack().peek(nargs);
             if (objref == Type.NULL) {
@@ -1842,11 +1779,8 @@ public class InstConstraintVisitor extends EmptyVisitor {
                     objref = GENERIC_ARRAY;
                 }
             }
-
             final String objRefClassName = ((ObjectType) 
objref).getClassName();
-
             final String theClass = o.getClassName(cpg);
-
             if (objref != GENERIC_ARRAY && 
!Repository.instanceOf(objRefClassName, theClass)) {
                 constraintViolated(o, "The 'objref' item '" + objref + "' does 
not implement '" + theClass + "' as expected.");
             }
@@ -1906,7 +1840,6 @@ public class InstConstraintVisitor extends EmptyVisitor {
     @Override
     public void visitISTORE(final ISTORE o) {
         // visitStoreInstruction(StoreInstruction) is called before.
-
         // Nothing else needs to be done here.
     }
 
@@ -1992,15 +1925,7 @@ public class InstConstraintVisitor extends EmptyVisitor {
     @Override
     public void visitLALOAD(final LALOAD o) {
         indexOfInt(o, stack().peek());
-        if (stack().peek(1) == Type.NULL) {
-            return;
-        }
-        if (!(stack().peek(1) instanceof ArrayType)) {
-            constraintViolated(o, "Stack next-to-top must be of type long[] 
but is '" + stack().peek(1) + "'.");
-        }
-        if (!((ArrayType) stack().peek(1)).isElementType(Type.LONG)) {
-            constraintViolated(o, "Stack next-to-top must be of type long[] 
but is '" + stack().peek(1) + "'.");
-        }
+        checkArrayElementType(Type.LONG, o, stack().peek(1));
     }
 
     /**
@@ -2019,15 +1944,7 @@ public class InstConstraintVisitor extends EmptyVisitor {
     public void visitLASTORE(final LASTORE o) {
         checkTypeLongConstraint(o, 0);
         indexOfInt(o, stack().peek(1));
-        if (stack().peek(2) == Type.NULL) {
-            return;
-        }
-        if (!(stack().peek(2) instanceof ArrayType)) {
-            constraintViolated(o, "Stack next-to-next-to-top must be of type 
long[] but is '" + stack().peek(2) + "'.");
-        }
-        if (!((ArrayType) stack().peek(2)).isElementType(Type.LONG)) {
-            constraintViolated(o, "Stack next-to-next-to-top must be of type 
long[] but is '" + stack().peek(2) + "'.");
-        }
+        checkArrayElementType(Type.LONG, o, stack().peek(2));
     }
 
     /**
@@ -2518,15 +2435,7 @@ public class InstConstraintVisitor extends EmptyVisitor {
     @Override
     public void visitSALOAD(final SALOAD o) {
         indexOfInt(o, stack().peek());
-        if (stack().peek(1) == Type.NULL) {
-            return;
-        }
-        if (!(stack().peek(1) instanceof ArrayType)) {
-            constraintViolated(o, "Stack next-to-top must be of type short[] 
but is '" + stack().peek(1) + "'.");
-        }
-        if (!((ArrayType) stack().peek(1)).isElementType(Type.SHORT)) {
-            constraintViolated(o, "Stack next-to-top must be of type short[] 
but is '" + stack().peek(1) + "'.");
-        }
+        checkArrayElementType(Type.SHORT, o, stack().peek(1));
     }
 
     /**
@@ -2536,15 +2445,7 @@ public class InstConstraintVisitor extends EmptyVisitor {
     public void visitSASTORE(final SASTORE o) {
         checkTypeIntConstraint(o, 0);
         indexOfInt(o, stack().peek(1));
-        if (stack().peek(2) == Type.NULL) {
-            return;
-        }
-        if (!(stack().peek(2) instanceof ArrayType)) {
-            constraintViolated(o, "Stack next-to-next-to-top must be of type 
short[] but is '" + stack().peek(2) + "'.");
-        }
-        if (!((ArrayType) stack().peek(2)).isElementType(Type.SHORT)) {
-            constraintViolated(o, "Stack next-to-next-to-top must be of type 
short[] but is '" + stack().peek(2) + "'.");
-        }
+        checkArrayElementType(Type.SHORT, o, stack().peek(2));
     }
 
     /**

Reply via email to