# Patch created by krokas
# Date: Sat Sep 16 17:27:10 MSD 2006
# Repository: pnet
# Comments:
# 
#### End of Preamble ####

#### Patch data follows ####
Index: engine/jitc.c
===================================================================
RCS file: /sources/dotgnu-pnet/./pnet/engine/jitc.c,v
retrieving revision 1.47
diff -c -r1.47 jitc.c
*** engine/jitc.c	4 Sep 2006 10:11:30 -0000	1.47
--- engine/jitc.c	16 Sep 2006 13:26:29 -0000
***************
*** 264,273 ****
  static ILJitType _ILJitSignature_ILStringWCreate = 0;
  
  /*
!  * void *ILJitDelegateGetClosure(ILExecThread *thread, ILObject *delegate, ILType *delType)
   */
  static ILJitType _ILJitSignature_ILJitDelegateGetClosure = 0;
  
  
  /*
   * Define offsetof macro if not present.
--- 264,283 ----
  static ILJitType _ILJitSignature_ILStringWCreate = 0;
  
  /*
!  * void *ILJitDelegateGetClosure(ILObject *delegate, ILType *delType)
   */
  static ILJitType _ILJitSignature_ILJitDelegateGetClosure = 0;
  
+ /*
+  * static void* MarshalObjectToCustom(void *value, ILType *type, ILMethod *method, ILExecThread *thread)
+  */
+ static ILJitType _ILJitSignature_MarshalObjectToCustom = 0;
+ 
+ /*
+  * static void* MarshalCustomToObject(void *value, ILType *type, ILMethod *method, ILExecThread *thread)
+  */
+ static ILJitType _ILJitSignature_MarshalCustomToObject = 0;
+ 
  
  /*
   * Define offsetof macro if not present.
***************
*** 2221,2230 ****
  
  	args[0] = _IL_JIT_TYPE_VPTR;
  	args[1] = _IL_JIT_TYPE_VPTR;
- 	args[2] = _IL_JIT_TYPE_VPTR;
  	returnType = _IL_JIT_TYPE_VPTR;
  	if(!(_ILJitSignature_ILJitDelegateGetClosure =
! 		jit_type_create_signature(IL_JIT_CALLCONV_CDECL, returnType, args, 3, 1)))
  	{
  		return 0;
  	}
--- 2231,2261 ----
  
  	args[0] = _IL_JIT_TYPE_VPTR;
  	args[1] = _IL_JIT_TYPE_VPTR;
  	returnType = _IL_JIT_TYPE_VPTR;
  	if(!(_ILJitSignature_ILJitDelegateGetClosure =
! 		jit_type_create_signature(IL_JIT_CALLCONV_CDECL, returnType, args, 2, 1)))
! 	{
! 		return 0;
! 	}
! 
! 	args[0] = _IL_JIT_TYPE_VPTR;
! 	args[1] = _IL_JIT_TYPE_VPTR;
! 	args[2] = _IL_JIT_TYPE_VPTR;
! 	args[3] = _IL_JIT_TYPE_VPTR;
! 	returnType = _IL_JIT_TYPE_VPTR;
! 	if(!(_ILJitSignature_MarshalObjectToCustom =
! 		jit_type_create_signature(IL_JIT_CALLCONV_CDECL, returnType, args, 4, 1)))
! 	{
! 		return 0;
! 	}
! 
! 	args[0] = _IL_JIT_TYPE_VPTR;
! 	args[1] = _IL_JIT_TYPE_VPTR;
! 	args[2] = _IL_JIT_TYPE_VPTR;
! 	args[3] = _IL_JIT_TYPE_VPTR;
! 	returnType = _IL_JIT_TYPE_VPTR;
! 	if(!(_ILJitSignature_MarshalCustomToObject = 
! 		jit_type_create_signature(IL_JIT_CALLCONV_CDECL, returnType, args, 4, 1)))
  	{
  		return 0;
  	}
Index: engine/jitc.h
===================================================================
RCS file: /sources/dotgnu-pnet/./pnet/engine/jitc.h,v
retrieving revision 1.17
diff -c -r1.17 jitc.h
*** engine/jitc.h	4 Sep 2006 10:11:30 -0000	1.17
--- engine/jitc.h	16 Sep 2006 13:26:30 -0000
***************
*** 226,234 ****
  /*
   * Get the closure for a delegate.
   */
! void *ILJitDelegateGetClosure(ILExecThread *thread,
! 							  ILObject *delegate,
! 							  ILType *delType);
  
  
  #endif  /* IL_USE_JIT */
--- 226,233 ----
  /*
   * Get the closure for a delegate.
   */
! void *ILJitDelegateGetClosure(ILObject *delegate,
! 				ILType *delType);
  
  
  #endif  /* IL_USE_JIT */
Index: engine/jitc_call.c
===================================================================
RCS file: /sources/dotgnu-pnet/./pnet/engine/jitc_call.c,v
retrieving revision 1.22
diff -c -r1.22 jitc_call.c
*** engine/jitc_call.c	28 Jul 2006 17:41:54 -0000	1.22
--- engine/jitc_call.c	16 Sep 2006 13:26:32 -0000
***************
*** 150,156 ****
  	jit_label_t labelException = jit_label_undefined;
  	jit_label_t label = jit_label_undefined;
  	ILJitValue args[3];
! 
  
  	/* Allocate an array to hold all of the arguments */
  	/* Find the constructor for the array. */
--- 150,156 ----
  	jit_label_t labelException = jit_label_undefined;
  	jit_label_t label = jit_label_undefined;
  	ILJitValue args[3];
! 	ILJitType callSignature = jit_function_get_signature(jitCoder->jitFunction);
  
  	/* Allocate an array to hold all of the arguments */
  	/* Find the constructor for the array. */
***************
*** 169,175 ****
  	args[0] = thread;
  	args[1] = arrayLength;
  	array = jit_insn_call(jitCoder->jitFunction, 0, jitCtor,
! 						  0, args, 2, 0);
  	jit_insn_branch_if_not(jitCoder->jitFunction, array, &labelException);
  	arrayBase = jit_insn_add_relative(jitCoder->jitFunction,
  									  array,
--- 169,175 ----
  	args[0] = thread;
  	args[1] = arrayLength;
  	array = jit_insn_call(jitCoder->jitFunction, 0, jitCtor,
! 						  callSignature, args, 2, 0);
  	jit_insn_branch_if_not(jitCoder->jitFunction, array, &labelException);
  	arrayBase = jit_insn_add_relative(jitCoder->jitFunction,
  									  array,
***************
*** 593,599 ****
  	ILJitValue returnValue;
  	char *methodName = 0;
  	ILInternalInfo fnInfo;
! 
  #if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS)
  	if (jitCoder->flags & IL_CODER_FLAG_STATS)
  	{
--- 593,600 ----
  	ILJitValue returnValue;
  	char *methodName = 0;
  	ILInternalInfo fnInfo;
! 	ILJitType signature = jit_function_get_signature(jitFunction);
! 	
  #if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS)
  	if (jitCoder->flags & IL_CODER_FLAG_STATS)
  	{
***************
*** 679,689 ****
  	{
  	#ifdef IL_JIT_THREAD_IN_SIGNATURE
  		returnValue = jit_insn_call(jitCoder->jitFunction, methodName,
! 									jitFunction, 0,
  									jitParams, argCount + 1, JIT_CALL_TAIL);
  	#else
  		returnValue = jit_insn_call(jitCoder->jitFunction, methodName,
! 									jitFunction, 0,
  									jitParams, argCount, JIT_CALL_TAIL);
  	#endif
  		if(returnItem->engineType != ILEngineType_Invalid)
--- 680,690 ----
  	{
  	#ifdef IL_JIT_THREAD_IN_SIGNATURE
  		returnValue = jit_insn_call(jitCoder->jitFunction, methodName,
! 									jitFunction, signature,
  									jitParams, argCount + 1, JIT_CALL_TAIL);
  	#else
  		returnValue = jit_insn_call(jitCoder->jitFunction, methodName,
! 									jitFunction, signature,
  									jitParams, argCount, JIT_CALL_TAIL);
  	#endif
  		if(returnItem->engineType != ILEngineType_Invalid)
***************
*** 695,711 ****
  		}
  	}
  	else
! 	{		
! 	#ifdef IL_JIT_THREAD_IN_SIGNATURE
! 		returnValue = jit_insn_call(jitCoder->jitFunction, methodName,
! 									jitFunction, 0,
! 									jitParams, argCount + 1, 0);
! 	#else
! 		returnValue = jit_insn_call(jitCoder->jitFunction, methodName,
! 									jitFunction, 0,
! 									jitParams, argCount, 0);
! 	#endif
! 		if(returnItem && returnItem->engineType != ILEngineType_Invalid)
  		{
  			jitCoder->jitStack[jitCoder->stackTop] =
  					_ILJitValueConvertToStackType(jitCoder->jitFunction,
--- 696,722 ----
  		}
  	}
  	else
! 	{
! #if !defined(IL_CONFIG_REDUCE_CODE) && !defined(_IL_JIT_ENABLE_DEBUG)
! 		ILPInvoke *pinv = ILPInvokeFind(methodInfo);
! 		if(pinv && ((ILJitMethodInfo*)(methodInfo->userData))->fnInfo.func)
! 		{
! 			returnValue = _ILJitInlinePinvoke(jitCoder, methodInfo, jitParams);
! 		}
! 		else 
! #endif
! 		{	
! 		    #ifdef IL_JIT_THREAD_IN_SIGNATURE
! 			returnValue = jit_insn_call(jitCoder->jitFunction, methodName,
! 										jitFunction, signature,
! 										jitParams, argCount + 1, 0);
! 		    #else
! 			returnValue = jit_insn_call(jitCoder->jitFunction, methodName,
! 										jitFunction, signature,
! 										jitParams, argCount, 0);
! 		    #endif
! 		}
!     		if(returnItem && returnItem->engineType != ILEngineType_Invalid)
  		{
  			jitCoder->jitStack[jitCoder->stackTop] =
  					_ILJitValueConvertToStackType(jitCoder->jitFunction,
***************
*** 758,763 ****
--- 769,776 ----
  	ILInternalInfo fnInfo;
  	int internalType = _IL_JIT_IMPL_DEFAULT;
  	char *methodName = 0;
+ 	ILJitType signature = jit_function_get_signature(jitFunction);
+ 	
  	
  #if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS)
  	if (jitCoder->flags & IL_CODER_FLAG_STATS)
***************
*** 855,866 ****
  	#ifdef IL_JIT_THREAD_IN_SIGNATURE
  		_ILJitFillArguments(jitCoder, &(jitParams[1]), info);
  		// call the constructor with jitParams as input
! 		returnValue = jit_insn_call(jitCoder->jitFunction, 0, jitFunction, 0,
  									jitParams, argCount + 1, 0);
  	#else
  		_ILJitFillArguments(jitCoder, &(jitParams[0]), info);
  		// call the constructor with jitParams as input
! 		returnValue = jit_insn_call(jitCoder->jitFunction, 0, jitFunction, 0,
  									jitParams, argCount, 0);
  	#endif
  		jitCoder->jitStack[jitCoder->stackTop] = returnValue;
--- 868,879 ----
  	#ifdef IL_JIT_THREAD_IN_SIGNATURE
  		_ILJitFillArguments(jitCoder, &(jitParams[1]), info);
  		// call the constructor with jitParams as input
! 		returnValue = jit_insn_call(jitCoder->jitFunction, 0, jitFunction, signature,
  									jitParams, argCount + 1, 0);
  	#else
  		_ILJitFillArguments(jitCoder, &(jitParams[0]), info);
  		// call the constructor with jitParams as input
! 		returnValue = jit_insn_call(jitCoder->jitFunction, 0, jitFunction, signature,
  									jitParams, argCount, 0);
  	#endif
  		jitCoder->jitStack[jitCoder->stackTop] = returnValue;
***************
*** 874,880 ****
  
  		// call the constructor with jitParams as input
  		returnValue = jit_insn_call(jitCoder->jitFunction, methodName,
! 									jitFunction, 0,
  									jitParams, argCount + 2, 0);
  
  		jitCoder->jitStack[jitCoder->stackTop] = jitParams[1];
--- 887,893 ----
  
  		// call the constructor with jitParams as input
  		returnValue = jit_insn_call(jitCoder->jitFunction, methodName,
! 									jitFunction, signature,
  									jitParams, argCount + 2, 0);
  
  		jitCoder->jitStack[jitCoder->stackTop] = jitParams[1];
***************
*** 885,891 ****
  
  		// call the constructor with jitParams as input
  		returnValue = jit_insn_call(jitCoder->jitFunction, methodName,
! 									jitFunction, 0,
  									jitParams, argCount + 1, 0);
  
  		jitCoder->jitStack[jitCoder->stackTop] = jitParams[0];
--- 898,904 ----
  
  		// call the constructor with jitParams as input
  		returnValue = jit_insn_call(jitCoder->jitFunction, methodName,
! 									jitFunction, signature,
  									jitParams, argCount + 1, 0);
  
  		jitCoder->jitStack[jitCoder->stackTop] = jitParams[0];
Index: engine/jitc_pinvoke.c
===================================================================
RCS file: /sources/dotgnu-pnet/./pnet/engine/jitc_pinvoke.c,v
retrieving revision 1.3
diff -c -r1.3 jitc_pinvoke.c
*** engine/jitc_pinvoke.c	28 Jul 2006 17:41:54 -0000	1.3
--- engine/jitc_pinvoke.c	16 Sep 2006 13:26:34 -0000
***************
*** 18,56 ****
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   */
  
  #define MARSHAL_FIRST_LEVEL_VALUE		0
  #define MARSHAL_ITEM_OF_STRUCTURE		1
  #define MARSHAL_ITEM_OF_ARRAY			2
  
- 
  static int NeedMarshalValue(ILType *type);
  static int NeedMarshalStruct(ILType *structureILType);
  
! static ILJitValue MarshalValue(jit_function_t function, ILJitValue in, ILType *type, ILUInt32 current, unsigned int addressKind, jit_nint offset, ILJitValue outAddress);
! static ILJitValue MarshalStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind);
! 
! static ILJitValue MarshalReturnValue(jit_function_t function, ILJitValue in, ILType *type, unsigned int addressKind, jit_nint offset, ILJitValue outAddress);
! static ILJitValue MarshalReturnStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind);
! 
! static void MarshalByRefValue(jit_function_t function, ILJitValue in, ILType *type, ILUInt32 current, unsigned int addressKind, jit_nint offset, ILJitValue outAddress);
! static void MarshalByRefStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind);
! 
! void *ILJitDelegateGetClosure(ILExecThread *currentThread, ILObject *del, ILType *delType);
! 
! static ILJitValue MarshalDelegateValue(jit_function_t function, ILJitValue in, ILType *type, ILUInt32 current, unsigned int addressKind, jit_nint offset, ILJitValue outAddress, ILExecThread *thread);
! static ILJitValue MarshalDelegateStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind, ILExecThread *thread);
  
! static ILJitValue MarshalDelegateReturnValue(jit_function_t function, ILJitValue in, ILType *type, unsigned int addressKind, jit_nint offset, ILJitValue outAddress, ILExecThread *thread);
! static ILJitValue MarshalDelegateReturnStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind, ILExecThread *thread);
  
! static void MarshalDelegateByRefValue(jit_function_t function, ILJitValue in, ILType *type, ILUInt32 current, unsigned int addressKind, jit_nint offset, ILJitValue outAddress, ILExecThread *thread);
! static void MarshalDelegateByRefStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind, ILExecThread *thread);
  
  /*
   * On demand code generator.for functions implemented in IL code.
   */
  static int _ILJitCompilePinvoke(jit_function_t func)
! {
  	ILMethod *method = (ILMethod *)jit_function_get_meta(func, IL_JIT_META_METHOD);
  	ILClass *info = ILMethod_Owner(method);
  	ILClassPrivate *classPrivate = (ILClassPrivate *)info->userData;
--- 18,62 ----
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   */
  
+ /*
+  * For enabling extended marshaling - of byref structures and arrays of structures uncomment the following define.
+  */
+ // #define USE_BYREF_MARSHALING 1
+ 
  #define MARSHAL_FIRST_LEVEL_VALUE		0
  #define MARSHAL_ITEM_OF_STRUCTURE		1
  #define MARSHAL_ITEM_OF_ARRAY			2
  
  static int NeedMarshalValue(ILType *type);
  static int NeedMarshalStruct(ILType *structureILType);
  
! static ILJitValue MarshalValue(jit_function_t function, ILJitValue in, ILType *type, ILUInt32 marshalType, unsigned int addressKind, jit_nint offset, ILJitValue outAddress);
! static ILJitValue MarshalStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILUInt32 marshalType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind);
  
! static ILJitValue MarshalReturnValue(jit_function_t function, ILJitValue in, ILType *type, ILUInt32 marshalType, unsigned int addressKind, jit_nint offset, ILJitValue outAddress);
! static ILJitValue MarshalReturnStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILUInt32 marshalType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind);
! #ifdef USE_BYREF_MARSHALING
! static void MarshalByRefValue(jit_function_t function, ILJitValue in, ILType *type, ILUInt32 marshalType, unsigned int addressKind, jit_nint offset, ILJitValue outAddress);
! static void MarshalByRefStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILUInt32 marshalType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind);
! #endif
! void *ILJitDelegateGetClosure(ILObject *del, ILType *delType);
  
! static ILJitValue MarshalDelegateValue(jit_function_t function, ILJitValue in, ILType *type, ILUInt32 marshalType, unsigned int addressKind, jit_nint offset, ILJitValue outAddress);
! static ILJitValue MarshalDelegateStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILUInt32 marshalType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind);
  
+ static ILJitValue MarshalDelegateReturnValue(jit_function_t function, ILJitValue in, ILType *type, ILUInt32 marshalType, unsigned int addressKind, jit_nint offset, ILJitValue outAddress);
+ static ILJitValue MarshalDelegateReturnStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILUInt32 marshalType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind);
+ #ifdef USE_BYREF_MARSHALING
+ static void MarshalDelegateByRefValue(jit_function_t function, ILJitValue in, ILType *type, ILUInt32 marshalType, unsigned int addressKind, jit_nint offset, ILJitValue outAddress);
+ static void MarshalDelegateByRefStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILUInt32 marshalType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind);
+ #endif
+ static void *MarshalObjectToCustom(void *value, ILType *type, ILMethod *method, ILExecThread *thread);
+ static void *MarshalCustomToObject(void *value, ILType *type, ILMethod *method, ILExecThread *thread);
  /*
   * On demand code generator.for functions implemented in IL code.
   */
  static int _ILJitCompilePinvoke(jit_function_t func)
