summaryrefslogtreecommitdiffstats
path: root/generic/tclCompCmds.c
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2013-06-05 07:19:02 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2013-06-05 07:19:02 (GMT)
commite2aebdd0bfef45036c0e1242c55efd86773ecca4 (patch)
tree9fd8c663b8cbd76efefec52f9614115721d587b0 /generic/tclCompCmds.c
parent63a81f0f749c1cc9965874146ba78f865ad5393a (diff)
downloadtcl-e2aebdd0bfef45036c0e1242c55efd86773ecca4.zip
tcl-e2aebdd0bfef45036c0e1242c55efd86773ecca4.tar.gz
tcl-e2aebdd0bfef45036c0e1242c55efd86773ecca4.tar.bz2
Stack cleanup works now even in the most evil expansion cases.
Diffstat (limited to 'generic/tclCompCmds.c')
-rw-r--r--generic/tclCompCmds.c62
1 files changed, 12 insertions, 50 deletions
diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c
index 3d6abcf..365e647 100644
--- a/generic/tclCompCmds.c
+++ b/generic/tclCompCmds.c
@@ -493,40 +493,21 @@ TclCompileBreakCmd(
rangePtr = TclGetInnermostExceptionRange(envPtr, TCL_BREAK, &auxPtr);
if (rangePtr && rangePtr->type == LOOP_EXCEPTION_RANGE) {
- int toPop;
-
- /*
- * Ditch the extra elements from the auxiliary stack.
- */
-
- toPop = envPtr->expandCount - auxPtr->expandTarget;
- while (toPop > 0) {
- TclEmitOpcode(INST_EXPAND_DROP, envPtr);
- toPop--;
- }
-
- /*
- * Pop off the extra stack frames.
- */
-
- toPop = envPtr->currStackDepth - auxPtr->stackDepth;
- while (toPop > 0) {
- TclEmitOpcode(INST_POP, envPtr);
- TclAdjustStackDepth(1, envPtr);
- toPop--;
- }
-
/*
* Found the target! No need for a nasty INST_BREAK here.
*/
+ TclCleanupStackForBreakContinue(envPtr, auxPtr);
TclAddLoopBreakFixup(envPtr, auxPtr);
} else {
/*
- * Emit a break instruction.
+ * Emit a real break.
*/
- TclEmitOpcode(INST_BREAK, envPtr);
+ PushStringLiteral(envPtr, "");
+ TclEmitOpcode(INST_DUP, envPtr);
+ TclEmitInstInt4(INST_RETURN_IMM, TCL_BREAK, envPtr);
+ TclEmitInt4(0, envPtr);
}
/*
@@ -846,40 +827,21 @@ TclCompileContinueCmd(
rangePtr = TclGetInnermostExceptionRange(envPtr, TCL_CONTINUE, &auxPtr);
if (rangePtr && rangePtr->type == LOOP_EXCEPTION_RANGE) {
- int toPop;
-
- /*
- * Ditch the extra elements from the auxiliary stack.
- */
-
- toPop = envPtr->expandCount - auxPtr->expandTarget;
- while (toPop > 0) {
- TclEmitOpcode(INST_EXPAND_DROP, envPtr);
- toPop--;
- }
-
- /*
- * Pop off the extra stack frames.
- */
-
- toPop = envPtr->currStackDepth - auxPtr->stackDepth;
- while (toPop > 0) {
- TclEmitOpcode(INST_POP, envPtr);
- TclAdjustStackDepth(1, envPtr);
- toPop--;
- }
-
/*
* Found the target! No need for a nasty INST_CONTINUE here.
*/
+ TclCleanupStackForBreakContinue(envPtr, auxPtr);
TclAddLoopContinueFixup(envPtr, auxPtr);
} else {
/*
- * Emit a continue instruction.
+ * Emit a real continue.
*/
- TclEmitOpcode(INST_CONTINUE, envPtr);
+ PushStringLiteral(envPtr, "");
+ TclEmitOpcode(INST_DUP, envPtr);
+ TclEmitInstInt4(INST_RETURN_IMM, TCL_CONTINUE, envPtr);
+ TclEmitInt4(0, envPtr);
}
/*