diff options
| author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2019-05-10 16:35:53 (GMT) |
|---|---|---|
| committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2019-05-10 16:35:53 (GMT) |
| commit | 8ffde10c063dd49dd207d2c8cf8b09e4487edf18 (patch) | |
| tree | 103b667a0137ede85b2de0abd509bd7a12e87cd9 /generic/tclExecute.c | |
| parent | d50da922b1c1a3043e6ee9f24282a638ee143b48 (diff) | |
| parent | b1139d3d2099aad8ad1981deaa0f689e1b4c322a (diff) | |
| download | tcl-8ffde10c063dd49dd207d2c8cf8b09e4487edf18.zip tcl-8ffde10c063dd49dd207d2c8cf8b09e4487edf18.tar.gz tcl-8ffde10c063dd49dd207d2c8cf8b09e4487edf18.tar.bz2 | |
Merge 8.7
Diffstat (limited to 'generic/tclExecute.c')
| -rw-r--r-- | generic/tclExecute.c | 174 |
1 files changed, 102 insertions, 72 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 17ad0bb..ed4fdd7 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -499,11 +499,11 @@ VarHashCreateVar( */ #define GetNumberFromObj(interp, objPtr, ptrPtr, tPtr) \ - (((objPtr)->typePtr == &tclIntType) \ + ((TclHasIntRep((objPtr), &tclIntType)) \ ? (*(tPtr) = TCL_NUMBER_INT, \ *(ptrPtr) = (ClientData) \ (&((objPtr)->internalRep.wideValue)), TCL_OK) : \ - ((objPtr)->typePtr == &tclDoubleType) \ + TclHasIntRep((objPtr), &tclDoubleType) \ ? (((TclIsNaN((objPtr)->internalRep.doubleValue)) \ ? (*(tPtr) = TCL_NUMBER_NAN) \ : (*(tPtr) = TCL_NUMBER_DOUBLE)), \ @@ -4768,7 +4768,7 @@ TEBCresume( */ if ((TclListObjGetElements(interp, valuePtr, &objc, &objv) == TCL_OK) - && (value2Ptr->typePtr != &tclListType) + && !TclHasIntRep(value2Ptr, &tclListType) && (TclGetIntForIndexM(NULL, value2Ptr, objc-1, &index) == TCL_OK)) { TclDecrRefCount(value2Ptr); @@ -5215,7 +5215,7 @@ TEBCresume( objResultPtr = Tcl_NewStringObj((const char *) valuePtr->bytes+index, 1); } else { - char buf[4]; + char buf[4] = ""; int ch = Tcl_GetUniChar(valuePtr, index); /* @@ -5227,8 +5227,8 @@ TEBCresume( objResultPtr = Tcl_NewObj(); } else { length = Tcl_UniCharToUtf(ch, buf); - if (!length) { - length = Tcl_UniCharToUtf(-1, buf); + if ((ch >= 0xD800) && (length < 3)) { + length += Tcl_UniCharToUtf(-1, buf + length); } objResultPtr = Tcl_NewStringObj(buf, length); } @@ -5486,8 +5486,8 @@ TEBCresume( * both. */ - if ((valuePtr->typePtr == &tclStringType) - || (value2Ptr->typePtr == &tclStringType)) { + if (TclHasIntRep(valuePtr, &tclStringType) + || TclHasIntRep(value2Ptr, &tclStringType)) { Tcl_UniChar *ustring1, *ustring2; ustring1 = Tcl_GetUnicodeFromObj(valuePtr, &length); @@ -5631,7 +5631,7 @@ TEBCresume( /* [string is wideinteger] is WIDE_MIN to WIDE_MAX range */ Tcl_WideInt w; - if (Tcl_GetWideIntFromObj(NULL, OBJ_AT_TOS, &w) == TCL_OK) { + if (TclGetWideIntFromObj(NULL, OBJ_AT_TOS, &w) == TCL_OK) { type1 = TCL_NUMBER_INT; } } @@ -6293,7 +6293,7 @@ TEBCresume( case INST_TRY_CVT_TO_BOOLEAN: valuePtr = OBJ_AT_TOS; - if (valuePtr->typePtr == &tclBooleanType) { + if (TclHasIntRep(valuePtr, &tclBooleanType)) { objResultPtr = TCONST(1); } else { int result = (TclSetBooleanFromAny(NULL, valuePtr) == TCL_OK); @@ -6769,55 +6769,23 @@ TEBCresume( TRACE_APPEND(("OK\n")); NEXT_INST_F(1, 1, 0); - case INST_DICT_GET: case INST_DICT_EXISTS: { - register Tcl_Interp *interp2 = interp; register int found; opnd = TclGetUInt4AtPtr(pc+1); TRACE(("%u => ", opnd)); dictPtr = OBJ_AT_DEPTH(opnd); - if (*pc == INST_DICT_EXISTS) { - interp2 = NULL; - } if (opnd > 1) { - dictPtr = TclTraceDictPath(interp2, dictPtr, opnd-1, - &OBJ_AT_DEPTH(opnd-1), DICT_PATH_READ); - if (dictPtr == NULL) { - if (*pc == INST_DICT_EXISTS) { - found = 0; - goto afterDictExists; - } - TRACE_WITH_OBJ(( - "ERROR tracing dictionary path into \"%.30s\": ", - O2S(OBJ_AT_DEPTH(opnd))), - Tcl_GetObjResult(interp)); - goto gotError; + dictPtr = TclTraceDictPath(NULL, dictPtr, opnd-1, + &OBJ_AT_DEPTH(opnd-1), DICT_PATH_EXISTS); + if (dictPtr == NULL || dictPtr == DICT_PATH_NON_EXISTENT) { + found = 0; + goto afterDictExists; } } - if (Tcl_DictObjGet(interp2, dictPtr, OBJ_AT_TOS, + if (Tcl_DictObjGet(NULL, dictPtr, OBJ_AT_TOS, &objResultPtr) == TCL_OK) { - if (*pc == INST_DICT_EXISTS) { - found = (objResultPtr ? 1 : 0); - goto afterDictExists; - } - if (!objResultPtr) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "key \"%s\" not known in dictionary", - TclGetString(OBJ_AT_TOS))); - DECACHE_STACK_INFO(); - Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "DICT", - TclGetString(OBJ_AT_TOS), NULL); - CACHE_STACK_INFO(); - TRACE_ERROR(interp); - goto gotError; - } - TRACE_APPEND(("%.30s\n", O2S(objResultPtr))); - NEXT_INST_V(5, opnd+1, 1); - } else if (*pc != INST_DICT_EXISTS) { - TRACE_APPEND(("ERROR reading leaf dictionary key \"%.30s\": %s", - O2S(dictPtr), O2S(Tcl_GetObjResult(interp)))); - goto gotError; + found = (objResultPtr ? 1 : 0); } else { found = 0; } @@ -6833,6 +6801,68 @@ TEBCresume( JUMP_PEEPHOLE_V(found, 5, opnd+1); } + case INST_DICT_GET: + opnd = TclGetUInt4AtPtr(pc+1); + TRACE(("%u => ", opnd)); + dictPtr = OBJ_AT_DEPTH(opnd); + if (opnd > 1) { + dictPtr = TclTraceDictPath(interp, dictPtr, opnd-1, + &OBJ_AT_DEPTH(opnd-1), DICT_PATH_READ); + if (dictPtr == NULL) { + TRACE_WITH_OBJ(( + "ERROR tracing dictionary path into \"%.30s\": ", + O2S(OBJ_AT_DEPTH(opnd))), + Tcl_GetObjResult(interp)); + goto gotError; + } + } + if (Tcl_DictObjGet(interp, dictPtr, OBJ_AT_TOS, + &objResultPtr) != TCL_OK) { + TRACE_APPEND(("ERROR reading leaf dictionary key \"%.30s\": %s", + O2S(dictPtr), O2S(Tcl_GetObjResult(interp)))); + goto gotError; + } + if (!objResultPtr) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "key \"%s\" not known in dictionary", + TclGetString(OBJ_AT_TOS))); + DECACHE_STACK_INFO(); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "DICT", + TclGetString(OBJ_AT_TOS), NULL); + CACHE_STACK_INFO(); + TRACE_ERROR(interp); + goto gotError; + } + TRACE_APPEND(("%.30s\n", O2S(objResultPtr))); + NEXT_INST_V(5, opnd+1, 1); + case INST_DICT_GET_DEF: + opnd = TclGetUInt4AtPtr(pc+1); + TRACE(("%u => ", opnd)); + dictPtr = OBJ_AT_DEPTH(opnd+1); + if (opnd > 1) { + dictPtr = TclTraceDictPath(interp, dictPtr, opnd-1, + &OBJ_AT_DEPTH(opnd), DICT_PATH_EXISTS); + if (dictPtr == NULL) { + TRACE_WITH_OBJ(( + "ERROR tracing dictionary path into \"%.30s\": ", + O2S(OBJ_AT_DEPTH(opnd+1))), + Tcl_GetObjResult(interp)); + goto gotError; + } else if (dictPtr == DICT_PATH_NON_EXISTENT) { + goto dictGetDefUseDefault; + } + } + if (Tcl_DictObjGet(interp, dictPtr, OBJ_UNDER_TOS, + &objResultPtr) != TCL_OK) { + TRACE_APPEND(("ERROR reading leaf dictionary key \"%.30s\": %s", + O2S(dictPtr), O2S(Tcl_GetObjResult(interp)))); + goto gotError; + } else if (!objResultPtr) { + dictGetDefUseDefault: + objResultPtr = OBJ_AT_TOS; + } + TRACE_APPEND(("%.30s\n", O2S(objResultPtr))); + NEXT_INST_V(5, opnd+2, 1); case INST_DICT_SET: case INST_DICT_UNSET: @@ -7108,7 +7138,7 @@ TEBCresume( } varPtr = LOCAL(opnd); if (varPtr->value.objPtr) { - if (varPtr->value.objPtr->typePtr == &dictIteratorType) { + if (TclHasIntRep(varPtr->value.objPtr, &dictIteratorType)) { Tcl_Panic("mis-issued dictFirst!"); } TclDecrRefCount(varPtr->value.objPtr); @@ -7985,8 +8015,8 @@ ExecuteExtendedBinaryMathOp( if (((wQuotient < (Tcl_WideInt) 0) || ((wQuotient == (Tcl_WideInt) 0) - && ((w1 < (Tcl_WideInt)0 && w2 > (Tcl_WideInt)0) - || (w1 > (Tcl_WideInt)0 && w2 < (Tcl_WideInt)0)))) + && ((w1 < 0 && w2 > 0) + || (w1 > 0 && w2 < 0)))) && (wQuotient * w2 != w1)) { wQuotient -= (Tcl_WideInt) 1; } @@ -8020,7 +8050,7 @@ ExecuteExtendedBinaryMathOp( mp_init(&bigResult); mp_init(&bigRemainder); mp_div(&big1, &big2, &bigResult, &bigRemainder); - if (!mp_iszero(&bigRemainder) && (bigRemainder.sign != big2.sign)) { + if ((bigRemainder.used != 0) && (bigRemainder.sign != big2.sign)) { /* * Convert to Tcl's integer division rules. */ @@ -8042,11 +8072,11 @@ ExecuteExtendedBinaryMathOp( switch (type2) { case TCL_NUMBER_INT: - invalid = (*((const Tcl_WideInt *)ptr2) < (Tcl_WideInt)0); + invalid = (*((const Tcl_WideInt *)ptr2) < 0); break; case TCL_NUMBER_BIG: Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2); - invalid = mp_isneg(&big2); + invalid = big2.sign != MP_ZPOS; mp_clear(&big2); break; default: @@ -8063,7 +8093,7 @@ ExecuteExtendedBinaryMathOp( * Zero shifted any number of bits is still zero. */ - if ((type1==TCL_NUMBER_INT) && (*((const Tcl_WideInt *)ptr1) == (Tcl_WideInt)0)) { + if ((type1==TCL_NUMBER_INT) && (*((const Tcl_WideInt *)ptr1) == 0)) { return constants[0]; } @@ -8121,11 +8151,11 @@ ExecuteExtendedBinaryMathOp( switch (type1) { case TCL_NUMBER_INT: - zero = (*(const Tcl_WideInt *)ptr1 > (Tcl_WideInt)0); + zero = (*(const Tcl_WideInt *)ptr1 > 0); break; case TCL_NUMBER_BIG: Tcl_TakeBignumFromObj(NULL, valuePtr, &big1); - zero = (!mp_isneg(&big1)); + zero = (big1.sign == MP_ZPOS); mp_clear(&big1); break; default: @@ -8146,7 +8176,7 @@ ExecuteExtendedBinaryMathOp( if (type1 == TCL_NUMBER_INT) { w1 = *(const Tcl_WideInt *)ptr1; if ((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideInt)) { - if (w1 >= (Tcl_WideInt)0) { + if (w1 >= 0) { return constants[0]; } WIDE_RESULT(-1); @@ -8249,9 +8279,9 @@ ExecuteExtendedBinaryMathOp( oddExponent = (int) (w2 & (Tcl_WideInt)1); } else { Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2); - negativeExponent = mp_isneg(&big2); + negativeExponent = big2.sign != MP_ZPOS; mp_mod_2d(&big2, 1, &big2); - oddExponent = !mp_iszero(&big2); + oddExponent = big2.used != 0; mp_clear(&big2); } @@ -8348,7 +8378,7 @@ ExecuteExtendedBinaryMathOp( * Reduce small powers of 2 to shifts. */ - if ((Tcl_WideUInt)w2 < CHAR_BIT*sizeof(Tcl_WideInt) - 1){ + if ((Tcl_WideUInt) w2 < CHAR_BIT * sizeof(Tcl_WideInt) - 1) { WIDE_RESULT(signum * (((Tcl_WideInt) 1) << (int) w2)); } goto overflowExpon; @@ -8399,18 +8429,18 @@ ExecuteExtendedBinaryMathOp( } overflowExpon: - Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2); - if (big2.used > 1) { - mp_clear(&big2); + + if ((TclGetWideIntFromObj(NULL, value2Ptr, &w2) != TCL_OK) + || (value2Ptr->typePtr != &tclIntType) + || (Tcl_WideUInt)w2 >= (1<<28)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "exponent too large", -1)); return GENERAL_ARITHMETIC_ERROR; } Tcl_TakeBignumFromObj(NULL, valuePtr, &big1); mp_init(&bigResult); - mp_expt_d_ex(&big1, big2.dp[0], &bigResult, 1); + mp_expt_d_ex(&big1, w2, &bigResult, 1); mp_clear(&big1); - mp_clear(&big2); BIG_RESULT(&bigResult); } @@ -8568,7 +8598,7 @@ ExecuteExtendedBinaryMathOp( mp_mul(&big1, &big2, &bigResult); break; case INST_DIV: - if (mp_iszero(&big2)) { + if (big2.used == 0) { mp_clear(&big1); mp_clear(&big2); mp_clear(&bigResult); @@ -8577,7 +8607,7 @@ ExecuteExtendedBinaryMathOp( mp_init(&bigRemainder); mp_div(&big1, &big2, &bigResult, &bigRemainder); /* TODO: internals intrusion */ - if (!mp_iszero(&bigRemainder) + if ((bigRemainder.used != 0) && (bigRemainder.sign != big2.sign)) { /* * Convert to Tcl's integer division rules. @@ -8724,7 +8754,7 @@ TclCompareTwoNumbers( goto wideCompare; case TCL_NUMBER_BIG: Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2); - if (mp_isneg(&big2)) { + if (big2.sign != MP_ZPOS) { compare = MP_GT; } else { compare = MP_LT; @@ -8761,7 +8791,7 @@ TclCompareTwoNumbers( } Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2); if ((d1 < (double)WIDE_MAX) && (d1 > (double)WIDE_MIN)) { - if (mp_isneg(&big2)) { + if (big2.sign != MP_ZPOS) { compare = MP_GT; } else { compare = MP_LT; @@ -9622,7 +9652,7 @@ EvalStatsCmd( for (i = 0; i < globalTablePtr->numBuckets; i++) { for (entryPtr = globalTablePtr->buckets[i]; entryPtr != NULL; entryPtr = entryPtr->nextPtr) { - if (entryPtr->objPtr->typePtr == &tclByteCodeType) { + if (TclHasIntRep(entryPtr->objPtr, &tclByteCodeType)) { numByteCodeLits++; } (void) TclGetStringFromObj(entryPtr->objPtr, &length); |