! {	
  	ILMethod *method = (ILMethod *)jit_function_get_meta(func, IL_JIT_META_METHOD);
  	ILClass *info = ILMethod_Owner(method);
  	ILClassPrivate *classPrivate = (ILClassPrivate *)info->userData;
***************
*** 68,77 ****
  	ILJitType returnType = jit_type_get_return(signature);
  	ILJitValue returnValue = jit_value_create(func, jit_type_void_ptr);
  	unsigned int current;
- 	unsigned int typeFlag;
- 	ILJitValue newValue;
  	ILType *valueType;
! 
  #if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) && defined(_IL_JIT_ENABLE_DEBUG)
  	if(jitCoder->flags & IL_CODER_FLAG_STATS)
  	{
--- 74,86 ----
  	ILJitType returnType = jit_type_get_return(signature);
  	ILJitValue returnValue = jit_value_create(func, jit_type_void_ptr);
  	unsigned int current;
  	ILType *valueType;
! 	ILUInt32 marshalType;
! 	char *customName;
! 	int customNameLen;
! 	char *customCookie;
! 	int customCookieLen;
! 	
  #if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) && defined(_IL_JIT_ENABLE_DEBUG)
  	if(jitCoder->flags & IL_CODER_FLAG_STATS)
  	{
***************
*** 134,206 ****
  
  		default:
  		{
! 			/* There is an invalid calling convention inthe metadata. */
  			return JIT_RESULT_COMPILE_ERROR;
  		}
  	}
  
- 
  	ILJitType paramType;
  	ILJitType jitParamTypes[numParams + 1];
  	ILJitValue jitParams[numParams + 1];
  	ILJitValue tempParams[numParams + 1];
  	ILUInt32 param = 0;
! 
  	for(current = 1; current < numParams; ++current)
  	{
- 
  		paramType = jit_type_get_param(signature, current);
  		valueType = ILTypeGetParam(ilSignature, current);
  		valueType = ILTypeGetEnumType(valueType);
! 		tempParams[param] = jit_insn_dup(func, jit_value_get_param(func, current));
! 		jitParams[param] = (ILJitValue)MarshalValue(func, tempParams[param], valueType, current, 0, 0, 0);
  		jitParamTypes[param] = paramType;
  		++param;
  	}
  	ILJitType callSignature = jit_type_create_signature(jitAbi,
  								   returnType,
  								   jitParamTypes,
  								   numParams - 1, 1);
! 	if(numParams > 1)
! 	{														   
  		type = ILTypeGetEnumType(ILTypeGetReturn(ilSignature));
  		returnValue = jit_insn_call_native(func, 0, jitMethodInfo->fnInfo.func,
  								 callSignature,
  								 jitParams, numParams - 1, 0);
! 		jit_insn_store(func, returnValue, (ILJitValue)MarshalReturnValue(func, jit_insn_dup(func, returnValue), type, 0, 0, 0));
! 		param = 0;
! 		for(current = 1; current < numParams; ++current)
  		{
! 			newValue = jit_insn_dup(func, jitParams[param]);
! 			type = ILTypeGetParam(ilSignature, current);
! 			type = ILTypeGetEnumType(type);
  
! 			if(type!=0 && ILType_IsSimpleArray(type))
! 			{
! 				MarshalByRefValue(func, newValue, type, current, 0, 0, tempParams[param]);
  			}
! 			else if(type!=0 && ILType_IsComplex(type))
  			{
  				typeFlag = ILType_Kind(type);
! 		    		if(typeFlag==IL_TYPE_COMPLEX_BYREF || typeFlag == IL_TYPE_COMPLEX_PTR)
  				{
! 					MarshalByRefValue(func, newValue, type,
! 								    current, 0,
  								    0, tempParams[param]);
  				}
  			}
- 			++param;
  		}
! 		jit_insn_return(func, returnValue);
! 
! 	}
! 	else
! 	{
! 		jit_insn_call_native(func, 0, jitMethodInfo->fnInfo.func,
! 									callSignature, 0, 0, 0);
! 		jit_insn_return(func, 0);
  	}
! 	jit_type_free(callSignature);	
  
  #if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) && defined(_IL_JIT_ENABLE_DEBUG)
  #ifdef _IL_JIT_DUMP_FUNCTION
--- 143,300 ----
  
  		default:
  		{
! 			/* There is an invalid calling convention in the metadata. */
  			return JIT_RESULT_COMPILE_ERROR;
  		}
+ 		break;
  	}
  
  	ILJitType paramType;
  	ILJitType jitParamTypes[numParams + 1];
  	ILJitValue jitParams[numParams + 1];
  	ILJitValue tempParams[numParams + 1];
  	ILUInt32 param = 0;
! #ifdef IL_JIT_THREAD_IN_SIGNATURE
  	for(current = 1; current < numParams; ++current)
+ 	
+ #else
+ 	for(current = 0; current < numParams; ++current)
+ #endif
  	{
  		paramType = jit_type_get_param(signature, current);
+ #ifdef IL_JIT_THREAD_IN_SIGNATURE
  		valueType = ILTypeGetParam(ilSignature, current);
+ #else
+ 		valueType = ILTypeGetParam(ilSignature, current + 1);
+ #endif
  		valueType = ILTypeGetEnumType(valueType);
! 		tempParams[param] = jit_value_get_param(func, current);
! 		marshalType = ILPInvokeGetMarshalType(pinv, method, current, &customName, &customNameLen,
! 								    &customCookie, &customCookieLen, valueType);
! 		jitParams[param] = jit_value_get_param(func, current);
! 		if(marshalType==IL_META_MARSHAL_CUSTOM)
! 		{
! 			ILJitValue params[4];
! 			params[0] = tempParams[param];
! 			params[1] = jit_value_create_nint_constant(func, _IL_JIT_TYPE_VPTR, (jit_nint)valueType);
! 			params[2] = jit_value_create_nint_constant(func, _IL_JIT_TYPE_VPTR, (jit_nint)method);
! 			params[3] = _ILJitFunctionGetThread(func);
! 			returnValue = jit_insn_call_native(func, "MarshalObjectToCustom", MarshalObjectToCustom, _ILJitSignature_MarshalObjectToCustom, params, 4, JIT_CALL_NOTHROW);
! 		}
! 		else if((!ILTypeIsStringClass(valueType) || marshalType!=IL_META_MARSHAL_DIRECT)
! 			    && NeedMarshalValue(valueType))
! 		{
! 			jitParams[param] = (ILJitValue)MarshalValue(func, tempParams[param], valueType, marshalType,
! 								    MARSHAL_FIRST_LEVEL_VALUE, 0, 0);
! 		}
  		jitParamTypes[param] = paramType;
  		++param;
  	}
+ #ifdef IL_JIT_THREAD_IN_SIGNATURE
+ 	if(numParams==2 && jitParamTypes[1]==jit_type_void)
+ 	{
+ 		numParams = 1;
+ 	}
+ #else
+ 	if(numParams==1 && jitParamTypes[0]==jit_type_void)
+ 	{
+ 		numParams = 0;
+ 	}
+ #endif
  	ILJitType callSignature = jit_type_create_signature(jitAbi,
  								   returnType,
  								   jitParamTypes,
+ #ifdef IL_JIT_THREAD_IN_SIGNATURE
  								   numParams - 1, 1);
! #else
! 								   numParams, 1);
! #endif
! 	if(returnType==jit_type_void)
! 	{
! 		jit_insn_call_native(func, 0, jitMethodInfo->fnInfo.func,
! 								callSignature,
! #ifdef IL_JIT_THREAD_IN_SIGNATURE
! 								jitParams, numParams - 1, 0);
! #else
! 								jitParams, numParams, 0);
! #endif
! 	}
! 	else
! 	{
  		type = ILTypeGetEnumType(ILTypeGetReturn(ilSignature));
  		returnValue = jit_insn_call_native(func, 0, jitMethodInfo->fnInfo.func,
  								 callSignature,
+ #ifdef IL_JIT_THREAD_IN_SIGNATURE
  								 jitParams, numParams - 1, 0);
! #else
! 								 jitParams, numParams, 0);
! #endif
! 		marshalType = ILPInvokeGetMarshalType
! 				(0, method, 0, &customName, &customNameLen,
! 				 &customCookie, &customCookieLen, type);
! 		if(marshalType==IL_META_MARSHAL_CUSTOM)
! 		{
! 			ILJitValue params[4];
! 			params[0] = returnValue;
! 			params[1] = jit_value_create_nint_constant(func, _IL_JIT_TYPE_VPTR, (jit_nint)type);
! 			params[2] = jit_value_create_nint_constant(func, _IL_JIT_TYPE_VPTR, (jit_nint)method);
! 			params[3] = _ILJitFunctionGetThread(func);
! 			returnValue = jit_insn_call_native(func, "MarshalCustomToObject", MarshalCustomToObject, _ILJitSignature_MarshalCustomToObject, params, 4, JIT_CALL_NOTHROW);
! 		}
! 		else if((!ILTypeIsStringClass(type) || marshalType != IL_META_MARSHAL_DIRECT)
! 			    && NeedMarshalValue(type))
  		{
! 			returnValue = (ILJitValue)MarshalReturnValue(func, returnValue, type, marshalType,
! 									MARSHAL_FIRST_LEVEL_VALUE, 0, 0);
! 		}
! 	}
  
! #ifdef USE_BYREF_MARSHALING
! 	param = 0;
! #ifdef IL_JIT_THREAD_IN_SIGNATURE
! 	for(current = 1; current < numParams; ++current)
! #else
! 	for(current = 0; current < numParams; ++current)
! #endif
! 	{
! #ifdef IL_JIT_THREAD_IN_SIGNATURE
! 		type = ILTypeGetParam(ilSignature, current);
! #else
! 		type = ILTypeGetParam(ilSignature, current + 1);
! #endif
! 		type = ILTypeGetEnumType(type);
! 
! 		// Does anyone use this?
! 		marshalType = ILPInvokeGetMarshalType
! 					(pinv, method, current, &customName, &customNameLen,
! 					 &customCookie, &customCookieLen, type);
! 		if((!ILTypeIsStringClass(type) || marshalType != IL_META_MARSHAL_DIRECT) && NeedMarshalValue(type)
! 			&& marshalType != IL_META_MARSHAL_CUSTOM && type != 0)
! 		{
! 			if(ILType_IsSimpleArray(type))
! 			{
! 				 MarshalByRefValue(func, jitParams[param], type, 
! 							    marshalType, MARSHAL_FIRST_LEVEL_VALUE, 
! 							    0, tempParams[param]);
  			}
! 			else if(ILType_IsComplex(type))
  			{
  				typeFlag = ILType_Kind(type);
! 			    	if(typeFlag==IL_TYPE_COMPLEX_BYREF)
  				{
! 					// Does anyone use this?
! 					MarshalByRefValue(func, jitParams[param], type,
! 								    marshalType, MARSHAL_FIRST_LEVEL_VALUE,
  								    0, tempParams[param]);
  				}
  			}
  		}
! 		++param;
  	}
! #endif
! 	if(returnType==jit_type_void)jit_insn_return(func, 0);
! 	else jit_insn_return(func, returnValue);
! 	jit_type_free(callSignature);
  
  #if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) && defined(_IL_JIT_ENABLE_DEBUG)
  #ifdef _IL_JIT_DUMP_FUNCTION
***************
*** 227,232 ****
--- 321,554 ----
  	return JIT_RESULT_OK;
  }
  
