deal with stack in MethodContext

This commit is contained in:
404Simon 2024-05-13 22:32:49 +02:00
parent a4c3e931a0
commit 6a0dd6976c
4 changed files with 23 additions and 28 deletions

View File

@ -3,6 +3,7 @@ package de.maishai.typedast;
import lombok.*; import lombok.*;
import org.objectweb.asm.Label; import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -10,29 +11,32 @@ import java.util.Stack;
@Getter @Getter
public class MethodContext { public class MethodContext {
private record LocalVariable(String name, int index, Type type) {} 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 ClassContext classContext;
private int localVarIndex = 0; private int localVarIndex = 0;
private final Map<String, LocalVariable> 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; private int maxStack = 0;
public MethodContext(MethodVisitor mv) { public MethodContext(ClassContext classContext, MethodVisitor mv) {
startLabel = new Label(); startLabel = new Label();
endLabel = new Label(); endLabel = new Label();
this.mv = mv; this.mv = mv;
this.classContext = classContext;
registerVariable("this", classContext.getName());
mv.visitCode(); mv.visitCode();
mv.visitLabel(startLabel); mv.visitLabel(startLabel);
} }
public int addVariable(String name, Type type) { public void registerVariable(String name, Type type) {
int index = localVarIndex; int index = localVarIndex;
localVarIndex++; localVarIndex++;
variableIndex.put(name, new LocalVariable(name, index, type)); variableIndex.put(name, new LocalVariable(name, index, type));
return index;
} }
public int getVariableIndex(String name) { public int getVariableIndex(String name) {
@ -43,11 +47,17 @@ public class MethodContext {
return index; return index;
} }
public void pushStack() { public void pushStack(String varName) {
stack.push(localVarIndex); stack.push(localVarIndex);
if (stack.size() > maxStack) { if (stack.size() > maxStack) {
maxStack = stack.size(); maxStack = stack.size();
} }
LocalVariable localVariable = variableIndex.get(varName);
if (localVariable.type.getKind() == Type.Kind.REFERENCE) {
mv.visitVarInsn(Opcodes.ALOAD, localVariable.index);
} else {
mv.visitVarInsn(Opcodes.ILOAD, localVariable.index);
}
} }
public void popStack() { public void popStack() {

View File

@ -6,13 +6,11 @@ import de.maishai.typedast.*;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
@RequiredArgsConstructor @RequiredArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@ -68,7 +66,7 @@ public class TypedConstructor implements TypedNode {
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedClass clas) {
type = typedBlock.typeCheck(clas); type = typedBlock.typeCheck(clas);
if(type != Type.VOID){ if (type != Type.VOID) {
throw new RuntimeException("Constructor must not habe a return statement"); throw new RuntimeException("Constructor must not habe a return statement");
} }
@ -79,11 +77,10 @@ public class TypedConstructor implements TypedNode {
public void codeGen(ClassContext ctx) { 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 = ctx.getCw().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 mctx = new MethodContext(mv); MethodContext mctx = new MethodContext(ctx, mv);
mctx.addVariable("this", ctx.getName()); typedParameters.forEach(param -> mctx.registerVariable(param.getParaName(), param.getType()));
typedParameters.forEach(param -> mctx.addVariable(param.getParaName(), param.getType()));
//super(); //super();
mv.visitVarInsn(Opcodes.ALOAD, mctx.getVariableIndex("this")); mctx.pushStack("this");
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
typedBlock.codeGen(mctx); typedBlock.codeGen(mctx);

View File

@ -1,20 +1,13 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Declaration; import de.maishai.ast.records.Declaration;
import de.maishai.ast.records.Node;
import de.maishai.typedast.MethodContext; import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedNode; import de.maishai.typedast.TypedNode;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.Map;
import static de.maishai.typedast.Type.Kind.REFERENCE;
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@ -53,6 +46,6 @@ public final class TypedLocalVariable implements TypedNode {
} }
public void codeGen(MethodVisitor mv, MethodContext ctx) { public void codeGen(MethodVisitor mv, MethodContext ctx) {
ctx.addVariable(name, type); ctx.registerVariable(name, type);
} }
} }

View File

@ -1,18 +1,14 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Method; import de.maishai.ast.records.Method;
import de.maishai.ast.records.Node;
import de.maishai.ast.records.Parameter;
import de.maishai.typedast.*; import de.maishai.typedast.*;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@ -88,9 +84,8 @@ public class TypedMethod implements TypedNode {
int accessModifier = Opcodes.ACC_PUBLIC; // ist laut Andi ok int accessModifier = Opcodes.ACC_PUBLIC; // ist laut Andi ok
MethodVisitor mv = ctx.getCw().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(ctx, mv);
context.addVariable("this", ctx.getName()); typedParameters.forEach(param -> context.registerVariable(param.getParaName(), param.getType()));
typedParameters.forEach(param -> context.addVariable(param.getParaName(), param.getType()));
typedBlock.codeGen(context); typedBlock.codeGen(context);
context.wrapUp(); context.wrapUp();