summaryrefslogtreecommitdiffstats
path: root/generic/tclCompCmdsGR.c
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2013-10-15 00:27:56 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2013-10-15 00:27:56 (GMT)
commit2aaf426036b86f6521dfb6d80b2641e8097e832d (patch)
tree7ee2b0d64d3baf69e1ed93317f150a8d59b9b25f /generic/tclCompCmdsGR.c
parente15b769c9d61251dfb59993b3ed7c6b878fd4151 (diff)
downloadtcl-2aaf426036b86f6521dfb6d80b2641e8097e832d.zip
tcl-2aaf426036b86f6521dfb6d80b2641e8097e832d.tar.gz
tcl-2aaf426036b86f6521dfb6d80b2641e8097e832d.tar.bz2
Do jump generation at places where INST_RETURN_IMM might occur.
Diffstat (limited to 'generic/tclCompCmdsGR.c')
-rw-r--r--generic/tclCompCmdsGR.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c
index 3efcba7..5513b01 100644
--- a/generic/tclCompCmdsGR.c
+++ b/generic/tclCompCmdsGR.c
@@ -2480,7 +2480,6 @@ TclCompileReturnCmd(
* emit the INST_RETURN_IMM instruction with code and level as operands.
*/
- // TODO: when (code==TCL_BREAK || code==TCL_CONTINUE)&&(level==0&&size==0), check for stack balance and jump opportunities
CompileReturnInternal(envPtr, INST_RETURN_IMM, code, level, returnOpts);
return TCL_OK;
@@ -2522,6 +2521,23 @@ CompileReturnInternal(
int level,
Tcl_Obj *returnOpts)
{
+ if (level == 0 && (code == TCL_BREAK || code == TCL_CONTINUE)) {
+ ExceptionRange *rangePtr;
+ ExceptionAux *exceptAux;
+
+ rangePtr = TclGetInnermostExceptionRange(envPtr, code, &exceptAux);
+ if (rangePtr && rangePtr->type == LOOP_EXCEPTION_RANGE) {
+ TclCleanupStackForBreakContinue(envPtr, exceptAux);
+ if (code == TCL_BREAK) {
+ TclAddLoopBreakFixup(envPtr, exceptAux);
+ } else {
+ TclAddLoopContinueFixup(envPtr, exceptAux);
+ }
+ Tcl_DecrRefCount(returnOpts);
+ return;
+ }
+ }
+
TclEmitPush(TclAddLiteralObj(envPtr, returnOpts, NULL), envPtr);
TclEmitInstInt4(op, code, envPtr);
TclEmitInt4(level, envPtr);