+ #if !defined(IL_CONFIG_REDUCE_CODE) && !defined(_IL_JIT_ENABLE_DEBUG)
+ static ILJitValue _ILJitInlinePinvoke(ILJITCoder *jitCoder, ILMethod *method, ILJitValue *tempParams)
+ {
+ 	ILJitFunction func = jitCoder->jitFunction;
+ 	ILJitMethodInfo *jitMethodInfo = (ILJitMethodInfo *)(method->userData);
+ 	ILType *ilSignature = ILMethod_Signature(method);
+ 	ILType *type;
+ 	ILJitType signature = jit_function_get_signature(ILJitFunctionFromILMethod(method));
+ 	ILPInvoke *pinv = ILPInvokeFind(method);
+ 	jit_abi_t jitAbi;
+ 	ILUInt32 numParams = jit_type_num_params(signature);
+ 	ILJitType returnType = _ILJitGetReturnType(ILTypeGetEnumType(ILTypeGetReturn(ilSignature)), jitCoder->process);
+ 	ILJitValue returnValue = jit_value_create(func, jit_type_void_ptr);
+ 	unsigned int current;
+ 	ILType *valueType;
+ 	ILUInt32 marshalType;
+ 	char *customName;
+ 	int customNameLen;
+ 	char *customCookie;
+ 	int customCookieLen;
+ 
+ 	if(!pinv)
+ 	{
+ 		/* The pinvoke record could not be found. */
+ 		return 0;
+ 	}
+ 
+ 	/* Setup the needed stuff in the jitCoder. */
+ 	jitCoder->jitFunction = func;
+ 
+ 	/* Check if the method to invoke was found on this system. */
+ 	if(_ILJitPinvokeError(jitMethodInfo->fnInfo))
+ 	{
+ 		if(jitMethodInfo->fnInfo.func == _IL_JIT_PINVOKE_DLLNOTFOUND)
+ 		{
+ 			_ILJitThrowSystem(jitCoder, _IL_JIT_DLL_NOT_FOUND);
+ 		}
+ 		else if(jitMethodInfo->fnInfo.func == _IL_JIT_PINVOKE_ENTRYPOINTNOTFOUND)
+ 		{
+ 			_ILJitThrowSystem(jitCoder, _IL_JIT_ENTRYPOINT_NOT_FOUND);
+ 		}
+ 		return 0;
+ 	}
+ 
+ 	/* determine which calling convention to use. */
+ 	switch(pinv->member.attributes & IL_META_PINVOKE_CALL_CONV_MASK)
+ 	{
+ 		case IL_META_PINVOKE_CALL_CONV_WINAPI:
+ 		{
+ 			/* TODO: There is no winapi calling convention in libjit. */
+ 			jitAbi = IL_JIT_CALLCONV_STDCALL;
+ 		}
+ 		break;
+ 
+ 		case IL_META_PINVOKE_CALL_CONV_CDECL:
+ 		{
+ 			jitAbi = IL_JIT_CALLCONV_CDECL;
+ 		}
+ 		break;
+ 
+ 		case IL_META_PINVOKE_CALL_CONV_STDCALL:
+ 		{
+ 			jitAbi = IL_JIT_CALLCONV_STDCALL;
+ 		}
+ 		break;
+ 
+ 		case IL_META_PINVOKE_CALL_CONV_FASTCALL:
+ 		{
+ 			jitAbi = IL_JIT_CALLCONV_FASTCALL;
+ 		}
+ 		break;
+ 
+ 		default:
+ 		{
+ 			/* There is an invalid calling convention inthe metadata. */
+ 			return 0;
+ 		}
+ 		break;
+ 	}
+ 
+ 	ILJitType paramType;
+ 	ILJitType jitParamTypes[numParams + 1];
+ 	ILJitValue jitParams[numParams + 1];
+ 	ILUInt32 param = 0;
+ #ifdef IL_JIT_THREAD_IN_SIGNATURE
+ 	for(current = 1; current < numParams; ++current)
+ #else
+ 	for(current = 0; current < numParams; ++current)
+ #endif
+ 	{
+ #ifdef IL_JIT_THREAD_IN_SIGNATURE
+ 		paramType = _ILJitGetArgType(ILTypeGetEnumType(ILTypeGetParam(ilSignature, current)), jitCoder->process);
+ 		valueType = ILTypeGetParam(ilSignature, current);
+ #else
+ 		paramType = _ILJitGetArgType(ILTypeGetEnumType(ILTypeGetParam(ilSignature, current + 1)), jitCoder->process);
+ 		valueType = ILTypeGetParam(ilSignature, current + 1);
+ #endif	
+ 		valueType = ILTypeGetEnumType(valueType);
+ 		marshalType = ILPInvokeGetMarshalType(pinv, method, current, &customName, &customNameLen,
+ 								    &customCookie, &customCookieLen, valueType);
+ 		jitParams[param] = tempParams[current];
+ 		if(marshalType==IL_META_MARSHAL_CUSTOM)
+ 		{
+ 			ILJitValue params[4];
+ 			params[0] = tempParams[current];
+ 			params[1] = jit_value_create_nint_constant(func, _IL_JIT_TYPE_VPTR, (jit_nint)valueType);
+ 			params[2] = jit_value_create_nint_constant(func, _IL_JIT_TYPE_VPTR, (jit_nint)method);
+ 			params[3] = _ILJitFunctionGetThread(func);
+ 			returnValue = jit_insn_call_native(func, "MarshalObjectToCustom", MarshalObjectToCustom,
+ 								_ILJitSignature_MarshalObjectToCustom, params, 4, JIT_CALL_NOTHROW);
+ 		}
+ 		else if((!ILTypeIsStringClass(valueType) || marshalType!=IL_META_MARSHAL_DIRECT)
+ 			    && NeedMarshalValue(valueType))
+ 		{
+ 			jitParams[param] = (ILJitValue)MarshalValue(func, tempParams[current], valueType, marshalType,
+ 									MARSHAL_FIRST_LEVEL_VALUE, 0, 0);
+ 		}
+ 		jitParamTypes[param] = paramType;
+ 		++param;
+ 	}
+ #ifdef IL_JIT_THREAD_IN_SIGNATURE
+ 	if(numParams==2 && jitParamTypes[0]==jit_type_void)
+ 	{
+ 		numParams = 1;
+ 	}
+ #else
+ 	if(numParams==1 && jitParamTypes[0]==jit_type_void)
+ 	{
+ 		numParams = 0;
+ 	}
+ #endif
+ 	ILJitType callSignature = jit_type_create_signature(jitAbi,
+ 								   returnType,
+ 								   jitParamTypes,
+ #ifdef IL_JIT_THREAD_IN_SIGNATURE
+ 								   numParams - 1, 1);
+ #else
+ 								   numParams, 1);
+ #endif
+ 	if(returnType==jit_type_void)
+ 	{
+ 		 jit_insn_call_native(func, 0, jitMethodInfo->fnInfo.func,
+ 								callSignature,
+ #ifdef IL_JIT_THREAD_IN_SIGNATURE
+ 								jitParams, numParams - 1, 0);
+ #else
+ 								jitParams, numParams, 0);
+ #endif
+ 	}
+ 	else
+ 	{
+ 		type = ILTypeGetEnumType(ILTypeGetReturn(ilSignature));
+ 		returnValue = jit_insn_call_native(func, 0, jitMethodInfo->fnInfo.func,
+ 								 callSignature,
+ #ifdef IL_JIT_THREAD_IN_SIGNATURE
+ 								 jitParams, numParams - 1, 0);
+ #else
+ 								 jitParams, numParams, 0);
+ #endif
+ 		marshalType = ILPInvokeGetMarshalType
+ 				(0, method, 0, &customName, &customNameLen,
+ 				 &customCookie, &customCookieLen, type);
+ 		if(marshalType==IL_META_MARSHAL_CUSTOM)
+ 		{
+ 			ILJitValue params[4];
+ 			params[0] = returnValue;
+ 			params[1] = jit_value_create_nint_constant(func, _IL_JIT_TYPE_VPTR, (jit_nint)type);
+ 			params[2] = jit_value_create_nint_constant(func, _IL_JIT_TYPE_VPTR, (jit_nint)method);
+ 			params[3] = _ILJitFunctionGetThread(func);
+ 			returnValue = jit_insn_call_native(func, "MarshalCustomToObject", MarshalCustomToObject, _ILJitSignature_MarshalCustomToObject, params, 4, JIT_CALL_NOTHROW);
+ 		}
+ 		else if((!ILTypeIsStringClass(type) || marshalType != IL_META_MARSHAL_DIRECT) 
+ 			    && NeedMarshalValue(type))
+ 		{
+ 			returnValue = (ILJitValue)MarshalReturnValue(func, returnValue, type, marshalType,
+ 									MARSHAL_FIRST_LEVEL_VALUE, 0, 0);
+ 		}
+ 	}
+ 
+ #ifdef USE_BYREF_MARSHALING
+ 	param = 0;
+ #ifdef IL_JIT_THREAD_IN_SIGNATURE
+ 	for(current = 1; current < numParams; ++current)
+ #else
+ 	for(current = 0; current < numParams; ++current)
+ #endif
+ 	{
+ #ifdef IL_JIT_THREAD_IN_SIGNATURE
+ 		type = ILTypeGetParam(ilSignature, current);
+ #else
+ 		type = ILTypeGetParam(ilSignature, current + 1);
+ #endif
+ 		type = ILTypeGetEnumType(type);
+ 
+ 		marshalType = ILPInvokeGetMarshalType
+ 					(pinv, method, current, &customName, &customNameLen,
+ 						&customCookie, &customCookieLen, type);
+ 		if((!ILTypeIsStringClass(type) || marshalType != IL_META_MARSHAL_DIRECT) && NeedMarshalValue(type)
+ 		    && marshalType != IL_META_MARSHAL_CUSTOM && type != 0)
+ 		{
+ 			if(ILType_IsSimpleArray(type))
+ 			{
+ 				// Does anyone use this?
+ 				MarshalByRefValue(func, jitParams[param], type, 
+ 							marshalType, MARSHAL_FIRST_LEVEL_VALUE, 
+ 							0, tempParams[current]);
+ 			}
+ 			else if(ILType_IsComplex(type))
+ 			{
+ 				typeFlag = ILType_Kind(type);
+ 			    	if(typeFlag==IL_TYPE_COMPLEX_BYREF)
+ 				{
+ 					// Does anyone use this?
+ 					MarshalByRefValue(func, jitParams[param], type,
+ 								    marshalType, MARSHAL_FIRST_LEVEL_VALUE,
+ 								    0, tempParams[current]);
+ 				}
+ 			}
+ 		}
+ 		++param;
+ 	}
+ #endif
+ 	if(returnType==jit_type_void)return 0;
+ 	else return(returnValue);
+ 	jit_type_free(callSignature);	
+ }
+ #endif // _ILJitInlinePinvoke
+ 
  static int NeedMarshalValue(ILType *type)
  {
      type = ILTypeGetEnumType(type);
***************
*** 334,349 ****
      {
  	    return 1;
      }
!     else if(ILType_IsClass(type))
!     {
! 	    return 0;
!     }
!     else if(type !=0 && ILType_IsComplex(type))
      {
- 	    
  	    switch(ILType_Kind(type))
  	    {
  		    case IL_TYPE_COMPLEX_PTR:
  		    case IL_TYPE_COMPLEX_BYREF:
  		    {
  			    return 1;
--- 656,670 ----
      {
  	    return 1;
      }
!     else if(type!=0 && ILType_IsComplex(type))
      {
  	    switch(ILType_Kind(type))
  	    {
  		    case IL_TYPE_COMPLEX_PTR:
+ 		    {
+ 			    return 0;
+ 		    }
+ 		    break;
  		    case IL_TYPE_COMPLEX_BYREF:
  		    {
  			    return 1;
***************
*** 366,372 ****
      	    return 1;
      }
  
!     return 1;
  }
  
  static int NeedMarshalStruct(ILType *structureILType)
--- 687,693 ----
      	    return 1;
      }
  
!     return 0;
  }
  
  static int NeedMarshalStruct(ILType *structureILType)
***************
*** 387,396 ****
  	return 0;
  }
  
! 
! static ILJitValue MarshalValue(jit_function_t function, ILJitValue in, ILType *type, ILUInt32 current, unsigned int addressKind, jit_nint offset, ILJitValue outAddress)
  {
-     ILJitValue outAddressValue = outAddress;
      ILJitValue temp = jit_value_create(function, _IL_JIT_TYPE_VPTR);
      ILJitValue ptr, valuePtr;
      ILType *refType;
--- 708,715 ----
  	return 0;
  }
  
! static ILJitValue MarshalValue(jit_function_t function, ILJitValue in, ILType *type, ILUInt32 marshalType, unsigned int addressKind, jit_nint offset, ILJitValue outAddressValue)
  {
      ILJitValue temp = jit_value_create(function, _IL_JIT_TYPE_VPTR);
      ILJitValue ptr, valuePtr;
      ILType *refType;
***************
*** 408,439 ****
      ILJitValue newElemAddress;
      ILJitValue counter;
      ILJitValue arraySize;
-     ILUInt32 marshalType;
-     char *customName;
-     int customNameLen;
-     char *customCookie;
-     int customCookieLen;
-     ILMethod *method = (ILMethod *)jit_function_get_meta(function, IL_JIT_META_METHOD);
-     ILPInvoke *pinv = ILPInvokeFind(method);
-     marshalType = ILPInvokeGetMarshalType(pinv, method, current, &customName, &customNameLen,
- 							&customCookie,	&customCookieLen, type);
-     if(marshalType==IL_META_MARSHAL_DIRECT && addressKind==MARSHAL_FIRST_LEVEL_VALUE) 
-     {
-     	return in;
-     }
-     else if(marshalType==IL_META_MARSHAL_CUSTOM)
-     {
- 	    fprintf(stderr, "Custom marshaling not yet supported\n");
- 	    return 0;
-     }
- 
-     if(!NeedMarshalValue(type) && addressKind==MARSHAL_FIRST_LEVEL_VALUE)
-     {
- 	    return in;
-     }    
      type = ILTypeGetEnumType(type);
!     if(addressKind==MARSHAL_ITEM_OF_ARRAY || addressKind == MARSHAL_ITEM_OF_STRUCTURE) outAddressValue = outAddress;
!     else if(addressKind!=MARSHAL_FIRST_LEVEL_VALUE && addressKind!=MARSHAL_ITEM_OF_STRUCTURE)
      {
  	    fprintf(stderr, "addressKind has an invalid value of %d\n", addressKind);
  	    return 0;
--- 727,734 ----
      ILJitValue newElemAddress;
      ILJitValue counter;
      ILJitValue arraySize;
      type = ILTypeGetEnumType(type);
!     if(addressKind!=MARSHAL_FIRST_LEVEL_VALUE && addressKind!=MARSHAL_ITEM_OF_STRUCTURE && addressKind!=MARSHAL_ITEM_OF_ARRAY)
      {
  	    fprintf(stderr, "addressKind has an invalid value of %d\n", addressKind);
  	    return 0;
***************
*** 576,592 ****
  			{
  				case MARSHAL_ITEM_OF_ARRAY:
  				{
! 					return (ILJitValue)MarshalStruct(function, valuePtr, refType, outAddressValue, offset, MARSHAL_ITEM_OF_ARRAY);
  				}
  				break;
  				case MARSHAL_ITEM_OF_STRUCTURE:
  				{
! 					return (ILJitValue)MarshalStruct(function, valuePtr, refType, outAddressValue, offset, MARSHAL_ITEM_OF_STRUCTURE);
  				}
  				break;
  				default:
  				{
! 					return (ILJitValue)MarshalStruct(function, valuePtr, refType, 0, 0, MARSHAL_FIRST_LEVEL_VALUE);
  				}
  				break;
  			}
--- 871,887 ----
  			{
  				case MARSHAL_ITEM_OF_ARRAY:
  				{
! 					return (ILJitValue)MarshalStruct(function, valuePtr, refType, marshalType, outAddressValue, offset, MARSHAL_ITEM_OF_ARRAY);
  				}
  				break;
  				case MARSHAL_ITEM_OF_STRUCTURE:
  				{
! 					return (ILJitValue)MarshalStruct(function, valuePtr, refType, marshalType, outAddressValue, offset, MARSHAL_ITEM_OF_STRUCTURE);
  				}
  				break;
  				default:
  				{
! 					return (ILJitValue)MarshalStruct(function, valuePtr, refType, marshalType, 0, 0, MARSHAL_FIRST_LEVEL_VALUE);
  				}
  				break;
  			}
***************
*** 603,621 ****
  		default:  break;
  	}			
      }
!     else if (ILType_IsValueType(type))
      {
  	    switch(addressKind)
  	    {
  		    case MARSHAL_ITEM_OF_STRUCTURE:
  		    case MARSHAL_ITEM_OF_ARRAY:
  		    {
! 			    return (ILJitValue)MarshalStruct(function, in, type, outAddressValue, offset, MARSHAL_ITEM_OF_ARRAY);
  		    }
  		    break;
  		    default:
  		    {
! 			    return (ILJitValue)MarshalStruct(function, jit_insn_address_of(function, in), type, 0, 0, MARSHAL_FIRST_LEVEL_VALUE);
  		    }
  		    break;
  	    }
--- 898,916 ----
  		default:  break;
  	}			
      }
!     else if(ILType_IsValueType(type))
      {
  	    switch(addressKind)
  	    {
  		    case MARSHAL_ITEM_OF_STRUCTURE:
  		    case MARSHAL_ITEM_OF_ARRAY:
  		    {
! 			    return (ILJitValue)MarshalStruct(function, in, type, marshalType, outAddressValue, offset, MARSHAL_ITEM_OF_ARRAY);
  		    }
  		    break;
  		    default:
  		    {
! 			    return (ILJitValue)MarshalStruct(function, jit_insn_address_of(function, in), type, marshalType, 0, 0, MARSHAL_FIRST_LEVEL_VALUE);
  		    }
  		    break;
  	    }
***************
*** 625,673 ****
  	    args[0] = _ILJitFunctionGetThread(function);
  	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) args[1] = in;
  	    else args[1] = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
  
  	    switch(marshalType)
  	    {
  			case IL_META_MARSHAL_ANSI_STRING:
  			{
! 				    jit_insn_store(function, temp, jit_insn_call_native(function,
! 						    "ILStringToAnsi",
! 						    ILStringToAnsi,
! 						    _ILJitSignature_ILStringToAnsi,
! 						    args, 2, JIT_CALL_NOTHROW));
  			}
  			break;
  			case IL_META_MARSHAL_UTF8_STRING:
  			{
! 				    jit_insn_store(function, temp, jit_insn_call_native(function,
! 						    "ILStringToUTF8",
! 						    ILStringToUTF8,
! 						    _ILJitSignature_ILStringToUTF8,
! 						    args, 2, JIT_CALL_NOTHROW));
  			}
  			break;
  			case IL_META_MARSHAL_UTF16_STRING:
  			{
! 				    jit_insn_store(function, temp, jit_insn_call_native(function,
! 						    "ILStringToUTF16",
! 						    ILStringToUTF16,
! 						    _ILJitSignature_ILStringToUTF16,
! 						    args, 2, JIT_CALL_NOTHROW));
  			}
  			break;
  			default:
  			{
! 				fprintf(stderr, "Unsupported string char set in marshaling\n");
! 				return 0;
! 			};
  	    }
  
  	    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
  		    jit_insn_store_relative(function, outAddressValue, offset, temp);
  	    return temp;
      }
! 
!     else if(type!=0 && ILTypeIsDelegate(type))
      {
  	    temp = jit_insn_dup(function, in);
  	    if(addressKind!=MARSHAL_FIRST_LEVEL_VALUE)
--- 920,976 ----
  	    args[0] = _ILJitFunctionGetThread(function);
  	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) args[1] = in;
  	    else args[1] = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
+ 	    char *customName;
+ 	    int customNameLen;
+ 	    char *customCookie;
+ 	    int customCookieLen;
+ 	    ILMethod *method = (ILMethod *)jit_function_get_meta(function, IL_JIT_META_METHOD);
+ 	    marshalType = ILPInvokeGetMarshalType
+ 			    (0, method, 0, &customName, &customNameLen, &customCookie, &customCookieLen, type);
  
  	    switch(marshalType)
  	    {
  			case IL_META_MARSHAL_ANSI_STRING:
  			{
! 				temp = jit_insn_call_native(function,
! 							    "ILStringToAnsi",
! 							    ILStringToAnsi,
! 							    _ILJitSignature_ILStringToAnsi,
! 							    args, 2, JIT_CALL_NOTHROW);
  			}
  			break;
  			case IL_META_MARSHAL_UTF8_STRING:
  			{
! 				temp = jit_insn_call_native(function,
! 							    "ILStringToUTF8",
! 							    ILStringToUTF8,
! 							    _ILJitSignature_ILStringToUTF8,
! 							    args, 2, JIT_CALL_NOTHROW);
  			}
  			break;
  			case IL_META_MARSHAL_UTF16_STRING:
  			{
! 				temp = jit_insn_call_native(function,
! 	    						    "ILStringToUTF16",
! 							    ILStringToUTF16,
! 							    _ILJitSignature_ILStringToUTF16,
! 							    args, 2, JIT_CALL_NOTHROW);
  			}
  			break;
  			default:
  			{
! 				temp = args[1];
! 			}
! 			break;
  	    }
  
  	    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
+ 	    {
  		    jit_insn_store_relative(function, outAddressValue, offset, temp);
+ 	    }
  	    return temp;
      }
!     else if(type!=0 && ILTypeIsDelegateSubClass(type))
      {
  	    temp = jit_insn_dup(function, in);
  	    if(addressKind!=MARSHAL_FIRST_LEVEL_VALUE)
***************
*** 676,689 ****
  	    }
  	    ILJitValue closure = jit_insn_load_relative(function, temp, offsetof(System_Delegate, closure), _IL_JIT_TYPE_VPTR);
  	    jit_insn_branch_if(function, jit_insn_to_bool(function, closure), &endLabel);
! 	    args[0] = _ILJitFunctionGetThread(function);
! 	    args[1] = jit_insn_dup(function, temp);
! 	    args[2] = jit_value_create_nint_constant(function, _IL_JIT_TYPE_VPTR, (jit_nint)type);
  	    jit_insn_store(function, closure, jit_insn_call_native(function,
  					    "ILJitDelegateGetClosure",
  					    ILJitDelegateGetClosure,
  					    _ILJitSignature_ILJitDelegateGetClosure,
! 					    args, 3, JIT_CALL_NOTHROW));
  	    jit_insn_label(function, &endLabel);
  	    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
  		    jit_insn_store_relative(function, outAddressValue, offset, closure);
--- 979,991 ----
  	    }
  	    ILJitValue closure = jit_insn_load_relative(function, temp, offsetof(System_Delegate, closure), _IL_JIT_TYPE_VPTR);
  	    jit_insn_branch_if(function, jit_insn_to_bool(function, closure), &endLabel);
! 	    args[0] = jit_insn_dup(function, temp);
! 	    args[1] = jit_value_create_nint_constant(function, _IL_JIT_TYPE_VPTR, (jit_nint)type);
  	    jit_insn_store(function, closure, jit_insn_call_native(function,
  					    "ILJitDelegateGetClosure",
  					    ILJitDelegateGetClosure,
  					    _ILJitSignature_ILJitDelegateGetClosure,
! 					    args, 2, JIT_CALL_NOTHROW));
  	    jit_insn_label(function, &endLabel);
  	    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
  		    jit_insn_store_relative(function, outAddressValue, offset, closure);
***************
*** 707,716 ****
  				    jit_insn_store(function, srcArray, jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR));
  			    else jit_insn_store(function, srcArray, in);
  			    elemType = ILType_Ref(type);
  			    if(NeedMarshalValue(elemType))
  			    {
  				        MarshalValue(function, jit_insn_dup(function, srcArray),
! 						    	    elemType, 0, 
  							    MARSHAL_ITEM_OF_STRUCTURE,
  							    0,
  							    jit_insn_dup(function, srcArray));
--- 1009,1019 ----
  				    jit_insn_store(function, srcArray, jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR));
  			    else jit_insn_store(function, srcArray, in);
  			    elemType = ILType_Ref(type);
+ 			    elemType = ILTypeGetEnumType(elemType);
  			    if(NeedMarshalValue(elemType))
  			    {
  				        MarshalValue(function, jit_insn_dup(function, srcArray),
! 						    	    elemType, marshalType, 
  							    MARSHAL_ITEM_OF_STRUCTURE,
  							    0,
  							    jit_insn_dup(function, srcArray));
***************
*** 720,813 ****
  			    return srcArray;
  		    }
  		    break;
! 		    default: break;
! 		    }
  
! 		    if(ILType_IsSimpleArray(type))
  		    {
! 			    srcArray = in;
! 			    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
! 				    srcArray = jit_insn_load_relative(function, srcArray, offset, _IL_JIT_TYPE_VPTR);
! 			    elemType = ILType_ElemType(type);
! 			    if(!NeedMarshalValue(elemType))
  			    {
! 				    jit_insn_store(function, newArray, srcArray);
! 				    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE)
! 				    {
! 					    jit_insn_store(function, newArray, jit_insn_add_relative(function,
! 				    	    					newArray,
! 				    						(jit_nint)(sizeof(ILUInt32))));
! 				    }
! 				    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
! 				    	    jit_insn_store_relative(function, outAddressValue, offset, newArray);
! 				    return newArray;
  			    }
- 
- 			    // The size of a simple array can be known only on run-time.
- 			    arraySize = jit_insn_load_relative(function, srcArray, 0, _IL_JIT_TYPE_UINT32);
- 			    thread = ILExecThreadCurrent();
- 			    srcElemSize = jit_value_create_nint_constant(function,
- 				    						_IL_JIT_TYPE_INT32,
- 										(jit_nint)(ILSizeOfType(thread, elemType)));
- 			    newElemSize = jit_value_create_nint_constant(function,
- 										_IL_JIT_TYPE_INT32,
- 									    	(jit_nint)(ILSizeOfType(thread, elemType)));
- 			    newArraySize = jit_insn_mul(function, arraySize, newElemSize);
- 			    newArraySize = jit_insn_add_relative(function, newArraySize, (jit_nint)sizeof(ILUInt32));
- 		 	    args[0] = newArraySize;
- 			    jit_insn_store(function, newArray, jit_insn_call_native(function, "_ILMalloc",
- 			    			    			ILGCAlloc,
- 			    			    			_ILJitSignature_malloc,
- 			    						args, 1, 0));
- 
- 			    jit_insn_branch_if(function,
- 						jit_insn_eq(function, arraySize,
- 									jit_value_create_nint_constant
- 										(function, _IL_JIT_TYPE_UINT32, 0)),
- 										&endLoop);
- 			    srcElemAddress = jit_insn_add_relative(function,
- 									srcArray,
- 									(jit_nint)(sizeof(ILUInt32)));
- 			    newElemAddress = jit_insn_dup(function, newArray);
- 			    counter = arraySize;
- 			    jit_insn_label(function, &startLoop);
- 			    jit_insn_store(function, counter, jit_insn_sub(function, counter,
- 		    									jit_value_create_nint_constant(function,
- 											_IL_JIT_TYPE_INT32,
- 											1)));
- 			    MarshalValue(function, jit_insn_dup(function, srcElemAddress),
- 							elemType, 0,
- 							MARSHAL_ITEM_OF_ARRAY,
- 							0,
- 							jit_insn_dup(function, newElemAddress));
- 			    jit_insn_store(function, srcElemAddress,
- 							    jit_insn_add(function,
- 							    srcElemAddress, srcElemSize));
- 			    jit_insn_store(function, newElemAddress,
- 							jit_insn_add(function,
- 							newElemAddress, newElemSize));
- 			    jit_insn_branch_if(function,
- 					        jit_insn_to_bool(function, counter),
- 					        &(startLoop));
- 			    jit_insn_label(function, &endLoop);
  			    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
! 					jit_insn_store_relative(function, outAddressValue, offset, newArray);
  			    return newArray;
  		    }
! 		    else if (ILType_IsArray(type))
! 		    {
! 			    fprintf(stderr, "Multidimential arrays are not supported for marshaling\n");
!     		    	    return 0;
!     		    }
      }
- 
      if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) return in;
      temp = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
      jit_insn_store_relative(function, outAddressValue, offset, temp);
      return temp;
  }
  
! static ILJitValue MarshalStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind)
  {
          ILClass *classInfo = ILClassResolve(ILType_ToValueType(structureILType));
  	ILExecThread *thread = ILExecThreadCurrent();
--- 1023,1117 ----
  			    return srcArray;
  		    }
  		    break;
!     		    default: break;
! 	    }
  
! 	    if(ILType_IsSimpleArray(type))
! 	    {
! 		    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
! 			    srcArray = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
! 		    else srcArray = in;
! 		    jit_insn_store(function, newArray, srcArray);
! 		    jit_insn_branch_if_not(function, jit_insn_to_bool(function, newArray),
! 						    &endLoop);
! 		    elemType = ILType_ElemType(type);
! 		    elemType = ILTypeGetEnumType(elemType);
! 		    if(!NeedMarshalValue(elemType))
  		    {
! 			    jit_insn_store(function, newArray, srcArray);
! 			    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE)
  			    {
! 				    jit_insn_store(function, newArray, jit_insn_add_relative(function,
! 				    	    				newArray,
! 				    					(jit_nint)(sizeof(ILUInt32))));
  			    }
  			    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
! 				    	jit_insn_store_relative(function, outAddressValue, offset, newArray);
  			    return newArray;
  		    }
