Tcl Source Code

Check-in [632abe2721]
Login

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

Overview
Comment:Revise name and interface of new utility routines to match work already in place on the trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | core-8-5-branch
Files: files | file ages | folders
SHA1: 632abe27213188a82287a82d3c69c4c190205aac
User & Date: dgp 2014-12-19 17:09:32
Context
2014-12-22
15:35
One more (interp==NULL) shortcut. check-in: c7613a6017 user: dgp tags: core-8-5-branch
2014-12-19
17:57
merge-mark. The compiler machinery has changed too much for any hope for a successful merge. TclIs... check-in: 5dfdd58c00 user: dgp tags: trunk
17:09
Revise name and interface of new utility routines to match work already in place on the trunk. check-in: 632abe2721 user: dgp tags: core-8-5-branch
16:09
[e711ffb458] Eliminate TclIsLocalScalar() and revise all callers to use more appropriate facilities. check-in: 05f7d1ec03 user: dgp tags: core-8-5-branch
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tclCompCmds.c.

148
149
150
151
152
153
154
155
156


157
158
159
160
161
162
163
			    Tcl_Obj *appendObj, ByteCode *codePtr,
			    unsigned int pcOffset);
static ClientData	DupJumptableInfo(ClientData clientData);
static void		FreeJumptableInfo(ClientData clientData);
static void		PrintJumptableInfo(ClientData clientData,
			    Tcl_Obj *appendObj, ByteCode *codePtr,
			    unsigned int pcOffset);
static int		GetLocalScalarIndex(Tcl_Token *tokenPtr,
			    CompileEnv *envPtr, int *indexPtr);


static int		PushVarName(Tcl_Interp *interp,
			    Tcl_Token *varTokenPtr, CompileEnv *envPtr,
			    int flags, int *localIndexPtr,
			    int *simpleVarNamePtr, int *isScalarPtr,
			    int line, int* clNext);
static int		CompileAssociativeBinaryOpCmd(Tcl_Interp *interp,
			    Tcl_Parse *parsePtr, const char *identity,







|
|
>
>







148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
			    Tcl_Obj *appendObj, ByteCode *codePtr,
			    unsigned int pcOffset);
static ClientData	DupJumptableInfo(ClientData clientData);
static void		FreeJumptableInfo(ClientData clientData);
static void		PrintJumptableInfo(ClientData clientData,
			    Tcl_Obj *appendObj, ByteCode *codePtr,
			    unsigned int pcOffset);
static int		LocalScalarFromToken(Tcl_Token *tokenPtr,
			    CompileEnv *envPtr);
static int		LocalScalar(const char *bytes, int numBytes,
			    CompileEnv *envPtr);
static int		PushVarName(Tcl_Interp *interp,
			    Tcl_Token *varTokenPtr, CompileEnv *envPtr,
			    int flags, int *localIndexPtr,
			    int *simpleVarNamePtr, int *isScalarPtr,
			    int line, int* clNext);
