diff --git a/src/main/java/de/maishai/typedast/ClassContext.java b/src/main/java/de/maishai/typedast/ClassContext.java new file mode 100644 index 0000000..50e100c --- /dev/null +++ b/src/main/java/de/maishai/typedast/ClassContext.java @@ -0,0 +1,16 @@ +package de.maishai.typedast; + +import lombok.AllArgsConstructor; +import lombok.Data; +import org.objectweb.asm.ClassWriter; + +@Data +public class ClassContext { + private Type name; + private ClassWriter cw; + + public ClassContext(String name, ClassWriter cw) { + this.name = Type.REFERENCE(name); + this.cw = cw; + } +} diff --git a/src/main/java/de/maishai/typedast/MethodContext.java b/src/main/java/de/maishai/typedast/MethodContext.java index b0c4ca6..6f9ad9f 100644 --- a/src/main/java/de/maishai/typedast/MethodContext.java +++ b/src/main/java/de/maishai/typedast/MethodContext.java @@ -9,16 +9,16 @@ import java.util.Map; import java.util.Stack; @Getter -@Setter -@Data public class MethodContext { + private record LocalVariable(String name, int index, Type type) {} private Label startLabel; private Label endLabel; private MethodVisitor mv; private String classname; private int localVarIndex = 0; - private Map variableIndex = new HashMap<>(); - //private Stack stack = new Stack<>(); + private final Map variableIndex = new HashMap<>(); + private Stack stack = new Stack<>(); + private int maxStack = 0; public MethodContext(MethodVisitor mv) { startLabel = new Label(); @@ -28,16 +28,35 @@ public class MethodContext { mv.visitLabel(startLabel); } - public int addVariable(String name) { + public int addVariable(String name, Type type) { int index = localVarIndex; localVarIndex++; - variableIndex.put(name, index); + variableIndex.put(name, new LocalVariable(name, index, type)); return index; } - public void wrapUp(int maxStack, int maxLocals) { + public int getVariableIndex(String name) { + int index = variableIndex.get(name).index; + if (index == -1) { + throw new RuntimeException("Variable not declared"); + } + return index; + } + + public void pushStack() { + stack.push(localVarIndex); + if (stack.size() > maxStack) { + maxStack = stack.size(); + } + } + + public void popStack() { + stack.pop(); + } + + public void wrapUp() { mv.visitLabel(endLabel); - mv.visitMaxs(maxStack, maxLocals); + mv.visitMaxs(maxStack, localVarIndex); mv.visitEnd(); } } diff --git a/src/main/java/de/maishai/typedast/TypedExpression.java b/src/main/java/de/maishai/typedast/TypedExpression.java index aa8d5cc..0144159 100644 --- a/src/main/java/de/maishai/typedast/TypedExpression.java +++ b/src/main/java/de/maishai/typedast/TypedExpression.java @@ -1,8 +1,7 @@ package de.maishai.typedast; -import org.objectweb.asm.MethodVisitor; - public interface TypedExpression extends TypedNode { - public void codeGen(MethodVisitor mv, MethodContext ctx); + public void codeGen(MethodContext ctx); + public Type getType(); } diff --git a/src/main/java/de/maishai/typedast/TypedStatement.java b/src/main/java/de/maishai/typedast/TypedStatement.java index 2c6e8e0..251dd97 100644 --- a/src/main/java/de/maishai/typedast/TypedStatement.java +++ b/src/main/java/de/maishai/typedast/TypedStatement.java @@ -1,7 +1,6 @@ package de.maishai.typedast; -import org.objectweb.asm.MethodVisitor; public interface TypedStatement extends TypedNode { - public void codeGen(MethodVisitor mv, MethodContext ctx); + public void codeGen(MethodContext ctx); } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedAssignment.java b/src/main/java/de/maishai/typedast/typedclass/TypedAssignment.java index 3c5bfa1..a518986 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedAssignment.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedAssignment.java @@ -56,11 +56,10 @@ public class TypedAssignment implements TypedStatement { } @Override - public void codeGen(MethodVisitor mv, MethodContext ctx) { + public void codeGen(MethodContext ctx) { if (value instanceof TypedIntLiteral) { - TypedIntLiteral intLiteral = (TypedIntLiteral) value; - mv.visitIntInsn(Opcodes.BIPUSH, ((TypedIntLiteral) value).getValue()); - mv.visitVarInsn(Opcodes.ISTORE, 1); + ctx.getMv().visitIntInsn(Opcodes.BIPUSH, ((TypedIntLiteral) value).getValue()); + ctx.getMv().visitVarInsn(Opcodes.ISTORE, ctx.getLocalVarIndex()); } } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedBinary.java b/src/main/java/de/maishai/typedast/typedclass/TypedBinary.java index d8b493c..190d6e0 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedBinary.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedBinary.java @@ -63,7 +63,7 @@ public class TypedBinary implements TypedExpression { } @Override - public void codeGen(MethodVisitor mv, MethodContext ctx) { + public void codeGen(MethodContext ctx) { } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedBlock.java b/src/main/java/de/maishai/typedast/typedclass/TypedBlock.java index 76708d1..5967ad7 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedBlock.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedBlock.java @@ -116,12 +116,12 @@ public class TypedBlock implements TypedNode { return type; } - public void codeGen(MethodVisitor mv, MethodContext ctx) { + public void codeGen(MethodContext ctx) { for (TypedLocalVariable var : vars) { - //var.codeGen(mv, ctx); + //var.codeGen(ctx); } for (TypedStatement stmt : stmts) { - stmt.codeGen(mv, ctx); + stmt.codeGen(ctx); } } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedBoolLiteral.java b/src/main/java/de/maishai/typedast/typedclass/TypedBoolLiteral.java index ae6a978..0b391a2 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedBoolLiteral.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedBoolLiteral.java @@ -35,11 +35,11 @@ public class TypedBoolLiteral implements TypedExpression { } @Override - public void codeGen(MethodVisitor mv, MethodContext ctx) { + public void codeGen(MethodContext ctx) { if(value){ - mv.visitInsn(Opcodes.ICONST_1); + ctx.getMv().visitInsn(Opcodes.ICONST_1); }else{ - mv.visitInsn(Opcodes.ICONST_0); + ctx.getMv().visitInsn(Opcodes.ICONST_0); } } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedBreak.java b/src/main/java/de/maishai/typedast/typedclass/TypedBreak.java index 64b6045..9ac05c8 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedBreak.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedBreak.java @@ -24,7 +24,7 @@ public class TypedBreak implements TypedStatement { } @Override - public void codeGen(MethodVisitor mv, MethodContext ctx) { + public void codeGen(MethodContext ctx) { } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedCharLiteral.java b/src/main/java/de/maishai/typedast/typedclass/TypedCharLiteral.java index d4683d8..b35bcd8 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedCharLiteral.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedCharLiteral.java @@ -29,7 +29,7 @@ public class TypedCharLiteral implements TypedExpression { @Override - public void codeGen(MethodVisitor mv, MethodContext ctx) { - mv.visitLdcInsn(value); + public void codeGen(MethodContext ctx) { + ctx.getMv().visitLdcInsn(value); } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedClass.java b/src/main/java/de/maishai/typedast/typedclass/TypedClass.java index 626818b..867d93f 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedClass.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedClass.java @@ -3,6 +3,7 @@ package de.maishai.typedast.typedclass; import de.maishai.ast.Operator; import de.maishai.ast.records.*; import de.maishai.ast.records.Class; +import de.maishai.typedast.ClassContext; import de.maishai.typedast.CodeGenUtils; import de.maishai.typedast.Type; import lombok.AllArgsConstructor; @@ -196,17 +197,18 @@ public class TypedClass implements TypedNode { public byte[] codeGen() { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + ClassContext ctx = new ClassContext(className, cw); cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, className, null, "java/lang/Object", null); for (TypedField field : typedFields) { field.codeGen(cw); } for (TypedConstructor constructor : typedConstructors) { - constructor.codeGen(cw); + constructor.codeGen(ctx); } for (TypedMethod m : typedMethods) { - m.codeGen(cw); + m.codeGen(ctx); } return cw.toByteArray(); diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedConstructor.java b/src/main/java/de/maishai/typedast/typedclass/TypedConstructor.java index 0634ec5..15de7af 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedConstructor.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedConstructor.java @@ -2,10 +2,7 @@ package de.maishai.typedast.typedclass; import de.maishai.ast.records.Constructor; import de.maishai.ast.records.Parameter; -import de.maishai.typedast.CodeGenUtils; -import de.maishai.typedast.MethodContext; -import de.maishai.typedast.TypedNode; -import de.maishai.typedast.Type; +import de.maishai.typedast.*; import lombok.AllArgsConstructor; import lombok.Data; import lombok.RequiredArgsConstructor; @@ -55,20 +52,20 @@ public class TypedConstructor implements TypedNode { } - public void codeGen(ClassWriter cw) { + public void codeGen(ClassContext ctx) { int accessModifier = Opcodes.ACC_PUBLIC; // ist laut Andi ok - MethodVisitor mv = cw.visitMethod(accessModifier, "", CodeGenUtils.generateDescriptor(typedParameters, Type.VOID), null, null); - MethodContext context = new MethodContext(mv); - context.addVariable("this"); - typedParameters.forEach(param -> context.addVariable(param.getParaName())); + MethodVisitor mv = ctx.getCw().visitMethod(accessModifier, "", CodeGenUtils.generateDescriptor(typedParameters, Type.VOID), null, null); + MethodContext mctx = new MethodContext(mv); + mctx.addVariable("this", ctx.getName()); + typedParameters.forEach(param -> mctx.addVariable(param.getParaName(), param.getType())); //super(); - mv.visitVarInsn(Opcodes.ALOAD, 0); + mv.visitVarInsn(Opcodes.ALOAD, mctx.getVariableIndex("this")); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "", "()V", false); - typedBlock.codeGen(mv, context); + typedBlock.codeGen(mctx); mv.visitInsn(Opcodes.RETURN); - context.wrapUp(0,0); + mctx.wrapUp(); } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedDoWhile.java b/src/main/java/de/maishai/typedast/typedclass/TypedDoWhile.java index d04f5fe..0deb060 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedDoWhile.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedDoWhile.java @@ -34,7 +34,7 @@ public class TypedDoWhile implements TypedStatement { } @Override - public void codeGen(MethodVisitor mv, MethodContext ctx) { + public void codeGen(MethodContext ctx) { } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedFieldVarAccess.java b/src/main/java/de/maishai/typedast/typedclass/TypedFieldVarAccess.java index 0b2d9fe..4321db8 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedFieldVarAccess.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedFieldVarAccess.java @@ -60,7 +60,7 @@ public class TypedFieldVarAccess implements TypedExpression { } @Override - public void codeGen(MethodVisitor mv, MethodContext ctx) { + public void codeGen(MethodContext ctx) { } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedFor.java b/src/main/java/de/maishai/typedast/typedclass/TypedFor.java index f474b1f..f4f1847 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedFor.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedFor.java @@ -42,7 +42,7 @@ public class TypedFor implements TypedStatement { } @Override - public void codeGen(MethodVisitor mv, MethodContext ctx) { + public void codeGen(MethodContext ctx) { } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedIfElse.java b/src/main/java/de/maishai/typedast/typedclass/TypedIfElse.java index 793c629..e5c47d5 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedIfElse.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedIfElse.java @@ -42,18 +42,18 @@ public class TypedIfElse implements TypedStatement { } @Override - public void codeGen(MethodVisitor mv, MethodContext ctx) { + public void codeGen(MethodContext ctx) { Label falseLabel = new Label(); Label end = new Label(); - typedCon.codeGen(mv, ctx); - mv.visitJumpInsn(Opcodes.IFEQ, falseLabel); - ifTypedBlock.codeGen(mv, ctx); - mv.visitJumpInsn(Opcodes.GOTO, end); + typedCon.codeGen(ctx); + ctx.getMv().visitJumpInsn(Opcodes.IFEQ, falseLabel); + ifTypedBlock.codeGen(ctx); + ctx.getMv().visitJumpInsn(Opcodes.GOTO, end); - mv.visitLabel(falseLabel); + ctx.getMv().visitLabel(falseLabel); if (elseTypedBlock != null) { - elseTypedBlock.codeGen(mv, ctx); + elseTypedBlock.codeGen(ctx); } - mv.visitLabel(end); + ctx.getMv().visitLabel(end); } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedIntLiteral.java b/src/main/java/de/maishai/typedast/typedclass/TypedIntLiteral.java index 8b19937..c7182ae 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedIntLiteral.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedIntLiteral.java @@ -38,7 +38,7 @@ public class TypedIntLiteral implements TypedExpression { @Override - public void codeGen(MethodVisitor mv, MethodContext ctx) { - mv.visitLdcInsn(value); + public void codeGen(MethodContext ctx) { + ctx.getMv().visitLdcInsn(value); } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedLocalVariable.java b/src/main/java/de/maishai/typedast/typedclass/TypedLocalVariable.java index 1a8af9c..17f24cb 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedLocalVariable.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedLocalVariable.java @@ -40,9 +40,6 @@ public final class TypedLocalVariable implements TypedNode { } public void codeGen(MethodVisitor mv, MethodContext ctx) { - System.out.println("Generating code for local variable " + name); - int index = ctx.addVariable(name); - mv.visitLocalVariable(name, type.getDescriptor(), null, ctx.getStartLabel(), ctx.getEndLabel(), index); - + ctx.addVariable(name, type); } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedMethod.java b/src/main/java/de/maishai/typedast/typedclass/TypedMethod.java index 16fa165..6c48ba3 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedMethod.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedMethod.java @@ -37,8 +37,8 @@ public class TypedMethod implements TypedNode { if (method.getName().equals(name) && method.getTypedParameters().size() == typedParameters.size() && method.getReturnType().equals(returnType)) { - for (int i = 0; i < method.getTypedParameters().size(); i++){ - if(method.getTypedParameters().get(i).getType().equals(typedParameters.get(i).getType())){ + for (int i = 0; i < method.getTypedParameters().size(); i++) { + if (method.getTypedParameters().get(i).getType().equals(typedParameters.get(i).getType())) { throw new RuntimeException("Method " + name + " already exists"); } } @@ -69,16 +69,16 @@ public class TypedMethod implements TypedNode { } - public void codeGen(ClassWriter cw) { + public void codeGen(ClassContext ctx) { int accessModifier = Opcodes.ACC_PUBLIC; // ist laut Andi ok - MethodVisitor mv = cw.visitMethod(accessModifier, name, + MethodVisitor mv = ctx.getCw().visitMethod(accessModifier, name, CodeGenUtils.generateDescriptor(typedParameters, returnType), null, null); MethodContext context = new MethodContext(mv); - context.addVariable("this"); - typedParameters.forEach(param -> context.addVariable(param.getParaName())); + context.addVariable("this", ctx.getName()); + typedParameters.forEach(param -> context.addVariable(param.getParaName(), param.getType())); - typedBlock.codeGen(mv, context); - context.wrapUp(0, 0); + typedBlock.codeGen(context); + context.wrapUp(); } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedMethodCall.java b/src/main/java/de/maishai/typedast/typedclass/TypedMethodCall.java index 96dbf18..ade950e 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedMethodCall.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedMethodCall.java @@ -38,7 +38,7 @@ public class TypedMethodCall implements TypedExpression, TypedStatement { @Override - public void codeGen(MethodVisitor mv, MethodContext ctx) { + public void codeGen(MethodContext ctx) { } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedNew.java b/src/main/java/de/maishai/typedast/typedclass/TypedNew.java index 8ace078..8e69fa0 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedNew.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedNew.java @@ -52,7 +52,7 @@ public class TypedNew implements TypedExpression, TypedStatement { @Override - public void codeGen(MethodVisitor mv, MethodContext ctx) { + public void codeGen(MethodContext ctx) { } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedReturn.java b/src/main/java/de/maishai/typedast/typedclass/TypedReturn.java index e960d99..8a604fd 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedReturn.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedReturn.java @@ -42,15 +42,15 @@ public class TypedReturn implements TypedStatement { } @Override - public void codeGen(MethodVisitor mv, MethodContext ctx) { + public void codeGen(MethodContext ctx) { if (ret == null) { - mv.visitInsn(Opcodes.RETURN); + ctx.getMv().visitInsn(Opcodes.RETURN); } else { - ret.codeGen(mv, ctx); + ret.codeGen(ctx); if (ret.getType().getKind() != Type.Kind.REFERENCE) { - mv.visitInsn(Opcodes.IRETURN); + ctx.getMv().visitInsn(Opcodes.IRETURN); } else { - mv.visitInsn(Opcodes.ARETURN); + ctx.getMv().visitInsn(Opcodes.ARETURN); } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedUnary.java b/src/main/java/de/maishai/typedast/typedclass/TypedUnary.java index 4f82630..a068da0 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedUnary.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedUnary.java @@ -46,14 +46,14 @@ public class TypedUnary implements TypedExpression { } @Override - public void codeGen(MethodVisitor mv, MethodContext ctx) { - right.codeGen(mv, ctx); + public void codeGen(MethodContext ctx) { + right.codeGen(ctx); if(op == UnaryOperator.NOT){ - mv.visitInsn(Opcodes.ICONST_1); - mv.visitInsn(Opcodes.IXOR); + ctx.getMv().visitInsn(Opcodes.ICONST_1); + ctx.getMv().visitInsn(Opcodes.IXOR); } if(op == UnaryOperator.SUB){ - mv.visitInsn(Opcodes.INEG); + ctx.getMv().visitInsn(Opcodes.INEG); } } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedWhile.java b/src/main/java/de/maishai/typedast/typedclass/TypedWhile.java index 291445d..82201b2 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedWhile.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedWhile.java @@ -35,7 +35,7 @@ public class TypedWhile implements TypedStatement { @Override - public void codeGen(MethodVisitor mv, MethodContext ctx) { + public void codeGen(MethodContext ctx) { } }