Skip to content

Commit 8743272

Browse files
author
jan.nijtmans
committed
Add (internal) TclNewUIntObj(), and use it to fix TCL_LINK_WIDE_UINT for big (>= 2^63) integers. With testcase
1 parent b2b0452 commit 8743272

File tree

4 files changed

+45
-7
lines changed

4 files changed

+45
-7
lines changed

generic/tclInt.h

+35
Original file line numberDiff line numberDiff line change
@@ -4852,6 +4852,26 @@ MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_SafeInit;
48524852
TCL_DTRACE_OBJ_CREATE(objPtr); \
48534853
} while (0)
48544854

4855+
#define TclNewUIntObj(objPtr, uw) \
4856+
do { \
4857+
TclIncrObjsAllocated(); \
4858+
TclAllocObjStorage(objPtr); \
4859+
(objPtr)->refCount = 0; \
4860+
(objPtr)->bytes = NULL; \
4861+
Tcl_WideUInt uw_ = (uw); \
4862+
if (uw_ > WIDE_MAX) { \
4863+
mp_int bignumValue_; \
4864+
if (mp_init_u64(&bignumValue_, uw_) != MP_OKAY) { \
4865+
Tcl_Panic("%s: memory overflow", "TclNewUIntObj"); \
4866+
} \
4867+
TclSetBignumInternalRep((objPtr), &bignumValue_); \
4868+
} else { \
4869+
(objPtr)->internalRep.wideValue = (Tcl_WideInt)(uw_); \
4870+
(objPtr)->typePtr = &tclIntType; \
4871+
} \
4872+
TCL_DTRACE_OBJ_CREATE(objPtr); \
4873+
} while (0)
4874+
48554875
#define TclNewIndexObj(objPtr, w) \
48564876
TclNewIntObj(objPtr, w)
48574877

@@ -4880,6 +4900,21 @@ MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_SafeInit;
48804900
#define TclNewIntObj(objPtr, w) \
48814901
(objPtr) = Tcl_NewWideIntObj(w)
48824902

4903+
#define TclNewUIntObj(objPtr, uw) \
4904+
do { \
4905+
Tcl_WideUInt uw_ = (uw); \
4906+
if (uw_ > WIDE_MAX) { \
4907+
mp_int bignumValue_; \
4908+
if (mp_init_u64(&bignumValue_, uw_) == MP_OKAY) { \
4909+
(objPtr) = Tcl_NewBignumObj(&bignumValue_)); \
4910+
} else { \
4911+
(objPtr) = NULL; \
4912+
} \
4913+
} else { \
4914+
(objPtr) = Tcl_NewWideIntObj(uw_); \
4915+
} \
4916+
} while (0)
4917+
48834918
#define TclNewIndexObj(objPtr, w) \
48844919
TclNewIntObj(objPtr, w)
48854920

generic/tclLink.c

+7-4
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ GetUWide(
553553
*/
554554
return 1;
555555
}
556-
#ifdef WORDS_BIGENDIAN
556+
#ifndef WORDS_BIGENDIAN
557557
while (numBytes-- > 0) {
558558
value = (value << CHAR_BIT) | *bytes++;
559559
}
@@ -1451,20 +1451,23 @@ ObjValue(
14511451
}
14521452
linkPtr->lastValue.f = LinkedVar(float);
14531453
return Tcl_NewDoubleObj(linkPtr->lastValue.f);
1454-
case TCL_LINK_WIDE_UINT:
1454+
case TCL_LINK_WIDE_UINT: {
14551455
if (linkPtr->flags & LINK_ALLOC_LAST) {
14561456
memcpy(linkPtr->lastValue.aryPtr, linkPtr->addr, linkPtr->bytes);
14571457
objv = (Tcl_Obj **)ckalloc(linkPtr->numElems * sizeof(Tcl_Obj *));
14581458
for (i=0; i < linkPtr->numElems; i++) {
1459-
TclNewIntObj(objv[i], (Tcl_WideInt)
1459+
TclNewUIntObj(objv[i],
14601460
linkPtr->lastValue.uwPtr[i]);
14611461
}
14621462
resultObj = Tcl_NewListObj(linkPtr->numElems, objv);
14631463
ckfree(objv);
14641464
return resultObj;
14651465
}
14661466
linkPtr->lastValue.uw = LinkedVar(Tcl_WideUInt);
1467-
return Tcl_NewWideIntObj((Tcl_WideInt) linkPtr->lastValue.uw);
1467+
Tcl_Obj *uwObj;
1468+
TclNewUIntObj(uwObj, linkPtr->lastValue.uw);
1469+
return uwObj;
1470+
}
14681471

14691472
case TCL_LINK_STRING:
14701473
p = LinkedVar(char *);

generic/tclOOBasic.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1249,7 +1249,7 @@ TclOOSelfObjCmd(
12491249
}
12501250
case SELF_CALL:
12511251
result[0] = TclOORenderCallChain(interp, contextPtr->callPtr);
1252-
TclNewIntObj(result[1], contextPtr->index);
1252+
TclNewIndexObj(result[1], contextPtr->index);
12531253
Tcl_SetObjResult(interp, Tcl_NewListObj(2, result));
12541254
return TCL_OK;
12551255
}

tests/link.test

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ test link-2.1 {writing C variables from Tcl} -constraints {testlink} -setup {
6969
set long 34543
7070
set ulong 567890
7171
set float 1.0987654321
72-
set uwide 357357357357
72+
set uwide 12345678901234567890
7373
concat [testlink get] | $int $real $bool $string $wide $char $uchar $short $ushort $uint $long $ulong $float $uwide
74-
} -result {465 -10.5 1 abcdef 135135 79 161 8000 40000 -1073628482 34543 567890 1.0987653732299805 357357357357 | 0o0721 -10.5 true abcdef 135135 79 161 8000 40000 0xc001babe 34543 567890 1.0987654321 357357357357}
74+
} -result {465 -10.5 1 abcdef 135135 79 161 8000 40000 -1073628482 34543 567890 1.0987653732299805 -6101065172474983726 | 0o0721 -10.5 true abcdef 135135 79 161 8000 40000 0xc001babe 34543 567890 1.0987654321 12345678901234567890}
7575
test link-2.2 {writing bad values into variables} -setup {
7676
testlink delete
7777
} -constraints {testlink} -body {

0 commit comments

Comments
 (0)