Skip to content

Commit

Permalink
remap & compute frames by hand
Browse files Browse the repository at this point in the history
  • Loading branch information
wagyourtail committed May 13, 2024
1 parent 08ab744 commit ae9b4d9
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 182 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ private static void makeEquals(ClassNode cnode, String mname, String desc, Type
visitor.visitInsn(Opcodes.ICONST_1);
visitor.visitInsn(Opcodes.IRETURN);
visitor.visitLabel(l0);
visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
var notEqual = new Label();
// if (obj != null) {
visitor.visitVarInsn(Opcodes.ALOAD, 1);
Expand Down Expand Up @@ -109,6 +110,7 @@ private static void makeEquals(ClassNode cnode, String mname, String desc, Type
visitor.visitInsn(Opcodes.ICONST_1);
visitor.visitInsn(Opcodes.IRETURN);
visitor.visitLabel(notEqual);
visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
// return false;
visitor.visitInsn(Opcodes.ICONST_0);
visitor.visitInsn(Opcodes.IRETURN);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public static MethodInsnNode makeSwitchInternal(String desc, List<Object> types,
var retLabel = new Label();
smnode.visitJumpInsn(Opcodes.GOTO, retLabel);
smnode.visitLabel(l0);
smnode.visitFrame(Opcodes.F_SAME, 0, null, 0, null);

List<CaseLabels> labels = new ArrayList<>();
List<Label> startLabels = new ArrayList<>();
Expand All @@ -114,6 +115,7 @@ public static MethodInsnNode makeSwitchInternal(String desc, List<Object> types,
for (int j = 0; j < types.size(); j++) {
var caseLabels = labels.get(j);
smnode.visitLabel(caseLabels.start);
smnode.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
var type = types.get(j);
if (type instanceof EnumType et) {
// lookahead if multiple EnumTypes in a row
Expand Down Expand Up @@ -156,6 +158,7 @@ public static MethodInsnNode makeSwitchInternal(String desc, List<Object> types,
}
// load enum value
smnode.visitLabel(caseLabels.afterTypeCheck);
smnode.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
smnode.visitFieldInsn(Opcodes.GETSTATIC, et.type.getInternalName(), et.value, et.type.getDescriptor());
smnode.visitVarInsn(Opcodes.ALOAD, 0);
// equals
Expand Down Expand Up @@ -200,6 +203,7 @@ public static MethodInsnNode makeSwitchInternal(String desc, List<Object> types,
}
}
smnode.visitLabel(caseLabels.afterTypeCheck);
smnode.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
// load string
smnode.visitLdcInsn(type);
smnode.visitVarInsn(Opcodes.ALOAD, 0);
Expand Down Expand Up @@ -250,6 +254,7 @@ public static MethodInsnNode makeSwitchInternal(String desc, List<Object> types,
}

smnode.visitLabel(caseLabels.afterTypeCheck);
smnode.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
// load int
// if (value instanceof Number v && v.intValue() == type.intValue()) {
// return j;
Expand Down Expand Up @@ -291,10 +296,12 @@ public static MethodInsnNode makeSwitchInternal(String desc, List<Object> types,
throw new IllegalStateException("Unknown type for switch: " + type);
}
smnode.visitLabel(caseLabels.end);
smnode.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
}
smnode.visitLabel(def);
smnode.visitLdcInsn(types.size());
smnode.visitLabel(retLabel);
smnode.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]{Opcodes.INTEGER});
smnode.visitInsn(Opcodes.IRETURN);


Expand Down
51 changes: 1 addition & 50 deletions src/main/java/xyz/wagyourtail/jvmdg/ClassDowngrader.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.util.Textifier;
import org.objectweb.asm.util.TraceClassVisitor;
import xyz.wagyourtail.jvmdg.asm.ASMClassWriter;
import xyz.wagyourtail.jvmdg.asm.ASMUtils;
import xyz.wagyourtail.jvmdg.classloader.DowngradingClassLoader;
import xyz.wagyourtail.jvmdg.util.Function;
Expand Down Expand Up @@ -326,56 +325,8 @@ public ClassNode apply(String s) {
return outputs;
}

public ASMClassWriter.ClassInfo fromClassNode(ClassNode node) {
String superType;
if (node.superName == null) {
superType = "java/lang/Object";
} else {
superType = stubClass(node.version, Type.getObjectType(node.superName)).getInternalName();
}
List<String> interfaces = new ArrayList<>();
for (String i : node.interfaces) {
interfaces.add(stubClass(node.version, Type.getObjectType(i)).getInternalName());
}
return new ASMClassWriter.ClassInfo((node.access & Opcodes.ACC_INTERFACE) != 0, node.name, superType, interfaces);
}

public ASMClassWriter.ClassInfo fromClassLoader(int version, String name) {
try (InputStream stream = classLoader.getResourceAsStream(name + ".class")) {
if (stream == null) return null;
ClassReader reader = new ClassReader(stream);
List<String> interfaces = new ArrayList<>();
String type = stubClass(version, Type.getObjectType(reader.getClassName())).getInternalName();
String superType = reader.getSuperName();
if (superType == null) {
superType = "java/lang/Object";
} else {
superType = stubClass(version, Type.getObjectType(superType)).getInternalName();
}
for (String i : reader.getInterfaces()) {
interfaces.add(stubClass(version, Type.getObjectType(i)).getInternalName());
}
return new ASMClassWriter.ClassInfo((reader.getAccess() & Opcodes.ACC_INTERFACE) != 0, type, superType, interfaces);
} catch (Exception e) {
return null;
}
}

public byte[] classNodeToBytes(final ClassNode node, final Function<String, byte[]> getExtraRead) {
ASMClassWriter cw = new ASMClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS, new Function<String, ASMClassWriter.ClassInfo>() {
@Override
public ASMClassWriter.ClassInfo apply(String s) {
if (s.equals(node.name)) {
return fromClassNode(node);
}
ASMClassWriter.ClassInfo ci = fromClassLoader(node.version, s);
if (ci != null) return ci;
byte[] b = getExtraRead.apply(s);
if (b == null) return null;
ClassNode cn = ASMUtils.bytesToClassNode(b, ClassReader.SKIP_CODE);
return fromClassNode(cn);
}
});
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
node.accept(cw);
return cw.toByteArray();
}
Expand Down
132 changes: 0 additions & 132 deletions src/main/java/xyz/wagyourtail/jvmdg/asm/ASMClassWriter.java

This file was deleted.

18 changes: 18 additions & 0 deletions src/main/java/xyz/wagyourtail/jvmdg/version/VersionProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,24 @@ public MethodNode stubMethods(MethodNode method, ClassNode owner, Set<ClassNode>
Handle bsm = condy.getBootstrapMethod();
throw MissingStubError.create(Type.getObjectType(bsm.getOwner()), bsm.getName(), Type.getType(bsm.getDesc()));
}
} else if (insn instanceof FrameNode) {
FrameNode fn = (FrameNode) insn;
if (fn.local != null) {
for (int j = 0; j < fn.local.size(); j++) {
Object o = fn.local.get(j);
if (o instanceof String) {
fn.local.set(j, stubClass(Type.getObjectType((String) o)).getInternalName());
}
}
}
if (fn.stack != null) {
for (int j = 0; j < fn.stack.size(); j++) {
Object o = fn.stack.get(j);
if (o instanceof String) {
fn.stack.set(j, stubClass(Type.getObjectType((String) o)).getInternalName());
}
}
}
}
}
return method;
Expand Down

0 comments on commit ae9b4d9

Please sign in to comment.