Skip to content

Commit

Permalink
Fix staticness check and functionality of ModifyVariable in constructors
Browse files Browse the repository at this point in the history
  • Loading branch information
Mumfrey committed Dec 6, 2019
1 parent ce622cd commit 66bdb7b
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.objectweb.asm.tree.VarInsnNode;
import org.spongepowered.asm.mixin.injection.InjectionPoint;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.InjectionPoint.RestrictTargetLevel;
import org.spongepowered.asm.mixin.injection.code.Injector;
import org.spongepowered.asm.mixin.injection.struct.InjectionInfo;
import org.spongepowered.asm.mixin.injection.struct.Target;
Expand Down Expand Up @@ -121,16 +122,12 @@ protected boolean findTargetNodes(MethodNode into, InjectionPoint injectionPoint
protected void sanityCheck(Target target, List<InjectionPoint> injectionPoints) {
super.sanityCheck(target, injectionPoints);

if (target.isStatic != this.isStatic) {
throw new InvalidInjectionException(this.info, "'static' of variable modifier method does not match target in " + this);
}

int ordinal = this.discriminator.getOrdinal();
if (ordinal < -1) {
throw new InvalidInjectionException(this.info, "Invalid ordinal " + ordinal + " specified in " + this);
}

if (this.discriminator.getIndex() == 0 && !this.isStatic) {
if (this.discriminator.getIndex() == 0 && !target.isStatic) {
throw new InvalidInjectionException(this.info, "Invalid index 0 specified in non-static variable modifier " + this);
}
}
Expand All @@ -149,6 +146,8 @@ protected void inject(Target target, InjectionNode node) {
if (this.discriminator.printLVT()) {
this.printLocals(target, context);
}

this.checkTargetForNode(target, node, RestrictTargetLevel.ALLOW_ALL);

InjectorData handler = new InjectorData(target, "handler", false);
this.validateParams(handler, this.returnType, this.returnType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,27 @@
*/
public final class ClassInfo {

/**
* Include <tt>private</tt> members when running a member search
*/
public static final int INCLUDE_PRIVATE = Opcodes.ACC_PRIVATE;

/**
* Include <tt>private</tt> members when running a member search
*/
public static final int INCLUDE_STATIC = Opcodes.ACC_STATIC;

/**
* Include <tt>private</tt> <b>and</b> <tt>static</tt> members when running
* a member search
*/
public static final int INCLUDE_ALL = ClassInfo.INCLUDE_PRIVATE | ClassInfo.INCLUDE_STATIC;

/**
* Include instance and class initialisers when running a method search
*/
public static final int INCLUDE_INITIALISERS = 0x40000;

/**
* Search type for the findInHierarchy methods, replaces a boolean flag
* which made calling code difficult to read
Expand Down Expand Up @@ -682,9 +699,14 @@ protected String getDisplayFormat() {
* Interfaces
*/
private final Set<String> interfaces;

/**
* Constructors and initialisers in this class
*/
private final Set<Method> initialisers;

/**
* Public and protected methods (instance) methods in this class
* Methods in this class
*/
private final Set<Method> methods;

Expand Down Expand Up @@ -754,6 +776,9 @@ private ClassInfo() {
this.superName = null;
this.outerName = null;
this.isProbablyStatic = true;
this.initialisers = ImmutableSet.<Method>of(
new Method("<init>", "()V")
);
this.methods = ImmutableSet.<Method>of(
new Method("getClass", "()Ljava/lang/Class;"),
new Method("hashCode", "()I"),
Expand Down Expand Up @@ -787,6 +812,7 @@ private ClassInfo(ClassNode classNode) {
try {
this.name = classNode.name;
this.superName = classNode.superName != null ? classNode.superName : ClassInfo.JAVA_LANG_OBJECT;
this.initialisers = new HashSet<Method>();
this.methods = new HashSet<Method>();
this.fields = new HashSet<Field>();
this.isInterface = ((classNode.access & Opcodes.ACC_INTERFACE) != 0);
Expand Down Expand Up @@ -839,7 +865,9 @@ void addMethod(MethodNode method) {
}

private void addMethod(MethodNode method, boolean injected) {
if (!method.name.startsWith("<")) {
if (method.name.startsWith("<")) {
this.initialisers.add(new Method(method, injected));
} else {
this.methods.add(new Method(method, injected));
}
}
Expand Down Expand Up @@ -1739,15 +1767,23 @@ public Field findField(String name, String desc, int flags) {
* @param memberType Type of member list to search
* @return the field object or null if the field could not be resolved
*/
@SuppressWarnings("unchecked")
private <M extends Member> M findMember(String name, String desc, int flags, Type memberType) {
@SuppressWarnings("unchecked")
Set<M> members = (Set<M>)(memberType == Type.METHOD ? this.methods : this.fields);

for (M member : members) {
if (member.equals(name, desc) && member.matchesFlags(flags)) {
return member;
}
}

if (memberType == Type.METHOD && (flags & ClassInfo.INCLUDE_INITIALISERS) != 0) {
for (Method ctor : this.initialisers) {
if (ctor.equals(name, desc) && ctor.matchesFlags(flags)) {
return (M)ctor;
}
}
}

return null;
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/spongepowered/asm/util/Locals.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public static LocalVariableNode[] getLocalsAt(ClassNode classNode, MethodNode me
if (classInfo == null) {
throw new LVTGeneratorError("Could not load class metadata for " + classNode.name + " generating LVT for " + method.name);
}
Method methodInfo = classInfo.findMethod(method);
Method methodInfo = classInfo.findMethod(method, method.access | ClassInfo.INCLUDE_INITIALISERS);
if (methodInfo == null) {
throw new LVTGeneratorError("Could not locate method metadata for " + method.name + " generating LVT in " + classNode.name);
}
Expand Down

0 comments on commit 66bdb7b

Please sign in to comment.