[gjs] arg: Allocate hash values that don't fit in pointers
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs] arg: Allocate hash values that don't fit in pointers
- Date: Thu, 3 Nov 2016 01:18:57 +0000 (UTC)
commit 28bbd24cd9d06b1580603bc771ae98357d42d516
Author: Philip Chimento <philip endlessm com>
Date: Wed Nov 2 14:52:55 2016 -0700
arg: Allocate hash values that don't fit in pointers
For GHashTables with value types that can't be stuffed into pointers, we
use heap-allocated values instead. Since the types we are concerned with
here are all primitive types, they are always copied, so the hash table
can always own the values, and they can be freed unconditionally when the
hash table GIArgument is released.
https://bugzilla.gnome.org/show_bug.cgi?id=773763
gi/arg.cpp | 41 ++++++++++++++++++++++++++----
installed-tests/js/testGIMarshalling.js | 20 +++++++++++++++
2 files changed, 55 insertions(+), 6 deletions(-)
---
diff --git a/gi/arg.cpp b/gi/arg.cpp
index 764bd06..f6d8d13 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -507,7 +507,7 @@ gjs_object_to_g_hash(JSContext *context,
JS::RootedValue key_js(context), val_js(context);
for (id_ix = 0, id_len = ids.length(); id_ix < id_len; id_ix++) {
- gpointer key_ptr;
+ gpointer key_ptr, val_ptr;
GIArgument val_arg = { 0 };
if (!JS_IdToValue(context, ids[id_ix], key_js.address()))
@@ -528,7 +528,30 @@ gjs_object_to_g_hash(JSContext *context,
&val_arg))
goto free_hash_and_fail;
- g_hash_table_insert(result, key_ptr, val_arg.v_pointer);
+ GITypeTag val_type = g_type_info_get_tag(val_param_info);
+ /* Use heap-allocated values for types that don't fit in a pointer */
+ if (val_type == GI_TYPE_TAG_INT64) {
+ int64_t *heap_val = g_new(int64_t, 1);
+ *heap_val = val_arg.v_int64;
+ val_ptr = heap_val;
+ } else if (val_type == GI_TYPE_TAG_UINT64) {
+ uint64_t *heap_val = g_new(uint64_t, 1);
+ *heap_val = val_arg.v_uint64;
+ val_ptr = heap_val;
+ } else if (val_type == GI_TYPE_TAG_FLOAT) {
+ float *heap_val = g_new(float, 1);
+ *heap_val = val_arg.v_float;
+ val_ptr = heap_val;
+ } else if (val_type == GI_TYPE_TAG_DOUBLE) {
+ double *heap_val = g_new(double, 1);
+ *heap_val = val_arg.v_double;
+ val_ptr = heap_val;
+ } else {
+ /* Other types are simply stuffed inside v_pointer */
+ val_ptr = val_arg.v_pointer;
+ }
+
+ g_hash_table_insert(result, key_ptr, val_ptr);
}
*hash_p = result;
@@ -3008,11 +3031,17 @@ gjs_ghr_helper(gpointer key, gpointer val, gpointer user_data) {
&key_arg))
c->failed = true;
- if (!gjs_g_arg_release_internal(c->context, c->transfer,
- c->val_param_info,
- g_type_info_get_tag(c->val_param_info),
- &val_arg))
+ GITypeTag val_type = g_type_info_get_tag(c->val_param_info);
+ if (val_type == GI_TYPE_TAG_INT64 ||
+ val_type == GI_TYPE_TAG_UINT64 ||
+ val_type == GI_TYPE_TAG_FLOAT ||
+ val_type == GI_TYPE_TAG_DOUBLE) {
+ g_free(val_arg.v_pointer);
+ } else if (!gjs_g_arg_release_internal(c->context, c->transfer,
+ c->val_param_info, val_type,
+ &val_arg)) {
c->failed = true;
+ }
return true;
}
diff --git a/installed-tests/js/testGIMarshalling.js b/installed-tests/js/testGIMarshalling.js
index 70cc18b..afab8ac 100644
--- a/installed-tests/js/testGIMarshalling.js
+++ b/installed-tests/js/testGIMarshalling.js
@@ -266,6 +266,12 @@ function testGHashTable() {
1: '-1',
2: '-2',
};
+ const NUMBER_DICT = {
+ '-1': -0.1,
+ 0: 0,
+ 1: 0.1,
+ 2: 0.2,
+ };
const STRING_DICT_OUT = {
'-1': '1',
0: '0',
@@ -279,6 +285,20 @@ function testGHashTable() {
GIMarshallingTests.ghashtable_int_none_in(INT_DICT);
GIMarshallingTests.ghashtable_utf8_none_in(STRING_DICT);
+ GIMarshallingTests.ghashtable_double_in(NUMBER_DICT);
+ GIMarshallingTests.ghashtable_float_in(NUMBER_DICT);
+ GIMarshallingTests.ghashtable_int64_in({
+ '-1': -1,
+ 0: 0,
+ 1: 1,
+ 2: 0x100000000,
+ });
+ GIMarshallingTests.ghashtable_uint64_in({
+ '-1': 0x100000000,
+ 0: 0,
+ 1: 1,
+ 2: 2,
+ });
dictEquals(GIMarshallingTests.ghashtable_utf8_none_out(), STRING_DICT);
dictEquals(GIMarshallingTests.ghashtable_utf8_container_out(), STRING_DICT);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]