diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2023-09-04 11:26:11 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2023-09-04 11:26:11 (GMT) |
commit | c95bf7bbbcab9035ac637890a738f95b6cf3aaae (patch) | |
tree | 6d8f3562d71ee5faded2a801bc3010b26cd9d5f4 /generic/tkObj.c | |
parent | 7c6c0958c653f1d01aac461a42154613ad44f926 (diff) | |
parent | 58d3fc25b8c6460bb4e314fc9716431ff90b8a94 (diff) | |
download | tk-c95bf7bbbcab9035ac637890a738f95b6cf3aaae.zip tk-c95bf7bbbcab9035ac637890a738f95b6cf3aaae.tar.gz tk-c95bf7bbbcab9035ac637890a738f95b6cf3aaae.tar.bz2 |
Merge 8.7. More progress in converting strtod/strtol
Diffstat (limited to 'generic/tkObj.c')
-rw-r--r-- | generic/tkObj.c | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/generic/tkObj.c b/generic/tkObj.c index 641f419..8978886 100644 --- a/generic/tkObj.c +++ b/generic/tkObj.c @@ -40,6 +40,19 @@ typedef struct PixelRep { ((PixelRep *) (objPtr)->internalRep.twoPtrValue.ptr2) /* + * One of these structures is created per thread to store thread-specific + * data. In this case, it is used to contain references to selected + * Tcl_ObjTypes that we can use as screen distances without conversion. The + * "dataKey" below is used to locate the ThreadSpecificData for the current + * thread. + */ + +typedef struct { + const Tcl_ObjType *doubleTypePtr; +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; + +/* * The following structure is the internal representation for mm objects. */ @@ -77,6 +90,7 @@ static void DupWindowInternalRep(Tcl_Obj *srcPtr,Tcl_Obj*copyPtr); static void FreeMMInternalRep(Tcl_Obj *objPtr); static void FreePixelInternalRep(Tcl_Obj *objPtr); static void FreeWindowInternalRep(Tcl_Obj *objPtr); +static ThreadSpecificData *GetTypeCache(void); static void UpdateStringOfMM(Tcl_Obj *objPtr); static int SetMMFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); static int SetPixelFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); @@ -161,6 +175,37 @@ static const TkObjType windowObjType = { /* *---------------------------------------------------------------------- * + * GetTypeCache -- + * + * Get (and build if necessary) the cache of useful Tcl object types for + * comparisons in the conversion functions. This allows optimized checks + * for standard cases. + * + *---------------------------------------------------------------------- + */ + +static ThreadSpecificData * +GetTypeCache(void) +{ + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + if (tsdPtr->doubleTypePtr == NULL) { + /* Smart initialization of doubleTypePtr without + * hash-table lookup or creating complete Tcl_Obj's */ + Tcl_Obj obj; + obj.length = 3; + obj.bytes = (char *)"0.0"; + obj.typePtr = NULL; + Tcl_GetDoubleFromObj(NULL, &obj, &obj.internalRep.doubleValue); + tsdPtr->doubleTypePtr = obj.typePtr; + } + return tsdPtr; +} + +/* + *---------------------------------------------------------------------- + * * TkGetIntForIndex -- * * Almost the same as Tcl_GetIntForIndex, but it retrieves an int. Accepts @@ -465,13 +510,15 @@ SetPixelFromAny( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ Tcl_Obj *objPtr) /* The object to convert. */ { + ThreadSpecificData *typeCache = GetTypeCache(); const Tcl_ObjType *typePtr; char *string; char *rest; double d; int i, units; - if (Tcl_GetIntFromObj(NULL, objPtr, &units) == TCL_OK) { + if (objPtr->typePtr != typeCache->doubleTypePtr + && Tcl_GetIntFromObj(NULL, objPtr, &units) == TCL_OK) { d = (double) units; units = -1; @@ -742,6 +789,7 @@ SetMMFromAny( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ Tcl_Obj *objPtr) /* The object to convert. */ { + ThreadSpecificData *typeCache = GetTypeCache(); const Tcl_ObjType *typePtr; char *string; char *rest; @@ -749,7 +797,8 @@ SetMMFromAny( int units; MMRep *mmPtr; - if (Tcl_GetIntFromObj(NULL, objPtr, &units) == TCL_OK) { + if (objPtr->typePtr != typeCache->doubleTypePtr + && Tcl_GetIntFromObj(NULL, objPtr, &units) == TCL_OK) { d = (double) units; units = -1; |