! 		    // The size of a simple array can be known only on run-time.
! 		    arraySize = jit_insn_load_relative(function, srcArray, 0, _IL_JIT_TYPE_UINT32);
! 		    thread = ILExecThreadCurrent();
! 		    srcElemSize = jit_value_create_nint_constant(function,
! 			    						_IL_JIT_TYPE_INT32,
! 									(jit_nint)(ILSizeOfType(thread, elemType)));
! 		    newElemSize = jit_value_create_nint_constant(function,
! 									_IL_JIT_TYPE_INT32,
! 								    	(jit_nint)(ILSizeOfType(thread, elemType)));
! 		    newArraySize = jit_insn_mul(function, arraySize, newElemSize);
! 		    args[0] = newArraySize;
! 		    jit_insn_store(function, newArray, jit_insn_call_native(function, "ILGCAllocAtomic",
! 			    						ILGCAllocAtomic,
! 			    				    		_ILJitSignature_malloc,
! 			    						args, 1, 0));
! 		    jit_insn_branch_if(function,
! 					jit_insn_eq(function, arraySize,
! 							    jit_value_create_nint_constant
! 									(function, _IL_JIT_TYPE_UINT32, 0)),
! 									&endLoop);
! 		    srcElemAddress = jit_insn_add_relative(function,
! 								srcArray,
! 								(jit_nint)(sizeof(ILUInt32)));
! 		    newElemAddress = jit_value_create(function, jit_type_int);
! 		    jit_insn_store(function, newElemAddress, newArray);
! 		    counter = jit_insn_dup(function, arraySize);
! 		    jit_insn_label(function, &startLoop);
! 		    jit_insn_store(function, counter, jit_insn_sub(function, counter,
! 		    								jit_value_create_nint_constant(function,
! 										_IL_JIT_TYPE_INT32,
! 										1)));
! 		    MarshalValue(function, srcElemAddress, elemType,
! 							    marshalType,
! 							    MARSHAL_ITEM_OF_ARRAY,
! 							    0,
! 							    newElemAddress);
! 		    jit_insn_store(function, srcElemAddress,
! 						    jit_insn_add(function,
! 						    srcElemAddress, srcElemSize));
! 		    jit_insn_store(function, newElemAddress,
! 						jit_insn_add(function,
! 						newElemAddress, newElemSize));
! 		    jit_insn_branch_if(function,
! 					    jit_insn_to_bool(function, counter),
! 					    &(startLoop));
! 		    jit_insn_label(function, &endLoop);
! 		    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
! 				jit_insn_store_relative(function, outAddressValue, offset, newArray);
! 		    return newArray;
! 	    }
! 	    else if (ILType_IsArray(type))
! 	    {
! 		    fprintf(stderr, "Multidimential arrays are not supported for marshaling\n");
!     		    return 0;
!     	    }
      }
      if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) return in;
      temp = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
      jit_insn_store_relative(function, outAddressValue, offset, temp);
      return temp;
  }
  
! static ILJitValue MarshalStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILUInt32 marshalType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind)
  {
          ILClass *classInfo = ILClassResolve(ILType_ToValueType(structureILType));
  	ILExecThread *thread = ILExecThreadCurrent();
***************
*** 820,826 ****
  		case MARSHAL_FIRST_LEVEL_VALUE:
  		{
  			ILJitValue sizeValue = jit_value_create_nint_constant(function, _IL_JIT_TYPE_UINT32, structSize);
! 			outAddress = jit_insn_call_native(function, "_ILMalloc",
  								    ILGCAlloc,
  								    _ILJitSignature_malloc,
  								    &sizeValue, 1, 0);
--- 1124,1130 ----
  		case MARSHAL_FIRST_LEVEL_VALUE:
  		{
  			ILJitValue sizeValue = jit_value_create_nint_constant(function, _IL_JIT_TYPE_UINT32, structSize);
! 			outAddress = jit_insn_call_native(function, "ILGCAlloc",
  								    ILGCAlloc,
  								    _ILJitSignature_malloc,
  								    &sizeValue, 1, 0);
***************
*** 850,908 ****
  			{
  				case MARSHAL_FIRST_LEVEL_VALUE:
  				{
! 					MarshalValue(function, inAddress, type, 0, MARSHAL_ITEM_OF_STRUCTURE, field->offset + offset, outAddress);
  				}
  			        break;
  				case MARSHAL_ITEM_OF_STRUCTURE:
  				{
! 					MarshalValue(function, inAddress, type, 0, MARSHAL_ITEM_OF_STRUCTURE, field->offset + offset, outAddress);
  				}
  				break;
  				default:
  				{
! 					MarshalValue(function, inAddress, type, 0, MARSHAL_ITEM_OF_ARRAY, field->offset + offset, outAddress);
  				}
  				break;
  			}
  		}
  	}
- 	
  	return outAddress;
  }
  
! 
! static ILJitValue MarshalReturnValue(jit_function_t function, ILJitValue in, ILType *type, unsigned int addressKind, jit_nint offset, ILJitValue outAddress)
  {
!     ILJitValue retValue;    
      ILJitValue outAddressValue = outAddress;
      ILJitValue temp = jit_value_create(function, _IL_JIT_TYPE_VPTR);
      ILJitValue args[3];
      ILJitValue srcArray = jit_value_create(function, _IL_JIT_TYPE_VPTR);
-     ILUInt32 marshalType;
-     char *customName;
-     int customNameLen;
-     char *customCookie;
-     int customCookieLen;
-     ILMethod *method = (ILMethod *)jit_function_get_meta(function, IL_JIT_META_METHOD);
-     ILPInvoke *pinv = ILPInvokeFind(method);
-     marshalType = ILPInvokeGetMarshalType(pinv, method, 1, &customName, &customNameLen,
- 							&customCookie,	&customCookieLen, type);
-     if(marshalType == IL_META_MARSHAL_DIRECT && addressKind==MARSHAL_FIRST_LEVEL_VALUE)
-     {
- 	    return in;
-     }
-     else if(marshalType == IL_META_MARSHAL_CUSTOM)
-     {
- 	    fprintf(stderr, "custom marshaling of return value is not supported\n");
- 	    return 0;
-     }
      type = ILTypeGetEnumType(type);
  
-     if(addressKind==MARSHAL_FIRST_LEVEL_VALUE && !NeedMarshalValue(type))
-     {
- 	    return in;
-     }
- 
      switch(addressKind)
      {    
  	    case MARSHAL_FIRST_LEVEL_VALUE:
--- 1154,1187 ----
  			{
  				case MARSHAL_FIRST_LEVEL_VALUE:
  				{
! 					MarshalValue(function, inAddress, type, marshalType, MARSHAL_ITEM_OF_STRUCTURE, field->offset + offset, outAddress);
  				}
  			        break;
  				case MARSHAL_ITEM_OF_STRUCTURE:
  				{
! 					MarshalValue(function, inAddress, type, marshalType, MARSHAL_ITEM_OF_STRUCTURE, field->offset + offset, outAddress);
  				}
  				break;
  				default:
  				{
! 					MarshalValue(function, inAddress, type, marshalType, MARSHAL_ITEM_OF_ARRAY, field->offset + offset, outAddress);
  				}
  				break;
  			}
  		}
  	}
  	return outAddress;
  }
  
! static ILJitValue MarshalReturnValue(jit_function_t function, ILJitValue in, ILType *type, ILUInt32 marshalType, unsigned int addressKind, jit_nint offset, ILJitValue outAddress)
  {
!     ILJitValue retValue;
      ILJitValue outAddressValue = outAddress;
      ILJitValue temp = jit_value_create(function, _IL_JIT_TYPE_VPTR);
      ILJitValue args[3];
      ILJitValue srcArray = jit_value_create(function, _IL_JIT_TYPE_VPTR);
      type = ILTypeGetEnumType(type);
  
      switch(addressKind)
      {    
  	    case MARSHAL_FIRST_LEVEL_VALUE:
***************
*** 1062,1105 ****
      }
      else if(ILType_IsValueType(type))
      {
! 	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) return (ILJitValue)MarshalReturnStruct(function, jit_insn_address_of(function, in), type, 0, 0, MARSHAL_FIRST_LEVEL_VALUE);
! 	    temp = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
! 	    retValue = (ILJitValue)MarshalReturnStruct(function, temp, type, outAddressValue, offset, MARSHAL_ITEM_OF_STRUCTURE);
  	    jit_insn_store_relative(function, outAddressValue, offset, retValue);
  	    return retValue;
      }
      else if(ILTypeIsStringClass(type))
      {
  	    args[0] = _ILJitFunctionGetThread(function);
! 	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) args[1] = in;
  	    else args[1] = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
  	    switch(marshalType)
  	    {
  			case IL_META_MARSHAL_ANSI_STRING:
  			{
! 				    jit_insn_store(function, temp, jit_insn_call_native(function,
  						    "ILStringCreate",
  						    ILStringCreate,
  						    _ILJitSignature_ILStringCreate,
! 						    args, 2, JIT_CALL_NOTHROW));
  			}
  			break;
  			case IL_META_MARSHAL_UTF8_STRING:
  			{
! 				    jit_insn_store(function, temp, jit_insn_call_native(function,
  						    "ILStringCreateUTF8",
  						    ILStringCreateUTF8,
  						    _ILJitSignature_ILStringCreateUTF8,
! 						    args, 2, JIT_CALL_NOTHROW));
  			}
  			break;
  			case IL_META_MARSHAL_UTF16_STRING:
  			{
! 				    jit_insn_store(function, temp, jit_insn_call_native(function,
! 						    "ILStringWCreate",
! 						    ILStringWCreate,
! 						    _ILJitSignature_ILStringWCreate,
! 						    args, 2, JIT_CALL_NOTHROW));
  			}
  			break;
  	    }
--- 1341,1395 ----
      }
      else if(ILType_IsValueType(type))
      {
! 	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) return (ILJitValue)MarshalReturnStruct(function, jit_insn_address_of(function, in), type, marshalType, 0, 0, MARSHAL_FIRST_LEVEL_VALUE);
! 	    retValue = (ILJitValue)MarshalReturnStruct(function, in, type, marshalType, outAddressValue, offset, MARSHAL_ITEM_OF_STRUCTURE);
  	    jit_insn_store_relative(function, outAddressValue, offset, retValue);
  	    return retValue;
      }
      else if(ILTypeIsStringClass(type))
      {
  	    args[0] = _ILJitFunctionGetThread(function);
! 	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) args[1] = jit_insn_dup(function, in);
  	    else args[1] = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
+ 	    char *customName;
+ 	    int customNameLen;
+ 	    char *customCookie;
+ 	    int customCookieLen;
+ 	    ILMethod *method = (ILMethod *)jit_function_get_meta(function, IL_JIT_META_METHOD);
+ 	    marshalType = ILPInvokeGetMarshalType
+ 			    (0, method, 0, &customName, &customNameLen, &customCookie, &customCookieLen, type);
  	    switch(marshalType)
  	    {
  			case IL_META_MARSHAL_ANSI_STRING:
  			{
! 				temp = jit_insn_call_native(function,
  						    "ILStringCreate",
  						    ILStringCreate,
  						    _ILJitSignature_ILStringCreate,
! 						    args, 2, JIT_CALL_NOTHROW);
  			}
  			break;
  			case IL_META_MARSHAL_UTF8_STRING:
  			{
! 				temp = jit_insn_call_native(function,
  						    "ILStringCreateUTF8",
  						    ILStringCreateUTF8,
  						    _ILJitSignature_ILStringCreateUTF8,
! 						    args, 2, JIT_CALL_NOTHROW);
  			}
  			break;
  			case IL_META_MARSHAL_UTF16_STRING:
  			{
! 				temp = jit_insn_call_native(function,
! 							    "ILStringWCreate",
! 							    ILStringWCreate,
! 							    _ILJitSignature_ILStringWCreate,
! 							    args, 2, JIT_CALL_NOTHROW);
! 			}
! 			break;
! 			default:
! 			{
! 				temp = args[1];
  			}
  			break;
  	    }
***************
*** 1112,1126 ****
  	    fprintf(stderr, "Marshaling of a delegate as a return value is not supported\n");
  	    return 0;
      }
!     else if(ILType_IsClass(type))
!     {
! 	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) return in;
! 	    temp = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
! 	    jit_insn_store_relative(function, outAddressValue, offset, temp);
! 	    retValue = temp;
! 	    return retValue;
!     }
!     else if(type !=0 && ILType_IsComplex(type))
      {
  	    switch(ILType_Kind(type))
  	    {
--- 1402,1408 ----
  	    fprintf(stderr, "Marshaling of a delegate as a return value is not supported\n");
  	    return 0;
      }
!     else if(type!=0 && ILType_IsComplex(type))
      {
  	    switch(ILType_Kind(type))
  	    {
***************
*** 1130,1136 ****
  			    temp = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
  			    jit_insn_store_relative(function, outAddressValue, offset, temp);
  			    return temp;
! 		    };
  		    break;
  		    case IL_TYPE_COMPLEX_BYREF:
  		    {
--- 1412,1418 ----
  			    temp = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
  			    jit_insn_store_relative(function, outAddressValue, offset, temp);
  			    return temp;
! 		    }
  		    break;
  		    case IL_TYPE_COMPLEX_BYREF:
  		    {
***************
*** 1141,1147 ****
  			    if(NeedMarshalValue(elemType))
  			    {
  				    MarshalReturnValue(function, jit_insn_dup(function, srcArray),
! 								    elemType,
  								    MARSHAL_ITEM_OF_STRUCTURE,
  								    0,
  								    jit_insn_dup(function, srcArray));
--- 1423,1429 ----
  			    if(NeedMarshalValue(elemType))
  			    {
  				    MarshalReturnValue(function, jit_insn_dup(function, srcArray),
! 								    elemType, marshalType,
  								    MARSHAL_ITEM_OF_STRUCTURE,
  								    0,
  								    jit_insn_dup(function, srcArray));
***************
*** 1158,1166 ****
  	    {
  			// The size of a simple array can be known only on run-time 
  			// and we cannot use the same return memory as it is allocated in C code.
  			fprintf(stderr, "Simple arrays not supported for marshaling as a return value");
! 			return 0;
! 			
  	    }
  	    else if(ILType_IsArray(type))
  	    {
--- 1440,1448 ----
  	    {
  			// The size of a simple array can be known only on run-time 
  			// and we cannot use the same return memory as it is allocated in C code.
+ 			// However, it is easy to be implemented using the MarshalValue case.
  			fprintf(stderr, "Simple arrays not supported for marshaling as a return value");
! 			return 0;			
  	    }
  	    else if(ILType_IsArray(type))
  	    {
***************
*** 1170,1183 ****
  
      }
  
-     // Do something smart.
      if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) return in;
      temp = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
      jit_insn_store_relative(function, outAddressValue, offset, temp);
      return temp;
  }
  
! static ILJitValue MarshalReturnStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind)
  {
      ILClass *classInfo = ILClassResolve(ILType_ToValueType(structureILType));
      ILExecThread *thread = ILExecThreadCurrent();
--- 1452,1464 ----
  
      }
  
      if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) return in;
      temp = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
      jit_insn_store_relative(function, outAddressValue, offset, temp);
      return temp;
  }
  
! static ILJitValue MarshalReturnStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILUInt32 marshalType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind)
  {
      ILClass *classInfo = ILClassResolve(ILType_ToValueType(structureILType));
      ILExecThread *thread = ILExecThreadCurrent();
***************
*** 1189,1194 ****
--- 1470,1478 ----
  
      if(addressKind==MARSHAL_FIRST_LEVEL_VALUE)
      {
+ 	    // A returned structure should be a libjit value, so we create one.
+ 	    // Although we could use ILGCAllocAtomic with structSize - it should
+ 	    // work.
  	    structType = jit_type_create_struct(0, 0, 0);
  	    jit_type_set_size_and_alignment(structType, structSize, 0);
  	    newStruct = jit_value_create(function, structType);
***************
*** 1201,1213 ****
  	    if(!ILField_IsStatic(field))
  	    {
  		    type = ILTypeGetEnumType(ILField_Type(field));
! 		    MarshalReturnValue(function, inAddress, type, MARSHAL_ITEM_OF_STRUCTURE, field->offset, outAddress);
  	    }
      }
!     return jit_insn_dup(function, newStruct);
  }
  
! static void MarshalByRefValue(jit_function_t function, ILJitValue in, ILType *type, ILUInt32 current, unsigned int addressKind, jit_nint offset, ILJitValue outAddress)
  {
      ILJitValue outAddressValue = outAddress;
      ILJitValue temp = jit_value_create(function, _IL_JIT_TYPE_VPTR);
--- 1485,1498 ----
  	    if(!ILField_IsStatic(field))
  	    {
  		    type = ILTypeGetEnumType(ILField_Type(field));
! 		    MarshalReturnValue(function, inAddress, type, marshalType, MARSHAL_ITEM_OF_STRUCTURE, offset + field->offset, outAddress);
  	    }
      }
!     return newStruct;
  }
  
! #ifdef USE_BYREF_MARSHALING
! static void MarshalByRefValue(jit_function_t function, ILJitValue in, ILType *type, ILUInt32 marshalType, unsigned int addressKind, jit_nint offset, ILJitValue outAddress)
  {
      ILJitValue outAddressValue = outAddress;
      ILJitValue temp = jit_value_create(function, _IL_JIT_TYPE_VPTR);
***************
*** 1223,1249 ****
      ILJitValue srcElemAddress;
      ILJitValue newElemAddress;
      ILJitValue counter;
!     ILJitValue arraySize;    
!     ILUInt32 marshalType;
!     char *customName;
!     int customNameLen;
!     char *customCookie;
!     int customCookieLen;
!     ILMethod *method = (ILMethod *)jit_function_get_meta(function, IL_JIT_META_METHOD);
!     ILPInvoke *pinv = ILPInvokeFind(method);
!     marshalType = ILPInvokeGetMarshalType(pinv, method, current, &customName, &customNameLen,
! 							&customCookie,	&customCookieLen, type);
! 	
!     if(marshalType == IL_META_MARSHAL_DIRECT && addressKind==MARSHAL_FIRST_LEVEL_VALUE)
!     {
! 	    return;
!     }
      type = ILTypeGetEnumType(type);
- 
      if(!NeedMarshalValue(type)) return;
  
      switch(addressKind)
!     {    
  	    case MARSHAL_FIRST_LEVEL_VALUE:
  	    case MARSHAL_ITEM_OF_STRUCTURE:
  	    case MARSHAL_ITEM_OF_ARRAY:
--- 1508,1519 ----
      ILJitValue srcElemAddress;
      ILJitValue newElemAddress;
      ILJitValue counter;
!     ILJitValue arraySize;
      type = ILTypeGetEnumType(type);
      if(!NeedMarshalValue(type)) return;
  
      switch(addressKind)
!     {
  	    case MARSHAL_FIRST_LEVEL_VALUE:
  	    case MARSHAL_ITEM_OF_STRUCTURE:
  	    case MARSHAL_ITEM_OF_ARRAY:
***************
*** 1353,1412 ****
  	}			
      }
      else if(ILType_IsValueType(type))
!     {	
  	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE)
  	    {
! 		    MarshalByRefStruct(function, jit_insn_address_of(function, in), type, jit_insn_address_of(function, in), 0, MARSHAL_ITEM_OF_STRUCTURE);
  		    return;
  	    }
! 	    temp = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
! 	    MarshalByRefStruct(function, temp, type, temp, offset, MARSHAL_ITEM_OF_STRUCTURE);
  	    return;
      }
      else if(ILTypeIsStringClass(type))
!     {	   
  	    args[0] = _ILJitFunctionGetThread(function);
  	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) args[1] = in;
  	    else args[1] = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
  	    switch(marshalType)
  	    {
  			case IL_META_MARSHAL_ANSI_STRING:
  			{
! 				    jit_insn_store(function, temp, jit_insn_call_native(function,
! 						    "ILStringCreate",
! 						    ILStringCreate,
! 						    _ILJitSignature_ILStringCreate,
! 						    args, 2, JIT_CALL_NOTHROW));
  			}
  			break;
  			case IL_META_MARSHAL_UTF8_STRING:
  			{
! 				    jit_insn_store(function, temp, jit_insn_call_native(function,
! 						    "ILStringCreateUTF8",
! 						    ILStringCreateUTF8,
! 						    _ILJitSignature_ILStringCreateUTF8,
! 						    args, 2, JIT_CALL_NOTHROW));
  			}
  			break;
  			case IL_META_MARSHAL_UTF16_STRING:
  			{
! 				    jit_insn_store(function, temp, jit_insn_call_native(function,
! 						    "ILStringWCreate",
! 						    ILStringWCreate,
! 						    _ILJitSignature_ILStringWCreate,
! 						    args, 2, JIT_CALL_NOTHROW));
  			}
  			break;
  	    }
  	    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
! 		    jit_insn_store_relative(function, in, offset, temp);
! 	    return;
!     }
!     else if(ILTypeIsDelegate(type))
!     {
  	    return;
      }
!     else if(ILType_IsClass(type))
      {
  	    return;
      }
--- 1623,1689 ----
  	}			
      }
      else if(ILType_IsValueType(type))
!     {
  	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE)
  	    {
! 		    MarshalByRefStruct(function, jit_insn_address_of(function, in), type, marshalType, outAddressValue, 0, MARSHAL_ITEM_OF_STRUCTURE);
  		    return;
  	    }
