refactor ctx structure

This commit is contained in:
404Simon 2024-05-11 18:33:06 +02:00
parent ba97c04414
commit 4fe433f961
24 changed files with 107 additions and 79 deletions

View File

@ -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;
}
}

View File

@ -9,16 +9,16 @@ import java.util.Map;
import java.util.Stack; import java.util.Stack;
@Getter @Getter
@Setter
@Data
public class MethodContext { public class MethodContext {
private record LocalVariable(String name, int index, Type type) {}
private Label startLabel; private Label startLabel;
private Label endLabel; private Label endLabel;
private MethodVisitor mv; private MethodVisitor mv;
private String classname; private String classname;
private int localVarIndex = 0; private int localVarIndex = 0;
private Map<String, Integer> variableIndex = new HashMap<>(); private final Map<String, LocalVariable> variableIndex = new HashMap<>();
//private Stack<Integer> stack = new Stack<>(); private Stack<Integer> stack = new Stack<>();
private int maxStack = 0;
public MethodContext(MethodVisitor mv) { public MethodContext(MethodVisitor mv) {
startLabel = new Label(); startLabel = new Label();
@ -28,16 +28,35 @@ public class MethodContext {
mv.visitLabel(startLabel); mv.visitLabel(startLabel);
} }
public int addVariable(String name) { public int addVariable(String name, Type type) {
int index = localVarIndex; int index = localVarIndex;
localVarIndex++; localVarIndex++;
variableIndex.put(name, index); variableIndex.put(name, new LocalVariable(name, index, type));
return index; 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.visitLabel(endLabel);
mv.visitMaxs(maxStack, maxLocals); mv.visitMaxs(maxStack, localVarIndex);
mv.visitEnd(); mv.visitEnd();
} }
} }

View File

@ -1,8 +1,7 @@
package de.maishai.typedast; package de.maishai.typedast;
import org.objectweb.asm.MethodVisitor;
public interface TypedExpression extends TypedNode { public interface TypedExpression extends TypedNode {
public void codeGen(MethodVisitor mv, MethodContext ctx); public void codeGen(MethodContext ctx);
public Type getType(); public Type getType();
} }

View File

@ -1,7 +1,6 @@
package de.maishai.typedast; package de.maishai.typedast;
import org.objectweb.asm.MethodVisitor;
public interface TypedStatement extends TypedNode { public interface TypedStatement extends TypedNode {
public void codeGen(MethodVisitor mv, MethodContext ctx); public void codeGen(MethodContext ctx);
} }

View File

@ -56,11 +56,10 @@ public class TypedAssignment implements TypedStatement {
} }
@Override @Override
public void codeGen(MethodVisitor mv, MethodContext ctx) { public void codeGen(MethodContext ctx) {
if (value instanceof TypedIntLiteral) { if (value instanceof TypedIntLiteral) {
TypedIntLiteral intLiteral = (TypedIntLiteral) value; ctx.getMv().visitIntInsn(Opcodes.BIPUSH, ((TypedIntLiteral) value).getValue());
mv.visitIntInsn(Opcodes.BIPUSH, ((TypedIntLiteral) value).getValue()); ctx.getMv().visitVarInsn(Opcodes.ISTORE, ctx.getLocalVarIndex());
mv.visitVarInsn(Opcodes.ISTORE, 1);
} }
} }
} }

View File

@ -63,7 +63,7 @@ public class TypedBinary implements TypedExpression {
} }
@Override @Override
public void codeGen(MethodVisitor mv, MethodContext ctx) { public void codeGen(MethodContext ctx) {
} }
} }

View File

@ -116,12 +116,12 @@ public class TypedBlock implements TypedNode {
return type; return type;
} }
public void codeGen(MethodVisitor mv, MethodContext ctx) { public void codeGen(MethodContext ctx) {
for (TypedLocalVariable var : vars) { for (TypedLocalVariable var : vars) {
//var.codeGen(mv, ctx); //var.codeGen(ctx);
} }
for (TypedStatement stmt : stmts) { for (TypedStatement stmt : stmts) {
stmt.codeGen(mv, ctx); stmt.codeGen(ctx);
} }
} }
} }

View File

@ -35,11 +35,11 @@ public class TypedBoolLiteral implements TypedExpression {
} }
@Override @Override
public void codeGen(MethodVisitor mv, MethodContext ctx) { public void codeGen(MethodContext ctx) {
if(value){ if(value){
mv.visitInsn(Opcodes.ICONST_1); ctx.getMv().visitInsn(Opcodes.ICONST_1);
}else{ }else{
mv.visitInsn(Opcodes.ICONST_0); ctx.getMv().visitInsn(Opcodes.ICONST_0);
} }
} }
} }

View File

