summaryrefslogtreecommitdiffstats
path: root/generic/tclEnsemble.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2013-07-16 17:21:12 (GMT)
committerdgp <dgp@users.sourceforge.net>2013-07-16 17:21:12 (GMT)
commit01f1692c1f639eeb817ce6c51928195620872173 (patch)
tree6bf6f2f1128916b28edbf150cdb10b22ad1761e8 /generic/tclEnsemble.c
parente783ef57ec6e0ab2d08f1524e86cbc849e36f763 (diff)
downloadtcl-01f1692c1f639eeb817ce6c51928195620872173.zip
tcl-01f1692c1f639eeb817ce6c51928195620872173.tar.gz
tcl-01f1692c1f639eeb817ce6c51928195620872173.tar.bz2
Simplify the ensemble subcommand compile. There's no need to be
crafting synthetic Tcl_Parse and copying tokens. Some pointer shifts will do.
Diffstat (limited to 'generic/tclEnsemble.c')
-rw-r--r--generic/tclEnsemble.c70
1 files changed, 15 insertions, 55 deletions
diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c
index 864283b..e4f96c0 100644
--- a/generic/tclEnsemble.c
+++ b/generic/tclEnsemble.c
@@ -3029,12 +3029,6 @@ TclCompileEnsemble(
return ourResult;
}
-/*
- * How to compile a subcommand using its own command compiler. To do that, we
- * have to perform some trickery to rewrite the arguments, as compilers *must*
- * have parse tokens that refer to addresses in the original script.
- */
-
static int
CompileToCompiledCommand(
Tcl_Interp *interp,
@@ -3043,10 +3037,8 @@ CompileToCompiledCommand(
Command *cmdPtr,
CompileEnv *envPtr) /* Holds resulting instructions. */
{
- Tcl_Parse synthetic;
- Tcl_Token *tokenPtr;
int result, i;
- int savedNumCmds = envPtr->numCommands;
+ Tcl_Token *saveTokenPtr = parsePtr->tokenPtr;
int savedStackDepth = envPtr->currStackDepth;
unsigned savedCodeNext = envPtr->codeNext - envPtr->codeStart;
DefineLineInformation;
@@ -3055,47 +3047,17 @@ CompileToCompiledCommand(
return TCL_ERROR;
}
- TclParseInit(interp, NULL, 0, &synthetic);
- synthetic.numWords = parsePtr->numWords - depth + 1;
- TclGrowParseTokenArray(&synthetic, 2);
- synthetic.numTokens = 2;
-
- /*
- * Now we have the space to work in, install something rewritten. The
- * first word will "officially" be the bytes of the structured ensemble
- * name. That's technically wrong, but nobody will care; we just need
- * *something* here...
- */
-
- synthetic.tokenPtr[0].type = TCL_TOKEN_SIMPLE_WORD;
- synthetic.tokenPtr[0].start = parsePtr->tokenPtr[0].start;
- synthetic.tokenPtr[0].numComponents = 1;
- synthetic.tokenPtr[1].type = TCL_TOKEN_TEXT;
- synthetic.tokenPtr[1].start = parsePtr->tokenPtr[0].start;
- synthetic.tokenPtr[1].numComponents = 0;
- for (i=0,tokenPtr=parsePtr->tokenPtr ; i<depth ; i++) {
- int sclen = (tokenPtr->start - synthetic.tokenPtr[0].start)
- + tokenPtr->size;
-
- synthetic.tokenPtr[0].size = sclen;
- synthetic.tokenPtr[1].size = sclen;
- tokenPtr = TokenAfter(tokenPtr);
- }
-
/*
- * Copy over the real argument tokens.
+ * Advance parsePtr->tokenPtr so that it points at the last subcommand.
+ * This will be wrong, but it will not matter, and it will put the
+ * tokens for the arguments in the right place without the needed to
+ * allocate a synthetic Tcl_Parse struct, or copy tokens around.
*/
- for (i=1; i<synthetic.numWords; i++) {
- int toCopy;
-
- toCopy = tokenPtr->numComponents + 1;
- TclGrowParseTokenArray(&synthetic, toCopy);
- memcpy(synthetic.tokenPtr + synthetic.numTokens, tokenPtr,
- sizeof(Tcl_Token) * toCopy);
- synthetic.numTokens += toCopy;
- tokenPtr = TokenAfter(tokenPtr);
+ for (i = 0; i < depth - 1; i++) {
+ parsePtr->tokenPtr = TokenAfter(parsePtr->tokenPtr);
}
+ parsePtr->numWords -= (depth - 1);
/*
* Shift the line information arrays to account for different word
@@ -3109,7 +3071,7 @@ CompileToCompiledCommand(
* Hand off compilation to the subcommand compiler. At last!
*/
- result = cmdPtr->compileProc(interp, &synthetic, cmdPtr, envPtr);
+ result = cmdPtr->compileProc(interp, parsePtr, cmdPtr, envPtr);
/*
* Undo the shift.
@@ -3118,22 +3080,20 @@ CompileToCompiledCommand(
mapPtr->loc[eclIndex].line -= (depth - 1);
mapPtr->loc[eclIndex].next -= (depth - 1);
+ parsePtr->numWords += (depth - 1);
+ parsePtr->tokenPtr = saveTokenPtr;
+
/*
- * If our target fails to compile, revert the number of commands and the
- * pointer to the place to issue the next instruction. [Bug 3600328]
+ * If our target failed to compile, revert any data from failed partial
+ * compiles. Note that envPtr->numCommands need not be checked because
+ * we avoid compiling subcommands that recursively call TclCompileScript().
*/
if (result != TCL_OK) {
- envPtr->numCommands = savedNumCmds;
envPtr->currStackDepth = savedStackDepth;
envPtr->codeNext = envPtr->codeStart + savedCodeNext;
}
- /*
- * Clean up if necessary.
- */
-
- Tcl_FreeParse(&synthetic);
return result;
}