From 12b55ed51dea5ca63f53c6aca59bfa5091984e49 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 13 Nov 2018 16:37:31 +0000 Subject: Implement TIP 506 --- generic/tcl.decls | 16 ++++++++++++- generic/tcl.h | 30 +++---------------------- generic/tclDecls.h | 20 +++++++++++++++-- generic/tclObj.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++ generic/tclStubInit.c | 3 +++ 5 files changed, 101 insertions(+), 30 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index f3d3e0d..fa22858 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -134,7 +134,7 @@ declare 28 { declare 29 { Tcl_Obj *Tcl_DuplicateObj(Tcl_Obj *objPtr) } -declare 30 { +declare 30 {deprecated {Kept only for deployed refcounting macros}} { void TclFreeObj(Tcl_Obj *objPtr) } declare 31 { @@ -2394,6 +2394,20 @@ declare 635 { unsigned char *data, size_t datalen, int copy) } + +# TIP #506 +declare 641 { + void Tcl_IncrRefCount(Tcl_Obj *objPtr) +} + +declare 642 { + void Tcl_DecrRefCount(Tcl_Obj *objPtr) +} + +declare 643 { + int Tcl_IsShared(Tcl_Obj *objPtr) +} + # ----- BASELINE -- FOR -- 8.7.0 ----- # ############################################################################## diff --git a/generic/tcl.h b/generic/tcl.h index 7d44ab2..a77211b 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -665,17 +665,6 @@ typedef struct Tcl_Obj { } internalRep; } Tcl_Obj; -/* - * Macros to increment and decrement a Tcl_Obj's reference count, and to test - * whether an object is shared (i.e. has reference count > 1). Note: clients - * should use Tcl_DecrRefCount() when they are finished using an object, and - * should never call TclFreeObj() directly. TclFreeObj() is only defined and - * made public in tcl.h to support Tcl_DecrRefCount's macro definition. - */ - -void Tcl_IncrRefCount(Tcl_Obj *objPtr); -void Tcl_DecrRefCount(Tcl_Obj *objPtr); -int Tcl_IsShared(Tcl_Obj *objPtr); /* *---------------------------------------------------------------------------- @@ -2306,28 +2295,15 @@ EXTERN int TclZipfs_AppHook(int *argc, char ***argv); #endif /* !TCL_MEM_DEBUG */ #ifdef TCL_MEM_DEBUG +# undef Tcl_IncrRefCount # define Tcl_IncrRefCount(objPtr) \ Tcl_DbIncrRefCount(objPtr, __FILE__, __LINE__) +# undef Tcl_DecrRefCount # define Tcl_DecrRefCount(objPtr) \ Tcl_DbDecrRefCount(objPtr, __FILE__, __LINE__) +# undef Tcl_IsShared # define Tcl_IsShared(objPtr) \ Tcl_DbIsShared(objPtr, __FILE__, __LINE__) -#else -# define Tcl_IncrRefCount(objPtr) \ - ++(objPtr)->refCount - /* - * Use do/while0 idiom for optimum correctness without compiler warnings. - * http://c2.com/cgi/wiki?TrivialDoWhileLoop - */ -# define Tcl_DecrRefCount(objPtr) \ - do { \ - Tcl_Obj *_objPtr = (objPtr); \ - if ((_objPtr)->refCount-- <= 1) { \ - TclFreeObj(_objPtr); \ - } \ - } while(0) -# define Tcl_IsShared(objPtr) \ - ((objPtr)->refCount > 1) #endif /* diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 169d1ac..d2403c6 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -137,7 +137,8 @@ EXTERN Tcl_Obj * Tcl_DbNewStringObj(const char *bytes, size_t length, /* 29 */ EXTERN Tcl_Obj * Tcl_DuplicateObj(Tcl_Obj *objPtr); /* 30 */ -EXTERN void TclFreeObj(Tcl_Obj *objPtr); +TCL_DEPRECATED("Kept only for deployed refcounting macros") +void TclFreeObj(Tcl_Obj *objPtr); /* 31 */ EXTERN int Tcl_GetBoolean(Tcl_Interp *interp, const char *src, int *boolPtr); @@ -1741,6 +1742,12 @@ EXTERN Tcl_Obj * TclZipfs_TclLibrary(void); EXTERN int TclZipfs_MountBuffer(Tcl_Interp *interp, const char *mountPoint, unsigned char *data, size_t datalen, int copy); +/* 641 */ +EXTERN void Tcl_IncrRefCount(Tcl_Obj *objPtr); +/* 642 */ +EXTERN void Tcl_DecrRefCount(Tcl_Obj *objPtr); +/* 643 */ +EXTERN int Tcl_IsShared(Tcl_Obj *objPtr); typedef struct { const struct TclPlatStubs *tclPlatStubs; @@ -1798,7 +1805,7 @@ typedef struct TclStubs { Tcl_Obj * (*tcl_DbNewObj) (const char *file, int line); /* 27 */ Tcl_Obj * (*tcl_DbNewStringObj) (const char *bytes, size_t length, const char *file, int line); /* 28 */ Tcl_Obj * (*tcl_DuplicateObj) (Tcl_Obj *objPtr); /* 29 */ - void (*tclFreeObj) (Tcl_Obj *objPtr); /* 30 */ + TCL_DEPRECATED_API("Kept only for deployed refcounting macros") void (*tclFreeObj) (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 */ @@ -2412,6 +2419,9 @@ typedef struct TclStubs { int (*tclZipfs_Unmount) (Tcl_Interp *interp, const char *mountPoint); /* 633 */ Tcl_Obj * (*tclZipfs_TclLibrary) (void); /* 634 */ int (*tclZipfs_MountBuffer) (Tcl_Interp *interp, const char *mountPoint, unsigned char *data, size_t datalen, int copy); /* 635 */ + void (*tcl_IncrRefCount) (Tcl_Obj *objPtr); /* 641 */ + void (*tcl_DecrRefCount) (Tcl_Obj *objPtr); /* 642 */ + int (*tcl_IsShared) (Tcl_Obj *objPtr); /* 643 */ } TclStubs; extern const TclStubs *tclStubsPtr; @@ -3668,6 +3678,12 @@ extern const TclStubs *tclStubsPtr; (tclStubsPtr->tclZipfs_TclLibrary) /* 634 */ #define TclZipfs_MountBuffer \ (tclStubsPtr->tclZipfs_MountBuffer) /* 635 */ +#define Tcl_IncrRefCount \ + (tclStubsPtr->tcl_IncrRefCount) /* 641 */ +#define Tcl_DecrRefCount \ + (tclStubsPtr->tcl_DecrRefCount) /* 642 */ +#define Tcl_IsShared \ + (tclStubsPtr->tcl_IsShared) /* 643 */ #endif /* defined(USE_TCL_STUBS) */ diff --git a/generic/tclObj.c b/generic/tclObj.c index db9f896..f3df304 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -3221,6 +3221,68 @@ TclGetNumberFromObj( /* *---------------------------------------------------------------------- * + * Tcl_IncrRefCount -- + * + * Increments the reference count of the object. + * + * Results: + * None. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_IncrRefCount( + Tcl_Obj *objPtr) /* The object we are registering a reference to. */ +{ + ++(objPtr)->refCount; +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_DecrRefCount -- + * + * Decrements the reference count of the object. + * + * Results: + * None. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_DecrRefCount( + Tcl_Obj *objPtr) /* The object we are releasing a reference to. */ +{ + if (objPtr->refCount-- <= 1) { + TclFreeObj(objPtr); + } +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_IsShared -- + * + * Tests if the object has a ref count greater than one. + * + * Results: + * Boolean value that is the result of the test. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_IsShared( + Tcl_Obj *objPtr) /* The object to test for being shared. */ +{ + return ((objPtr)->refCount > 1); +} + +/* + *---------------------------------------------------------------------- + * * Tcl_DbIncrRefCount -- * * This function is normally called when debugging: i.e., when diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 9e7d33c..327060c 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -1327,6 +1327,9 @@ const TclStubs tclStubs = { TclZipfs_Unmount, /* 633 */ TclZipfs_TclLibrary, /* 634 */ TclZipfs_MountBuffer, /* 635 */ + Tcl_IncrRefCount, /* 641 */ + Tcl_DecrRefCount, /* 642 */ + Tcl_IsShared, /* 643 */ }; /* !END!: Do not edit above this line. */ -- cgit v0.12