diff --git a/src/main/java/ast/parameter/ParameterListNode.java b/src/main/java/ast/parameter/ParameterListNode.java index 69d12f3..ff1c58d 100644 --- a/src/main/java/ast/parameter/ParameterListNode.java +++ b/src/main/java/ast/parameter/ParameterListNode.java @@ -6,7 +6,7 @@ import java.util.ArrayList; import java.util.List; public class ParameterListNode implements ASTNode { - List parameters = new ArrayList<>(); + public List parameters = new ArrayList<>(); public ParameterListNode(List parameters){ this.parameters = parameters; diff --git a/src/main/java/bytecode/ClassCodeGen.java b/src/main/java/bytecode/ClassCodeGen.java index 7a1c0f0..b0afa69 100644 --- a/src/main/java/bytecode/ClassCodeGen.java +++ b/src/main/java/bytecode/ClassCodeGen.java @@ -13,14 +13,19 @@ import org.objectweb.asm.Opcodes; import java.io.FileOutputStream; import java.io.IOException; + public class ClassCodeGen implements ClassVisitor { - Mapper mapper = new Mapper(); - ClassWriter classWriter; + private Mapper mapper; + private ClassWriter classWriter; + + public ClassCodeGen() { + mapper = new Mapper(); + } @Override public void visit(ClassNode classNode) { 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); for (MemberNode memberNode : classNode.members) { @@ -41,7 +46,7 @@ public class ClassCodeGen implements ClassVisitor { @Override public void visit(FieldNode fieldNode) { 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(); } diff --git a/src/main/java/bytecode/FieldCodeGen.java b/src/main/java/bytecode/FieldCodeGen.java deleted file mode 100644 index abbda43..0000000 --- a/src/main/java/bytecode/FieldCodeGen.java +++ /dev/null @@ -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); - } -} diff --git a/src/main/java/bytecode/Mapper.java b/src/main/java/bytecode/Mapper.java index fb4f484..4bc1e7c 100644 --- a/src/main/java/bytecode/Mapper.java +++ b/src/main/java/bytecode/Mapper.java @@ -1,10 +1,12 @@ package bytecode; +import ast.parameter.ParameterListNode; +import ast.parameter.ParameterNode; import ast.type.*; import org.objectweb.asm.Opcodes; public class Mapper { - public int mapAccesTypeToOpcode(AccessTypeNode type) { + public int mapAccessTypeToOpcode(AccessTypeNode type) { switch (type.enumAccessTypeNode) { case EnumAccessTypeNode.PUBLIC: return Opcodes.ACC_PUBLIC; @@ -14,8 +16,12 @@ public class Mapper { return 0; } - public String generateMethodDescriptor(BaseTypeNode baseTypeNode) { - String descriptor = "()"; + public String generateMethodDescriptor(BaseTypeNode baseTypeNode, ParameterListNode parameterListNode) { + String descriptor = "("; + for(ParameterNode parameterNode : parameterListNode.parameters) { + descriptor += getTypeChar(EnumTypeNode.INT); + } + descriptor += ")"; descriptor += getTypeChar(baseTypeNode.enumType); return descriptor; } diff --git a/src/main/java/bytecode/MethodCodeGen.java b/src/main/java/bytecode/MethodCodeGen.java index c8a38f3..a4249f1 100644 --- a/src/main/java/bytecode/MethodCodeGen.java +++ b/src/main/java/bytecode/MethodCodeGen.java @@ -2,40 +2,99 @@ package bytecode; import ast.member.ConstructorNode; import ast.member.MethodNode; +import ast.parameter.ParameterListNode; +import ast.parameter.ParameterNode; import ast.type.BaseTypeNode; +import ast.type.EnumTypeNode; import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Label; 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 { private ClassWriter classWriter; - Mapper mapper = new Mapper(); + private Mapper mapper; private MethodVisitor methodVisitor; + private List localVaribales; + public MethodCodeGen(ClassWriter classWriter) { this.classWriter = classWriter; + mapper = new Mapper(); + localVaribales = new ArrayList<>(); } @Override public void visit(ConstructorNode constructorNode) { - MethodVisitor constructor = - classWriter.visitMethod(mapper.mapAccesTypeToOpcode(constructorNode.visibility), + methodVisitor = + classWriter.visitMethod(mapper.mapAccessTypeToOpcode(constructorNode.visibility), "", "()V", null, null); - constructor.visitEnd(); + methodVisitor.visitCode(); + methodVisitor.visitVarInsn(ALOAD, 0); + methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); + methodVisitor.visitInsn(RETURN); + methodVisitor.visitMaxs(1, 1); + methodVisitor.visitEnd(); } @Override public void visit(MethodNode methodNode) { - if(methodNode.type instanceof BaseTypeNode baseTypeNode){ - MethodVisitor method = classWriter.visitMethod(mapper.mapAccesTypeToOpcode(methodNode.visibility), + if (methodNode.type instanceof BaseTypeNode baseTypeNode) { + methodVisitor = classWriter.visitMethod(mapper.mapAccessTypeToOpcode(methodNode.visibility), methodNode.identifier, - mapper.generateMethodDescriptor(baseTypeNode), + mapper.generateMethodDescriptor(baseTypeNode, methodNode.parameters), 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(); + } }