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