@@ -2102,6 +2102,16 @@ TclNRExecuteByteCode(
21022102 return TCL_OK ;
21032103}
21042104
2105+ static inline Var *
2106+ FollowLinks (
2107+ Var * varPtr )
2108+ {
2109+ while (TclIsVarLink (varPtr )) {
2110+ varPtr = varPtr -> value .linkPtr ;
2111+ }
2112+ return varPtr ;
2113+ }
2114+
21052115static int
21062116TEBCresume (
21072117 void * data [],
@@ -2150,6 +2160,7 @@ TEBCresume(
21502160
21512161#define LOCAL (i ) (&compiledLocals[(i)])
21522162#define TCONST (i ) (constants[(i)])
2163+ #define LOCALVAR (i ) FollowLinks(LOCAL(i))
21532164
21542165 /*
21552166 * These macros are just meant to save some global variables that are not
@@ -3160,10 +3171,7 @@ TEBCresume(
31603171 case INST_LOAD_SCALAR1 :
31613172 DEPRECATED_OPCODE_MARK (INST_LOAD_SCALAR1 );
31623173 varIdx = TclGetUInt1AtPtr (pc + 1 );
3163- varPtr = LOCAL (varIdx );
3164- while (TclIsVarLink (varPtr )) {
3165- varPtr = varPtr -> value .linkPtr ;
3166- }
3174+ varPtr = LOCALVAR (varIdx );
31673175 TRACE (("%u => " , (unsigned ) varIdx ));
31683176 if (TclIsVarDirectReadable (varPtr )) {
31693177 /*
@@ -3184,10 +3192,7 @@ TEBCresume(
31843192 case INST_LOAD_SCALAR :
31853193 instLoadScalar :
31863194 varIdx = TclGetUInt4AtPtr (pc + 1 );
3187- varPtr = LOCAL (varIdx );
3188- while (TclIsVarLink (varPtr )) {
3189- varPtr = varPtr -> value .linkPtr ;
3190- }
3195+ varPtr = LOCALVAR (varIdx );
31913196 TRACE (("%u => " , (unsigned ) varIdx ));
31923197 if (TclIsVarDirectReadable (varPtr )) {
31933198 /*
@@ -3219,10 +3224,7 @@ TEBCresume(
32193224#endif
32203225 part1Ptr = NULL ;
32213226 part2Ptr = OBJ_AT_TOS ;
3222- arrayPtr = LOCAL (varIdx );
3223- while (TclIsVarLink (arrayPtr )) {
3224- arrayPtr = arrayPtr -> value .linkPtr ;
3225- }
3227+ arrayPtr = LOCALVAR (varIdx );
32263228 TRACE (("%u \"%.30s\" => " , (unsigned ) varIdx , O2S (part2Ptr )));
32273229 if (TclIsVarArray (arrayPtr ) && !ReadTraced (arrayPtr )) {
32283230 varPtr = VarHashFindVar (arrayPtr -> value .tablePtr , part2Ptr );
@@ -3332,12 +3334,9 @@ TEBCresume(
33323334#endif
33333335 valuePtr = OBJ_AT_TOS ;
33343336 part2Ptr = OBJ_UNDER_TOS ;
3335- arrayPtr = LOCAL (varIdx );
3337+ arrayPtr = LOCALVAR (varIdx );
33363338 TRACE (("%u \"%.30s\" <- \"%.30s\" => " , (unsigned ) varIdx , O2S (part2Ptr ),
33373339 O2S (valuePtr )));
3338- while (TclIsVarLink (arrayPtr )) {
3339- arrayPtr = arrayPtr -> value .linkPtr ;
3340- }
33413340 if (TclIsVarArray (arrayPtr ) && !WriteTraced (arrayPtr )) {
33423341 varPtr = VarHashFindVar (arrayPtr -> value .tablePtr , part2Ptr );
33433342 if (varPtr && TclIsVarDirectWritable (varPtr )) {
@@ -3368,11 +3367,8 @@ TEBCresume(
33683367 doStoreScalarDirect :
33693368#endif
33703369 valuePtr = OBJ_AT_TOS ;
3371- varPtr = LOCAL (varIdx );
3370+ varPtr = LOCALVAR (varIdx );
33723371 TRACE (("%u <- \"%.30s\" => " , (unsigned ) varIdx , O2S (valuePtr )));
3373- while (TclIsVarLink (varPtr )) {
3374- varPtr = varPtr -> value .linkPtr ;
3375- }
33763372 if (!TclIsVarDirectWritable (varPtr )) {
33773373 storeFlags = TCL_LEAVE_ERR_MSG ;
33783374 part1Ptr = NULL ;
@@ -3501,12 +3497,9 @@ TEBCresume(
35013497 doStoreArray :
35023498 valuePtr = OBJ_AT_TOS ;
35033499 part2Ptr = OBJ_UNDER_TOS ;
3504- arrayPtr = LOCAL (varIdx );
3500+ arrayPtr = LOCALVAR (varIdx );
35053501 TRACE (("%u \"%.30s\" <- \"%.30s\" => " , (unsigned ) varIdx , O2S (part2Ptr ),
35063502 O2S (valuePtr )));
3507- while (TclIsVarLink (arrayPtr )) {
3508- arrayPtr = arrayPtr -> value .linkPtr ;
3509- }
35103503 cleanup = 2 ;
35113504 part1Ptr = NULL ;
35123505
@@ -3553,11 +3546,8 @@ TEBCresume(
35533546
35543547 doStoreScalar :
35553548 valuePtr = OBJ_AT_TOS ;
3556- varPtr = LOCAL (varIdx );
3549+ varPtr = LOCALVAR (varIdx );
35573550 TRACE (("%u <- \"%.30s\" => " , (unsigned ) varIdx , O2S (valuePtr )));
3558- while (TclIsVarLink (varPtr )) {
3559- varPtr = varPtr -> value .linkPtr ;
3560- }
35613551 cleanup = 1 ;
35623552 arrayPtr = NULL ;
35633553 part1Ptr = part2Ptr = NULL ;
@@ -3582,12 +3572,9 @@ TEBCresume(
35823572 case INST_LAPPEND_LIST :
35833573 varIdx = TclGetUInt4AtPtr (pc + 1 );
35843574 valuePtr = OBJ_AT_TOS ;
3585- varPtr = LOCAL (varIdx );
3575+ varPtr = LOCALVAR (varIdx );
35863576 cleanup = 1 ;
35873577 pcAdjustment = 5 ;
3588- while (TclIsVarLink (varPtr )) {
3589- varPtr = varPtr -> value .linkPtr ;
3590- }
35913578 TRACE (("%u <- \"%.30s\" => " , (unsigned ) varIdx , O2S (valuePtr )));
35923579 if (TclListObjGetElements (interp , valuePtr , & objc , & objv )
35933580 != TCL_OK ) {
@@ -3607,12 +3594,9 @@ TEBCresume(
36073594 valuePtr = OBJ_AT_TOS ;
36083595 part1Ptr = NULL ;
36093596 part2Ptr = OBJ_UNDER_TOS ;
3610- arrayPtr = LOCAL (varIdx );
3597+ arrayPtr = LOCALVAR (varIdx );
36113598 cleanup = 2 ;
36123599 pcAdjustment = 5 ;
3613- while (TclIsVarLink (arrayPtr )) {
3614- arrayPtr = arrayPtr -> value .linkPtr ;
3615- }
36163600 TRACE (("%u \"%.30s\" \"%.30s\" => " ,
36173601 (unsigned ) varIdx , O2S (part2Ptr ), O2S (valuePtr )));
36183602 if (TclListObjGetElements (interp , valuePtr , & objc , & objv )
@@ -3868,11 +3852,8 @@ TEBCresume(
38683852 doIncrArray :
38693853 part1Ptr = NULL ;
38703854 part2Ptr = OBJ_AT_TOS ;
3871- arrayPtr = LOCAL (varIdx );
3855+ arrayPtr = LOCALVAR (varIdx );
38723856 cleanup = 1 ;
3873- while (TclIsVarLink (arrayPtr )) {
3874- arrayPtr = arrayPtr -> value .linkPtr ;
3875- }
38763857 TRACE (("%u \"%.30s\" (by %ld) => " , (unsigned ) varIdx , O2S (part2Ptr ),
38773858 increment ));
38783859 varPtr = TclLookupArrayElement (interp , part1Ptr , part2Ptr ,
@@ -3900,10 +3881,7 @@ TEBCresume(
39003881 doIncrScalarImm :
39013882#endif
39023883 cleanup = 0 ;
3903- varPtr = LOCAL (varIdx );
3904- while (TclIsVarLink (varPtr )) {
3905- varPtr = varPtr -> value .linkPtr ;
3906- }
3884+ varPtr = LOCALVAR (varIdx );
39073885
39083886 if (TclIsVarDirectModifyable (varPtr )) {
39093887 void * ptr ;
@@ -3981,10 +3959,7 @@ TEBCresume(
39813959 Tcl_IncrRefCount (incrPtr );
39823960
39833961 doIncrScalar :
3984- varPtr = LOCAL (varIdx );
3985- while (TclIsVarLink (varPtr )) {
3986- varPtr = varPtr -> value .linkPtr ;
3987- }
3962+ varPtr = LOCALVAR (varIdx );
39883963 arrayPtr = NULL ;
39893964 part1Ptr = part2Ptr = NULL ;
39903965 cleanup = 0 ;
@@ -4038,10 +4013,7 @@ TEBCresume(
40384013 cleanup = 0 ;
40394014 pcAdjustment = 5 ;
40404015 varIdx = TclGetUInt4AtPtr (pc + 1 );
4041- varPtr = LOCAL (varIdx );
4042- while (TclIsVarLink (varPtr )) {
4043- varPtr = varPtr -> value .linkPtr ;
4044- }
4016+ varPtr = LOCALVAR (varIdx );
40454017 TRACE (("%u => " , (unsigned ) varIdx ));
40464018 if (ReadTraced (varPtr )) {
40474019 DECACHE_STACK_INFO ();
@@ -4060,10 +4032,7 @@ TEBCresume(
40604032 pcAdjustment = 5 ;
40614033 varIdx = TclGetUInt4AtPtr (pc + 1 );
40624034 part2Ptr = OBJ_AT_TOS ;
4063- arrayPtr = LOCAL (varIdx );
4064- while (TclIsVarLink (arrayPtr )) {
4065- arrayPtr = arrayPtr -> value .linkPtr ;
4066- }
4035+ arrayPtr = LOCALVAR (varIdx );
40674036 TRACE (("%u \"%.30s\" => " , (unsigned )varIdx , O2S (part2Ptr )));
40684037 if (TclIsVarArray (arrayPtr ) && !ReadTraced (arrayPtr )) {
40694038 varPtr = VarHashFindVar (arrayPtr -> value .tablePtr , part2Ptr );
@@ -4141,10 +4110,7 @@ TEBCresume(
41414110 case INST_UNSET_SCALAR :
41424111 flags = TclGetUInt1AtPtr (pc + 1 ) ? TCL_LEAVE_ERR_MSG : 0 ;
41434112 varIdx = TclGetUInt4AtPtr (pc + 2 );
4144- varPtr = LOCAL (varIdx );
4145- while (TclIsVarLink (varPtr )) {
4146- varPtr = varPtr -> value .linkPtr ;
4147- }
4113+ varPtr = LOCALVAR (varIdx );
41484114 TRACE (("%s %u => " , (flags ? "normal" : "noerr" ), (unsigned )varIdx ));
41494115 if (TclIsVarDirectUnsettable (varPtr ) && !TclIsVarInHash (varPtr )) {
41504116 /*
@@ -4175,10 +4141,7 @@ TEBCresume(
41754141 flags = TclGetUInt1AtPtr (pc + 1 ) ? TCL_LEAVE_ERR_MSG : 0 ;
41764142 varIdx = TclGetUInt4AtPtr (pc + 2 );
41774143 part2Ptr = OBJ_AT_TOS ;
4178- arrayPtr = LOCAL (varIdx );
4179- while (TclIsVarLink (arrayPtr )) {
4180- arrayPtr = arrayPtr -> value .linkPtr ;
4181- }
4144+ arrayPtr = LOCALVAR (varIdx );
41824145 TRACE (("%s %u \"%.30s\" => " ,
41834146 (flags ? "normal" : "noerr" ), (unsigned )varIdx , O2S (part2Ptr )));
41844147 if (TclIsVarArray (arrayPtr ) && !UnsetTraced (arrayPtr )
@@ -4272,11 +4235,8 @@ TEBCresume(
42724235 part1Ptr = NULL ;
42734236 objPtr = OBJ_AT_TOS ;
42744237 TRACE (("%u \"%.30s\" => \n" , (unsigned ) varIdx , O2S (objPtr )));
4275- varPtr = LOCAL (varIdx );
4238+ varPtr = LOCALVAR (varIdx );
42764239 arrayPtr = NULL ;
4277- while (TclIsVarLink (varPtr )) {
4278- varPtr = varPtr -> value .linkPtr ;
4279- }
42804240 goto doConst ;
42814241 case INST_CONST_STK :
42824242 varIdx = -1 ;
@@ -4341,10 +4301,7 @@ TEBCresume(
43414301 part1Ptr = NULL ;
43424302 arrayPtr = NULL ;
43434303 TRACE (("%u => " , (unsigned )varIdx ));
4344- varPtr = LOCAL (varIdx );
4345- while (TclIsVarLink (varPtr )) {
4346- varPtr = varPtr -> value .linkPtr ;
4347- }
4304+ varPtr = LOCALVAR (varIdx );
43484305 goto doArrayExists ;
43494306 case INST_ARRAY_EXISTS_STK :
43504307 varIdx = -1 ;
@@ -4377,10 +4334,7 @@ TEBCresume(
43774334 part1Ptr = NULL ;
43784335 arrayPtr = NULL ;
43794336 TRACE (("%u => " , (unsigned )varIdx ));
4380- varPtr = LOCAL (varIdx );
4381- while (TclIsVarLink (varPtr )) {
4382- varPtr = varPtr -> value .linkPtr ;
4383- }
4337+ varPtr = LOCALVAR (varIdx );
43844338 goto doArrayMake ;
43854339 case INST_ARRAY_MAKE_STK :
43864340 varIdx = -1 ;
@@ -6967,10 +6921,7 @@ TEBCresume(
69676921 }
69686922
69696923 varIndex = varListPtr -> varIndexes [j ];
6970- varPtr = LOCAL (varIndex );
6971- while (TclIsVarLink (varPtr )) {
6972- varPtr = varPtr -> value .linkPtr ;
6973- }
6924+ varPtr = LOCALVAR (varIndex );
69746925 if (TclIsVarDirectWritable (varPtr )) {
69756926 value2Ptr = varPtr -> value .objPtr ;
69766927 if (valuePtr != value2Ptr ) {
@@ -7312,10 +7263,7 @@ TEBCresume(
73127263 numArgs = TclGetUInt4AtPtr (pc + 1 );
73137264 varIdx = TclGetUInt4AtPtr (pc + 5 );
73147265
7315- varPtr = LOCAL (varIdx );
7316- while (TclIsVarLink (varPtr )) {
7317- varPtr = varPtr -> value .linkPtr ;
7318- }
7266+ varPtr = LOCALVAR (varIdx );
73197267 TRACE (("%u %u => " , (unsigned )numArgs , (unsigned )varIdx ));
73207268 if (TclIsVarDirectReadable (varPtr )) {
73217269 dictPtr = varPtr -> value .objPtr ;
@@ -7415,10 +7363,7 @@ TEBCresume(
74157363 case INST_DICT_APPEND :
74167364 case INST_DICT_LAPPEND :
74177365 varIdx = TclGetUInt4AtPtr (pc + 1 );
7418- varPtr = LOCAL (varIdx );
7419- while (TclIsVarLink (varPtr )) {
7420- varPtr = varPtr -> value .linkPtr ;
7421- }
7366+ varPtr = LOCALVAR (varIdx );
74227367 TRACE (("%u => " , (unsigned )varIdx ));
74237368 if (TclIsVarDirectReadable (varPtr )) {
74247369 dictPtr = varPtr -> value .objPtr ;
@@ -7569,6 +7514,7 @@ TEBCresume(
75697514 ir .twoPtrValue .ptr2 = dictPtr ;
75707515 Tcl_StoreInternalRep (statePtr , & dictIteratorType , & ir );
75717516 }
7517+ // Special var; never linked
75727518 varPtr = LOCAL (varIdx );
75737519 if (varPtr -> value .objPtr ) {
75747520 if (TclHasInternalRep (varPtr -> value .objPtr , & dictIteratorType )) {
@@ -7584,6 +7530,7 @@ TEBCresume(
75847530 case INST_DICT_NEXT :
75857531 varIdx = TclGetUInt4AtPtr (pc + 1 );
75867532 TRACE (("%u => " , (unsigned )varIdx ));
7533+ // Special var; never linked
75877534 statePtr = (* LOCAL (varIdx )).value .objPtr ;
75887535 {
75897536 const Tcl_ObjInternalRep * irPtr ;
@@ -7622,11 +7569,8 @@ TEBCresume(
76227569 varIdx = TclGetUInt4AtPtr (pc + 1 );
76237570 tblIdx = TclGetUInt4AtPtr (pc + 5 );
76247571 TRACE (("%u %u => " , (unsigned )varIdx , tblIdx ));
7625- varPtr = LOCAL (varIdx );
7572+ varPtr = LOCALVAR (varIdx );
76267573 duiPtr = (DictUpdateInfo * )codePtr -> auxDataArrayPtr [tblIdx ].clientData ;
7627- while (TclIsVarLink (varPtr )) {
7628- varPtr = varPtr -> value .linkPtr ;
7629- }
76307574 if (TclIsVarDirectReadable (varPtr )) {
76317575 dictPtr = varPtr -> value .objPtr ;
76327576 } else {
@@ -7656,10 +7600,7 @@ TEBCresume(
76567600 Tcl_DecrRefCount (dictPtr );
76577601 goto gotError ;
76587602 }
7659- varPtr = LOCAL (duiPtr -> varIndices [i ]);
7660- while (TclIsVarLink (varPtr )) {
7661- varPtr = varPtr -> value .linkPtr ;
7662- }
7603+ varPtr = LOCALVAR (duiPtr -> varIndices [i ]);
76637604 DECACHE_STACK_INFO ();
76647605 if (valuePtr == NULL ) {
76657606 TclObjUnsetVar2 (interp ,
@@ -7683,11 +7624,8 @@ TEBCresume(
76837624 varIdx = TclGetUInt4AtPtr (pc + 1 );
76847625 tblIdx = TclGetUInt4AtPtr (pc + 5 );
76857626 TRACE (("%u %u => " , (unsigned )varIdx , tblIdx ));
7686- varPtr = LOCAL (varIdx );
7627+ varPtr = LOCALVAR (varIdx );
76877628 duiPtr = (DictUpdateInfo * )codePtr -> auxDataArrayPtr [tblIdx ].clientData ;
7688- while (TclIsVarLink (varPtr )) {
7689- varPtr = varPtr -> value .linkPtr ;
7690- }
76917629 if (TclIsVarDirectReadable (varPtr )) {
76927630 dictPtr = varPtr -> value .objPtr ;
76937631 } else {
@@ -7714,11 +7652,9 @@ TEBCresume(
77147652 TclInvalidateStringRep (dictPtr );
77157653 }
77167654 for (i = 0 ; i < length ; i ++ ) {
7717- Var * var2Ptr = LOCAL (duiPtr -> varIndices [i ]);
7718-
7719- while (TclIsVarLink (var2Ptr )) {
7720- var2Ptr = var2Ptr -> value .linkPtr ;
7721- }
7655+ Var * var2Ptr ;
7656+
7657+ var2Ptr = LOCALVAR (duiPtr -> varIndices [i ]);
77227658 if (TclIsVarDirectReadable (var2Ptr )) {
77237659 valuePtr = var2Ptr -> value .objPtr ;
77247660 } else {
@@ -7806,16 +7742,13 @@ TEBCresume(
78067742 varIdx = TclGetUInt4AtPtr (pc + 1 );
78077743 listPtr = OBJ_UNDER_TOS ;
78087744 keysPtr = OBJ_AT_TOS ;
7809- varPtr = LOCAL (varIdx );
7745+ varPtr = LOCALVAR (varIdx );
78107746 TRACE (("%u <- \"%.30s\" \"%.30s\" => " , (unsigned )varIdx , O2S (valuePtr ),
78117747 O2S (keysPtr )));
78127748 if (TclListObjGetElements (interp , listPtr , & objc , & objv ) != TCL_OK ) {
78137749 TRACE_ERROR (interp );
78147750 goto gotError ;
78157751 }
7816- while (TclIsVarLink (varPtr )) {
7817- varPtr = varPtr -> value .linkPtr ;
7818- }
78197752 DECACHE_STACK_INFO ();
78207753 result = TclDictWithFinish (interp , varPtr , NULL , NULL , NULL , varIdx ,
78217754 objc , objv , keysPtr );
0 commit comments