Index: TODO =================================================================== diff -u -ra5bf2874a6cb0338860062dce1846279c1704444 -r27bb1e990885cba2fd62749c714566c01f2ca662 --- TODO (.../TODO) (revision a5bf2874a6cb0338860062dce1846279c1704444) +++ TODO (.../TODO) (revision 27bb1e990885cba2fd62749c714566c01f2ca662) @@ -2897,9 +2897,11 @@ (supporting result MONGO_OK for mongo_cursor_next) * factored out "mongo cond" from "mongo query" -TODO: +- fixing part of the memleak introduced for bignum handling above + (for some unknown reasons, we see crashes from mp_clear) +- extend regression test - +TODO: - in method-require.test # TODO: make me more pretty set ::nsf::unknown(nx) {::nx::Class __unknown} Index: generic/nsf.c =================================================================== diff -u -r417968f9109f1c27af478b142b34b64f38e3908e -r27bb1e990885cba2fd62749c714566c01f2ca662 --- generic/nsf.c (.../nsf.c) (revision 417968f9109f1c27af478b142b34b64f38e3908e) +++ generic/nsf.c (.../nsf.c) (revision 27bb1e990885cba2fd62749c714566c01f2ca662) @@ -161,7 +161,8 @@ static Tcl_ObjType CONST86 *Nsf_OT_byteCodeType = NULL, *Nsf_OT_tclCmdNameType = NULL, - *Nsf_OT_listType = NULL; + *Nsf_OT_listType = NULL, + *Nsf_OT_intType = NULL; /* * Function prototypes @@ -9458,15 +9459,42 @@ * *---------------------------------------------------------------------- */ +//void foo() {;} + #include int Nsf_ConvertToInteger(Tcl_Interp *interp, Tcl_Obj *objPtr, Nsf_Param CONST *pPtr, ClientData *clientData, Tcl_Obj **outObjPtr) { int result; - mp_int bignumValue; - result = Tcl_GetBignumFromObj(interp, objPtr, &bignumValue); - + //fprintf(stderr, "type is on call %p %s value %s\n", + // objPtr->typePtr, objPtr->typePtr? objPtr->typePtr->name:"NULL", ObjStr(objPtr)); + + /* + * Try to short_cut common cases to avoid conversion to bignums, since + * Tcl_GetBignumFromObj returns a value, which has to be freed. + */ + if (objPtr->typePtr == Nsf_OT_intType) { + //fprintf(stderr, "shortcut\n"); + result = TCL_OK; + } else { + mp_int bignumValue; + result = Tcl_GetBignumFromObj(interp, objPtr, &bignumValue); + + //fprintf(stderr, "type after call %p %s\n", + // objPtr->typePtr, objPtr->typePtr? objPtr->typePtr->name:"NULL"); + + if (result == TCL_OK) { + //fprintf(stderr, "call clear used %d alloc %d sign %d dp %p\n", bignumValue.used, bignumValue.alloc, bignumValue.sign, bignumValue.dp); + //foo(); + + /* for some unknown reasons, the folloing call crashes */ + //mp_clear(&bignumValue); + + //fprintf(stderr, "call clear DONE\n"); + } + } + if (result == TCL_OK) { *clientData = (ClientData)objPtr; *outObjPtr = objPtr; @@ -20929,8 +20957,28 @@ */ NsfMutexLock(&initMutex); Nsf_OT_byteCodeType = Tcl_GetObjType("bytecode"); + assert(Nsf_OT_byteCodeType); + Nsf_OT_tclCmdNameType = Tcl_GetObjType("cmdName"); + assert(Nsf_OT_tclCmdNameType); + Nsf_OT_listType = Tcl_GetObjType("list"); + assert(Nsf_OT_listType); + + Nsf_OT_intType = Tcl_GetObjType("int"); + assert(Nsf_OT_intType); +#if 0 + { + mp_int bignumValue = {NULL}; + Tcl_Obj *objPtr; + + // also this crashes + mp_init(&bignumValue); + objPtr = Tcl_NewBignumObj(&bignumValue); + Nsf_OT_bignumType = objPtr->typePtr; + } + assert(Nsf_OT_bignumType); +#endif NsfMutexUnlock(&initMutex); /* Index: tests/parameters.test =================================================================== diff -u -r417968f9109f1c27af478b142b34b64f38e3908e -r27bb1e990885cba2fd62749c714566c01f2ca662 --- tests/parameters.test (.../parameters.test) (revision 417968f9109f1c27af478b142b34b64f38e3908e) +++ tests/parameters.test (.../parameters.test) (revision 27bb1e990885cba2fd62749c714566c01f2ca662) @@ -1642,7 +1642,7 @@ # # Test integer, wideinteger and bignums # -Test parameter count 10000 +Test parameter count 1 Test case bignums { ::nx::Object create o { @@ -1671,6 +1671,12 @@ ? {o foo [expr {2 ** 64}]} "18446744073709551616" ? {o foo [expr {2 ** 128}]} "340282366920938463463374607431768211456" + ? {o foo [expr {wide(2 ** 63)}]} "-9223372036854775808" + + ? {o foo [expr {2.0 * 2}]} {expected integer but got "4.0" for parameter "x"} + ? {o foo [expr {2.0 ** 128}]} {expected integer but got "3.4028236692093846e+38" for parameter "x"} + ? {o foo [expr {(2 ** 128)*1.0}]} {expected integer but got "3.4028236692093846e+38" for parameter "x"} + ? {o foo32 [expr {2 ** 31}]} "2147483648" ? {o foo32 [expr {2 ** 32}]} {expected int32 but got "4294967296" for parameter "x"}