Tk Source Code

Check-in [b6dad9ba]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:A better way of managing the type cache across the tkObj.c file.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | core-8-5-branch
Files: files | file ages | folders
SHA1: b6dad9bade6cc2e9e80fa4479da14115f007d2c3
User & Date: dkf 2011-11-02 09:25:53
Context
2011-11-07
17:23
merge release to dev check-in: 39b87b42 user: dgp tags: core-8-5-branch
2011-11-04
12:45
merge, tag & bag another 8.5.11 RC Closed-Leaf check-in: 51558497 user: dgp tags: core-8-5-11, core-8-5-11-rc
2011-11-02
09:31
A better way of managing the type cache across the tkObj.c file. check-in: 8c2f350d user: dkf tags: trunk
09:25
A better way of managing the type cache across the tkObj.c file. check-in: b6dad9ba user: dkf tags: core-8-5-branch
2011-11-01
22:46
* generic/tkObj.c (GetPixelsFromObjEx): [Bug 3431491]: Use a bit of type hackery to allow numbers to be interpreted as coordinates (most notably on a canvas) without reinterpreting via a string.
check-in: 6a735cbb user: dkf tags: core-8-5-branch
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tkObj.c.

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
 * 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 ThreadSpecificData {
    Tcl_ObjType *doubleTypePtr;
    Tcl_ObjType *intTypePtr;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * The following structure is the internal representation for mm objects.
 */








|
|







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
 * 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 ThreadSpecificData {
    const Tcl_ObjType *doubleTypePtr;
    const Tcl_ObjType *intTypePtr;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * The following structure is the internal representation for mm objects.
 */

83
84
85
86
87
88
89

90
91
92
93
94
95
96

static void		DupMMInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr);
static void		DupPixelInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr);
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 void		UpdateStringOfMM(Tcl_Obj *objPtr);
static int		SetMMFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static int		SetPixelFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static int		SetWindowFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);

/*
 * The following structure defines the implementation of the "pixel" Tcl







>







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

static void		DupMMInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr);
static void		DupPixelInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr);
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);
static int		SetWindowFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);

/*
 * The following structure defines the implementation of the "pixel" Tcl
132
133
134
135
136
137
138

























139
140
141
142
143
144
145
    NULL,			/* updateStringProc */
    SetWindowFromAny		/* setFromAnyProc */
};

/*
 *----------------------------------------------------------------------
 *

























 * GetPixelsFromObjEx --
 *
 *	Attempt to return a pixel value from the Tcl object "objPtr". If the
 *	object is not already a pixel value, an attempt will be made to
 *	convert it to one.
 *
 * Results:







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
    NULL,			/* updateStringProc */
    SetWindowFromAny		/* setFromAnyProc */
};

/*
 *----------------------------------------------------------------------
 *
 * 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()
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (tsdPtr->doubleTypePtr == NULL) {
	tsdPtr->doubleTypePtr = Tcl_GetObjType("double");
	tsdPtr->intTypePtr = Tcl_GetObjType("int");
    }
    return tsdPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * GetPixelsFromObjEx --
 *
 *	Attempt to return a pixel value from the Tcl object "objPtr". If the
 *	object is not already a pixel value, an attempt will be made to
 *	convert it to one.
 *
 * Results:
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
     * Special hacks where the type of the object is known to be something
     * that is just numeric and cannot require distance conversion. This pokes
     * holes in Tcl's abstractions, but they are just for optimization, not
     * semantics.
     */

    if (objPtr->typePtr != &pixelObjType) {
	ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
		Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

	if (tsdPtr->doubleTypePtr == NULL) {
	    tsdPtr->doubleTypePtr = Tcl_GetObjType("double");
	    tsdPtr->intTypePtr = Tcl_GetObjType("int");
	}

	if (objPtr->typePtr == tsdPtr->doubleTypePtr) {
	    (void) Tcl_GetDoubleFromObj(interp, objPtr, &d);
	    if (dblPtr != NULL) {
		*dblPtr = d;
	    }
	    *intPtr = (int) d;







|
<
<
<
<
<
<







200
201
202
203
204
205
206
207






208
209
210
211
212
213
214
     * Special hacks where the type of the object is known to be something
     * that is just numeric and cannot require distance conversion. This pokes
     * holes in Tcl's abstractions, but they are just for optimization, not
     * semantics.
     */

    if (objPtr->typePtr != &pixelObjType) {
	ThreadSpecificData *tsdPtr = GetTypeCache();







	if (objPtr->typePtr == tsdPtr->doubleTypePtr) {
	    (void) Tcl_GetDoubleFromObj(interp, objPtr, &d);
	    if (dblPtr != NULL) {
		*dblPtr = d;
	    }
	    *intPtr = (int) d;
683
684
685
686
687
688
689

690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
 */

static int
SetMMFromAny(
    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr)		/* The object to convert. */
{

    const Tcl_ObjType *typePtr;
    char *string, *rest;
    double d;
    int units;
    MMRep *mmPtr;

    static const Tcl_ObjType *tclDoubleObjType = NULL;
    static const Tcl_ObjType *tclIntObjType = NULL;

    if (tclDoubleObjType == NULL) {
	/*
	 * Cache the object types for comaprison below. This allows optimized
	 * checks for standard cases.
	 */

	tclDoubleObjType = Tcl_GetObjType("double");
	tclIntObjType    = Tcl_GetObjType("int");
    }

    if (objPtr->typePtr == tclDoubleObjType) {
	Tcl_GetDoubleFromObj(interp, objPtr, &d);
	units = -1;
    } else if (objPtr->typePtr == tclIntObjType) {
	Tcl_GetIntFromObj(interp, objPtr, &units);
	d = (double) units;
	units = -1;

	/*
	 * In the case of ints, we need to ensure that a valid string exists
	 * in order for int-but-not-string objects to be converted back to







>






<
<
<
<
<
<
<
<
<
<
<
<
<
|


|







703
704
705
706
707
708
709
710
711
712
713
714
715
716













717
718
719
720
721
722
723
724
725
726
727
 */

static int
SetMMFromAny(
    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr)		/* The object to convert. */
{
    ThreadSpecificData *tsdPtr = GetTypeCache();
    const Tcl_ObjType *typePtr;
    char *string, *rest;
    double d;
    int units;
    MMRep *mmPtr;














    if (objPtr->typePtr == tsdPtr->doubleTypePtr) {
	Tcl_GetDoubleFromObj(interp, objPtr, &d);
	units = -1;
    } else if (objPtr->typePtr == tsdPtr->intTypePtr) {
	Tcl_GetIntFromObj(interp, objPtr, &units);
	d = (double) units;
	units = -1;

	/*
	 * In the case of ints, we need to ensure that a valid string exists
	 * in order for int-but-not-string objects to be converted back to