summaryrefslogtreecommitdiffstats
path: root/generic/tclCompCmdsGR.c
diff options
context:
space:
mode:
authordkf <dkf@noemail.net>2013-10-15 00:27:56 (GMT)
committerdkf <dkf@noemail.net>2013-10-15 00:27:56 (GMT)
commite32a18f07743f40bbd14f8812c07dc3dd49c504e (patch)
tree466bc473e8418f88ba75f7d6abd13340020be374 /generic/tclCompCmdsGR.c
parent629ace57c2b7f914ddba75c8bb7731d0e839cba2 (diff)
downloadtcl-e32a18f07743f40bbd14f8812c07dc3dd49c504e.zip
tcl-e32a18f07743f40bbd14f8812c07dc3dd49c504e.tar.gz
tcl-e32a18f07743f40bbd14f8812c07dc3dd49c504e.tar.bz2
Do jump generation at places where INST_RETURN_IMM might occur.
FossilOrigin-Name: 98717da70ac4138e4cd0b3eee434ee78c0db0b98
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);