summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
Diffstat (limited to 'generic')
-rw-r--r--generic/tclCompCmds.c55
-rw-r--r--generic/tclDictObj.c3
2 files changed, 34 insertions, 24 deletions
diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c
index 13f479d..61f7988 100644
--- a/generic/tclCompCmds.c
+++ b/generic/tclCompCmds.c
@@ -854,6 +854,19 @@ CompileDictEachCmd(
}
/*
+ * Create temporary variable to capture return values from loop body when
+ * we're collecting results.
+ */
+
+ if (collect == TCL_EACH_COLLECT) {
+ collectVar = TclFindCompiledLocal(NULL, /*nameChars*/ 0, /*create*/ 1,
+ envPtr);
+ if (collectVar < 0) {
+ return TCL_ERROR;
+ }
+ }
+
+ /*
* Check we've got a pair of variables and that they are local variables.
* Then extract their indices in the LVT.
*/
@@ -903,23 +916,21 @@ CompileDictEachCmd(
}
/*
- * Create temporary variable to capture return values from loop body.
+ * Preparation complete; issue instructions. Note that this code issues
+ * fixed-sized jumps. That simplifies things a lot!
+ *
+ * First up, initialize the accumulator dictionary if needed.
*/
if (collect == TCL_EACH_COLLECT) {
- collectVar = TclFindCompiledLocal(NULL, /*nameChars*/ 0, /*create*/ 1,
- envPtr);
- if (collectVar < 0) {
- return TCL_ERROR;
- }
+ PushLiteral(envPtr, "", 0);
+ Emit14Inst( INST_STORE_SCALAR, collectVar, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
}
/*
- * Preparation complete; issue instructions. Note that this code issues
- * fixed-sized jumps. That simplifies things a lot!
- *
- * First up, get the dictionary and start the iteration. No catching of
- * errors at this point.
+ * Get the dictionary and start the iteration. No catching of errors at
+ * this point.
*/
CompileWord(envPtr, dictTokenPtr, interp, 3);
@@ -928,16 +939,6 @@ CompileDictEachCmd(
TclEmitInstInt4( INST_JUMP_TRUE4, 0, envPtr);
/*
- * Initialize the accumulator dictionary, if needed.
- */
-
- if (collect == TCL_EACH_COLLECT) {
- PushLiteral(envPtr, "", 0);
- Emit14Inst( INST_STORE_SCALAR, collectVar, envPtr);
- TclEmitOpcode( INST_POP, envPtr);
- }
-
- /*
* Now we catch errors from here on so that we can finalize the search
* started by Tcl_DictObjFirst above.
*/
@@ -973,7 +974,7 @@ CompileDictEachCmd(
Emit14Inst( INST_LOAD_SCALAR, keyVarIndex, envPtr);
TclEmitInstInt4(INST_OVER, 1, envPtr);
TclEmitInstInt4(INST_DICT_SET, 1, envPtr);
- TclEmitInt4( collectVar, envPtr);
+ TclEmitInt4( collectVar, envPtr);
TclEmitOpcode( INST_POP, envPtr);
}
TclEmitOpcode( INST_POP, envPtr);
@@ -1024,6 +1025,10 @@ CompileDictEachCmd(
TclEmitInstInt1( INST_UNSET_SCALAR, 0, envPtr);
TclEmitInt4( infoIndex, envPtr);
TclEmitOpcode( INST_END_CATCH, envPtr);
+ if (collect == TCL_EACH_COLLECT) {
+ TclEmitInstInt1(INST_UNSET_SCALAR, 0, envPtr);
+ TclEmitInt4( collectVar, envPtr);
+ }
TclEmitOpcode( INST_RETURN_STK, envPtr);
/*
@@ -1039,7 +1044,7 @@ CompileDictEachCmd(
TclEmitOpcode( INST_POP, envPtr);
TclEmitOpcode( INST_POP, envPtr);
TclEmitInstInt1( INST_UNSET_SCALAR, 0, envPtr);
- TclEmitInt4( infoIndex, envPtr);
+ TclEmitInt4( infoIndex, envPtr);
/*
* Final stage of the command (normal case) is that we push an empty
@@ -1052,6 +1057,8 @@ CompileDictEachCmd(
envPtr->codeStart + endTargetOffset);
if (collect == TCL_EACH_COLLECT) {
Emit14Inst( INST_LOAD_SCALAR, collectVar, envPtr);
+ TclEmitInstInt1(INST_UNSET_SCALAR, 0, envPtr);
+ TclEmitInt4( collectVar, envPtr);
} else {
PushLiteral(envPtr, "", 0);
}
@@ -2279,6 +2286,8 @@ CompileEachloopCmd(
envPtr->currStackDepth = savedStackDepth;
if (collect == TCL_EACH_COLLECT) {
Emit14Inst( INST_LOAD_SCALAR, collectVar, envPtr);
+ TclEmitInstInt1(INST_UNSET_SCALAR, 0, envPtr);
+ TclEmitInt4( collectVar, envPtr);
} else {
PushLiteral(envPtr, "", 0);
}
diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c
index dac4cbe..b64b776 100644
--- a/generic/tclDictObj.c
+++ b/generic/tclDictObj.c
@@ -2619,6 +2619,7 @@ DictMapNRCmd(
* internally so that updates, shimmering, etc are not a problem.
*/
+ Tcl_IncrRefCount(storagePtr->accumulatorObj);
Tcl_IncrRefCount(storagePtr->keyVarObj);
Tcl_IncrRefCount(storagePtr->valueVarObj);
Tcl_IncrRefCount(storagePtr->scriptObj);
@@ -2707,7 +2708,7 @@ DictMapLoopCallback(
Tcl_DictObjNext(&storagePtr->search, &keyObj, &valueObj, &done);
if (done) {
- Tcl_ResetResult(interp);
+ Tcl_SetObjResult(interp, storagePtr->accumulatorObj);
goto done;
}