Skip to content

WIP: Make tests pass on 64-bit big-endian architectures

Simon McVittie requested to merge wip/smcv/lp64be into master

This branch starts with @ptomato's changes from !417 (merged), then adds two commits from me:


  • arg: Fix GHashTable key marshalling on 64-bit big-endian

    Similar to the previous commit, it is not correct to write to arg->v_pointer and then have _g_type_info_argument_from_hash_pointer() read out a different member of the GIArgument union.

    This particular change fixes conversion of GHashTable<int, x> from GLib to JavaScript, part of #309 (closed).

  • function: Use GIArgument.v_int for enum and flags types

    set_return_ffi_arg_from_giargument() is called after gjs_value_to_g_argument(), which puts enum and flags values in GIArgument.v_int. If we don't read from GIArgment.v_int, the resulting type-punning can give us the wrong answer, and in particular does give the wrong answer in practice on big-endian LP64 architectures, where v_int occupies the same memory as the most significant half of v_long.

    This happened to work on ILP32 architectures becase v_int and v_long occupy the same memory there, and it also happened to work on little-endian LP64 architectures because v_int occupies the same memory as the least significant half of v_long, resulting in v_long being truncated to 32 bits, equivalent to it being cast to int.

    This is somewhat consistent with GObject-Introspection gi_type_info_extract_ffi_return_value() (which uses GIArgument.v_int32, which is the same thing as v_int in practice), but is notably not consistent with GValue (which uses GValue.data[0].v_long for enums and GValue.data[0].v_ulong for flags).


I also pushed the first of those commits to !417 (merged).

I wasn't sure whether the second commit is appropriate for !417 (merged) since it isn't really anything to do with marshalling stuffed pointers, but you're welcome to include it in !417 (merged) and close this MR if you think that's an acceptable stretch.

It does have the same high-level goal: reduce type-punning in GIArgument, so that we get the right answer on machines where the bits used to store an int do not coincide with the bits used to store the least-significant part of a long or pointer. (In practice that means 64-bit big-endian, and my concrete goal here is to get the tests passing on Debian's s390x port.)

Merge request reports