pushNull(); pushNull(); } else if (opcode == ARETURN) { dup(); dup(); } else { if ((opcode == LRETURN) || (opcode == DRETURN)) { dup2(); } else { dup(); box(Type.getReturnType(this.methodDesc)); dup(); generateAfterBodyCall("dispatchFirstMethodAfterBody", false); generateAfterBodyCall("dispatchSecondMethodAfterBody", false);
loadHookDispatcher(); swap(); push(methodId); dup2X1(); pop2(); pushNull(); } else { loadThis(); swap(); loadArgArray(); swap();
/** * {@inheritDoc} */ @Override protected void onMethodEnter() { generateBeforeBodyCall(); // start our try block visitLabel(tryBlockStart); }
/** * {@inheritDoc} * <p> * Generates call for {@link IHookDispatcher#dispatchBeforeCatch(long, Object)}. This method * expects exception object on stack that can be consumed. */ @Override protected void generateBeforeCatchCall() { // prepare for calls // we expect exception on stack so we must swap as exception is last argument in the call loadHookDispatcher(); swap(); // first push method id push(methodId); // can not just swap because method id is long, thus a bit of gymnastic // r-l-l2 dup2X1(); // l-l2-r-l-l2 pop2(); // l-l2-r :) // execute before catch mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, IInstrumenterConstant.IHOOK_DISPATCHER_INTERNAL_NAME, "dispatchBeforeCatch", IInstrumenterConstant.DISPATCH_BEFORE_CATCH_DESCRIPTOR, true); }
/** * {@inheritDoc} */ @Override public void visitMaxs(int maxStack, int maxLocals) { // the definition of the end of the try block Label tryBlockEnd = new Label(); visitLabel(tryBlockEnd); // setup for the finally block super.visitTryCatchBlock(tryBlockStart, tryBlockEnd, finallyHandler, null); visitLabel(finallyHandler); // only generate the throw in body if exception sensor is active if (enhancedExceptionSensor) { // duplicate exception and call dup(); generateThrowInBodyCall(); } // generate code for calling first and second // push exception as we don't have a result dup(); dup(); // add true booleans to denote exception in the call generateAfterBodyCall("dispatchFirstMethodAfterBody", true); generateAfterBodyCall("dispatchSecondMethodAfterBody", true); mv.visitInsn(ATHROW); // update the max stack stuff super.visitMaxs(maxStack, maxLocals); }
@Test public void method() { long id = 7L; String name = "method"; String desc = "()V"; boolean enhancedExceptionSensor = false; when(sensorInstrumentationPoint.isConstructor()).thenReturn(false); when(sensorInstrumentationPoint.getId()).thenReturn(id); MethodVisitor methodVisitor = factory.getMethodVisitor(sensorInstrumentationPoint, superMethodVisitor, 0, name, desc, enhancedExceptionSensor); assertThat(methodVisitor, is(instanceOf(MethodInstrumenter.class))); MethodInstrumenter methodInstrumenter = (MethodInstrumenter) methodVisitor; assertThat(methodInstrumenter.getMethodId(), is(id)); assertThat(methodInstrumenter.isEnhancedExceptionSensor(), is(enhancedExceptionSensor)); }
return new ConstructorInstrumenter(superMethodVisitor, access, name, desc, sensorInstrumentationPoint.getId(), enhancedExceptionSensor); } else { return new MethodInstrumenter(superMethodVisitor, access, name, desc, sensorInstrumentationPoint.getId(), enhancedExceptionSensor);
@Test public void methodEnchancedExceptionSensor() { long id = 7L; String name = "method"; String desc = "()V"; boolean enhancedExceptionSensor = true; when(sensorInstrumentationPoint.isConstructor()).thenReturn(false); when(sensorInstrumentationPoint.getId()).thenReturn(id); MethodVisitor methodVisitor = factory.getMethodVisitor(sensorInstrumentationPoint, superMethodVisitor, 0, name, desc, enhancedExceptionSensor); assertThat(methodVisitor, is(instanceOf(MethodInstrumenter.class))); MethodInstrumenter methodInstrumenter = (MethodInstrumenter) methodVisitor; assertThat(methodInstrumenter.getMethodId(), is(id)); assertThat(methodInstrumenter.isEnhancedExceptionSensor(), is(enhancedExceptionSensor)); }