Skip to content

Commit

Permalink
the invokespecial private method in interface thing is actually java 11
Browse files Browse the repository at this point in the history
  • Loading branch information
wagyourtail committed Sep 30, 2024
1 parent c73486c commit 27eafc5
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,12 @@ public void init() {
@Override
public ClassNode otherTransforms(ClassNode clazz, Set<ClassNode> extra, Function<String, ClassNode> getReadOnly) {
super.otherTransforms(clazz);
if (clazz.name.equals("module-info")) {
return null;
}
fixNests(clazz, getReadOnly);
replaceCondy(clazz);
fixPrivateMethodsInInterfaces(clazz);
return clazz;
}

Expand Down Expand Up @@ -611,4 +615,40 @@ public void insertCondyArgs(ConstantDynamic condy, List<Object> bsmArgs) {
}
}

public void fixPrivateMethodsInInterfaces(ClassNode node) {
if ((node.access & Opcodes.ACC_INTERFACE) == 0) return;

List<String> privateMethods = new ArrayList<>();
for (MethodNode method : node.methods) {
if ((method.access & Opcodes.ACC_PRIVATE) != 0) {
privateMethods.add(method.name + method.desc);
}
}

for (MethodNode method : node.methods) {
if (method.instructions == null) continue;
for (AbstractInsnNode insn : method.instructions) {
if (insn instanceof MethodInsnNode) {
MethodInsnNode min = (MethodInsnNode) insn;
if (min.getOpcode() == Opcodes.INVOKEINTERFACE && min.owner.equals(node.name) && privateMethods.contains(min.name + min.desc)) {
min.setOpcode(Opcodes.INVOKESPECIAL);
}
} else if (insn instanceof InvokeDynamicInsnNode) {
InvokeDynamicInsnNode indy = (InvokeDynamicInsnNode) insn;
if (indy.bsm.getOwner().equals("java/lang/invoke/LambdaMetafactory")) {
if (indy.bsmArgs[1] instanceof Handle) {
Handle lambda = (Handle) indy.bsmArgs[1];
if (lambda.getOwner().equals(node.name) &&
lambda.getTag() == Opcodes.H_INVOKEINTERFACE &&
privateMethods.contains(lambda.getName() + lambda.getDesc())
) {
indy.bsmArgs[1] = new Handle(Opcodes.H_INVOKESPECIAL, lambda.getOwner(), lambda.getName(), lambda.getDesc(), lambda.isInterface());
}
}
}
}
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -509,45 +509,7 @@ public void init() {

@Override
public ClassNode otherTransforms(ClassNode clazz) {
fixPrivateMethodsInInterfaces(clazz);
if (clazz.name.equals("module-info")) {
return null;
}
return clazz;
}

public void fixPrivateMethodsInInterfaces(ClassNode node) {
if ((node.access & Opcodes.ACC_INTERFACE) == 0) return;

List<String> privateMethods = new ArrayList<>();
for (MethodNode method : node.methods) {
if ((method.access & Opcodes.ACC_PRIVATE) != 0) {
privateMethods.add(method.name + method.desc);
}
}

for (MethodNode method : node.methods) {
if (method.instructions == null) continue;
for (AbstractInsnNode insn : method.instructions) {
if (insn instanceof MethodInsnNode) {
MethodInsnNode min = (MethodInsnNode) insn;
if (min.getOpcode() == Opcodes.INVOKEINTERFACE && min.owner.equals(node.name) && privateMethods.contains(min.name + min.desc)) {
min.setOpcode(Opcodes.INVOKESPECIAL);
}
} else if (insn instanceof InvokeDynamicInsnNode) {
InvokeDynamicInsnNode indy = (InvokeDynamicInsnNode) insn;
if (indy.bsmArgs[1] instanceof Handle) {
Handle lambda = (Handle) indy.bsmArgs[1];
if (lambda.getOwner().equals(node.name) &&
lambda.getTag() == Opcodes.H_INVOKEINTERFACE &&
privateMethods.contains(lambda.getName() + lambda.getDesc())
) {
indy.bsmArgs[1] = new Handle(Opcodes.H_INVOKESPECIAL, lambda.getOwner(), lambda.getName(), lambda.getDesc(), lambda.isInterface());
}
}
}
}
}
}

}

0 comments on commit 27eafc5

Please sign in to comment.