diff -up newer-but-still-old/gi/function.c.fix-ffi-on-big-endian newer-but-still-old/gi/function.c --- newer-but-still-old/gi/function.c.fix-ffi-on-big-endian 2011-11-28 15:24:07.453082729 -0600 +++ newer-but-still-old/gi/function.c 2011-11-29 12:25:58.317567749 -0600 @@ -166,6 +166,8 @@ gjs_callback_closure(ffi_cif *cif, int i, n_args, n_jsargs; jsval *jsargs, rval; GITypeInfo ret_type; + GITypeTag return_tag; + GArgument return_value; gboolean success = FALSE; trampoline = data; @@ -215,10 +217,55 @@ gjs_callback_closure(ffi_cif *cif, GJS_ARGUMENT_RETURN_VALUE, FALSE, TRUE, - result)) { + &return_value)) { goto out; } + return_tag = g_type_info_get_tag(&ret_type); + switch (return_tag) { + case GI_TYPE_TAG_INT8: + *(ffi_sarg *) result = (gint8) return_value.v_int8; + case GI_TYPE_TAG_UINT8: + *(ffi_arg *) result = (guint8) return_value.v_uint8; + break; + case GI_TYPE_TAG_INT16: + *(ffi_sarg *) result = (gint16) return_value.v_int16; + break; + case GI_TYPE_TAG_UINT16: + *(ffi_arg *) result = (guint16) return_value.v_uint16; + break; + case GI_TYPE_TAG_INT32: + *(ffi_sarg *) result = (gint32) return_value.v_int32; + break; + case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_BOOLEAN: + case GI_TYPE_TAG_UNICHAR: + *(ffi_arg *) result = (guint32) return_value.v_uint32; + + break; + case GI_TYPE_TAG_INTERFACE: + { + GIBaseInfo* interface_info; + GIInfoType interface_type; + + interface_info = g_type_info_get_interface(&ret_type); + interface_type = g_base_info_get_type(interface_info); + + switch (interface_type) { + case GI_INFO_TYPE_ENUM: + case GI_INFO_TYPE_FLAGS: + *(ffi_sarg *) result = (gint32) return_value.v_long; + break; + default: + *(ffi_arg *) result = (ffi_arg) return_value.v_pointer; + break; + } + } + default: + *(ffi_arg *) result = (ffi_arg) return_value.v_pointer; + break; + } + success = TRUE; out: @@ -673,6 +720,50 @@ gjs_invoke_c_function(JSContext *co g_assert_cmpuint(next_rval, <, function->js_out_argc); + switch (return_tag) { + case GI_TYPE_TAG_INT8: + return_value.v_int8 = (gint8) return_value.v_long; + case GI_TYPE_TAG_UINT8: + return_value.v_uint8 = (guint8) return_value.v_ulong; + break; + case GI_TYPE_TAG_INT16: + return_value.v_int16 = (gint16) return_value.v_long; + break; + case GI_TYPE_TAG_UINT16: + return_value.v_uint16 = (guint16) return_value.v_ulong; + break; + case GI_TYPE_TAG_INT32: + return_value.v_int32 = (gint32) return_value.v_long; + break; + case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_BOOLEAN: + case GI_TYPE_TAG_UNICHAR: + return_value.v_uint32 = (guint32) return_value.v_ulong; + + break; + case GI_TYPE_TAG_INTERFACE: + { + GIBaseInfo* interface_info; + GIInfoType interface_type; + + interface_info = g_type_info_get_interface(&return_info); + interface_type = g_base_info_get_type(interface_info); + + + switch(interface_type) { + case GI_INFO_TYPE_ENUM: + case GI_INFO_TYPE_FLAGS: + return_value.v_int32 = (gint32) return_value.v_long; + break; + default: + break; + } + } + break; + default: + break; + } + array_length_pos = g_type_info_get_array_length(&return_info); if (array_length_pos >= 0) { GIArgInfo array_length_arg;