Fix jsctypes unsigned __int64 conversion on MSVC.
b=519235, r=jorendorff
--- a/js/ctypes/Function.cpp
+++ b/js/ctypes/Function.cpp
@@ -47,30 +47,50 @@
namespace mozilla {
namespace ctypes {
/*******************************************************************************
** Static helpers
*******************************************************************************/
template<class IntegerType>
+static IntegerType
+Convert(jsdouble d)
+{
+ return IntegerType(d);
+}
+
+#ifdef _MSC_VER
+// MSVC can't perform double to unsigned __int64 conversion when the
+// double is greater than 2^63 - 1. Help it along a little.
+template<>
+static PRUint64
+Convert<PRUint64>(jsdouble d)
+{
+ return d > 0x7fffffffffffffffui64 ?
+ PRUint64(d - 0x8000000000000000ui64) + 0x8000000000000000ui64 :
+ PRUint64(d);
+}
+#endif
+
+template<class IntegerType>
static bool
jsvalToIntStrict(jsval aValue, IntegerType *aResult)
{
if (JSVAL_IS_INT(aValue)) {
jsint i = JSVAL_TO_INT(aValue);
*aResult = IntegerType(i);
// Make sure the integer fits in the alotted precision, and has the right sign.
return jsint(*aResult) == i &&
(i < 0) == (*aResult < 0);
}
if (JSVAL_IS_DOUBLE(aValue)) {
jsdouble d = *JSVAL_TO_DOUBLE(aValue);
- *aResult = IntegerType(d);
+ *aResult = Convert<IntegerType>(d);
// Don't silently lose bits here -- check that aValue really is an
// integer value, and has the right sign.
return jsdouble(*aResult) == d &&
(d < 0) == (*aResult < 0);
}
if (JSVAL_IS_BOOLEAN(aValue)) {
// Implicitly promote boolean values to 0 or 1, like C.
--- a/js/ctypes/tests/unit/test_jsctypes.js.in
+++ b/js/ctypes/tests/unit/test_jsctypes.js.in
@@ -217,19 +217,17 @@ function run_int64_tests(library) {
do_check_throws(function () { test_i64_i64(vals[i]); }, TypeError);
var test_i64_i64_sum = library.declare("test_i64_i64_sum", Types.DEFAULT, Types.INT64, Types.INT64, Types.INT64);
do_check_eq(test_i64_i64_sum(5, 5), 10);
// test the range of unsigned. (we can reuse the signed C function
// here, since it's binary-compatible.)
var test_ui64_ui64 = library.declare("test_i64_i64", Types.DEFAULT, Types.UINT64, Types.UINT64);
-#ifndef XP_WIN
do_check_eq(test_ui64_ui64(0xfffffffffffff000), 0xfffffffffffff000);
-#endif
do_check_throws(function () { test_ui64_ui64(0x10000000000000000); }, TypeError);
do_check_throws(function () { test_ui64_ui64(-1); }, TypeError);
}
function run_float_tests(library) {
var test_f = library.declare("test_f", Types.DEFAULT, Types.FLOAT);
do_check_eq(test_f(), 123456.5);