! 	    MarshalByRefStruct(function, in, type, marshalType, outAddressValue, offset, MARSHAL_ITEM_OF_STRUCTURE);
  	    return;
      }
      else if(ILTypeIsStringClass(type))
!     {
  	    args[0] = _ILJitFunctionGetThread(function);
  	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) args[1] = in;
  	    else args[1] = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
+ 	    char *customName;
+ 	    int customNameLen;
+ 	    char *customCookie;
+ 	    int customCookieLen;
+ 	    ILMethod *method = (ILMethod *)jit_function_get_meta(function, IL_JIT_META_METHOD);
+ 	    marshalType = ILPInvokeGetMarshalType
+ 			    (0, method, 0, &customName, &customNameLen, &customCookie, &customCookieLen, type);
  	    switch(marshalType)
  	    {
  			case IL_META_MARSHAL_ANSI_STRING:
  			{
! 				temp = jit_insn_call_native(function,
! 							    "ILStringCreate",
! 							    ILStringCreate,
! 							    _ILJitSignature_ILStringCreate,
! 							    args, 2, JIT_CALL_NOTHROW);
  			}
  			break;
  			case IL_META_MARSHAL_UTF8_STRING:
  			{
! 				temp = jit_insn_call_native(function,
! 							    "ILStringCreateUTF8",
! 							    ILStringCreateUTF8,
! 							    _ILJitSignature_ILStringCreateUTF8,
! 							    args, 2, JIT_CALL_NOTHROW);
  			}
  			break;
  			case IL_META_MARSHAL_UTF16_STRING:
  			{
! 				temp = jit_insn_call_native(function,
! 							    "ILStringWCreate",
! 							    ILStringWCreate,
! 							    _ILJitSignature_ILStringWCreate,
! 							    args, 2, JIT_CALL_NOTHROW);
! 			}
! 			break;
! 			default:
! 			{
! 				temp = args[1];
  			}
  			break;
  	    }
  	    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
! 		    jit_insn_store_relative(function, outAddressValue, offset, temp);
  	    return;
      }
!     else if(ILTypeIsDelegateSubClass(type))
      {
  	    return;
      }
***************
*** 1416,1426 ****
  	    {
  		    case IL_TYPE_COMPLEX_PTR:
  		    {
- 			    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE)return;
- 			    temp = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
- 			    jit_insn_store_relative(function, outAddressValue, offset, temp);
  			    return;
! 		    };
  		    break;
  		    case IL_TYPE_COMPLEX_BYREF:
  		    {
--- 1693,1700 ----
  	    {
  		    case IL_TYPE_COMPLEX_PTR:
  		    {
  			    return;
! 		    }
  		    break;
  		    case IL_TYPE_COMPLEX_BYREF:
  		    {
***************
*** 1430,1448 ****
  			    }
  			    else jit_insn_store(function, srcArray, in);
  			    ILType *elemType = ILType_Ref(type);
  			    if(NeedMarshalValue(elemType))
  			    {
  				    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
  				    {
  				    
  					    MarshalByRefValue(function, jit_insn_dup(function, srcArray),
! 										    elemType, current,
  										    MARSHAL_ITEM_OF_STRUCTURE,
  										    0,
  										    jit_insn_load_relative(function, outAddressValue, offset, _IL_JIT_TYPE_VPTR));
  				    }
  				    else MarshalByRefValue(function, jit_insn_dup(function, srcArray),
! 										    elemType, current,
  										    MARSHAL_ITEM_OF_STRUCTURE,
  										    0,
  										    srcArray);
--- 1704,1723 ----
  			    }
  			    else jit_insn_store(function, srcArray, in);
  			    ILType *elemType = ILType_Ref(type);
+ 			    elemType = ILTypeGetEnumType(elemType);
  			    if(NeedMarshalValue(elemType))
  			    {
  				    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
  				    {
  				    
  					    MarshalByRefValue(function, jit_insn_dup(function, srcArray),
! 										    elemType, marshalType,
  										    MARSHAL_ITEM_OF_STRUCTURE,
  										    0,
  										    jit_insn_load_relative(function, outAddressValue, offset, _IL_JIT_TYPE_VPTR));
  				    }
  				    else MarshalByRefValue(function, jit_insn_dup(function, srcArray),
! 										    elemType, marshalType,
  										    MARSHAL_ITEM_OF_STRUCTURE,
  										    0,
  										    srcArray);
***************
*** 1457,1480 ****
  	    {
  			    srcArray = in;
  			    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
  				    srcArray = jit_insn_load_relative(function, srcArray, offset, _IL_JIT_TYPE_VPTR);
  			    elemType = ILType_ElemType(type);
! 
  			    if(!NeedMarshalValue(elemType))
  			    {
  				    return;
  			    }
- 
  			    // The size of a simple array can be known only on run-time.
  			    arraySize = jit_insn_load_relative(function, outAddressValue, 0, _IL_JIT_TYPE_UINT32);
  			    thread = ILExecThreadCurrent();
  			    srcElemSize = jit_value_create_nint_constant(function,
! 				    						_IL_JIT_TYPE_INT32,
! 										(jit_nint)(ILSizeOfType(thread, elemType)));
  			    newElemSize = jit_value_create_nint_constant(function,
  										_IL_JIT_TYPE_INT32,
  									    	(jit_nint)(ILSizeOfType(thread, elemType)));
- 
  			    newArray = jit_insn_add_relative(function, outAddressValue, (jit_nint)(sizeof(ILUInt32)));
  			    jit_insn_branch_if(function,
  						jit_insn_eq(function, arraySize,
--- 1732,1759 ----
  	    {
  			    srcArray = in;
  			    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
+ 			    {
  				    srcArray = jit_insn_load_relative(function, srcArray, offset, _IL_JIT_TYPE_VPTR);
+ 			    }
+ 			    jit_insn_branch_if_not(function, jit_insn_to_bool(function, srcArray),
+ 							    &endLoop);
+ 			    jit_insn_branch_if_not(function, jit_insn_to_bool(function, outAddressValue),
+ 							    &endLoop);
  			    elemType = ILType_ElemType(type);
! 			    elemType = ILTypeGetEnumType(elemType);
  			    if(!NeedMarshalValue(elemType))
  			    {
  				    return;
  			    }
  			    // The size of a simple array can be known only on run-time.
  			    arraySize = jit_insn_load_relative(function, outAddressValue, 0, _IL_JIT_TYPE_UINT32);
  			    thread = ILExecThreadCurrent();
  			    srcElemSize = jit_value_create_nint_constant(function,
! 					    					_IL_JIT_TYPE_INT32,
! 										(jit_nint)(ILSizeOfType(thread, elemType)));			    
  			    newElemSize = jit_value_create_nint_constant(function,
  										_IL_JIT_TYPE_INT32,
  									    	(jit_nint)(ILSizeOfType(thread, elemType)));
  			    newArray = jit_insn_add_relative(function, outAddressValue, (jit_nint)(sizeof(ILUInt32)));
  			    jit_insn_branch_if(function,
  						jit_insn_eq(function, arraySize,
***************
*** 1483,1496 ****
  										&endLoop);
  			    srcElemAddress = jit_insn_dup(function, srcArray);
  			    newElemAddress = jit_insn_dup(function, newArray);
! 			    counter = arraySize;
  			    jit_insn_label(function, &startLoop);
  			    jit_insn_store(function, counter, jit_insn_sub(function, counter,
  		    									jit_value_create_nint_constant(function,
  											_IL_JIT_TYPE_INT32,
  											1)));
  			    MarshalByRefValue(function, srcElemAddress,
! 								elemType, current,
  								MARSHAL_ITEM_OF_ARRAY,
  								0,
  								newElemAddress);
--- 1762,1775 ----
  										&endLoop);
  			    srcElemAddress = jit_insn_dup(function, srcArray);
  			    newElemAddress = jit_insn_dup(function, newArray);
! 			    counter = jit_insn_dup(function, arraySize);
  			    jit_insn_label(function, &startLoop);
  			    jit_insn_store(function, counter, jit_insn_sub(function, counter,
  		    									jit_value_create_nint_constant(function,
  											_IL_JIT_TYPE_INT32,
  											1)));
  			    MarshalByRefValue(function, srcElemAddress,
! 								elemType, marshalType,
  								MARSHAL_ITEM_OF_ARRAY,
  								0,
  								newElemAddress);
***************
*** 1511,1523 ****
  		    fprintf(stderr, "Multidimential arrays are not supported for marshaling as a return value\n");
  		    return;
  	    }
- 
      }
!     // Should not reach here but, make the compiler happy.
      return;
  }
  
! static void MarshalByRefStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind)
  {
      ILClass *classInfo = ILClassResolve(ILType_ToValueType(structureILType));
      ILField *field = 0;
--- 1790,1802 ----
  		    fprintf(stderr, "Multidimential arrays are not supported for marshaling as a return value\n");
  		    return;
  	    }
      }
!     // If we handle about all the cases above then we should not reach here,
!     // however we make the compiler happy.
      return;
  }
  
! static void MarshalByRefStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILUInt32 marshalType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind)
  {
      ILClass *classInfo = ILClassResolve(ILType_ToValueType(structureILType));
      ILField *field = 0;
***************
*** 1529,1551 ****
  	    if(!ILField_IsStatic(field))
  	    {
  		    type = ILTypeGetEnumType(ILField_Type(field));
! 		    MarshalByRefValue(function, inAddress, type, 1, MARSHAL_ITEM_OF_STRUCTURE, field->offset + offset, outAddress);
  	    }
      }
      return;
  }
  
  
  
! void *ILJitDelegateGetClosure(ILExecThread *currentThread, ILObject *del, ILType *delType)
  {
- 	ILType *invokeSignature = ILMethod_Signature(((System_Delegate*)del)->methodInfo);
- 	int paramCount = ILTypeNumParams(invokeSignature);
- 	ILType *returnILType = ILTypeGetReturn(invokeSignature);
- 	ILJitType returnType = _ILJitGetReturnType(returnILType, ILExecThreadGetProcess(currentThread));
- 	ILJitType jitParamTypes[paramCount];
- 	ILJitType jitInvokeTypes[paramCount + 2];
- 	ILJitValue jitParams[paramCount + 2];
  	int current;
  	ILJitType newSignature;
  	ILType *valueType;	
--- 1808,1928 ----
  	    if(!ILField_IsStatic(field))
  	    {
  		    type = ILTypeGetEnumType(ILField_Type(field));
! 		    MarshalByRefValue(function, inAddress, type, marshalType, MARSHAL_ITEM_OF_STRUCTURE,
! 					field->offset + offset, outAddress);
  	    }
      }
      return;
  }
+ #endif // USE_BYREF_MARSHALING
+ 
+ /*
+  * Emit the code to call a delegate.
+  * args contains only the arguments passed to the method (excluding the this pointer).
+  */
+ static ILJitValue __ILJitDelegateInvokeCodeGen(ILJitFunction func,
+ 											  ILJitFunction invokeFunc,
+ 											  ILJitValue delegate,
+ 											  ILJitValue *args,
+ 											  ILUInt32 argCount)
+ {
+ 	ILJitType signature = jit_function_get_signature(invokeFunc);
+ 	ILUInt32 numArgs = jit_type_num_params(signature);
+ 	ILJitType returnType = jit_type_get_return(signature);
+ 	jit_label_t noTarget = jit_label_undefined;
+ 	jit_label_t endLabel = jit_label_undefined;
+ 	ILJitValue returnValue = 0;
+ 	ILJitValue temp;
+ 	ILJitValue target = jit_insn_load_relative(func, delegate,
+ 											   offsetof(System_Delegate, target),
+ 											   _IL_JIT_TYPE_VPTR);
+ 	ILJitValue function = jit_insn_load_relative(func, delegate,
+ 												 offsetof(System_Delegate, methodInfo),
+ 												 _IL_JIT_TYPE_VPTR);
+ 	ILJitType types[numArgs];
+ 	ILJitValue invokeArgs[numArgs];
+ 	ILUInt32 current;
+ 
+ #ifdef IL_JIT_THREAD_IN_SIGNATURE
+ 	if(argCount != numArgs - 2)
+ #else
+ 	if(argCount != numArgs - 1)
+ #endif
+ 	{
+ 		/* Something is wrong here. */
+ 	}
  
+ 	if(returnType != _IL_JIT_TYPE_VOID)
+ 	{
+ 		returnValue = jit_value_create(func, returnType);
+ 	}
+ #ifdef IL_JIT_FNPTR_ILMETHOD
+ 	/* We need to convert the methodInfo pointer to the vtable pointer first. */
+ 	function = jit_insn_call_native(func,
+ 									"ILRuntimeMethodToVtablePointer",
+ 									ILRuntimeMethodToVtablePointer,
+ 									_ILJitSignature_ILRuntimeMethodToVtablePointer,
+ 									&function, 1, 0);
+ #endif
  
+ 	jit_insn_branch_if_not(func, target, &noTarget);
+ #ifdef IL_JIT_THREAD_IN_SIGNATURE
+ 	invokeArgs[0] = _ILJitFunctionGetThread(func);
+ 	invokeArgs[1] = target;
+ #else
+ 	invokeArgs[0] = target;
+ #endif
+ 	for(current = 0; current < argCount; ++current)
+ 	{
+ 	#ifdef IL_JIT_THREAD_IN_SIGNATURE
+ 		invokeArgs[current + 2] = args[current];
+ 	#else
+ 		invokeArgs[current + 1] = args[current];
+ 	#endif
+ 	}
+ 	temp = jit_insn_call_indirect_vtable(func,
+ 										 function, signature,
+ 										 invokeArgs, numArgs, 0);
+ 	if(returnType != _IL_JIT_TYPE_VOID)
+ 	{
+ 		jit_insn_store(func, returnValue, temp);
+ 	}
+ 	jit_insn_branch(func, &endLabel);
+ 	jit_insn_label(func, &noTarget);
+ #ifdef IL_JIT_THREAD_IN_SIGNATURE
+ 	types[0] = jit_type_get_param(signature, 0);
+ 	invokeArgs[0] = _ILJitFunctionGetThread(func);
+ #endif
+ 	for(current = 0; current < argCount; ++current)
+ 	{
+ 	#ifdef IL_JIT_THREAD_IN_SIGNATURE
+ 		types[current + 1] = jit_type_get_param(signature, current + 2);
+ 		invokeArgs[current + 1] = args[current];
+ 	#else
+ 		types[current] = jit_type_get_param(signature, current + 1);
+ 		invokeArgs[current] = args[current];
+ 	#endif
+ 	}
+ 	if(!(signature = jit_type_create_signature(IL_JIT_CALLCONV_DEFAULT,
+ 											   returnType,
+ 											   types, numArgs - 1, 1)))
+ 	{
+ 		return 0;
+ 	}
+ 	temp = jit_insn_call_indirect_vtable(func,
+ 										 function, signature,
+ 										 invokeArgs, numArgs - 1, 0);
+ 	jit_type_free(signature);
+ 	if(returnType != _IL_JIT_TYPE_VOID)
+ 	{
+ 		jit_insn_store(func, returnValue, temp);
+ 	}
+ 	jit_insn_label(func, &endLabel);
+ 	return returnValue;
+ }
  
