dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[dotgnu-pnet-commits] pnet ChangeLog engine/jitc.c engine/jitc.h engi...


From: Klaus Treichel
Subject: [dotgnu-pnet-commits] pnet ChangeLog engine/jitc.c engine/jitc.h engi...
Date: Sun, 24 Sep 2006 18:16:21 +0000

CVSROOT:        /cvsroot/dotgnu-pnet
Module name:    pnet
Changes by:     Klaus Treichel <ktreichel>      06/09/24 18:16:21

Modified files:
        .              : ChangeLog 
        engine         : jitc.c jitc.h jitc_call.c jitc_pinvoke.c 
                         lib_marshal.c 

Log message:
        2006-09-24  Kirill Kononenko <address@hidden>
        
                * engine/jitc_pinvoke.c, engine/jitc.c:
                Improve multicast delegates handling.
                - Handle delegates and multicast delegates differently, that is,
                with a direct call to the delegate method or with a use of
                __ILJitDelegateInvokeCodeGen respectivaly.
                - Improve marshaling to/from Ansi/UTF8/UTF16 strings using the 
pinvoke
                record and the ILPInvokeGetMarshalType function.
                - Allow extended marshaling of simple arrays for complex types 
and
                strings if defined USE_BYREF_MARSHALING (default is set to 0).
                - Implement handling of strings, which are embedded in 
structures or
                simple arrays (needed for gtk#/sample/testdnd.exe).
                - Improve recursive marshaling of arrays and structures by 
handling the
                IL_META_MARSHAL_DIRECT flag and the NeedMarshalValue methods.
                - Introduce handling of the IL_META_MARSHAL_CUSTOM flag with 
two new
                MarshalCustomToObject and MarshalObjectToCustom methods which 
are used
                for objects that support custom marshaling.
                - Support marshaling for the case when the methods are compiled 
with
                IL_JIT_THREAD_IN_SIGNATURE undefined.
        
                * engine/jitc_pinvoke.c, engine/jitc_call.c: Inline marshaling
                code, which embed a call to the external native method directly 
in
                the body of the build function - if undefined 
_IL_JIT_ENABLE_DEBUG (if
                it is defined we call a stub method).
        
                * engine/jitc_pinvoke.c, engine/jitc.c, engine/jitc.h,
                engine/lib_marshal.c: Changed the ILJitDelegateGetClosure 
signature.
                Removed the thread from the first input argument in this method.
                The current thread is handled in the delegate code with
                _ILJitFunctionGetThread.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/pnet/ChangeLog?cvsroot=dotgnu-pnet&r1=1.3362&r2=1.3363
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc.c?cvsroot=dotgnu-pnet&r1=1.49&r2=1.50
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc.h?cvsroot=dotgnu-pnet&r1=1.18&r2=1.19
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_call.c?cvsroot=dotgnu-pnet&r1=1.23&r2=1.24
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_pinvoke.c?cvsroot=dotgnu-pnet&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/lib_marshal.c?cvsroot=dotgnu-pnet&r1=1.9&r2=1.10

Patches:
Index: ChangeLog
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/ChangeLog,v
retrieving revision 1.3362
retrieving revision 1.3363
diff -u -b -r1.3362 -r1.3363
--- ChangeLog   17 Sep 2006 18:32:31 -0000      1.3362
+++ ChangeLog   24 Sep 2006 18:16:21 -0000      1.3363
@@ -1,3 +1,35 @@
+2006-09-24  Kirill Kononenko <address@hidden>
+
+       * engine/jitc_pinvoke.c, engine/jitc.c:
+       Improve multicast delegates handling.
+       - Handle delegates and multicast delegates differently, that is,
+       with a direct call to the delegate method or with a use of
+       __ILJitDelegateInvokeCodeGen respectivaly.
+       - Improve marshaling to/from Ansi/UTF8/UTF16 strings using the pinvoke
+       record and the ILPInvokeGetMarshalType function.
+       - Allow extended marshaling of simple arrays for complex types and
+       strings if defined USE_BYREF_MARSHALING (default is set to 0).
+       - Implement handling of strings, which are embedded in structures or
+       simple arrays (needed for gtk#/sample/testdnd.exe).
+       - Improve recursive marshaling of arrays and structures by handling the
+       IL_META_MARSHAL_DIRECT flag and the NeedMarshalValue methods.
+       - Introduce handling of the IL_META_MARSHAL_CUSTOM flag with two new
+       MarshalCustomToObject and MarshalObjectToCustom methods which are used
+       for objects that support custom marshaling.
+       - Support marshaling for the case when the methods are compiled with
+       IL_JIT_THREAD_IN_SIGNATURE undefined.
+
+       * engine/jitc_pinvoke.c, engine/jitc_call.c: Inline marshaling
+       code, which embed a call to the external native method directly in
+       the body of the build function - if undefined _IL_JIT_ENABLE_DEBUG (if
+       it is defined we call a stub method).
+
+       * engine/jitc_pinvoke.c, engine/jitc.c, engine/jitc.h,
+       engine/lib_marshal.c: Changed the ILJitDelegateGetClosure signature.
+       Removed the thread from the first input argument in this method.
+       The current thread is handled in the delegate code with
+       _ILJitFunctionGetThread.
+
 2006-09-17  Radek Polak <address@hidden>
 
         * engine/engine.h: add ILWatch struct for keeping information about

Index: engine/jitc.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc.c,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -b -r1.49 -r1.50
--- engine/jitc.c       17 Sep 2006 18:32:31 -0000      1.49
+++ engine/jitc.c       24 Sep 2006 18:16:21 -0000      1.50
@@ -129,12 +129,10 @@
  * They have to be kept in sync wirh the corresponding engine funcions.
  */
 
-#ifndef IL_JIT_THREAD_IN_SIGNATURE
 /*
  * ILExecThread *ILExecThreadCurrent()
  */
 static ILJitType _ILJitSignature_ILExecThreadCurrent = 0;
-#endif
 
 /*
  * ILObject *_ILJitAlloc(ILClass *classInfo, ILUInt32 size)
@@ -264,11 +262,21 @@
 static ILJitType _ILJitSignature_ILStringWCreate = 0;
 
 /*
- * void *ILJitDelegateGetClosure(ILExecThread *thread, ILObject *delegate, 
ILType *delType)
+ * void *ILJitDelegateGetClosure(ILObject *delegate, ILType *delType)
  */
 static ILJitType _ILJitSignature_ILJitDelegateGetClosure = 0;
 
 /*
+ * void* MarshalObjectToCustom(void *value, ILType *type, ILMethod *method, 
ILExecThread *thread)
+ */
+static ILJitType _ILJitSignature_MarshalObjectToCustom = 0;
+
+/*
+ * void* MarshalCustomToObject(void *value, ILType *type, ILMethod *method, 
ILExecThread *thread)
+ */
+static ILJitType _ILJitSignature_MarshalCustomToObject = 0;
+
+/*
  * Define offsetof macro if not present.
  */
 #ifndef offsetof
@@ -2021,14 +2029,12 @@
        _ILJitTypesInitBase(&_ILJitType_TYPEDREF, _ILJitTypedRef);
 
        /* Initialize the native method signatures. */
-#ifndef IL_JIT_THREAD_IN_SIGNATURE
        returnType = _IL_JIT_TYPE_VPTR;
        if(!(_ILJitSignature_ILExecThreadCurrent = 
                jit_type_create_signature(IL_JIT_CALLCONV_CDECL, returnType, 0, 
0, 1)))
        {
                return 0;
        }
-#endif
 
        args[0] = _IL_JIT_TYPE_VPTR;
        args[1] = _IL_JIT_TYPE_UINT32;
@@ -2234,10 +2240,31 @@
 
        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)))
