mirror of
https://github.com/irmen/prog8.git
synced 2024-11-29 17:50:35 +00:00
astchecker is smarter in detecting rts in inline assembly
This commit is contained in:
parent
b6fe40ada4
commit
edffe92a24
@ -217,7 +217,7 @@ internal class AstChecker(private val program: Program,
|
||||
super.visit(label)
|
||||
}
|
||||
|
||||
private fun hasReturnOrJump(scope: IStatementContainer): Boolean {
|
||||
private fun hasReturnOrJumpOrRts(scope: IStatementContainer): Boolean {
|
||||
class Searcher: IAstVisitor
|
||||
{
|
||||
var count=0
|
||||
@ -229,6 +229,13 @@ internal class AstChecker(private val program: Program,
|
||||
if(!jump.isGosub)
|
||||
count++
|
||||
}
|
||||
|
||||
override fun visit(inlineAssembly: InlineAssembly) {
|
||||
val assembly = inlineAssembly.assembly
|
||||
if(" rti" in assembly || "\trti" in assembly || " rts" in assembly || "\trts" in assembly ||
|
||||
" jmp" in assembly || "\tjmp" in assembly || " bra" in assembly || "\tbra" in assembly )
|
||||
count++
|
||||
}
|
||||
}
|
||||
|
||||
val s=Searcher()
|
||||
@ -262,15 +269,13 @@ internal class AstChecker(private val program: Program,
|
||||
|
||||
// subroutine must contain at least one 'return' or 'goto'
|
||||
// (or if it has an asm block, that must contain a 'rts' or 'jmp' or 'bra')
|
||||
if(!hasReturnOrJump(subroutine)) {
|
||||
if (subroutine.amountOfRtsInAsm() == 0) {
|
||||
if(!hasReturnOrJumpOrRts(subroutine)) {
|
||||
if (subroutine.returntypes.isNotEmpty()) {
|
||||
// for asm subroutines with an address, no statement check is possible.
|
||||
if (subroutine.asmAddress == null && !subroutine.inline)
|
||||
err("non-inline subroutine has result value(s) and thus must have at least one 'return' or 'goto' in it (or rts/jmp/bra in case of %asm)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(subroutine.inline && !subroutine.isAsmSubroutine)
|
||||
err("subroutine inlining is currently only supported on asmsub routines")
|
||||
|
@ -706,12 +706,11 @@ class Subroutine(override val name: String,
|
||||
return KeepAresult(false, saveAonReturn)
|
||||
}
|
||||
|
||||
// TODO fix this to also look in asm nodes in subscopes
|
||||
fun amountOfRtsInAsm(): Int = statements
|
||||
.asSequence()
|
||||
.filter { it is InlineAssembly }
|
||||
.map { (it as InlineAssembly).assembly }
|
||||
.count { " rti" in it || "\trti" in it || " rts" in it || "\trts" in it || " jmp" in it || "\tjmp" in it || " bra" in it || "\tbra" in it}
|
||||
.count { " rti" in it || "\trti" in it || " rts" in it || "\trts" in it || " jmp" in it || "\tjmp" in it || " bra" in it || "\tbra" in it }
|
||||
|
||||
|
||||
// code to provide the ability to reference asmsub parameters via qualified name:
|
||||
|
@ -3,7 +3,6 @@ TODO
|
||||
|
||||
For next compiler release (7.5)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
- fix: amountOfRtsInAsm() look in subscopes too
|
||||
- fix: when statements generate unneeded branches to choice_end?
|
||||
|
||||
|
||||
|
@ -6,4 +6,12 @@ main {
|
||||
sub start() {
|
||||
ubyte @shared bb = @(cx16.r0)
|
||||
}
|
||||
|
||||
sub count() -> ubyte {
|
||||
repeat {
|
||||
%asm {{
|
||||
rts
|
||||
}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user