Skip to content

Commit 05a9ba9

Browse files
committed
WIP Tcl TIP 484, types not registered in Tcl 9.0
1 parent ca3595d commit 05a9ba9

File tree

1 file changed

+53
-9
lines changed

1 file changed

+53
-9
lines changed

Tcl.xs

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -546,13 +546,31 @@ SvFromTclObj(pTHX_ Tcl_Obj *objPtr)
546546
*/
547547
sv = newSV(0);
548548
}
549-
else if (objPtr->typePtr == tclIntTypePtr) {
550-
sv = newSViv(objPtr->internalRep.longValue);
549+
else if (objPtr->typePtr == NULL) {
550+
goto handle_as_string;
551+
}
552+
else if ((tclIntTypePtr != NULL && objPtr->typePtr == tclIntTypePtr) ||
553+
(tclWideIntTypePtr != NULL && objPtr->typePtr == tclWideIntTypePtr)) {
554+
/*
555+
* Tcl TIP 484 means that value type 'int' may be 64-bit (or wider?)
556+
* even on 32-bit systems
557+
*/
558+
Tcl_WideInt w;
559+
int code = Tcl_GetWideIntFromObj(NULL, objPtr, &w); /* this must return TCL_OK */
560+
if (IVSIZE >= sizeof(Tcl_WideInt) ||
561+
(w >= (Tcl_WideInt)IV_MIN && w <= (Tcl_WideInt)IV_MAX)
562+
) {
563+
sv = newSViv(w);
564+
} else if (w >= (Tcl_WideInt)UV_MIN && w <= (Tcl_WideInt)UV_MAX) {
565+
sv = newSVuv(w);
566+
} else {
567+
goto handle_as_string;
568+
}
551569
}
552570
else if (objPtr->typePtr == tclDoubleTypePtr) {
553571
sv = newSVnv(objPtr->internalRep.doubleValue);
554572
}
555-
else if (objPtr->typePtr == tclBooleanTypePtr) {
573+
else if (tclBooleanTypePtr != NULL && objPtr->typePtr == tclBooleanTypePtr) {
556574
/*
557575
* Booleans can originate as words (yes/true/...), so if there is a
558576
* string rep, use it instead. We could check if the first byte
@@ -566,7 +584,7 @@ SvFromTclObj(pTHX_ Tcl_Obj *objPtr)
566584
sv = newSVpvn(str, len);
567585
}
568586
}
569-
else if (objPtr->typePtr == tclByteArrayTypePtr) {
587+
else if (tclByteArrayTypePtr != NULL && objPtr->typePtr == tclByteArrayTypePtr) {
570588
str = (const char *) Tcl_GetByteArrayFromObj(objPtr, &len);
571589
sv = newSVpvn(str, len);
572590
}
@@ -601,8 +619,9 @@ SvFromTclObj(pTHX_ Tcl_Obj *objPtr)
601619
}
602620
}
603621
/* tclStringTypePtr is true unicode */
604-
/* tclWideIntTypePtr is 64-bit int */
622+
/* may also be handling int/wideInt outside of [IV_MIN,UV_MAX] */
605623
else {
624+
handle_as_string:
606625
str = Tcl_GetStringFromObj(objPtr, &len);
607626
sv = newSVpvn(str, len);
608627
/* should turn on, but let's check this first for efficiency */
@@ -1838,13 +1857,38 @@ BOOT:
18381857
hvInterps = newHV();
18391858
}
18401859

1841-
tclBooleanTypePtr = Tcl_GetObjType("boolean");
1842-
tclByteArrayTypePtr = Tcl_GetObjType("bytearray");
18431860
tclDoubleTypePtr = Tcl_GetObjType("double");
1844-
tclIntTypePtr = Tcl_GetObjType("int");
18451861
tclListTypePtr = Tcl_GetObjType("list");
18461862
tclStringTypePtr = Tcl_GetObjType("string");
1847-
tclWideIntTypePtr = Tcl_GetObjType("wideInt");
1863+
{
1864+
/* As of Tcl 9.0, Tcl_GetObjType() returns NULL for these types */
1865+
Tcl_Obj *objPtr;
1866+
1867+
objPtr = Tcl_NewBooleanObj(0);
1868+
if (strcmp("boolean", objPtr->typePtr->name) == 0) {
1869+
tclBooleanTypePtr = objPtr->typePtr;
1870+
}
1871+
Tcl_DecrRefCount(objPtr);
1872+
1873+
objPtr = Tcl_NewIntObj(0);
1874+
if (strcmp("int", objPtr->typePtr->name) == 0) {
1875+
tclIntTypePtr = objPtr->typePtr;
1876+
}
1877+
Tcl_DecrRefCount(objPtr);
1878+
#if !defined(TCL_WIDE_INT_IS_LONG) && LONGLONGSIZE > IVSIZE
1879+
objPtr = Tcl_NewWideIntObj((Tcl_WideInt)IV_MIN - 1);
1880+
if (strcmp("wideInt", objPtr->typePtr->name) == 0) {
1881+
tclWideIntTypePtr = objPtr->typePtr;
1882+
}
1883+
Tcl_DecrRefCount(objPtr);
1884+
#endif
1885+
1886+
objPtr = Tcl_NewByteArrayObj(NULL, 0);
1887+
if(strcmp("bytearray", objPtr->typePtr->name) == 0) {
1888+
tclByteArrayTypePtr = objPtr->typePtr;
1889+
}
1890+
Tcl_DecrRefCount(objPtr);
1891+
}
18481892

18491893
/* set up constant subs */
18501894
{

0 commit comments

Comments
 (0)