diff options
author | dkf <dkf@noemail.net> | 2013-10-15 00:27:56 (GMT) |
---|---|---|
committer | dkf <dkf@noemail.net> | 2013-10-15 00:27:56 (GMT) |
commit | e32a18f07743f40bbd14f8812c07dc3dd49c504e (patch) | |
tree | 466bc473e8418f88ba75f7d6abd13340020be374 /generic/tclCompCmdsGR.c | |
parent | 629ace57c2b7f914ddba75c8bb7731d0e839cba2 (diff) | |
download | tcl-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.c | 18 |
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); |