@ -24,7 +24,7 @@ public class TypedBreak implements TypedStatement {
} }
@Override @Override
public void codeGen(MethodVisitor mv, MethodContext ctx) { public void codeGen(MethodContext ctx) {
} }
} }

View File

@ -29,7 +29,7 @@ public class TypedCharLiteral implements TypedExpression {
@Override @Override
public void codeGen(MethodVisitor mv, MethodContext ctx) { public void codeGen(MethodContext ctx) {
mv.visitLdcInsn(value); ctx.getMv().visitLdcInsn(value);
} }
} }

View File

@ -3,6 +3,7 @@ package de.maishai.typedast.typedclass;
import de.maishai.ast.Operator; import de.maishai.ast.Operator;
import de.maishai.ast.records.*; import de.maishai.ast.records.*;
import de.maishai.ast.records.Class; import de.maishai.ast.records.Class;
import de.maishai.typedast.ClassContext;
import de.maishai.typedast.CodeGenUtils; import de.maishai.typedast.CodeGenUtils;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@ -196,17 +197,18 @@ public class TypedClass implements TypedNode {
public byte[] codeGen() { public byte[] codeGen() {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); 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); cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, className, null, "java/lang/Object", null);
for (TypedField field : typedFields) { for (TypedField field : typedFields) {
field.codeGen(cw); field.codeGen(cw);
} }
for (TypedConstructor constructor : typedConstructors) { for (TypedConstructor constructor : typedConstructors) {
constructor.codeGen(cw); constructor.codeGen(ctx);
} }
for (TypedMethod m : typedMethods) { for (TypedMethod m : typedMethods) {
m.codeGen(cw); m.codeGen(ctx);
} }
return cw.toByteArray(); return cw.toByteArray();

View File

@ -2,10 +2,7 @@ package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Constructor; import de.maishai.ast.records.Constructor;
import de.maishai.ast.records.Parameter; import de.maishai.ast.records.Parameter;
import de.maishai.typedast.CodeGenUtils; import de.maishai.typedast.*;
import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedNode;
import de.maishai.typedast.Type;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.RequiredArgsConstructor; 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 int accessModifier = Opcodes.ACC_PUBLIC; // ist laut Andi ok
MethodVisitor mv = cw.visitMethod(accessModifier, "<init>", CodeGenUtils.generateDescriptor(typedParameters, Type.VOID), null, null); MethodVisitor mv = ctx.getCw().visitMethod(accessModifier, "<init>", CodeGenUtils.generateDescriptor(typedParameters, Type.VOID), null, null);
MethodContext context = new MethodContext(mv); MethodContext mctx = new MethodContext(mv);
context.addVariable("this"); mctx.addVariable("this", ctx.getName());
typedParameters.forEach(param -> context.addVariable(param.getParaName())); typedParameters.forEach(param -> mctx.addVariable(param.getParaName(), param.getType()));
//super(); //super();
mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, mctx.getVariableIndex("this"));
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
typedBlock.codeGen(mv, context); typedBlock.codeGen(mctx);
mv.visitInsn(Opcodes.RETURN); mv.visitInsn(Opcodes.RETURN);
context.wrapUp(0,0); mctx.wrapUp();
} }
} }

View File

@ -34,7 +34,7 @@ public class TypedDoWhile implements TypedStatement {
} }
@Override @Override
public void codeGen(MethodVisitor mv, MethodContext ctx) { public void codeGen(MethodContext ctx) {
} }
} }

View File

@ -60,7 +60,7 @@ public class TypedFieldVarAccess implements TypedExpression {
} }
@Override @Override
public void codeGen(MethodVisitor mv, MethodContext ctx) { public void codeGen(MethodContext ctx) {
} }
} }

View File

@ -42,7 +42,7 @@ public class TypedFor implements TypedStatement {
} }
@Override @Override
public void codeGen(MethodVisitor mv, MethodContext ctx) { public void codeGen(MethodContext ctx) {
} }
} }

View File

@ -42,18 +42,18 @@ public class TypedIfElse implements TypedStatement {
} }
@Override @Override
public void codeGen(MethodVisitor mv, MethodContext ctx) { public void codeGen(MethodContext ctx) {
Label falseLabel = new Label(); Label falseLabel = new Label();
Label end = new Label(); Label end = new Label();
typedCon.codeGen(mv, ctx); typedCon.codeGen(ctx);
mv.visitJumpInsn(Opcodes.IFEQ, falseLabel); ctx.getMv().visitJumpInsn(Opcodes.IFEQ, falseLabel);
ifTypedBlock.codeGen(mv, ctx); ifTypedBlock.codeGen(ctx);
mv.visitJumpInsn(Opcodes.GOTO, end); ctx.getMv().visitJumpInsn(Opcodes.GOTO, end);
mv.visitLabel(falseLabel); ctx.getMv().visitLabel(falseLabel);
if (elseTypedBlock != null) { if (elseTypedBlock != null) {
elseTypedBlock.codeGen(mv, ctx); elseTypedBlock.codeGen(ctx);
} }
mv.visitLabel(end); ctx.getMv().visitLabel(end);
} }
} }

