remove unused labels and make break work

This commit is contained in:
404Simon 2024-05-20 20:45:17 +02:00
parent cc68035406
commit 050dedd4db
6 changed files with 17 additions and 12 deletions

View File

@ -15,23 +15,20 @@ public class MethodContext {
public record LocalVariable(String name, int index, Type type) { public record LocalVariable(String name, int index, Type type) {
} }
private Label startLabel;
private Label endLabel;
private MethodVisitor mv; private MethodVisitor mv;
private ClassContext classContext; private final 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;
//used to jump out of loops with break
private final Stack<Label> breakLabels = new Stack<>();
public MethodContext(ClassContext classContext, MethodVisitor mv) { public MethodContext(ClassContext classContext, MethodVisitor mv) {
startLabel = new Label();
endLabel = new Label();
this.mv = mv; this.mv = mv;
this.classContext = classContext; this.classContext = classContext;
registerVariable("this", classContext.getType()); registerVariable("this", classContext.getType());
mv.visitCode(); mv.visitCode();
mv.visitLabel(startLabel);
} }
public void registerVariable(String name, Type type) { public void registerVariable(String name, Type type) {
@ -79,7 +76,6 @@ public class MethodContext {
} }
public void wrapUp() { public void wrapUp() {
mv.visitLabel(endLabel);
System.out.println("maxStack: " + maxStack + " localVarIndex: " + localVarIndex); System.out.println("maxStack: " + maxStack + " localVarIndex: " + localVarIndex);
mv.visitMaxs(maxStack, localVarIndex); mv.visitMaxs(maxStack, localVarIndex);
mv.visitEnd(); mv.visitEnd();

View File

@ -5,6 +5,7 @@ import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedStatement; import de.maishai.typedast.TypedStatement;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import lombok.Data; import lombok.Data;
import org.objectweb.asm.Opcodes;
@Data @Data
public class TypedBreak implements TypedStatement { public class TypedBreak implements TypedStatement {
@ -17,6 +18,9 @@ public class TypedBreak implements TypedStatement {
@Override @Override
public void codeGen(MethodContext ctx) { public void codeGen(MethodContext ctx) {
if (ctx.getBreakLabels().isEmpty()) {
throw new RuntimeException("Break statement outside of loop");
}
ctx.getMv().visitJumpInsn(Opcodes.GOTO, ctx.getBreakLabels().pop());
} }
} }

View File

@ -37,6 +37,7 @@ public class TypedDoWhile implements TypedStatement {
public void codeGen(MethodContext ctx) { public void codeGen(MethodContext ctx) {
Label loopStart = new Label(); Label loopStart = new Label();
Label loopEnd = new Label(); Label loopEnd = new Label();
ctx.getBreakLabels().push(loopEnd);
ctx.getMv().visitLabel(loopStart); ctx.getMv().visitLabel(loopStart);

View File

@ -47,6 +47,7 @@ public class TypedFor implements TypedStatement {
Label loopStart = new Label(); Label loopStart = new Label();
Label loopUpdate = new Label(); Label loopUpdate = new Label();
Label loopEnd = new Label(); Label loopEnd = new Label();
ctx.getBreakLabels().push(loopEnd);
assign.codeGen(ctx); assign.codeGen(ctx);
ctx.getMv().visitLabel(loopStart); ctx.getMv().visitLabel(loopStart);

View File

@ -38,6 +38,7 @@ public class TypedWhile implements TypedStatement {
public void codeGen(MethodContext ctx) { public void codeGen(MethodContext ctx) {
Label loopStart = new Label(); Label loopStart = new Label();
Label loopEnd = new Label(); Label loopEnd = new Label();
ctx.getBreakLabels().push(loopEnd);
ctx.getMv().visitLabel(loopStart); ctx.getMv().visitLabel(loopStart);
cond.codeGen(ctx); cond.codeGen(ctx);

View File

@ -4,14 +4,16 @@ public class ClassCanBeBytecoded {
public ClassCanBeBytecoded() { public ClassCanBeBytecoded() {
} }
public int callable() {
return 1;
}
public int test(int var1) { public int test(int var1) {
int i; int i;
for (i = 0; i < 12; i = i + 1) { i = 0;
while (i < 10) {
i = i + 1;
var1 = var1 + 1; var1 = var1 + 1;
if (var1 == 5) {
break;
}
} }
return var1; return var1;
} }