summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2022-11-11 21:09:21 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2022-11-11 21:09:21 (GMT)
commit874327229c5e64a52e1fc3b4da6a31936ec07ed2 (patch)
tree62f3596453a433b26e323d6f37de74cba263e81e /generic
parentb2b045293797df7ff4e350e74cfdab191eadc31f (diff)
downloadtcl-874327229c5e64a52e1fc3b4da6a31936ec07ed2.zip
tcl-874327229c5e64a52e1fc3b4da6a31936ec07ed2.tar.gz
tcl-874327229c5e64a52e1fc3b4da6a31936ec07ed2.tar.bz2
Add (internal) TclNewUIntObj(), and use it to fix TCL_LINK_WIDE_UINT for big (>= 2^63) integers. With testcase
Diffstat (limited to 'generic')
-rw-r--r--generic/tclInt.h35
-rw-r--r--generic/tclLink.c11
-rw-r--r--generic/tclOOBasic.c2
3 files changed, 43 insertions, 5 deletions
diff --git a/generic/tclInt.h b/generic/tclInt.h
index ec82abd..036c653 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -4852,6 +4852,26 @@ MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_SafeInit;
TCL_DTRACE_OBJ_CREATE(objPtr); \
} while (0)
+#define TclNewUIntObj(objPtr, uw) \
+ do { \
+ TclIncrObjsAllocated(); \
+ TclAllocObjStorage(objPtr); \
+ (objPtr)->refCount = 0; \
+ (objPtr)->bytes = NULL; \
+ Tcl_WideUInt uw_ = (uw); \
+ if (uw_ > WIDE_MAX) { \
+ mp_int bignumValue_; \
+ if (mp_init_u64(&bignumValue_, uw_) != MP_OKAY) { \
+ Tcl_Panic("%s: memory overflow", "TclNewUIntObj"); \
+ } \
+ TclSetBignumInternalRep((objPtr), &bignumValue_); \
+ } else { \
+ (objPtr)->internalRep.wideValue = (Tcl_WideInt)(uw_); \
+ (objPtr)->typePtr = &tclIntType; \
+ } \
+ TCL_DTRACE_OBJ_CREATE(objPtr); \
+ } while (0)
+
#define TclNewIndexObj(objPtr, w) \
TclNewIntObj(objPtr, w)
@@ -4880,6 +4900,21 @@ MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_SafeInit;
#define TclNewIntObj(objPtr, w) \
(objPtr) = Tcl_NewWideIntObj(w)
+#define TclNewUIntObj(objPtr, uw) \
+ do { \
+ Tcl_WideUInt uw_ = (uw); \
+ if (uw_ > WIDE_MAX) { \
+ mp_int bignumValue_; \
+ if (mp_init_u64(&bignumValue_, uw_) == MP_OKAY) { \
+ (objPtr) = Tcl_NewBignumObj(&bignumValue_)); \
+ } else { \
+ (objPtr) = NULL; \
+ } \
+ } else { \
+ (objPtr) = Tcl_NewWideIntObj(uw_); \
+ } \
+ } while (0)
+
#define TclNewIndexObj(objPtr, w) \
TclNewIntObj(objPtr, w)
diff --git a/generic/tclLink.c b/generic/tclLink.c
index 0d57d44..af48302 100644
--- a/generic/tclLink.c
+++ b/generic/tclLink.c
@@ -553,7 +553,7 @@ GetUWide(
*/
return 1;
}
-#ifdef WORDS_BIGENDIAN
+#ifndef WORDS_BIGENDIAN
while (numBytes-- > 0) {
value = (value << CHAR_BIT) | *bytes++;
}
@@ -1451,12 +1451,12 @@ ObjValue(
}
linkPtr->lastValue.f = LinkedVar(float);
return Tcl_NewDoubleObj(linkPtr->lastValue.f);
- case TCL_LINK_WIDE_UINT:
+ case TCL_LINK_WIDE_UINT: {
if (linkPtr->flags & LINK_ALLOC_LAST) {
memcpy(linkPtr->lastValue.aryPtr, linkPtr->addr, linkPtr->bytes);
objv = (Tcl_Obj **)ckalloc(linkPtr->numElems * sizeof(Tcl_Obj *));
for (i=0; i < linkPtr->numElems; i++) {
- TclNewIntObj(objv[i], (Tcl_WideInt)
+ TclNewUIntObj(objv[i],
linkPtr->lastValue.uwPtr[i]);
}
resultObj = Tcl_NewListObj(linkPtr->numElems, objv);
@@ -1464,7 +1464,10 @@ ObjValue(
return resultObj;
}
linkPtr->lastValue.uw = LinkedVar(Tcl_WideUInt);
- return Tcl_NewWideIntObj((Tcl_WideInt) linkPtr->lastValue.uw);
+ Tcl_Obj *uwObj;
+ TclNewUIntObj(uwObj, linkPtr->lastValue.uw);
+ return uwObj;
+ }
case TCL_LINK_STRING:
p = LinkedVar(char *);
diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c
index 6ea4681..3593193 100644
--- a/generic/tclOOBasic.c
+++ b/generic/tclOOBasic.c
@@ -1249,7 +1249,7 @@ TclOOSelfObjCmd(
}
case SELF_CALL:
result[0] = TclOORenderCallChain(interp, contextPtr->callPtr);
- TclNewIntObj(result[1], contextPtr->index);
+ TclNewIndexObj(result[1], contextPtr->index);
Tcl_SetObjResult(interp, Tcl_NewListObj(2, result));
return TCL_OK;
}