summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2019-05-16 17:56:37 (GMT)
committersebres <sebres@users.sourceforge.net>2019-05-16 17:56:37 (GMT)
commit8af3fb7317d53796f74a0cda158ecbe8e4fa1013 (patch)
tree6d848dcfde9f2617c1fb20efe1a85497ecfcbfb2
parentde4f571baa7f9d53f48031e230c4d8f7c69cf1f5 (diff)
parentccc592df50d217757d74cb343d046a92d76860c1 (diff)
downloadtcl-8af3fb7317d53796f74a0cda158ecbe8e4fa1013.zip
tcl-8af3fb7317d53796f74a0cda158ecbe8e4fa1013.tar.gz
tcl-8af3fb7317d53796f74a0cda158ecbe8e4fa1013.tar.bz2
merge 8.5 (timerate fix to avoid impact of object duplication on shared interp result by the measurement)
-rw-r--r--generic/tclCmdMZ.c40
-rw-r--r--tests/cmdMZ.test8
2 files changed, 33 insertions, 15 deletions
diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c
index b2c4ae3..e58d026 100644
--- a/generic/tclCmdMZ.c
+++ b/generic/tclCmdMZ.c
@@ -4512,6 +4512,14 @@ Tcl_TimeRateObjCmd(
}
codePtr = TclCompileObj(interp, objPtr, NULL, 0);
TclPreserveByteCode(codePtr);
+ /*
+ * Replace last compiled done instruction with continue: it's a part of
+ * iteration, this way evaluation will be more similar to a cycle (also
+ * avoids extra overhead to set result to interp, etc.)
+ */
+ if (codePtr->codeStart[codePtr->numCodeBytes-1] == INST_DONE) {
+ codePtr->codeStart[codePtr->numCodeBytes-1] = INST_CONTINUE;
+ }
}
/*
@@ -4558,23 +4566,25 @@ Tcl_TimeRateObjCmd(
} else { /* eval */
result = TclEvalObjEx(interp, objPtr, 0, NULL, 0);
}
- if (result != TCL_OK) {
- /*
- * Allow break from measurement cycle (used for conditional
- * stop).
- */
+ /*
+ * Allow break and continue from measurement cycle (used for
+ * conditional stop and flow control of iterations).
+ */
- if (result != TCL_BREAK) {
+ switch (result) {
+ case TCL_OK:
+ break;
+ case TCL_BREAK:
+ /*
+ * Force stop immediately.
+ */
+ threshold = 1;
+ maxcnt = 0;
+ case TCL_CONTINUE:
+ result = TCL_OK;
+ break;
+ default:
goto done;
- }
-
- /*
- * Force stop immediately.
- */
-
- threshold = 1;
- maxcnt = 0;
- result = TCL_OK;
}
/*
diff --git a/tests/cmdMZ.test b/tests/cmdMZ.test
index 7dc04a5..cbccd1c 100644
--- a/tests/cmdMZ.test
+++ b/tests/cmdMZ.test
@@ -407,6 +407,14 @@ test cmdMZ-6.8 {Tcl_TimeRateObjCmd: allow (conditional) break from timerate} {
[expr {[lindex $m1 4] > 1000}] \
[expr {[lindex $m1 6] < 10}]
} {1 1 1 1}
+test cmdMZ-6.8.1 {Tcl_TimeRateObjCmd: allow (conditional) continue in timerate} {
+ set m1 [timerate {continue; return -code error "unexpected"} 1000 10]
+ list \
+ [expr {[lindex $m1 0] < 1000}] \
+ [expr {[lindex $m1 2] == 10}] \
+ [expr {[lindex $m1 4] > 1000}] \
+ [expr {[lindex $m1 6] < 100}]
+} {1 1 1 1}
test cmdMZ-6.9 {Tcl_TimeRateObjCmd: max count of iterations} {
set m1 [timerate {} 1000 5]; # max-count wins
set m2 [timerate {_nrt_sleep 20} 1 5]; # max-time wins