! void *ILJitDelegateGetClosure(ILObject *del, ILType *delType)
  {
  	int current;
  	ILJitType newSignature;
  	ILType *valueType;	
***************
*** 1557,1625 ****
  	ILJITCoder *jitCoder;
  	ILJitFunction delFunction;
  	ILJitValue returnValue = 0;
- 	ILJitValue tempParams[paramCount + 2];
- 	unsigned int typeFlag;
  	ILType *type;
! 	ILJitValue newValue;
      	for(current = 0; current < paramCount; ++current)
  	{
  		valueType = ILTypeGetParam(invokeSignature, current + 1);
! 		jitParamTypes[current] = _ILJitGetArgType(valueType, ILExecThreadGetProcess(currentThread));
  		jitInvokeTypes[current + 2] = jitParamTypes[current];
  	}
  	newSignature = jit_type_create_signature(jit_abi_cdecl,
  						    returnType,
  						    jitParamTypes,
  						    paramCount, 1);
  	jitInvokeTypes[0] = jit_type_void_ptr;
  	jitInvokeTypes[1] = jit_type_void_ptr;
  	delInvokeSignature = jit_type_create_signature(jit_abi_cdecl,
  							returnType,
  							jitInvokeTypes,
  							paramCount + 2, 1);
! 	method = ILTypeGetDelegateMethod(delType);
  	info = ILMethod_Owner(method);
  	classPrivate = (ILClassPrivate *)info->userData;
  	jitCoder = (ILJITCoder *)(classPrivate->process->coder);
  
  	function = jit_function_create(jitCoder->context, newSignature);
- 	delFunction = ILJitFunctionFromILMethod(method);
  
  	jit_function_set_meta(function, IL_JIT_META_METHOD, method, 0, 0);
  
  	for(current = 0; current < paramCount; ++current)
  	{
  		tempParams[current] = jit_value_get_param(function, current);
! 		jitParams[current + 2] = (ILJitValue)MarshalDelegateValue(function, jit_value_get_param(function, current), ILTypeGetParam(invokeSignature, current + 1), current + 1, 0, 0, 0, currentThread);
  	}
- 
- 	jitParams[0] = jit_value_create_nint_constant(function, jit_type_void_ptr, (jit_nint)currentThread);
- 	jitParams[1] = jit_value_create_nint_constant(function, jit_type_void_ptr, (jit_nint)del);
- 	if(returnType==jit_type_void) jit_insn_call(function, "callDelegatePinvokeMethod", delFunction, delInvokeSignature, jitParams, paramCount + 2, JIT_CALL_NOTHROW);
  	else
  	{
! 		returnValue = jit_insn_call(function, "callDelegatePinvokeMethod", delFunction, delInvokeSignature, jitParams, paramCount + 2, JIT_CALL_NOTHROW);
! 		returnValue = (ILJitValue)MarshalDelegateReturnValue(function, returnValue, returnILType, 0, 0, 0, currentThread);
  	}
  	for(current = 0; current < paramCount; ++current)
  	{
  		newValue = jitParams[current + 2];
  		type = ILTypeGetParam(invokeSignature, current + 1);
  		type = ILTypeGetEnumType(type);
! 
! 		if(type!=0 && ILType_IsSimpleArray(type))
! 		{
! 			MarshalDelegateByRefValue(function, newValue, type, current + 1, 0, 0, tempParams[current], currentThread);
! 		}
! 		else if(type!=0 && ILType_IsComplex(type))
! 		{
! 			typeFlag = ILType_Kind(type);
! 			if(typeFlag==IL_TYPE_COMPLEX_BYREF || typeFlag==IL_TYPE_COMPLEX_PTR)
  			{
! 				MarshalDelegateByRefValue(function, newValue, type, current + 1, 0, 0, tempParams[current], currentThread);
  			}
  		}
  	}
  	if(returnType==jit_type_void)jit_insn_return(function, 0);
  	else jit_insn_return(function, returnValue);
  	jit_function_compile(function);
--- 1934,2152 ----
  	ILJITCoder *jitCoder;
  	ILJitFunction delFunction;
  	ILJitValue returnValue = 0;
  	ILType *type;
! 	method = ILTypeGetDelegateMethod(delType);
! 	if(!method)
! 	{
! 		method = ((System_Delegate*)del)->methodInfo;
! 	}
! 	ILType *invokeSignature = ILMethod_Signature(method);
! 	int paramCount = ILTypeNumParams(invokeSignature);
! 	ILType *returnILType = ILTypeGetReturn(invokeSignature);
! 	ILJitType returnType = _ILJitGetReturnType(returnILType, ILExecThreadGetProcess(ILExecThreadCurrent()));
! 	ILJitType jitParamTypes[paramCount];
! 	ILJitType jitInvokeTypes[paramCount + 2];
! 	ILJitValue jitParams[paramCount + 2];
! 	ILJitValue tempParams[paramCount + 2];
! 	ILUInt32 marshalType;
! 	char *customName;
! 	int customNameLen;
! 	char *customCookie;
! 	int customCookieLen;
! 
      	for(current = 0; current < paramCount; ++current)
  	{
  		valueType = ILTypeGetParam(invokeSignature, current + 1);
! 		jitParamTypes[current] = _ILJitGetArgType(valueType, ILExecThreadGetProcess(ILExecThreadCurrent()));
! #ifdef IL_JIT_THREAD_IN_SIGNATURE
  		jitInvokeTypes[current + 2] = jitParamTypes[current];
+ #else
+ 		jitInvokeTypes[current + 1] = jitParamTypes[current];
+ #endif
  	}
  	newSignature = jit_type_create_signature(jit_abi_cdecl,
  						    returnType,
  						    jitParamTypes,
  						    paramCount, 1);
  	jitInvokeTypes[0] = jit_type_void_ptr;
+ #ifdef IL_JIT_THREAD_IN_SIGNATURE
  	jitInvokeTypes[1] = jit_type_void_ptr;
+ #endif
  	delInvokeSignature = jit_type_create_signature(jit_abi_cdecl,
  							returnType,
  							jitInvokeTypes,
+ #ifdef IL_JIT_THREAD_IN_SIGNATURE
  							paramCount + 2, 1);
! #else
! 							paramCount + 1, 1);
! #endif
  	info = ILMethod_Owner(method);
  	classPrivate = (ILClassPrivate *)info->userData;
  	jitCoder = (ILJITCoder *)(classPrivate->process->coder);
  
  	function = jit_function_create(jitCoder->context, newSignature);
  
  	jit_function_set_meta(function, IL_JIT_META_METHOD, method, 0, 0);
  
  	for(current = 0; current < paramCount; ++current)
  	{
  		tempParams[current] = jit_value_get_param(function, current);
! 		type = ILTypeGetParam(invokeSignature, current + 1);
! 		marshalType = ILPInvokeGetMarshalType(0, method, current + 1, &customName, &customNameLen,
! 									      &customCookie, &customCookieLen,
! 									      type);
! #ifdef IL_JIT_THREAD_IN_SIGNATURE
! 		jitParams[current + 2] = jit_value_get_param(function, current);
! #else
! 		jitParams[current + 1] = jit_value_get_param(function, current);
! #endif
! 		if(marshalType==IL_META_MARSHAL_CUSTOM)
! 		{
! 			ILJitValue params[4];
! 			params[0] = jit_value_get_param(function, current);
! 			params[1] = jit_value_create_nint_constant(function, _IL_JIT_TYPE_VPTR, (jit_nint)type);
! 			params[2] = jit_value_create_nint_constant(function, _IL_JIT_TYPE_VPTR, (jit_nint)method);
! 			params[3] = _ILJitFunctionGetThread(function);
! 			returnValue = jit_insn_call_native(function, "MarshalCustomToObject", MarshalCustomToObject,
! 							    _ILJitSignature_MarshalCustomToObject, params, 4, JIT_CALL_NOTHROW);
! 		}
! #ifdef IL_JIT_THREAD_IN_SIGNATURE
! 		else if((!jitParams[current + 2] || marshalType != IL_META_MARSHAL_DIRECT) && NeedMarshalValue(type))
! #else
! 		else if((!jitParams[current + 1] || marshalType != IL_META_MARSHAL_DIRECT) && NeedMarshalValue(type))
! #endif
! 		{
! #ifdef IL_JIT_THREAD_IN_SIGNATURE
! 			jitParams[current + 2] =
! #else
! 			jitParams[current + 1] =
! #endif
! 						    (ILJitValue)MarshalDelegateValue(function, jit_value_get_param(function, current), type,
! 										    marshalType, MARSHAL_FIRST_LEVEL_VALUE, 0, 0);
! 		}
! 	}
! 	marshalType = ILPInvokeGetMarshalType
! 			(0, method, 0, &customName, &customNameLen,
! 			 &customCookie, &customCookieLen, returnILType);
! 	if(!ILTypeIsDelegate(delType))
!         {
! 		delFunction = jit_function_create(jitCoder->context, delInvokeSignature);	
! 		returnValue = __ILJitDelegateInvokeCodeGen(function, delFunction,
! 									jit_value_create_nint_constant(function, _IL_JIT_TYPE_VPTR, (jit_nint)del),
! #ifdef IL_JIT_THREAD_IN_SIGNATURE
! 									&jitParams[2], paramCount);
! #else
! 									&jitParams[1], paramCount);
! #endif
! 		if(returnType!=jit_type_void)
! 		{
! 			if(marshalType==IL_META_MARSHAL_CUSTOM)
! 			{
! 				ILJitValue params[4];
! 				params[0] = returnValue;
! 				params[1] = jit_value_create_nint_constant(function, _IL_JIT_TYPE_VPTR, (jit_nint)returnILType);
! 				params[2] = jit_value_create_nint_constant(function, _IL_JIT_TYPE_VPTR, (jit_nint)method);
! 				params[3] = _ILJitFunctionGetThread(function);
! 				returnValue = jit_insn_call_native(function, "MarshalObjectToCustom",
! 										MarshalObjectToCustom,
! 										_ILJitSignature_MarshalObjectToCustom,
! 										params, 4, JIT_CALL_NOTHROW);
! 			}
! 			else if((!ILTypeIsStringClass(returnILType) || marshalType!=IL_META_MARSHAL_DIRECT)
! 					&& NeedMarshalValue(returnILType))
! 			{
! 				returnValue = (ILJitValue)MarshalDelegateReturnValue(function, returnValue,
! 											returnILType, marshalType,
! 											MARSHAL_FIRST_LEVEL_VALUE, 0,
! 											0);
! 			}
! 		}
  	}
  	else
  	{
! 		delFunction = ILJitFunctionFromILMethod(method);
! #ifdef IL_JIT_THREAD_SIGNATURE
! 		jitParams[0] = _ILJitFunctionGetThread(function);
! 		jitParams[1] = jit_value_create_nint_constant(function, jit_type_void_ptr, (jit_nint)del);
! #else
! 		jitParams[0] = jit_value_create_nint_constant(function, jit_type_void_ptr, (jit_nint)del);
! #endif
! 		if(returnType==jit_type_void) jit_insn_call(function, "callDelegatePinvokeMethod",
! 							    delFunction, delInvokeSignature,
! #ifdef IL_JIT_THREAD_SIGNATURE
! 							    jitParams, paramCount + 2,
! #else
! 							    jitParams, paramCount + 1,
! #endif
! 							    JIT_CALL_NOTHROW);
! 		else
! 		{
! 			returnValue = jit_insn_call(function, "callDelegatePinvokeMethod",
! 						    delFunction, delInvokeSignature,
! #ifdef IL_JIT_THREAD_SIGNATURE
! 						    jitParams, paramCount + 2,
! #else
! 						    jitParams, paramCount + 1,
! #endif
! 						    JIT_CALL_NOTHROW);
! 			if(marshalType==IL_META_MARSHAL_CUSTOM)
! 			{
! 				ILJitValue params[4];
! 				params[0] = returnValue;
! 				params[1] = jit_value_create_nint_constant(function, _IL_JIT_TYPE_VPTR, (jit_nint)returnILType);
! 				params[2] = jit_value_create_nint_constant(function, _IL_JIT_TYPE_VPTR, (jit_nint)method);
! 				params[3] = _ILJitFunctionGetThread(function);
! 				returnValue = jit_insn_call_native(function, "MarshalObjectToCustom", MarshalObjectToCustom,
! 									    _ILJitSignature_MarshalObjectToCustom, params, 4, JIT_CALL_NOTHROW);
! 			}
! 			else if((!ILTypeIsStringClass(returnILType) || marshalType!=IL_META_MARSHAL_DIRECT)
! 				    && NeedMarshalValue(returnILType))
! 			{
! 				returnValue = (ILJitValue)MarshalDelegateReturnValue(function, returnValue,
! 											returnILType, marshalType,
! 											MARSHAL_FIRST_LEVEL_VALUE, 0,
! 											0);
! 			}
! 		}	
  	}
+ 
+ #ifdef USE_BYREF_MARSHALING
  	for(current = 0; current < paramCount; ++current)
  	{
+ #ifdef IL_JIT_THREAD_IN_SIGNATURE
  		newValue = jitParams[current + 2];
+ #else
+ 		newValue = jitParams[current + 1];
+ #endif
  		type = ILTypeGetParam(invokeSignature, current + 1);
  		type = ILTypeGetEnumType(type);
! 		marshalType = ILPInvokeGetMarshalType
! 					(0, method, current, &customName, &customNameLen,
! 							&customCookie, &customCookieLen, type);
! 		if((ILTypeIsStringClass(type) || type!=IL_META_MARSHAL_DIRECT)
! 			&& NeedMarshalValue(type) && marshalType!=IL_META_MARSHAL_CUSTOM && type!=0)
! 		{
! 			if(ILType_IsSimpleArray(type))
! 			{
! 				// Does anyone use this?
! 				MarshalDelegateByRefValue(function, newValue, type, marshalType,
! 				 				    MARSHAL_FIRST_LEVEL_VALUE, 0,
! 			 					    tempParams[current]);
! 			}
! 			else if(ILType_IsComplex(type))
  			{
! 				typeFlag = ILType_Kind(type);
! 				if(typeFlag==IL_TYPE_COMPLEX_BYREF || typeFlag==IL_TYPE_COMPLEX_PTR)
! 				{
! 					// Does anyone use this?
! 					MarshalDelegateByRefValue(function, newValue, type, marshalType, 
! 									    MARSHAL_FIRST_LEVEL_VALUE, 0, 
! 									    tempParams[current]);
! 				}
  			}
  		}
  	}
+ #endif
  	if(returnType==jit_type_void)jit_insn_return(function, 0);
  	else jit_insn_return(function, returnValue);
  	jit_function_compile(function);
***************
*** 1627,1634 ****
  	return ((System_Delegate*)del)->closure;
  }
  
! 
! static ILJitValue MarshalDelegateValue(jit_function_t function, ILJitValue in, ILType *type, ILUInt32 current, unsigned int addressKind, jit_nint offset, ILJitValue outAddress, ILExecThread *thread)
  {
      ILJitValue retValue;
      ILJitValue outAddressValue = outAddress;
--- 2154,2160 ----
  	return ((System_Delegate*)del)->closure;
  }
  
! static ILJitValue MarshalDelegateValue(jit_function_t function, ILJitValue in, ILType *type, ILUInt32 marshalType, unsigned int addressKind, jit_nint offset, ILJitValue outAddress)
  {
      ILJitValue retValue;
      ILJitValue outAddressValue = outAddress;
***************
*** 1638,1669 ****
      ILJitValue srcElemSize;
      ILType *elemType;
      ILJitValue newElemSize, newArraySize;
!     ILJitValue newArray;
      jit_label_t startLoop = jit_label_undefined;
      jit_label_t endLoop = jit_label_undefined;
      ILJitValue srcElemAddress;
      ILJitValue newElemAddress;
      ILJitValue counter;
!     ILJitValue arraySize;    
!     ILUInt32 marshalType;
!     char *customName;
!     int customNameLen;
!     char *customCookie;
!     int customCookieLen;
!     ILMethod *method = (ILMethod *)jit_function_get_meta(function, IL_JIT_META_METHOD);
!     ILPInvoke *pinv = ILPInvokeFind(method);
!     marshalType = ILPInvokeGetMarshalType(pinv, method, current, &customName, &customNameLen,
! 							&customCookie,	&customCookieLen, type);
!     if(marshalType == IL_META_MARSHAL_DIRECT && addressKind==MARSHAL_FIRST_LEVEL_VALUE)
!     {
! 	    return in;
!     }
!     else if(marshalType == IL_META_MARSHAL_CUSTOM)
      {
  	    fprintf(stderr, "Custom marshaling not supported in delegate value\n");
  	    return 0;
      }
-     type = ILTypeGetEnumType(type);
  
      switch(addressKind)
      {    
--- 2164,2183 ----
      ILJitValue srcElemSize;
      ILType *elemType;
      ILJitValue newElemSize, newArraySize;
!     ILJitValue newArray = jit_value_create(function, _IL_JIT_TYPE_VPTR);
      jit_label_t startLoop = jit_label_undefined;
      jit_label_t endLoop = jit_label_undefined;
      ILJitValue srcElemAddress;
      ILJitValue newElemAddress;
      ILJitValue counter;
!     ILJitValue arraySize;
!     type = ILTypeGetEnumType(type);
! 
!     if(marshalType == IL_META_MARSHAL_CUSTOM)
      {
  	    fprintf(stderr, "Custom marshaling not supported in delegate value\n");
  	    return 0;
      }
  
      switch(addressKind)
      {    
***************
*** 1681,1687 ****
  	    }
  	    break;
      }
- 
      if(ILType_IsPrimitive(type))
      {
  	switch(ILType_ToElement(type))
--- 2195,2200 ----
***************
*** 1825,1867 ****
      }
      else if(ILType_IsValueType(type))
      {	
! 	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) return (ILJitValue)MarshalDelegateStruct(function, jit_insn_address_of(function, in), type, 0, 0, MARSHAL_FIRST_LEVEL_VALUE, thread);
! 	    retValue = (ILJitValue)MarshalDelegateStruct(function, in, type, outAddressValue, offset, MARSHAL_ITEM_OF_STRUCTURE, thread);
  	    jit_insn_store_relative(function, outAddressValue, offset, retValue);
  	    return retValue;
      }
      else if(ILTypeIsStringClass(type))
      {
! 	    args[0] = jit_value_create_nint_constant(function, _IL_JIT_TYPE_VPTR, (jit_nint)thread);
  	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) args[1] = in;
  	    else args[1] = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
  	    switch(marshalType)
  	    {
  			case IL_META_MARSHAL_ANSI_STRING:
  			{
! 				    jit_insn_store(function, temp, jit_insn_call_native(function,
! 						    "ILStringCreate",
! 						    ILStringCreate,
! 						    _ILJitSignature_ILStringCreate,
! 						    args, 2, JIT_CALL_NOTHROW));
  			}
  			break;
  			case IL_META_MARSHAL_UTF8_STRING:
  			{
! 				    jit_insn_store(function, temp, jit_insn_call_native(function,
! 						    "ILStringCreateUTF8",
! 						    ILStringCreateUTF8,
! 						    _ILJitSignature_ILStringCreateUTF8,
! 						    args, 2, JIT_CALL_NOTHROW));
  			}
  			break;
  			case IL_META_MARSHAL_UTF16_STRING:
  			{
! 				    jit_insn_store(function, temp, jit_insn_call_native(function,
! 						    "ILStringWCreate",
! 						    ILStringWCreate,
! 						    _ILJitSignature_ILStringWCreate,
! 						    args, 2, JIT_CALL_NOTHROW));
  			}
  			break;
  	    }
--- 2338,2392 ----
      }
      else if(ILType_IsValueType(type))
      {	
! 	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) return (ILJitValue)MarshalDelegateStruct(function, jit_insn_address_of(function, in), type, marshalType, 0, 0, MARSHAL_FIRST_LEVEL_VALUE);
! 	    retValue = (ILJitValue)MarshalDelegateStruct(function, in, type, marshalType, outAddressValue, offset, MARSHAL_ITEM_OF_STRUCTURE);
  	    jit_insn_store_relative(function, outAddressValue, offset, retValue);
  	    return retValue;
      }
      else if(ILTypeIsStringClass(type))
      {
! 	    args[0] = _ILJitFunctionGetThread(function);
  	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) args[1] = in;
  	    else args[1] = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
+ 	    char *customName;
+ 	    int customNameLen;
+ 	    char *customCookie;
+ 	    int customCookieLen;
+ 	    ILMethod *method = (ILMethod *)jit_function_get_meta(function, IL_JIT_META_METHOD);
+ 	    marshalType = ILPInvokeGetMarshalType
+ 				(0, method, 0, &customName, &customNameLen, &customCookie, &customCookieLen, type);
  	    switch(marshalType)
  	    {
  			case IL_META_MARSHAL_ANSI_STRING:
  			{
! 				temp = jit_insn_call_native(function,
! 							    "ILStringCreate",
! 							    ILStringCreate,
! 							    _ILJitSignature_ILStringCreate,
! 							    args, 2, JIT_CALL_NOTHROW);
  			}
  			break;
  			case IL_META_MARSHAL_UTF8_STRING:
  			{
! 				temp = jit_insn_call_native(function,
! 							    "ILStringCreateUTF8",
! 							    ILStringCreateUTF8,
! 							    _ILJitSignature_ILStringCreateUTF8,
! 							    args, 2, JIT_CALL_NOTHROW);
  			}
  			break;
  			case IL_META_MARSHAL_UTF16_STRING:
  			{
! 				temp = jit_insn_call_native(function,
! 							    "ILStringWCreate",
! 							    ILStringWCreate,
! 							    _ILJitSignature_ILStringWCreate,
! 							    args, 2, JIT_CALL_NOTHROW);
! 			}
! 			break;
! 			default:
! 			{
! 				temp = args[1];
  			}
  			break;
  	    }
***************
*** 1877,1891 ****
  	    jit_insn_store_relative(function, outAddressValue, offset, temp);
  	    return temp;
      }
!     else if(ILType_IsClass(type))
!     {
! 	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) return in;
! 	    temp = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
! 	    jit_insn_store_relative(function, outAddressValue, offset, temp);
! 	    retValue = temp;
! 	    return retValue;
!     }
!     else if(type !=0 && ILType_IsComplex(type))
      {
  	    switch(ILType_Kind(type))
  	    {
--- 2402,2408 ----
  	    jit_insn_store_relative(function, outAddressValue, offset, temp);
  	    return temp;
      }
!     else if(type!=0 && ILType_IsComplex(type))
      {
  	    switch(ILType_Kind(type))
  	    {
***************
*** 1895,1901 ****
  			    temp = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
  			    jit_insn_store_relative(function, outAddressValue, offset, temp);
  			    return temp;
! 		    };
  		    break;
  		    case IL_TYPE_COMPLEX_BYREF:
  		    {
--- 2412,2418 ----
  			    temp = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
  			    jit_insn_store_relative(function, outAddressValue, offset, temp);
  			    return temp;
! 		    }
  		    break;
  		    case IL_TYPE_COMPLEX_BYREF:
  		    {
***************
*** 1903,1916 ****
  				    jit_insn_store(function, srcArray, jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR));
  			    else jit_insn_store(function, srcArray, in);
  			    ILType *elemType = ILType_Ref(type);
  			    if(NeedMarshalValue(elemType))
  			    {
  				    jit_insn_store(function, temp, MarshalDelegateStruct(function, jit_insn_dup(function, srcArray),
  									    elemType,
  									    0,
  									    0,
! 									    MARSHAL_FIRST_LEVEL_VALUE,
! 									    thread));
  			    }
  			    else jit_insn_store(function, temp, srcArray);
  			    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
--- 2420,2434 ----
  				    jit_insn_store(function, srcArray, jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR));
  			    else jit_insn_store(function, srcArray, in);
  			    ILType *elemType = ILType_Ref(type);
+ 			    elemType = ILTypeGetEnumType(elemType);
  			    if(NeedMarshalValue(elemType))
  			    {
  				    jit_insn_store(function, temp, MarshalDelegateStruct(function, jit_insn_dup(function, srcArray),
  									    elemType,
+ 									    marshalType,
  									    0,
  									    0,
! 									    MARSHAL_FIRST_LEVEL_VALUE));
  			    }
  			    else jit_insn_store(function, temp, srcArray);
  			    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
***************
*** 1918,1929 ****
  			    return srcArray;
  		    }
  		    break;
- 		    case IL_TYPE_COMPLEX_PINNED:
- 		    {
- 			    fprintf(stderr, "Marshaling in a delegate a COMPLEX_PINNED type is not yet supported\n");
- 			    return 0;
- 		    }
- 		    break;
  		    default: break;
  	    }
  
--- 2436,2441 ----
***************
*** 1933,1952 ****
  			    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
  				    srcArray = jit_insn_load_relative(function, srcArray, offset, _IL_JIT_TYPE_VPTR);
  			    elemType = ILType_ElemType(type);
