diff options
author | mig <mig> | 2013-12-11 17:13:15 (GMT) |
---|---|---|
committer | mig <mig> | 2013-12-11 17:13:15 (GMT) |
commit | 928127b4eb0729876cc60550259d1e26ae8fb3b5 (patch) | |
tree | 0424b78ec3b386d0963a408650f546d0fd08a58b | |
parent | 9069cb221f98a9b613716d5d4040c17d1743cb26 (diff) | |
download | tcl-928127b4eb0729876cc60550259d1e26ae8fb3b5.zip tcl-928127b4eb0729876cc60550259d1e26ae8fb3b5.tar.gz tcl-928127b4eb0729876cc60550259d1e26ae8fb3b5.tar.bz2 |
allow simple optimization of the OK case, at the cost of some code duplicationmig_catch_compiler
-rw-r--r-- | generic/tclCompCmds.c | 58 |
1 files changed, 28 insertions, 30 deletions
diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 72b338c..34c4691 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -614,10 +614,26 @@ TclCompileCatchCmd( ExceptionRangeEnds(envPtr, range); /* - * Emit the "no errors" epilogue: push "0" (TCL_OK) as the catch result, - * and jump around the "error case" code. + * Emit the "no errors" epilogue: last instruction is push "0" (TCL_OK) + * as the catch result, and jump to the end. There is some code + * duplication in order to allow the optimization of the OK case. + * + * NOTE: see comments on instruction ordering below! */ + if (optsIndex != -1) { + TclEmitOpcode( INST_PUSH_RETURN_OPTIONS, envPtr); + } + TclEmitOpcode( INST_END_CATCH, envPtr); + if (optsIndex != -1) { + Emit14Inst( INST_STORE_SCALAR, optsIndex, envPtr); + TclEmitOpcode( INST_POP, envPtr); + } + if (resultIndex != -1) { + Emit14Inst( INST_STORE_SCALAR, resultIndex, envPtr); + } + TclEmitOpcode( INST_POP, envPtr); + PushStringLiteral(envPtr, "0"); TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup); @@ -626,32 +642,21 @@ TclCompileCatchCmd( * return code. */ - TclAdjustStackDepth(-2, envPtr); + TclAdjustStackDepth(-1, envPtr); ExceptionRangeTarget(envPtr, range, catchOffset); - /* Stack at this point is empty */ - TclEmitOpcode( INST_PUSH_RESULT, envPtr); - TclEmitOpcode( INST_PUSH_RETURN_CODE, envPtr); - /* Stack at this point on both branches: result returnCode */ - - if (TclFixupForwardJumpToHere(envPtr, &jumpFixup, 127)) { - Tcl_Panic("TclCompileCatchCmd: bad jump distance %d", - (int)(CurrentOffset(envPtr) - jumpFixup.codeOffset)); - } - - /* - * Push the return options if the caller wants them. This needs to happen - * before INST_END_CATCH + /* Stack at this point is empty. Push the return code, then push the + * result and return options if the caller wants them. This needs to + * happen before INST_END_CATCH. */ + TclEmitOpcode( INST_PUSH_RETURN_CODE, envPtr); + if (resultIndex != -1) { + TclEmitOpcode( INST_PUSH_RESULT, envPtr); + } if (optsIndex != -1) { TclEmitOpcode( INST_PUSH_RETURN_OPTIONS, envPtr); } - - /* - * End the catch - */ - TclEmitOpcode( INST_END_CATCH, envPtr); /* @@ -663,19 +668,12 @@ TclCompileCatchCmd( Emit14Inst( INST_STORE_SCALAR, optsIndex, envPtr); TclEmitOpcode( INST_POP, envPtr); } - - /* - * At this point, the top of the stack is inconveniently ordered: - * result returnCode - * Reverse the stack to store the result. - */ - - TclEmitInstInt4( INST_REVERSE, 2, envPtr); if (resultIndex != -1) { Emit14Inst( INST_STORE_SCALAR, resultIndex, envPtr); + TclEmitOpcode( INST_POP, envPtr); } - TclEmitOpcode( INST_POP, envPtr); + TclFixupForwardJumpToHere(envPtr, &jumpFixup, 127); return TCL_OK; } |