From b66682a05b01ed0c1bae4e51758e26b4257ab6db Mon Sep 17 00:00:00 2001 From: acqn Date: Sun, 10 Dec 2023 00:47:10 +0800 Subject: [PATCH] Fixed wrapped call when the function to wrap has already got defined before it is wrapped with the pragma. --- doc/cc65.sgml | 9 +++++++-- src/cc65/declare.c | 22 ---------------------- src/cc65/expr.c | 14 +++++--------- src/cc65/funcdesc.c | 2 -- src/cc65/funcdesc.h | 2 -- src/cc65/symentry.h | 2 ++ src/cc65/symtab.c | 19 +++++++++++++------ test/val/trampoline.c | 14 +++++++------- 8 files changed, 34 insertions(+), 50 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 37e3e493d..efe48b61b 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -1613,13 +1613,13 @@ parameter with the function will be used to determine the number from the bank attribute defined in the linker config, see . Note that @@ -1629,6 +1629,11 @@ parameter with the WrappedCall = WrappedCall; - F->WrappedCallData = WrappedCallData; - } - /* Return the function descriptor */ return F; } @@ -2099,7 +2088,6 @@ static void DirectDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) /* Function declarator */ FuncDesc* F; - SymEntry* PrevEntry; /* Parse the function declarator */ F = ParseFuncDecl (); @@ -2110,16 +2098,6 @@ static void DirectDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) Qualifiers &= ~T_QUAL_FASTCALL; } - /* Was there a previous entry? If so, copy WrappedCall info from it */ - PrevEntry = FindGlobalSym (D->Ident); - if (PrevEntry && PrevEntry->Flags & SC_FUNC) { - FuncDesc* D = GetFuncDesc (PrevEntry->Type); - if (D->WrappedCall && !F->WrappedCall) { - F->WrappedCall = D->WrappedCall; - F->WrappedCallData = D->WrappedCallData; - } - } - /* Add the function type. Be sure to bounds check the type buffer */ NeedTypeSpace (D, 1); D->Type[D->Index].C = T_FUNC | Qualifiers; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 963ea8bd6..af39a79f9 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1057,11 +1057,6 @@ static void FunctionCall (ExprDesc* Expr) /* Special handling for function pointers */ if (IsFuncPtr) { - - if (Func->WrappedCall) { - Warning ("Calling a wrapped function via a pointer, wrapped-call will not be used"); - } - /* If the function is not a fastcall function, load the pointer to ** the function into the primary. */ @@ -1110,18 +1105,18 @@ static void FunctionCall (ExprDesc* Expr) } else { /* Normal function */ - if (Func->WrappedCall) { + if (Expr->Sym && Expr->Sym->V.F.WrappedCall) { char tmp[64]; StrBuf S = AUTO_STRBUF_INITIALIZER; - if (Func->WrappedCallData == WRAPPED_CALL_USE_BANK) { + if (Expr->Sym->V.F.WrappedCallData == WRAPPED_CALL_USE_BANK) { /* Store the bank attribute in tmp4 */ SB_AppendStr (&S, "ldy #<.bank(_"); SB_AppendStr (&S, (const char*) Expr->Name); SB_AppendChar (&S, ')'); } else { /* Store the WrappedCall data in tmp4 */ - sprintf(tmp, "ldy #%u", Func->WrappedCallData); + sprintf(tmp, "ldy #%u", Expr->Sym->V.F.WrappedCallData); SB_AppendStr (&S, tmp); } g_asmcode (&S); @@ -1154,7 +1149,7 @@ static void FunctionCall (ExprDesc* Expr) SB_Done (&S); - g_call (CG_CallFlags (Expr->Type), Func->WrappedCall->Name, ArgSize); + g_call (CG_CallFlags (Expr->Type), Expr->Sym->V.F.WrappedCall->Name, ArgSize); } else { g_call (CG_CallFlags (Expr->Type), (const char*) Expr->Name, ArgSize); } @@ -1328,6 +1323,7 @@ static void Primary (ExprDesc* E) E->Type = type_int; } + E->Sym = Sym; } break; diff --git a/src/cc65/funcdesc.c b/src/cc65/funcdesc.c index 2291b35ee..de881167d 100644 --- a/src/cc65/funcdesc.c +++ b/src/cc65/funcdesc.c @@ -61,8 +61,6 @@ FuncDesc* NewFuncDesc (void) F->ParamSize = 0; F->LastParam = 0; F->FuncDef = 0; - F->WrappedCall = 0; - F->WrappedCallData = 0; /* Return the new struct */ return F; diff --git a/src/cc65/funcdesc.h b/src/cc65/funcdesc.h index e065c7602..8d21d3080 100644 --- a/src/cc65/funcdesc.h +++ b/src/cc65/funcdesc.h @@ -70,8 +70,6 @@ struct FuncDesc { unsigned ParamSize; /* Size of the parameters */ struct SymEntry* LastParam; /* Pointer to last parameter */ struct FuncDesc* FuncDef; /* Descriptor used in definition */ - struct SymEntry* WrappedCall; /* Pointer to the WrappedCall */ - unsigned int WrappedCallData; /* The WrappedCall's user data */ }; diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 715c036d6..639221625 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -159,6 +159,8 @@ struct SymEntry { struct { struct SegContext* Seg; /* SegContext for this function */ struct LiteralPool* LitPool; /* Literal pool for this function */ + struct SymEntry* WrappedCall; /* Pointer to the WrappedCall */ + unsigned int WrappedCallData; /* The WrappedCall's user data */ } F; /* Label name for static symbols */ diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 1b5c1e0b5..3018c910d 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -61,6 +61,7 @@ #include "symentry.h" #include "typecmp.h" #include "typeconv.h" +#include "wrappedcall.h" #include "symtab.h" @@ -1407,24 +1408,30 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) } if (Entry == 0) { - /* Create a new entry */ Entry = NewSymEntry (Name, Flags); /* Set the symbol attributes */ Entry->Type = TypeDup (T); - /* If this is a function, clear additional fields */ - if (IsTypeFunc (T)) { - Entry->V.F.Seg = 0; - } - /* Add the assembler name of the symbol */ SymSetAsmName (Entry); /* Add the entry to the symbol table */ AddSymEntry (Tab, Entry); + } + /* If this is a function, do we wrap calls to it? */ + if (IsTypeFunc (Entry->Type)) { + SymEntry* WrappedCall; + unsigned int WrappedCallData; + + /* Always use the latest wrapper data for it */ + GetWrappedCall ((void**)&WrappedCall, &WrappedCallData); + if (WrappedCall) { + Entry->V.F.WrappedCall = WrappedCall; + Entry->V.F.WrappedCallData = WrappedCallData; + } } /* Add an alias of the global symbol to the local symbol table */ diff --git a/test/val/trampoline.c b/test/val/trampoline.c index 8f1e1547c..d3e73b47d 100644 --- a/test/val/trampoline.c +++ b/test/val/trampoline.c @@ -22,23 +22,23 @@ void func3() { } -#pragma wrapped-call(push, trampoline_inc, 0) - void func2() { func3(); } +#pragma wrapped-call(push, trampoline_inc, 0) + +void func2(void); + #pragma wrapped-call(push, trampoline_set, 4) -void func1(void); - -#pragma wrapped-call(pop) -#pragma wrapped-call(pop) - void func1(void) { func2(); } +#pragma wrapped-call(pop) +#pragma wrapped-call(pop) + int main(void) { flag = 0;