Author: zoltan
Date: 2005-03-23 14:43:38 -0500 (Wed, 23 Mar 2005)
New Revision: 42165

Modified:
   trunk/mono/mono/metadata/ChangeLog
   trunk/mono/mono/metadata/marshal.c
   trunk/mono/mono/metadata/marshal.h
Log:
2005-03-23  Zoltan Varga  <[EMAIL PROTECTED]>

        * marshal.c (mono_marshal_get_managed_wrapper): Add support for the 
modopt(CallConvCdecl).


Modified: trunk/mono/mono/metadata/ChangeLog
===================================================================
--- trunk/mono/mono/metadata/ChangeLog  2005-03-23 19:14:21 UTC (rev 42164)
+++ trunk/mono/mono/metadata/ChangeLog  2005-03-23 19:43:38 UTC (rev 42165)
@@ -1,5 +1,9 @@
 2005-03-23  Zoltan Varga  <[EMAIL PROTECTED]>
 
+       * marshal.c (mono_marshal_get_managed_wrapper): Add support for the 
modopt(CallConvCdecl).
+
+2005-03-23  Zoltan Varga  <[EMAIL PROTECTED]>
+
        * class-internals.h object-internals.h class.c reflection.c: Extend the
        mono_lookup_dynamic_token () function to return the class of the
        token as well. 

