[gjs/wip/smcv/lp64be] function: Use GIArgument.v_int for enum and flags types



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]