avoid JDK 21+/Kotlin method conflict of removeLast()/removeFirst()

background: see https://www.reddit.com/r/androiddev/comments/1gspjrs/dont_use_kotlins_removefirst_and_removelast_when/
https://youtrack.jetbrains.com/issue/KT-71375/Prevent-Kotlins-removeFirst-and-removeLast-from-causing-crashes-on-Android-14-and-below-after-upgrading-to-Android-API-Level-35

it's about Android but the problem also occurs on desktop JDKs for example when running a Java21 compiled prog8 with Java17
This commit is contained in:
Irmen de Jong 2025-04-24 17:48:09 +02:00
parent 8debc42381
commit 1e702439b7
4 changed files with 6 additions and 6 deletions

View File

@ -105,7 +105,7 @@ class Inliner(private val program: Program, private val options: CompilationOpti
if (subroutine.inline && subroutine.statements.size > 1) {
require(subroutine.statements.size == 2 && isEmptyReturn(subroutine.statements[1]))
subroutine.statements.removeLast() // get rid of the Return, to be able to inline the (single) statement preceding it.
subroutine.statements.removeLastOrNull() // get rid of the Return, to be able to inline the (single) statement preceding it.
}
}
}

View File

@ -126,7 +126,7 @@ class CallGraph(private val program: Program) : IAstVisitor {
// if it's a scoped identifier, the subroutines in the name are also referenced!
val scope = identifier.definingScope
val name = identifier.nameInSource.toMutableList()
val name = ArrayDeque(identifier.nameInSource)
while(name.size>1) {
name.removeLast()
val scopeTarget = scope.lookup(name)

View File

@ -1088,7 +1088,7 @@ data class IRInstruction(
}
}
if(result.last().endsWith(',')) {
result.add(result.removeLast().trimEnd(','))
result.add(result.removeLastOrNull()!!.trimEnd(','))
}
result.add(")")
val returns = fcallArgs.returns
@ -1158,7 +1158,7 @@ data class IRInstruction(
}
}
if(result.last() == ",")
result.removeLast()
result.removeLastOrNull()
return result.joinToString("").trimEnd()
}
}

View File

@ -39,8 +39,8 @@ sealed interface IPtSubroutine {
val availableFloatRegisters = mutableListOf(RegisterOrPair.FAC1) // just one value is possible
val others = returns.drop(1).map { type ->
when {
type.isFloat -> RegisterOrStatusflag(availableFloatRegisters.removeLast(), null) to type
type.isIntegerOrBool -> RegisterOrStatusflag(availableIntegerRegisters.removeLast(), null) to type
type.isFloat -> RegisterOrStatusflag(availableFloatRegisters.removeLastOrNull()!!, null) to type
type.isIntegerOrBool -> RegisterOrStatusflag(availableIntegerRegisters.removeLastOrNull()!!, null) to type
else -> throw AssemblyError("unsupported return type $type")
}
}