Commit 6c5368b3 authored by 徐世桐's avatar 徐世桐
Browse files

sx119: WIP: debug infinite loop in function call

parent a5e21fa3
......@@ -81,9 +81,12 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
private int currParamListSize;
/* stack size of current scope, not including parameter and for-init statement stack size
* at entry of visitScope, it is stack size of parent scopeNode, if no parent, equal to 0 */
private int currentScopeStackSize;
/* mark whether this scope is function top level scope
* Level -1: not in function
* Level 0: set by funcNode
* Level 1: function top level
* Level 2+: not function top level */
int funcLevel;
public IntelInstructionGenerator() {
branchLabelGenerator = new LabelGenerator<>(".L", Label.class);
......@@ -92,7 +95,7 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
dataSection = new LinkedHashMap<>();
biDataSection = new LinkedHashMap<>();
currParamListSize = 0;
currentScopeStackSize = 0;
funcLevel = 0;
}
@Override
......@@ -287,8 +290,15 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
node.getType().showType();
System.out.println();
System.out.println();
int offset = currSymbolTable.getStackOffset(node.getName(), node.getSymbol())
- currParamListSize + stackOffset;
int offset;
if (funcLevel == 1) {
offset = currSymbolTable.getStackOffset(node.getName(), node.getSymbol())
- currParamListSize + stackOffset;
} else {
offset = currSymbolTable.getStackOffset(node.getName(), node.getSymbol())
+ stackOffset;
}
/* if is lhs, then only put address in register */
if (isLhs) {
......@@ -446,7 +456,12 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
/* TODO: add intel move type here */
int offset = node.getScope().lookup(node.getIdentifier()).getStackOffset() - currParamListSize;
int offset;
if (funcLevel == 1) {
offset = node.getScope().lookup(node.getIdentifier()).getStackOffset() - currParamListSize;
} else {
offset = node.getScope().lookup(node.getIdentifier()).getStackOffset();
}
instructions.add(new Mov(intelRegAllocator.curr().withSize(intToIntelSize.get(identTypeSize)), new IntelAddress(rbp, -offset)));
intelRegAllocator.free();
......@@ -639,9 +654,25 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
public Void visitScopeNode(ScopeNode node) {
List<StatNode> list = node.getBody();
System.out.println("funcLevel = " + funcLevel);
/* 1 leave space for variables in stack */
int stackSize = node.getScope().getParentSymbolTable() == null
? 0 : node.getScope().getParentSymbolTable().getSize();
? 0 : node.getScope().getParentSymbolTable().getSize();
if (funcLevel == 2) {
/* prev scope was top level scope of function */
stackSize = node.getScope().getParentSymbolTable().getSize() - currParamListSize;
}
if (funcLevel == -1) {
/* not in function, no operation */
} else {
/* function level increase on enter a new scope */
funcLevel++;
}
int temp = stackSize;
while (temp > 0) {
int realStackSize = temp / 1024 >= 1 ? 1024 : temp;
......@@ -671,6 +702,13 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
temp = temp - realStackSize;
}
if (funcLevel == -1) {
/* not in function, no operation */
} else {
/* function level decrease on exit a scope */
funcLevel--;
}
return null;
}
......@@ -744,8 +782,7 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
public Void visitFuncNode(FuncNode node) {
/* cannot call get stack size on function body, as that will return 0
* public field used here, so that on visit return statement, return can add stack back */
funcStackSize = node.getFunctionBody().getScope().getSize();
funcStackSize -= node.paramListStackSize();
funcStackSize = node.getFunctionBody().minStackRequired();
/* 1 add function label,
* PUSH {lr}
......@@ -762,8 +799,11 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
/* 3 visit function,
* RETURN are responsible for adding stack back
* no need to set back isFuncTopLevel, since next visitFunc will set as true again,
* visit program will set it false after all visitFunc
*/
currParamListSize = node.paramListStackSize();
funcLevel = 0;
visit(node.getFunctionBody());
currParamListSize = 0;
......@@ -780,6 +820,10 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
visitFuncNode(func);
}
/* clear fields associated with function visit */
funcLevel = -1;
currParamListSize = 0;
/* 2 start of main */
Label mainLabel = new Label("main");
instructions.add(mainLabel);
......@@ -787,8 +831,8 @@ public class IntelInstructionGenerator extends InstructionGenerator<IntelInstruc
/* 3 PUSH rsp and MOV rsp to rbp */
instructions.add(new Push(Collections.singletonList(rbp)));
instructions.add(new Mov(rsp, rbp));
int rspOffset = Math.max(16, ((ScopeNode) node.getBody()).getMaxAccumulativeDepth());
System.out.println("#################rsp offset: " + ((ScopeNode) node.getBody()).getMaxAccumulativeDepth());
int rspOffset = Math.max(16, node.getBody().minStackRequired());
System.out.println("#################rsp offset: " + node.getBody().minStackRequired());
instructions.add(new Sub(rspOffset, IntelInstructionSize.Q, rsp));
/* 4 main body */
......
......@@ -17,6 +17,7 @@ public class DeclareNode extends StatNode {
public DeclareNode(String identifier, ExprNode rhs) {
this.identifier = identifier;
this.rhs = rhs;
this.minStackSpace = rhs.getType().getSize();
}
public String getIdentifier() {
......
......@@ -17,6 +17,7 @@ public class ForNode extends StatNode {
this.cond = cond;
this.increment = increment;
this.body = body;
this.minStackSpace = init.minStackSpace + increment.minStackSpace + body.minStackSpace;
}
public StatNode getInit() {
......
......@@ -18,6 +18,7 @@ public class IfNode extends StatNode {
this.ifBody = ifBody;
this.elseBody = elseBody;
setLeaveAtEnd(getEndValue());
this.minStackSpace = Math.max(ifBody.minStackSpace, elseBody.minStackSpace);
}
......
......@@ -16,20 +16,18 @@ public class ScopeNode extends StatNode {
private final List<StatNode> body;
private boolean avoidSubStack = false;
private boolean isBeginEnd = false;
private int maxAccumulativeDepth = 0;
public ScopeNode(StatNode node) {
body = new ArrayList<>();
if (node instanceof ScopeNode) {
body.addAll(((ScopeNode) node).body);
maxAccumulativeDepth = ((ScopeNode) node).maxAccumulativeDepth;
} else {
body.add(node);
maxAccumulativeDepth = node.getScope().getSize();
}
setLeaveAtEnd(getEndValue());
isBeginEnd = true;
setScope(node.getScope());
this.minStackSpace = node.minStackSpace;
}
/* Handle the sequential statement */
......@@ -37,8 +35,8 @@ public class ScopeNode extends StatNode {
body = new ArrayList<>();
mergeScope(before);
mergeScope(after);
setLeaveAtEnd(getEndValue());
this.minStackSpace = before.minStackSpace + after.minStackSpace;
}
/* constructor used by optimisation */
......@@ -47,17 +45,17 @@ public class ScopeNode extends StatNode {
this.isBeginEnd = cloneSrc.isBeginEnd;
this.avoidSubStack = cloneSrc.avoidSubStack;
this.scope = cloneSrc.scope;
this.maxAccumulativeDepth = cloneSrc.getMaxAccumulativeDepth();
this.minStackSpace = body.stream()
.map(StatNode::minStackRequired)
.reduce(Integer::sum).orElse(0);
}
private void mergeScope(StatNode s) {
if (s instanceof ScopeNode && !((ScopeNode) s).isBeginEnd) {
ScopeNode scope = (ScopeNode) s;
body.addAll(scope.body);
this.maxAccumulativeDepth = Math.max(scope.maxAccumulativeDepth, this.maxAccumulativeDepth);
} else if (!(s instanceof SkipNode)) {
body.add(s);
this.maxAccumulativeDepth = Math.max(s.getScope().getSize(), this.maxAccumulativeDepth);
}
}
......@@ -90,7 +88,7 @@ public class ScopeNode extends StatNode {
return scope.getSize();
}
public int getMaxAccumulativeDepth() {
return maxAccumulativeDepth;
}
// public int getMaxAccumulativeDepth() {
// return maxAccumulativeDepth;
// }
}
......@@ -12,6 +12,7 @@ public abstract class StatNode implements Node {
private boolean leaveAtEnd = false;
protected SymbolTable scope;
protected int weight = 0;
protected int minStackSpace;
/* Set leaveAtEnd if needs overwrite */
protected void setLeaveAtEnd(boolean value) {
......@@ -31,6 +32,11 @@ public abstract class StatNode implements Node {
return scope;
}
/* return how much stack is required at least to execute this statement */
public int minStackRequired() {
return minStackSpace;
}
@Override
public StatNode asStatNode() {
return this;
......
......@@ -33,6 +33,12 @@ public class SwitchNode extends StatNode {
this.expr = expr;
this.cases = cases;
this.defaultCase = defaultCase;
this.minStackSpace = cases.stream()
.map(CaseStat::getBody)
.map(StatNode::minStackRequired)
.reduce(Integer::max)
.orElse(0);
this.minStackSpace = Math.max(minStackSpace, defaultCase.minStackSpace);
}
public ExprNode getExpr() {
......
......@@ -17,6 +17,7 @@ public class WhileNode extends StatNode {
this.cond = cond;
this.body = body;
this.isDoWhile = isDoWhile;
this.minStackSpace = body.minStackSpace;
}
public WhileNode(ExprNode cond, StatNode body) {
......
begin
int f(int x) is
if x == 0 then
skip
else
int i = x ;
if i > 0 then
print "-" ;
i = i - 1
else
skip
fi ;
println i ;
int s = call f(x - 1)
fi ;
return 0
end
int r = call f(13);
println "ending";
println r
end
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment