diff options
Diffstat (limited to 'generic/tclCompCmds.c')
-rw-r--r-- | generic/tclCompCmds.c | 115 |
1 files changed, 69 insertions, 46 deletions
diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 6a71666..d01964d 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclCompCmds.c,v 1.143.2.1 2008/05/07 10:39:38 dkf Exp $ + * RCS: @(#) $Id: tclCompCmds.c,v 1.143.2.2 2009/08/25 21:01:05 andreas_kupries Exp $ */ #include "tclInt.h" @@ -31,7 +31,8 @@ TclEmitPush(TclRegisterNewLiteral((envPtr), (tokenPtr)[1].start, \ (tokenPtr)[1].size), (envPtr)); \ } else { \ - envPtr->line = mapPtr->loc[eclIndex].line[word]; \ + envPtr->line = mapPtr->loc[eclIndex].line[word]; \ + envPtr->clNext = mapPtr->loc[eclIndex].next[word]; \ TclCompileTokens((interp), (tokenPtr)+1, (tokenPtr)->numComponents, \ (envPtr)); \ } @@ -49,6 +50,10 @@ ExtCmdLoc *mapPtr = envPtr->extCmdMapPtr; \ int eclIndex = mapPtr->nuloc - 1 +#define SetLineInformation(word) \ + envPtr->line = mapPtr->loc [eclIndex].line [(word)]; \ + envPtr->clNext = mapPtr->loc [eclIndex].next [(word)] + /* * Convenience macro for use when compiling bodies of commands. The ANSI C * "prototype" for this macro is: @@ -152,7 +157,8 @@ static void PrintJumptableInfo(ClientData clientData, static int PushVarName(Tcl_Interp *interp, Tcl_Token *varTokenPtr, CompileEnv *envPtr, int flags, int *localIndexPtr, - int *simpleVarNamePtr, int *isScalarPtr, int line); + int *simpleVarNamePtr, int *isScalarPtr, + int line, int* clNext); static int CompileAssociativeBinaryOpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, const char *identity, int instruction, CompileEnv *envPtr); @@ -169,6 +175,11 @@ static void CompileReturnInternal(CompileEnv *envPtr, unsigned char op, int code, int level, Tcl_Obj *returnOpts); +#define PushVarNameWord(i,v,e,f,l,s,sc,word) \ + PushVarName (i,v,e,f,l,s,sc, \ + mapPtr->loc [eclIndex].line [(word)], \ + mapPtr->loc [eclIndex].next [(word)]) + /* * Flags bits used by PushVarName. */ @@ -259,9 +270,8 @@ TclCompileAppendCmd( varTokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarName(interp, varTokenPtr, envPtr, TCL_CREATE_VAR, - &localIndex, &simpleVarName, &isScalar, - mapPtr->loc[eclIndex].line[1]); + PushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR, + &localIndex, &simpleVarName, &isScalar, 1); /* * We are doing an assignment, otherwise TclCompileSetCmd was called, so @@ -449,7 +459,7 @@ TclCompileCatchCmd( * range so that errors in the substitution are not catched [Bug 219184] */ - envPtr->line = mapPtr->loc[eclIndex].line[1]; + SetLineInformation (1); if (cmdTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) { ExceptionRangeStarts(envPtr, range); CompileBody(envPtr, cmdTokenPtr, interp); @@ -921,7 +931,7 @@ TclCompileDictForCmd( * Compile the loop body itself. It should be stack-neutral. */ - envPtr->line = mapPtr->loc[eclIndex].line[4]; + SetLineInformation (4); CompileBody(envPtr, bodyTokenPtr, interp); TclEmitOpcode( INST_POP, envPtr); @@ -1447,7 +1457,7 @@ TclCompileForCmd( * Inline compile the initial command. */ - envPtr->line = mapPtr->loc[eclIndex].line[1]; + SetLineInformation (1); CompileBody(envPtr, startTokenPtr, interp); TclEmitOpcode(INST_POP, envPtr); @@ -1470,7 +1480,7 @@ TclCompileForCmd( */ bodyCodeOffset = ExceptionRangeStarts(envPtr, bodyRange); - envPtr->line = mapPtr->loc[eclIndex].line[4]; + SetLineInformation (4); CompileBody(envPtr, bodyTokenPtr, interp); ExceptionRangeEnds(envPtr, bodyRange); envPtr->currStackDepth = savedStackDepth + 1; @@ -1482,7 +1492,7 @@ TclCompileForCmd( envPtr->currStackDepth = savedStackDepth; nextCodeOffset = ExceptionRangeStarts(envPtr, nextRange); - envPtr->line = mapPtr->loc[eclIndex].line[3]; + SetLineInformation (3); CompileBody(envPtr, nextTokenPtr, interp); ExceptionRangeEnds(envPtr, nextRange); envPtr->currStackDepth = savedStackDepth + 1; @@ -1503,7 +1513,7 @@ TclCompileForCmd( testCodeOffset += 3; } - envPtr->line = mapPtr->loc[eclIndex].line[2]; + SetLineInformation (2); envPtr->currStackDepth = savedStackDepth; TclCompileExprWords(interp, testTokenPtr, 1, envPtr); envPtr->currStackDepth = savedStackDepth + 1; @@ -1753,7 +1763,7 @@ TclCompileForeachCmd( i < numWords-1; i++, tokenPtr = TokenAfter(tokenPtr)) { if ((i%2 == 0) && (i > 0)) { - envPtr->line = mapPtr->loc[eclIndex].line[i]; + SetLineInformation (i); CompileTokens(envPtr, tokenPtr, interp); tempVar = (firstValueTemp + loopIndex); if (tempVar <= 255) { @@ -1785,7 +1795,7 @@ TclCompileForeachCmd( * Inline compile the loop body. */ - envPtr->line = mapPtr->loc[eclIndex].line[bodyIndex]; + SetLineInformation (bodyIndex); ExceptionRangeStarts(envPtr, range); CompileBody(envPtr, bodyTokenPtr, interp); ExceptionRangeEnds(envPtr, range); @@ -2124,7 +2134,7 @@ TclCompileIfCmd( compileScripts = 0; } } else { - envPtr->line = mapPtr->loc[eclIndex].line[wordIdx]; + SetLineInformation (wordIdx); Tcl_ResetResult(interp); TclCompileExprWords(interp, testTokenPtr, 1, envPtr); if (jumpFalseFixupArray.next >= jumpFalseFixupArray.end) { @@ -2166,7 +2176,7 @@ TclCompileIfCmd( */ if (compileScripts) { - envPtr->line = mapPtr->loc[eclIndex].line[wordIdx]; + SetLineInformation (wordIdx); envPtr->currStackDepth = savedStackDepth; CompileBody(envPtr, tokenPtr, interp); } @@ -2254,7 +2264,7 @@ TclCompileIfCmd( * Compile the else command body. */ - envPtr->line = mapPtr->loc[eclIndex].line[wordIdx]; + SetLineInformation (wordIdx); CompileBody(envPtr, tokenPtr, interp); } @@ -2356,9 +2366,8 @@ TclCompileIncrCmd( varTokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarName(interp, varTokenPtr, envPtr, TCL_NO_LARGE_INDEX|TCL_CREATE_VAR, - &localIndex, &simpleVarName, &isScalar, - mapPtr->loc[eclIndex].line[1]); + PushVarNameWord(interp, varTokenPtr, envPtr, TCL_NO_LARGE_INDEX|TCL_CREATE_VAR, + &localIndex, &simpleVarName, &isScalar, 1); /* * If an increment is given, push it, but see first if it's a small @@ -2384,7 +2393,7 @@ TclCompileIncrCmd( PushLiteral(envPtr, word, numBytes); } } else { - envPtr->line = mapPtr->loc[eclIndex].line[2]; + SetLineInformation (2); CompileTokens(envPtr, incrTokenPtr, interp); } } else { /* No incr amount given so use 1. */ @@ -2499,9 +2508,8 @@ TclCompileLappendCmd( varTokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarName(interp, varTokenPtr, envPtr, TCL_CREATE_VAR, - &localIndex, &simpleVarName, &isScalar, - mapPtr->loc[eclIndex].line[1]); + PushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR, + &localIndex, &simpleVarName, &isScalar, 1); /* * If we are doing an assignment, push the new value. In the no values @@ -2606,8 +2614,8 @@ TclCompileLassignCmd( * Generate the next variable name. */ - PushVarName(interp, tokenPtr, envPtr, TCL_CREATE_VAR, &localIndex, - &simpleVarName, &isScalar, mapPtr->loc[eclIndex].line[idx+2]); + PushVarNameWord(interp, tokenPtr, envPtr, TCL_CREATE_VAR, &localIndex, + &simpleVarName, &isScalar, idx+2); /* * Emit instructions to get the idx'th item out of the list value on @@ -2943,9 +2951,8 @@ TclCompileLsetCmd( */ varTokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarName(interp, varTokenPtr, envPtr, TCL_CREATE_VAR, - &localIndex, &simpleVarName, &isScalar, - mapPtr->loc[eclIndex].line[1]); + PushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR, + &localIndex, &simpleVarName, &isScalar, 1); /* * Push the "index" args and the new element value. @@ -3445,9 +3452,8 @@ TclCompileSetCmd( */ varTokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarName(interp, varTokenPtr, envPtr, TCL_CREATE_VAR, - &localIndex, &simpleVarName, &isScalar, - mapPtr->loc[eclIndex].line[1]); + PushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR, + &localIndex, &simpleVarName, &isScalar, 1); /* * If we are doing an assignment, push the new value. @@ -3728,7 +3734,7 @@ TclCompileStringMatchCmd( } PushLiteral(envPtr, str, length); } else { - envPtr->line = mapPtr->loc[eclIndex].line[i+1+nocase]; + SetLineInformation (i+1+nocase); CompileTokens(envPtr, tokenPtr, interp); } tokenPtr = TokenAfter(tokenPtr); @@ -3794,7 +3800,7 @@ TclCompileStringLenCmd( len = sprintf(buf, "%d", len); PushLiteral(envPtr, buf, len); } else { - envPtr->line = mapPtr->loc[eclIndex].line[1]; + SetLineInformation (1); CompileTokens(envPtr, tokenPtr, interp); TclEmitOpcode(INST_STR_LEN, envPtr); } @@ -3844,6 +3850,7 @@ TclCompileSwitchCmd( Tcl_Token **bodyToken; /* Array of pointers to pattern list items. */ int *bodyLines; /* Array of line numbers for body list * items. */ + int** bodyNext; int foundDefault; /* Flag to indicate whether a "default" clause * is present. */ @@ -3862,6 +3869,7 @@ TclCompileSwitchCmd( int isListedArms = 0; int i, valueIndex; DefineLineInformation; /* TIP #280 */ + int* clNext = envPtr->clNext; /* * Only handle the following versions: @@ -4040,6 +4048,7 @@ TclCompileSwitchCmd( bodyTokenArray = (Tcl_Token *) ckalloc(sizeof(Tcl_Token) * numWords); bodyToken = (Tcl_Token **) ckalloc(sizeof(Tcl_Token *) * numWords); bodyLines = (int *) ckalloc(sizeof(int) * numWords); + bodyNext = (int **) ckalloc(sizeof(int*) * numWords); /* * Locate the start of the arms within the overall word. @@ -4083,6 +4092,7 @@ TclCompileSwitchCmd( ckfree((char *) bodyToken); ckfree((char *) bodyTokenArray); ckfree((char *) bodyLines); + ckfree((char *) bodyNext); return TCL_ERROR; } @@ -4093,7 +4103,10 @@ TclCompileSwitchCmd( */ TclAdvanceLines(&bline, p, bodyTokenArray[i].start); + TclAdvanceContinuations (&bline, &clNext, + bodyTokenArray[i].start - envPtr->source); bodyLines[i] = bline; + bodyNext[i] = clNext; p = bodyTokenArray[i].start; while (isspace(UCHAR(*tokenStartPtr))) { @@ -4121,6 +4134,7 @@ TclCompileSwitchCmd( ckfree((char *) bodyToken); ckfree((char *) bodyTokenArray); ckfree((char *) bodyLines); + ckfree((char *) bodyNext); return TCL_ERROR; } @@ -4141,6 +4155,7 @@ TclCompileSwitchCmd( bodyToken = (Tcl_Token **) ckalloc(sizeof(Tcl_Token *) * numWords); bodyLines = (int *) ckalloc(sizeof(int) * numWords); + bodyNext = (int **) ckalloc(sizeof(int*) * numWords); bodyTokenArray = NULL; for (i=0 ; i<numWords ; i++) { /* @@ -4153,6 +4168,7 @@ TclCompileSwitchCmd( tokenPtr->numComponents != 1) { ckfree((char *) bodyToken); ckfree((char *) bodyLines); + ckfree((char *) bodyNext); return TCL_ERROR; } bodyToken[i] = tokenPtr+1; @@ -4162,6 +4178,7 @@ TclCompileSwitchCmd( */ bodyLines[i] = mapPtr->loc[eclIndex].line[valueIndex+1+i]; + bodyNext[i] = mapPtr->loc[eclIndex].next[valueIndex+1+i]; tokenPtr = TokenAfter(tokenPtr); } } @@ -4175,6 +4192,7 @@ TclCompileSwitchCmd( bodyToken[numWords-1]->start[0] == '-') { ckfree((char *) bodyToken); ckfree((char *) bodyLines); + ckfree((char *) bodyNext); if (bodyTokenArray != NULL) { ckfree((char *) bodyTokenArray); } @@ -4186,7 +4204,7 @@ TclCompileSwitchCmd( * First, we push the value we're matching against on the stack. */ - envPtr->line = mapPtr->loc[eclIndex].line[valueIndex]; + SetLineInformation (valueIndex); CompileTokens(envPtr, valueTokenPtr, interp); /* @@ -4308,6 +4326,7 @@ TclCompileSwitchCmd( */ envPtr->line = bodyLines[i+1]; /* TIP #280 */ + envPtr->clNext = bodyNext[i+1]; /* TIP #280 */ TclCompileCmdWord(interp, bodyToken[i+1], 1, envPtr); /* @@ -4359,6 +4378,7 @@ TclCompileSwitchCmd( ckfree((char *) finalFixups); ckfree((char *) bodyToken); ckfree((char *) bodyLines); + ckfree((char *) bodyNext); if (bodyTokenArray != NULL) { ckfree((char *) bodyTokenArray); } @@ -4520,6 +4540,7 @@ TclCompileSwitchCmd( TclEmitOpcode(INST_POP, envPtr); envPtr->currStackDepth = savedStackDepth + 1; envPtr->line = bodyLines[i+1]; /* TIP #280 */ + envPtr->clNext = bodyNext[i+1]; /* TIP #280 */ TclCompileCmdWord(interp, bodyToken[i+1], 1, envPtr); if (!foundDefault) { @@ -4536,6 +4557,7 @@ TclCompileSwitchCmd( ckfree((char *) bodyToken); ckfree((char *) bodyLines); + ckfree((char *) bodyNext); if (bodyTokenArray != NULL) { ckfree((char *) bodyTokenArray); } @@ -4792,7 +4814,7 @@ TclCompileWhileCmd( * Compile the loop body. */ - envPtr->line = mapPtr->loc[eclIndex].line[2]; + SetLineInformation (2); bodyCodeOffset = ExceptionRangeStarts(envPtr, range); CompileBody(envPtr, bodyTokenPtr, interp); ExceptionRangeEnds(envPtr, range); @@ -4812,7 +4834,7 @@ TclCompileWhileCmd( testCodeOffset += 3; } envPtr->currStackDepth = savedStackDepth; - envPtr->line = mapPtr->loc[eclIndex].line[1]; + SetLineInformation (1); TclCompileExprWords(interp, testTokenPtr, 1, envPtr); envPtr->currStackDepth = savedStackDepth + 1; @@ -4877,7 +4899,8 @@ PushVarName( int *localIndexPtr, /* Must not be NULL. */ int *simpleVarNamePtr, /* Must not be NULL. */ int *isScalarPtr, /* Must not be NULL. */ - int line) /* Line the token starts on. */ + int line, /* Line the token starts on. */ + int* clNext) /* Reference to offset of next hidden cont. line */ { register const char *p; const char *name, *elName; @@ -5061,6 +5084,7 @@ PushVarName( if (elName != NULL) { if (elNameChars) { envPtr->line = line; + envPtr->clNext = clNext; TclCompileTokens(interp, elemTokenPtr, elemTokenCount, envPtr); } else { PushLiteral(envPtr, "", 0); @@ -5072,6 +5096,7 @@ PushVarName( */ envPtr->line = line; + envPtr->clNext = clNext; CompileTokens(envPtr, varTokenPtr, interp); } @@ -5849,9 +5874,8 @@ TclCompileUpvarCmd( localTokenPtr = TokenAfter(otherTokenPtr); CompileWord(envPtr, otherTokenPtr, interp, 1); - PushVarName(interp, localTokenPtr, envPtr, TCL_CREATE_VAR, - &localIndex, &simpleVarName, &isScalar, - mapPtr->loc[eclIndex].line[1]); + PushVarNameWord(interp, localTokenPtr, envPtr, TCL_CREATE_VAR, + &localIndex, &simpleVarName, &isScalar, 1); if((localIndex < 0) || !isScalar) { return TCL_ERROR; @@ -5942,9 +5966,8 @@ TclCompileNamespaceCmd( localTokenPtr = TokenAfter(otherTokenPtr); CompileWord(envPtr, otherTokenPtr, interp, 1); - PushVarName(interp, localTokenPtr, envPtr, TCL_CREATE_VAR, - &localIndex, &simpleVarName, &isScalar, - mapPtr->loc[eclIndex].line[1]); + PushVarNameWord(interp, localTokenPtr, envPtr, TCL_CREATE_VAR, + &localIndex, &simpleVarName, &isScalar, 1); if((localIndex < 0) || !isScalar) { return TCL_ERROR; @@ -6444,8 +6467,8 @@ TclCompileInfoExistsCmd( */ tokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarName(interp, tokenPtr, envPtr, TCL_CREATE_VAR, &localIndex, - &simpleVarName, &isScalar, mapPtr->loc[eclIndex].line[1]); + PushVarNameWord(interp, tokenPtr, envPtr, TCL_CREATE_VAR, &localIndex, + &simpleVarName, &isScalar, 1); /* * Emit instruction to check the variable for existence. |