summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2019-07-24 14:14:35 (GMT)
committersebres <sebres@users.sourceforge.net>2019-07-24 14:14:35 (GMT)
commit363284783b87919ec374721bc7712342a1b73bf2 (patch)
tree6f90a68f4dc93c9e07f11b9051786890fcc7ff52 /generic
parentbb0e258bba9de0be9568baf642416f1db0b0f797 (diff)
parent87df0b3b65c1bde69b3eb846b990c87cddf24ab5 (diff)
downloadtcl-363284783b87919ec374721bc7712342a1b73bf2.zip
tcl-363284783b87919ec374721bc7712342a1b73bf2.tar.gz
tcl-363284783b87919ec374721bc7712342a1b73bf2.tar.bz2
merge 8.6
Diffstat (limited to 'generic')
-rw-r--r--generic/tclCmdMZ.c21
-rw-r--r--generic/tclExecute.c20
-rw-r--r--generic/tclInt.h1
3 files changed, 25 insertions, 17 deletions
diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c
index cdc1e28..a754a09 100644
--- a/generic/tclCmdMZ.c
+++ b/generic/tclCmdMZ.c
@@ -4188,7 +4188,6 @@ Tcl_TimeRateObjCmd(
};
NRE_callback *rootPtr;
ByteCode *codePtr = NULL;
- int codeOptimized = 0;
for (i = 1; i < objc - 1; i++) {
int index;
@@ -4373,15 +4372,6 @@ 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;
- codeOptimized = 1;
- }
}
/*
@@ -4423,6 +4413,12 @@ Tcl_TimeRateObjCmd(
count++;
if (!direct) { /* precompiled */
rootPtr = TOP_CB(interp);
+ /*
+ * Use loop optimized TEBC call (TCL_EVAL_DISCARD_RESULT): 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.)
+ */
+ ((Interp *)interp)->evalFlags |= TCL_EVAL_DISCARD_RESULT;
result = TclNRExecuteByteCode(interp, codePtr);
result = TclNRRunCallbacks(interp, result, rootPtr);
} else { /* eval */
@@ -4675,11 +4671,6 @@ Tcl_TimeRateObjCmd(
done:
if (codePtr != NULL) {
- if ( codeOptimized
- && codePtr->codeStart[codePtr->numCodeBytes-1] == INST_CONTINUE
- ) {
- codePtr->codeStart[codePtr->numCodeBytes-1] = INST_DONE;
- }
TclReleaseByteCode(codePtr);
}
return result;
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 520c2ee..faf5865 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -1981,7 +1981,14 @@ TclNRExecuteByteCode(
*/
TclNRAddCallback(interp, TEBCresume, TD, /* pc */ NULL,
- /* cleanup */ INT2PTR(0), NULL);
+ /* cleanup */ INT2PTR(0), INT2PTR(iPtr->evalFlags));
+
+ /*
+ * Reset discard result flag - because it is applicable for this call only,
+ * and should not affect all the nested invocations may return result.
+ */
+ iPtr->evalFlags &= ~TCL_EVAL_DISCARD_RESULT;
+
return TCL_OK;
}
@@ -2043,6 +2050,7 @@ TEBCresume(
#define auxObjList (TD->auxObjList)
#define catchTop (TD->catchTop)
#define codePtr (TD->codePtr)
+#define curEvalFlags PTR2INT(data[3]) /* calling iPtr->evalFlags */
/*
* Globals: variables that store state, must remain valid at all times.
@@ -2526,6 +2534,14 @@ TEBCresume(
case INST_DONE:
if (tosPtr > initTosPtr) {
+
+ if ((curEvalFlags & TCL_EVAL_DISCARD_RESULT) && (result == TCL_OK)) {
+ /* simulate pop & fast done (like it does continue in loop) */
+ TRACE_WITH_OBJ(("=> discarding "), OBJ_AT_TOS);
+ objPtr = POP_OBJECT();
+ TclDecrRefCount(objPtr);
+ goto abnormalReturn;
+ }
/*
* Set the interpreter's object result to point to the topmost
* object from the stack, and check for a possible [catch]. The
@@ -7695,7 +7711,7 @@ TEBCresume(
*/
/*
- * Abnormal return code. Restore the stack to state it had when
+ * Done or abnormal return code. Restore the stack to state it had when
* starting to execute the ByteCode. Panic if the stack is below the
* initial level.
*/
diff --git a/generic/tclInt.h b/generic/tclInt.h
index 7029173..adb4244 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -2259,6 +2259,7 @@ typedef struct Interp {
#define TCL_EVAL_FILE 0x02
#define TCL_EVAL_SOURCE_IN_FRAME 0x10
#define TCL_EVAL_NORESOLVE 0x20
+#define TCL_EVAL_DISCARD_RESULT 0x40
/*
* Flag bits for Interp structures: