Hi Jeremy,

It seems like when `simple_setters_caller` calls `simple_setter_caller<void*>` 
this function calls 
`gi_marshalling_tests_properties_accessors_object_set_flags` with 
`arg->v_pointer` as the `some_flags` where `some_flags` is an `enum` and 
arg->v_pointer is of `void*` (Actually it's a gpointer but is getting casted to 
void*).

Memory of arg->v_pointer will look the following (arg is a union):

> (gdb) x/8bx &arg->v_pointer
> 0x3ffffff5170:  0x00    0x00    0x00    0x02    0x00    0x00    0x00    0x00

So, for a direct integer casting( `(int)arg->v_pointer` ) a big endian machine 
will take the last 4 bytes and hence will be 0.

`some_flags` gets written into the object and a GIArgument is reconstructed 
back in a later stage when the value is tried to retrieve through a getter in 
`prop_getter_impl`. The value is written to this GIArgument variable through 
`simple_getter_caller<void*>` where the value is inserted via `arg->v_pointer` 
which is of type `void*`.
At this point memory of arg->v_pointer will look like the following:

> (gdb) x/8bx &arg->v_pointer
> 0x3ffffff5288:  0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x02

Now this data is read back from this GIArgument variable at line no. 3336 of 
arg.cpp where `_gjs_enum_from_int` ultimately return `arg->v_int` which will be 
the first 4 bytes of `arg` and hence will be 0. When these 2 values are 
corrected at runtime through gdb, the GIMarshalling tests are passing.

In a little endian machine the first byte will hold `0x02` and this won't cause 
any of these issues. Even when we set `arg->v_pointer = 2`, in a little endian 
machine `arg->v_int` will be 2 but not in a big endian machine.

Hope this helps.

Thanks,
Pranav

Reply via email to