GNOME Bugzilla – Bug 581691
Improve support for integer types and arrays.
Last modified: 2009-05-18 17:19:50 UTC
We use a centralized function to convert all the machine-dependent integer types into explicitly-sized machine-independent types. This code should constant-fold nicely under optimization. We also remove some dead code involving type tags. We translate GType as an appropriately sized integer, to allow invocation of generic functions which take a GType parameter. We implement support for marshalling arrays of integer types from javascript to C code. Note that we don't check ranges here, we just use truncation, so it is the caller's responsibility to ensure that the input to a GI function is of appropriate magnitude. Test cases against the 'Everything' module show how this works. The second patch allows passing values into C functions which take arrays of small integers using the standard "one value per character" encoding of buffers as JavaScript strings. This is primarily useful for methods which take binary buffers as gint8* or uint8* (instead of char *). More test cases included to show how it works. Depends on the improvements to the Everything typelib in bug 581682.
Created attachment 134160 [details] [review] Improve-support-for-machine-dependent-integer-types.patch
Created attachment 134161 [details] [review] Allow-passing-a-JS-string-as-a-C-array-of-int8-uint8.patch
(In reply to comment #1) > Created an attachment (id=134160) [edit] > Improve-support-for-machine-dependent-integer-types.patch > I think this one changes how 64bit long are handled? They used to be converted to JS double (JS_ValueToNumber), now it seems we'd reach the g_assert_not_reached(); in gjs_array_to_intarray?
(In reply to comment #2) > Created an attachment (id=134161) [edit] > Allow-passing-a-JS-string-as-a-C-array-of-int8-uint8.patch > I think gjs_string_to_intarray should throw an exception when it fails Looks good to me otherwise
Pushed with an exception added to gjs_string_to_intarray jobi it looks like 64-bit long are still converted to double when standalone, it's just that they aren't handled in arrays?
havoc: i believe that's right, although I'm not certain that's the question jobi was asking. Jobi: I believe the assert_not_reached is in fact never reached; you'd never get there. I think you were concerned about: -#if (GLIB_SIZEOF_LONG == 8) - case GI_TYPE_TAG_ULONG: - case GI_TYPE_TAG_SIZE: -#endif case GI_TYPE_TAG_UINT64: { double v; if (!JS_ValueToNumber(context, value, &v)) @@ -644,6 +741,16 @@ gjs_value_to_g_argument(JSContext *context, } break; + case GI_TYPE_TAG_INT: + case GI_TYPE_TAG_UINT: + case GI_TYPE_TAG_LONG: + case GI_TYPE_TAG_ULONG: + case GI_TYPE_TAG_SIZE: + case GI_TYPE_TAG_SSIZE: + case GI_TYPE_TAG_GTYPE: + /* these types are converted by normalize_int_types */ + g_assert_not_reached(); but GI_TYPE_TAG_ULONG (etc) is never seen in that switch statement; normalize_int_types ensures that it would be converted to GI_TYPE_TAG_UINT32 or GI_TYPE_TAG_UINT64 as appropriate, so you'd never reach the g_assert_not_reached().
(In reply to comment #6) > havoc: i believe that's right, although I'm not certain that's the question > jobi was asking. Jobi: I believe the assert_not_reached is in fact never > reached; you'd never get there. I think you were concerned about: > > > -#if (GLIB_SIZEOF_LONG == 8) > - case GI_TYPE_TAG_ULONG: > - case GI_TYPE_TAG_SIZE: > -#endif > case GI_TYPE_TAG_UINT64: { > double v; > if (!JS_ValueToNumber(context, value, &v)) > @@ -644,6 +741,16 @@ gjs_value_to_g_argument(JSContext *context, > } > break; > > + case GI_TYPE_TAG_INT: > + case GI_TYPE_TAG_UINT: > + case GI_TYPE_TAG_LONG: > + case GI_TYPE_TAG_ULONG: > + case GI_TYPE_TAG_SIZE: > + case GI_TYPE_TAG_SSIZE: > + case GI_TYPE_TAG_GTYPE: > + /* these types are converted by normalize_int_types */ > + g_assert_not_reached(); > > but GI_TYPE_TAG_ULONG (etc) is never seen in that switch statement; > normalize_int_types ensures that it would be converted to GI_TYPE_TAG_UINT32 or > GI_TYPE_TAG_UINT64 as appropriate, so you'd never reach the > g_assert_not_reached(). > Yeah it's right, I somehow got confused by gjs_array_to_array not handling 64bit ints, but i think that's fine