@Override public Size apply( MethodVisitor methodVisitor, Context implementationContext, MethodDescription instrumentedMethod) { StackManipulation thisReference = MethodVariableAccess.forType(instrumentedType).loadOffset(0); FieldList<?> fieldList = instrumentedType.getDeclaredFields(); StackManipulation[] fieldLoading = new StackManipulation[fieldList.size()]; int index = 0; for (FieldDescription fieldDescription : fieldList) { fieldLoading[index++] = new StackManipulation.Compound( thisReference, FieldAccess.forField(fieldDescription).getter()); } StackManipulation.Size stackSize = new StackManipulation.Compound( new StackManipulation.Compound(fieldLoading), MethodInvocation.invoke(accessorMethod), assigner.assign( accessorMethod.getReturnType().asErasure(), instrumentedMethod.getReturnType().asErasure(), Assigner.Typing.DYNAMIC), MethodReturn.returning(instrumentedMethod.getReturnType().asErasure())) .apply(methodVisitor, implementationContext); return new Size(stackSize.getMaximalSize(), instrumentedMethod.getStackSize()); }
@Override public Size apply( MethodVisitor methodVisitor, Context implementationContext, MethodDescription instrumentedMethod) { StackManipulation thisReference = MethodVariableAccess.REFERENCE.loadOffset(0); FieldList<?> fieldList = instrumentedType.getDeclaredFields(); StackManipulation[] fieldLoading = new StackManipulation[fieldList.size()]; int index = 0; for (FieldDescription fieldDescription : fieldList) { fieldLoading[index] = new StackManipulation.Compound( thisReference, MethodVariableAccess.forType(fieldDescription.getType().asErasure()) .loadOffset(instrumentedMethod.getParameters().get(index).getOffset()), FieldAccess.forField(fieldDescription).putter()); index++; } StackManipulation.Size stackSize = new StackManipulation.Compound( thisReference, MethodInvocation.invoke(ConstructorCall.INSTANCE.objectTypeDefaultConstructor), new StackManipulation.Compound(fieldLoading), MethodReturn.VOID) .apply(methodVisitor, implementationContext); return new Size(stackSize.getMaximalSize(), instrumentedMethod.getStackSize()); }
public Size apply( MethodVisitor methodVisitor, Implementation.Context implementationContext, MethodDescription instrumentedMethod) { checkMethodSignature(instrumentedMethod); try { StackManipulation stack = buildStack(); StackManipulation.Size finalStackSize = stack.apply(methodVisitor, implementationContext); return new Size( finalStackSize.getMaximalSize(), instrumentedMethod.getStackSize() + 2); // 2 stack slots for a single local variable } catch (NoSuchMethodException | NoSuchFieldException e) { throw new RuntimeException(e); } }
/** * Blueprint method that for applying the actual implementation. * * @param methodVisitor The method visitor to which the implementation is applied to. * @param implementationContext The implementation context for the given implementation. * @param instrumentedMethod The instrumented method that is target of the implementation. * @param fixedValueType A description of the type of the fixed value that is loaded by the {@code * valueLoadingInstruction}. * @param valueLoadingInstruction A stack manipulation that represents the loading of the fixed * value onto the operand stack. * @return A representation of the stack and variable array sized that are required for this * implementation. */ protected ByteCodeAppender.Size apply( MethodVisitor methodVisitor, Context implementationContext, MethodDescription instrumentedMethod, TypeDescription.Generic fixedValueType, StackManipulation valueLoadingInstruction) { StackManipulation assignment = assigner.assign(fixedValueType, instrumentedMethod.getReturnType(), typing); if (!assignment.isValid()) { throw new IllegalArgumentException( "Cannot return value of type " + fixedValueType + " for " + instrumentedMethod); } StackManipulation.Size stackSize = new StackManipulation.Compound( valueLoadingInstruction, assignment, MethodReturn.returning(instrumentedMethod.getReturnType().asErasure())) .apply(methodVisitor, implementationContext); return new ByteCodeAppender.Size(stackSize.getMaximalSize(), instrumentedMethod.getStackSize()); }