summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2005-08-30 19:20:41 (GMT)
committerdgp <dgp@users.sourceforge.net>2005-08-30 19:20:41 (GMT)
commit40d6b9153fa94807b693bc543ad5bb88022f7aef (patch)
treefa879e82865b6e6bd560513a6cf7f43ecbf0acd7
parentfa017c619ce3a26b2765bca23aa499ca4fd0053c (diff)
downloadtcl-40d6b9153fa94807b693bc543ad5bb88022f7aef.zip
tcl-40d6b9153fa94807b693bc543ad5bb88022f7aef.tar.gz
tcl-40d6b9153fa94807b693bc543ad5bb88022f7aef.tar.bz2
[kennykb-numerics-branch]
* generic/tclObj.c: Extended bignum support to include bignums so large they will not pack into a Tcl_Obj. When they outgrow Tcl's string rep length limits, a panic will result.
-rw-r--r--ChangeLog4
-rw-r--r--generic/tclObj.c29
2 files changed, 22 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index f3e71f3..d8a7462 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,10 @@
[kennykb-numerics-branch]
+ * generic/tclObj.c: Extended bignum support to include bignums
+ so large they will not pack into a Tcl_Obj. When they outgrow Tcl's
+ string rep length limits, a panic will result.
+
* generic/tclTomMath.h: Added mp_sqrt to routines from
* unix/Makefile.in: libtommath used by Tcl.
* win/Makefile.in:
diff --git a/generic/tclObj.c b/generic/tclObj.c
index 4895bd0..f7fbffd 100644
--- a/generic/tclObj.c
+++ b/generic/tclObj.c
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclObj.c,v 1.72.2.31 2005/08/25 15:46:31 dgp Exp $
+ * RCS: @(#) $Id: tclObj.c,v 1.72.2.32 2005/08/30 19:20:42 dgp Exp $
*/
#include "tclInt.h"
@@ -145,22 +145,32 @@ Tcl_ThreadDataKey pendingObjDataKey;
*/
#define PACK_BIGNUM(bignum, objPtr) \
- do { \
+ if ((bignum).used > 0x7fff) { \
+ mp_int *temp = (void *) ckalloc((unsigned) sizeof(mp_int)); \
+ *temp = bignum; \
+ (objPtr)->internalRep.bignumValue.digits = (void*) temp; \
+ (objPtr)->internalRep.bignumValue.misc = -1; \
+ } else { \
+ if ((bignum).alloc > 0x7fff) { \
+ mp_shrink(&(bignum)); \
+ } \
(objPtr)->internalRep.bignumValue.digits = (void*) (bignum).dp; \
(objPtr)->internalRep.bignumValue.misc = ( \
((bignum).sign << 30) \
| ((bignum).alloc << 15) \
| ((bignum).used)); \
- } while (0)
+ }
#define UNPACK_BIGNUM(objPtr, bignum) \
- do { \
+ if ((objPtr)->internalRep.bignumValue.misc == -1) { \
+ (bignum) = *((mp_int *) ((objPtr)->internalRep.bignumValue.digits)); \
+ } else { \
(bignum).dp = (mp_digit*) (objPtr)->internalRep.bignumValue.digits; \
(bignum).sign = (objPtr)->internalRep.bignumValue.misc >> 30; \
(bignum).alloc = \
((objPtr)->internalRep.bignumValue.misc >> 15) & 0x7fff; \
(bignum).used = (objPtr)->internalRep.bignumValue.misc & 0x7fff; \
- } while (0)
+ }
/*
* Prototypes for procedures defined later in this file:
@@ -2520,6 +2530,9 @@ FreeBignum(Tcl_Obj *objPtr)
UNPACK_BIGNUM(objPtr, toFree);
mp_clear(&toFree);
+ if (objPtr->internalRep.bignumValue.misc < 0) {
+ ckfree((char *)objPtr->internalRep.bignumValue.digits);
+ }
}
/*
@@ -2836,12 +2849,6 @@ TclSetBignumIntRep(objPtr, bignumValue)
Tcl_Obj *objPtr;
mp_int *bignumValue;
{
- if (bignumValue->used > 0x7fff) {
- Tcl_Panic("TclSetBignumIntRep: too large for packed bignum");
- }
- if (bignumValue->alloc > 0x7fff) {
- mp_shrink(bignumValue);
- }
objPtr->typePtr = &tclBignumType;
PACK_BIGNUM(*bignumValue, objPtr);