Modified: trunk/mono/mono/metadata/marshal.c
===================================================================
--- trunk/mono/mono/metadata/marshal.c  2005-03-23 19:14:21 UTC (rev 42164)
+++ trunk/mono/mono/metadata/marshal.c  2005-03-23 19:43:38 UTC (rev 42165)
@@ -200,10 +200,8 @@
 gpointer
 mono_delegate_to_ftnptr (MonoDelegate *delegate)
 {
-       MonoMethod *method, *wrapper, *invoke;
-       MonoMarshalSpec **mspecs;
+       MonoMethod *method, *wrapper;
        MonoClass *klass;
-       int i;
 
        if (!delegate)
                return NULL;
@@ -215,18 +213,9 @@
        g_assert (klass->delegate);
 
        method = delegate->method_info->method;
-       invoke = mono_class_get_method_from_name (klass, "Invoke", 
mono_method_signature (method)->param_count);
 
-       mspecs = g_new0 (MonoMarshalSpec*, mono_method_signature 
(invoke)->param_count + 1);
-       mono_method_get_marshal_info (invoke, mspecs);
+       wrapper = mono_marshal_get_managed_wrapper (method, klass, 
delegate->target);
 
-       wrapper = mono_marshal_get_managed_wrapper (method, delegate->target, 
mspecs);
-
-       for (i = mono_method_signature (invoke)->param_count; i >= 0; i--)
-               if (mspecs [i])
-                       mono_metadata_free_marshal_spec (mspecs [i]);
-       g_free (mspecs);
-
        delegate->delegate_trampoline =  mono_compile_method (wrapper);
 
        // Add the delegate to the delegate hash table
@@ -6046,11 +6035,14 @@
  * generates IL code to call managed methods from unmanaged code 
  */
 MonoMethod *
-mono_marshal_get_managed_wrapper (MonoMethod *method, MonoObject *this, 
MonoMarshalSpec **mspecs)
+mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass 
*delegate_klass, MonoObject *this)
 {
-       MonoMethodSignature *sig, *csig;
+       static MonoClass *UnmanagedFunctionPointerAttribute;
+       MonoMethodSignature *sig, *csig, *invoke_sig;
        MonoMethodBuilder *mb;
-       MonoMethod *res;
+       MonoMethod *res, *invoke;
+       MonoMarshalSpec **mspecs;
+       MonoMethodPInvoke piinfo;
        GHashTable *cache;
        int i, *tmp_locals;
        EmitMarshalContext m;
@@ -6067,6 +6059,12 @@
        if (!this && (res = mono_marshal_find_in_cache (cache, method)))
                return res;
 
+       invoke = mono_class_get_method_from_name (delegate_klass, "Invoke", 
mono_method_signature (method)->param_count);
+       invoke_sig = mono_method_signature (invoke);
+
+       mspecs = g_new0 (MonoMarshalSpec*, mono_method_signature 
(invoke)->param_count + 1);
+       mono_method_get_marshal_info (invoke, mspecs);
+
        sig = mono_method_signature (method);
 
        mb = mono_mb_new (method->klass, method->name, 
MONO_WRAPPER_NATIVE_TO_MANAGED);
@@ -6091,6 +6089,11 @@
        csig->hasthis = 0;
        csig->pinvoke = 1;
 
+       m.mb = mb;
+       m.sig = sig;
+       m.piinfo = NULL;
+       m.retobj_var = 0;
+
 #ifdef PLATFORM_WIN32
        /* 
         * Under windows, delegates passed to native code must use the STDCALL
@@ -6099,6 +6102,55 @@
        csig->call_convention = MONO_CALL_STDCALL;
 #endif
 
+       /* FIXME: Handle the 2.0 UnmanagedFunctionPointerAttribute as well */
+
+       /* Change default calling convention if needed */
+       /* Why is this a modopt ? */
+       if (invoke_sig->ret && invoke_sig->ret->num_mods) {
+               for (i = 0; i < invoke_sig->ret->num_mods; ++i) {
+                       MonoClass *cmod_class = mono_class_get 
(delegate_klass->image, invoke_sig->ret->modifiers [i].token);
+                       g_assert (cmod_class);
+                       printf ("B: %s\n", cmod_class->name);
+                       if ((cmod_class->image == mono_defaults.corlib) && 
!strcmp (cmod_class->name_space, "System.Runtime.CompilerServices")) {
+                               if (!strcmp (cmod_class->name, "CallConvCdecl"))
+                                       csig->call_convention = MONO_CALL_C;
+                               else if (!strcmp (cmod_class->name, 
"CallConvStdcall"))
+                                       csig->call_convention = 
MONO_CALL_STDCALL;
+                               else if (!strcmp (cmod_class->name, 
"CallConvFastcall"))
+                                       csig->call_convention = 
MONO_CALL_FASTCALL;
+                               else if (!strcmp (cmod_class->name, 
"CallConvThiscall"))
+                                       csig->call_convention = 
MONO_CALL_THISCALL;
+                       }
+               }
+       }
+
+       /* Handle the UnmanagedFunctionPointerAttribute */
+       if (!UnmanagedFunctionPointerAttribute)
+               UnmanagedFunctionPointerAttribute = mono_class_from_name 
(mono_defaults.corlib, "System.Runtime.InteropServices", 
"UnmanagedFunctionPointerAttribute");
+
+       /* The attribute is only available in Net 2.0 */
+       if (UnmanagedFunctionPointerAttribute) {
+               MonoReflectionUnmanagedFunctionPointerAttribute *attr;
+               MonoCustomAttrInfo *cinfo;
+
+               /* 
+                * The pinvoke attributes are stored in a real custom attribute 
so we have to
+                * construct it.
+                */
+               cinfo = mono_custom_attrs_from_class (delegate_klass);
+               attr = 
(MonoReflectionUnmanagedFunctionPointerAttribute*)mono_custom_attrs_get_attr 
(cinfo, UnmanagedFunctionPointerAttribute);
+               if (attr) {
+                       memset (&piinfo, 0, sizeof (piinfo));
+                       m.piinfo = &piinfo;
+                       piinfo.piflags = (attr->call_conv << 8) | 
(attr->charset ? (attr->charset - 1) * 2 : 1) | attr->set_last_error;
+               }
+               if (!cinfo->cached)
+                       mono_custom_attrs_free (cinfo);
+
+               /* FIXME: modify the calling convention */
+               g_assert_not_reached ();
+       }
+
        /* fixme: howto handle this ? */
        if (sig->hasthis) {
                if (this) {
@@ -6111,11 +6163,6 @@
                }
        } 
 
-       m.mb = mb;
-       m.sig = sig;
-       m.piinfo = NULL;
-       m.retobj_var = 0;
-
        /* we first do all conversions */
        tmp_locals = alloca (sizeof (int) * sig->param_count);
        for (i = 0; i < sig->param_count; i ++) {
@@ -6234,6 +6281,11 @@
        }
        mono_mb_free (mb);
 
+       for (i = mono_method_signature (invoke)->param_count; i >= 0; i--)
+               if (mspecs [i])
+                       mono_metadata_free_marshal_spec (mspecs [i]);
+       g_free (mspecs);
+
        /* printf ("CODE FOR %s: \n%s.\n", mono_method_full_name (res, TRUE), 
mono_disasm_code (0, res, ((MonoMethodNormal*)res)->header->code, 
((MonoMethodNormal*)res)->header->code + 
((MonoMethodNormal*)res)->header->code_size)); */
 
        return res;

Modified: trunk/mono/mono/metadata/marshal.h
===================================================================
--- trunk/mono/mono/metadata/marshal.h  2005-03-23 19:14:21 UTC (rev 42164)
+++ trunk/mono/mono/metadata/marshal.h  2005-03-23 19:43:38 UTC (rev 42165)
@@ -186,7 +186,7 @@
 mono_marshal_get_runtime_invoke (MonoMethod *method);
 
 MonoMethod *
-mono_marshal_get_managed_wrapper (MonoMethod *method, MonoObject *this, 
MonoMarshalSpec **mspecs);
+mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass 
*delegate_klass, MonoObject *this);
 
 MonoMethod *
 mono_marshal_get_icall_wrapper (MonoMethodSignature *sig, const char *name, 
gconstpointer func);

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to