@@ -8291,6 +8291,7 @@ protected void convertValue(MethodVisitor methodVisitor) {
82918291 * Resolves a relocation handler for a given type.
82928292 *
82938293 * @param typeDefinition The type to be resolved for a relocation attempt.
8294+ * @param index The index in the array returned by the advice method that contains the value to be checked.
82948295 * @param inverted {@code true} if the relocation should be applied for any non-default value of a type.
82958296 * @return An appropriate relocation handler.
82968297 */
@@ -8318,8 +8319,8 @@ protected static RelocationHandler of(TypeDefinition typeDefinition, int index,
83188319 skipDispatcher = REFERENCE;
83198320 }
83208321 return inverted
8321- ? skipDispatcher.new Inverted (index)
8322- : skipDispatcher.new Regular (index);
8322+ ? skipDispatcher.new OfNonDefault (index)
8323+ : skipDispatcher.new OfDefault (index);
83238324 }
83248325
83258326 /**
@@ -8330,14 +8331,22 @@ protected static RelocationHandler of(TypeDefinition typeDefinition, int index,
83308331 protected abstract void convertValue(MethodVisitor methodVisitor);
83318332
83328333 /**
8333- * An inverted version of the outer relocation handler .
8334+ * A relocation handler that checks for a value being a default value .
83348335 */
83358336 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
8336- protected class Regular implements RelocationHandler {
8337+ protected class OfDefault implements RelocationHandler {
83378338
8339+ /**
8340+ * The index of the array returned by the advice method that contains the value to check for its value.
8341+ */
83388342 private final int index;
83398343
8340- public Regular(int index) {
8344+ /**
8345+ * A relocation handler that checks if a value is a default value.
8346+ *
8347+ * @param index The index of the array returned by the advice method that contains the value to check for its value.
8348+ */
8349+ public OfDefault(int index) {
83418350 this.index = index;
83428351 }
83438352
@@ -8350,14 +8359,22 @@ public Bound bind(MethodDescription instrumentedMethod, Relocation relocation) {
83508359 }
83518360
83528361 /**
8353- * An inverted version of the outer relocation handler .
8362+ * A relocation handler that checks for a value being a non-default value .
83548363 */
83558364 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
8356- protected class Inverted implements RelocationHandler {
8365+ protected class OfNonDefault implements RelocationHandler {
83578366
8367+ /**
8368+ * The index of the array returned by the advice method that contains the value to check for its value.
8369+ */
83588370 private final int index;
83598371
8360- protected Inverted(int index) {
8372+ /**
8373+ * A relocation handler that checks if a value is a non-default value.
8374+ *
8375+ * @param index The index of the array returned by the advice method that contains the value to check for its value.
8376+ */
8377+ protected OfNonDefault(int index) {
83618378 this.index = index;
83628379 }
83638380
@@ -8418,13 +8435,16 @@ public int apply(MethodVisitor methodVisitor, Implementation.Context implementat
84188435 throw new IllegalStateException("Cannot skip code execution from constructor: " + instrumentedMethod);
84198436 }
84208437 Label noSkip = new Label();
8438+ int size;
84218439 if (index < 0) {
84228440 methodVisitor.visitVarInsn(load, offset);
84238441 } else {
84248442 methodVisitor.visitVarInsn(Opcodes.ALOAD, offset);
84258443 methodVisitor.visitJumpInsn(Opcodes.IFNULL, noSkip);
84268444 methodVisitor.visitVarInsn(Opcodes.ALOAD, offset);
8427- methodVisitor.visitLdcInsn(index); // TODO: index opt, size opt
8445+ size = Math.max(requiredSize, IntegerConstant.forValue(index)
8446+ .apply(methodVisitor, implementationContext)
8447+ .getMaximalSize() + 1);
84288448 methodVisitor.visitInsn(arrayLoad);
84298449 }
84308450 convertValue(methodVisitor);
@@ -8449,12 +8469,16 @@ class ForType implements RelocationHandler {
84498469 */
84508470 private final TypeDescription typeDescription;
84518471
8472+ /**
8473+ * The index of the array returned by the advice method that contains the value to check for its type.
8474+ */
84528475 private final int index;
84538476
84548477 /**
84558478 * Creates a new relocation handler that triggers a relocation if a value is an instance of a given type.
84568479 *
84578480 * @param typeDescription The type that triggers a relocation.
8481+ * @param index The index of the array returned by the advice method that contains the value to check for its type.
84588482 */
84598483 protected ForType(TypeDescription typeDescription, int index) {
84608484 this.typeDescription = typeDescription;
@@ -8466,27 +8490,26 @@ protected ForType(TypeDescription typeDescription, int index) {
84668490 *
84678491 * @param typeDescription The type that triggers a relocation.
84688492 * @param index The array index of the value that is returned.
8469- * @param checkedType The type that is carrying the checked value .
8493+ * @param returnedType The type that is returned by the advice method .
84708494 * @return An appropriate relocation handler.
84718495 */
84728496 @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = "Assuming component type for array type.")
8473- protected static RelocationHandler of(TypeDescription typeDescription, int index, TypeDefinition checkedType ) {
8474- TypeDefinition target ;
8497+ protected static RelocationHandler of(TypeDescription typeDescription, int index, TypeDefinition returnedType ) {
8498+ TypeDefinition targetType ;
84758499 if (index < 0) {
8476- target = checkedType ;
8477- } else if (checkedType .isArray()) {
8478- target = checkedType .getComponentType();
8500+ targetType = returnedType ;
8501+ } else if (returnedType .isArray()) {
8502+ targetType = returnedType .getComponentType();
84798503 } else {
8480- throw new IllegalStateException();
8504+ throw new IllegalStateException(returnedType + " is not an array type but an index for a relocation is defined" );
84818505 }
8482- // TODO: index for array
84838506 if (typeDescription.represents(void.class)) {
84848507 return Disabled.INSTANCE;
84858508 } else if (typeDescription.represents(OnDefaultValue.class)) {
8486- return ForValue.of(checkedType , index, false);
8509+ return ForValue.of(targetType , index, false);
84878510 } else if (typeDescription.represents(OnNonDefaultValue.class)) {
8488- return ForValue.of(target , index, true);
8489- } else if (typeDescription.isPrimitive() || target .isPrimitive()) {
8511+ return ForValue.of(targetType , index, true);
8512+ } else if (typeDescription.isPrimitive() || targetType .isPrimitive()) {
84908513 throw new IllegalStateException("Cannot relocate execution by instance type for primitive type");
84918514 } else {
84928515 return new ForType(typeDescription, index);
@@ -8536,17 +8559,22 @@ public int apply(MethodVisitor methodVisitor, Implementation.Context implementat
85368559 }
85378560 methodVisitor.visitVarInsn(Opcodes.ALOAD, offset);
85388561 Label noSkip = new Label();
8539- if (index >= 0) {
8562+ int size;
8563+ if (index < 0) {
8564+ size = NO_REQUIRED_SIZE;
8565+ } else {
85408566 methodVisitor.visitJumpInsn(Opcodes.IFNULL, noSkip);
85418567 methodVisitor.visitVarInsn(Opcodes.ALOAD, offset);
8542- methodVisitor.visitLdcInsn(index); // TODO: offset
8568+ size = IntegerConstant.forValue(index)
8569+ .apply(methodVisitor, implementationContext)
8570+ .getMaximalSize() + 1;
85438571 methodVisitor.visitInsn(Opcodes.AALOAD);
85448572 }
85458573 methodVisitor.visitTypeInsn(Opcodes.INSTANCEOF, typeDescription.getInternalName());
85468574 methodVisitor.visitJumpInsn(Opcodes.IFEQ, noSkip);
85478575 relocation.apply(methodVisitor);
85488576 methodVisitor.visitLabel(noSkip);
8549- return NO_REQUIRED_SIZE ;
8577+ return size ;
85508578 }
85518579 }
85528580 }
@@ -8665,12 +8693,13 @@ abstract class AbstractBase implements Resolved {
86658693 /**
86668694 * Creates a new resolved version of a dispatcher.
86678695 *
8668- * @param adviceMethod The represented advice method.
8669- * @param postProcessor The post processor to use.
8670- * @param factories A list of factories to resolve for the parameters of the advice method.
8671- * @param throwableType The type to handle by a suppression handler or {@link NoExceptionHandler} to not handle any exceptions.
8672- * @param relocatableType The type to trigger a relocation of the method's control flow or {@code void} if no relocation should be executed.
8673- * @param adviceType The applied advice type.
8696+ * @param adviceMethod The represented advice method.
8697+ * @param postProcessor The post processor to use.
8698+ * @param factories A list of factories to resolve for the parameters of the advice method.
8699+ * @param throwableType The type to handle by a suppression handler or {@link NoExceptionHandler} to not handle any exceptions.
8700+ * @param relocatableType The type to trigger a relocation of the method's control flow or {@code void} if no relocation should be executed.
8701+ * @param relocatableIndex The index within an array that is returned by the advice method, indicating the value to consider for relocation.
8702+ * @param adviceType The applied advice type.
86748703 */
86758704 protected AbstractBase(MethodDescription.InDefinedShape adviceMethod,
86768705 PostProcessor postProcessor,
@@ -8981,12 +9010,13 @@ protected abstract static class Resolved extends Dispatcher.Resolved.AbstractBas
89819010 /**
89829011 * Creates a new resolved version of a dispatcher.
89839012 *
8984- * @param adviceMethod The represented advice method.
8985- * @param postProcessor The post processor to apply.
8986- * @param factories A list of factories to resolve for the parameters of the advice method.
8987- * @param throwableType The type to handle by a suppression handler or {@link NoExceptionHandler} to not handle any exceptions.
8988- * @param relocatableType The type to trigger a relocation of the method's control flow or {@code void} if no relocation should be executed.
8989- * @param classReader A class reader to query for the class file of the advice method.
9013+ * @param adviceMethod The represented advice method.
9014+ * @param postProcessor The post processor to apply.
9015+ * @param factories A list of factories to resolve for the parameters of the advice method.
9016+ * @param throwableType The type to handle by a suppression handler or {@link NoExceptionHandler} to not handle any exceptions.
9017+ * @param relocatableType The type to trigger a relocation of the method's control flow or {@code void} if no relocation should be executed.
9018+ * @param relocatableIndex The index within an array that is returned by the advice method, indicating the value to consider for relocation.
9019+ * @param classReader A class reader to query for the class file of the advice method.
89909020 */
89919021 protected Resolved(MethodDescription.InDefinedShape adviceMethod,
89929022 PostProcessor postProcessor,
@@ -10402,12 +10432,13 @@ protected abstract static class Resolved extends Dispatcher.Resolved.AbstractBas
1040210432 /**
1040310433 * Creates a new resolved version of a dispatcher.
1040410434 *
10405- * @param adviceMethod The represented advice method.
10406- * @param postProcessor The post processor to apply.
10407- * @param factories A list of factories to resolve for the parameters of the advice method.
10408- * @param throwableType The type to handle by a suppression handler or {@link NoExceptionHandler} to not handle any exceptions.
10409- * @param relocatableType The type to trigger a relocation of the method's control flow or {@code void} if no relocation should be executed.
10410- * @param delegator The delegator to use.
10435+ * @param adviceMethod The represented advice method.
10436+ * @param postProcessor The post processor to apply.
10437+ * @param factories A list of factories to resolve for the parameters of the advice method.
10438+ * @param throwableType The type to handle by a suppression handler or {@link NoExceptionHandler} to not handle any exceptions.
10439+ * @param relocatableType The type to trigger a relocation of the method's control flow or {@code void} if no relocation should be executed.
10440+ * @param relocatableIndex The index within an array that is returned by the advice method, indicating the value to consider for relocation.
10441+ * @param delegator The delegator to use.
1041110442 */
1041210443 protected Resolved(MethodDescription.InDefinedShape adviceMethod,
1041310444 PostProcessor postProcessor,
0 commit comments