! 
! 			    // The size of a simple array can be known only on run-time.
  			    arraySize = jit_insn_load_relative(function, srcArray, 0, _IL_JIT_TYPE_UINT32);
  			    srcElemSize = jit_value_create_nint_constant(function,
  				    						_IL_JIT_TYPE_INT32,
! 										(jit_nint)(ILSizeOfType(thread, elemType)));
  			    newElemSize = jit_value_create_nint_constant(function,
  										_IL_JIT_TYPE_INT32,
! 									    	(jit_nint)(ILSizeOfType(thread, elemType)));
  			    newArraySize = jit_insn_mul(function, arraySize, newElemSize);
  			    newArraySize = jit_insn_add_relative(function, newArraySize, (jit_nint)(sizeof(ILUInt32)));
  			    args[0] = newArraySize;
! 			    newArray = jit_insn_call_native(function, "_ILMalloc",
! 			    		    				ILGCAlloc,
  			    		    				_ILJitSignature_malloc,
  									args, 1, 0);
  			    jit_insn_store_relative(function, newArray, 0, arraySize);
--- 2445,2467 ----
  			    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
  				    srcArray = jit_insn_load_relative(function, srcArray, offset, _IL_JIT_TYPE_VPTR);
  			    elemType = ILType_ElemType(type);
! 			    elemType = ILTypeGetEnumType(elemType);
! 			    jit_insn_store(function, newArray, srcArray);
! 			    jit_insn_branch_if_not(function, jit_insn_to_bool(function, srcArray),
! 							    &endLoop);
!     			    // The size of a simple array can be known only on run-time.
  			    arraySize = jit_insn_load_relative(function, srcArray, 0, _IL_JIT_TYPE_UINT32);
  			    srcElemSize = jit_value_create_nint_constant(function,
  				    						_IL_JIT_TYPE_INT32,
! 										(jit_nint)(ILSizeOfType(ILExecThreadCurrent(), elemType)));
  			    newElemSize = jit_value_create_nint_constant(function,
  										_IL_JIT_TYPE_INT32,
! 									    	(jit_nint)(ILSizeOfType(ILExecThreadCurrent(), elemType)));
  			    newArraySize = jit_insn_mul(function, arraySize, newElemSize);
  			    newArraySize = jit_insn_add_relative(function, newArraySize, (jit_nint)(sizeof(ILUInt32)));
  			    args[0] = newArraySize;
! 			    newArray = jit_insn_call_native(function, "_ILGCAllocAtomic",
! 			    		    				ILGCAllocAtomic,
  			    		    				_ILJitSignature_malloc,
  									args, 1, 0);
  			    jit_insn_store_relative(function, newArray, 0, arraySize);
***************
*** 1962,1979 ****
  												_IL_JIT_TYPE_INT32,
  												(jit_nint)(sizeof(ILUInt32))));
  			    newElemAddress = jit_insn_dup(function, newArray);
! 			    counter = arraySize;
  			    jit_insn_label(function, &startLoop);
  			    jit_insn_store(function, counter, jit_insn_sub(function, counter,
  		    									jit_value_create_nint_constant(function,
  											_IL_JIT_TYPE_INT32,
  											1)));
  			    MarshalDelegateValue(function, srcElemAddress,
! 							elemType, current,
  							MARSHAL_ITEM_OF_ARRAY,
  							0,
! 							newElemAddress,
! 							thread);
  			    jit_insn_store(function, srcElemAddress,
  							    jit_insn_add(function,
  							    srcElemAddress, srcElemSize));
--- 2477,2493 ----
  												_IL_JIT_TYPE_INT32,
  												(jit_nint)(sizeof(ILUInt32))));
  			    newElemAddress = jit_insn_dup(function, newArray);
! 			    counter = jit_insn_dup(function, arraySize);
  			    jit_insn_label(function, &startLoop);
  			    jit_insn_store(function, counter, jit_insn_sub(function, counter,
  		    									jit_value_create_nint_constant(function,
  											_IL_JIT_TYPE_INT32,
  											1)));
  			    MarshalDelegateValue(function, srcElemAddress,
! 							elemType, marshalType,
  							MARSHAL_ITEM_OF_ARRAY,
  							0,
! 							newElemAddress);
  			    jit_insn_store(function, srcElemAddress,
  							    jit_insn_add(function,
  							    srcElemAddress, srcElemSize));
***************
*** 1996,2039 ****
  
      }
  
!     // Should not reach here if all every case is above, however do something smart.
      if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) return in;
      temp = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
      jit_insn_store_relative(function, outAddressValue, offset, temp);
      return temp;
  }
  
! ILJitValue MarshalDelegateStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind, ILExecThread *thread)
  {
      ILClass *classInfo = ILClassResolve(ILType_ToValueType(structureILType));
!     unsigned int structSize = ILSizeOfType(thread, structureILType);
      ILField *field = 0;
-     ILJitValue newStruct = 0;
      ILType *type;
!     ILJitType structType;	
! 
      if(addressKind==MARSHAL_FIRST_LEVEL_VALUE)
      {
  	    structType = jit_type_create_struct(0, 0, 0);
  	    jit_type_set_size_and_alignment(structType, structSize, 0);
  	    newStruct = jit_value_create(function, structType);
  	    outAddress = jit_insn_address_of(function, newStruct);
      }
- 
      while((field = (ILField *)ILClassNextMemberByKind
      		(classInfo, (ILMember *)field, IL_META_MEMBERKIND_FIELD)) != 0)
      {
  	    if(!ILField_IsStatic(field))
  	    {
  		    type = ILTypeGetEnumType(ILField_Type(field));
! 		    MarshalDelegateValue(function, inAddress, type, 1, MARSHAL_ITEM_OF_STRUCTURE, field->offset, outAddress, thread);
  	    }
      }
!     return jit_insn_dup(function, newStruct);
  }
- 	
  
! static ILJitValue MarshalDelegateReturnValue(jit_function_t function, ILJitValue in, ILType *type, unsigned int addressKind, jit_nint offset, ILJitValue outAddress, ILExecThread *thread)
  {
      ILJitValue outAddressValue = outAddress;
      ILJitValue temp = jit_value_create(function, _IL_JIT_TYPE_VPTR);
--- 2510,2553 ----
  
      }
  
!     // Should not reach here if every case is handled above,
!     // however we make the compiler happy.
      if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) return in;
      temp = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
      jit_insn_store_relative(function, outAddressValue, offset, temp);
      return temp;
  }
  
! ILJitValue MarshalDelegateStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILUInt32 marshalType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind)
  {
      ILClass *classInfo = ILClassResolve(ILType_ToValueType(structureILType));
!     unsigned int structSize = ILSizeOfType(ILExecThreadCurrent(), structureILType);
      ILField *field = 0;
      ILType *type;
!     ILJitType structType;
!     ILJitValue newStruct = 0;
      if(addressKind==MARSHAL_FIRST_LEVEL_VALUE)
      {
+ 	    // A structure passed to the delegate need to be a libjit value,
+ 	    // although we could use ILGCAllocAtomic with the structSize.
  	    structType = jit_type_create_struct(0, 0, 0);
  	    jit_type_set_size_and_alignment(structType, structSize, 0);
  	    newStruct = jit_value_create(function, structType);
  	    outAddress = jit_insn_address_of(function, newStruct);
      }
      while((field = (ILField *)ILClassNextMemberByKind
      		(classInfo, (ILMember *)field, IL_META_MEMBERKIND_FIELD)) != 0)
      {
  	    if(!ILField_IsStatic(field))
  	    {
  		    type = ILTypeGetEnumType(ILField_Type(field));
! 		    MarshalDelegateValue(function, inAddress, type, marshalType, MARSHAL_ITEM_OF_STRUCTURE, field->offset, outAddress);
  	    }
      }
!     return newStruct;
  }
  
! static ILJitValue MarshalDelegateReturnValue(jit_function_t function, ILJitValue in, ILType *type, ILUInt32 marshalType, unsigned int addressKind, jit_nint offset, ILJitValue outAddress)
  {
      ILJitValue outAddressValue = outAddress;
      ILJitValue temp = jit_value_create(function, _IL_JIT_TYPE_VPTR);
***************
*** 2042,2076 ****
      ILJitValue args[3];
      ILType *elemType;
      jit_label_t endLabel = jit_label_undefined;
!     ILJitValue srcArray = jit_value_create(function, _IL_JIT_TYPE_VPTR);    
!     ILUInt32 marshalType;
!     char *customName;
!     int customNameLen;
!     char *customCookie;
!     int customCookieLen;
!     ILMethod *method = (ILMethod *)jit_function_get_meta(function, IL_JIT_META_METHOD);
!     ILPInvoke *pinv = ILPInvokeFind(method);
!     marshalType = ILPInvokeGetMarshalType(pinv, method, 1, &customName, &customNameLen,
! 							&customCookie,	&customCookieLen, type);
! 
!     if(marshalType == IL_META_MARSHAL_DIRECT && addressKind==MARSHAL_FIRST_LEVEL_VALUE)
!     {
! 	    return in;
!     }    
!     else if(marshalType == IL_META_MARSHAL_CUSTOM)
      {
  	    fprintf(stderr, "Custom marshaling not supported in return value\n");
  	    return 0;
      }
-     type = ILTypeGetEnumType(type);
- 
-     if(addressKind==MARSHAL_FIRST_LEVEL_VALUE)
-     {
- 	    if(!NeedMarshalValue(type))return in;
-     }
  
!     if(addressKind==MARSHAL_ITEM_OF_ARRAY || addressKind == MARSHAL_ITEM_OF_STRUCTURE) outAddressValue = outAddress;
!     else if(addressKind!=MARSHAL_FIRST_LEVEL_VALUE && addressKind!=MARSHAL_ITEM_OF_STRUCTURE)
      {
  	    fprintf(stderr, "addressKind has an invalid value of %d\n", addressKind);
  	    return 0;
--- 2556,2570 ----
      ILJitValue args[3];
      ILType *elemType;
      jit_label_t endLabel = jit_label_undefined;
!     ILJitValue srcArray = jit_value_create(function, _IL_JIT_TYPE_VPTR);
!     type = ILTypeGetEnumType(type);    
!     if(marshalType == IL_META_MARSHAL_CUSTOM)
      {
  	    fprintf(stderr, "Custom marshaling not supported in return value\n");
  	    return 0;
      }
  
!     if(addressKind!=MARSHAL_FIRST_LEVEL_VALUE && addressKind!=MARSHAL_ITEM_OF_STRUCTURE && addressKind!=MARSHAL_ITEM_OF_ARRAY)
      {
  	    fprintf(stderr, "addressKind has an invalid value of %d\n", addressKind);
  	    return 0;
***************
*** 2214,2230 ****
  			{
  				case MARSHAL_ITEM_OF_ARRAY:
  				{
! 					return (ILJitValue)MarshalDelegateReturnStruct(function, valuePtr, refType, outAddressValue, offset, MARSHAL_ITEM_OF_ARRAY, thread);
  				}
  				break;
  				case MARSHAL_ITEM_OF_STRUCTURE:
  				{
! 					return (ILJitValue)MarshalDelegateReturnStruct(function, valuePtr, refType, outAddressValue, offset, MARSHAL_ITEM_OF_STRUCTURE, thread);
  				}
  				break;
  				default:
  				{
! 					return (ILJitValue)MarshalDelegateReturnStruct(function, valuePtr, refType, 0, 0, MARSHAL_FIRST_LEVEL_VALUE, thread);
  				}
  				break;
  			}
--- 2708,2724 ----
  			{
  				case MARSHAL_ITEM_OF_ARRAY:
  				{
! 					return (ILJitValue)MarshalDelegateReturnStruct(function, valuePtr, refType, marshalType, outAddressValue, offset, MARSHAL_ITEM_OF_ARRAY);
  				}
  				break;
  				case MARSHAL_ITEM_OF_STRUCTURE:
  				{
! 					return (ILJitValue)MarshalDelegateReturnStruct(function, valuePtr, refType, marshalType, outAddressValue, offset, MARSHAL_ITEM_OF_STRUCTURE);
  				}
  				break;
  				default:
  				{
! 					return (ILJitValue)MarshalDelegateReturnStruct(function, valuePtr, refType, marshalType, 0, 0, MARSHAL_FIRST_LEVEL_VALUE);
  				}
  				break;
  			}
***************
*** 2241,2295 ****
  		default:  break;
  	}			
      }
!     else if (ILType_IsValueType(type))
      {
  	    switch(addressKind)
  	    {
  		    case MARSHAL_ITEM_OF_STRUCTURE:
  		    case MARSHAL_ITEM_OF_ARRAY:
  		    {
! 			    return (ILJitValue)MarshalDelegateReturnStruct(function, in, type, outAddressValue, offset, MARSHAL_ITEM_OF_ARRAY, thread);
  		    }
  		    break;
  		    default:
  		    {
! 			    return (ILJitValue)MarshalDelegateReturnStruct(function, jit_insn_address_of(function, in), type, outAddressValue, 0, MARSHAL_FIRST_LEVEL_VALUE, thread);
  		    }
  		    break;
  	    }
      }
      else if(ILTypeIsStringClass(type))
      {
! 	    args[0] = jit_value_create_nint_constant(function, _IL_JIT_TYPE_VPTR, (jit_nint)thread);
  	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) args[1] = in;
  	    else args[1] = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
  	    switch(marshalType)
  	    {
  			case IL_META_MARSHAL_ANSI_STRING:
  			{
! 				    jit_insn_store(function, temp, jit_insn_call_native(function,
! 						    "ILStringToAnsi",
! 						    ILStringToAnsi,
! 						    _ILJitSignature_ILStringToAnsi,
! 						    args, 2, JIT_CALL_NOTHROW));
  			}
  			break;
  			case IL_META_MARSHAL_UTF8_STRING:
  			{
! 				    jit_insn_store(function, temp, jit_insn_call_native(function,
! 						    "ILStringToUTF8",
! 						    ILStringToUTF8,
! 						    _ILJitSignature_ILStringToUTF8,
! 						    args, 2, JIT_CALL_NOTHROW));
  			}
  			break;
  			case IL_META_MARSHAL_UTF16_STRING:
  			{
! 				    jit_insn_store(function, temp, jit_insn_call_native(function,
! 						    "ILStringToUTF16",
! 						    ILStringToUTF16,
! 						    _ILJitSignature_ILStringToUTF16,
! 						    args, 2, JIT_CALL_NOTHROW));
  			}
  			break;
  	    }
--- 2735,2801 ----
  		default:  break;
  	}			
      }
!     else if(ILType_IsValueType(type))
      {
  	    switch(addressKind)
  	    {
  		    case MARSHAL_ITEM_OF_STRUCTURE:
  		    case MARSHAL_ITEM_OF_ARRAY:
  		    {
! 			    return (ILJitValue)MarshalDelegateReturnStruct(function, in, type, marshalType, outAddressValue, offset, MARSHAL_ITEM_OF_ARRAY);
  		    }
  		    break;
  		    default:
  		    {
! 			    return (ILJitValue)MarshalDelegateReturnStruct(function, jit_insn_address_of(function, in), type, marshalType, outAddressValue, 0, MARSHAL_FIRST_LEVEL_VALUE);
  		    }
  		    break;
  	    }
      }
      else if(ILTypeIsStringClass(type))
      {
! 	    args[0] = _ILJitFunctionGetThread(function);
  	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) args[1] = in;
  	    else args[1] = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
+ 	    char *customName;
+ 	    int customNameLen;
+ 	    char *customCookie;
+ 	    int customCookieLen;
+ 	    ILMethod *method = (ILMethod *)jit_function_get_meta(function, IL_JIT_META_METHOD);
+ 	    marshalType = ILPInvokeGetMarshalType
+ 			    (0, method, 0, &customName, &customNameLen, &customCookie, &customCookieLen, type);
  	    switch(marshalType)
  	    {
  			case IL_META_MARSHAL_ANSI_STRING:
  			{
! 				temp = jit_insn_call_native(function,
! 							    "ILStringToAnsi",
! 							    ILStringToAnsi,
! 							    _ILJitSignature_ILStringToAnsi,
! 							    args, 2, JIT_CALL_NOTHROW);
  			}
  			break;
  			case IL_META_MARSHAL_UTF8_STRING:
  			{
! 				temp = jit_insn_call_native(function,
! 							    "ILStringToUTF8",
! 							    ILStringToUTF8,
! 							    _ILJitSignature_ILStringToUTF8,
! 							    args, 2, JIT_CALL_NOTHROW);
  			}
  			break;
  			case IL_META_MARSHAL_UTF16_STRING:
  			{
! 				temp = jit_insn_call_native(function,
! 							    "ILStringToUTF16",
! 							    ILStringToUTF16,
! 							    _ILJitSignature_ILStringToUTF16,
! 							    args, 2, JIT_CALL_NOTHROW);
! 			}
! 			break;
! 			default:
! 			{
! 				temp = args[1];
  			}
  			break;
  	    }
***************
*** 2303,2316 ****
  	    if(addressKind!=MARSHAL_FIRST_LEVEL_VALUE) temp = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
  	    ILJitValue closure = jit_insn_load_relative(function, temp, offsetof(System_Delegate, closure), _IL_JIT_TYPE_VPTR);
  	    jit_insn_branch_if(function, jit_insn_to_bool(function, closure), &endLabel);
! 	    args[0] = jit_value_create_nint_constant(function, _IL_JIT_TYPE_VPTR, (jit_nint)thread);
! 	    args[1] = jit_insn_dup(function, temp);
! 	    args[2] = jit_value_create_nint_constant(function, _IL_JIT_TYPE_VPTR, (jit_nint)type);
  	    jit_insn_store(function, closure, jit_insn_call_native(function,
  					    "ILJitDelegateGetClosure",
  					    ILJitDelegateGetClosure,
  					    _ILJitSignature_ILJitDelegateGetClosure,
! 					    args, 3, JIT_CALL_NOTHROW));
  	    jit_insn_label(function, &endLabel);
  	    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
  		    jit_insn_store_relative(function, outAddressValue, offset, closure);
--- 2809,2821 ----
  	    if(addressKind!=MARSHAL_FIRST_LEVEL_VALUE) temp = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
  	    ILJitValue closure = jit_insn_load_relative(function, temp, offsetof(System_Delegate, closure), _IL_JIT_TYPE_VPTR);
  	    jit_insn_branch_if(function, jit_insn_to_bool(function, closure), &endLabel);
! 	    args[0] = jit_insn_dup(function, temp);
! 	    args[1] = jit_value_create_nint_constant(function, _IL_JIT_TYPE_VPTR, (jit_nint)type);
  	    jit_insn_store(function, closure, jit_insn_call_native(function,
  					    "ILJitDelegateGetClosure",
  					    ILJitDelegateGetClosure,
  					    _ILJitSignature_ILJitDelegateGetClosure,
! 					    args, 2, JIT_CALL_NOTHROW));
  	    jit_insn_label(function, &endLabel);
  	    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
  		    jit_insn_store_relative(function, outAddressValue, offset, closure);
***************
*** 2335,2348 ****
  				    jit_insn_store(function, srcArray, jit_insn_load_relative(function, srcArray, offset, _IL_JIT_TYPE_VPTR));
  			    else jit_insn_store(function, srcArray, in);
  			    elemType = ILType_Ref(type);
  			    if(NeedMarshalValue(elemType))
  			    {
  				    MarshalDelegateReturnValue(function, jit_insn_dup(function, srcArray),
! 								elemType,
  								MARSHAL_ITEM_OF_ARRAY,
  								0,
! 								jit_insn_dup(function, srcArray),
! 								thread);
  			    }
  			    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
  				    jit_insn_store_relative(function, outAddressValue, offset, srcArray);
--- 2840,2853 ----
  				    jit_insn_store(function, srcArray, jit_insn_load_relative(function, srcArray, offset, _IL_JIT_TYPE_VPTR));
  			    else jit_insn_store(function, srcArray, in);
  			    elemType = ILType_Ref(type);
+ 			    elemType = ILTypeGetEnumType(elemType);
  			    if(NeedMarshalValue(elemType))
  			    {
  				    MarshalDelegateReturnValue(function, jit_insn_dup(function, srcArray),
! 								elemType, marshalType,
  								MARSHAL_ITEM_OF_ARRAY,
  								0,
! 								jit_insn_dup(function, srcArray));
  			    }
  			    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
  				    jit_insn_store_relative(function, outAddressValue, offset, srcArray);
***************
*** 2354,2361 ****
  
  		    if(ILType_IsSimpleArray(type))
  		    {
! 			    // The size of a simple array can be known only on run-time and we
! 			    // cannot use the same memory as it is used in the C code.
  			    fprintf(stderr, "Simple arrays are not supported for marshaling as a return value\n");
  			    return 0;
  		    }
