]> git.sur5r.net Git - cc65/blobdiff - src/cc65/function.c
Added the io module
[cc65] / src / cc65 / function.c
index f1a160b6d9115801eb5fc5de61b35ec03bba6f4f..7f26312d94ef6200f9a63a22acfcbf6f34a7fb71 100644 (file)
@@ -33,6 +33,8 @@
 
 
 
+#include "../common/xmalloc.h"
+
 #include "asmcode.h"
 #include "asmlabel.h"
 #include "codegen.h"
@@ -40,7 +42,6 @@
 #include "funcdesc.h"
 #include "litpool.h"
 #include "locals.h"
-#include "mem.h"
 #include "scanner.h"
 #include "stmt.h"
 #include "symtab.h"
@@ -60,9 +61,8 @@ struct Function {
     type*              ReturnType;     /* Function return type */
     struct FuncDesc*   Desc;           /* Function descriptor */
     CodeMark           EntryCode;      /* Backpatch addr for entry code */
-    unsigned           LocalMax;       /* Total space for locals */
-    unsigned                   LocalSize;      /* Current space for locals */
-    unsigned           RetLab;         /* Return code label */
+    int                        Reserved;       /* Reserved local space */
+    unsigned           RetLab;         /* Return code label */
 };
 
 /* Pointer to current function */
@@ -71,7 +71,7 @@ Function* CurrentFunc = 0;
 
 
 /*****************************************************************************/
-/*                                          code                                    */
+/*                Subroutines working with struct Function                  */
 /*****************************************************************************/
 
 
@@ -86,9 +86,8 @@ static Function* NewFunction (struct SymEntry* Sym)
     F->FuncEntry  = Sym;
     F->ReturnType = Sym->Type + 1 + DECODE_SIZE;
     F->Desc      = DecodePtr (Sym->Type + 1);
-    F->EntryCode  = GetCodePos ();
-    F->LocalMax          = 0;
-    F->LocalSize  = 0;
+    F->EntryCode  = 0;
+    F->Reserved          = 0;
     F->RetLab    = GetLabel ();
 
     /* Return the new structure */
@@ -137,6 +136,14 @@ int HasVoidReturn (const Function* F)
 
 
 
+void RememberEntry (Function* F)
+/* Remember the current output position for local space creation later */
+{
+    F->EntryCode = GetCodePos ();
+}
+
+
+
 unsigned GetRetLab (const Function* F)
 /* Return the return jump label */
 {
@@ -145,32 +152,46 @@ unsigned GetRetLab (const Function* F)
 
 
 
-unsigned AllocLocalSpace (Function* F, unsigned Size)
-/* Allocate space for the function locals, return stack offset */
+int ReserveLocalSpace (Function* F, unsigned Size)
+/* Reserve (but don't allocate) the given local space and return the stack
+ * offset.
+ */
 {
-    /* Remember the current offset */
-    unsigned Offs = F->LocalSize;
-
-    /* Add the size */
-    F->LocalSize += Size;
-    if (F->LocalSize > F->LocalMax) {
-       F->LocalMax = F->LocalSize;
-    }
-
-    /* Return the offset */
-    return Offs;
+    F->Reserved += Size;
+    return oursp - F->Reserved;
 }
 
 
 
-void FreeLocalSpace (Function* F, unsigned Size)
-/* Free space allocated for function locals */
+void AllocLocalSpace (Function* F)
+/* Allocate any local space previously reserved. The function will do
+ * nothing if there is no reserved local space.
+ */
 {
-    F->LocalSize -= Size;
+    if (F->Reserved > 0) {
+
+       /* Switch to the code segment */
+       g_usecode ();
+
+       /* Create space on the stack */
+       g_space (F->Reserved);
+
+       /* Correct the stack pointer */
+       oursp -= F->Reserved;
+
+       /* Nothing more reserved */
+       F->Reserved = 0;
+    }
 }
 
 
 
+/*****************************************************************************/
+/*                                          code                                    */
+/*****************************************************************************/
+
+
+
 void NewFunc (SymEntry* Func)
 /* Parse argument declarations and function body. */
 {
@@ -190,20 +211,30 @@ void NewFunc (SymEntry* Func)
 
     /* C functions cannot currently have __fastcall__ calling conventions */
     if (IsFastCallFunc (Func->Type)) {
-       Error (ERR_FASTCALL);
+       Error (ERR_FASTCALL);
     }
 
     /* Need a starting curly brace */
-    if (curtok != LCURLY) {
+    if (curtok != TOK_LCURLY) {
        Error (ERR_LCURLY_EXPECTED);
     }
 
     /* Setup register variables */
     InitRegVars ();
 
-    /* Switch to the code segment and generate function entry code */
+    /* Switch to the code segment and define the function name label */
     g_usecode ();
-    g_enter (TypeOf (Func->Type), Func->Name, GetParamSize (CurrentFunc));
+    g_defgloblabel (Func->Name);
+
+    /* Generate function entry code if needed */
+    g_enter (TypeOf (Func->Type), GetParamSize (CurrentFunc));
+
+    /* Remember the current code position. This may be used later to create
+     * local variable space once we have created the function body itself.
+     * Currently this is not possible because the stack offsets of all locals
+     * have to be known in advance.
+     */
+    RememberEntry (CurrentFunc);
 
     /* Parse the function body */
     oursp = 0;
@@ -237,3 +268,4 @@ void NewFunc (SymEntry* Func)
 
 
 
+