[gjs/wip/smcv/lp64be] function: Use GIArgument.v_int for enum and flags types
- From: Simon McVittie <smcv src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/wip/smcv/lp64be] function: Use GIArgument.v_int for enum and flags types
- Date: Tue, 7 Apr 2020 18:26:14 +0000 (UTC)
commit 1ba19d63f2d7c5a26a89326bbd398580b064516d
Author: Simon McVittie <smcv debian org>
Date: Tue Apr 7 19:23:46 2020 +0100
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).
Signed-off-by: Simon McVittie <smcv debian org>
gi/function.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
---
diff --git a/gi/function.cpp b/gi/function.cpp
index 34e9a7ae..038dffa1 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -153,7 +153,7 @@ set_return_ffi_arg_from_giargument (GITypeInfo *ret_type,
if (interface_type == GI_INFO_TYPE_ENUM ||
interface_type == GI_INFO_TYPE_FLAGS)
- *(ffi_sarg *) result = return_value->v_long;
+ *(ffi_sarg *) result = return_value->v_int;
else
*(ffi_arg *) result = (ffi_arg) return_value->v_pointer;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]