--- 2859,2866 ----
  
  		    if(ILType_IsSimpleArray(type))
  		    {
! 			    // The size of a simple array can be known only on run-time but
! 			    // we should note that we cannot use the same memory as it is used in the C code.
  			    fprintf(stderr, "Simple arrays are not supported for marshaling as a return value\n");
  			    return 0;
  		    }
***************
*** 2372,2381 ****
      return temp;
  }
  
! static ILJitValue MarshalDelegateReturnStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind, ILExecThread *thread)
  {
          ILClass *classInfo = ILClassResolve(ILType_ToValueType(structureILType));
!         unsigned int structSize = ILSizeOfType(thread, structureILType);
  	ILField *field = 0;
  	ILType *type;
  
--- 2877,2886 ----
      return temp;
  }
  
! static ILJitValue MarshalDelegateReturnStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILUInt32 marshalType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind)
  {
          ILClass *classInfo = ILClassResolve(ILType_ToValueType(structureILType));
!         unsigned int structSize = ILSizeOfType(ILExecThreadCurrent(), structureILType);
  	ILField *field = 0;
  	ILType *type;
  
***************
*** 2384,2390 ****
  		case MARSHAL_FIRST_LEVEL_VALUE:
  		{
  			ILJitValue sizeValue = jit_value_create_nint_constant(function, _IL_JIT_TYPE_UINT32, structSize);
! 			outAddress = jit_insn_call_native(function, "_ILMalloc",
  								    ILGCAlloc,
  								    _ILJitSignature_malloc,
  								    &sizeValue, 1, 0);
--- 2889,2895 ----
  		case MARSHAL_FIRST_LEVEL_VALUE:
  		{
  			ILJitValue sizeValue = jit_value_create_nint_constant(function, _IL_JIT_TYPE_UINT32, structSize);
! 			outAddress = jit_insn_call_native(function, "ILGCAlloc",
  								    ILGCAlloc,
  								    _ILJitSignature_malloc,
  								    &sizeValue, 1, 0);
***************
*** 2414,2440 ****
  			{
  				case MARSHAL_FIRST_LEVEL_VALUE:
  				{
! 					MarshalDelegateReturnValue(function, inAddress, type, MARSHAL_ITEM_OF_STRUCTURE, field->offset + offset, outAddress, thread);
  				}
  			        break;
  				case MARSHAL_ITEM_OF_STRUCTURE:
  				{
! 					MarshalDelegateReturnValue(function, inAddress, type, MARSHAL_ITEM_OF_STRUCTURE, field->offset + offset, outAddress, thread);
  				}
  				break;
  				default:
  				{
! 					MarshalDelegateReturnValue(function, inAddress, type, MARSHAL_ITEM_OF_ARRAY, field->offset + offset, outAddress, thread);
  				}
  				break;
  			}
  		}
  	}
- 	
  	return outAddress;
  }
  
! static void MarshalDelegateByRefValue(jit_function_t function, ILJitValue in, ILType *type, ILUInt32 current, unsigned int addressKind, jit_nint offset, ILJitValue outAddress, ILExecThread *thread)
  {
      ILJitValue outAddressValue;
      ILJitValue temp = jit_value_create(function, _IL_JIT_TYPE_VPTR);
--- 2919,2945 ----
  			{
  				case MARSHAL_FIRST_LEVEL_VALUE:
  				{
! 					MarshalDelegateReturnValue(function, inAddress, type, marshalType, MARSHAL_ITEM_OF_STRUCTURE, field->offset + offset, outAddress);
  				}
  			        break;
  				case MARSHAL_ITEM_OF_STRUCTURE:
  				{
! 					MarshalDelegateReturnValue(function, inAddress, type, marshalType, MARSHAL_ITEM_OF_STRUCTURE, field->offset + offset, outAddress);
  				}
  				break;
  				default:
  				{
! 					MarshalDelegateReturnValue(function, inAddress, type, marshalType, MARSHAL_ITEM_OF_ARRAY, field->offset + offset, outAddress);
  				}
  				break;
  			}
  		}
  	}
  	return outAddress;
  }
  
! #ifdef USE_BYREF_MARSHALING
! static void MarshalDelegateByRefValue(jit_function_t function, ILJitValue in, ILType *type, ILUInt32 marshalType, unsigned int addressKind, jit_nint offset, ILJitValue outAddress, ILExecThread *thread)
  {
      ILJitValue outAddressValue;
      ILJitValue temp = jit_value_create(function, _IL_JIT_TYPE_VPTR);
***************
*** 2448,2473 ****
      ILJitValue srcElemAddress;
      ILJitValue newElemAddress;
      ILJitValue counter;
!     ILJitValue arraySize;    
!     ILUInt32 marshalType;
!     char *customName;
!     int customNameLen;
!     char *customCookie;
!     int customCookieLen;
!     ILMethod *method = (ILMethod *)jit_function_get_meta(function, IL_JIT_META_METHOD);
!     ILPInvoke *pinv = ILPInvokeFind(method);
!     marshalType = ILPInvokeGetMarshalType(pinv, method, current, &customName, &customNameLen,
! 							&customCookie,	&customCookieLen, type);
!     if(marshalType == IL_META_MARSHAL_DIRECT && addressKind==MARSHAL_FIRST_LEVEL_VALUE)
!     {
! 	    return;
!     }
!     else if(marshalType == IL_META_MARSHAL_CUSTOM)
      {
  	    fprintf(stderr, "Custom marshaling not supported in delegate by ref value\n");
  	    return;
      }
-     type = ILTypeGetEnumType(type);
  
      if(addressKind==MARSHAL_FIRST_LEVEL_VALUE)
      {
--- 2953,2965 ----
      ILJitValue srcElemAddress;
      ILJitValue newElemAddress;
      ILJitValue counter;
!     ILJitValue arraySize;
! 
!     if(marshalType == IL_META_MARSHAL_CUSTOM)
      {
  	    fprintf(stderr, "Custom marshaling not supported in delegate by ref value\n");
  	    return;
      }
  
      if(addressKind==MARSHAL_FIRST_LEVEL_VALUE)
      {
***************
*** 2588,2598 ****
      {
  	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE)
  	    {
! 		    MarshalDelegateByRefStruct(function, jit_insn_address_of(function, in), type, jit_insn_address_of(function, in), 0, MARSHAL_ITEM_OF_STRUCTURE, thread);
  		    return;
  	    }
! 	    temp = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
! 	    MarshalDelegateByRefStruct(function, temp, type, temp, 0, MARSHAL_ITEM_OF_STRUCTURE, thread);
  	    return;
      }
      else if(ILTypeIsDelegateSubClass(type))
--- 3080,3089 ----
      {
  	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE)
  	    {
! 		    MarshalDelegateByRefStruct(function, jit_insn_address_of(function, in), type, marshalType, jit_insn_address_of(function, in), 0, MARSHAL_ITEM_OF_STRUCTURE);
  		    return;
  	    }
! 	    MarshalDelegateByRefStruct(function, in, type, marshalType, outAddressValue, offset, MARSHAL_ITEM_OF_STRUCTURE);
  	    return;
      }
      else if(ILTypeIsDelegateSubClass(type))
***************
*** 2601,2685 ****
      }
      else if(ILTypeIsStringClass(type))
      {
! 	    args[0] = jit_value_create_nint_constant(function, _IL_JIT_TYPE_VPTR, (jit_nint)thread);
  	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) args[1] = in;
  	    else args[1] = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
  	    switch(marshalType)
  	    {
  			case IL_META_MARSHAL_ANSI_STRING:
  			{
! 				    jit_insn_store(function, temp, jit_insn_call_native(function,
! 						    "ILStringToAnsi",
! 						    ILStringToAnsi,
! 						    _ILJitSignature_ILStringToAnsi,
! 						    args, 2, JIT_CALL_NOTHROW));
  			}
  			break;
  			case IL_META_MARSHAL_UTF8_STRING:
  			{
! 				    jit_insn_store(function, temp, jit_insn_call_native(function,
! 						    "ILStringToUTF8",
! 						    ILStringToUTF8,
! 						    _ILJitSignature_ILStringToUTF8,
! 						    args, 2, JIT_CALL_NOTHROW));
  			}
  			break;
  			case IL_META_MARSHAL_UTF16_STRING:
  			{
! 				    jit_insn_store(function, temp, jit_insn_call_native(function,
! 						    "ILStringToUTF16",
! 						    ILStringToUTF16,
! 						    _ILJitSignature_ILStringToUTF16,
! 						    args, 2, JIT_CALL_NOTHROW));
  			}
  			break;
  	    }
  	    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
! 		    jit_insn_store_relative(function, in, offset, temp);
! 	    return;
!     }
!     else if(ILType_IsClass(type))
!     {
  	    return;
      }
!     else if(type !=0 && ILType_IsComplex(type))
      {
  	    switch(ILType_Kind(type))
  	    {
  		    case IL_TYPE_COMPLEX_PTR:
  		    case IL_TYPE_COMPLEX_BYREF:
  		    {
  			    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
  				    jit_insn_store(function, srcArray, jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR));
  			    else jit_insn_store(function, srcArray, in);
  			    ILType *elemType = ILType_Ref(type);
  			    if(NeedMarshalValue(elemType))
  			    {
  				    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
  				    {
  					    MarshalDelegateByRefValue(function, jit_insn_dup(function, srcArray),
! 										    elemType, current,
  										    MARSHAL_ITEM_OF_STRUCTURE,
  										    0,
! 										    jit_insn_load_relative(function, outAddressValue, offset, _IL_JIT_TYPE_VPTR),
! 										    thread);
  				    }
  				    else MarshalDelegateByRefValue(function, jit_insn_dup(function, srcArray),
! 										    elemType, current,
  										    MARSHAL_ITEM_OF_STRUCTURE,
  										    0,
! 										    srcArray,
! 										    thread);
  			    }
  			    return;
  		    }
  		    break;
- 		    case IL_TYPE_COMPLEX_PINNED:
- 		    {
- 			    fprintf(stderr, "Marshaling a COMPLEX_PINNED type is not yet supported for marshaling as a return byref value\n");
- 			    return;
- 		    }
- 		    break;
  		    default: break;
  	    }
  
--- 3092,3183 ----
      }
      else if(ILTypeIsStringClass(type))
      {
! 	    args[0] = _ILJitFunctionGetThread(function);
  	    if(addressKind==MARSHAL_FIRST_LEVEL_VALUE) args[1] = in;
  	    else args[1] = jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR);
+ 	    char *customName;
+ 	    int customNameLen;
+ 	    char *customCookie;
+ 	    int customCookieLen;
+ 	    ILMethod *method = (ILMethod *)jit_function_get_meta(function, IL_JIT_META_METHOD);
+ 	    marshalType = ILPInvokeGetMarshalType
+ 			    (0, method, 0, &customName, &customNameLen, &customCookie, &customCookieLen, type);
  	    switch(marshalType)
  	    {
  			case IL_META_MARSHAL_ANSI_STRING:
  			{
! 				temp = jit_insn_call_native(function,
! 							    "ILStringToAnsi",
! 							    ILStringToAnsi,
! 							    _ILJitSignature_ILStringToAnsi,
! 							    args, 2, JIT_CALL_NOTHROW);
  			}
  			break;
  			case IL_META_MARSHAL_UTF8_STRING:
  			{
! 				temp = jit_insn_call_native(function,
! 							    "ILStringToUTF8",
! 							    ILStringToUTF8,
! 							    _ILJitSignature_ILStringToUTF8,
! 							    args, 2, JIT_CALL_NOTHROW);
  			}
  			break;
  			case IL_META_MARSHAL_UTF16_STRING:
  			{
! 				temp = jit_insn_call_native(function,
! 							    "ILStringToUTF16",
! 							    ILStringToUTF16,
! 							    _ILJitSignature_ILStringToUTF16,
! 							    args, 2, JIT_CALL_NOTHROW);
! 			}
! 			break;
! 			default:
! 			{
! 				temp = args[1];
  			}
  			break;
  	    }
  	    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
! 		    jit_insn_store_relative(function, outAddressValue, offset, temp);
  	    return;
      }
!     else if(type!=0 && ILType_IsComplex(type))
      {
  	    switch(ILType_Kind(type))
  	    {
  		    case IL_TYPE_COMPLEX_PTR:
+ 		    {
+ 			    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
+ 				    jit_insn_store_relative(function, in, offset, temp);
+ 			    return;
+ 		    }
+ 		    break;
  		    case IL_TYPE_COMPLEX_BYREF:
  		    {
  			    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
  				    jit_insn_store(function, srcArray, jit_insn_load_relative(function, in, offset, _IL_JIT_TYPE_VPTR));
  			    else jit_insn_store(function, srcArray, in);
  			    ILType *elemType = ILType_Ref(type);
+ 			    elemType = ILTypeGetEnumType(elemType);
  			    if(NeedMarshalValue(elemType))
  			    {
  				    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
  				    {
  					    MarshalDelegateByRefValue(function, jit_insn_dup(function, srcArray),
! 										    elemType, marshalType,
  										    MARSHAL_ITEM_OF_STRUCTURE,
  										    0,
! 										    jit_insn_load_relative(function, outAddressValue, offset, _IL_JIT_TYPE_VPTR));
  				    }
  				    else MarshalDelegateByRefValue(function, jit_insn_dup(function, srcArray),
! 										    elemType, marshalType,
  										    MARSHAL_ITEM_OF_STRUCTURE,
  										    0,
! 										    srcArray);
  			    }
  			    return;
  		    }
  		    break;
  		    default: break;
  	    }
  
***************
*** 2688,2696 ****
  			    srcArray = in;
  			    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
  				    srcArray = jit_insn_load_relative(function, srcArray, offset, _IL_JIT_TYPE_VPTR);
  			    elemType = ILType_ElemType(type);
! 
! 			    if(!NeedMarshalValue(elemType))
  			    {
  				    return;
  			    }
--- 3186,3196 ----
  			    srcArray = in;
  			    if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || addressKind==MARSHAL_ITEM_OF_ARRAY)
  				    srcArray = jit_insn_load_relative(function, srcArray, offset, _IL_JIT_TYPE_VPTR);
+ 			    jit_insn_branch_if_not(function, jit_insn_to_bool(function, srcArray),
+ 								&endLoop);
  			    elemType = ILType_ElemType(type);
! 			    elemType = ILTypeGetEnumType(elemType);
! 			    if(!NeedMarshalValue(elemType) || ILType_IsValueType(elemType))
  			    {
  				    return;
  			    }
***************
*** 2711,2728 ****
  										&endLoop);
  			    newElemAddress = jit_insn_dup(function, outAddressValue);
  			    srcElemAddress = jit_insn_add_relative(function, srcArray, (jit_nint)(sizeof(ILUInt32)));
! 			    counter = arraySize;
  			    jit_insn_label(function, &startLoop);
  			    jit_insn_store(function, counter, jit_insn_sub(function, counter,
  		    									jit_value_create_nint_constant(function,
  											_IL_JIT_TYPE_INT32,
  											1)));
  			    MarshalDelegateByRefValue(function, srcElemAddress,
! 							elemType, current,
  							MARSHAL_ITEM_OF_ARRAY,
  							0,
! 							newElemAddress,
! 							thread);
  			    jit_insn_store(function, srcElemAddress,
  							    jit_insn_add(function,
  							    srcElemAddress, srcElemSize));
--- 3211,3227 ----
  										&endLoop);
  			    newElemAddress = jit_insn_dup(function, outAddressValue);
  			    srcElemAddress = jit_insn_add_relative(function, srcArray, (jit_nint)(sizeof(ILUInt32)));
! 			    counter = jit_insn_dup(function, arraySize);
  			    jit_insn_label(function, &startLoop);
  			    jit_insn_store(function, counter, jit_insn_sub(function, counter,
  		    									jit_value_create_nint_constant(function,
  											_IL_JIT_TYPE_INT32,
  											1)));
  			    MarshalDelegateByRefValue(function, srcElemAddress,
! 							elemType, marshalType,
  							MARSHAL_ITEM_OF_ARRAY,
  							0,
! 							newElemAddress);
  			    jit_insn_store(function, srcElemAddress,
  							    jit_insn_add(function,
  							    srcElemAddress, srcElemSize));
***************
*** 2742,2753 ****
  	    }
  
      }
! 
!     // Should not reach here, but make the compiler happy.
      return;
  }
  
! static void MarshalDelegateByRefStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind, ILExecThread *thread)
  {
      ILClass *classInfo = ILClassResolve(ILType_ToValueType(structureILType));
      ILField *field = 0;
--- 3241,3252 ----
  	    }
  
      }
!     // If we handled every case above, we should not reach here,
!     // but make the compiler happy.
      return;
  }
  
! static void MarshalDelegateByRefStruct(jit_function_t function, ILJitValue inAddress, ILType *structureILType, ILUInt32 marshalType, ILJitValue outAddress, jit_nint offset, unsigned int addressKind)
  {
      ILClass *classInfo = ILClassResolve(ILType_ToValueType(structureILType));
      ILField *field = 0;
***************
*** 2759,2766 ****
  	    if(!ILField_IsStatic(field))
  	    {
  		    type = ILTypeGetEnumType(ILField_Type(field));
! 		    MarshalDelegateByRefValue(function, inAddress, type, 1, MARSHAL_ITEM_OF_STRUCTURE, field->offset + offset, outAddress, thread);
  	    }
      }
      return;
  }
--- 3258,3302 ----
  	    if(!ILField_IsStatic(field))
  	    {
  		    type = ILTypeGetEnumType(ILField_Type(field));
! 		    MarshalDelegateByRefValue(function, inAddress, type, marshalType, MARSHAL_ITEM_OF_STRUCTURE, field->offset + offset, outAddress);
  	    }
      }
      return;
  }
+ #endif // USE_BYREF_MARSHALING
+ 
+ /*
+  * Marshal a CLR object to its native representation with custom marshaling support.
+  */
+ static void* MarshalObjectToCustom(void *value, ILType *type, ILMethod *method, ILExecThread *thread)
+ {
+ 	char *customName;
+ 	int customNameLen;
+ 	char *customCookie;
+ 	int customCookieLen;
+ 
+ 	ILPInvokeGetMarshalType
+ 	    (0, method, 0, &customName, &customNameLen,
+ 		&customCookie, &customCookieLen, type);
+ 	void *ptr = _ILObjectToCustom (thread, value, customName, 
+ 					    customNameLen, customCookie, customCookieLen);
+ 	return ptr;
+ }
+ 
+ /*
+  * Marshal a returned native value to a CLR object with custom marshaling support.
+  */
+ static void* MarshalCustomToObject(void *value, ILType *type, ILMethod *method, ILExecThread *thread)
+ {
+ 	char *customName;
+ 	int customNameLen;
+ 	char *customCookie;
+ 	int customCookieLen;
+ 
+ 	ILPInvokeGetMarshalType
+ 	    (0, method, 0, &customName, &customNameLen,
+ 		&customCookie, &customCookieLen, type);
+ 	void *ptr = _ILCustomToObject (thread, value, customName,
+ 					    customNameLen, customCookie, customCookieLen);
+ 	return ptr;
+ }
Index: engine/lib_marshal.c
===================================================================
RCS file: /sources/dotgnu-pnet/./pnet/engine/lib_marshal.c,v
retrieving revision 1.9
diff -c -r1.9 lib_marshal.c
*** engine/lib_marshal.c	22 Jul 2006 08:48:32 -0000	1.9
--- engine/lib_marshal.c	16 Sep 2006 13:26:36 -0000
***************
*** 644,650 ****
  		{
  	    #ifdef IL_USE_JIT
  			*((void **)ptr) = ILJitDelegateGetClosure
! 				(thread, *((ILObject **)ptr), type);
  	    #else
  			*((void **)ptr) = _ILDelegateGetClosure
  				(thread, *((ILObject **)ptr));
--- 644,650 ----
  		{
  	    #ifdef IL_USE_JIT
  			*((void **)ptr) = ILJitDelegateGetClosure
! 				(*((ILObject **)ptr), type);
  	    #else
  			*((void **)ptr) = _ILDelegateGetClosure
  				(thread, *((ILObject **)ptr));
#### End of Patch data ####