View File

@ -38,7 +38,7 @@ public class TypedIntLiteral implements TypedExpression {
@Override @Override
public void codeGen(MethodVisitor mv, MethodContext ctx) { public void codeGen(MethodContext ctx) {
mv.visitLdcInsn(value); ctx.getMv().visitLdcInsn(value);
} }
} }

View File

@ -40,9 +40,6 @@ public final class TypedLocalVariable implements TypedNode {
} }
public void codeGen(MethodVisitor mv, MethodContext ctx) { public void codeGen(MethodVisitor mv, MethodContext ctx) {
System.out.println("Generating code for local variable " + name); ctx.addVariable(name, type);
int index = ctx.addVariable(name);
mv.visitLocalVariable(name, type.getDescriptor(), null, ctx.getStartLabel(), ctx.getEndLabel(), index);
} }
} }

View File

@ -37,8 +37,8 @@ public class TypedMethod implements TypedNode {
if (method.getName().equals(name) && method.getTypedParameters().size() == typedParameters.size() if (method.getName().equals(name) && method.getTypedParameters().size() == typedParameters.size()
&& method.getReturnType().equals(returnType)) { && method.getReturnType().equals(returnType)) {
for (int i = 0; i < method.getTypedParameters().size(); i++){ for (int i = 0; i < method.getTypedParameters().size(); i++) {
if(method.getTypedParameters().get(i).getType().equals(typedParameters.get(i).getType())){ if (method.getTypedParameters().get(i).getType().equals(typedParameters.get(i).getType())) {
throw new RuntimeException("Method " + name + " already exists"); 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 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); CodeGenUtils.generateDescriptor(typedParameters, returnType), null, null);
MethodContext context = new MethodContext(mv); MethodContext context = new MethodContext(mv);
context.addVariable("this"); context.addVariable("this", ctx.getName());
typedParameters.forEach(param -> context.addVariable(param.getParaName())); typedParameters.forEach(param -> context.addVariable(param.getParaName(), param.getType()));
typedBlock.codeGen(mv, context); typedBlock.codeGen(context);
context.wrapUp(0, 0); context.wrapUp();
} }
} }

View File

@ -38,7 +38,7 @@ public class TypedMethodCall implements TypedExpression, TypedStatement {
@Override @Override
public void codeGen(MethodVisitor mv, MethodContext ctx) { public void codeGen(MethodContext ctx) {
} }
} }

View File

@ -52,7 +52,7 @@ public class TypedNew implements TypedExpression, TypedStatement {
@Override @Override
public void codeGen(MethodVisitor mv, MethodContext ctx) { public void codeGen(MethodContext ctx) {
} }
} }

View File

@ -42,15 +42,15 @@ public class TypedReturn implements TypedStatement {
} }
@Override @Override
public void codeGen(MethodVisitor mv, MethodContext ctx) { public void codeGen(MethodContext ctx) {
if (ret == null) { if (ret == null) {
mv.visitInsn(Opcodes.RETURN); ctx.getMv().visitInsn(Opcodes.RETURN);
} else { } else {
ret.codeGen(mv, ctx); ret.codeGen(ctx);
if (ret.getType().getKind() != Type.Kind.REFERENCE) { if (ret.getType().getKind() != Type.Kind.REFERENCE) {
mv.visitInsn(Opcodes.IRETURN); ctx.getMv().visitInsn(Opcodes.IRETURN);
} else { } else {
mv.visitInsn(Opcodes.ARETURN); ctx.getMv().visitInsn(Opcodes.ARETURN);
} }
} }

View File

@ -46,14 +46,14 @@ public class TypedUnary implements TypedExpression {
} }
@Override @Override
public void codeGen(MethodVisitor mv, MethodContext ctx) { public void codeGen(MethodContext ctx) {
right.codeGen(mv, ctx); right.codeGen(ctx);
if(op == UnaryOperator.NOT){ if(op == UnaryOperator.NOT){
mv.visitInsn(Opcodes.ICONST_1); ctx.getMv().visitInsn(Opcodes.ICONST_1);
mv.visitInsn(Opcodes.IXOR); ctx.getMv().visitInsn(Opcodes.IXOR);
} }
if(op == UnaryOperator.SUB){ if(op == UnaryOperator.SUB){
mv.visitInsn(Opcodes.INEG); ctx.getMv().visitInsn(Opcodes.INEG);
} }
} }
} }

View File

@ -35,7 +35,7 @@ public class TypedWhile implements TypedStatement {
@Override @Override
public void codeGen(MethodVisitor mv, MethodContext ctx) { public void codeGen(MethodContext ctx) {
} }
} }