summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2022-11-15 13:31:35 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2022-11-15 13:31:35 (GMT)
commit1412e9b9f0da015eacc10e723f1e602bf255c697 (patch)
treeca45b570040a5fd4d358ad4933e2d9318a874a96
parentc381a177849c7043f3fee5559c42e5f02a7dff14 (diff)
parent870cb82c96d74e93a642296f68319c777359a11d (diff)
downloadtcl-1412e9b9f0da015eacc10e723f1e602bf255c697.zip
tcl-1412e9b9f0da015eacc10e723f1e602bf255c697.tar.gz
tcl-1412e9b9f0da015eacc10e723f1e602bf255c697.tar.bz2
Merge 8.7
-rw-r--r--doc/LinkVar.35
-rw-r--r--generic/tclObj.c34
2 files changed, 12 insertions, 27 deletions
diff --git a/doc/LinkVar.3 b/doc/LinkVar.3
index 40399ac..db5a90b 100644
--- a/doc/LinkVar.3
+++ b/doc/LinkVar.3
@@ -239,9 +239,8 @@ The C variable, or each element of the C array, is of type \fBTcl_WideUInt\fR
(which is an unsigned integer type at least 64-bits wide on all platforms that
can support it.)
Any value written into the Tcl variable must have a proper unsigned
-integer form acceptable to \fBTcl_GetWideIntFromObj\fR (it will be
-cast to unsigned);
-.\" FIXME! Use bignums instead.
+wideinteger form acceptable to \fBTcl_GetBignumFromObj\fR and in the
+platform's defined range for the \fBTcl_WideUInt\fR type;
attempts to write non-integer values into \fIvarName\fR will be
rejected with Tcl errors. Incomplete integer representations (like
the empty string, '+', '-' or the hex/octal/decimal/binary prefix) are accepted
diff --git a/generic/tclObj.c b/generic/tclObj.c
index d385ed0..db4d3c0 100644
--- a/generic/tclObj.c
+++ b/generic/tclObj.c
@@ -2678,15 +2678,12 @@ Tcl_GetLongFromObj(
{
mp_int big;
- unsigned long scratch, value = 0;
- unsigned char *bytes = (unsigned char *) &scratch;
+ unsigned long value = 0;
size_t numBytes;
TclUnpackBignum(objPtr, big);
- if (mp_to_ubin(&big, bytes, sizeof(long), &numBytes) == MP_OKAY) {
- while (numBytes-- > 0) {
- value = (value << CHAR_BIT) | *bytes++;
- }
+ if (mp_pack(&value, 1,
+ &numBytes, 0, sizeof(Tcl_WideUInt), 0, 0, &big) == MP_OKAY) {
if (big.sign) {
if (value <= 1 + (unsigned long)LONG_MAX) {
*longPtr = (long)(-value);
@@ -2918,14 +2915,10 @@ Tcl_GetWideIntFromObj(
mp_int big;
Tcl_WideUInt value = 0;
size_t numBytes;
- Tcl_WideInt scratch;
- unsigned char *bytes = (unsigned char *) &scratch;
TclUnpackBignum(objPtr, big);
- if (mp_to_ubin(&big, bytes, sizeof(Tcl_WideInt), &numBytes) == MP_OKAY) {
- while (numBytes-- > 0) {
- value = (value << CHAR_BIT) | *bytes++;
- }
+ if (mp_pack(&value, 1,
+ &numBytes, 0, sizeof(Tcl_WideUInt), 0, 0, &big) == MP_OKAY) {
if (big.sign) {
if (value <= 1 + ~(Tcl_WideUInt)WIDE_MIN) {
*wideIntPtr = (Tcl_WideInt)(-value);
@@ -2998,21 +2991,18 @@ TclGetWideBitsFromObj(
mp_int big;
mp_err err;
- Tcl_WideUInt value = 0, scratch;
+ Tcl_WideUInt value = 0;
size_t numBytes;
- unsigned char *bytes = (unsigned char *) &scratch;
Tcl_GetBignumFromObj(NULL, objPtr, &big);
err = mp_mod_2d(&big, (int) (CHAR_BIT * sizeof(Tcl_WideInt)), &big);
if (err == MP_OKAY) {
- err = mp_to_ubin(&big, bytes, sizeof(Tcl_WideInt), &numBytes);
+ err = mp_pack(&value, 1,
+ &numBytes, 0, sizeof(Tcl_WideUInt), 0, 0, &big);
}
if (err != MP_OKAY) {
return TCL_ERROR;
}
- while (numBytes-- > 0) {
- value = (value << CHAR_BIT) | *bytes++;
- }
*wideIntPtr = !big.sign ? (Tcl_WideInt)value : -(Tcl_WideInt)value;
mp_clear(&big);
return TCL_OK;
@@ -3382,19 +3372,15 @@ Tcl_SetBignumObj(
{
Tcl_WideUInt value = 0;
size_t numBytes;
- Tcl_WideUInt scratch;
- unsigned char *bytes = (unsigned char *) &scratch;
mp_int *bignumValue = (mp_int *) big;
if (Tcl_IsShared(objPtr)) {
Tcl_Panic("%s called with shared object", "Tcl_SetBignumObj");
}
- if (mp_to_ubin(bignumValue, bytes, sizeof(Tcl_WideUInt), &numBytes) != MP_OKAY) {
+ if (mp_pack(&value, 1,
+ &numBytes, 0, sizeof(Tcl_WideUInt), 0, 0, bignumValue) != MP_OKAY) {
goto tooLargeForWide;
}
- while (numBytes-- > 0) {
- value = (value << CHAR_BIT) | *bytes++;
- }
if (value > ((Tcl_WideUInt)WIDE_MAX + bignumValue->sign)) {
goto tooLargeForWide;
}