Skip to content

Commit

Permalink
Added frame computation.
Browse files Browse the repository at this point in the history
  • Loading branch information
raphw committed Apr 5, 2016
1 parent dd03ae9 commit fc3589b
Showing 1 changed file with 64 additions and 36 deletions.
100 changes: 64 additions & 36 deletions byte-buddy-dep/src/main/java/net/bytebuddy/asm/Advice.java
@@ -1,6 +1,5 @@
package net.bytebuddy.asm;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import net.bytebuddy.description.annotation.AnnotationDescription;
import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.method.MethodDescription;
Expand All @@ -13,6 +12,7 @@
import net.bytebuddy.dynamic.scaffold.FieldLocator;
import net.bytebuddy.implementation.bytecode.StackSize;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.utility.CompoundList;
import org.objectweb.asm.*;

import java.io.IOException;
Expand Down Expand Up @@ -338,7 +338,8 @@ protected int compoundLocalVariableSize(int localVariableLength) {
* @param methodVisitor The method visitor to write the frame to.
*/
protected void injectHandlerFrame(MethodVisitor methodVisitor) {
methodVisitor.visitFrame(Opcodes.F_SAME1, 0, EMPTY, 1, new Object[]{Type.getInternalName(Throwable.class)});
// methodVisitor.visitFrame(Opcodes.F_SAME1, 0, EMPTY, 1, new Object[]{Type.getInternalName(Throwable.class)});
injectFrame(methodVisitor, intermediateTypes, true);
}

/**
Expand All @@ -347,10 +348,33 @@ protected void injectHandlerFrame(MethodVisitor methodVisitor) {
* @param methodVisitor The method visitor to write the frame to.
*/
protected void injectCompletionFrame(MethodVisitor methodVisitor) {
Object[] local = instrumentedMethod.getReturnType().represents(void.class)
// Object[] local = instrumentedMethod.getReturnType().represents(void.class)
// ? new Object[]{Type.getInternalName(Throwable.class)}
// : new Object[]{toFrame(instrumentedMethod.getReturnType().asErasure()), Type.getInternalName(Throwable.class)};
// methodVisitor.visitFrame(Opcodes.F_APPEND, local.length, local, 0, EMPTY);
injectFrame(methodVisitor, CompoundList.of(intermediateTypes, instrumentedMethod.getReturnType().represents(void.class)
? Collections.singletonList(TypeDescription.THROWABLE)
: Arrays.asList(instrumentedMethod.getReturnType().asErasure(), TypeDescription.THROWABLE)), false);
}

private void injectFrame(MethodVisitor methodVisitor,
List<? extends TypeDescription> additionalTypes,
boolean exceptionOnStack) {
Object[] localVariable = new Object[instrumentedMethod.getParameters().size() + (instrumentedMethod.isStatic() ? 0 : 1) + additionalTypes.size()];
int index = 0;
if (!instrumentedMethod.isStatic()) {
localVariable[index++] = toFrame(instrumentedMethod.getDeclaringType());
}
for (TypeDescription typeDescription : instrumentedMethod.getParameters().asTypeList().asErasures()) {
localVariable[index++] = toFrame(typeDescription);
}
for (TypeDescription typeDescription : additionalTypes) {
localVariable[index++] = toFrame(typeDescription);
}
Object[] stackType = exceptionOnStack
? new Object[]{Type.getInternalName(Throwable.class)}
: new Object[]{toFrame(instrumentedMethod.getReturnType().asErasure()), Type.getInternalName(Throwable.class)};
methodVisitor.visitFrame(Opcodes.F_APPEND, local.length, local, 0, EMPTY);
: EMPTY;
methodVisitor.visitFrame(Opcodes.F_FULL, localVariable.length, localVariable, stackType.length, stackType);
}

/**
Expand Down Expand Up @@ -492,6 +516,31 @@ protected void recordMaxima(int stackSize, int localVariableLength) {
+ intermediateTypes.getStackSize());
}

/**
* Injects a frame that describes the method when entering its surrounding exception handler.
*
* @param methodVisitor The method visitor to write the frame to.
*/
protected void injectHandlerFrame(MethodVisitor methodVisitor) {
injectFrame(methodVisitor, intermediateTypes, true);
// FrameTranslator.this.injectHandlerFrame(methodVisitor);
}

/**
* Injects a frame that describes the method after completion.
*
* @param methodVisitor The method visitor to write the frame to.
*/
protected void injectCompletionFrame(MethodVisitor methodVisitor) {
injectFrame(methodVisitor, CompoundList.of(intermediateTypes, yieldedTypes), false);
// Object[] local = new Object[yieldedTypes.size()];
// int index = 0;
// for (TypeDescription typeDescription : yieldedTypes) {
// local[index++] = toFrame(typeDescription);
// }
// methodVisitor.visitFrame(Opcodes.F_APPEND, local.length, local, 0, EMPTY);
}

/**
* Translates an existing frame.
*
Expand All @@ -518,29 +567,6 @@ protected void translateFrame(MethodVisitor methodVisitor,
stack);
}

/**
* Injects a frame that describes the method when entering its surrounding exception handler.
*
* @param methodVisitor The method visitor to write the frame to.
*/
protected void injectHandlerFrame(MethodVisitor methodVisitor) {
FrameTranslator.this.injectHandlerFrame(methodVisitor);
}

/**
* Injects a frame that describes the method after completion.
*
* @param methodVisitor The method visitor to write the frame to.
*/
protected void injectCompletionFrame(MethodVisitor methodVisitor) {
Object[] local = new Object[yieldedTypes.size()];
int index = 0;
for (TypeDescription typeDescription : yieldedTypes) {
local[index++] = toFrame(typeDescription);
}
methodVisitor.visitFrame(Opcodes.F_APPEND, local.length, local, 0, EMPTY);
}

@Override
public String toString() {
return "Advice.FrameTranslator.Bound{" +
Expand Down Expand Up @@ -635,29 +661,29 @@ public void visitVarInsn(int opcode, int offset) {
}

@Override
@SuppressFBWarnings(value = "SF_SWITCH_NO_DEFAULT", justification = "Switch is supposed to fall through")
public void visitInsn(int opcode) {
switch (opcode) {
case Opcodes.RETURN:
onMethodExit();
break;
return;
case Opcodes.IRETURN:
onMethodExit(Opcodes.ISTORE);
break;
return;
case Opcodes.FRETURN:
onMethodExit(Opcodes.FSTORE);
break;
return;
case Opcodes.DRETURN:
onMethodExit(Opcodes.DSTORE);
break;
return;
case Opcodes.LRETURN:
onMethodExit(Opcodes.LSTORE);
break;
return;
case Opcodes.ARETURN:
onMethodExit(Opcodes.ASTORE);
break;
return;
default:
mv.visitInsn(opcode);
}
mv.visitInsn(opcode);
}

/**
Expand Down Expand Up @@ -2767,6 +2793,7 @@ public void visitLineNumber(int line, Label start) {
public void visitEnd() {
mv.visitLabel(endOfMethod);
suppressionHandler.onEnd(mv, frameTranslator, this);
frameTranslator.injectCompletionFrame(mv);
}

@Override
Expand Down Expand Up @@ -2886,6 +2913,7 @@ public void onStart(MethodVisitor methodVisitor, FrameTranslator.Bound frameTran
public void onEnd(MethodVisitor methodVisitor, FrameTranslator.Bound frameTranslator, ReturnValueProducer returnValueProducer) {
Label endOfHandler = new Label();
methodVisitor.visitJumpInsn(Opcodes.GOTO, endOfHandler);
frameTranslator.injectHandlerFrame(methodVisitor);
methodVisitor.visitLabel(handler);
methodVisitor.visitInsn(Opcodes.POP);
returnValueProducer.makeDefault(methodVisitor);
Expand Down

0 comments on commit fc3589b

Please sign in to comment.