From 8f18fa7c78d11dad67f038dcd834c40ecc572780 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 27 Nov 2018 22:52:04 +0000 Subject: Make TclFreeObj MODULE_SCOPE, so the only way to access it is through the stub table, for backwards-compatible stub-enabled extensions --- generic/tcl.decls | 5 +++-- generic/tcl.h | 26 ++++++++++++++++++++++++++ generic/tclDecls.h | 9 ++++----- generic/tclInt.h | 1 + generic/tclStubInit.c | 4 +++- 5 files changed, 37 insertions(+), 8 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index f9e4763..367372d 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -132,8 +132,9 @@ declare 28 { declare 29 { Tcl_Obj *Tcl_DuplicateObj(Tcl_Obj *objPtr) } -declare 30 {deprecated {Kept only for deployed refcounting macros}} { - void TclFreeObj(Tcl_Obj *objPtr) +# Only available as stub-entry, for backwards-compatible stub-enabled extensions +declare 30 { + void TclOldFreeObj(Tcl_Obj *objPtr) } declare 31 { int Tcl_GetBoolean(Tcl_Interp *interp, const char *src, int *boolPtr) diff --git a/generic/tcl.h b/generic/tcl.h index 733bbc6..64ad440 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -2479,6 +2479,32 @@ EXTERN int TclZipfs_AppHook(int *argc, char ***argv); # undef Tcl_IsShared # define Tcl_IsShared(objPtr) \ Tcl_DbIsShared(objPtr, __FILE__, __LINE__) +#elif (!defined(TCL_NO_DEPRECATED) && defined(USE_TCL_STUBS)) +/* + * When compiling stub-enabled extensions without -DTCL_NO_DEPRECATED, + * those extensions are expected to run fine with Tcl 8.6 as well. + * This means we must continue to use macro's for the above 3 functions, + * and the old stub entry for TclFreeObj. All other usage of TclFreeObj() + * is forbidden now, therefore it is changed to be MODULE_SCOPE internal. + */ +# undef Tcl_IncrRefCount +# define Tcl_IncrRefCount(objPtr) \ + ++(objPtr)->refCount + /* + * Use do/while0 idiom for optimum correctness without compiler warnings. + * http://c2.com/cgi/wiki?TrivialDoWhileLoop + */ +# undef Tcl_DecrRefCount +# define Tcl_DecrRefCount(objPtr) \ + do { \ + Tcl_Obj *_objPtr = (objPtr); \ + if ((_objPtr)->refCount-- <= 1) { \ + TclOldFreeObj(_objPtr); \ + } \ + } while(0) +# undef Tcl_IsShared +# define Tcl_IsShared(objPtr) \ + ((objPtr)->refCount > 1) #endif /* diff --git a/generic/tclDecls.h b/generic/tclDecls.h index ed081ac..ad8fbbc 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -143,8 +143,7 @@ EXTERN Tcl_Obj * Tcl_DbNewStringObj(const char *bytes, int length, /* 29 */ EXTERN Tcl_Obj * Tcl_DuplicateObj(Tcl_Obj *objPtr); /* 30 */ -TCL_DEPRECATED("Kept only for deployed refcounting macros") -void TclFreeObj(Tcl_Obj *objPtr); +EXTERN void TclOldFreeObj(Tcl_Obj *objPtr); /* 31 */ EXTERN int Tcl_GetBoolean(Tcl_Interp *interp, const char *src, int *boolPtr); @@ -1953,7 +1952,7 @@ typedef struct TclStubs { Tcl_Obj * (*tcl_DbNewObj) (const char *file, int line); /* 27 */ Tcl_Obj * (*tcl_DbNewStringObj) (const char *bytes, int length, const char *file, int line); /* 28 */ Tcl_Obj * (*tcl_DuplicateObj) (Tcl_Obj *objPtr); /* 29 */ - TCL_DEPRECATED_API("Kept only for deployed refcounting macros") void (*tclFreeObj) (Tcl_Obj *objPtr); /* 30 */ + void (*tclOldFreeObj) (Tcl_Obj *objPtr); /* 30 */ int (*tcl_GetBoolean) (Tcl_Interp *interp, const char *src, int *boolPtr); /* 31 */ int (*tcl_GetBooleanFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *boolPtr); /* 32 */ unsigned char * (*tcl_GetByteArrayFromObj) (Tcl_Obj *objPtr, int *lengthPtr); /* 33 */ @@ -2661,8 +2660,8 @@ extern const TclStubs *tclStubsPtr; (tclStubsPtr->tcl_DbNewStringObj) /* 28 */ #define Tcl_DuplicateObj \ (tclStubsPtr->tcl_DuplicateObj) /* 29 */ -#define TclFreeObj \ - (tclStubsPtr->tclFreeObj) /* 30 */ +#define TclOldFreeObj \ + (tclStubsPtr->tclOldFreeObj) /* 30 */ #define Tcl_GetBoolean \ (tclStubsPtr->tcl_GetBoolean) /* 31 */ #define Tcl_GetBooleanFromObj \ diff --git a/generic/tclInt.h b/generic/tclInt.h index c1d90d2..9fc064e 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4119,6 +4119,7 @@ MODULE_SCOPE int TclObjCallVarTraces(Interp *iPtr, Var *arrayPtr, */ MODULE_SCOPE int TclCompareObjKeys(void *keyPtr, Tcl_HashEntry *hPtr); +MODULE_SCOPE void TclFreeObj(Tcl_Obj *objPtr); MODULE_SCOPE void TclFreeObjEntry(Tcl_HashEntry *hPtr); MODULE_SCOPE TCL_HASH_TYPE TclHashObjKey(Tcl_HashTable *tablePtr, void *keyPtr); diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index f58c7f1..106bb08 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -491,6 +491,7 @@ static int uniCharNcasecmp(const Tcl_UniChar *ucs, const Tcl_UniChar *uct, unsig # define Tcl_SetPanicProc 0 # define Tcl_FindExecutable 0 # define Tcl_GetUnicode 0 +# define TclOldFreeObj 0 #else /* TCL_NO_DEPRECATED */ # define Tcl_SeekOld seekOld # define Tcl_TellOld tellOld @@ -511,6 +512,7 @@ static int uniCharNcasecmp(const Tcl_UniChar *ucs, const Tcl_UniChar *uct, unsig # define TclGetCommandFullName Tcl_GetCommandFullName # define TclpLocaltime_unix TclpLocaltime # define TclpGmtime_unix TclpGmtime +# define TclOldFreeObj TclFreeObj static int seekOld( @@ -1062,7 +1064,7 @@ const TclStubs tclStubs = { Tcl_DbNewObj, /* 27 */ Tcl_DbNewStringObj, /* 28 */ Tcl_DuplicateObj, /* 29 */ - TclFreeObj, /* 30 */ + TclOldFreeObj, /* 30 */ Tcl_GetBoolean, /* 31 */ Tcl_GetBooleanFromObj, /* 32 */ Tcl_GetByteArrayFromObj, /* 33 */ -- cgit v0.12