diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java b/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java index b5e7e08..7848143 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java @@ -71,7 +71,7 @@ public class GenASM implements Visitor { private int lCount = 0; private int currentFunctionStartLabel = 0; private long bytesToClearFromTheStack = 0; - private Parameter[] currentFunctionParams; + private FunctionDefinition currentFunctionDef; public GenASM(String mainName, Map structs) { this.mainName = mainName; @@ -543,9 +543,23 @@ public class GenASM implements Visitor { @Override public Void visit(Block e) { - for (var statement : e.statementsOrFunctionCalls) { - statement.welcome(this); + for (var statementOrFunctionCall : e.statementsOrFunctionCalls) { + statementOrFunctionCall.welcome(this); } + + // It's possible (and allowed -> void functions) that there is no return statement + // in the outermost block of a function body. In this case, no + // direct descendant of Block will be a return statement. + // This means we have to generate an implicit return, otherwise + // the code would fall through to the next function below :D + // We also have to clean up the stack which is the ReturnStatement's job. + + // Check if we have to generate an implicit return + var lastStatementOrFunctionCall = e.statementsOrFunctionCalls[e.statementsOrFunctionCalls.length - 1]; + if (currentFunctionDef.block == e && !(lastStatementOrFunctionCall instanceof ReturnStatement)) { + visit(new ReturnStatement()); + } + return null; } @@ -558,9 +572,11 @@ public class GenASM implements Visitor { e.name = "main_by_user"; } + // Remember the current function definition so everyone below us knows where they belong to. + currentFunctionDef = e; + var lblStart = ++lCount; currentFunctionStartLabel = lblStart; - currentFunctionParams = e.parameters; asm.functionHead(e.name); asm.push("q", "%rbp"); asm.mov("q", "%rsp", "%rbp"); @@ -675,10 +691,10 @@ public class GenASM implements Visitor { // push args into local var locations, last arg is on top of the stack for (int i = e.arguments.length - 1; i >= 0; i--) { - asm.pop("q", this.env.get(this.currentFunctionParams[i].name) + "(%rbp)"); + asm.pop("q", env.get(currentFunctionDef.parameters[i].name) + "(%rbp)"); } - asm.jmp(this.currentFunctionStartLabel); + asm.jmp(currentFunctionStartLabel); return null; }