Translator.translateCallExpr方法中关于设置函数入参偏移量的问题
来源:6-13 (编程 trans 04 java)翻译——作用域和整体程序

老谭客
2020-09-06
原代码如下
private Symbol translateCallExpr(TAProgram program, ASTNode node, SymbolTable symbolTable) throws ParseException {
//函数名称
var factor = node.getChild(0);
var list = new ArrayList<TAInstruction>();
//函数入参
for(int i = 1; i < node.getChildren().size(); i++) {
var expr = node.getChildren().get(i);
//由于参数可以是表达式,所以通过translateExpr进行翻译
var addr = translateExpr(program, expr, symbolTable);
list.add(new TAInstruction(TAInstructionType.PARAM, null, null, addr, i - 1));
}
//将arg2设置为offset
for(var instruction : list) {
instruction.setArg2( symbolTable.localSize() + (int)instruction.getArg2() + 2);
program.add(instruction);
}
//函数返回值
var returnValue = symbolTable.createVariable();
//函数返回地址
var funcAddr = symbolTable.cloneFromSymbolTree(factor.getLexeme(), 0);
if(funcAddr == null) {
throw new ParseException("function " + factor.getLexeme().getValue() + " not found");
}
//函数压栈,消耗栈空间symbolTable.localSize()个单位
program.add(new TAInstruction(TAInstructionType.SP, null, null,
-symbolTable.localSize(), null));
program.add(new TAInstruction(TAInstructionType.CALL, null, null, funcAddr, null));
//函数出栈,恢复栈空间
program.add(new TAInstruction(TAInstructionType.SP, null, null,
symbolTable.localSize(),null));
return returnValue;
}
为什么在设置入参偏移量的时候会+2,视频中好像没解释?
//将arg2设置为offset
for(var instruction : list) {
instruction.setArg2( symbolTable.localSize() + (int)instruction.getArg2() + 2);
program.add(instruction);
}
写回答
1回答
-
求老仙
2020-09-09
每次函数调用会产生一个活动记录,返回值、返回地址会先于参数被压栈。因此执行到这里有个2,对应返回值和返回地址的偏移量。
00
相似问题