1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-08-13 02:28:59 +00:00

Fixed allocating allocating local variables twice

This commit is contained in:
Karol Stasiak 2018-04-15 01:29:47 +02:00
parent 7eab7c439e
commit cdfbbf61b8
2 changed files with 20 additions and 10 deletions

View File

@ -79,6 +79,15 @@ class Environment(val parent: Option[Environment], val prefix: String) {
}.toList }.toList
} }
private def isLocalVariableName(name: String): Boolean = name.contains('$') && !name.endsWith("$") && {
val fname = name.substring(0, name.indexOf('$'))
things.get(fname) -> parent.flatMap(_.things.get(fname)) match {
case (Some(_: NormalFunction), _) => true
case (_, Some(_: NormalFunction)) => true
case _ => false
}
}
def allocateVariables(nf: Option[NormalFunction], mem: CompiledMemory, callGraph: CallGraph, allocators: Map[String, VariableAllocator], options: CompilationOptions, onEachVariable: (String, Int) => Unit): Unit = { def allocateVariables(nf: Option[NormalFunction], mem: CompiledMemory, callGraph: CallGraph, allocators: Map[String, VariableAllocator], options: CompilationOptions, onEachVariable: (String, Int) => Unit): Unit = {
val b = get[Type]("byte") val b = get[Type]("byte")
val p = get[Type]("pointer") val p = get[Type]("pointer")
@ -91,7 +100,7 @@ class Environment(val parent: Option[Environment], val prefix: String) {
} }
}.toSet }.toSet
val toAdd = things.values.flatMap { val toAdd = things.values.flatMap {
case m: UninitializedMemory => case m: UninitializedMemory if nf.isDefined == isLocalVariableName(m.name) =>
val vertex = if (options.flag(CompilationFlag.VariableOverlap)) { val vertex = if (options.flag(CompilationFlag.VariableOverlap)) {
nf.fold[VariableVertex](GlobalVertex) { f => nf.fold[VariableVertex](GlobalVertex) { f =>
if (m.alloc == VariableAllocationMethod.Static) { if (m.alloc == VariableAllocationMethod.Static) {

View File

@ -4,6 +4,7 @@ import millfork.error.ErrorReporting
import millfork.node.{CallGraph, VariableVertex} import millfork.node.{CallGraph, VariableVertex}
import millfork.{CompilationFlag, CompilationOptions} import millfork.{CompilationFlag, CompilationOptions}
import scala.annotation.tailrec
import scala.collection.mutable import scala.collection.mutable
/** /**
@ -49,10 +50,10 @@ class AfterCodeByteAllocator(val endBefore: Int) extends ByteAllocator {
def notifyAboutEndOfCode(org: Int): Unit = startAt = org def notifyAboutEndOfCode(org: Int): Unit = startAt = org
} }
class VariableAllocator(private var pointers: List[Int], private val bytes: ByteAllocator) { class VariableAllocator(private val pointers: List[Int], private val bytes: ByteAllocator) {
private var pointerMap = mutable.Map[Int, Set[VariableVertex]]() private val pointerMap = mutable.Map[Int, Set[VariableVertex]]()
private var variableMap = mutable.Map[Int, mutable.Map[Int, Set[VariableVertex]]]() private val variableMap = mutable.Map[Int, mutable.Map[Int, Set[VariableVertex]]]()
def allocatePointer(mem: MemoryBank, callGraph: CallGraph, p: VariableVertex): Int = { def allocatePointer(mem: MemoryBank, callGraph: CallGraph, p: VariableVertex): Int = {
// TODO: search for free zeropage locations // TODO: search for free zeropage locations
@ -62,16 +63,16 @@ class VariableAllocator(private var pointers: List[Int], private val bytes: Byte
return addr return addr
} }
} }
def pickFreePointer(): Int = @tailrec
pointers match { def pickFreePointer(ps: List[Int]): Int =
ps match {
case Nil => case Nil =>
ErrorReporting.trace(pointerMap.mkString(", "))
ErrorReporting.fatal("Out of zero-page memory") ErrorReporting.fatal("Out of zero-page memory")
case next :: rest => case next :: rest =>
if (mem.occupied(next) || mem.occupied(next + 1)) { if (mem.occupied(next) || mem.occupied(next + 1)) {
pointers = rest pickFreePointer(rest)
pickFreePointer()
} else { } else {
pointers = rest
mem.readable(next) = true mem.readable(next) = true
mem.readable(next + 1) = true mem.readable(next + 1) = true
mem.occupied(next) = true mem.occupied(next) = true
@ -82,7 +83,7 @@ class VariableAllocator(private var pointers: List[Int], private val bytes: Byte
next next
} }
} }
pickFreePointer() pickFreePointer(pointers)
} }
def allocateBytes(mem: MemoryBank, callGraph: CallGraph, p: VariableVertex, options: CompilationOptions, count: Int, initialized: Boolean, writeable: Boolean): Int = { def allocateBytes(mem: MemoryBank, callGraph: CallGraph, p: VariableVertex, options: CompilationOptions, count: Int, initialized: Boolean, writeable: Boolean): Int = {