@@ -36,16 +36,17 @@ HasStubSupport( Tcl_Interp *interp, int magic) { Interp *iPtr = (Interp *) interp; - if (iPtr->stubTable && iPtr->stubTable->magic == magic - && iPtr->stubTable->magic == TCL_STUB_MAGIC) { + + if (iPtr->stubTable && iPtr->stubTable->magic == magic) { return iPtr->stubTable; } - iPtr->result = (char *) "interpreter uses an incompatible stubs mechanism"; - iPtr->freeProc = TCL_STATIC; + iPtr->legacyResult + = "interpreter uses an incompatible stubs mechanism"; + iPtr->legacyFreeProc = 0; /* TCL_STATIC */ return NULL; } /* * Use our own isdigit to avoid linking to libc on windows @@ -80,86 +81,55 @@ const char *version, int exact, const char *tclversion, int magic) { - const char *p; - char *q; - char major[TCL_INTEGER_SPACE]; const char *actualVersion = NULL; - ClientData pkgData = NULL; - Interp *iPtr = (Interp *) interp; + const TclStubs *stubsPtr; /* * 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] */ - tclStubsPtr = HasStubSupport(interp, magic); - if (!tclStubsPtr) { - return NULL; - } - - /* - * Check that the [load]ing interp and [load]ed extension were compiled - * against headers from the same major version of Tcl. If not, they - * will not agree on the layout of the stubs and will crash. Report - * the error instead of crashing. - */ - - p = tclversion; - q = major; - while (isDigit(*p)) { - *q++ = *p++; - if (q-major > TCL_INTEGER_SPACE) { - iPtr->result = (char *) "major version overflow"; - iPtr->freeProc = TCL_STATIC; - return NULL; - } - } - *q = '\0'; - - if (NULL == Tcl_PkgRequireEx(interp, "Tcl", major, 0, NULL)) { - return NULL; - } - - /* - * Check satisfaction of the requirement requested by the caller. - */ - - actualVersion = Tcl_PkgRequireEx(interp, "Tcl", version, 0, &pkgData); + stubsPtr = HasStubSupport(interp, magic); + if (!stubsPtr) { + return NULL; + } + + actualVersion = stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 0, NULL); if (actualVersion == NULL) { return NULL; } if (exact) { + const char *p = version; int count = 0; - p = version; while (*p) { count += !isDigit(*p++); } if (count == 1) { - q = actualVersion; + const char *q = actualVersion; p = version; while (*p && (*p == *q)) { p++; q++; } if (*p || isDigit(*q)) { /* Construct error message */ - Tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL); + stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL); return NULL; } } else { - actualVersion = Tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL); + actualVersion = stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL); if (actualVersion == NULL) { return NULL; } } } - tclStubsPtr = (TclStubs *) pkgData; + tclStubsPtr = stubsPtr; if (tclStubsPtr->hooks) { tclPlatStubsPtr = tclStubsPtr->hooks->tclPlatStubs; tclIntStubsPtr = tclStubsPtr->hooks->tclIntStubs; tclIntPlatStubsPtr = tclStubsPtr->hooks->tclIntPlatStubs;