diff options
author | Evan Welsh <contact@evanwelsh.com> | 2021-08-25 01:28:15 -0700 |
---|---|---|
committer | Evan Welsh <contact@evanwelsh.com> | 2021-08-25 21:34:07 -0700 |
commit | 9f68b106d5cb500c52a9c394fa0ce54e8c2f4341 (patch) | |
tree | c156e3e95cecd261f54b8f894df31c2f1a934b5e | |
parent | ed1a149430970adc43d1f3d1239b3f48b073a472 (diff) | |
download | gjs-ewlsh/fix-int64-conversion.tar.gz |
gi: Convert GJS values to 64-bit GValue integersewlsh/fix-int64-conversion
Previously we relied on g_value_type_transformable to transform JS
numbers to uint64 and int64 values, this coerced the values into
ints and broke setting values larger than GLib.MAXINT32 during
construction.
Fixes #92
-rw-r--r-- | gi/value.cpp | 17 | ||||
-rw-r--r-- | installed-tests/js/testGObjectClass.js | 31 |
2 files changed, 47 insertions, 1 deletions
diff --git a/gi/value.cpp b/gi/value.cpp index ec64f0ac..4ba2160d 100644 --- a/gi/value.cpp +++ b/gi/value.cpp @@ -423,6 +423,13 @@ gjs_value_to_g_value_internal(JSContext *context, } else { return throw_expect_type(context, value, "integer"); } + } else if (gtype == G_TYPE_INT64) { + gint64 i; + if (Gjs::js_value_to_c(context, value, &i)) { + g_value_set_int64(gvalue, i); + } else { + return throw_expect_type(context, value, "64-bit integer"); + } } else if (gtype == G_TYPE_DOUBLE) { gdouble d; if (Gjs::js_value_to_c(context, value, &d)) { @@ -446,10 +453,18 @@ gjs_value_to_g_value_internal(JSContext *context, } else { return throw_expect_type(context, value, "unsigned integer"); } + } else if (gtype == G_TYPE_UINT64) { + guint64 i; + if (Gjs::js_value_to_c(context, value, &i)) { + g_value_set_uint64(gvalue, i); + } else { + return throw_expect_type(context, value, "unsigned 64-bit integer"); + } } else if (gtype == G_TYPE_BOOLEAN) { /* JS::ToBoolean() can't fail */ g_value_set_boolean(gvalue, JS::ToBoolean(value)); - } else if (g_type_is_a(gtype, G_TYPE_OBJECT) || g_type_is_a(gtype, G_TYPE_INTERFACE)) { + } else if (g_type_is_a(gtype, G_TYPE_OBJECT) || + g_type_is_a(gtype, G_TYPE_INTERFACE)) { GObject *gobj; gobj = NULL; diff --git a/installed-tests/js/testGObjectClass.js b/installed-tests/js/testGObjectClass.js index 4b611aed..0b46d417 100644 --- a/installed-tests/js/testGObjectClass.js +++ b/installed-tests/js/testGObjectClass.js @@ -1293,3 +1293,34 @@ describe('GObject class with JSObject signals', function () { }); }); +describe('GObject class with int64 properties', function () { + const MyInt64Class = GObject.registerClass(class MyInt64Class extends GObject.Object { + static [GObject.properties] = { + 'int64': GObject.ParamSpec.int64('int64', 'int64', 'int64', + GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE | GObject.ParamFlags.CONSTRUCT, + // GLib.MAXINT64 exceeds JS' ability to safely represent an integer + GLib.MININT32 * 2, GLib.MAXINT32 * 2, 0), + }; + }); + + it('can set an int64 property', function () { + const instance = new MyInt64Class({ + int64: GLib.MAXINT32, + }); + + expect(instance.int64).toBe(GLib.MAXINT32); + + instance.int64 = GLib.MAXINT32 + 1; + + expect(instance.int64).toBe(GLib.MAXINT32 + 1); + }); + + + it('can construct with int64 property', function () { + const instance = new MyInt64Class({ + int64: GLib.MAXINT32 + 1, + }); + + expect(instance.int64).toBe(GLib.MAXINT32 + 1); + }); +}); |