Skip to content

Commit

Permalink
Finished implementation of the invoke dynamic instrumentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
Rafael Winterhalter committed Feb 16, 2015
1 parent 37febf6 commit ef37fe7
Show file tree
Hide file tree
Showing 6 changed files with 619 additions and 152 deletions.

Large diffs are not rendered by default.

Expand Up @@ -1020,7 +1020,7 @@ static class ForStaticField implements ArgumentLoader {
/**
* The modifier of the field.
*/
private static final int FIELD_MODIFIER = Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC;
private static final int FIELD_MODIFIER = Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC;

/**
* The value to be stored in the field.
Expand Down Expand Up @@ -1125,7 +1125,7 @@ static class ForInstanceField implements ArgumentLoader {
/**
* The modifier to be applied to the instance field.
*/
private static final int MODIFIERS = Opcodes.ACC_PRIVATE;
private static final int MODIFIERS = Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC;

/**
* The type of the field.
Expand Down
Expand Up @@ -21,4 +21,42 @@ public interface Assigner {
* is possible. An illegal stack manipulation otherwise.
*/
StackManipulation assign(TypeDescription sourceType, TypeDescription targetType, boolean dynamicallyTyped);

/**
* An assigner that only allows to assign types if they are equal to another.
*/
static enum EqualTypesOnly implements Assigner {

/**
* The singleton instance.
*/
INSTANCE;

@Override
public StackManipulation assign(TypeDescription sourceType,
TypeDescription targetType,
boolean dynamicallyTyped) {
return sourceType.equals(targetType)
? StackManipulation.LegalTrivial.INSTANCE
: StackManipulation.Illegal.INSTANCE;
}
}

/**
* An assigner that does not allow any assignments.
*/
static enum Refusing implements Assigner {

/**
* The singleton instance.
*/
INSTANCE;

@Override
public StackManipulation assign(TypeDescription sourceType,
TypeDescription targetType,
boolean dynamicallyTyped) {
return StackManipulation.Illegal.INSTANCE;
}
}
}
Expand Up @@ -59,6 +59,4 @@ public String foo() {
return null;
}
}

// TODO: Test illegal bootstrap methods and bootstrap with arguments - Implement argument loader similar to MethodCall instrumentation?
}
@@ -0,0 +1,69 @@
package net.bytebuddy.instrumentation.method.bytecode.stack.assign;

import net.bytebuddy.instrumentation.Instrumentation;
import net.bytebuddy.instrumentation.method.bytecode.stack.StackManipulation;
import net.bytebuddy.instrumentation.type.TypeDescription;
import net.bytebuddy.test.utility.MockitoRule;
import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.mockito.Mock;
import org.objectweb.asm.MethodVisitor;

import java.util.Arrays;
import java.util.Collection;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;
import static org.mockito.Mockito.verifyZeroInteractions;

@RunWith(Parameterized.class)
public class AssignerEqualTypesOnlyTest {

@Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[] {false}, new Object[] {true});
}

private final boolean dynamicallyTyped;

public AssignerEqualTypesOnlyTest(boolean dynamicallyTyped) {
this.dynamicallyTyped = dynamicallyTyped;
}

@Rule
public TestRule mockitoRule = new MockitoRule(this);

@Mock
private TypeDescription first, second;

@Mock
private MethodVisitor methodVisitor;

@Mock
private Instrumentation.Context instrumentationContext;

@After
public void tearDown() throws Exception {
verifyZeroInteractions(methodVisitor);
verifyZeroInteractions(instrumentationContext);
}

@Test
public void testAssignmentEqual() throws Exception {
StackManipulation stackManipulation = Assigner.EqualTypesOnly.INSTANCE.assign(first, first, dynamicallyTyped);
assertThat(stackManipulation.isValid(), is(true));
StackManipulation.Size size = stackManipulation.apply(methodVisitor, instrumentationContext);
assertThat(size.getSizeImpact(), is(0));
assertThat(size.getMaximalSize(), is(0));
}

@Test
public void testAssignmentNotEqual() throws Exception {
StackManipulation stackManipulation = Assigner.EqualTypesOnly.INSTANCE.assign(first, second, dynamicallyTyped);
assertThat(stackManipulation.isValid(), is(false));
}
}
@@ -0,0 +1,66 @@
package net.bytebuddy.instrumentation.method.bytecode.stack.assign;

import net.bytebuddy.instrumentation.Instrumentation;
import net.bytebuddy.instrumentation.method.bytecode.stack.StackManipulation;
import net.bytebuddy.instrumentation.type.TypeDescription;
import net.bytebuddy.test.utility.MockitoRule;
import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.mockito.Mock;
import org.objectweb.asm.MethodVisitor;

import java.util.Arrays;
import java.util.Collection;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;
import static org.mockito.Mockito.verifyZeroInteractions;

@RunWith(Parameterized.class)
public class AssignerRefusingTest {

@Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[]{false}, new Object[]{true});
}

private final boolean dynamicallyTyped;

public AssignerRefusingTest(boolean dynamicallyTyped) {
this.dynamicallyTyped = dynamicallyTyped;
}

@Rule
public TestRule mockitoRule = new MockitoRule(this);

@Mock
private TypeDescription first, second;

@Mock
private MethodVisitor methodVisitor;

@Mock
private Instrumentation.Context instrumentationContext;

@After
public void tearDown() throws Exception {
verifyZeroInteractions(methodVisitor);
verifyZeroInteractions(instrumentationContext);
}

@Test
public void testAssignmentEqual() throws Exception {
StackManipulation stackManipulation = Assigner.Refusing.INSTANCE.assign(first, first, dynamicallyTyped);
assertThat(stackManipulation.isValid(), is(false));
}

@Test
public void testAssignmentNotEqual() throws Exception {
StackManipulation stackManipulation = Assigner.Refusing.INSTANCE.assign(first, second, dynamicallyTyped);
assertThat(stackManipulation.isValid(), is(false));
}
}

0 comments on commit ef37fe7

Please sign in to comment.