summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2022-07-27 15:56:13 (GMT)
committersebres <sebres@users.sourceforge.net>2022-07-27 15:56:13 (GMT)
commita66ed8e23823b7ddefdb8867d3f4d5dc5dfd44d6 (patch)
treee407ca30fc502db26f62d88a08df22b71f4c7501 /generic
parentcf9f33de53a5c07f902ad314bf150e3385b1184f (diff)
downloadtcl-a66ed8e23823b7ddefdb8867d3f4d5dc5dfd44d6.zip
tcl-a66ed8e23823b7ddefdb8867d3f4d5dc5dfd44d6.tar.gz
tcl-a66ed8e23823b7ddefdb8867d3f4d5dc5dfd44d6.tar.bz2
fixes [4eb3a155ac] and similar segfaults: reset corresponding bodyPtr->procPtr if procPtr gets released in TclProcCleanupProc, also recompile body if its procPtr is not the same as supplied.
Diffstat (limited to 'generic')
-rw-r--r--generic/tclProc.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/generic/tclProc.c b/generic/tclProc.c
index 59153b8..7550bfa 100644
--- a/generic/tclProc.c
+++ b/generic/tclProc.c
@@ -1576,13 +1576,16 @@ TclPushProcCallFrame(
* is up-to-date), the namespace must match (so variable handling
* is right) and the resolverEpoch must match (so that new shadowed
* commands and/or resolver changes are considered).
+ * Ensure the ByteCode's procPtr is the same (or it's precompiled).
*/
codePtr = procPtr->bodyPtr->internalRep.twoPtrValue.ptr1;
if (((Interp *) *codePtr->interpHandle != iPtr)
|| (codePtr->compileEpoch != iPtr->compileEpoch)
|| (codePtr->nsPtr != nsPtr)
- || (codePtr->nsEpoch != nsPtr->resolverEpoch)) {
+ || (codePtr->nsEpoch != nsPtr->resolverEpoch)
+ || ((codePtr->procPtr != procPtr) && procPtr->bodyPtr->bytes)
+ ) {
goto doCompilation;
}
} else {
@@ -1920,6 +1923,7 @@ TclProcCompileProc(
* procPtr->numCompiledLocals if new local variables are found while
* compiling.
*
+ * Ensure the ByteCode's procPtr is the same (or it is pure precompiled).
* Precompiled procedure bodies, however, are immutable and therefore they
* are not recompiled, even if things have changed.
*/
@@ -1928,7 +1932,9 @@ TclProcCompileProc(
if (((Interp *) *codePtr->interpHandle == iPtr)
&& (codePtr->compileEpoch == iPtr->compileEpoch)
&& (codePtr->nsPtr == nsPtr)
- && (codePtr->nsEpoch == nsPtr->resolverEpoch)) {
+ && (codePtr->nsEpoch == nsPtr->resolverEpoch)
+ && ((codePtr->procPtr == procPtr) || !bodyPtr->bytes)
+ ) {
return TCL_OK;
}
@@ -2139,6 +2145,13 @@ TclProcCleanupProc(
Interp *iPtr = procPtr->iPtr;
if (bodyPtr != NULL) {
+ /* procPtr is stored in body's ByteCode, so ensure to reset it. */
+ if (bodyPtr->typePtr == &tclByteCodeType) {
+ ByteCode *codePtr = bodyPtr->internalRep.twoPtrValue.ptr1;
+ if (codePtr->procPtr == procPtr) {
+ codePtr->procPtr = NULL;
+ }
+ }
Tcl_DecrRefCount(bodyPtr);
}
for (localPtr = procPtr->firstLocalPtr; localPtr != NULL; ) {