fix compiler crash when using a gosub/subroutinecall in a branch statement

This commit is contained in:
Irmen de Jong 2021-12-11 14:51:06 +01:00
parent 02010170ce
commit a7b5949e6a
3 changed files with 27 additions and 8 deletions

View File

@ -1340,9 +1340,7 @@ $repeatLabel lda $counterVar
throw AssemblyError("only else part contains code, shoud have been switched already") throw AssemblyError("only else part contains code, shoud have been switched already")
val jump = stmt.truepart.statements.first() as? Jump val jump = stmt.truepart.statements.first() as? Jump
if(jump!=null) { if(jump!=null && !jump.isGosub) {
if(jump.isGosub)
throw FatalAstException("didn't expect GoSub here")
// branch with only a jump (goto) // branch with only a jump (goto)
val instruction = branchInstruction(stmt.condition, false) val instruction = branchInstruction(stmt.condition, false)
out(" $instruction ${getJumpTarget(jump)}") out(" $instruction ${getJumpTarget(jump)}")

View File

@ -279,7 +279,19 @@ class StatementOptimizer(private val program: Program,
} }
override fun after(jump: Jump, parent: Node): Iterable<IAstModification> { override fun after(jump: Jump, parent: Node): Iterable<IAstModification> {
if(!jump.isGosub) { if(jump.isGosub) {
// if the next statement is return with no returnvalue, change into a regular jump if there are no parameters as well.
val subroutineParams = jump.identifier?.targetSubroutine(program)?.parameters
if(subroutineParams!=null && subroutineParams.isEmpty()) {
val returnstmt = jump.nextSibling() as? Return
if(returnstmt!=null && returnstmt.value==null) {
return listOf(
IAstModification.Remove(returnstmt, parent as IStatementContainer),
IAstModification.ReplaceNode(jump, Jump(jump.address, jump.identifier, jump.generatedLabel, jump.position), parent)
)
}
}
} else {
// if the jump is to the next statement, remove the jump // if the jump is to the next statement, remove the jump
val scope = jump.parent as IStatementContainer val scope = jump.parent as IStatementContainer
val label = jump.identifier?.targetStatement(program) val label = jump.identifier?.targetStatement(program)

View File

@ -3,9 +3,18 @@
main { main {
sub start() { sub start() {
ubyte @shared yy
uword foobar yy = foobar()
}
foobar() sub foobar() -> ubyte {
if_mi {
foobar2()
foobar2()
return true
}
return 22
}
sub foobar2() {
main.start.yy++
} }
} }