From 96850d295d782edd597b809eb4f1e2a51f80e040 Mon Sep 17 00:00:00 2001 From: Karol Stasiak Date: Fri, 26 Jul 2019 14:56:44 +0200 Subject: [PATCH] Disallow calls to main when using software stack --- src/main/scala/millfork/compiler/mos/MosCompiler.scala | 2 ++ .../millfork/compiler/mos/MosExpressionCompiler.scala | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/src/main/scala/millfork/compiler/mos/MosCompiler.scala b/src/main/scala/millfork/compiler/mos/MosCompiler.scala index ed54e245..0ae186b5 100644 --- a/src/main/scala/millfork/compiler/mos/MosCompiler.scala +++ b/src/main/scala/millfork/compiler/mos/MosCompiler.scala @@ -131,6 +131,7 @@ object MosCompiler extends AbstractCompiler[AssemblyLine] { if (ctx.options.flag(CompilationFlag.SoftwareStack)) { val stackPointer = ctx.env.get[ThingInMemory]("__sp") if (m.name == "main") { + // TODO: what about recursive calls to main? List( AssemblyLine.immediate(LDX, 0xff - m.stackVariablesSize), AssemblyLine.absolute(STX, stackPointer)).map(_.position(m.position)) @@ -152,6 +153,7 @@ object MosCompiler extends AbstractCompiler[AssemblyLine] { AssemblyLine.immediate(SBX, m.stackVariablesSize), AssemblyLine.implied(TXS)).map(_.position(m.position)) // this TXS is fine, it won't appear in 65816 code } + // TODO: be smarter in case of large stack frames: if (ctx.prologueShouldAvoidA && ctx.options.flag(CompilationFlag.EmitCmosOpcodes)) { return List.fill(m.stackVariablesSize)(AssemblyLine.implied(PHX)).map(_.position(m.position)) } diff --git a/src/main/scala/millfork/compiler/mos/MosExpressionCompiler.scala b/src/main/scala/millfork/compiler/mos/MosExpressionCompiler.scala index 46ea5008..59631a97 100644 --- a/src/main/scala/millfork/compiler/mos/MosExpressionCompiler.scala +++ b/src/main/scala/millfork/compiler/mos/MosExpressionCompiler.scala @@ -1519,6 +1519,13 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] { if (nf.interrupt) { ctx.log.error(s"Calling an interrupt function `${f.functionName}`", expr.position) } + if (nf.name == "main" && ctx.options.flag(CompilationFlag.SoftwareStack)) { + if (nf.stackVariablesSize != 0 || env.things.values.exists(_.isInstanceOf[StackVariable])) { + ctx.log.error("Calling the main function when using software stack is not allowed", expr.position) + } else { + ctx.log.warn("Calling the main function when using software stack is not allowed", expr.position) + } + } case _ => () } val result = function.params match {