diff --git a/changes.md b/changes.md index e1c94fc40de..806afa72a5d 100644 --- a/changes.md +++ b/changes.md @@ -4,6 +4,20 @@ changes to the Tcl source code at > [Tcl Source Code](https://core.tcl-lang.org/tcl/timeline) +Release Tcl 9.0.2 arises from the check-in with tag `core-9-0-2`. + +Tcl patch releases have the primary purpose of delivering bug fixes +to the userbase. + +# Bug fixes + - Better error-message than "interpreter uses an incompatible stubs mechanism"](https://core.tcl-lang.org/tcl/tktview/fc3509) + +# Incompatibilities + - No known incompatibilities with the Tcl 9.0.0 public interface. + +# Updated bundled packages, libraries, standards, data + - sqlite3 3.48.0 + Release Tcl 9.0.1 arises from the check-in with tag `core-9-0-1`. Tcl patch releases have the primary purpose of delivering bug fixes diff --git a/doc/InitStubs.3 b/doc/InitStubs.3 index 80a21de8ab3..ba18ed4c80f 100644 --- a/doc/InitStubs.3 +++ b/doc/InitStubs.3 @@ -80,7 +80,7 @@ and a Boolean flag indicating whether the extension requires an exact version match or not. If \fIexact\fR is 0, then the extension is indicating that newer versions of Tcl are acceptable as long as they have the same major version number as \fIversion\fR; -non-zero means that only the specified \fIversion\fR is acceptable. +1 means that only the specified \fIversion\fR is acceptable. \fBTcl_InitStubs\fR returns a string containing the actual version of Tcl satisfying the request, or NULL if the Tcl version is not acceptable, does not support stubs, or any other error condition occurred. diff --git a/generic/tclLoad.c b/generic/tclLoad.c index 95f9c223495..96691cc6a43 100644 --- a/generic/tclLoad.c +++ b/generic/tclLoad.c @@ -482,11 +482,10 @@ Tcl_LoadObjCmd( Interp *iPtr = (Interp *) target; if (iPtr->legacyResult && *(iPtr->legacyResult) && !iPtr->legacyFreeProc) { /* - * A call to Tcl_InitStubs() determined the caller extension and - * this interp are incompatible in their stubs mechanisms, and - * recorded the error in the oldest legacy place we have to do so. + * A call to Tcl_InitStubs() determined the caller extension + * Stubs were introduced in Tcl 8.1, so there's only one possible reason. */ - Tcl_SetObjResult(target, Tcl_NewStringObj(iPtr->legacyResult, -1)); + Tcl_SetObjResult(target, Tcl_NewStringObj("this extension is compiled for Tcl 8.x", -1)); iPtr->legacyResult = NULL; iPtr->legacyFreeProc = (void (*) (void))-1; } diff --git a/generic/tclStubLib.c b/generic/tclStubLib.c index 55001cf8a38..1da7e0848f1 100644 --- a/generic/tclStubLib.c +++ b/generic/tclStubLib.c @@ -60,19 +60,41 @@ Tcl_InitStubs( const char *actualVersion = NULL; void *pkgData = NULL; const TclStubs *stubsPtr = iPtr->stubTable; - const char *tclName = (((exact&0xFF00) >= 0x900) ? "tcl" : "Tcl"); + const char *tclName = "tcl"; -#undef TCL_STUB_MAGIC /* We need the TCL_STUB_MAGIC from Tcl 8.x here */ -#define TCL_STUB_MAGIC ((int) 0xFCA3BACF) + if ((exact&0xFF00) < 0x900) { + magic = (int)0xFCA3BACF; /* TCL_STUB_MAGIC from Tcl 8.x */ + tclName = "Tcl"; + } /* * We can't optimize this check by caching tclStubsPtr because that * prevents apps from being able to load/unload Tcl dynamically multiple * times. [Bug 615304] */ - if (!stubsPtr || (stubsPtr->magic != (((exact&0xFF00) >= 0x900) ? magic : TCL_STUB_MAGIC))) { - iPtr->legacyResult = "interpreter uses an incompatible stubs mechanism"; - iPtr->legacyFreeProc = 0; /* TCL_STATIC */ + if (!stubsPtr || (stubsPtr->magic != magic)) { + exact &= 0xFFFF00; /* Filter out minor/major Tcl version */ + if (!exact) { + exact = 0x060800; + } + if (stubsPtr && (stubsPtr->magic == TCL_STUB_MAGIC) + && ((exact|0x010000) == 0x070800)) { + /* We are running in Tcl 9.x, but extension is compiled with 8.6 or 8.7 */ + stubsPtr->tcl_SetObjResult(interp, stubsPtr->tcl_ObjPrintf( + "this extension is compiled for Tcl %d.%d", + (exact & 0x0FF00)>>8, (exact & 0x0FF0000)>>16)); + } else if (stubsPtr && (stubsPtr->magic == (int)0xFCA3BACF) + && ((exact & 0x0FF00) >= 0x0900)) { + /* We are running in Tcl 8.x, but extension is compiled with 9.0+ */ + char major[4], minor[4]; + snprintf(major, sizeof(major), "%d", (exact & 0xFF00)>>8); + snprintf(minor, sizeof(minor), "%d", (exact & 0xFF0000)>>16); + stubsPtr->tcl_AppendResult(interp, + "this extension is compiled for Tcl ", major, ".", minor, (char *)NULL); + } else { + iPtr->legacyResult = "interpreter uses an incompatible stubs mechanism"; + iPtr->legacyFreeProc = 0; /* TCL_STATIC */ + } return NULL; }