summaryrefslogtreecommitdiffstats
path: root/generic/tclCompile.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclCompile.c')
-rw-r--r--generic/tclCompile.c49
1 files changed, 39 insertions, 10 deletions
diff --git a/generic/tclCompile.c b/generic/tclCompile.c
index 3c8e4ef..f3e9db3 100644
--- a/generic/tclCompile.c
+++ b/generic/tclCompile.c
@@ -545,6 +545,17 @@ InstructionDesc const tclInstructionTable[] = {
/* Drops an element from the auxiliary stack, popping stack elements
* until the matching stack depth is reached. */
+ /* New foreach implementation */
+ {"foreach_start", 5, +2, 1, {OPERAND_AUX4}},
+ /* Initialize execution of a foreach loop. Operand is aux data index
+ * of the ForeachInfo structure for the foreach command. It pushes 2
+ * elements which hold runtime params for foreach_step, they are later
+ * dropped by foreach_end together with the value lists. */
+ {"foreach_step", 1, 0, 0, {OPERAND_NONE}},
+ /* "Step" or begin next iteration of foreach loop. */
+ {"foreach_end", 1, 0, 0, {OPERAND_NONE}},
+ {"lmap_collect", 1, -1, 0, {OPERAND_NONE}},
+
{NULL, 0, 0, 0, {OPERAND_NONE}}
};
@@ -754,7 +765,9 @@ TclSetByteCodeFromAny(
* instruction generator boundaries.
*/
- TclOptimizeBytecode(&compEnv);
+ if (iPtr->extra.optimizer) {
+ (iPtr->extra.optimizer)(&compEnv);
+ }
/*
* Invoke the compilation hook procedure if one exists.
@@ -1709,7 +1722,7 @@ TclCompileInvocation(
int numWords,
CompileEnv *envPtr)
{
- int wordIdx = 0;
+ int wordIdx = 0, depth = TclGetStackDepth(envPtr);
DefineLineInformation;
if (cmdObj) {
@@ -1742,6 +1755,7 @@ TclCompileInvocation(
} else {
TclEmitInvoke(envPtr, INST_INVOKE_STK4, wordIdx);
}
+ TclCheckStackDepth(depth+1, envPtr);
}
static void
@@ -1754,7 +1768,8 @@ CompileExpanded(
{
int wordIdx = 0;
DefineLineInformation;
-
+ int depth = TclGetStackDepth(envPtr);
+
StartExpanding(envPtr);
if (cmdObj) {
CompileCmdLiteral(interp, cmdObj, envPtr);
@@ -1800,6 +1815,7 @@ CompileExpanded(
*/
TclEmitInvoke(envPtr, INST_INVOKE_EXPANDED, wordIdx);
+ TclCheckStackDepth(depth+1, envPtr);
}
static int
@@ -1811,6 +1827,7 @@ CompileCmdCompileProc(
{
int unwind = 0, incrOffset = -1;
DefineLineInformation;
+ int depth = TclGetStackDepth(envPtr);
/*
* Emit of the INST_START_CMD instruction is controlled by the value of
@@ -1858,6 +1875,7 @@ CompileCmdCompileProc(
TclStoreInt4AtPtr(envPtr->codeNext - startPtr, startPtr + 1);
}
}
+ TclCheckStackDepth(depth+1, envPtr);
return TCL_OK;
}
@@ -1900,7 +1918,8 @@ CompileCommandTokens(
int *clNext = envPtr->clNext;
int cmdIdx = envPtr->numCommands;
int startCodeOffset = envPtr->codeNext - envPtr->codeStart;
-
+ int depth = TclGetStackDepth(envPtr);
+
assert (parsePtr->numWords > 0);
/* Pre-Compile */
@@ -1991,6 +2010,7 @@ CompileCommandTokens(
eclPtr->loc[wlineat].line = wlines;
eclPtr->loc[wlineat].next = NULL;
+ TclCheckStackDepth(depth, envPtr);
return cmdIdx;
}
@@ -2010,6 +2030,7 @@ TclCompileScript(
* Initial value of -1 indicates this routine
* has not yet generated any bytecode. */
const char *p = script; /* Where we are in our compile. */
+ int depth = TclGetStackDepth(envPtr);
if (envPtr->iPtr == NULL) {
Tcl_Panic("TclCompileScript() called on uninitialized CompileEnv");
@@ -2121,6 +2142,7 @@ TclCompileScript(
envPtr->codeNext--;
envPtr->currStackDepth++;
}
+ TclCheckStackDepth(depth+1, envPtr);
}
/*
@@ -2231,6 +2253,7 @@ TclCompileTokens(
#define NUM_STATIC_POS 20
int isLiteral, maxNumCL, numCL;
int *clPosition = NULL;
+ int depth = TclGetStackDepth(envPtr);
/*
* For the handling of continuation lines in literals we first check if
@@ -2408,6 +2431,7 @@ TclCompileTokens(
if (maxNumCL) {
ckfree(clPosition);
}
+ TclCheckStackDepth(depth+1, envPtr);
}
/*
@@ -3923,7 +3947,8 @@ TclEmitInvoke(
ExceptionAux *auxBreakPtr, *auxContinuePtr;
int arg1, arg2, wordCount = 0, expandCount = 0;
int loopRange = 0, breakRange = 0, continueRange = 0;
-
+ int cleanup, depth = TclGetStackDepth(envPtr);
+
/*
* Parse the arguments.
*/
@@ -3931,30 +3956,31 @@ TclEmitInvoke(
va_start(argList, opcode);
switch (opcode) {
case INST_INVOKE_STK1:
- wordCount = arg1 = va_arg(argList, int);
+ wordCount = arg1 = cleanup = va_arg(argList, int);
arg2 = 0;
break;
case INST_INVOKE_STK4:
- wordCount = arg1 = va_arg(argList, int);
+ wordCount = arg1 = cleanup = va_arg(argList, int);
arg2 = 0;
break;
case INST_INVOKE_REPLACE:
arg1 = va_arg(argList, int);
arg2 = va_arg(argList, int);
wordCount = arg1 + arg2 - 1;
+ cleanup = arg1 + 1;
break;
default:
Tcl_Panic("unexpected opcode");
case INST_EVAL_STK:
- wordCount = 1;
+ wordCount = cleanup = 1;
arg1 = arg2 = 0;
break;
case INST_RETURN_STK:
- wordCount = 2;
+ wordCount = cleanup = 2;
arg1 = arg2 = 0;
break;
case INST_INVOKE_EXPANDED:
- wordCount = arg1 = va_arg(argList, int);
+ wordCount = arg1 = cleanup = va_arg(argList, int);
arg2 = 0;
expandCount = 1;
break;
@@ -4057,6 +4083,7 @@ TclEmitInvoke(
ExceptionRangeTarget(envPtr, loopRange, breakOffset);
TclCleanupStackForBreakContinue(envPtr, auxBreakPtr);
TclAddLoopBreakFixup(envPtr, auxBreakPtr);
+ TclAdjustStackDepth(1, envPtr);
envPtr->currStackDepth = savedStackDepth;
envPtr->expandCount = savedExpandCount;
@@ -4068,6 +4095,7 @@ TclEmitInvoke(
ExceptionRangeTarget(envPtr, loopRange, continueOffset);
TclCleanupStackForBreakContinue(envPtr, auxContinuePtr);
TclAddLoopContinueFixup(envPtr, auxContinuePtr);
+ TclAdjustStackDepth(1, envPtr);
envPtr->currStackDepth = savedStackDepth;
envPtr->expandCount = savedExpandCount;
@@ -4076,6 +4104,7 @@ TclEmitInvoke(
TclFinalizeLoopExceptionRange(envPtr, loopRange);
TclFixupForwardJumpToHere(envPtr, &nonTrapFixup, 127);
}
+ TclCheckStackDepth(depth+1-cleanup, envPtr);
}
/*