package net.bytebuddy.asm;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import java.util.Arrays;
import java.util.Collection;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
@RunWith(Parameterized.class)
public class AdviceFrameTest {
private static final String FOO = "foo", BAR = "bar", QUX = "qux", COUNT = "count";
@Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
{FrameAdvice.class, 2},
{FrameAdviceWithoutThrowable.class, 2},
{FrameAdviceWithSuppression.class, 2},
{FrameAdviceEntryOnly.class, 1},
{FrameAdviceEntryOnlyWithSuppression.class, 1},
{FrameAdviceExitOnly.class, 1},
{FrameAdviceExitOnlyWithSuppression.class, 1},
{FrameAdviceExitOnlyWithSuppressionAndNonExceptionHandling.class, 1},
{FrameReturnAdvice.class, 2}
});
}
private final Class<?> advice;
private final int count;
public AdviceFrameTest(Class<?> advice, int count) {
this.advice = advice;
this.count = count;
}
@Test
public void testFrameAdvice() throws Exception {
Class<?> type = new ByteBuddy()
.redefine(FrameSample.class)
.visit(Advice.to(advice).on(named(FOO)))
.make()
.load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
assertThat(type.getDeclaredMethod(FOO, String.class).invoke(type.getDeclaredConstructor().newInstance(), FOO), is((Object) FOO));
assertThat(type.getField(COUNT).getInt(null), is((Object) count));
}
@Test
public void testFrameAdviceStaticMethod() throws Exception {
Class<?> type = new ByteBuddy()
.redefine(FrameSample.class)
.visit(Advice.to(advice).on(named(BAR)))
.make()
.load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
assertThat(type.getDeclaredMethod(BAR, String.class).invoke(null, FOO), is((Object) FOO));
assertThat(type.getField(COUNT).getInt(null), is((Object) count));
}
@Test
public void testFrameAdviceExpanded() throws Exception {
Class<?> type = new ByteBuddy()
.redefine(FrameSample.class)
.visit(Advice.to(advice).on(named(FOO)).readerFlags(ClassReader.EXPAND_FRAMES))
.make()
.load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
assertThat(type.getDeclaredMethod(FOO, String.class).invoke(type.getDeclaredConstructor().newInstance(), FOO), is((Object) FOO));
assertThat(type.getField(COUNT).getInt(null), is((Object) count));
}
@Test
public void testFrameAdviceStaticMethodExpanded() throws Exception {
Class<?> type = new ByteBuddy()
.redefine(FrameSample.class)
.visit(Advice.to(advice).on(named(BAR)).readerFlags(ClassReader.EXPAND_FRAMES))
.make()
.load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
assertThat(type.getDeclaredMethod(BAR, String.class).invoke(null, FOO), is((Object) FOO));
assertThat(type.getField(COUNT).getInt(null), is((Object) count));
}
@Test
public void testFrameAdviceComputedMaxima() throws Exception {
Class<?> type = new ByteBuddy()
.redefine(FrameSample.class)
.visit(Advice.to(advice).on(named(FOO)).writerFlags(ClassWriter.COMPUTE_MAXS))
.make()
.load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
assertThat(type.getDeclaredMethod(FOO, String.class).invoke(type.getDeclaredConstructor().newInstance(), FOO), is((Object) FOO));
assertThat(type.getField(COUNT).getInt(null), is((Object) count));
}
@Test
public void testFrameAdviceStaticMethodComputedMaxima() throws Exception {
Class<?> type = new ByteBuddy()
.redefine(FrameSample.class)
.visit(Advice.to(advice).on(named(BAR)).writerFlags(ClassWriter.COMPUTE_MAXS))
.make()
.load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
assertThat(type.getDeclaredMethod(BAR, String.class).invoke(null, FOO), is((Object) FOO));
assertThat(type.getField(COUNT).getInt(null), is((Object) count));
}
@Test
public void testFrameAdviceComputedFrames() throws Exception {
Class<?> type = new ByteBuddy()
.redefine(FrameSample.class)
.visit(Advice.to(advice).on(named(FOO)).writerFlags(ClassWriter.COMPUTE_FRAMES))
.make()
.load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
assertThat(type.getDeclaredMethod(FOO, String.class).invoke(type.getDeclaredConstructor().newInstance(), FOO), is((Object) FOO));
assertThat(type.getField(COUNT).getInt(null), is((Object) count));
}
@Test
public void testFrameAdviceStaticMethodComputedFrames() throws Exception {
Class<?> type = new ByteBuddy()
.redefine(FrameSample.class)
.visit(Advice.to(advice).on(named(BAR)).writerFlags(ClassWriter.COMPUTE_FRAMES))
.make()
.load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
assertThat(type.getDeclaredMethod(BAR, String.class).invoke(null, FOO), is((Object) FOO));
assertThat(type.getField(COUNT).getInt(null), is((Object) count));
}
@SuppressWarnings("all")
public static class FrameSample {
public static int count;
public String foo(String value) {
int ignored = 0;
{
long v1 = 1L, v2 = 2L;
if (ignored == 1) {
throw new AssertionError();
} else if (ignored == 2) {
if (v1 + v2 == 0L) {
throw new AssertionError();
}
}
}
long v3 = 3L, v4 = 4L, v5 = 5L, v6 = 6L;
if (ignored == 3) {
throw new AssertionError();
} else if (ignored == 4) {
if (v3 + v4 + v5 + v6 == 0L) {
throw new AssertionError();
}
}
try {
long v7 = 7L;
} catch (Exception exception) {
long v8 = 8L;
}
return value;
}
public static String bar(String value) {
int ignored = 0;
{
long v1 = 1L, v2 = 2L;
if (ignored == 1) {
throw new AssertionError();
} else if (ignored == 2) {
if (v1 + v2 == 0L) {
throw new AssertionError();
}
}
}
long v3 = 3L, v4 = 4L, v5 = 5L, v6 = 6L;
if (ignored == 3) {
throw new AssertionError();
} else if (ignored == 4) {
if (v3 + v4 + v5 + v6 == 0L) {
throw new AssertionError();
}
}
try {
long v7 = 7L;
} catch (Exception exception) {
long v8 = 8L;
}
return value;
}
}
@SuppressWarnings("unused")
public static class FrameAdvice {
@Advice.OnMethodEnter
@Advice.OnMethodExit(onThrowable = Exception.class)
private static String advice(@Advice.Unused int ignored, @Advice.Argument(0) String value) {
int v0 = 0;
{
long v1 = 1L, v2 = 2L;
if (ignored == 1) {
throw new AssertionError();
} else if (ignored == 2) {
if (v1 + v2 == 0L) {
throw new AssertionError();
}
}
}
long v3 = 3L, v4 = 4L, v5 = 5L, v6 = 6L;
if (ignored == 3) {
throw new AssertionError();
} else if (ignored == 4) {
if (v3 + v4 + v5 + v6 == 0L) {
throw new AssertionError();
}
}
try {
long v7 = 7L;
} catch (Exception exception) {
long v8 = 8L;
}
FrameSample.count++;
return value;
}
}
@SuppressWarnings("unused")
public static class FrameAdviceWithoutThrowable {
@Advice.OnMethodEnter
@Advice.OnMethodExit
private static String advice(@Advice.Unused int ignored, @Advice.Argument(0) String value) {
int v0 = 0;
{
long v1 = 1L, v2 = 2L;
if (ignored == 1) {
throw new AssertionError();
} else if (ignored == 2) {
if (v1 + v2 == 0L) {
throw new AssertionError();
}
}
}
long v3 = 3L, v4 = 4L, v5 = 5L, v6 = 6L;
if (ignored == 3) {
throw new AssertionError();
} else if (ignored == 4) {
if (v3 + v4 + v5 + v6 == 0L) {
throw new AssertionError();
}
}
try {
long v7 = 7L;
} catch (Exception exception) {
long v8 = 8L;
}
FrameSample.count++;
return value;
}
}
@SuppressWarnings("unused")
public static class FrameAdviceWithSuppression {
@Advice.OnMethodEnter(suppress = Exception.class)
@Advice.OnMethodExit(suppress = Exception.class, onThrowable = Exception.class)
private static String advice(@Advice.Unused int ignored, @Advice.Argument(0) String value) {
int v0 = 0;
{
long v1 = 1L, v2 = 2L;
if (ignored == 1) {
throw new AssertionError();
} else if (ignored == 2) {
if (v1 + v2 == 0L) {
throw new AssertionError();
}
}
}
long v3 = 3L, v4 = 4L, v5 = 5L, v6 = 6L;
if (ignored == 3) {
throw new AssertionError();
} else if (ignored == 4) {
if (v3 + v4 + v5 + v6 == 0L) {
throw new AssertionError();
}
}
try {
long v7 = 7L;
} catch (Exception exception) {
long v8 = 8L;
}
FrameSample.count++;
return value;
}
}
@SuppressWarnings("unused")
public static class FrameAdviceEntryOnly {
@Advice.OnMethodEnter
private static String advice(@Advice.Unused int ignored, @Advice.Argument(0) String value) {
int v0 = 0;
{
long v1 = 1L, v2 = 2L;
if (ignored == 1) {
throw new AssertionError();
} else if (ignored == 2) {
if (v1 + v2 == 0L) {
throw new AssertionError();
}
}
}
long v3 = 3L, v4 = 4L, v5 = 5L, v6 = 6L;
if (ignored == 3) {
throw new AssertionError();
} else if (ignored == 4) {
if (v3 + v4 + v5 + v6 == 0L) {
throw new AssertionError();
}
}
try {
long v7 = 7L;
} catch (Exception exception) {
long v8 = 8L;
}
FrameSample.count++;
return value;
}
}
@SuppressWarnings("unused")
public static class FrameAdviceEntryOnlyWithSuppression {
@Advice.OnMethodEnter(suppress = Exception.class)
private static String advice(@Advice.Unused int ignored, @Advice.Argument(0) String value) {
int v0 = 0;
{
long v1 = 1L, v2 = 2L;
if (ignored == 1) {
throw new AssertionError();
} else if (ignored == 2) {
if (v1 + v2 == 0L) {
throw new AssertionError();
}
}
}
long v3 = 3L, v4 = 4L, v5 = 5L, v6 = 6L;
if (ignored == 3) {
throw new AssertionError();
} else if (ignored == 4) {
if (v3 + v4 + v5 + v6 == 0L) {
throw new AssertionError();
}
}
try {
long v7 = 7L;
} catch (Exception exception) {
long v8 = 8L;
}
FrameSample.count++;
return value;
}
}
@SuppressWarnings("unused")
public static class FrameAdviceExitOnly {
@Advice.OnMethodExit(onThrowable = Exception.class)
private static String advice(@Advice.Unused int ignored, @Advice.Argument(0) String value) {
int v0 = 0;
{
long v1 = 1L, v2 = 2L;
if (ignored == 1) {
throw new AssertionError();
} else if (ignored == 2) {
if (v1 + v2 == 0L) {
throw new AssertionError();
}
}
}
long v3 = 3L, v4 = 4L, v5 = 5L, v6 = 6L;
if (ignored == 3) {
throw new AssertionError();
} else if (ignored == 4) {
if (v3 + v4 + v5 + v6 == 0L) {
throw new AssertionError();
}
}
try {
long v7 = 7L;
} catch (Exception exception) {
long v8 = 8L;
}
FrameSample.count++;
return value;
}
}
@SuppressWarnings("unused")
public static class FrameAdviceExitOnlyWithSuppression {
@Advice.OnMethodExit(suppress = Exception.class, onThrowable = Exception.class)
private static String advice(@Advice.Unused int ignored, @Advice.Argument(0) String value) {
int v0 = 0;
{
long v1 = 1L, v2 = 2L;
if (ignored == 1) {
throw new AssertionError();
} else if (ignored == 2) {
if (v1 + v2 == 0L) {
throw new AssertionError();
}
}
}
long v3 = 3L, v4 = 4L, v5 = 5L, v6 = 6L;
if (ignored == 3) {
throw new AssertionError();
} else if (ignored == 4) {
if (v3 + v4 + v5 + v6 == 0L) {
throw new AssertionError();
}
}
try {
long v7 = 7L;
} catch (Exception exception) {
long v8 = 8L;
}
FrameSample.count++;
return value;
}
}
@SuppressWarnings("unused")
public static class FrameAdviceExitOnlyWithSuppressionAndNonExceptionHandling {
@Advice.OnMethodExit(suppress = Exception.class, onThrowable = Exception.class)
private static String advice(@Advice.Unused int ignored, @Advice.Argument(0) String value) {
int v0 = 0;
{
long v1 = 1L, v2 = 2L;
if (ignored == 1) {
throw new AssertionError();
} else if (ignored == 2) {
if (v1 + v2 == 0L) {
throw new AssertionError();
}
}
}
long v3 = 3L, v4 = 4L, v5 = 5L, v6 = 6L;
if (ignored == 3) {
throw new AssertionError();
} else if (ignored == 4) {
if (v3 + v4 + v5 + v6 == 0L) {
throw new AssertionError();
}
}
try {
long v7 = 7L;
} catch (Exception exception) {
long v8 = 8L;
}
FrameSample.count++;
return value;
}
}
@SuppressWarnings("all")
public static class FrameReturnAdvice {
@Advice.OnMethodEnter(suppress = RuntimeException.class)
@Advice.OnMethodExit(suppress = RuntimeException.class)
private static String advice() {
try {
int ignored = 0;
if (ignored != 0) {
return BAR;
}
} catch (Exception e) {
int ignored = 0;
if (ignored != 0) {
return QUX;
}
}
FrameSample.count++;
return FOO;
}
}
}