Skip to content

Commit b9ed5b9

Browse files
committed
Avoid that type initializer extension adjusts exception handlers by prepending new handler blocks.
1 parent 7d35c66 commit b9ed5b9

2 files changed

Lines changed: 57 additions & 7 deletions

File tree

byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/scaffold/TypeWriter.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
import net.bytebuddy.utility.nullability.UnknownNull;
7171
import net.bytebuddy.utility.privilege.GetSystemPropertyAction;
7272
import net.bytebuddy.utility.visitor.ContextClassVisitor;
73+
import net.bytebuddy.utility.visitor.ExceptionTableSensitiveMethodVisitor;
7374
import net.bytebuddy.utility.visitor.MetadataAwareClassVisitor;
7475
import org.objectweb.asm.AnnotationVisitor;
7576
import org.objectweb.asm.ClassReader;
@@ -4465,7 +4466,7 @@ public void complete(ClassVisitor classVisitor, Implementation.Context.Extractab
44654466
/**
44664467
* An initialization handler that appends code to a previously visited type initializer.
44674468
*/
4468-
abstract class Appending extends MethodVisitor implements InitializationHandler, TypeInitializer.Drain {
4469+
abstract class Appending extends ExceptionTableSensitiveMethodVisitor implements InitializationHandler, TypeInitializer.Drain {
44694470

44704471
/**
44714472
* The instrumented type.
@@ -4600,6 +4601,10 @@ private static WithoutDrain withoutDrain(MethodVisitor methodVisitor,
46004601
public void visitCode() {
46014602
record.applyAttributes(mv, annotationValueFilterFactory);
46024603
super.visitCode();
4604+
}
4605+
4606+
@Override
4607+
protected void onAfterExceptionTable() {
46034608
onStart();
46044609
}
46054610

@@ -4609,8 +4614,8 @@ public void visitCode() {
46094614
protected abstract void onStart();
46104615

46114616
@Override
4612-
public void visitFrame(int type, int localVariableLength, @MaybeNull Object[] localVariable, int stackSize, @MaybeNull Object[] stack) {
4613-
super.visitFrame(type, localVariableLength, localVariable, stackSize, stack);
4617+
protected void onVisitFrame(int type, int localVariableLength, @MaybeNull Object[] localVariable, int stackSize, @MaybeNull Object[] stack) {
4618+
super.onVisitFrame(type, localVariableLength, localVariable, stackSize, stack);
46144619
frameWriter.onFrame(type, localVariableLength);
46154620
}
46164621

@@ -4869,11 +4874,11 @@ protected WithActiveRecord(MethodVisitor methodVisitor,
48694874
}
48704875

48714876
@Override
4872-
public void visitInsn(int opcode) {
4877+
protected void onVisitInsn(int opcode) {
48734878
if (opcode == Opcodes.RETURN) {
48744879
mv.visitJumpInsn(Opcodes.GOTO, label);
48754880
} else {
4876-
super.visitInsn(opcode);
4881+
super.onVisitInsn(opcode);
48774882
}
48784883
}
48794884

@@ -5013,11 +5018,11 @@ protected WithActiveRecord(MethodVisitor methodVisitor,
50135018
}
50145019

50155020
@Override
5016-
public void visitInsn(int opcode) {
5021+
protected void onVisitInsn(int opcode) {
50175022
if (opcode == Opcodes.RETURN) {
50185023
mv.visitJumpInsn(Opcodes.GOTO, label);
50195024
} else {
5020-
super.visitInsn(opcode);
5025+
super.onVisitInsn(opcode);
50215026
}
50225027
}
50235028

byte-buddy-dep/src/test/java/net/bytebuddy/asm/AdviceTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2428,6 +2428,28 @@ public void testSelfCallHandleNotAssignable() throws Exception {
24282428
Advice.to(SelfCallHandleIllegalSample.class);
24292429
}
24302430

2431+
@Test
2432+
public void testTypeInitializerExceptionHandlingRetainedOnRebase() throws Exception {
2433+
Class<?> type = new ByteBuddy()
2434+
.rebase(TypeInitializerWithExceptionHandlingSample.class)
2435+
.visit(Advice.to(TypeInitializerWithExceptionHandlingAdvice.class).on(ElementMatchers.isTypeInitializer()))
2436+
.make()
2437+
.load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER)
2438+
.getLoaded();
2439+
assertThat(type.getDeclaredField("handled").get(null), is((Object) true));
2440+
}
2441+
2442+
@Test
2443+
public void testTypeInitializerExceptionHandlingRetainedOnRedefine() throws Exception {
2444+
Class<?> type = new ByteBuddy()
2445+
.redefine(TypeInitializerWithExceptionHandlingSample.class)
2446+
.visit(Advice.to(TypeInitializerWithExceptionHandlingAdvice.class).on(ElementMatchers.isTypeInitializer()))
2447+
.make()
2448+
.load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER)
2449+
.getLoaded();
2450+
assertThat(type.getDeclaredField("handled").get(null), is((Object) true));
2451+
}
2452+
24312453
@SuppressWarnings("unused")
24322454
public static class Sample {
24332455

@@ -4341,4 +4363,27 @@ static void exit() {
43414363
/* do nothing */
43424364
}
43434365
}
4366+
4367+
public static class TypeInitializerWithExceptionHandlingSample {
4368+
4369+
public static boolean handled = false;
4370+
4371+
static {
4372+
try {
4373+
throw new Exception();
4374+
} catch (Exception e) {
4375+
handled = true;
4376+
}
4377+
}
4378+
}
4379+
4380+
public static class TypeInitializerWithExceptionHandlingAdvice {
4381+
4382+
@Advice.OnMethodExit(onThrowable = Throwable.class, inline = true)
4383+
static void exit(
4384+
@Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object returning,
4385+
@Advice.Thrown(readOnly = false, typing = Assigner.Typing.DYNAMIC) Throwable throwing
4386+
) {
4387+
}
4388+
}
43444389
}

0 commit comments

Comments
 (0)