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/tclObj.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/tclObj.c')
| -rw-r--r-- | generic/tclObj.c | 138 |
1 files changed, 58 insertions, 80 deletions
diff --git a/generic/tclObj.c b/generic/tclObj.c index 3385c0d..d329aba 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -191,17 +191,6 @@ static Tcl_ThreadDataKey pendingObjDataKey; | ((bignum).alloc << 15) | ((bignum).used)); \ } -#define UNPACK_BIGNUM(objPtr, bignum) \ - if ((objPtr)->internalRep.twoPtrValue.ptr2 == INT2PTR(-1)) { \ - (bignum) = *((mp_int *) ((objPtr)->internalRep.twoPtrValue.ptr1)); \ - } else { \ - (bignum).dp = (objPtr)->internalRep.twoPtrValue.ptr1; \ - (bignum).sign = PTR2INT((objPtr)->internalRep.twoPtrValue.ptr2) >> 30; \ - (bignum).alloc = \ - (PTR2INT((objPtr)->internalRep.twoPtrValue.ptr2) >> 15) & 0x7fff; \ - (bignum).used = PTR2INT((objPtr)->internalRep.twoPtrValue.ptr2) & 0x7fff; \ - } - /* * Prototypes for functions defined later in this file: */ @@ -2517,7 +2506,7 @@ Tcl_GetDoubleFromObj( if (objPtr->typePtr == &tclBignumType) { mp_int big; - UNPACK_BIGNUM(objPtr, big); + TclUnpackBignum(objPtr, big); *dblPtr = TclBignumToDouble(&big); return TCL_OK; } @@ -3030,27 +3019,23 @@ Tcl_GetLongFromObj( */ mp_int big; + unsigned long scratch, value = 0, numBytes = sizeof(unsigned long); + unsigned char *bytes = (unsigned char *) &scratch; - UNPACK_BIGNUM(objPtr, big); - if ((size_t) big.used <= (CHAR_BIT * sizeof(unsigned long) + DIGIT_BIT - 1) - / DIGIT_BIT) { - unsigned long scratch, value = 0, numBytes = sizeof(unsigned long); - unsigned char *bytes = (unsigned char *) &scratch; - - if (mp_to_unsigned_bin_n(&big, bytes, &numBytes) == MP_OKAY) { - while (numBytes-- > 0) { + TclUnpackBignum(objPtr, big); + if (mp_to_unsigned_bin_n(&big, bytes, &numBytes) == MP_OKAY) { + while (numBytes-- > 0) { value = (value << CHAR_BIT) | *bytes++; + } + if (big.sign) { + if (value <= 1 + (unsigned long)LONG_MAX) { + *longPtr = - (long) value; + return TCL_OK; } - if (big.sign) { - if (value <= 1 + (unsigned long)LONG_MAX) { - *longPtr = - (long) value; - return TCL_OK; - } - } else { - if (value <= (unsigned long)ULONG_MAX) { - *longPtr = (long) value; - return TCL_OK; - } + } else { + if (value <= (unsigned long)ULONG_MAX) { + *longPtr = (long) value; + return TCL_OK; } } } @@ -3272,29 +3257,25 @@ Tcl_GetWideIntFromObj( */ mp_int big; + Tcl_WideUInt value = 0; + unsigned long numBytes = sizeof(Tcl_WideInt); + Tcl_WideInt scratch; + unsigned char *bytes = (unsigned char *) &scratch; - UNPACK_BIGNUM(objPtr, big); - if ((size_t) big.used <= (CHAR_BIT * sizeof(Tcl_WideInt) - + DIGIT_BIT - 1) / DIGIT_BIT) { - Tcl_WideUInt value = 0; - unsigned long numBytes = sizeof(Tcl_WideInt); - Tcl_WideInt scratch; - unsigned char *bytes = (unsigned char *) &scratch; - - if (mp_to_unsigned_bin_n(&big, bytes, &numBytes) == MP_OKAY) { - while (numBytes-- > 0) { - value = (value << CHAR_BIT) | *bytes++; + TclUnpackBignum(objPtr, big); + if (mp_to_unsigned_bin_n(&big, bytes, &numBytes) == MP_OKAY) { + while (numBytes-- > 0) { + value = (value << CHAR_BIT) | *bytes++; + } + if (big.sign) { + if (value <= 1 + ~(Tcl_WideUInt)WIDE_MIN) { + *wideIntPtr = - (Tcl_WideInt) value; + return TCL_OK; } - if (big.sign) { - if (value <= 1 + ~(Tcl_WideUInt)WIDE_MIN) { - *wideIntPtr = - (Tcl_WideInt) value; - return TCL_OK; - } - } else { - if (value <= (Tcl_WideUInt)WIDE_MAX) { - *wideIntPtr = (Tcl_WideInt) value; - return TCL_OK; - } + } else { + if (value <= (Tcl_WideUInt)WIDE_MAX) { + *wideIntPtr = (Tcl_WideInt) value; + return TCL_OK; } } } @@ -3395,7 +3376,7 @@ FreeBignum( { mp_int toFree; /* Bignum to free */ - UNPACK_BIGNUM(objPtr, toFree); + TclUnpackBignum(objPtr, toFree); mp_clear(&toFree); if (PTR2INT(objPtr->internalRep.twoPtrValue.ptr2) < 0) { ckfree(objPtr->internalRep.twoPtrValue.ptr1); @@ -3428,7 +3409,7 @@ DupBignum( mp_int bignumCopy; copyPtr->typePtr = &tclBignumType; - UNPACK_BIGNUM(srcPtr, bignumVal); + TclUnpackBignum(srcPtr, bignumVal); if (mp_init_copy(&bignumCopy, &bignumVal) != MP_OKAY) { Tcl_Panic("initialization failure in DupBignum"); } @@ -3463,7 +3444,7 @@ UpdateStringOfBignum( int size; char *stringVal; - UNPACK_BIGNUM(objPtr, bignumVal); + TclUnpackBignum(objPtr, bignumVal); if (MP_OKAY != mp_radix_size(&bignumVal, 10, &size)) { Tcl_Panic("radix size failure in UpdateStringOfBignum"); } @@ -3602,10 +3583,10 @@ GetBignumFromObj( if (copy || Tcl_IsShared(objPtr)) { mp_int temp; - UNPACK_BIGNUM(objPtr, temp); + TclUnpackBignum(objPtr, temp); mp_init_copy(bignumValue, &temp); } else { - UNPACK_BIGNUM(objPtr, *bignumValue); + TclUnpackBignum(objPtr, *bignumValue); /* Optimized TclFreeIntRep */ objPtr->internalRep.twoPtrValue.ptr1 = NULL; objPtr->internalRep.twoPtrValue.ptr2 = NULL; @@ -3731,33 +3712,30 @@ Tcl_SetBignumObj( Tcl_Obj *objPtr, /* Object to set */ mp_int *bignumValue) /* Value to store */ { + Tcl_WideUInt value = 0; + unsigned long numBytes = sizeof(Tcl_WideUInt); + Tcl_WideUInt scratch; + unsigned char *bytes = (unsigned char *) &scratch; + if (Tcl_IsShared(objPtr)) { Tcl_Panic("%s called with shared object", "Tcl_SetBignumObj"); } - if ((size_t) bignumValue->used - <= (CHAR_BIT * sizeof(Tcl_WideUInt) + DIGIT_BIT - 1) / DIGIT_BIT) { - Tcl_WideUInt value = 0; - unsigned long numBytes = sizeof(Tcl_WideUInt); - Tcl_WideUInt scratch; - unsigned char *bytes = (unsigned char *) &scratch; - - if (mp_to_unsigned_bin_n(bignumValue, bytes, &numBytes) != MP_OKAY) { - goto tooLargeForWide; - } - while (numBytes-- > 0) { - value = (value << CHAR_BIT) | *bytes++; - } - if (value > ((Tcl_WideUInt)WIDE_MAX + bignumValue->sign)) { - goto tooLargeForWide; - } - if (bignumValue->sign) { - TclSetIntObj(objPtr, -(Tcl_WideInt)value); - } else { - TclSetIntObj(objPtr, (Tcl_WideInt)value); - } - mp_clear(bignumValue); - return; + if (mp_to_unsigned_bin_n(bignumValue, bytes, &numBytes) != MP_OKAY) { + goto tooLargeForWide; + } + while (numBytes-- > 0) { + value = (value << CHAR_BIT) | *bytes++; + } + if (value > ((Tcl_WideUInt)WIDE_MAX + bignumValue->sign)) { + goto tooLargeForWide; + } + if (bignumValue->sign) { + TclSetIntObj(objPtr, -(Tcl_WideInt)value); + } else { + TclSetIntObj(objPtr, (Tcl_WideInt)value); } + mp_clear(bignumValue); + return; tooLargeForWide: TclInvalidateStringRep(objPtr); TclFreeIntRep(objPtr); @@ -3849,7 +3827,7 @@ TclGetNumberFromObj( mp_int *bigPtr = Tcl_GetThreadData(&bignumKey, (int) sizeof(mp_int)); - UNPACK_BIGNUM(objPtr, *bigPtr); + TclUnpackBignum(objPtr, *bigPtr); *typePtr = TCL_NUMBER_BIG; *clientDataPtr = bigPtr; return TCL_OK; |
