Merge branch 'main' into johns-branch

This commit is contained in:
Bruder John 2024-05-14 15:35:03 +02:00
commit 149caf5202
4 changed files with 86 additions and 28 deletions

View File

@ -13,14 +13,19 @@ import org.objectweb.asm.Opcodes;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
public class ClassCodeGen implements ClassVisitor { public class ClassCodeGen implements ClassVisitor {
Mapper mapper = new Mapper(); private Mapper mapper;
ClassWriter classWriter; private ClassWriter classWriter;
public ClassCodeGen() {
mapper = new Mapper();
}
@Override @Override
public void visit(ClassNode classNode) { public void visit(ClassNode classNode) {
classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
classWriter.visit(Opcodes.V1_8, mapper.mapAccesTypeToOpcode(classNode.accessType), classNode.identifier, null, classWriter.visit(Opcodes.V1_5, mapper.mapAccessTypeToOpcode(classNode.accessType), classNode.identifier, null,
"java/lang/Object", null); "java/lang/Object", null);
for (MemberNode memberNode : classNode.members) { for (MemberNode memberNode : classNode.members) {
@ -41,7 +46,7 @@ public class ClassCodeGen implements ClassVisitor {
@Override @Override
public void visit(FieldNode fieldNode) { public void visit(FieldNode fieldNode) {
if(fieldNode.type instanceof BaseTypeNode baseTypeNode){ if(fieldNode.type instanceof BaseTypeNode baseTypeNode){
classWriter.visitField(mapper.mapAccesTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, mapper.getTypeChar(baseTypeNode.enumType), null, null ); classWriter.visitField(mapper.mapAccessTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, mapper.getTypeChar(baseTypeNode.enumType), null, null );
} }
classWriter.visitEnd(); classWriter.visitEnd();
} }

View File

@ -1,13 +0,0 @@
package bytecode;
import ast.member.FieldNode;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
public class FieldCodeGen {
public void generateFieldCode(ClassWriter classWriter, FieldNode fieldNode) {
Mapper mapper = new Mapper();
FieldVisitor fieldVisitor = classWriter.visitField(mapper.mapAccesTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, "", null, null);
}
}

View File

@ -1,11 +1,13 @@
package bytecode; package bytecode;
import ast.parameter.ParameterListNode;
import ast.parameter.ParameterNode;
import ast.type.*; import ast.type.*;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import ast.type.BaseTypeNode; import ast.type.BaseTypeNode;
public class Mapper { public class Mapper {
public int mapAccesTypeToOpcode(AccessTypeNode type) { public int mapAccessTypeToOpcode(AccessTypeNode type) {
switch (type.enumAccessTypeNode) { switch (type.enumAccessTypeNode) {
case EnumAccessTypeNode.PUBLIC: case EnumAccessTypeNode.PUBLIC:
return Opcodes.ACC_PUBLIC; return Opcodes.ACC_PUBLIC;
@ -15,8 +17,12 @@ public class Mapper {
return 0; return 0;
} }
public String generateMethodDescriptor(BaseTypeNode baseTypeNode) { public String generateMethodDescriptor(BaseTypeNode baseTypeNode, ParameterListNode parameterListNode) {
String descriptor = "()"; String descriptor = "(";
for(ParameterNode parameterNode : parameterListNode.parameters) {
descriptor += getTypeChar(EnumTypeNode.INT);
}
descriptor += ")";
descriptor += getTypeChar(baseTypeNode.enumType); descriptor += getTypeChar(baseTypeNode.enumType);
return descriptor; return descriptor;
} }

View File

@ -2,39 +2,99 @@ package bytecode;
import ast.member.ConstructorNode; import ast.member.ConstructorNode;
import ast.member.MethodNode; import ast.member.MethodNode;
import ast.parameter.ParameterListNode;
import ast.parameter.ParameterNode;
import ast.type.BaseTypeNode; import ast.type.BaseTypeNode;
import ast.type.EnumTypeNode;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.ArrayList;
import java.util.List;
import static org.objectweb.asm.Opcodes.*;
public class MethodCodeGen implements bytecode.visitor.MethodVisitor { public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
private ClassWriter classWriter; private ClassWriter classWriter;
Mapper mapper = new Mapper(); private Mapper mapper;
private MethodVisitor methodVisitor;
private List<String> localVaribales;
public MethodCodeGen(ClassWriter classWriter) { public MethodCodeGen(ClassWriter classWriter) {
this.classWriter = classWriter; this.classWriter = classWriter;
mapper = new Mapper();
localVaribales = new ArrayList<>();
} }
@Override @Override
public void visit(ConstructorNode constructorNode) { public void visit(ConstructorNode constructorNode) {
MethodVisitor constructor = methodVisitor =
classWriter.visitMethod(mapper.mapAccesTypeToOpcode(constructorNode.visibility), classWriter.visitMethod(mapper.mapAccessTypeToOpcode(constructorNode.visibility),
"<init>", "<init>",
"()V", "()V",
null, null,
null); null);
constructor.visitEnd(); methodVisitor.visitCode();
methodVisitor.visitVarInsn(ALOAD, 0);
methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
methodVisitor.visitInsn(RETURN);
methodVisitor.visitMaxs(1, 1);
methodVisitor.visitEnd();
} }
@Override @Override
public void visit(MethodNode methodNode) { public void visit(MethodNode methodNode) {
if(methodNode.type instanceof BaseTypeNode baseTypeNode){ if (methodNode.type instanceof BaseTypeNode baseTypeNode) {
MethodVisitor method = classWriter.visitMethod(mapper.mapAccesTypeToOpcode(methodNode.visibility), methodVisitor = classWriter.visitMethod(mapper.mapAccessTypeToOpcode(methodNode.visibility),
methodNode.identifier, methodNode.identifier,
mapper.generateMethodDescriptor(baseTypeNode), mapper.generateMethodDescriptor(baseTypeNode, methodNode.parameters),
null, null,
null); null);
method.visitEnd();
methodVisitor.visitCode();
localVaribales.add("this");
for (ParameterNode parameterNode : methodNode.parameters.parameters) {
localVaribales.add(parameterNode.identifier);
}
//test();
methodVisitor.visitMaxs(1, localVaribales.size());
methodVisitor.visitEnd();
} }
} }
public void test() {
Label start = new Label();
Label loop = new Label();
Label end = new Label();
methodVisitor.visitLabel(start);
//methodVisitor.visitVarInsn(Opcodes.ICONST_M1, 99);
//methodVisitor.visitInsn(Opcodes.ICONST_5);
methodVisitor.visitLdcInsn(99);
// methodVisitor.visitInsn(Opcodes.ICONST_0);
//methodVisitor.visitVarInsn(Opcodes.ILOAD, 2);
methodVisitor.visitVarInsn(Opcodes.ISTORE, 1);
methodVisitor.visitLabel(loop);
methodVisitor.visitVarInsn(Opcodes.ILOAD, 1);
methodVisitor.visitInsn(Opcodes.ICONST_5);
methodVisitor.visitJumpInsn(Opcodes.IF_ICMPGE, end);
methodVisitor.visitFieldInsn(Opcodes.GETSTATIC,
"java/lang/System", "out",
"Ljava/io/PrintStream;");
methodVisitor.visitLdcInsn("Bytecode");
methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
"java/io/PrintStream", "println",
"(Ljava/lang/String;)V", false);
methodVisitor.visitIincInsn(1, 1);
methodVisitor.visitJumpInsn(Opcodes.GOTO, loop);
methodVisitor.visitLabel(end);
methodVisitor.visitVarInsn(Opcodes.ILOAD, 1);
methodVisitor.visitInsn(Opcodes.IRETURN);
methodVisitor.visitEnd();
}
} }