+               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: /cvsroot/dotgnu-pnet/pnet/engine/jitc.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -b -r1.18 -r1.19
--- engine/jitc.h       17 Sep 2006 18:32:31 -0000      1.18
+++ engine/jitc.h       24 Sep 2006 18:16:21 -0000      1.19
@@ -234,8 +234,7 @@
 /*
  * Get the closure for a delegate.
  */
-void *ILJitDelegateGetClosure(ILExecThread *thread,
-                                                         ILObject *delegate,
+void *ILJitDelegateGetClosure(ILObject *delegate,
                                                          ILType *delType);
 
 

Index: engine/jitc_call.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_call.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -b -r1.23 -r1.24
--- engine/jitc_call.c  17 Sep 2006 18:32:31 -0000      1.23
+++ engine/jitc_call.c  24 Sep 2006 18:16:21 -0000      1.24
@@ -696,6 +696,15 @@
        }
        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, 0,
@@ -705,6 +714,7 @@
                                                                        
jitFunction, 0,
                                                                        
jitParams, argCount, 0);
        #endif
+               }
                if(returnItem && returnItem->engineType != ILEngineType_Invalid)
                {
                        jitCoder->jitStack[jitCoder->stackTop] =

Index: engine/jitc_pinvoke.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_pinvoke.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- engine/jitc_pinvoke.c       28 Jul 2006 17:41:54 -0000      1.3
+++ engine/jitc_pinvoke.c       24 Sep 2006 18:16:21 -0000      1.4
@@ -18,34 +18,53 @@
  * 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 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);
-
+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.
  */
@@ -68,9 +87,12 @@
        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;
