Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | merge trunk |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | dgp-properbytearray |
Files: | files | file ages | folders |
SHA3-256: |
d03f410e2ae15593b887122f16149f43 |
User & Date: | dgp 2019-06-12 19:04:04.970 |
Context
2019-06-17
| ||
18:29 | merge trunk check-in: fa4cdb8590 user: dgp tags: dgp-properbytearray | |
2019-06-12
| ||
19:04 | merge trunk check-in: d03f410e2a user: dgp tags: dgp-properbytearray | |
15:42 | Merge 8.7 check-in: c5ff3f41bd user: jan.nijtmans tags: trunk | |
2019-06-09
| ||
21:21 | Merge trunk check-in: 86b6e6c0a9 user: jan.nijtmans tags: dgp-properbytearray | |
Changes
Changes to doc/expr.n.
︙ | ︙ | |||
91 92 93 94 95 96 97 | \fBTcl\fR. .PP Below are some examples of simple expressions where the value of \fBa\fR is 3 and the value of \fBb\fR is 6. The command on the left side of each line produces the value on the right side. .PP .CS | | | 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | \fBTcl\fR. .PP Below are some examples of simple expressions where the value of \fBa\fR is 3 and the value of \fBb\fR is 6. The command on the left side of each line produces the value on the right side. .PP .CS .ta 9c \fBexpr\fR 3.1 + $a \fI6.1\fR \fBexpr\fR 2 + "$a.$b" \fI5.6\fR \fBexpr\fR 4*[llength "6 2"] \fI8\fR \fBexpr\fR {{word one} < "word $a"} \fI0\fR .CE .SS OPERATORS .PP |
︙ | ︙ | |||
184 185 186 187 188 189 190 | \fB|\fR . Bit-wise OR. Valid for integer operands. .TP 20 \fB&&\fR . Logical AND. If both operands are true, the result is 1, or 0 otherwise. | | > > > > > > > | 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | \fB|\fR . Bit-wise OR. Valid for integer operands. .TP 20 \fB&&\fR . Logical AND. If both operands are true, the result is 1, or 0 otherwise. This operator evaluates lazily; it only evaluates its second operand if it must in order to determine its result. This operator evaluates lazily; it only evaluates its second operand if it must in order to determine its result. .TP 20 \fB||\fR . Logical OR. If both operands are false, the result is 0, or 1 otherwise. This operator evaluates lazily; it only evaluates its second operand if it must in order to determine its result. .TP 20 \fIx\fB?\fIy\fB:\fIz\fR . If-then-else, as in C. If \fIx\fR is false , the result is the value of \fIy\fR. Otherwise the result is the value of \fIz\fR. This operator evaluates lazily; it evaluates only one of \fIy\fR or \fIz\fR. .PP The exponentiation operator promotes types in the same way that the multiply and divide operators do, and the result is is the same as the result of \fBpow\fR. Exponentiation groups right-to-left within a precedence level. Other binary operators group left-to-right. For example, the value of .PP .PP .CS \fBexpr\fR {4*2 < 7} .CE .PP is 0, while the value of .PP |
︙ | ︙ | |||
331 332 333 334 335 336 337 | substitutions on, enclosing an expression in braces or otherwise quoting it so that it's a static value allows the Tcl compiler to generate bytecode for the expression, resulting in better speed and smaller storage requirements. This also avoids issues that can arise if Tcl is allowed to perform substitution on the value before \fBexpr\fR is called. .PP In the following example, the value of the expression is 11 because the Tcl parser first | | > > > | > > < | | > > > > > > > > > > > > > > > > > > > > > > | 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 | substitutions on, enclosing an expression in braces or otherwise quoting it so that it's a static value allows the Tcl compiler to generate bytecode for the expression, resulting in better speed and smaller storage requirements. This also avoids issues that can arise if Tcl is allowed to perform substitution on the value before \fBexpr\fR is called. .PP In the following example, the value of the expression is 11 because the Tcl parser first substitutes \fB$b\fR and \fBexpr\fR then substitutes \fB$a\fR as part of evaluating the expression .QW "$a + 2*4" . Enclosing the expression in braces would result in a syntax error as \fB$b\fR does not evaluate to a numeric value. .PP .CS set a 3 set b {$a + 2} \fBexpr\fR $b*4 .CE .PP When an expression is generated at runtime, like the one above is, the bytecode compiler must ensure that new code is generated each time the expression is evaluated. This is the most costly kind of expression from a performance perspective. In such cases, consider directly using the commands described in the \fBmathfunc\fR(n) or \fBmathop\fR(n) documentation instead of \fBexpr\fR. .PP Most expressions are not formed at runtime, but are literal strings or contain substitutions that don't introduce other substitutions. To allow the bytecode compiler to work with an expression as a string literal at compilation time, ensure that it contains no substitutions or that it is enclosed in braces or otherwise quoted to prevent Tcl from performing substitutions, allowing \fBexpr\fR to perform them instead. .PP If it is necessary to include a non-constant expression string within the wider context of an otherwise-constant expression, the most efficient technique is to put the varying part inside a recursive \fBexpr\fR, as this at least allows for the compilation of the outer part, though it does mean that the varying part must itself be evaluated as a separate expression. Thus, in this example the result is 20 and the outer expression benefits from fully cached bytecode compilation. .PP .CS set a 3 set b {$a + 2} \fBexpr\fR {[\fBexpr\fR $b] * 4} .CE .PP In general, you should enclose your expression in braces wherever possible, and where not possible, the argument to \fBexpr\fR should be an expression defined elsewhere as simply as possible. It is usually more efficient and safer to use other techniques (e.g., the commands in the \fBtcl::mathop\fR namespace) than it is to do complex expression generation. .SH EXAMPLES .PP A numeric comparison whose result is 1: .PP .CS \fBexpr\fR {"0x03" > "2"} .CE .PP A string comparison whose result is 1: .PP .CS \fBexpr\fR {"0y" > "0x12"} .CE .PP Define a procedure that computes an .QW interesting mathematical function: |
︙ | ︙ |
Changes to generic/tclAssembly.c.
︙ | ︙ | |||
511 512 513 514 515 516 517 518 519 520 521 522 523 524 | * The instructions must be in ascending order by numeric operation code. */ static const unsigned char NonThrowingByteCodes[] = { INST_PUSH1, INST_PUSH4, INST_POP, INST_DUP, /* 1-4 */ INST_JUMP1, INST_JUMP4, /* 34-35 */ INST_END_CATCH, INST_PUSH_RESULT, INST_PUSH_RETURN_CODE, /* 70-72 */ INST_LIST, /* 79 */ INST_OVER, /* 95 */ INST_PUSH_RETURN_OPTIONS, /* 108 */ INST_REVERSE, /* 126 */ INST_NOP, /* 132 */ INST_STR_MAP, /* 143 */ INST_STR_FIND, /* 144 */ | > | 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 | * The instructions must be in ascending order by numeric operation code. */ static const unsigned char NonThrowingByteCodes[] = { INST_PUSH1, INST_PUSH4, INST_POP, INST_DUP, /* 1-4 */ INST_JUMP1, INST_JUMP4, /* 34-35 */ INST_END_CATCH, INST_PUSH_RESULT, INST_PUSH_RETURN_CODE, /* 70-72 */ INST_STR_EQ, INST_STR_NEQ, INST_STR_CMP, INST_STR_LEN, /* 73-76 */ INST_LIST, /* 79 */ INST_OVER, /* 95 */ INST_PUSH_RETURN_OPTIONS, /* 108 */ INST_REVERSE, /* 126 */ INST_NOP, /* 132 */ INST_STR_MAP, /* 143 */ INST_STR_FIND, /* 144 */ |
︙ | ︙ |
Changes to generic/tclBasic.c.
︙ | ︙ | |||
577 578 579 580 581 582 583 | } #if defined(_WIN32) && !defined(_WIN64) if (sizeof(time_t) != 4) { /*NOTREACHED*/ Tcl_Panic("<time.h> is not compatible with MSVC"); } | | | | 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 | } #if defined(_WIN32) && !defined(_WIN64) if (sizeof(time_t) != 4) { /*NOTREACHED*/ Tcl_Panic("<time.h> is not compatible with MSVC"); } if ((offsetof(Tcl_StatBuf,st_atime) != 32) || (offsetof(Tcl_StatBuf,st_ctime) != 40)) { /*NOTREACHED*/ Tcl_Panic("<sys/stat.h> is not compatible with MSVC"); } #endif if (cancelTableInitialized == 0) { Tcl_MutexLock(&cancelLock); |
︙ | ︙ |
Changes to generic/tclBinary.c.
︙ | ︙ | |||
258 259 260 261 262 263 264 | * minus 1 byte. */ unsigned char bytes[1]; /* The array of bytes. The actual size of this * field depends on the 'allocated' field * above. */ } ByteArray; #define BYTEARRAY_SIZE(len) \ | | | 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | * minus 1 byte. */ unsigned char bytes[1]; /* The array of bytes. The actual size of this * field depends on the 'allocated' field * above. */ } ByteArray; #define BYTEARRAY_SIZE(len) \ (offsetof(ByteArray, bytes) + (len)) #define GET_BYTEARRAY(irPtr) ((ByteArray *) (irPtr)->twoPtrValue.ptr1) #define SET_BYTEARRAY(irPtr, baPtr) \ (irPtr)->twoPtrValue.ptr1 = (baPtr) int TclIsPureByteArray( Tcl_Obj * objPtr) |
︙ | ︙ |
Changes to generic/tclCkalloc.c.
︙ | ︙ | |||
35 36 37 38 39 40 41 | size_t refCount; /* Number of mem_headers referencing this * tag. */ char string[1]; /* Actual size of string will be as large as * needed for actual tag. This must be the * last field in the structure. */ } MemTag; | | | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | size_t refCount; /* Number of mem_headers referencing this * tag. */ char string[1]; /* Actual size of string will be as large as * needed for actual tag. This must be the * last field in the structure. */ } MemTag; #define TAG_SIZE(bytesInString) ((offsetof(MemTag, string) + 1) + bytesInString) static MemTag *curTagPtr = NULL;/* Tag to use in all future mem_headers (set * by "memory tag" command). */ /* * One of the following structures is allocated just before each dynamically * allocated chunk of memory, both to record information about the chunk and |
︙ | ︙ |
Changes to generic/tclCompile.c.
︙ | ︙ | |||
3008 3009 3010 3011 3012 3013 3014 | /* * Create a new variable if appropriate. */ if (create || (name == NULL)) { localVar = procPtr->numCompiledLocals; | | | 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 | /* * Create a new variable if appropriate. */ if (create || (name == NULL)) { localVar = procPtr->numCompiledLocals; localPtr = Tcl_Alloc(offsetof(CompiledLocal, name) + nameBytes + 1); if (procPtr->firstLocalPtr == NULL) { procPtr->firstLocalPtr = procPtr->lastLocalPtr = localPtr; } else { procPtr->lastLocalPtr->nextPtr = localPtr; procPtr->lastLocalPtr = localPtr; } localPtr->nextPtr = NULL; |
︙ | ︙ |
Changes to generic/tclExecute.c.
︙ | ︙ | |||
149 150 151 152 153 154 155 | } while (0) /* * These variable-access macros have to coincide with those in tclVar.c */ #define VarHashGetValue(hPtr) \ | | | 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | } while (0) /* * These variable-access macros have to coincide with those in tclVar.c */ #define VarHashGetValue(hPtr) \ ((Var *) ((char *)hPtr - offsetof(VarInHash, entry))) static inline Var * VarHashCreateVar( TclVarHashTable *tablePtr, Tcl_Obj *key, int *newPtr) { |
︙ | ︙ |
Changes to generic/tclHash.c.
︙ | ︙ | |||
778 779 780 781 782 783 784 | Tcl_HashEntry *hPtr; size_t size, allocsize; allocsize = size = strlen(string) + 1; if (size < sizeof(hPtr->key)) { allocsize = sizeof(hPtr->key); } | | | 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 | Tcl_HashEntry *hPtr; size_t size, allocsize; allocsize = size = strlen(string) + 1; if (size < sizeof(hPtr->key)) { allocsize = sizeof(hPtr->key); } hPtr = Tcl_Alloc(offsetof(Tcl_HashEntry, key) + allocsize); memcpy(hPtr->key.string, string, size); Tcl_SetHashValue(hPtr, NULL); return hPtr; } /* *---------------------------------------------------------------------- |
︙ | ︙ |
Changes to generic/tclIO.h.
︙ | ︙ | |||
46 47 48 49 50 51 52 | /* Next buffer in chain. */ char buf[1]; /* Placeholder for real buffer. The real * buffer occuppies this space + bufSize-1 * bytes. This must be the last field in the * structure. */ } ChannelBuffer; | | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | /* Next buffer in chain. */ char buf[1]; /* Placeholder for real buffer. The real * buffer occuppies this space + bufSize-1 * bytes. This must be the last field in the * structure. */ } ChannelBuffer; #define CHANNELBUFFER_HEADER_SIZE offsetof(ChannelBuffer, buf) /* * How much extra space to allocate in buffer to hold bytes from previous * buffer (when converting to UTF-8) or to hold bytes that will go to next * buffer (when converting from UTF-8). */ |
︙ | ︙ |
Changes to generic/tclInt.h.
︙ | ︙ | |||
60 61 62 63 64 65 66 | #endif #ifdef NO_STRING_H #include "../compat/string.h" #else #include <string.h> #endif #if defined(STDC_HEADERS) || defined(__STDC__) || defined(__C99__FUNC__) \ | | | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | #endif #ifdef NO_STRING_H #include "../compat/string.h" #else #include <string.h> #endif #if defined(STDC_HEADERS) || defined(__STDC__) || defined(__C99__FUNC__) \ || defined(__cplusplus) || defined(_MSC_VER) || defined(__ICC) #include <stddef.h> #else typedef int ptrdiff_t; #endif /* * Ensure WORDS_BIGENDIAN is defined correctly: |
︙ | ︙ | |||
3949 3950 3951 3952 3953 3954 3955 | struct CompileEnv *envPtr); MODULE_SCOPE int TclDivOpCmd(void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE int TclCompileDivOpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); | < < < < < < < < < < < < < < < < < < | 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 | struct CompileEnv *envPtr); MODULE_SCOPE int TclDivOpCmd(void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE int TclCompileDivOpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileLessOpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileLeqOpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileGreaterOpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileGeqOpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileEqOpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileStreqOpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileAssembleCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); |
︙ | ︙ | |||
4833 4834 4835 4836 4837 4838 4839 | # ifdef NO_ISNAN # define TclIsNaN(d) ((d) != (d)) # else # define TclIsNaN(d) (isnan(d)) # endif #endif | < < < < < | | < < | | 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 | # ifdef NO_ISNAN # define TclIsNaN(d) ((d) != (d)) # else # define TclIsNaN(d) (isnan(d)) # endif #endif /* Workaround for platforms missing offsetof(), e.g. VC++ 6.0 */ #ifndef offsetof # define offsetof(type, field) ((size_t) ((char *) &((type *) 0)->field)) #endif /* *---------------------------------------------------------------- * Inline version of Tcl_GetCurrentNamespace and Tcl_GetGlobalNamespace. */ |
︙ | ︙ |
Changes to generic/tclOOMethod.c.
︙ | ︙ | |||
117 118 119 120 121 122 123 | /* * Helper macros (derived from things private to tclVar.c) */ #define TclVarTable(contextNs) \ ((Tcl_HashTable *) (&((Namespace *) (contextNs))->varTable)) #define TclVarHashGetValue(hPtr) \ | | | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | /* * Helper macros (derived from things private to tclVar.c) */ #define TclVarTable(contextNs) \ ((Tcl_HashTable *) (&((Namespace *) (contextNs))->varTable)) #define TclVarHashGetValue(hPtr) \ ((Tcl_Var) ((char *)hPtr - offsetof(VarInHash, entry))) /* * ---------------------------------------------------------------------- * * Tcl_NewInstanceMethod -- * * Attach a method to an object instance. |
︙ | ︙ |
Changes to generic/tclProc.c.
︙ | ︙ | |||
630 631 632 633 634 635 636 | localPtr = localPtr->nextPtr; } else { /* * Allocate an entry in the runtime procedure frame's array of * local variables for the argument. */ | | | 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 | localPtr = localPtr->nextPtr; } else { /* * Allocate an entry in the runtime procedure frame's array of * local variables for the argument. */ localPtr = Tcl_Alloc(offsetof(CompiledLocal, name) + fieldValues[0]->length +1); if (procPtr->firstLocalPtr == NULL) { procPtr->firstLocalPtr = procPtr->lastLocalPtr = localPtr; } else { procPtr->lastLocalPtr->nextPtr = localPtr; procPtr->lastLocalPtr = localPtr; } localPtr->nextPtr = NULL; |
︙ | ︙ |
Changes to generic/tclTest.c.
︙ | ︙ | |||
7699 7700 7701 7702 7703 7704 7705 | if (resVarInfo->var) { HashVarFree(resVarInfo->var); } Tcl_Free(vInfoPtr); } #define TclVarHashGetValue(hPtr) \ | | | 7699 7700 7701 7702 7703 7704 7705 7706 7707 7708 7709 7710 7711 7712 7713 | if (resVarInfo->var) { HashVarFree(resVarInfo->var); } Tcl_Free(vInfoPtr); } #define TclVarHashGetValue(hPtr) \ ((Var *) ((char *)hPtr - offsetof(VarInHash, entry))) static Tcl_Var MyCompiledVarFetch( Tcl_Interp *interp, Tcl_ResolvedVarInfo *vinfoPtr) { MyResolvedVarInfo *resVarInfo = (MyResolvedVarInfo *) vinfoPtr; |
︙ | ︙ |
Changes to generic/tclTrace.c.
︙ | ︙ | |||
467 468 469 470 471 472 473 | break; } } command = TclGetStringFromObj(objv[5], &commandLength); length = commandLength; if ((enum traceOptions) optionIndex == TRACE_ADD) { TraceCommandInfo *tcmdPtr = Tcl_Alloc( | | | 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 | break; } } command = TclGetStringFromObj(objv[5], &commandLength); length = commandLength; if ((enum traceOptions) optionIndex == TRACE_ADD) { TraceCommandInfo *tcmdPtr = Tcl_Alloc( offsetof(TraceCommandInfo, command) + 1 + length); tcmdPtr->flags = flags; tcmdPtr->stepTrace = NULL; tcmdPtr->startLevel = 0; tcmdPtr->startCmd = NULL; tcmdPtr->length = length; tcmdPtr->refCount = 1; |
︙ | ︙ | |||
704 705 706 707 708 709 710 | } } command = TclGetStringFromObj(objv[5], &commandLength); length = commandLength; if ((enum traceOptions) optionIndex == TRACE_ADD) { TraceCommandInfo *tcmdPtr = Tcl_Alloc( | | | 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 | } } command = TclGetStringFromObj(objv[5], &commandLength); length = commandLength; if ((enum traceOptions) optionIndex == TRACE_ADD) { TraceCommandInfo *tcmdPtr = Tcl_Alloc( offsetof(TraceCommandInfo, command) + 1 + length); tcmdPtr->flags = flags; tcmdPtr->stepTrace = NULL; tcmdPtr->startLevel = 0; tcmdPtr->startCmd = NULL; tcmdPtr->length = length; tcmdPtr->refCount = 1; |
︙ | ︙ | |||
907 908 909 910 911 912 913 | break; } } command = TclGetStringFromObj(objv[5], &commandLength); length = commandLength; if ((enum traceOptions) optionIndex == TRACE_ADD) { CombinedTraceVarInfo *ctvarPtr = Tcl_Alloc( | | | 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 | break; } } command = TclGetStringFromObj(objv[5], &commandLength); length = commandLength; if ((enum traceOptions) optionIndex == TRACE_ADD) { CombinedTraceVarInfo *ctvarPtr = Tcl_Alloc( offsetof(CombinedTraceVarInfo, traceCmdInfo.command) + 1 + length); ctvarPtr->traceCmdInfo.flags = flags; #ifndef TCL_REMOVE_OBSOLETE_TRACES if (objv[0] == NULL) { ctvarPtr->traceCmdInfo.flags |= TCL_TRACE_OLD_STYLE; } |
︙ | ︙ |
Changes to generic/tclVar.c.
︙ | ︙ | |||
41 42 43 44 45 46 47 | Tcl_Obj *key, int *newPtr); static inline Var * VarHashFirstVar(TclVarHashTable *tablePtr, Tcl_HashSearch *searchPtr); static inline Var * VarHashNextVar(Tcl_HashSearch *searchPtr); static inline void CleanupVar(Var *varPtr, Var *arrayPtr); #define VarHashGetValue(hPtr) \ | | | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | Tcl_Obj *key, int *newPtr); static inline Var * VarHashFirstVar(TclVarHashTable *tablePtr, Tcl_HashSearch *searchPtr); static inline Var * VarHashNextVar(Tcl_HashSearch *searchPtr); static inline void CleanupVar(Var *varPtr, Var *arrayPtr); #define VarHashGetValue(hPtr) \ ((Var *) ((char *)hPtr - offsetof(VarInHash, entry))) /* * NOTE: VarHashCreateVar increments the recount of its key argument. * All callers that will call Tcl_DecrRefCount on that argument must * call Tcl_IncrRefCount on it before passing it in. This requirement * can bubble up to callers of callers .... etc. */ |
︙ | ︙ |