@@ -324,11 +324,32 @@ callable_allocate (lua_State *L, int nargs, ffi_type ***ffi_args)
324324 return callable ;
325325}
326326
327+ static Param *
328+ callable_get_param (Callable * callable , gint n )
329+ {
330+ Param * param ;
331+
332+ if (n < 0 || n >= callable -> nargs )
333+ return NULL ;
334+
335+ param = & callable -> params [n ];
336+ if (!param -> has_arg_info )
337+ {
338+ /* Ensure basic fields are initialized. */
339+ g_callable_info_load_arg (callable -> info , n , & param -> ai );
340+ param -> has_arg_info = TRUE;
341+ param -> ti = g_arg_info_get_type (& param -> ai );
342+ param -> dir = g_arg_info_get_direction (& param -> ai );
343+ param -> transfer = g_arg_info_get_ownership_transfer (& param -> ai );
344+ }
345+ return param ;
346+ }
347+
327348int
328349lgi_callable_create (lua_State * L , GICallableInfo * info , gpointer addr )
329350{
330351 Callable * callable ;
331- Param * param ;
352+ Param * param , * data_param ;
332353 ffi_type * * ffi_arg , * * ffi_args ;
333354 ffi_type * ffi_retval ;
334355 gint nargs , argi , arg ;
@@ -377,32 +398,32 @@ lgi_callable_create (lua_State *L, GICallableInfo *info, gpointer addr)
377398 * ffi_arg ++ = & ffi_type_pointer ;
378399
379400 /* Process the rest of the arguments. */
380- param = & callable -> params [0 ];
381- for (argi = 0 ; argi < nargs ; argi ++ , param ++ , ffi_arg ++ )
401+ for (argi = 0 ; argi < nargs ; argi ++ , ffi_arg ++ )
382402 {
383- g_callable_info_load_arg (callable -> info , argi , & param -> ai );
384- param -> has_arg_info = TRUE;
385- param -> ti = g_arg_info_get_type (& param -> ai );
386- param -> dir = g_arg_info_get_direction (& param -> ai );
387- param -> transfer = g_arg_info_get_ownership_transfer (& param -> ai );
403+ param = callable_get_param (callable , argi );
388404 * ffi_arg = (param -> dir == GI_DIRECTION_IN )
389405 ? get_ffi_type (param ) : & ffi_type_pointer ;
390406
391- /* Mark closure-related user_data fields and possibly destroy_notify
392- fields as internal. */
407+ /* Mark closure-related user_data fields as internal. */
393408 arg = g_arg_info_get_closure (& param -> ai );
394- if (arg >= 0 && arg < nargs )
409+ data_param = callable_get_param (callable , arg );
410+ /* `arg` is defined also on callbacks, so check for invalid scope
411+ to avoid setting the internal flag on them. */
412+ if (data_param != NULL && g_arg_info_get_scope (& data_param -> ai ) == GI_SCOPE_TYPE_INVALID )
395413 {
396- callable -> params [ arg ]. internal = TRUE;
414+ data_param -> internal = TRUE;
397415 if (arg == argi )
398- callable -> params [ arg ]. internal_user_data = TRUE;
399- callable -> params [ arg ]. n_closures ++ ;
416+ data_param -> internal_user_data = TRUE;
417+ data_param -> n_closures ++ ;
400418 if (g_arg_info_get_scope (& param -> ai ) == GI_SCOPE_TYPE_CALL )
401- callable -> params [ arg ]. call_scoped_user_data = TRUE;
419+ data_param -> call_scoped_user_data = TRUE;
402420 }
421+
422+ /* Mark destroy_notify fields as internal. */
403423 arg = g_arg_info_get_destroy (& param -> ai );
404- if (arg > 0 && arg < nargs )
405- callable -> params [arg ].internal = TRUE;
424+ data_param = callable_get_param (callable , arg );
425+ if (data_param != NULL )
426+ data_param -> internal = TRUE;
406427
407428 /* Similarly for array length field. */
408429 callable_mark_array_length (callable , param -> ti );
0 commit comments