static int		CompileAssociativeBinaryOpCmd(Tcl_Interp *interp,
			    Tcl_Parse *parsePtr, const char *identity,
400
401
402
403
404
405
406
407

408
409
410
411
412
413

414
415
416
417
418
419
420
     * refer to local scalars.
     */

    resultIndex = optsIndex = -1;
    cmdTokenPtr = TokenAfter(parsePtr->tokenPtr);
    if (parsePtr->numWords >= 3) {
	resultNameTokenPtr = TokenAfter(cmdTokenPtr);
	if (!GetLocalScalarIndex(resultNameTokenPtr, envPtr, &resultIndex)) {

	    return TCL_ERROR;
	}

	if (parsePtr->numWords == 4) {
	    optsNameTokenPtr = TokenAfter(resultNameTokenPtr);
	    if (!GetLocalScalarIndex(optsNameTokenPtr, envPtr, &optsIndex)) {

		return TCL_ERROR;
	    }
	}
    }

    /*
     * We will compile the catch command. Declare the exception range







|
>





|
>







402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
     * refer to local scalars.
     */

    resultIndex = optsIndex = -1;
    cmdTokenPtr = TokenAfter(parsePtr->tokenPtr);
    if (parsePtr->numWords >= 3) {
	resultNameTokenPtr = TokenAfter(cmdTokenPtr);
	resultIndex = LocalScalarFromToken(resultNameTokenPtr, envPtr);
	if (resultIndex < 0) {
	    return TCL_ERROR;
	}

	if (parsePtr->numWords == 4) {
	    optsNameTokenPtr = TokenAfter(resultNameTokenPtr);
	    optsIndex = LocalScalarFromToken(optsNameTokenPtr, envPtr);
	    if (optsIndex < 0) {
		return TCL_ERROR;
	    }
	}
    }

    /*
     * We will compile the catch command. Declare the exception range
666
667
668
669
670
671
672
673

674
675
676
677
678
679
680
    /*
     * The dictionary variable must be a local scalar that is knowable at
     * compile time; anything else exceeds the complexity of the opcode. So
     * discover what the index is.
     */

    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
    if (!GetLocalScalarIndex(varTokenPtr, envPtr, &dictVarIndex)) {

	return TCL_ERROR;
    }

    /*
     * Remaining words (key path and value to set) can be handled normally.
     */








|
>







670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
    /*
     * The dictionary variable must be a local scalar that is knowable at
     * compile time; anything else exceeds the complexity of the opcode. So
     * discover what the index is.
     */

    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
    dictVarIndex = LocalScalarFromToken(varTokenPtr, envPtr);
    if (dictVarIndex < 0) {
	return TCL_ERROR;
    }

    /*
     * Remaining words (key path and value to set) can be handled normally.
     */

717
718
719
720
721
722
723
724

725
726
727
728
729
730
731
    /*
     * The dictionary variable must be a local scalar that is knowable at
     * compile time; anything else exceeds the complexity of the opcode. So
     * discover what the index is.
     */

    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
    if (!GetLocalScalarIndex(varTokenPtr, envPtr, &dictVarIndex)) {

	return TCL_ERROR;
    }

    keyTokenPtr = TokenAfter(varTokenPtr);

    /*
     * Parse the increment amount, if present.







|
>







722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
    /*
     * The dictionary variable must be a local scalar that is knowable at
     * compile time; anything else exceeds the complexity of the opcode. So
     * discover what the index is.
     */

    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
    dictVarIndex = LocalScalarFromToken(varTokenPtr, envPtr);
    if (dictVarIndex < 0) {
	return TCL_ERROR;
    }

    keyTokenPtr = TokenAfter(varTokenPtr);

    /*
     * Parse the increment amount, if present.
798
799
800
801
802
803
804
805

806
807
808
809
810
811
812
813
814
815
816
817
818
				 * compiled. */
    CompileEnv *envPtr)		/* Holds resulting instructions. */
{
    Proc *procPtr = envPtr->procPtr;
    Tcl_Token *varsTokenPtr, *dictTokenPtr, *bodyTokenPtr;
    int keyVarIndex, valueVarIndex, loopRange, catchRange;
    int infoIndex, jumpDisplacement, bodyTargetOffset, emptyTargetOffset;
    int numVars, endTargetOffset;

    int savedStackDepth = envPtr->currStackDepth;
				/* Needed because jumps confuse the stack
				 * space calculator. */
    Tcl_Obj *varNameObj, *varListObj = NULL;
    Tcl_Token token[2] =	{{TCL_TOKEN_SIMPLE_WORD, NULL, 0, 1},
				 {TCL_TOKEN_TEXT, NULL, 0, 0}};
    DefineLineInformation;	/* TIP #280 */

    /*
     * There must be exactly three arguments after the command.
     */

    if (parsePtr->numWords != 4 || procPtr == NULL) {







|
>




<
<







804
805
806
807
808
809
810
811
812
813
814
815
816


817
818
819
820
821
822
823
				 * compiled. */
    CompileEnv *envPtr)		/* Holds resulting instructions. */
{
    Proc *procPtr = envPtr->procPtr;
    Tcl_Token *varsTokenPtr, *dictTokenPtr, *bodyTokenPtr;
    int keyVarIndex, valueVarIndex, loopRange, catchRange;
    int infoIndex, jumpDisplacement, bodyTargetOffset, emptyTargetOffset;
    int numVars, endTargetOffset, numBytes;
    const char *bytes;
    int savedStackDepth = envPtr->currStackDepth;
				/* Needed because jumps confuse the stack
				 * space calculator. */
    Tcl_Obj *varNameObj, *varListObj = NULL;


    DefineLineInformation;	/* TIP #280 */

    /*
     * There must be exactly three arguments after the command.
     */

    if (parsePtr->numWords != 4 || procPtr == NULL) {
837
838
839
840
841
842
843
844

845
846
847
848
849
850
851

852
853
854
855
856
857
858
859
	    TCL_OK != Tcl_ListObjLength(NULL, varListObj, &numVars) ||
	    numVars != 2) {
	Tcl_DecrRefCount(varListObj);
	return TCL_ERROR;
    }

    Tcl_ListObjIndex(NULL, varListObj, 0, &varNameObj);
    token[1].start = Tcl_GetStringFromObj(varNameObj, &token[1].size);

    if (!GetLocalScalarIndex(token, envPtr, &keyVarIndex)) {
	Tcl_DecrRefCount(varListObj);
	return TCL_ERROR;
    }

    Tcl_ListObjIndex(NULL, varListObj, 1, &varNameObj);
    token[1].start = Tcl_GetStringFromObj(varNameObj, &token[1].size);

    if (!GetLocalScalarIndex(token, envPtr, &valueVarIndex)) {
	Tcl_DecrRefCount(varListObj);
	return TCL_ERROR;
    }

    Tcl_DecrRefCount(varListObj);

    /*







|
>
|





|
>
|







842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
	    TCL_OK != Tcl_ListObjLength(NULL, varListObj, &numVars) ||
	    numVars != 2) {
	Tcl_DecrRefCount(varListObj);
	return TCL_ERROR;
    }

    Tcl_ListObjIndex(NULL, varListObj, 0, &varNameObj);
    bytes = Tcl_GetStringFromObj(varNameObj, &numBytes);
    keyVarIndex = LocalScalar(bytes, numBytes, envPtr);
    if (keyVarIndex < 0) {
	Tcl_DecrRefCount(varListObj);
	return TCL_ERROR;
    }

    Tcl_ListObjIndex(NULL, varListObj, 1, &varNameObj);
    bytes = Tcl_GetStringFromObj(varNameObj, &numBytes);
    valueVarIndex = LocalScalar(bytes, numBytes, envPtr);
    if (valueVarIndex < 0) {
	Tcl_DecrRefCount(varListObj);
	return TCL_ERROR;
    }

    Tcl_DecrRefCount(varListObj);

    /*
1016
1017
1018
1019
1020
1021
1022
1023

1024
1025
1026
1027
1028
1029
1030
    /*
     * The dictionary variable must be a local scalar that is knowable at
     * compile time; anything else exceeds the complexity of the opcode. So
     * discover what the index is.
     */

    dictVarTokenPtr = TokenAfter(parsePtr->tokenPtr);
    if (!GetLocalScalarIndex(dictVarTokenPtr, envPtr, &dictIndex)) {

	return TCL_ERROR;
    }

    /*
     * Assemble the instruction metadata. This is complex enough that it is
     * represented as auxData; it holds an ordered list of variable indices
     * that are to be used.







|
>







1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
    /*
     * The dictionary variable must be a local scalar that is knowable at
     * compile time; anything else exceeds the complexity of the opcode. So
     * discover what the index is.
     */

    dictVarTokenPtr = TokenAfter(parsePtr->tokenPtr);
    dictIndex = LocalScalarFromToken(dictVarTokenPtr, envPtr);
    if (dictIndex < 0) {
	return TCL_ERROR;
    }

    /*
     * Assemble the instruction metadata. This is complex enough that it is
     * represented as auxData; it holds an ordered list of variable indices
     * that are to be used.
1047
1048
1049
1050
1051
1052
1053
1054

1055
1056
1057
1058
1059
1060
1061
	keyTokenPtrs[i] = tokenPtr;

	/*
	 * Variables first need to be checked for sanity.
	 */

	tokenPtr = TokenAfter(tokenPtr);
	if (!GetLocalScalarIndex(tokenPtr, envPtr, &index)) {

	    ckfree((char *) duiPtr);
	    TclStackFree(interp, keyTokenPtrs);
	    return TCL_ERROR;
	}

	/*
	 * Stash the index in the auxiliary data.







|
>







1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
	keyTokenPtrs[i] = tokenPtr;

	/*
	 * Variables first need to be checked for sanity.
	 */

	tokenPtr = TokenAfter(tokenPtr);
	index = LocalScalarFromToken(tokenPtr, envPtr);
	if (index < 0) {
	    ckfree((char *) duiPtr);
	    TclStackFree(interp, keyTokenPtrs);
	    return TCL_ERROR;
	}

	/*
	 * Stash the index in the auxiliary data.
1157
1158
1159
1160
1161
1162
1163
1164

1165
1166
1167
1168
1169
1170
1171
    }

    /*
     * Get the index of the local variable that we will be working with.
     */

    tokenPtr = TokenAfter(parsePtr->tokenPtr);
    if (!GetLocalScalarIndex(tokenPtr, envPtr, &dictVarIndex)) {

	return TCL_ERROR;
    }

    /*
     * Produce the string to concatenate onto the dictionary entry.
     */








|
>







1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
    }

    /*
     * Get the index of the local variable that we will be working with.
     */

    tokenPtr = TokenAfter(parsePtr->tokenPtr);
    dictVarIndex = LocalScalarFromToken(tokenPtr, envPtr);
    if (dictVarIndex < 0) {
	return TCL_ERROR;
    }

    /*
     * Produce the string to concatenate onto the dictionary entry.
     */

1206
1207
1208
1209
1210
1211
1212
1213

1214
1215
1216
1217
1218
1219
1220
    if (parsePtr->numWords != 4) {
	return TCL_ERROR;
    }

    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
    keyTokenPtr = TokenAfter(varTokenPtr);
    valueTokenPtr = TokenAfter(keyTokenPtr);
    if (!GetLocalScalarIndex(varTokenPtr, envPtr, &dictVarIndex)) {

	return TCL_ERROR;
    }
    CompileWord(envPtr, keyTokenPtr, interp, 2);
    CompileWord(envPtr, valueTokenPtr, interp, 3);
    TclEmitInstInt4( INST_DICT_LAPPEND, dictVarIndex, envPtr);
    return TCL_OK;
}







