[gjs] arg: Warn on lossy conversion from (u)int64
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs] arg: Warn on lossy conversion from (u)int64
- Date: Sat, 25 Feb 2017 06:00:31 +0000 (UTC)
commit 048fceed7b8501f23d06bbdb109aa235767be4a1
Author: Philip Chimento <philip chimento gmail com>
Date: Thu Feb 23 22:52:51 2017 -0800
arg: Warn on lossy conversion from (u)int64
Previously, a conversion from 64-bit integer that could not be stored
exactly in a double, would trip an assertion in debug mode SpiderMonkey.
This new behaviour in SpiderMonkey 38 would cause code like
"GLib.MAXINT64" to crash.
Instead, we check for that situation, log a warning for the developer,
and proceed with the lossy value.
https://bugzilla.gnome.org/show_bug.cgi?id=778705
gi/arg.cpp | 17 +++++++++++++++--
installed-tests/js/testEverythingBasic.js | 12 ++++++++++++
2 files changed, 27 insertions(+), 2 deletions(-)
---
diff --git a/gi/arg.cpp b/gi/arg.cpp
index b867ab8..d1194ef 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -2572,6 +2572,13 @@ gjs_object_from_g_hash (JSContext *context,
return result;
}
+template<typename T>
+static bool
+is_safe_to_store_in_double(T number)
+{
+ return static_cast<T>(static_cast<double>(number)) == number;
+}
+
bool
gjs_value_from_g_argument (JSContext *context,
JS::MutableHandleValue value_p,
@@ -2607,11 +2614,17 @@ gjs_value_from_g_argument (JSContext *context,
break;
case GI_TYPE_TAG_INT64:
- value_p.set(JS::NumberValue(arg->v_int64));
+ if (!is_safe_to_store_in_double(arg->v_int64))
+ g_warning("Value %" G_GINT64_FORMAT " cannot be safely stored in "
+ "a JS Number and will be rounded", arg->v_int64);
+ value_p.setNumber(static_cast<double>(arg->v_int64));
break;
case GI_TYPE_TAG_UINT64:
- value_p.set(JS::NumberValue(arg->v_uint64));
+ if (!is_safe_to_store_in_double(arg->v_uint64))
+ g_warning("Value %" G_GUINT64_FORMAT " cannot be safely stored in "
+ "a JS Number and will be rounded", arg->v_uint64);
+ value_p.setNumber(static_cast<double>(arg->v_uint64));
break;
case GI_TYPE_TAG_UINT16:
diff --git a/installed-tests/js/testEverythingBasic.js b/installed-tests/js/testEverythingBasic.js
index 8e6d953..fda1204 100644
--- a/installed-tests/js/testEverythingBasic.js
+++ b/installed-tests/js/testEverythingBasic.js
@@ -101,6 +101,18 @@ describe('Life, the Universe and Everything', function () {
run_test(bytes, 'MAX', 'test_int');
});
});
+
+ it('warns when conversion is lossy', function () {
+ GLib.test_expect_message('Gjs', GLib.LogLevelFlags.LEVEL_WARNING,
+ "*cannot be safely stored*");
+ GLib.test_expect_message('Gjs', GLib.LogLevelFlags.LEVEL_WARNING,
+ "*cannot be safely stored*");
+ void GLib.MAXINT64;
+ void GLib.MAXUINT64;
+ GLib.test_assert_expected_messages_internal('Gjs',
+ 'testEverythingBasic.js', 0,
+ 'Limits warns when conversion is lossy');
+ });
});
describe('No implicit conversion to unsigned', function () {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]