+       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,72 +156,234 @@
 
                default:
                {
-                       /* There is an invalid calling convention inthe 
metadata. */
+                       /* 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_insn_dup(func, 
jit_value_get_param(func, current));
-               jitParams[param] = (ILJitValue)MarshalValue(func, 
tempParams[param], valueType, current, 0, 0, 0);
+               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))
+               {
+                        ILJitValue args[2];
+                        args[0] = _ILJitFunctionGetThread(func);
+                        args[1] = jit_value_get_param(func, current);
+                        switch(marshalType)
+                        {
+                               case IL_META_MARSHAL_ANSI_STRING:
+                               {
+                                       jitParams[param] = 
jit_insn_call_native(func,
+                                                                               
    "ILStringToAnsi",
+                                                                               
    ILStringToAnsi,
+                                                                               
    _ILJitSignature_ILStringToAnsi,
+                                                                               
    args, 2, JIT_CALL_NOTHROW);
+                               }
+                               break;
+                               case IL_META_MARSHAL_UTF8_STRING:
+                               {
+                                       jitParams[param] = 
jit_insn_call_native(func,
+                                                                               
    "ILStringToUTF8",
+                                                                               
    ILStringToUTF8,
+                                                                               
    _ILJitSignature_ILStringToUTF8,
+                                                                               
    args, 2, JIT_CALL_NOTHROW);
+                               }
+                               break;
+                               case IL_META_MARSHAL_UTF16_STRING:
+                               {
+                                       jitParams[param] = 
jit_insn_call_native(func,
+                                                                               
    "ILStringToUTF16",
+                                                                               
    ILStringToUTF16,
+                                                                               
    _ILJitSignature_ILStringToUTF16,
+                                                                               
    args, 2, JIT_CALL_NOTHROW);
+                               }
+                               break;
+                               default: break;
+                       }
+               }
+               else if(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);
-       if(numParams > 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);
-               jit_insn_store(func, returnValue, 
(ILJitValue)MarshalReturnValue(func, jit_insn_dup(func, returnValue), type, 0, 
0, 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))
+               {
+                       ILJitValue args[2];
+                       args[0] = _ILJitFunctionGetThread(func);
+                       args[1] = returnValue;
+                       switch(marshalType)
+                       {
+                               case IL_META_MARSHAL_ANSI_STRING:
+                               {
+                                       returnValue = jit_insn_call_native(func,
+                                                                           
"ILStringCreate",
+                                                                           
ILStringCreate,
+                                                                           
_ILJitSignature_ILStringCreate,
+                                                                           
args, 2, JIT_CALL_NOTHROW);
+                               }
+                               break;
+                               case IL_META_MARSHAL_UTF8_STRING:
+                               {
+                                       returnValue = jit_insn_call_native(func,
+                                                                           
"ILStringCreateUTF8",
+                                                                           
ILStringCreateUTF8,
+                                                                           
_ILJitSignature_ILStringCreateUTF8,
+                                                                           
args, 2, JIT_CALL_NOTHROW);
+                               }
+                               break;
+                               case IL_META_MARSHAL_UTF16_STRING:
+                               {
+                                       returnValue = jit_insn_call_native(func,
+                                                                           
"ILStringWCreate",
+                                                                           
ILStringWCreate,
+                                                                           
_ILJitSignature_ILStringWCreate,
+                                                                           
args, 2, JIT_CALL_NOTHROW);
+                               }
+                               break;
+                               default: break;
+                       }
+               }
+               else if(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
                {
-                       newValue = jit_insn_dup(func, jitParams[param]);
+#ifdef IL_JIT_THREAD_IN_SIGNATURE
                        type = ILTypeGetParam(ilSignature, current);
+#else
+               type = ILTypeGetParam(ilSignature, current + 1);
+#endif
                        type = ILTypeGetEnumType(type);
 
-                       if(type!=0 && ILType_IsSimpleArray(type))
+               // Does anyone use this?
+               marshalType = ILPInvokeGetMarshalType
+                                       (pinv, method, current, &customName, 
&customNameLen,
+                                        &customCookie, &customCookieLen, type);
+               if((marshalType != IL_META_MARSHAL_DIRECT || 
NeedMarshalValue(type))
+                       && marshalType != IL_META_MARSHAL_CUSTOM && type != 0)
+               {
+                       if(ILType_IsSimpleArray(type))
                        {
-                               MarshalByRefValue(func, newValue, type, 
current, 0, 0, tempParams[param]);
+                                MarshalByRefValue(func, jitParams[param], 
type, 
+                                                           marshalType, 
MARSHAL_FIRST_LEVEL_VALUE, 
+                                                           0, 
tempParams[param]);
                        }
-                       else if(type!=0 && ILType_IsComplex(type))
+                       else if(ILType_IsComplex(type))
                        {
                                typeFlag = ILType_Kind(type);
-                               if(typeFlag==IL_TYPE_COMPLEX_BYREF || typeFlag 
== IL_TYPE_COMPLEX_PTR)
+                               if(typeFlag==IL_TYPE_COMPLEX_BYREF)
                                {
-                                       MarshalByRefValue(func, newValue, type,
-                                                                   current, 0,
+                                       // Does anyone use this?
+                                       MarshalByRefValue(func, 
jitParams[param], type,
+                                                                   
marshalType, MARSHAL_FIRST_LEVEL_VALUE,
                                                                    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);
+               ++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)
@@ -227,6 +411,306 @@
        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;
+       }
+
+       /* 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 in the 
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))
+               {
+                        ILJitValue args[2];
+                        args[0] = _ILJitFunctionGetThread(func);
+                        args[1] = tempParams[current];
+                        switch(marshalType)
+                        {
+                               case IL_META_MARSHAL_ANSI_STRING:
+                               {
+                                       jitParams[param] = 
jit_insn_call_native(func,
+                                                                               
    "ILStringToAnsi",
+                                                                               
    ILStringToAnsi,
+                                                                               
    _ILJitSignature_ILStringToAnsi,
+                                                                               
    args, 2, JIT_CALL_NOTHROW);
+                               }
+                               break;
+                               case IL_META_MARSHAL_UTF8_STRING:
+                               {
+                                       jitParams[param] = 
jit_insn_call_native(func,
+                                                                               
    "ILStringToUTF8",
+                                                                               
    ILStringToUTF8,
+                                                                               
    _ILJitSignature_ILStringToUTF8,
+                                                                               
    args, 2, JIT_CALL_NOTHROW);
+                               }
+                               break;
+                               case IL_META_MARSHAL_UTF16_STRING:
+                               {
+                                       jitParams[param] = 
jit_insn_call_native(func,
+                                                                               
    "ILStringToUTF16",
+                                                                               
    ILStringToUTF16,
+                                                                               
    _ILJitSignature_ILStringToUTF16,
+                                                                               
    args, 2, JIT_CALL_NOTHROW);
+                               }
+                               break;
+                               default: break;
+                       }
+               }
+               else if(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))
+               {
+                       ILJitValue args[2];
+                       args[0] = _ILJitFunctionGetThread(func);
+                       args[1] = returnValue;
+                       switch(marshalType)
+                       {
+                               case IL_META_MARSHAL_ANSI_STRING:
+                               {
+                                       returnValue = jit_insn_call_native(func,
+                                                                           
"ILStringCreate",
+                                                                           
ILStringCreate,
+                                                                           
_ILJitSignature_ILStringCreate,
+                                                                           
args, 2, JIT_CALL_NOTHROW);
+                               }
+                               break;
+                               case IL_META_MARSHAL_UTF8_STRING:
+                               {
+                                       returnValue = jit_insn_call_native(func,
+                                                                           
"ILStringCreateUTF8",
+                                                                           
ILStringCreateUTF8,
+                                                                           
_ILJitSignature_ILStringCreateUTF8,
+                                                                           
args, 2, JIT_CALL_NOTHROW);
+                               }
+                               break;
+                               case IL_META_MARSHAL_UTF16_STRING:
+                               {
+                                       returnValue = jit_insn_call_native(func,
+                                                                           
"ILStringWCreate",
+                                                                           
ILStringWCreate,
+                                                                           
_ILJitSignature_ILStringWCreate,
+                                                                           
args, 2, JIT_CALL_NOTHROW);
+                               }
+                               break;
+                               default: break;
+                       }
+               }
+               else if(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((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,16 +818,15 @@
     {
            return 1;
     }
-    else if(ILType_IsClass(type))
-    {
-           return 0;
-    }
-    else if(type !=0 && ILType_IsComplex(type))
+    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,7 +849,7 @@
            return 1;
     }
 
-    return 1;
+    return 0;
 }
 
 static int NeedMarshalStruct(ILType *structureILType)
@@ -387,10 +870,9 @@
        return 0;
 }
 
-
-static ILJitValue MarshalValue(jit_function_t function, ILJitValue in, ILType 
*type, ILUInt32 current, unsigned int addressKind, jit_nint offset, ILJitValue 
outAddress)
+static ILJitValue MarshalValue(jit_function_t function, ILJitValue in, ILType 
*type, ILUInt32 marshalType,
+                                   unsigned int addressKind, jit_nint offset, 
ILJitValue outAddressValue)
 {
-    ILJitValue outAddressValue = outAddress;
     ILJitValue temp = jit_value_create(function, _IL_JIT_TYPE_VPTR);
     ILJitValue ptr, valuePtr;
     ILType *refType;
@@ -408,32 +890,9 @@
     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)
+    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,17 +1035,20 @@
                        {
                                case MARSHAL_ITEM_OF_ARRAY:
                                {
-                                       return 
(ILJitValue)MarshalStruct(function, valuePtr, refType, outAddressValue, offset, 
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, outAddressValue, offset, 
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, 0, 0, 
MARSHAL_FIRST_LEVEL_VALUE);
+                                       return 
(ILJitValue)MarshalStruct(function, valuePtr, refType,
+                                                           marshalType, 0, 0, 
MARSHAL_FIRST_LEVEL_VALUE);
                                }
                                break;
                        }
@@ -603,19 +1065,21 @@
                default:  break;
        }                       
     }
-    else if (ILType_IsValueType(type))
+    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);
+                           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, 0, 0, MARSHAL_FIRST_LEVEL_VALUE);
+                           return (ILJitValue)MarshalStruct(function, 
jit_insn_address_of(function, in), type, marshalType,
+                                                               0, 0, 
MARSHAL_FIRST_LEVEL_VALUE);
                    }
                    break;
            }
@@ -625,65 +1089,75 @@
            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;
+           if(addressKind!=MARSHAL_FIRST_LEVEL_VALUE)
+           {
+                   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:
                        {
-                                   jit_insn_store(function, temp, 
jit_insn_call_native(function,
+                               temp = jit_insn_call_native(function,
                                                    "ILStringToAnsi",
                                                    ILStringToAnsi,
                                                    
_ILJitSignature_ILStringToAnsi,
-                                                   args, 2, JIT_CALL_NOTHROW));
+                                                           args, 2, 
JIT_CALL_NOTHROW);
                        }
                        break;
                        case IL_META_MARSHAL_UTF8_STRING:
                        {
-                                   jit_insn_store(function, temp, 
jit_insn_call_native(function,
+                               temp = jit_insn_call_native(function,
                                                    "ILStringToUTF8",
                                                    ILStringToUTF8,
                                                    
_ILJitSignature_ILStringToUTF8,
-                                                   args, 2, JIT_CALL_NOTHROW));
+                                                           args, 2, 
JIT_CALL_NOTHROW);
                        }
                        break;
                        case IL_META_MARSHAL_UTF16_STRING:
                        {
-                                   jit_insn_store(function, temp, 
jit_insn_call_native(function,
+                               temp = jit_insn_call_native(function,
                                                    "ILStringToUTF16",
                                                    ILStringToUTF16,
                                                    
_ILJitSignature_ILStringToUTF16,
-                                                   args, 2, JIT_CALL_NOTHROW));
+                                                           args, 2, 
JIT_CALL_NOTHROW);
                        }
                        break;
                        default:
                        {
-                               fprintf(stderr, "Unsupported string char set in 
marshaling\n");
-                               return 0;
-                       };
+                               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 && ILTypeIsDelegate(type))
+    else if(type!=0 && ILTypeIsDelegateSubClass(type))
     {
            temp = jit_insn_dup(function, in);
            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);
+           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);
+           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, 3, JIT_CALL_NOTHROW));
+                                           args, 2, 0));
            jit_insn_label(function, &endLabel);
            if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || 
addressKind==MARSHAL_ITEM_OF_ARRAY)
                    jit_insn_store_relative(function, outAddressValue, offset, 
closure);
@@ -704,13 +1178,15 @@
                    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));
+                                   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, 0, 
+                                                           elemType, 
marshalType, 
                                                            
MARSHAL_ITEM_OF_STRUCTURE,
                                                            0,
                                                            
jit_insn_dup(function, srcArray));
@@ -725,10 +1201,14 @@
 
                    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);
+                           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);
@@ -742,7 +1222,6 @@
                                            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();
@@ -753,13 +1232,11 @@
                                                                                
_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,
+                   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
@@ -768,18 +1245,19 @@
                            srcElemAddress = jit_insn_add_relative(function,
                                                                        
srcArray,
                                                                        
(jit_nint)(sizeof(ILUInt32)));
-                           newElemAddress = jit_insn_dup(function, newArray);
-                           counter = arraySize;
+                   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, jit_insn_dup(function, 
srcElemAddress),
-                                                       elemType, 0,
+                   MarshalValue(function, srcElemAddress, elemType,
+                                                           marshalType,
                                                        MARSHAL_ITEM_OF_ARRAY,
                                                        0,
-                                                       jit_insn_dup(function, 
newElemAddress));
+                                                           newElemAddress);
                            jit_insn_store(function, srcElemAddress,
                                                            
jit_insn_add(function,
                                                            srcElemAddress, 
srcElemSize));
@@ -800,14 +1278,14 @@
                            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)
+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,7 +1298,7 @@
                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",
+                       outAddress = jit_insn_call_native(function, "ILGCAlloc",
                                                                    ILGCAlloc,
                                                                    
_ILJitSignature_malloc,
                                                                    &sizeValue, 
1, 0);
@@ -850,59 +1328,38 @@
                        {
                                case MARSHAL_FIRST_LEVEL_VALUE:
                                {
-                                       MarshalValue(function, inAddress, type, 
0, MARSHAL_ITEM_OF_STRUCTURE, field->offset + offset, outAddress);
+                                       MarshalValue(function, inAddress, type, 
marshalType, 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);
+                                       MarshalValue(function, inAddress, type, 
marshalType, MARSHAL_ITEM_OF_STRUCTURE,
+                                                       field->offset + offset, 
outAddress);
                                }
                                break;
                                default:
                                {
-                                       MarshalValue(function, inAddress, type, 
0, MARSHAL_ITEM_OF_ARRAY, field->offset + offset, outAddress);
+                                       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, unsigned int addressKind, jit_nint offset, ILJitValue 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);
-    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:
@@ -1062,44 +1519,61 @@
     }
     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);
+           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] = in;
+           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;
+           if(addressKind!=MARSHAL_FIRST_LEVEL_VALUE)
+           {
+                   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:
                        {
-                                   jit_insn_store(function, temp, 
jit_insn_call_native(function,
+                               temp = jit_insn_call_native(function,
                                                    "ILStringCreate",
                                                    ILStringCreate,
                                                    
_ILJitSignature_ILStringCreate,
-                                                   args, 2, JIT_CALL_NOTHROW));
+                                                   args, 2, JIT_CALL_NOTHROW);
                        }
                        break;
                        case IL_META_MARSHAL_UTF8_STRING:
                        {
-                                   jit_insn_store(function, temp, 
jit_insn_call_native(function,
+                               temp = jit_insn_call_native(function,
                                                    "ILStringCreateUTF8",
                                                    ILStringCreateUTF8,
                                                    
_ILJitSignature_ILStringCreateUTF8,
-                                                   args, 2, JIT_CALL_NOTHROW));
+                                                   args, 2, JIT_CALL_NOTHROW);
                        }
                        break;
                        case IL_META_MARSHAL_UTF16_STRING:
                        {
-                                   jit_insn_store(function, temp, 
jit_insn_call_native(function,
+                               temp = jit_insn_call_native(function,
                                                    "ILStringWCreate",
                                                    ILStringWCreate,
                                                    
_ILJitSignature_ILStringWCreate,
-                                                   args, 2, JIT_CALL_NOTHROW));
+                                                           args, 2, 
JIT_CALL_NOTHROW);
+                       }
+                       break;
+                       default:
+                       {
+                               temp = args[1];
                        }
                        break;
            }
@@ -1112,15 +1586,7 @@
            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))
+    else if(type!=0 && ILType_IsComplex(type))
     {
            switch(ILType_Kind(type))
            {
@@ -1130,18 +1596,19 @@
                            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:
                    {
                            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));
+                                   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))
                            {
                                    MarshalReturnValue(function, 
jit_insn_dup(function, srcArray),
-                                                                   elemType,
+                                                                   elemType, 
marshalType,
                                                                    
MARSHAL_ITEM_OF_STRUCTURE,
                                                                    0,
                                                                    
jit_insn_dup(function, srcArray));
@@ -1158,9 +1625,9 @@
            {
                        // 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,14 +1637,15 @@
 
     }
 
-    // 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)
+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,6 +1657,9 @@
 
     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,13 +1672,16 @@
            if(!ILField_IsStatic(field))
            {
                    type = ILTypeGetEnumType(ILField_Type(field));
-                   MarshalReturnValue(function, inAddress, type, 
MARSHAL_ITEM_OF_STRUCTURE, field->offset, outAddress);
+                   MarshalReturnValue(function, inAddress, type, marshalType, 
MARSHAL_ITEM_OF_STRUCTURE,
+                                           offset + field->offset, outAddress);
            }
     }
-    return jit_insn_dup(function, newStruct);
+    return newStruct;
 }
 
-static void MarshalByRefValue(jit_function_t function, ILJitValue in, ILType 
*type, ILUInt32 current, unsigned int addressKind, jit_nint offset, ILJitValue 
outAddress)
+#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);
@@ -1224,22 +1698,7 @@
     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)
@@ -1356,11 +1815,11 @@
     {  
            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);
+                   MarshalByRefStruct(function, jit_insn_address_of(function, 
in), type, marshalType, outAddressValue, 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);
+           MarshalByRefStruct(function, in, type, marshalType, 
outAddressValue, offset, MARSHAL_ITEM_OF_STRUCTURE);
            return;
     }
     else if(ILTypeIsStringClass(type))
@@ -1368,45 +1827,56 @@
            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;
+           if(addressKind!=MARSHAL_FIRST_LEVEL_VALUE)
+           {
+                   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:
                        {
-                                   jit_insn_store(function, temp, 
jit_insn_call_native(function,
+                               temp = jit_insn_call_native(function,
                                                    "ILStringCreate",
                                                    ILStringCreate,
                                                    
_ILJitSignature_ILStringCreate,
-                                                   args, 2, JIT_CALL_NOTHROW));
+                                                           args, 2, 
JIT_CALL_NOTHROW);
                        }
                        break;
                        case IL_META_MARSHAL_UTF8_STRING:
                        {
-                                   jit_insn_store(function, temp, 
jit_insn_call_native(function,
+                               temp = jit_insn_call_native(function,
                                                    "ILStringCreateUTF8",
                                                    ILStringCreateUTF8,
                                                    
_ILJitSignature_ILStringCreateUTF8,
-                                                   args, 2, JIT_CALL_NOTHROW));
+                                                           args, 2, 
JIT_CALL_NOTHROW);
                        }
                        break;
                        case IL_META_MARSHAL_UTF16_STRING:
                        {
-                                   jit_insn_store(function, temp, 
jit_insn_call_native(function,
+                               temp = jit_insn_call_native(function,
                                                    "ILStringWCreate",
                                                    ILStringWCreate,
                                                    
_ILJitSignature_ILStringWCreate,
-                                                   args, 2, JIT_CALL_NOTHROW));
+                                                           args, 2, 
JIT_CALL_NOTHROW);
                        }
                        break;
+                       default:
+                       {
+                               temp = args[1];
            }
-           if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || 
addressKind==MARSHAL_ITEM_OF_ARRAY)
-                   jit_insn_store_relative(function, in, offset, temp);
-           return;
+                       break;
     }
-    else if(ILTypeIsDelegate(type))
-    {
+           if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || 
addressKind==MARSHAL_ITEM_OF_ARRAY)
+                   jit_insn_store_relative(function, outAddressValue, offset, 
temp);
            return;
     }
-    else if(ILType_IsClass(type))
+    else if(ILTypeIsDelegateSubClass(type))
     {
            return;
     }
@@ -1416,33 +1886,34 @@
            {
                    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:
                    {
                            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));
+                                   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)
                                    {
                                    
                                            MarshalByRefValue(function, 
jit_insn_dup(function, srcArray),
-                                                                               
    elemType, current,
+                                                                               
    elemType, marshalType,
                                                                                
    MARSHAL_ITEM_OF_STRUCTURE,
                                                                                
    0,
-                                                                               
    jit_insn_load_relative(function, outAddressValue, offset, 
_IL_JIT_TYPE_VPTR));
+                                                                               
    jit_insn_load_relative(function,
+                                                                               
        outAddressValue, offset,
+                                                                               
        _IL_JIT_TYPE_VPTR));
                                    }
                                    else MarshalByRefValue(function, 
jit_insn_dup(function, srcArray),
-                                                                               
    elemType, current,
+                                                                               
    elemType, marshalType,
                                                                                
    MARSHAL_ITEM_OF_STRUCTURE,
                                                                                
    0,
                                                                                
    srcArray);
@@ -1457,14 +1928,19 @@
            {
                            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();
@@ -1474,7 +1950,6 @@
                            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,14 +1958,15 @@
                                                                                
&endLoop);
                            srcElemAddress = jit_insn_dup(function, srcArray);
                            newElemAddress = jit_insn_dup(function, newArray);
-                           counter = arraySize;
+                           counter = jit_insn_dup(function, arraySize);
                            jit_insn_label(function, &startLoop);
-                           jit_insn_store(function, counter, 
jit_insn_sub(function, counter,
+                           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,
+                                                               elemType, 
marshalType,
                                                                
MARSHAL_ITEM_OF_ARRAY,
                                                                0,
                                                                newElemAddress);
@@ -1511,13 +1987,14 @@
                    fprintf(stderr, "Multidimential arrays are not supported 
for marshaling as a return value\n");
                    return;
            }
-
     }
-    // Should not reach here but, make the compiler happy.
+    // 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, ILJitValue outAddress, jit_nint offset, unsigned int 
addressKind)
+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;
@@ -1526,100 +2003,503 @@
     while((field = (ILField *)ILClassNextMemberByKind
                (classInfo, (ILMember *)field, IL_META_MEMBERKIND_FIELD)) != 0)
     {
-           if(!ILField_IsStatic(field))
+           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] = jit_insn_call_native(func, "ILExecThreadCurrent", 
ILExecThreadCurrent,
+                                                               
_ILJitSignature_ILExecThreadCurrent,
+                                                               0, 0, 
JIT_CALL_NOTHROW);
+       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_void_ptr;
+       invokeArgs[0] = jit_insn_call_native(func, "ILExecThreadCurrent", 
ILExecThreadCurrent,
+                                                                           
_ILJitSignature_ILExecThreadCurrent,
+                                                                           0, 
0, JIT_CALL_NOTHROW);
+#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;      
+       ILJitType delInvokeSignature;
+       ILJitFunction function;
+       ILMethod *method;
+       ILClass *info;
+       ILClassPrivate *classPrivate;
+       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] = jit_insn_call_native(function, 
"ILExecThreadCurrent", ILExecThreadCurrent,
+                                                                   
_ILJitSignature_ILExecThreadCurrent,
+                                                                   0, 0, 
JIT_CALL_NOTHROW);
+#ifdef IL_JIT_THREAD_IN_SIGNATURE
+                       jitParams[current + 2] =
+#else
+                       jitParams[current + 1] =
+#endif
+                                                   
jit_insn_call_native(function, "MarshalCustomToObject",
+                                                                           
MarshalCustomToObject,
+                                                                           
_ILJitSignature_MarshalCustomToObject,
+                                                                           
params, 4, JIT_CALL_NOTHROW);
+               }
+               else if(ILTypeIsStringClass(type))
+               {
+                       ILJitValue args[2];
+                       args[0] = jit_insn_call_native(function, 
"ILExecThreadCurrent", ILExecThreadCurrent,
+                                                                   
_ILJitSignature_ILExecThreadCurrent,
+                                                                   0, 0, 
JIT_CALL_NOTHROW);
+                       args[1] = jit_value_get_param(function, current);
+                       switch(marshalType)
+                       {
+                               case IL_META_MARSHAL_ANSI_STRING:
+                               {
+#ifdef IL_JIT_THREAD_IN_SIGNATURE
+                                       jitParams[current + 2] =
+#else
+                                       jitParams[current + 1] =
+#endif
+                                                       
jit_insn_call_native(function,
+                                                                               
"ILStringCreate",
+                                                                               
ILStringCreate,
+                                                                               
_ILJitSignature_ILStringCreate,
+                                                                               
args, 2, JIT_CALL_NOTHROW);
+                               }
+                               break;
+                               case IL_META_MARSHAL_UTF8_STRING:
+                               {
+#ifdef IL_JIT_THREAD_IN_SIGNATURE
+                                       jitParams[current + 2] =
+#else
+                                       jitParams[current + 1] =
+#endif
+                                                       
jit_insn_call_native(function,
+                                                                               
"ILStringCreateUTF8",
+                                                                               
ILStringCreateUTF8,
+                                                                               
_ILJitSignature_ILStringCreateUTF8,
+                                                                               
args, 2, JIT_CALL_NOTHROW);
+                               }
+                               break;
+                               case IL_META_MARSHAL_UTF16_STRING:
+                               {
+#ifdef IL_JIT_THREAD_IN_SIGNATURE
+                                       jitParams[current + 2] =
+#else
+                                       jitParams[current + 1] =
+#endif
+                                                       
jit_insn_call_native(function,
+                                                                               
"ILStringWCreate",
+                                                                               
ILStringWCreate,
+                                                                               
_ILJitSignature_ILStringWCreate,
+                                                                               
args, 2, JIT_CALL_NOTHROW);
+                               }
+                               break;
+                               default: break;
+                       }
+               }
+#ifdef IL_JIT_THREAD_IN_SIGNATURE
+               else if(marshalType != IL_META_MARSHAL_DIRECT || 
NeedMarshalValue(type))
+#else
+               else if(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] = jit_insn_call_native(function, 
"ILExecThreadCurrent", ILExecThreadCurrent,
+                                                                               
        _ILJitSignature_ILExecThreadCurrent,
+                                                                               
        0, 0, JIT_CALL_NOTHROW);
+                               returnValue = jit_insn_call_native(function, 
"MarshalObjectToCustom",
+                                                                               
MarshalObjectToCustom,
+                                                                               
_ILJitSignature_MarshalObjectToCustom,
+                                                                               
params, 4, JIT_CALL_NOTHROW);
+                       }
+                       else if(ILTypeIsStringClass(returnILType))
+                       {
+                               ILJitValue args[2];
+                               args[0] = jit_insn_call_native(function, 
"ILExecThreadCurrent", ILExecThreadCurrent,
+                                                                           
_ILJitSignature_ILExecThreadCurrent,
+                                                                           0, 
0, JIT_CALL_NOTHROW);
+                               args[1] = returnValue;
+                               switch(marshalType)
+                               {
+                                       case IL_META_MARSHAL_ANSI_STRING:
+                                       {
+                                               returnValue = 
jit_insn_call_native(function,
+                                                                               
    "ILStringToAnsi",
+                                                                               
    ILStringToAnsi,
+                                                                               
    _ILJitSignature_ILStringToAnsi,
+                                                                               
    args, 2, JIT_CALL_NOTHROW);
+                                       }
+                                       break;
+                                       case IL_META_MARSHAL_UTF8_STRING:
+                                       {
+                                               returnValue = 
jit_insn_call_native(function,
+                                                                               
    "ILStringToUTF8",
+                                                                               
    ILStringToUTF8,
+                                                                               
    _ILJitSignature_ILStringToUTF8,
+                                                                               
    args, 2, JIT_CALL_NOTHROW);
+                                       }
+                                       break;
+                                       case IL_META_MARSHAL_UTF16_STRING:
+                                       {
+                                               returnValue = 
jit_insn_call_native(function,
+                                                                               
    "ILStringToUTF16",
+                                                                               
    ILStringToUTF16,
+                                                                               
    _ILJitSignature_ILStringToUTF16,
+                                                                               
    args, 2, JIT_CALL_NOTHROW);
+                                       }
+                                       break;
+                                       default: break;
+                               }
+                       }
+                       else if(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_IN_SIGNATURE
+               jitParams[0] = jit_insn_call_native(function, 
"ILExecThreadCurrent", ILExecThreadCurrent,
+                                                                               
_ILJitSignature_ILExecThreadCurrent,
+                                                                               
0, 0, JIT_CALL_NOTHROW);
+               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_IN_SIGNATURE
+                                                           jitParams, 
paramCount + 2,
+#else
+                                                           jitParams, 
paramCount + 1,
+#endif
+                                                           0);
+               else
+               {
+                       returnValue = jit_insn_call(function, 
"callDelegatePinvokeMethod",
+                                                   delFunction, 
delInvokeSignature,
+#ifdef IL_JIT_THREAD_IN_SIGNATURE
+                                                   jitParams, paramCount + 2,
+#else
+                                                   jitParams, paramCount + 1,
+#endif
+                                                   0);
+                       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] = jit_insn_call_native(function, 
"ILExecThreadCurrent", ILExecThreadCurrent,
+                                                                           
_ILJitSignature_ILExecThreadCurrent,
+                                                                           0, 
0, JIT_CALL_NOTHROW);
+                               returnValue = jit_insn_call_native(function, 
"MarshalObjectToCustom", MarshalObjectToCustom,
+                                                                           
_ILJitSignature_MarshalObjectToCustom, params,
+                                                                           4, 
JIT_CALL_NOTHROW);
+                       }
+                       else if(ILTypeIsStringClass(returnILType))
+                       {
+                               ILJitValue args[2];
+                               args[0] = jit_insn_call_native(function, 
"ILExecThreadCurrent", ILExecThreadCurrent,
+                                                                           
_ILJitSignature_ILExecThreadCurrent,
+                                                                           0, 
0, JIT_CALL_NOTHROW);
+                               args[1] = returnValue;
+                               switch(marshalType)
+                               {
+                                       case IL_META_MARSHAL_ANSI_STRING:
+                                       {
+                                               returnValue = 
jit_insn_call_native(function,
+                                                                               
    "ILStringToAnsi",
+                                                                               
    ILStringToAnsi,
+                                                                               
    _ILJitSignature_ILStringToAnsi,
+                                                                               
    args, 2, JIT_CALL_NOTHROW);
+                                       }
+                                       break;
+                                       case IL_META_MARSHAL_UTF8_STRING:
+                                       {
+                                               returnValue = 
jit_insn_call_native(function,
+                                                                               
    "ILStringToUTF8",
+                                                                               
    ILStringToUTF8,
+                                                                               
    _ILJitSignature_ILStringToUTF8,
+                                                                               
    args, 2, JIT_CALL_NOTHROW);
+                                       }
+                                       break;
+                                       case IL_META_MARSHAL_UTF16_STRING:
            {
-                   type = ILTypeGetEnumType(ILField_Type(field));
-                   MarshalByRefValue(function, inAddress, type, 1, 
MARSHAL_ITEM_OF_STRUCTURE, field->offset + offset, outAddress);
+                                               returnValue = 
jit_insn_call_native(function,
+                                                                               
    "ILStringToUTF16",
+                                                                               
    ILStringToUTF16,
+                                                                               
    _ILJitSignature_ILStringToUTF16,
+                                                                               
    args, 2, JIT_CALL_NOTHROW);
            }
+                                       break;
+                                       default: break;
     }
-    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;      
-       ILJitType delInvokeSignature;
-       ILJitFunction function;
-       ILMethod *method;
-       ILClass *info;
-       ILClassPrivate *classPrivate;
-       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)
+                       else if(marshalType!=IL_META_MARSHAL_DIRECT || 
NeedMarshalValue(returnILType))
        {
-               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);
+                               returnValue = 
(ILJitValue)MarshalDelegateReturnValue(function, returnValue,
+                                                                               
        returnILType, marshalType,
+                                                                               
        MARSHAL_FIRST_LEVEL_VALUE, 0,
+                                                                               
        0);
+                       }
        }
-
-       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);
        }
+#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);
-
-               if(type!=0 && ILType_IsSimpleArray(type))
+               marshalType = ILPInvokeGetMarshalType
+                                       (0, method, current, &customName, 
&customNameLen,
+                                                       &customCookie, 
&customCookieLen, type);
+               if((type!=IL_META_MARSHAL_DIRECT || NeedMarshalValue(type))
+                       && marshalType!=IL_META_MARSHAL_CUSTOM && type!=0)
+               {
+                       if(ILType_IsSimpleArray(type))
                {
-                       MarshalDelegateByRefValue(function, newValue, type, 
current + 1, 0, 0, tempParams[current], currentThread);
+                               // Does anyone use this?
+                               MarshalDelegateByRefValue(function, newValue, 
type, marshalType,
+                                                                   
MARSHAL_FIRST_LEVEL_VALUE, 0,
+                                                                   
tempParams[current]);
                }
-               else if(type!=0 && ILType_IsComplex(type))
+                       else if(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);
+                                       // 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,8 +2507,8 @@
        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)
+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,32 +2518,20 @@
     ILJitValue srcElemSize;
     ILType *elemType;
     ILJitValue newElemSize, newArraySize;
-    ILJitValue newArray;
+    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;    
-    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)
+    type = ILTypeGetEnumType(type);
+
+    if(marshalType == IL_META_MARSHAL_CUSTOM)
     {
            fprintf(stderr, "Custom marshaling not supported in delegate 
value\n");
            return 0;
     }
-    type = ILTypeGetEnumType(type);
 
     switch(addressKind)
     {    
@@ -1681,7 +2549,6 @@
            }
            break;
     }
-
     if(ILType_IsPrimitive(type))
     {
        switch(ILType_ToElement(type))
@@ -1825,43 +2692,63 @@
     }
     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);
+           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] = jit_value_create_nint_constant(function, 
_IL_JIT_TYPE_VPTR, (jit_nint)thread);
+           args[0] = jit_insn_call_native(function, "ILExecThreadCurrent", 
ILExecThreadCurrent,
+                                                       
_ILJitSignature_ILExecThreadCurrent,
+                                                       0, 0, JIT_CALL_NOTHROW);
            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;
+           if(addressKind!=MARSHAL_FIRST_LEVEL_VALUE)
+           {
+                   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:
                        {
-                                   jit_insn_store(function, temp, 
jit_insn_call_native(function,
+                               temp = jit_insn_call_native(function,
                                                    "ILStringCreate",
                                                    ILStringCreate,
                                                    
_ILJitSignature_ILStringCreate,
-                                                   args, 2, JIT_CALL_NOTHROW));
+                                                           args, 2, 
JIT_CALL_NOTHROW);
                        }
                        break;
                        case IL_META_MARSHAL_UTF8_STRING:
                        {
-                                   jit_insn_store(function, temp, 
jit_insn_call_native(function,
+                               temp = jit_insn_call_native(function,
                                                    "ILStringCreateUTF8",
                                                    ILStringCreateUTF8,
                                                    
_ILJitSignature_ILStringCreateUTF8,
-                                                   args, 2, JIT_CALL_NOTHROW));
+                                                           args, 2, 
JIT_CALL_NOTHROW);
                        }
                        break;
                        case IL_META_MARSHAL_UTF16_STRING:
                        {
-                                   jit_insn_store(function, temp, 
jit_insn_call_native(function,
+                               temp = jit_insn_call_native(function,
                                                    "ILStringWCreate",
                                                    ILStringWCreate,
                                                    
_ILJitSignature_ILStringWCreate,
-                                                   args, 2, JIT_CALL_NOTHROW));
+                                                           args, 2, 
JIT_CALL_NOTHROW);
+                       }
+                       break;
+                       default:
+                       {
+                               temp = args[1];
                        }
                        break;
            }
@@ -1877,15 +2764,7 @@
            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))
+    else if(type!=0 && ILType_IsComplex(type))
     {
            switch(ILType_Kind(type))
            {
@@ -1895,22 +2774,25 @@
                            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:
                    {
                            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));
+                                   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),
+                                   jit_insn_store(function, temp, 
MarshalDelegateStruct(function,
+                                                                               
            jit_insn_dup(function, srcArray),
                                                                            
elemType,
+                                                                               
            marshalType,
                                                                            0,
                                                                            0,
-                                                                           
MARSHAL_FIRST_LEVEL_VALUE,
-                                                                           
thread));
+                                                                               
            MARSHAL_FIRST_LEVEL_VALUE));
                            }
                            else jit_insn_store(function, temp, srcArray);
                            if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || 
addressKind==MARSHAL_ITEM_OF_ARRAY)
@@ -1918,12 +2800,6 @@
                            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;
            }
 
@@ -1933,20 +2809,25 @@
                            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(thread, elemType)));
+                                                                           
(jit_nint)(ILSizeOfType(ILExecThreadCurrent(),
+                                                                               
                    elemType)));
                            newElemSize = 
jit_value_create_nint_constant(function,
                                                                                
_IL_JIT_TYPE_INT32,
-                                                                               
(jit_nint)(ILSizeOfType(thread, elemType)));
+                                                                           
(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, 
"_ILMalloc",
-                                                                       
ILGCAlloc,
+                           newArray = jit_insn_call_native(function, 
"_ILGCAllocAtomic",
+                                                                       
ILGCAllocAtomic,
                                                                        
_ILJitSignature_malloc,
                                                                        args, 
1, 0);
                            jit_insn_store_relative(function, newArray, 0, 
arraySize);
@@ -1962,18 +2843,18 @@
                                                                                
                _IL_JIT_TYPE_INT32,
                                                                                
                (jit_nint)(sizeof(ILUInt32))));
                            newElemAddress = jit_insn_dup(function, newArray);
-                           counter = arraySize;
+                           counter = jit_insn_dup(function, arraySize);
                            jit_insn_label(function, &startLoop);
-                           jit_insn_store(function, counter, 
jit_insn_sub(function, counter,
+                           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,
+                                                       elemType, marshalType,
                                                        MARSHAL_ITEM_OF_ARRAY,
                                                        0,
-                                                       newElemAddress,
-                                                       thread);
+                                                       newElemAddress);
                            jit_insn_store(function, srcElemAddress,
                                                            
jit_insn_add(function,
                                                            srcElemAddress, 
srcElemSize));
@@ -1996,44 +2877,47 @@
 
     }
 
-    // Should not reach here if all every case is above, however do something 
smart.
+    // 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, ILJitValue outAddress, jit_nint offset, 
unsigned int addressKind, ILExecThread *thread)
+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(thread, structureILType);
+    unsigned int structSize = ILSizeOfType(ILExecThreadCurrent(), 
structureILType);
     ILField *field = 0;
-    ILJitValue newStruct = 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, 1, 
MARSHAL_ITEM_OF_STRUCTURE, field->offset, outAddress, thread);
+                   MarshalDelegateValue(function, inAddress, type, 
marshalType, MARSHAL_ITEM_OF_STRUCTURE,
+                                           field->offset, outAddress);
            }
     }
-    return jit_insn_dup(function, newStruct);
+    return newStruct;
 }
        
-
-static ILJitValue MarshalDelegateReturnValue(jit_function_t function, 
ILJitValue in, ILType *type, unsigned int addressKind, jit_nint offset, 
ILJitValue outAddress, ILExecThread *thread)
+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);
@@ -2043,34 +2927,15 @@
     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)
+    type = ILTypeGetEnumType(type);    
+    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)
+    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,17 +3079,20 @@
                        {
                                case MARSHAL_ITEM_OF_ARRAY:
                                {
-                                       return 
(ILJitValue)MarshalDelegateReturnStruct(function, valuePtr, refType, 
outAddressValue, offset, MARSHAL_ITEM_OF_ARRAY, thread);
+                                       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, 
outAddressValue, offset, MARSHAL_ITEM_OF_STRUCTURE, thread);
+                                       return 
(ILJitValue)MarshalDelegateReturnStruct(function, valuePtr, refType,
+                                                           marshalType, 
outAddressValue, offset, MARSHAL_ITEM_OF_STRUCTURE);
                                }
                                break;
                                default:
                                {
-                                       return 
(ILJitValue)MarshalDelegateReturnStruct(function, valuePtr, refType, 0, 0, 
MARSHAL_FIRST_LEVEL_VALUE, thread);
+                                       return 
(ILJitValue)MarshalDelegateReturnStruct(function, valuePtr, refType,
+                                                           marshalType, 0, 0, 
MARSHAL_FIRST_LEVEL_VALUE);
                                }
                                break;
                        }
@@ -2241,55 +3109,74 @@
                default:  break;
        }                       
     }
-    else if (ILType_IsValueType(type))
+    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);
+                           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, outAddressValue, 0, MARSHAL_FIRST_LEVEL_VALUE, thread);
+                           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] = jit_value_create_nint_constant(function, 
_IL_JIT_TYPE_VPTR, (jit_nint)thread);
+           args[0] = jit_insn_call_native(function, "ILExecThreadCurrent", 
ILExecThreadCurrent,
+                                                               
_ILJitSignature_ILExecThreadCurrent,
+                                                               0, 0, 
JIT_CALL_NOTHROW);
            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;
+           if(addressKind!=MARSHAL_FIRST_LEVEL_VALUE)
+           {
+                   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:
                        {
-                                   jit_insn_store(function, temp, 
jit_insn_call_native(function,
+                               temp = jit_insn_call_native(function,
                                                    "ILStringToAnsi",
                                                    ILStringToAnsi,
                                                    
_ILJitSignature_ILStringToAnsi,
-                                                   args, 2, JIT_CALL_NOTHROW));
+                                                           args, 2, 
JIT_CALL_NOTHROW);
                        }
                        break;
                        case IL_META_MARSHAL_UTF8_STRING:
                        {
-                                   jit_insn_store(function, temp, 
jit_insn_call_native(function,
+                               temp = jit_insn_call_native(function,
                                                    "ILStringToUTF8",
                                                    ILStringToUTF8,
                                                    
_ILJitSignature_ILStringToUTF8,
-                                                   args, 2, JIT_CALL_NOTHROW));
+                                                           args, 2, 
JIT_CALL_NOTHROW);
                        }
                        break;
                        case IL_META_MARSHAL_UTF16_STRING:
                        {
-                                   jit_insn_store(function, temp, 
jit_insn_call_native(function,
+                               temp = jit_insn_call_native(function,
                                                    "ILStringToUTF16",
                                                    ILStringToUTF16,
                                                    
_ILJitSignature_ILStringToUTF16,
-                                                   args, 2, JIT_CALL_NOTHROW));
+                                                           args, 2, 
JIT_CALL_NOTHROW);
+                       }
+                       break;
+                       default:
+                       {
+                               temp = args[1];
                        }
                        break;
            }
@@ -2300,17 +3187,18 @@
     else if(ILTypeIsDelegateSubClass(type))
     {
            temp = jit_insn_dup(function, in);
-           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);
+           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);
+           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, 3, JIT_CALL_NOTHROW));
+                                           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);
@@ -2332,17 +3220,18 @@
                    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, srcArray, offset, _IL_JIT_TYPE_VPTR));
+                                   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,
+                                                               elemType, 
marshalType,
                                                                
MARSHAL_ITEM_OF_ARRAY,
                                                                0,
-                                                               
jit_insn_dup(function, srcArray),
-                                                               thread);
+                                                               
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,8 +3243,8 @@
 
                    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.
+                           // 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,10 +3261,12 @@
     return temp;
 }
 
-static ILJitValue MarshalDelegateReturnStruct(jit_function_t function, 
ILJitValue inAddress, ILType *structureILType, ILJitValue outAddress, jit_nint 
offset, unsigned int addressKind, ILExecThread *thread)
+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(thread, structureILType);
+        unsigned int structSize = ILSizeOfType(ILExecThreadCurrent(), 
structureILType);
        ILField *field = 0;
        ILType *type;
 
@@ -2384,7 +3275,7 @@
                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",
+                       outAddress = jit_insn_call_native(function, "ILGCAlloc",
                                                                    ILGCAlloc,
                                                                    
_ILJitSignature_malloc,
                                                                    &sizeValue, 
1, 0);
@@ -2414,27 +3305,35 @@
                        {
                                case MARSHAL_FIRST_LEVEL_VALUE:
                                {
-                                       MarshalDelegateReturnValue(function, 
inAddress, type, MARSHAL_ITEM_OF_STRUCTURE, field->offset + offset, outAddress, 
thread);
+                                       MarshalDelegateReturnValue(function, 
inAddress, type, marshalType,
+                                                                       
MARSHAL_ITEM_OF_STRUCTURE, field->offset + offset,
+                                                                       
outAddress);
                                }
                                break;
                                case MARSHAL_ITEM_OF_STRUCTURE:
                                {
-                                       MarshalDelegateReturnValue(function, 
inAddress, type, MARSHAL_ITEM_OF_STRUCTURE, field->offset + offset, outAddress, 
thread);
+                                       MarshalDelegateReturnValue(function, 
inAddress, type, marshalType,
+                                                                       
MARSHAL_ITEM_OF_STRUCTURE, field->offset + offset,
+                                                                       
outAddress);
                                }
                                break;
                                default:
                                {
-                                       MarshalDelegateReturnValue(function, 
inAddress, type, MARSHAL_ITEM_OF_ARRAY, field->offset + offset, outAddress, 
thread);
+                                       MarshalDelegateReturnValue(function, 
inAddress, type, marshalType,
+                                                                       
MARSHAL_ITEM_OF_ARRAY, field->offset + offset,
+                                                                       
outAddress);
                                }
                                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)
+#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);
@@ -2449,25 +3348,12 @@
     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)
+
+    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)
     {
@@ -2588,11 +3474,11 @@
     {
            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);
+                   MarshalDelegateByRefStruct(function, 
jit_insn_address_of(function, in), type, marshalType,
+                                                   
jit_insn_address_of(function, in), 0, MARSHAL_ITEM_OF_STRUCTURE);
                    return;
            }
-           temp = jit_insn_load_relative(function, in, offset, 
_IL_JIT_TYPE_VPTR);
-           MarshalDelegateByRefStruct(function, temp, type, temp, 0, 
MARSHAL_ITEM_OF_STRUCTURE, thread);
+           MarshalDelegateByRefStruct(function, in, type, marshalType, 
outAddressValue, offset, MARSHAL_ITEM_OF_STRUCTURE);
            return;
     }
     else if(ILTypeIsDelegateSubClass(type))
@@ -2601,82 +3487,98 @@
     }
     else if(ILTypeIsStringClass(type))
     {
-           args[0] = jit_value_create_nint_constant(function, 
_IL_JIT_TYPE_VPTR, (jit_nint)thread);
+           args[0] = jit_insn_call_native(function, "ILExecThreadCurrent", 
ILExecThreadCurrent,
+                                                           
_ILJitSignature_ILExecThreadCurrent,
+                                                           0, 0, 
JIT_CALL_NOTHROW);
            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;
+           if(addressKind!=MARSHAL_FIRST_LEVEL_VALUE)
+           {
+                   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:
                        {
-                                   jit_insn_store(function, temp, 
jit_insn_call_native(function,
+                               temp = jit_insn_call_native(function,
                                                    "ILStringToAnsi",
                                                    ILStringToAnsi,
                                                    
_ILJitSignature_ILStringToAnsi,
-                                                   args, 2, JIT_CALL_NOTHROW));
+                                                           args, 2, 
JIT_CALL_NOTHROW);
                        }
                        break;
                        case IL_META_MARSHAL_UTF8_STRING:
                        {
-                                   jit_insn_store(function, temp, 
jit_insn_call_native(function,
+                               temp = jit_insn_call_native(function,
                                                    "ILStringToUTF8",
                                                    ILStringToUTF8,
                                                    
_ILJitSignature_ILStringToUTF8,
-                                                   args, 2, JIT_CALL_NOTHROW));
+                                                           args, 2, 
JIT_CALL_NOTHROW);
                        }
                        break;
                        case IL_META_MARSHAL_UTF16_STRING:
                        {
-                                   jit_insn_store(function, temp, 
jit_insn_call_native(function,
+                               temp = jit_insn_call_native(function,
                                                    "ILStringToUTF16",
                                                    ILStringToUTF16,
                                                    
_ILJitSignature_ILStringToUTF16,
-                                                   args, 2, JIT_CALL_NOTHROW));
+                                                           args, 2, 
JIT_CALL_NOTHROW);
                        }
                        break;
+                       default:
+                       {
+                               temp = args[1];
            }
-           if(addressKind==MARSHAL_ITEM_OF_STRUCTURE || 
addressKind==MARSHAL_ITEM_OF_ARRAY)
-                   jit_insn_store_relative(function, in, offset, temp);
-           return;
+                       break;
     }
-    else if(ILType_IsClass(type))
-    {
+           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))
+    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));
+                                   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, current,
+                                                                               
elemType, marshalType,
                                                                                
    MARSHAL_ITEM_OF_STRUCTURE,
                                                                                
    0,
-                                                                               
    jit_insn_load_relative(function, outAddressValue, offset, 
_IL_JIT_TYPE_VPTR),
-                                                                               
    thread);
+                                                                               
jit_insn_load_relative(function,
+                                                                               
                        outAddressValue,
+                                                                               
                        offset,
+                                                                               
                        _IL_JIT_TYPE_VPTR));
                                    }
                                    else MarshalDelegateByRefValue(function, 
jit_insn_dup(function, srcArray),
-                                                                               
    elemType, current,
+                                                                               
    elemType, marshalType,
                                                                                
    MARSHAL_ITEM_OF_STRUCTURE,
                                                                                
    0,
-                                                                               
    srcArray,
-                                                                               
    thread);
-                           }
-                           return;
+                                                                               
    srcArray);
                    }
-                   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;
@@ -2688,9 +3590,11 @@
                            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);
-
-                           if(!NeedMarshalValue(elemType))
+                           elemType = ILTypeGetEnumType(elemType);
+                           if(!NeedMarshalValue(elemType) || 
ILType_IsValueType(elemType))
                            {
                                    return;
                            }
@@ -2711,18 +3615,18 @@
                                                                                
&endLoop);
                            newElemAddress = jit_insn_dup(function, 
outAddressValue);
                            srcElemAddress = jit_insn_add_relative(function, 
srcArray, (jit_nint)(sizeof(ILUInt32)));
-                           counter = arraySize;
+                           counter = jit_insn_dup(function, arraySize);
                            jit_insn_label(function, &startLoop);
-                           jit_insn_store(function, counter, 
jit_insn_sub(function, counter,
+                           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,
+                                                       elemType, marshalType,
                                                        MARSHAL_ITEM_OF_ARRAY,
                                                        0,
-                                                       newElemAddress,
-                                                       thread);
+                                                       newElemAddress);
                            jit_insn_store(function, srcElemAddress,
                                                            
jit_insn_add(function,
                                                            srcElemAddress, 
srcElemSize));
@@ -2742,12 +3646,14 @@
            }
 
     }
-
-    // Should not reach here, but make the compiler happy.
+    // 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, ILJitValue outAddress, jit_nint offset, 
unsigned int addressKind, ILExecThread *thread)
+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,8 +3665,46 @@
            if(!ILField_IsStatic(field))
            {
                    type = ILTypeGetEnumType(ILField_Type(field));
-                   MarshalDelegateByRefValue(function, inAddress, type, 1, 
MARSHAL_ITEM_OF_STRUCTURE, field->offset + offset, outAddress, thread);
+                   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: /cvsroot/dotgnu-pnet/pnet/engine/lib_marshal.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- engine/lib_marshal.c        22 Jul 2006 08:48:32 -0000      1.9
+++ engine/lib_marshal.c        24 Sep 2006 18:16:21 -0000      1.10
@@ -644,7 +644,7 @@
                {
            #ifdef IL_USE_JIT
                        *((void **)ptr) = ILJitDelegateGetClosure
-                               (thread, *((ILObject **)ptr), type);
+                               (*((ILObject **)ptr), type);
            #else
                        *((void **)ptr) = _ILDelegateGetClosure
                                (thread, *((ILObject **)ptr));




reply via email to

[Prev in Thread] Current Thread [Next in Thread]