|
>







1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
    if (parsePtr->numWords != 4) {
	return TCL_ERROR;
    }

    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
    keyTokenPtr = TokenAfter(varTokenPtr);
    valueTokenPtr = TokenAfter(keyTokenPtr);
    dictVarIndex = LocalScalarFromToken(varTokenPtr, envPtr);
    if (dictVarIndex < 0) {
	return TCL_ERROR;
    }
    CompileWord(envPtr, keyTokenPtr, interp, 2);
    CompileWord(envPtr, valueTokenPtr, interp, 3);
    TclEmitInstInt4( INST_DICT_LAPPEND, dictVarIndex, envPtr);
    return TCL_OK;
}
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
    CompileEnv *envPtr)		/* Holds resulting instructions. */
{
    Proc *procPtr = envPtr->procPtr;
    ForeachInfo *infoPtr = NULL;/* Points to the structure describing this
				 * foreach command. Stored in a AuxData
				 * record in the ByteCode. */
    Tcl_Token *tokenPtr, *bodyTokenPtr;
    Tcl_Token token[2];
    unsigned char *jumpPc;
    JumpFixup jumpFalseFixup;
    int jumpBackDist, jumpBackOffset, infoIndex, range;
    int numWords, numLists, tempVar, i, j, code = TCL_OK;
    int savedStackDepth = envPtr->currStackDepth;
    Tcl_Obj *varListObj = NULL;
    DefineLineInformation;	/* TIP #280 */







<







1529
1530
1531
1532
1533
1534
1535

1536
1537
1538
1539
1540
1541
1542
    CompileEnv *envPtr)		/* Holds resulting instructions. */
{
    Proc *procPtr = envPtr->procPtr;
    ForeachInfo *infoPtr = NULL;/* Points to the structure describing this
				 * foreach command. Stored in a AuxData
				 * record in the ByteCode. */
    Tcl_Token *tokenPtr, *bodyTokenPtr;

    unsigned char *jumpPc;
    JumpFixup jumpFalseFixup;
    int jumpBackDist, jumpBackOffset, infoIndex, range;
    int numWords, numLists, tempVar, i, j, code = TCL_OK;
    int savedStackDepth = envPtr->currStackDepth;
    Tcl_Obj *varListObj = NULL;
    DefineLineInformation;	/* TIP #280 */
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
    /*
     * Parse each var list into sequence of var names. Don't
     * compile the foreach inline if any var name needs substitutions or isn't
     * a scalar, or if any var list needs substitutions.
     */

    varListObj = Tcl_NewObj();
    token[0].type = TCL_TOKEN_SIMPLE_WORD;
    token[0].numComponents = 1;
    for (i = 0, tokenPtr = parsePtr->tokenPtr;
	    i < numWords-1;
	    i++, tokenPtr = TokenAfter(tokenPtr)) {
	ForeachVarList *varListPtr;
	int numVars;

	if (i%2 != 1) {







<
<







1582
1583
1584
1585
1586
1587
1588


1589
1590
1591
1592
1593
1594
1595
    /*
     * Parse each var list into sequence of var names. Don't
     * compile the foreach inline if any var name needs substitutions or isn't
     * a scalar, or if any var list needs substitutions.
     */

    varListObj = Tcl_NewObj();


    for (i = 0, tokenPtr = parsePtr->tokenPtr;
	    i < numWords-1;
	    i++, tokenPtr = TokenAfter(tokenPtr)) {
	ForeachVarList *varListPtr;
	int numVars;

	if (i%2 != 1) {
1605
1606
1607
1608
1609
1610
1611


1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
		sizeof(ForeachVarList) + numVars*sizeof(int));
	varListPtr->numVars = numVars;
	infoPtr->varLists[i/2] = varListPtr;
	infoPtr->numLists++;

	for (j = 0;  j < numVars;  j++) {
	    Tcl_Obj *varNameObj;



	    Tcl_ListObjIndex(NULL, varListObj, j, &varNameObj);
	    token[1].start = Tcl_GetStringFromObj(varNameObj, &token[1].size);
	    if (!GetLocalScalarIndex(token, envPtr,
		    varListPtr->varIndexes + j)) {
		code = TCL_ERROR;
		goto done;
	    }
	}
	Tcl_SetObjLength(varListObj, 0);
    }








>
>


|
|
|







1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
		sizeof(ForeachVarList) + numVars*sizeof(int));
	varListPtr->numVars = numVars;
	infoPtr->varLists[i/2] = varListPtr;
	infoPtr->numLists++;

	for (j = 0;  j < numVars;  j++) {
	    Tcl_Obj *varNameObj;
	    int numBytes;
	    const char *bytes;

	    Tcl_ListObjIndex(NULL, varListObj, j, &varNameObj);
	    bytes = Tcl_GetStringFromObj(varNameObj, &numBytes);
	    varListPtr->varIndexes[j] = LocalScalar(bytes, numBytes, envPtr);
	    if (varListPtr->varIndexes[j] < 0) {
		code = TCL_ERROR;
		goto done;
	    }
	}
	Tcl_SetObjLength(varListObj, 0);
    }

4691
4692
4693
4694
4695
4696
4697
4698
4699

4700
4701
4702
4703
4704


4705
4706
4707
4708
4709

4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723



4724














4725
4726
4727
4728
4729
4730
4731
    PushLiteral(envPtr, "", 0);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GetLocalScalarIndex --
 *

 *	Procedure used in the compiling where pushing a variable name is
 *	necessary (append, lappend, set).
 *
 * Results:
 * 	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer


 * 	evaluation to runtime.
 *
 * Side effects:
 *	Instructions are added to envPtr to execute the "set" command at
 *	runtime.

 *
 *----------------------------------------------------------------------
 */

static int
GetLocalScalarIndex(
    Tcl_Token *tokenPtr,
    CompileEnv *envPtr,
    int *indexPtr)
{
    int isSimple, isScalar;

    PushVarName(NULL, tokenPtr, envPtr, TCL_CREATE_VAR, indexPtr,
	    &isSimple, &isScalar, 0 /* ignored */, NULL /* ignored */);



    return (isScalar && *indexPtr >= 0);














}

/*
 *----------------------------------------------------------------------
 *
 * PushVarName --
 *







|

>
|
<


|
>
>
|


<
<
>





|

|
<

|

|

>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>







4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711

4712
4713
4714
4715
4716
4717
4718
4719


4720
4721
4722
4723
4724
4725
4726
4727
4728

4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
    PushLiteral(envPtr, "", 0);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * LocalScalar(FromToken) --
 *
 *	Get the index into the table of compiled locals that corresponds
 *	to a local scalar variable name.

 *
 * Results:
 * 	Returns the non-negative integer index value into the table of
 *	compiled locals corresponding to a local scalar variable name.
 *	If the arguments passed in do not identify a local scalar variable
 *	then return -1.
 *
 * Side effects:


 *	May add an entry into the table of compiled locals.
 *
 *----------------------------------------------------------------------
 */

static int
LocalScalarFromToken(
    Tcl_Token *tokenPtr,
    CompileEnv *envPtr)

{
    int isSimple, isScalar, index;

    PushVarName(NULL, tokenPtr, envPtr, TCL_CREATE_VAR, &index,
	    &isSimple, &isScalar, 0 /* ignored */, NULL /* ignored */);
    if (!isScalar) {
	index = -1;
    }
    return index;
}

static int
LocalScalar(
    const char *bytes,
    int numBytes,
    CompileEnv *envPtr)
{
    Tcl_Token token[2] =	{{TCL_TOKEN_SIMPLE_WORD, NULL, 0, 1},
				 {TCL_TOKEN_TEXT, NULL, 0, 0}};

    token[1].start = bytes;
    token[1].size = numBytes;
    return LocalScalarFromToken(token, envPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * PushVarName --
 *
5714
5715
5716
5717
5718
5719
5720
5721

5722
5723
5724
5725
5726
5727
5728
     * be called at runtime.
     */

    for(; i<numWords; i+=2, otherTokenPtr = TokenAfter(localTokenPtr)) {
	localTokenPtr = TokenAfter(otherTokenPtr);

	CompileWord(envPtr, otherTokenPtr, interp, i);
	if (!GetLocalScalarIndex(localTokenPtr, envPtr, &localIndex)) {

	    return TCL_ERROR;
	}
	TclEmitInstInt4(INST_UPVAR, localIndex, envPtr);
    }

    /*
     * Pop the frame index, and set the result to empty







|
>







5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
     * be called at runtime.
     */

    for(; i<numWords; i+=2, otherTokenPtr = TokenAfter(localTokenPtr)) {
	localTokenPtr = TokenAfter(otherTokenPtr);

	CompileWord(envPtr, otherTokenPtr, interp, i);
	localIndex = LocalScalarFromToken(localTokenPtr, envPtr);
	if (localIndex < 0) {
	    return TCL_ERROR;
	}
	TclEmitInstInt4(INST_UPVAR, localIndex, envPtr);
    }

    /*
     * Pop the frame index, and set the result to empty
5803
5804
5805
5806
5807
5808
5809
5810

5811
5812
5813
5814
5815
5816
5817

    localTokenPtr = tokenPtr;
    for(i=3; i<numWords; i+=2) {
	otherTokenPtr = TokenAfter(localTokenPtr);
	localTokenPtr = TokenAfter(otherTokenPtr);

	CompileWord(envPtr, otherTokenPtr, interp, i);
	if (!GetLocalScalarIndex(localTokenPtr, envPtr, &localIndex)) {

	    return TCL_ERROR;
	}
	TclEmitInstInt4(INST_NSUPVAR, localIndex, envPtr);
    }

    /*
     * Pop the namespace, and set the result to empty







|
>







5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846

    localTokenPtr = tokenPtr;
    for(i=3; i<numWords; i+=2) {
	otherTokenPtr = TokenAfter(localTokenPtr);
	localTokenPtr = TokenAfter(otherTokenPtr);

	CompileWord(envPtr, otherTokenPtr, interp, i);
	localIndex = LocalScalarFromToken(localTokenPtr, envPtr);
	if (localIndex < 0) {
	    return TCL_ERROR;
	}
	TclEmitInstInt4(INST_NSUPVAR, localIndex, envPtr);
    }

    /*
     * Pop the namespace, and set the result to empty