Index: generic/tclExecute.c ================================================================== --- generic/tclExecute.c +++ generic/tclExecute.c @@ -490,11 +490,13 @@ } \ } while (0) /* * Macro used in this file to save a function call for common uses of - * TclGetNumberFromObj(). The ANSI C "prototype" is: + * TclGetNumberFromObj(). An "unsafe" version is available when objPtr + * is known to be of numeric type and valid (non-NAN) value already. + * The ANSI C "prototype" is: * * MODULE_SCOPE int GetNumberFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, * ClientData *ptrPtr, int *tPtr); */ @@ -511,10 +513,18 @@ *(ptrPtr) = (ClientData) \ (&((objPtr)->internalRep.doubleValue)), TCL_OK) : \ (((objPtr)->bytes != NULL) && ((objPtr)->length == 0)) \ ? TCL_ERROR : \ TclGetNumberFromObj((interp), (objPtr), (ptrPtr), (tPtr))) +#define GetNumberFromObjUnsafe(objPtr, ptrPtr, tPtr) \ + ((objPtr)->typePtr == &tclIntType) \ + ? (*(tPtr) = TCL_NUMBER_LONG, \ + *(ptrPtr) = (ClientData) \ + (&((objPtr)->internalRep.longValue))) : \ + (*(tPtr) = TCL_NUMBER_DOUBLE, \ + *(ptrPtr) = (ClientData) \ + (&((objPtr)->internalRep.doubleValue))) #else /* !TCL_WIDE_INT_IS_LONG */ #define GetNumberFromObj(interp, objPtr, ptrPtr, tPtr) \ (((objPtr)->typePtr == &tclIntType) \ ? (*(tPtr) = TCL_NUMBER_LONG, \ *(ptrPtr) = (ClientData) \ @@ -530,10 +540,22 @@ *(ptrPtr) = (ClientData) \ (&((objPtr)->internalRep.doubleValue)), TCL_OK) : \ (((objPtr)->bytes != NULL) && ((objPtr)->length == 0)) \ ? TCL_ERROR : \ TclGetNumberFromObj((interp), (objPtr), (ptrPtr), (tPtr))) +#define GetNumberFromObjUnsafe(objPtr, ptrPtr, tPtr) \ + ((objPtr)->typePtr == &tclIntType) \ + ? (*(tPtr) = TCL_NUMBER_LONG, \ + *(ptrPtr) = (ClientData) \ + (&((objPtr)->internalRep.longValue))) : \ + ((objPtr)->typePtr == &tclWideIntType) \ + ? (*(tPtr) = TCL_NUMBER_WIDE, \ + *(ptrPtr) = (ClientData) \ + (&((objPtr)->internalRep.wideValue))) : \ + (*(tPtr) = TCL_NUMBER_DOUBLE, \ + *(ptrPtr) = (ClientData) \ + (&((objPtr)->internalRep.doubleValue))) #endif /* TCL_WIDE_INT_IS_LONG */ /* * Macro used in this file to save a function call for common uses of * Tcl_GetBooleanFromObj(). The ANSI C "prototype" is: @@ -8160,12 +8182,12 @@ mp_int big1, big2, bigResult, bigRemainder; Tcl_Obj *objResultPtr; int invalid, numPos, zero; long shift; - (void) GetNumberFromObj(NULL, valuePtr, &ptr1, &type1); - (void) GetNumberFromObj(NULL, value2Ptr, &ptr2, &type2); + GetNumberFromObjUnsafe(valuePtr, &ptr1, &type1); + GetNumberFromObjUnsafe(value2Ptr, &ptr2, &type2); switch (opcode) { case INST_MOD: /* TODO: Attempts to re-use unshared operands on stack */ @@ -9155,11 +9177,11 @@ int type; Tcl_WideInt w; mp_int big; Tcl_Obj *objResultPtr; - (void) GetNumberFromObj(NULL, valuePtr, &ptr, &type); + GetNumberFromObjUnsafe(valuePtr, &ptr, &type); switch (opcode) { case INST_BITNOT: #ifndef TCL_WIDE_INT_IS_LONG if (type == TCL_NUMBER_WIDE) { @@ -9237,12 +9259,12 @@ long l1, l2; #ifndef TCL_WIDE_INT_IS_LONG Tcl_WideInt w1, w2; #endif - (void) GetNumberFromObj(NULL, valuePtr, &ptr1, &type1); - (void) GetNumberFromObj(NULL, value2Ptr, &ptr2, &type2); + GetNumberFromObjUnsafe(valuePtr, &ptr1, &type1); + GetNumberFromObjUnsafe(value2Ptr, &ptr2, &type2); switch (type1) { case TCL_NUMBER_LONG: l1 = *((const long *)ptr1); switch (type2) {