summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormig <mig>2013-12-11 17:13:15 (GMT)
committermig <mig>2013-12-11 17:13:15 (GMT)
commit928127b4eb0729876cc60550259d1e26ae8fb3b5 (patch)
tree0424b78ec3b386d0963a408650f546d0fd08a58b
parent9069cb221f98a9b613716d5d4040c17d1743cb26 (diff)
downloadtcl-mig_catch_compiler.zip
tcl-mig_catch_compiler.tar.gz
tcl-mig_catch_compiler.tar.bz2
allow simple optimization of the OK case, at the cost of some code duplicationmig_catch_compiler
-rw-r--r--generic/tclCompCmds.c58
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;
}