fix: much fixes to make things good
Some checks failed
Maven release / build (push) Has been cancelled

This commit is contained in:
Ashhhleyyy 2024-04-10 23:57:43 +01:00
parent 54a90cac53
commit cedcca2f98
Signed by: ash
GPG key ID: 83B789081A0878FB
2 changed files with 121 additions and 3 deletions

View file

@ -2,11 +2,14 @@ package dev.ashhhleyyy.bad;
import dev.ashhhleyyy.bad.framework.ClassMaker;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.LabelNode;
import java.lang.reflect.Method;
public class Main {
public static void main(String[] args) throws Exception {
System.setProperty("ashhhleyyy.bad.framework.dumpClassFiles", "out/bfGenerated");
System.out.println("Hello world!");
ClassMaker maker = new ClassMaker("dev/ashhhleyyy/runtime/RuntimeClass_");
@ -24,10 +27,45 @@ public class Main {
bytecode.invokestatic( "java/lang/Integer", "parseInt", "(Ljava/lang/String;I)I");
bytecode.ireturn();
});
builder.method(
Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
"iAmALoop",
"()V",
null,
new String[0],
bytecode -> {
bytecode.startLocal("i", "I", null, 0);
bytecode.bipush(0);
bytecode.istore(0);
LabelNode loopStart = bytecode.label();
bytecode.iload(0);
bytecode.bipush(10);
LabelNode loopBreak = bytecode.if_icmpge();
bytecode.getstatic("java/lang/System", "out", "Ljava/io/PrintStream;");
bytecode.ldc("i am a loop");
bytecode.invokevirtual("java/io/PrintStream", "println", "(Ljava/lang/String;)V");
bytecode.iinc(0, 1);
bytecode.$goto(loopStart);
bytecode.label(loopBreak);
bytecode.endLocal("i");
bytecode.getstatic("java/lang/System", "out", "Ljava/io/PrintStream;");
bytecode.ldc("i am not a loop");
bytecode.invokevirtual("java/io/PrintStream", "println", "(Ljava/lang/String;)V");
bytecode.$return();
}
);
});
Method method = cls.getMethod("toBase10", String.class);
int i = (int) method.invoke(null, "10101010");
System.out.println(i);
Method loop = cls.getMethod("iAmALoop");
loop.invoke(null);
}
}

View file

@ -1,15 +1,20 @@
package dev.ashhhleyyy.bad.framework;
import java.util.HashMap;
import java.util.Map;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.IincInsnNode;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.IntInsnNode;
import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.LocalVariableNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TypeInsnNode;
@ -19,13 +24,21 @@ public final class BytecodeBuilder {
private final ClassNode classNode;
private final MethodNode methodNode;
private final Map<String, LocalVariableNode> locals;
private LabelNode currentLabel = null;
public BytecodeBuilder(ClassNode classNode, MethodNode methodNode) {
this.classNode = classNode;
this.methodNode = methodNode;
this.locals = new HashMap<>();
}
public void add(AbstractInsnNode insn) {
this.methodNode.instructions.add(insn);
if (!(insn instanceof LabelNode)) {
this.currentLabel = null;
}
}
// Helpers
@ -38,6 +51,28 @@ public final class BytecodeBuilder {
this.add(new FieldInsnNode(Opcodes.GETFIELD, this.classNode.name, name, desc));
}
// Local variable management
public void startLocal(String name, String descriptor, String signature, int index) {
if (this.locals.containsKey(name)) {
throw new IllegalArgumentException("there is already a local called " + name);
}
LabelNode start = this.label();
LocalVariableNode lv = new LocalVariableNode(name, descriptor, signature, start, null, index);
this.locals.put(name, lv);
}
public void endLocal(String name) {
LocalVariableNode lv = this.locals.get(name);
if (lv == null) {
throw new IllegalArgumentException("there is no current local variable called " + name);
}
LabelNode end = this.label();
lv.end = end;
this.methodNode.localVariables.add(lv);
this.locals.remove(name);
}
// Raw instructions
public void iadd() {
@ -72,10 +107,22 @@ public final class BytecodeBuilder {
this.add(new VarInsnNode(Opcodes.ILOAD, index));
}
public void istore(int index) {
this.add(new VarInsnNode(Opcodes.ISTORE, index));
}
public void aload(int index) {
this.add(new VarInsnNode(Opcodes.ALOAD, index));
}
public void astore(int index) {
this.add(new VarInsnNode(Opcodes.ASTORE, index));
}
public void iinc(int index, int amount) {
this.add(new IincInsnNode(index, amount));
}
public void sipush(int operand) {
this.add(new IntInsnNode(Opcodes.SIPUSH, operand));
}
@ -92,8 +139,20 @@ public final class BytecodeBuilder {
this.add(new TypeInsnNode(Opcodes.ANEWARRAY, type));
}
public void invokedynamic(String owner, String name, String desc) {
this.add(new MethodInsnNode(Opcodes.INVOKEDYNAMIC, owner, name, desc));
public void getfield(String owner, String name, String desc) {
this.add(new FieldInsnNode(Opcodes.GETFIELD, owner, name, desc));
}
public void getstatic(String owner, String name, String desc) {
this.add(new FieldInsnNode(Opcodes.GETSTATIC, owner, name, desc));
}
public void invokevirtual(String owner, String name, String desc) {
this.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, owner, name, desc));
}
public void invokeinterface(String owner, String name, String desc) {
this.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, owner, name, desc));
}
public void invokespecial(String owner, String name, String desc) {
@ -104,12 +163,29 @@ public final class BytecodeBuilder {
this.add(new MethodInsnNode(Opcodes.INVOKESTATIC, owner, name, desc));
}
private LabelNode getCurrentLabel() {
if (this.currentLabel != null) {
return this.currentLabel;
} else {
this.currentLabel = new LabelNode(new Label());
return this.currentLabel;
}
}
public LabelNode label() {
return this.label(new LabelNode(new Label()));
return this.label(this.getCurrentLabel());
}
public LabelNode label(LabelNode label) {
this.add(label);
if (this.currentLabel == null) {
this.currentLabel = label;
}
return label;
}
public LabelNode $goto(LabelNode label) {
this.add(new JumpInsnNode(Opcodes.GOTO, label));
return label;
}
@ -123,6 +199,10 @@ public final class BytecodeBuilder {
return label;
}
public LabelNode $goto() {
return this.$goto(new LabelNode(new Label()));
}
public LabelNode if_icmpge() {
return this.if_icmpge(new LabelNode(new Label()));
}