2016-04-21 15:19:32 +03:00
# include < stdint . h >
# include < stdio . h >
# include < objc / objc . h >
# include < objc / runtime . h >
# include < objc / message . h >
# include "xamarin/xamarin.h"
# include "runtime-internal.h"
# include "trampolines-internal.h"
# include "slinked-list.h"
# include "delegates.h"
2017-02-20 21:29:56 +03:00
# include "product.h"
2016-04-21 15:19:32 +03:00
2021-04-27 15:59:03 +03:00
# if defined ( CORECLR_RUNTIME )
# define ADD_TO _MONOOBJECT _RELEASE _LIST ( item ) release_list = s_list _prepend ( release_list , item )
# else
# define ADD_TO _MONOOBJECT _RELEASE _LIST ( item )
# endif
2021-02-11 10:18:38 +03:00
static GCHandle
xamarin_get _exception _for _method ( int code , GCHandle inner_exception _gchandle , const char * reason , SEL sel , id self )
2019-04-26 12:16:23 +03:00
{
2021-02-11 10:18:38 +03:00
GCHandle exception_gchandle = INVALID_GCHANDLE ;
2019-04-26 12:16:23 +03:00
char * msg = xamarin_strdup _printf ( "%s\n"
"Additional information:\n"
"\tSelector: %s\n"
"\tType: %s\n" , reason , sel_getName ( sel ) , class_getName ( [ self class ] ) ) ;
exception_gchandle = xamarin_create _product _exception _with _inner _exception ( code , inner_exception _gchandle , msg ) ;
xamarin_free ( msg ) ;
return exception_gchandle ;
}
2021-02-11 10:18:38 +03:00
GCHandle
xamarin_get _exception _for _parameter ( int code , GCHandle inner_exception _gchandle , const char * reason , SEL sel , MonoMethod * method , MonoType * p , int i , bool to_managed )
2019-04-26 12:16:23 +03:00
{
2021-02-11 10:18:38 +03:00
GCHandle exception_gchandle = INVALID_GCHANDLE ;
2019-04-26 12:16:23 +03:00
char * to_name = xamarin_type _get _full _name ( p , & exception_gchandle ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2019-04-26 12:16:23 +03:00
return exception_gchandle ;
char * method_full _name = mono_method _full _name ( method , TRUE ) ;
char * msg = xamarin_strdup _printf ( "%s #%i whose managed type is '%s' %s.\n"
"Additional information:\n"
"\tSelector: %s\n"
"\tMethod: %s\n" , reason , i + 1 , to_name , to_managed ? "to managed" : "to Objective-C" , sel_getName ( sel ) , method_full _name ) ;
exception_gchandle = xamarin_create _product _exception _with _inner _exception ( code , inner_exception _gchandle , msg ) ;
xamarin_free ( msg ) ;
xamarin_free ( to_name ) ;
xamarin_free ( method_full _name ) ;
return exception_gchandle ;
}
2019-03-19 20:31:10 +03:00
NSString *
xamarin_string _to _nsstring ( MonoString * obj , bool retain )
{
if ( obj = = NULL )
return NULL ;
2021-03-16 17:23:58 +03:00
char * str = mono_string _to _utf8 ( obj ) ;
2019-03-19 20:31:10 +03:00
NSString * arg ;
if ( retain ) {
arg = [ [ NSString alloc ] initWithUTF8String : str ] ;
} else {
arg = [ NSString stringWithUTF8String : str ] ;
}
mono_free ( str ) ;
return arg ;
}
2019-03-19 20:34:55 +03:00
MonoString *
xamarin_nsstring _to _string ( MonoDomain * domain , NSString * obj )
{
if ( obj = = NULL )
return NULL ;
if ( domain = = NULL )
domain = mono_domain _get ( ) ;
return mono_string _new ( domain , [ obj UTF8String ] ) ;
}
2016-04-21 15:19:32 +03:00
void
xamarin_invoke _trampoline ( enum TrampolineType type , id self , SEL sel , iterator_func iterator , marshal_return _value _func marshal_return _value , void * context )
{
2016-02-15 21:02:14 +03:00
// COOP : No managed data in input , but accesses managed data .
// COOP : FIXME : This method needs a lot of work when the runtime team
// implements a handle api for mono objects .
// Random notes :
// * Must switch to SAFE mode when calling any external code .
// * mono_runtime _invoke will have to change , since ' out / ref '
// objects arguments are now put into the arg_ptrs array
// ( clearly not GC - safe upon return ) .
2016-05-16 20:30:58 +03:00
MONO_ASSERT _GC _SAFE _OR _DETACHED ;
2016-02-15 21:02:14 +03:00
2016-05-11 14:27:51 +03:00
MonoObject * exception = NULL ;
2016-10-28 20:07:01 +03:00
MonoObject * * exception_ptr = xamarin_is _managed _exception _marshaling _disabled ( ) ? NULL : & exception ;
2021-02-11 10:18:38 +03:00
GCHandle exception_gchandle = INVALID_GCHANDLE ;
2016-04-21 15:19:32 +03:00
bool is_static = ( type & Tramp_Static ) = = Tramp_Static ;
bool is_ctor = type = = Tramp_Ctor ;
2016-06-02 13:18:45 +03:00
const char * ret_type = NULL ;
2021-05-31 09:02:45 +03:00
MonoType * sig_ret _type = NULL ;
2016-04-21 15:19:32 +03:00
if ( is_ctor ) {
2016-06-02 13:18:45 +03:00
bool has_nsobject = xamarin_has _nsobject ( self , & exception_gchandle ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE ) {
2016-06-02 13:18:45 +03:00
xamarin_process _managed _exception _gchandle ( exception_gchandle ) ;
return ; // we shouldn ' t get here .
}
if ( has_nsobject ) {
2024-05-20 19:57:42 +03:00
if ( strchr ( sel_getName ( sel ) , ' : ' ) ! = NULL ) {
char * msg = xamarin_strdup _printf ( "The dynamic registrar does not support calling base Objective-C constructors with arguments (type: %s, selector: %s). Please use any of the static registrars." , class_getName ( [ self class ] ) , sel_getName ( sel ) ) ;
exception_gchandle = xamarin_create _product _exception ( 8058 , msg ) ;
xamarin_free ( msg ) ;
xamarin_process _managed _exception _gchandle ( exception_gchandle ) ;
return ;
}
2016-04-21 15:19:32 +03:00
self = xamarin_invoke _objc _method _implementation ( self , sel , ( IMP ) xamarin_ctor _trampoline ) ;
2019-11-14 16:50:34 +03:00
marshal_return _value ( context , "|" , __SIZEOF _POINTER __ , self , NULL , false , NULL , NULL , & exception_gchandle ) ;
2016-06-02 13:18:45 +03:00
xamarin_process _managed _exception _gchandle ( exception_gchandle ) ;
2016-04-21 15:19:32 +03:00
return ;
}
}
2016-05-16 20:31:56 +03:00
MONO_THREAD _ATTACH ; // COOP : This will swith to GC_UNSAFE
2016-02-15 21:02:14 +03:00
2019-04-23 08:30:46 +03:00
MonoDomain * domain = mono_domain _get ( ) ;
2016-04-21 15:19:32 +03:00
// pre - prolog
SList * dispose_list = NULL ;
2017-07-03 20:18:02 +03:00
SList * free_list = NULL ;
2021-04-27 15:59:03 +03:00
SList * release_list = NULL ; // list of MonoObject * ' s to release at the end .
2019-11-05 19:00:14 +03:00
unsigned long num_arg ;
unsigned long managed_arg _count ;
2016-04-21 15:19:32 +03:00
NSMethodSignature * sig ;
if ( is_static ) {
sig = [ NSMethodSignature signatureWithObjCTypes : method_getTypeEncoding ( class_getClassMethod ( self , sel ) ) ] ;
} else {
sig = [ self methodSignatureForSelector : sel ] ;
}
num_arg = [ sig numberOfArguments ] - 2 ;
// prolog
MonoObject * mthis = NULL ;
2017-07-03 20:18:02 +03:00
MethodDescription * desc = NULL ;
2016-06-02 13:18:45 +03:00
MonoMethod * method ;
2021-05-06 17:19:59 +03:00
MonoMethodSignature * msig = NULL ;
2021-04-27 15:59:03 +03:00
MonoReflectionMethod * reflection_method = NULL ;
2016-06-02 13:18:45 +03:00
int semantic ;
bool isCategoryInstance ;
2016-04-21 15:19:32 +03:00
// setup callstack
2019-11-05 19:00:14 +03:00
unsigned long frame_length ;
2016-06-02 13:18:45 +03:00
void * * arg_frame ;
void * * arg_ptrs ;
2019-04-24 10:31:37 +03:00
void * * arg_copy = NULL ; // used to detect if ref / out parameters were changed .
bool * writeback = NULL ; // used to detect if a particular parameter is ref / out parameter .
2016-04-21 15:19:32 +03:00
void * iter = NULL ;
2019-04-24 10:31:37 +03:00
gboolean needs_writeback = FALSE ; // determines if there are any ref / out parameters .
2016-04-21 15:19:32 +03:00
MonoType * p ;
int ofs ;
2019-11-05 19:00:14 +03:00
unsigned long i ;
2019-11-14 13:44:51 +03:00
unsigned long mofs = 0 ;
2016-04-21 15:19:32 +03:00
2019-11-05 19:00:14 +03:00
unsigned long desc_arg _count = num_arg + 2 ; / * 1 for the return value + 1 if this is a category instance method * /
2017-07-03 20:18:02 +03:00
size_t desc_size = desc_arg _count * sizeof ( BindAsData ) + sizeof ( MethodDescription ) ;
desc = ( MethodDescription * ) xamarin_calloc ( desc_size ) ;
2019-11-05 19:00:14 +03:00
desc -> bindas_count = ( int32_t ) desc_arg _count ;
2017-07-03 20:18:02 +03:00
free_list = s_list _prepend ( free_list , desc ) ;
2016-09-30 22:02:17 +03:00
if ( is_ctor || is_static ) {
2017-09-22 11:23:37 +03:00
xamarin_get _method _for _selector ( [ self class ] , sel , is_static , desc , & exception_gchandle ) ;
2016-06-02 13:18:45 +03:00
} else {
2020-05-04 12:08:29 +03:00
GCHandle mthis_handle = INVALID_GCHANDLE ;
xamarin_get _method _and _object _for _selector ( [ self class ] , sel , is_static , self , & mthis_handle , desc , & exception_gchandle ) ;
mthis = xamarin_gchandle _get _target ( mthis_handle ) ;
2021-04-27 15:59:03 +03:00
ADD_TO _MONOOBJECT _RELEASE _LIST ( mthis ) ;
2020-05-04 12:08:29 +03:00
xamarin_gchandle _free ( mthis_handle ) ;
2016-06-02 13:18:45 +03:00
}
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE ) {
2019-04-26 12:16:23 +03:00
exception_gchandle = xamarin_get _exception _for _method ( 8034 , exception_gchandle , "Failed to lookup the required marshalling information." , sel , self ) ;
2016-06-02 13:18:45 +03:00
goto exception_handling ;
2019-04-26 12:16:23 +03:00
}
2016-06-02 13:18:45 +03:00
2021-04-27 15:59:03 +03:00
reflection_method = ( MonoReflectionMethod * ) xamarin_gchandle _get _target ( desc -> method_handle ) ;
ADD_TO _MONOOBJECT _RELEASE _LIST ( reflection_method ) ;
method = xamarin_get _reflection _method _method ( reflection_method ) ;
2021-04-30 08:49:25 +03:00
ADD_TO _MONOOBJECT _RELEASE _LIST ( method ) ;
2016-06-02 13:18:45 +03:00
msig = mono_method _signature ( method ) ;
2017-07-03 20:18:02 +03:00
semantic = desc -> semantic & ArgumentSemanticMask ;
isCategoryInstance = ( desc -> semantic & ArgumentSemanticCategoryInstance ) = = ArgumentSemanticCategoryInstance ;
2016-06-02 13:18:45 +03:00
frame_length = [ sig frameLength ] - ( sizeof ( void * ) * ( isCategoryInstance ? 1 : 2 ) ) ;
arg_frame = ( void * * ) alloca ( frame_length ) ;
2019-04-24 10:31:37 +03:00
managed_arg _count = num_arg + ( isCategoryInstance ? 1 : 0 ) ;
arg_ptrs = ( void * * ) alloca ( sizeof ( void * ) * managed_arg _count ) ;
2016-06-02 13:18:45 +03:00
2016-04-21 15:19:32 +03:00
# ifdef TRACE
memset ( arg_ptrs , 0 xDEADF00D , num_arg * sizeof ( void * ) ) ;
# endif
if ( isCategoryInstance ) {
// we know this must be an id
p = mono_signature _get _params ( msig , & iter ) ;
2021-05-31 09:02:45 +03:00
ADD_TO _MONOOBJECT _RELEASE _LIST ( p ) ;
2021-04-27 15:59:03 +03:00
MonoObject * catobj = xamarin_get _nsobject _with _type _for _ptr ( self , false , p , & exception_gchandle ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE ) {
2019-04-26 12:16:23 +03:00
exception_gchandle = xamarin_get _exception _for _parameter ( 8029 , exception_gchandle , "Unable to marshal the parameter" , sel , method , p , 0 , true ) ;
2016-06-02 13:18:45 +03:00
goto exception_handling ;
2019-04-26 12:16:23 +03:00
}
2021-04-27 15:59:03 +03:00
arg_ptrs [ 0 ] = catobj ;
ADD_TO _MONOOBJECT _RELEASE _LIST ( catobj ) ;
2016-04-21 15:19:32 +03:00
mofs = 1 ;
}
2016-06-02 13:18:45 +03:00
iterator ( IteratorStart , context , NULL , 0 , NULL , & exception_gchandle ) ; // start
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2016-06-02 13:18:45 +03:00
goto exception_handling ;
2016-04-21 15:19:32 +03:00
for ( i = 0 , ofs = 0 ; i < num_arg ; i + + ) {
const char * type = xamarin_skip _encoding _flags ( [ sig getArgumentTypeAtIndex : ( i + 2 ) ] ) ;
2019-10-30 22:58:13 +03:00
unsigned long size = xamarin_objc _type _size ( type ) ;
2016-04-21 15:19:32 +03:00
int frameofs = ofs ;
p = mono_signature _get _params ( msig , & iter ) ;
2021-05-31 09:02:45 +03:00
ADD_TO _MONOOBJECT _RELEASE _LIST ( p ) ;
2016-04-21 15:19:32 +03:00
# if __SIZEOF _POINTER __ = = 4
if ( * type = = ' i ' || * type = = ' I ' ) {
// this might be a [ Native ] enum , in which case managed code expects a 64 - bit value .
MonoClass * p_klass = mono_class _from _mono _type ( p ) ;
2021-05-07 16:47:03 +03:00
bool is_native _enum = mono_class _is _enum ( p_klass ) && mono_class _value _size ( p_klass , NULL ) = = 8 ;
xamarin_mono _object _release ( & p_klass ) ;
if ( is_native _enum ) {
2016-04-21 15:19:32 +03:00
// Don ' t bother checking for the attribute ( it ' s quite expensive ) ,
// just check whether managed code expects a 64 - bit value and assume
// we end up in this condition because it ' s a [ Native ] enum .
2016-06-02 13:18:45 +03:00
iterator ( IteratorIterate , context , type , size , & arg_frame [ ofs + + ] , & exception_gchandle ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2016-06-02 13:18:45 +03:00
goto exception_handling ;
2016-04-21 15:19:32 +03:00
arg_frame [ ofs + + ] = 0 ;
arg_ptrs [ i + mofs ] = & arg_frame [ frameofs ] ;
continue ;
}
}
# endif
if ( size > sizeof ( void * ) ) {
2016-06-02 13:18:45 +03:00
iterator ( IteratorIterate , context , type , size , & arg_frame [ ofs ] , & exception_gchandle ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2016-06-02 13:18:45 +03:00
goto exception_handling ;
2016-04-21 15:19:32 +03:00
ofs + = size / sizeof ( void * ) ;
arg_ptrs [ i + mofs ] = & arg_frame [ frameofs ] ;
} else {
void * arg ;
2016-06-02 13:18:45 +03:00
iterator ( IteratorIterate , context , type , size , & arg , & exception_gchandle ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2016-06-02 13:18:45 +03:00
goto exception_handling ;
2020-05-04 12:08:47 +03:00
if ( desc -> bindas [ i + 1 ] . original_type _handle ! = INVALID_GCHANDLE ) {
MonoReflectionType * original_type = ( MonoReflectionType * ) xamarin_gchandle _get _target ( desc -> bindas [ i + 1 ] . original_type _handle ) ;
2021-04-27 15:59:03 +03:00
ADD_TO _MONOOBJECT _RELEASE _LIST ( original_type ) ;
2021-05-13 00:37:40 +03:00
MonoType * original_mono _type = mono_reflection _type _get _type ( original_type ) ;
ADD_TO _MONOOBJECT _RELEASE _LIST ( original_mono _type ) ;
arg_ptrs [ i + mofs ] = xamarin_generate _conversion _to _managed ( ( id ) arg , original_mono _type , p , method , & exception_gchandle , ( void * ) INVALID_TOKEN _REF , ( void * * ) & free_list , ( void * * ) & release_list ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2017-07-03 20:18:02 +03:00
goto exception_handling ;
ofs + + ;
continue ;
}
2016-04-21 15:19:32 +03:00
switch ( type [ 0 ] ) {
case _C _PTR : {
switch ( type [ 1 ] ) {
2019-04-23 09:03:28 +03:00
case _C _CLASS :
case _C _SEL :
2016-04-21 15:19:32 +03:00
case _C _ID : {
MonoClass * p_klass = mono_class _from _mono _type ( p ) ;
2021-05-07 16:47:03 +03:00
ADD_TO _MONOOBJECT _RELEASE _LIST ( p_klass ) ;
2016-06-02 13:18:45 +03:00
if ( ! mono_type _is _byref ( p ) ) {
2021-05-19 08:34:13 +03:00
GCHandle ex_handle = xamarin_create _runtime _exception ( 8040 , "Invalid type encoding for parameter" , & exception_gchandle ) ;
if ( exception_gchandle = = INVALID_GCHANDLE )
exception_gchandle = ex_handle ;
2016-06-02 13:18:45 +03:00
goto exception_handling ;
}
2021-05-11 08:21:18 +03:00
MonoReflectionMethod * rmethod = mono_method _get _object ( domain , method , NULL ) ;
bool is_parameter _out = xamarin_is _parameter _out ( rmethod , ( int ) i , & exception_gchandle ) ;
ADD_TO _MONOOBJECT _RELEASE _LIST ( rmethod ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2016-06-02 13:18:45 +03:00
goto exception_handling ;
2019-04-24 10:31:37 +03:00
if ( ! needs_writeback ) {
2016-04-21 15:19:32 +03:00
needs_writeback = TRUE ;
2019-04-24 10:31:37 +03:00
arg_copy = ( void * * ) calloc ( managed_arg _count , sizeof ( void * ) ) ;
writeback = ( bool * ) calloc ( managed_arg _count , sizeof ( bool ) ) ;
2019-10-25 22:49:22 +03:00
if ( ! arg_copy || ! writeback ) {
exception = ( MonoObject * ) mono_get _exception _out _of _memory ( ) ;
goto exception_handling ;
}
2019-04-24 10:31:37 +03:00
}
arg_frame [ ofs ] = NULL ;
arg_ptrs [ i + mofs ] = & arg_frame [ frameofs ] ;
writeback [ i + mofs ] = TRUE ;
if ( is_parameter _out ) {
2016-04-21 15:19:32 +03:00
LOGZ ( " argument %i is an out parameter. Passing in a pointer to a NULL value.\n" , i + 1 ) ;
2019-04-24 10:31:37 +03:00
if ( arg ! = NULL ) {
// Write NULL to the argument we got right away . Managed code might not write to it ( or write NULL ) ,
// in which case our code to detect if the value changed will say it didn ' t and not copy it back .
* ( NSObject * * ) arg = NULL ;
}
2019-03-19 21:14:55 +03:00
} else if ( xamarin_is _class _nsobject ( p_klass ) ) {
2021-04-27 15:59:03 +03:00
MonoObject * mobj = xamarin_get _nsobject _with _type _for _ptr (*(NSObject **) arg , false , p , & exception_gchandle ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE ) {
2019-12-12 06:17:29 +03:00
exception_gchandle = xamarin_get _exception _for _parameter ( 8029 , exception_gchandle , "Unable to marshal the byref parameter" , sel , method , p , ( int ) i , true ) ;
2016-06-02 13:18:45 +03:00
goto exception_handling ;
2016-04-21 15:19:32 +03:00
}
2021-04-27 15:59:03 +03:00
arg_frame [ ofs ] = mobj ;
ADD_TO _MONOOBJECT _RELEASE _LIST ( mobj ) ;
2019-03-19 21:18:15 +03:00
LOGZ ( " argument %i is a ref NSObject parameter: %p = %p\n" , i + 1 , arg , arg_frame [ ofs ] ) ;
2019-04-23 09:03:28 +03:00
} else if ( xamarin_is _class _inativeobject ( p_klass ) ) {
2021-05-10 16:38:13 +03:00
MonoReflectionType * reflectionp = mono_type _get _object ( domain , p ) ;
ADD_TO _MONOOBJECT _RELEASE _LIST ( reflectionp ) ;
MonoObject * mobj = xamarin_get _inative _object _dynamic (*(NSObject **) arg , false , reflectionp , & exception_gchandle ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2019-04-23 09:03:28 +03:00
goto exception_handling ;
2021-04-27 15:59:03 +03:00
arg_frame [ ofs ] = mobj ;
ADD_TO _MONOOBJECT _RELEASE _LIST ( mobj ) ;
2019-04-23 09:03:28 +03:00
LOGZ ( " argument %i is a ref ptr/INativeObject %p: %p\n" , i + 1 , arg , arg_frame [ ofs ] ) ;
2021-05-11 00:12:52 +03:00
} else if ( xamarin_is _class _string ( p_klass ) ) {
2021-04-27 15:59:03 +03:00
MonoString * mstr = xamarin_nsstring _to _string ( domain , * ( NSString * * ) arg ) ;
arg_frame [ ofs ] = mstr ;
ADD_TO _MONOOBJECT _RELEASE _LIST ( mstr ) ;
2019-04-23 09:08:13 +03:00
LOGZ ( " argument %i is a ref NSString %p: %p\n" , i + 1 , arg , arg_frame [ ofs ] ) ;
2019-04-23 09:10:12 +03:00
} else if ( xamarin_is _class _array ( p_klass ) ) {
2021-05-12 16:21:56 +03:00
MonoArray * array_arg = xamarin_nsarray _to _managed _array (*(NSArray **) arg , p , p_klass , & exception_gchandle ) ;
arg_frame [ ofs ] = array_arg ;
ADD_TO _MONOOBJECT _RELEASE _LIST ( array_arg ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE ) {
2019-12-12 06:17:29 +03:00
exception_gchandle = xamarin_get _exception _for _parameter ( 8029 , exception_gchandle , "Unable to marshal the byref parameter" , sel , method , p , ( int ) i , true ) ;
2019-04-23 09:10:12 +03:00
goto exception_handling ;
}
LOGZ ( " argument %i is ref NSArray (%p => %p => %p)\n" , i + 1 , arg , * ( NSArray * * ) arg , arg_frame [ ofs ] ) ;
2019-03-19 21:14:55 +03:00
} else {
2019-12-12 06:17:29 +03:00
exception_gchandle = xamarin_get _exception _for _parameter ( 8029 , 0 , "Unable to marshal the byref parameter" , sel , method , p , ( int ) i , true ) ;
2019-03-19 21:14:55 +03:00
goto exception_handling ;
2016-04-21 15:19:32 +03:00
}
2019-04-24 10:31:37 +03:00
arg_copy [ i + mofs ] = arg_frame [ ofs ] ;
LOGZ ( " argument %i's value: %p\n" , i + 1 , arg_copy [ i + mofs ] ) ;
2019-03-19 21:14:55 +03:00
break ;
2016-04-21 15:19:32 +03:00
}
case _C _PTR : {
if ( mono_type _is _byref ( p ) ) {
arg_ptrs [ i + mofs ] = arg ;
} else {
arg_frame [ ofs ] = arg ;
arg_ptrs [ i + mofs ] = & arg_frame [ frameofs ] ;
}
break ;
}
default : {
MonoClass * p_klass = mono_class _from _mono _type ( p ) ;
2021-05-07 16:47:03 +03:00
ADD_TO _MONOOBJECT _RELEASE _LIST ( p_klass ) ;
2016-04-21 15:19:32 +03:00
if ( mono_class _is _delegate ( p_klass ) ) {
2021-04-27 15:59:03 +03:00
MonoObject * del = xamarin_get _delegate _for _block _parameter ( method , INVALID_TOKEN _REF , ( int ) i , arg , & exception_gchandle ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2016-06-02 13:18:45 +03:00
goto exception_handling ;
2021-04-27 15:59:03 +03:00
arg_ptrs [ i + mofs ] = del ;
ADD_TO _MONOOBJECT _RELEASE _LIST ( del ) ;
2016-04-21 15:19:32 +03:00
} else if ( xamarin_is _class _inativeobject ( p_klass ) ) {
id id_arg = ( id ) arg ;
if ( semantic = = ArgumentSemanticCopy ) {
id_arg = [ id_arg copy ] ;
[ id_arg autorelease ] ;
}
MonoObject * obj ;
2021-05-10 16:38:13 +03:00
MonoReflectionType * reflectionp = mono_type _get _object ( domain , p ) ;
ADD_TO _MONOOBJECT _RELEASE _LIST ( reflectionp ) ;
obj = xamarin_get _inative _object _dynamic ( id_arg , false , reflectionp , & exception_gchandle ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2016-06-02 13:18:45 +03:00
goto exception_handling ;
2021-04-27 15:59:03 +03:00
ADD_TO _MONOOBJECT _RELEASE _LIST ( obj ) ;
2016-04-21 15:19:32 +03:00
LOGZ ( " argument %i is ptr/INativeObject %p: %p\n" , i + 1 , id_arg , obj ) ;
arg_ptrs [ i + mofs ] = obj ;
} else {
arg_frame [ ofs ] = arg ;
if ( mono_type _is _byref ( p ) ) {
arg_ptrs [ i + mofs ] = arg ;
} else if ( mono_class _is _valuetype ( p_klass ) ) {
arg_ptrs [ i + mofs ] = & arg_frame [ frameofs ] ;
} else {
arg_ptrs [ i + mofs ] = arg ;
}
}
break ;
}
}
break ;
}
case _C _CLASS : {
if ( ! arg ) {
arg_ptrs [ i + mofs ] = NULL ;
LOGZ ( " argument %i is Class: NULL\n" , i + 1 ) ;
break ;
} else {
2021-04-27 15:59:03 +03:00
MonoObject * mclass = xamarin_get _class ( ( Class ) arg , & exception_gchandle ) ;
arg_ptrs [ i + mofs ] = mclass ;
ADD_TO _MONOOBJECT _RELEASE _LIST ( mclass ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2016-06-02 13:18:45 +03:00
goto exception_handling ;
2016-04-21 15:19:32 +03:00
LOGZ ( " argument %i is Class: %p = %s\n" , i + 1 , arg , class_getName ( ( Class ) arg ) ) ;
break ;
}
}
case _C _SEL : {
if ( ! arg ) {
arg_ptrs [ i + mofs ] = NULL ;
LOGZ ( " argument %i is SEL: NULL\n" , i + 1 ) ;
break ;
} else {
2021-04-27 15:59:03 +03:00
MonoObject * msel = xamarin_get _selector ( ( SEL ) arg , & exception_gchandle ) ;
arg_ptrs [ i + mofs ] = msel ;
ADD_TO _MONOOBJECT _RELEASE _LIST ( msel ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2016-06-02 13:18:45 +03:00
goto exception_handling ;
2016-04-21 15:19:32 +03:00
LOGZ ( " argument %i is SEL: %p = %s\n" , i + 1 , arg , sel_getName ( ( SEL ) arg ) ) ;
break ;
}
}
case _C _CHARPTR : {
if ( ! arg ) {
arg_ptrs [ i + mofs ] = NULL ;
LOGZ ( " argument %i is char*: NULL\n" , i + 1 ) ;
break ;
} else {
2021-04-27 15:59:03 +03:00
MonoString * mstr = mono_string _new ( domain , ( const char * ) arg ) ;
arg_ptrs [ i + mofs ] = ( void * ) mstr ;
ADD_TO _MONOOBJECT _RELEASE _LIST ( mstr ) ;
2016-04-21 15:19:32 +03:00
LOGZ ( " argument %i is char*: %p = %s\n" , i + 1 , arg , arg ) ;
break ;
}
}
case _C _ID : {
id id_arg = ( id ) arg ;
2016-05-31 12:58:27 +03:00
MonoClass * p_klass = mono_class _from _mono _type ( p ) ;
2021-05-07 16:47:03 +03:00
ADD_TO _MONOOBJECT _RELEASE _LIST ( p_klass ) ;
2021-05-11 00:12:52 +03:00
if ( xamarin_is _class _intptr ( p_klass ) ) {
2016-05-31 12:58:27 +03:00
arg_frame [ ofs ] = id_arg ;
arg_ptrs [ i + mofs ] = & arg_frame [ frameofs ] ;
LOGZ ( " argument %i is IntPtr: %p\n" , i + 1 , id_arg ) ;
break ;
2021-11-17 12:30:52 +03:00
# if DOTNET
} else if ( xamarin_is _class _nativehandle ( p_klass ) ) {
arg_frame [ ofs ] = id_arg ;
arg_ptrs [ i + mofs ] = & arg_frame [ frameofs ] ;
LOGZ ( " argument %i is NativeHandle: %p\n" , i + 1 , id_arg ) ;
break ;
# endif
2016-05-31 12:58:27 +03:00
} else if ( ! id_arg ) {
2016-04-21 15:19:32 +03:00
arg_ptrs [ i + mofs ] = NULL ;
break ;
} else {
2021-05-11 00:12:52 +03:00
if ( xamarin_is _class _string ( p_klass ) ) {
2016-04-21 15:19:32 +03:00
NSString * str = ( NSString * ) id_arg ;
2021-04-27 15:59:03 +03:00
MonoString * mstr = xamarin_nsstring _to _string ( domain , str ) ;
arg_ptrs [ i + mofs ] = mstr ;
ADD_TO _MONOOBJECT _RELEASE _LIST ( mstr ) ;
2016-04-21 15:19:32 +03:00
LOGZ ( " argument %i is NSString: %p = %s\n" , i + 1 , id_arg , [ str UTF8String ] ) ;
} else if ( xamarin_is _class _array ( p_klass ) ) {
2021-05-12 16:21:56 +03:00
MonoArray * array_arg = xamarin_nsarray _to _managed _array ( ( NSArray * ) id_arg , p , p_klass , & exception_gchandle ) ;
arg_ptrs [ i + mofs ] = array_arg ;
ADD_TO _MONOOBJECT _RELEASE _LIST ( array_arg ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE ) {
2019-12-12 06:17:29 +03:00
exception_gchandle = xamarin_get _exception _for _parameter ( 8029 , exception_gchandle , "Unable to marshal the array parameter" , sel , method , p , ( int ) i , true ) ;
2019-04-22 18:50:38 +03:00
goto exception_handling ;
2016-04-21 15:19:32 +03:00
}
LOGZ ( " argument %i is NSArray\n" , i + 1 ) ;
} else if ( xamarin_is _class _nsobject ( p_klass ) ) {
if ( semantic = = ArgumentSemanticCopy ) {
id_arg = [ id_arg copy ] ;
[ id_arg autorelease ] ;
}
MonoObject * obj ;
int32_t created = false ;
2019-04-26 12:16:23 +03:00
obj = xamarin_get _nsobject _with _type _for _ptr _created ( id_arg , false , p , & created , & exception_gchandle ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE ) {
2019-12-12 06:17:29 +03:00
exception_gchandle = xamarin_get _exception _for _parameter ( 8029 , exception_gchandle , "Unable to marshal the parameter" , sel , method , p , ( int ) i , true ) ;
2016-06-02 13:18:45 +03:00
goto exception_handling ;
2019-04-26 12:16:23 +03:00
}
2021-04-27 15:59:03 +03:00
ADD_TO _MONOOBJECT _RELEASE _LIST ( obj ) ;
2016-04-21 15:19:32 +03:00
if ( created && obj ) {
2021-05-11 08:21:18 +03:00
MonoReflectionMethod * rmethod = mono_method _get _object ( domain , method , NULL ) ;
bool is_transient = xamarin_is _parameter _transient ( rmethod , ( int32_t ) i , & exception_gchandle ) ;
ADD_TO _MONOOBJECT _RELEASE _LIST ( rmethod ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2016-06-02 13:18:45 +03:00
goto exception_handling ;
2016-04-21 15:19:32 +03:00
if ( is_transient )
dispose_list = s_list _prepend ( dispose_list , obj ) ;
}
# if DEBUG
xamarin_verify _parameter ( obj , sel , self , id_arg , i , p_klass , method ) ;
# endif
LOGZ ( " argument %i is NSObject %p: %p\n" , i + 1 , id_arg , obj ) ;
arg_ptrs [ i + mofs ] = obj ;
} else if ( xamarin_is _class _inativeobject ( p_klass ) ) {
if ( semantic = = ArgumentSemanticCopy ) {
id_arg = [ id_arg copy ] ;
[ id_arg autorelease ] ;
}
MonoObject * obj ;
2021-05-10 16:38:13 +03:00
MonoReflectionType * reflectionp = mono_type _get _object ( domain , p ) ;
ADD_TO _MONOOBJECT _RELEASE _LIST ( reflectionp ) ;
obj = xamarin_get _inative _object _dynamic ( id_arg , false , reflectionp , & exception_gchandle ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2016-06-02 13:18:45 +03:00
goto exception_handling ;
2021-04-27 15:59:03 +03:00
ADD_TO _MONOOBJECT _RELEASE _LIST ( obj ) ;
2016-04-21 15:19:32 +03:00
LOGZ ( " argument %i is NSObject/INativeObject %p: %p\n" , i + 1 , id_arg , obj ) ;
arg_ptrs [ i + mofs ] = obj ;
} else if ( mono_class _is _delegate ( p_klass ) ) {
2021-04-27 15:59:03 +03:00
MonoObject * del = xamarin_get _delegate _for _block _parameter ( method , INVALID_TOKEN _REF , ( int ) i , id_arg , & exception_gchandle ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2016-06-02 13:18:45 +03:00
goto exception_handling ;
2021-04-27 15:59:03 +03:00
arg_ptrs [ i + mofs ] = del ;
ADD_TO _MONOOBJECT _RELEASE _LIST ( del ) ;
2016-04-21 15:19:32 +03:00
} else {
if ( semantic = = ArgumentSemanticCopy ) {
id_arg = [ id_arg copy ] ;
[ id_arg autorelease ] ;
}
MonoObject * obj ;
2019-04-26 12:16:23 +03:00
obj = xamarin_get _nsobject _with _type _for _ptr ( id_arg , false , p , & exception_gchandle ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2016-06-02 13:18:45 +03:00
goto exception_handling ;
2021-04-27 15:59:03 +03:00
ADD_TO _MONOOBJECT _RELEASE _LIST ( obj ) ;
2016-04-21 15:19:32 +03:00
# if DEBUG
xamarin_verify _parameter ( obj , sel , self , id_arg , i , p_klass , method ) ;
# endif
arg_ptrs [ i + mofs ] = obj ;
}
break ;
}
}
default :
arg_frame [ ofs ] = arg ;
arg_ptrs [ i + mofs ] = & arg_frame [ frameofs ] ;
break ;
}
ofs + + ;
}
}
2016-06-02 13:18:45 +03:00
iterator ( IteratorEnd , context , NULL , 0 , NULL , & exception_gchandle ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2016-06-02 13:18:45 +03:00
goto exception_handling ;
2016-04-21 15:19:32 +03:00
// invoke
MonoObject * retval ;
2022-03-05 07:00:52 +03:00
MonoObject * ctorval __attribute __ ( ( unused ) ) ;
2016-04-21 15:19:32 +03:00
if ( is_ctor ) {
/ *
* Some Objective - C classes overwrite retain , release ,
* retainCount and those methods are not operational
* until one of the init methods has been called
* ( CALayer for example ) . This means that the standard
* code path that we have to Retain in NSObject does not
* work for objects surfaced through xamarin_ctor _trampoline .
*
* To work around this , we will perform the retain here , after
* managed code has initialized the NSObject . To let managed
* code know to not invoke the Retain in InitializeObject we set
* the NativeRef flag on the object .
*
* This is checked by NSObject . InitializeObject and it
* instruct the method to not attempt to call ` retain '
* on the object
*
* Instead , when surfacing objects by
* xamarin_ctor _trampoline , we perform the retain on
* behalf of managed code here ( managed code owns one
* reference , and unmanaged code the other ) .
*
* This problem is documented in the following bug :
* https : // bugzilla . xamarin . com / show_bug . cgi ? id = 6556
* /
2021-04-30 08:53:30 +03:00
MonoClass * declaring_type = mono_method _get _class ( method ) ;
ADD_TO _MONOOBJECT _RELEASE _LIST ( declaring_type ) ;
retval = xamarin_new _nsobject ( self , declaring_type , & exception_gchandle ) ;
2021-03-16 09:40:19 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
goto exception_handling ;
2021-04-27 15:59:03 +03:00
ADD_TO _MONOOBJECT _RELEASE _LIST ( retval ) ;
2016-04-21 15:19:32 +03:00
2021-04-27 15:59:03 +03:00
ctorval = mono_runtime _invoke ( method , retval , ( void * * ) arg_ptrs , exception_ptr ) ;
2016-06-02 13:18:45 +03:00
if ( exception ! = NULL )
goto exception_handling ;
2021-04-27 15:59:03 +03:00
ADD_TO _MONOOBJECT _RELEASE _LIST ( ctorval ) ;
2016-04-21 15:19:32 +03:00
} else {
# ifdef TRACE
fprintf ( stderr , " calling managed method with %i arguments: " , num_arg ) ;
for ( int i = 0 ; i < num_arg ; i + + )
fprintf ( stderr , "%p " , arg_ptrs [ i ] ) ;
2019-04-24 10:31:37 +03:00
fprintf ( stderr , " writeback: %i" , needs_writeback ) ;
2016-04-21 15:19:32 +03:00
fprintf ( stderr , "\n" ) ;
# endif
2016-05-11 14:27:51 +03:00
retval = mono_runtime _invoke ( method , mthis , ( void * * ) arg_ptrs , exception_ptr ) ;
2016-04-21 15:19:32 +03:00
# ifdef TRACE
fprintf ( stderr , " called managed method with %i arguments: " , num_arg ) ;
for ( int i = 0 ; i < num_arg ; i + + )
fprintf ( stderr , "%p " , arg_ptrs [ i ] ) ;
2019-04-24 10:31:37 +03:00
fprintf ( stderr , " writeback: %i" , needs_writeback ) ;
2016-04-21 15:19:32 +03:00
fprintf ( stderr , "\n" ) ;
# endif
2016-06-02 13:18:45 +03:00
if ( exception ! = NULL )
goto exception_handling ;
2021-04-27 15:59:03 +03:00
ADD_TO _MONOOBJECT _RELEASE _LIST ( retval ) ;
2016-04-21 15:19:32 +03:00
}
// writeback
if ( needs_writeback ) {
iter = NULL ;
2016-06-02 13:18:45 +03:00
iterator ( IteratorStart , context , NULL , 0 , NULL , & exception_gchandle ) ; // start
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2016-06-02 13:18:45 +03:00
goto exception_handling ;
2019-03-19 21:05:50 +03:00
for ( i = 0 ; i < num_arg ; i + + ) {
2016-04-21 15:19:32 +03:00
const char * type = [ sig getArgumentTypeAtIndex : ( i + 2 ) ] ;
2019-09-04 17:02:33 +03:00
type = xamarin_skip _encoding _flags ( type ) ;
2019-10-30 22:58:13 +03:00
unsigned long size = xamarin_objc _type _size ( type ) ;
2016-04-21 15:19:32 +03:00
p = mono_signature _get _params ( msig , & iter ) ;
2021-05-31 09:02:45 +03:00
ADD_TO _MONOOBJECT _RELEASE _LIST ( p ) ;
2016-04-21 15:19:32 +03:00
2019-03-19 21:09:25 +03:00
// Skip over any structs . In any case they can ' t be write - back parameters .
// Also skip over anything we ' re not supposed to write back to .
bool skip = size > sizeof ( void * ) || ! writeback [ i + mofs ] ;
void * arg ;
iterator ( IteratorIterate , context , type , size , skip ? NULL : & arg , & exception_gchandle ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2019-03-19 21:09:25 +03:00
goto exception_handling ;
if ( skip ) {
LOGZ ( " skipping argument %i (size: %i, pointer: %p)\n" , i , size , arg_copy [ i + mofs ] ) ;
continue ;
}
if ( arg = = NULL ) {
LOGZ ( " not writing back to a null pointer\n" ) ;
continue ;
}
2019-04-23 09:03:28 +03:00
if ( type [ 0 ] = = _C _PTR && ( type [ 1 ] = = _C _ID || type [ 1 ] = = _C _SEL || type [ 1 ] = = _C _CLASS ) ) {
2019-03-19 21:09:25 +03:00
MonoClass * p_klass = mono_class _from _mono _type ( p ) ;
2021-05-07 16:47:03 +03:00
ADD_TO _MONOOBJECT _RELEASE _LIST ( p_klass ) ;
2019-03-19 21:09:25 +03:00
MonoObject * value = * ( MonoObject * * ) arg_ptrs [ i + mofs ] ;
MonoObject * pvalue = ( MonoObject * ) arg_copy [ i + mofs ] ;
NSObject * obj = NULL ;
2021-05-31 09:01:24 +03:00
ADD_TO _MONOOBJECT _RELEASE _LIST ( value ) ;
2019-03-19 21:09:25 +03:00
if ( value = = pvalue ) {
// No need to copy back if the value didn ' t change
2019-04-23 09:10:12 +03:00
// For arrays this means that we won ' t copy back arrays if an element in the array changed ( which can happen in managed code : the array pointer and size are immutable , but array elements can change ) .
// If the developer wants to change an array element , a new array must be created and assigned to the ref parameter .
// This is by design : otherwise we ' ll have to copy arrays even though they didn ' t change ( because we can ' t know if they changed without comparing every element ) .
2019-03-19 21:09:25 +03:00
LOGZ ( " not writing back managed object to argument at index %i (%p => %p) because it didn't change\n" , i , arg , value ) ;
continue ;
} else if ( value = = NULL ) {
LOGZ ( " writing back null to argument at index %i (%p)\n" , i + 1 , arg ) ;
2021-05-11 00:12:52 +03:00
} else if ( xamarin_is _class _string ( p_klass ) ) {
2019-03-19 21:09:25 +03:00
obj = xamarin_string _to _nsstring ( ( MonoString * ) value , false ) ;
LOGZ ( " writing back managed string %p to argument at index %i (%p)\n" , value , i + 1 , arg ) ;
} else if ( xamarin_is _class _nsobject ( p_klass ) ) {
obj = xamarin_get _handle ( value , & exception_gchandle ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2016-06-02 13:18:45 +03:00
goto exception_handling ;
2019-03-19 21:09:25 +03:00
LOGZ ( " writing back managed NSObject %p to argument at index %i (%p)\n" , value , i + 1 , arg ) ;
} else if ( xamarin_is _class _inativeobject ( p_klass ) ) {
obj = xamarin_get _handle _for _inativeobject ( value , & exception_gchandle ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2019-03-19 21:09:25 +03:00
goto exception_handling ;
LOGZ ( " writing back managed INativeObject %p to argument at index %i (%p)\n" , value , i + 1 , arg ) ;
2019-04-23 09:10:12 +03:00
} else if ( xamarin_is _class _array ( p_klass ) ) {
obj = xamarin_managed _array _to _nsarray ( ( MonoArray * ) value , p , p_klass , & exception_gchandle ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE ) {
2019-12-12 06:17:29 +03:00
exception_gchandle = xamarin_get _exception _for _parameter ( 8030 , exception_gchandle , "Unable to marshal the out/ref parameter" , sel , method , p , ( int ) i , false ) ;
2019-04-23 09:10:12 +03:00
goto exception_handling ;
}
LOGZ ( " writing back managed array %p to argument at index %i (%p)\n" , value , i + 1 , arg ) ;
2019-03-19 21:09:25 +03:00
} else {
2019-12-12 06:17:29 +03:00
exception_gchandle = xamarin_get _exception _for _parameter ( 8030 , 0 , "Unable to marshal the out/ref parameter" , sel , method , p , ( int ) i , false ) ;
2019-03-19 21:09:25 +03:00
goto exception_handling ;
2016-04-21 15:19:32 +03:00
}
2019-03-19 21:09:25 +03:00
* ( NSObject * * ) arg = obj ;
2019-03-19 21:10:40 +03:00
} else {
2019-12-12 06:17:29 +03:00
exception_gchandle = xamarin_get _exception _for _parameter ( 8030 , 0 , "Unable to marshal the out/ref parameter" , sel , method , p , ( int ) i , false ) ;
2019-03-19 21:10:40 +03:00
goto exception_handling ;
2016-04-21 15:19:32 +03:00
}
}
2016-06-02 13:18:45 +03:00
iterator ( IteratorEnd , context , NULL , 0 , NULL , & exception_gchandle ) ;
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE )
2016-06-02 13:18:45 +03:00
goto exception_handling ;
2016-04-21 15:19:32 +03:00
}
2016-06-02 13:18:45 +03:00
ret_type = [ sig methodReturnType ] ;
2016-04-21 15:19:32 +03:00
ret_type = xamarin_skip _encoding _flags ( ret_type ) ;
2021-05-31 09:02:45 +03:00
sig_ret _type = mono_signature _get _return _type ( msig ) ;
2016-04-21 15:19:32 +03:00
if ( is_ctor ) {
2021-05-31 09:02:45 +03:00
marshal_return _value ( context , "|" , __SIZEOF _POINTER __ , self , sig_ret _type , ( desc -> semantic & ArgumentSemanticRetainReturnValue ) ! = 0 , method , desc , & exception_gchandle ) ;
2016-04-21 15:19:32 +03:00
} else if ( * ret_type ! = ' v ' ) {
2021-05-31 09:02:45 +03:00
marshal_return _value ( context , ret_type , [ sig methodReturnLength ] , retval , sig_ret _type , ( desc -> semantic & ArgumentSemanticRetainReturnValue ) ! = 0 , method , desc , & exception_gchandle ) ;
2016-04-21 15:19:32 +03:00
}
2021-05-31 09:02:45 +03:00
xamarin_mono _object _release ( & sig_ret _type ) ;
2016-05-11 14:27:51 +03:00
2016-06-02 13:18:45 +03:00
exception_handling :
;
2016-05-16 20:31:56 +03:00
2017-02-20 21:29:56 +03:00
if ( dispose_list ) {
SList * list = dispose_list ;
while ( list ) {
2021-02-11 10:18:38 +03:00
GCHandle dispose_exception _gchandle = INVALID_GCHANDLE ;
2017-02-20 21:29:56 +03:00
xamarin_dispose ( ( MonoObject * ) list -> data , & dispose_exception _gchandle ) ;
2021-02-11 10:18:38 +03:00
if ( dispose_exception _gchandle ! = INVALID_GCHANDLE ) {
if ( exception_gchandle = = INVALID_GCHANDLE ) {
2017-02-20 21:29:56 +03:00
// If we get an exception while disposing , and we don ' t already have an exception , then we need to throw the dispose exception ( later , when done disposing )
exception_gchandle = dispose_exception _gchandle ;
} else {
// If we already have an exception , don ' t overwrite it with an exception from disposing something .
// However we don ' t want to silently ignore it , so print it .
NSLog ( @ PRODUCT ": An exception occurred while disposing the object %p:" , list -> data ) ;
2021-03-12 09:37:13 +03:00
NSLog ( @ "%@" , xamarin_print _all _exceptions ( dispose_exception _gchandle ) ) ;
2017-02-20 21:29:56 +03:00
}
}
list = list -> next ;
}
s_list _free ( dispose_list ) ;
}
2020-05-04 12:08:47 +03:00
if ( desc ! = NULL ) {
xamarin_gchandle _free ( desc -> method_handle ) ;
for ( int i = 0 ; i < desc -> bindas_count ; i + + )
xamarin_gchandle _free ( desc -> bindas [ i ] . original_type _handle ) ;
}
2017-07-03 20:18:02 +03:00
if ( free_list ) {
SList * list = free_list ;
while ( list ) {
xamarin_free ( list -> data ) ;
list = list -> next ;
}
s_list _free ( free_list ) ;
}
2017-02-20 21:29:56 +03:00
2021-04-27 15:59:03 +03:00
# if defined ( CORECLR_RUNTIME )
if ( release_list ) {
SList * list = release_list ;
while ( list ) {
xamarin_mono _object _release ( ( MonoObject * * ) & list -> data ) ;
list = list -> next ;
}
s_list _free ( release_list ) ;
}
# endif
2019-04-24 10:31:37 +03:00
if ( arg_copy ! = NULL ) {
free ( arg_copy ) ;
arg_copy = NULL ;
}
if ( writeback ) {
free ( writeback ) ;
writeback = NULL ;
}
2021-05-06 17:19:59 +03:00
xamarin_bridge _free _mono _signature ( & msig ) ;
2016-05-16 20:31:56 +03:00
MONO_THREAD _DETACH ; // COOP : This will switch to GC_SAFE
2016-06-02 13:18:45 +03:00
2021-02-11 10:18:38 +03:00
if ( exception_gchandle ! = INVALID_GCHANDLE ) {
2016-06-02 13:18:45 +03:00
xamarin_process _managed _exception _gchandle ( exception_gchandle ) ;
} else {
xamarin_process _managed _exception ( exception ) ;
}
2019-11-14 13:44:51 +03:00
}