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 org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.HashMap;
import java.util.Map;
@ -10,29 +11,32 @@ import java.util.Stack;
@Getter
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 endLabel;
private MethodVisitor mv;
private String classname;
private ClassContext classContext;
private int localVarIndex = 0;
private final Map<String, LocalVariable> variableIndex = new HashMap<>();
private Stack<Integer> stack = new Stack<>();
private int maxStack = 0;
public MethodContext(MethodVisitor mv) {
public MethodContext(ClassContext classContext, MethodVisitor mv) {
startLabel = new Label();
endLabel = new Label();
this.mv = mv;
this.classContext = classContext;
registerVariable("this", classContext.getName());
mv.visitCode();
mv.visitLabel(startLabel);
}
public int addVariable(String name, Type type) {
public void registerVariable(String name, Type type) {
int index = localVarIndex;
localVarIndex++;
variableIndex.put(name, new LocalVariable(name, index, type));
return index;
}
public int getVariableIndex(String name) {
@ -43,11 +47,17 @@ public class MethodContext {
return index;
}
public void pushStack() {
public void pushStack(String varName) {
stack.push(localVarIndex);
if (stack.size() > maxStack) {
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() {

View File

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

View File

@ -1,20 +1,13 @@
package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Declaration;
import de.maishai.ast.records.Node;
import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedNode;
import de.maishai.typedast.Type;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.Map;
import static de.maishai.typedast.Type.Kind.REFERENCE;
@Data
@AllArgsConstructor
@ -53,6 +46,6 @@ public final class TypedLocalVariable implements TypedNode {
}
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;
import de.maishai.ast.records.Method;
import de.maishai.ast.records.Node;
import de.maishai.ast.records.Parameter;
import de.maishai.typedast.*;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Data
@NoArgsConstructor
@ -88,9 +84,8 @@ public class TypedMethod implements TypedNode {
int accessModifier = Opcodes.ACC_PUBLIC; // ist laut Andi ok
MethodVisitor mv = ctx.getCw().visitMethod(accessModifier, name,
CodeGenUtils.generateDescriptor(typedParameters, returnType), null, null);
MethodContext context = new MethodContext(mv);
context.addVariable("this", ctx.getName());
typedParameters.forEach(param -> context.addVariable(param.getParaName(), param.getType()));
MethodContext context = new MethodContext(ctx, mv);
typedParameters.forEach(param -> context.registerVariable(param.getParaName(), param.getType()));
typedBlock.codeGen(context);
context.wrapUp();