summaryrefslogtreecommitdiffstats
path: root/generic/tkObj.c
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2023-09-04 11:26:11 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2023-09-04 11:26:11 (GMT)
commitc95bf7bbbcab9035ac637890a738f95b6cf3aaae (patch)
tree6d8f3562d71ee5faded2a801bc3010b26cd9d5f4 /generic/tkObj.c
parent7c6c0958c653f1d01aac461a42154613ad44f926 (diff)
parent58d3fc25b8c6460bb4e314fc9716431ff90b8a94 (diff)
downloadtk-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.c53
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;