diff options
author | hobbs <hobbs> | 2001-09-19 18:18:52 (GMT) |
---|---|---|
committer | hobbs <hobbs> | 2001-09-19 18:18:52 (GMT) |
commit | 0a49e15c0a1c2f09391b38a86273bfa0fcc05831 (patch) | |
tree | 7909fd1e1b3c7e9e59b4662874455f9345ea251e /generic | |
parent | a16345e2070ed06336f7beb52a79dbd5eb07f102 (diff) | |
download | tcl-0a49e15c0a1c2f09391b38a86273bfa0fcc05831.zip tcl-0a49e15c0a1c2f09391b38a86273bfa0fcc05831.tar.gz tcl-0a49e15c0a1c2f09391b38a86273bfa0fcc05831.tar.bz2 |
* generic/tclExecute.c (TclExecuteByteCode): fixed invalid usage
of valuePtr in TRACE_WITH_OBJ in INST_EVAL_STK case. [Bug #462594]
Changed INST_STR_CMP instruction to promote to Unicode strings
only when one of the strings is already of Unicode type.
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclExecute.c | 69 |
1 files changed, 39 insertions, 30 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 226386b..b189869 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclExecute.c,v 1.32 2001/09/19 11:59:58 msofer Exp $ + * RCS: @(#) $Id: tclExecute.c,v 1.33 2001/09/19 18:18:52 hobbs Exp $ */ #include "tclInt.h" @@ -1044,14 +1044,13 @@ TclExecuteByteCode(interp, codePtr) newPcOffset = rangePtr->continueOffset; } result = TCL_OK; - TRACE_WITH_OBJ(("\"%.30s\" => %s, range at %d, new pc %d ", + TRACE(("\"%.30s\" => %s, range at %d, new pc %d ", O2S(objPtr), StringForResultCode(result), - rangePtr->codeOffset, newPcOffset), valuePtr); + rangePtr->codeOffset, newPcOffset)); break; case CATCH_EXCEPTION_RANGE: - TRACE_WITH_OBJ(("\"%.30s\" => %s ", - O2S(objPtr), StringForResultCode(result)), - valuePtr); + TRACE(("\"%.30s\" => %s ", + O2S(objPtr), StringForResultCode(result))); Tcl_DecrRefCount(objPtr); goto processCatch; /* it will use rangePtr */ default: @@ -2139,8 +2138,19 @@ TclExecuteByteCode(interp, codePtr) s2 = (char *) Tcl_GetByteArrayFromObj(value2Ptr, &s2len); iResult = memcmp(s1, s2, (size_t) ((s1len < s2len) ? s1len : s2len)); + } else if ((valuePtr->typePtr == &tclStringType) || + (value2Ptr->typePtr == &tclStringType)) { + /* + * The alternative is to break this into more code + * that does type sensitive comparison, as done in + * Tcl_StringObjCmd. + */ + Tcl_UniChar *uni1, *uni2; + uni1 = Tcl_GetUnicodeFromObj(valuePtr, &s1len); + uni2 = Tcl_GetUnicodeFromObj(value2Ptr, &s2len); + iResult = Tcl_UniCharNcmp(uni1, uni2, + (unsigned) ((s1len < s2len) ? s1len : s2len)); } else { -#if 0 /* * This solution is less mem intensive, but it is * computationally expensive as the string grows. The @@ -2153,18 +2163,6 @@ TclExecuteByteCode(interp, codePtr) s2 = Tcl_GetStringFromObj(value2Ptr, &s2len); iResult = Tcl_UtfNcmp(s1, s2, (size_t) ((s1len < s2len) ? s1len : s2len)); -#else - /* - * The alternative is to break this into more code - * that does type sensitive comparison, as done in - * Tcl_StringObjCmd. - */ - Tcl_UniChar *uni1, *uni2; - uni1 = Tcl_GetUnicodeFromObj(valuePtr, &s1len); - uni2 = Tcl_GetUnicodeFromObj(value2Ptr, &s2len); - iResult = Tcl_UniCharNcmp(uni1, uni2, - (unsigned) ((s1len < s2len) ? s1len : s2len)); -#endif } /* @@ -2273,31 +2271,42 @@ TclExecuteByteCode(interp, codePtr) { int nocase, match; + nocase = TclGetInt1AtPtr(pc+1); valuePtr = POP_OBJECT(); /* String */ value2Ptr = POP_OBJECT(); /* Pattern */ - objPtr = POP_OBJECT(); /* Case Sensitivity */ - Tcl_GetBooleanFromObj(interp, objPtr, &nocase); - match = Tcl_UniCharCaseMatch(Tcl_GetUnicode(valuePtr), - Tcl_GetUnicode(value2Ptr), nocase); + /* + * Check that at least one of the objects + * is Unicode before promoting both. + */ + if ((valuePtr->typePtr == &tclStringType) + || (value2Ptr->typePtr == &tclStringType)) { + match = Tcl_UniCharCaseMatch(Tcl_GetUnicode(valuePtr), + Tcl_GetUnicode(value2Ptr), nocase); + } else { + match = Tcl_StringCaseMatch(Tcl_GetString(valuePtr), + Tcl_GetString(value2Ptr), nocase); + } /* - * Reuse the casePtr object already on stack if possible. + * Reuse value2Ptr object already on stack if possible. */ TRACE(("%.20s %.20s => %d\n", O2S(valuePtr), O2S(value2Ptr), match)); - if (Tcl_IsShared(objPtr)) { + TclDecrRefCount(valuePtr); + if (Tcl_IsShared(value2Ptr)) { PUSH_OBJECT(Tcl_NewIntObj(match)); - TclDecrRefCount(objPtr); + TclDecrRefCount(value2Ptr); } else { /* reuse the valuePtr object */ - Tcl_SetIntObj(objPtr, match); + Tcl_SetIntObj(value2Ptr, match); ++stackTop; /* valuePtr now on stk top has right r.c. */ } - TclDecrRefCount(valuePtr); - TclDecrRefCount(value2Ptr); } - ADJUST_PC(1); + /* + * Adjustment is 2 due to the nocase byte + */ + ADJUST_PC(2); case INST_EQ: case INST_NEQ: |