Author: joncham
Date: 2006-11-27 23:04:55 -0500 (Mon, 27 Nov 2006)
New Revision: 68551
Modified:
trunk/mono/mono/metadata/ChangeLog
trunk/mono/mono/metadata/marshal.c
Log:
2006-11-27 Jonathan Chambers <[EMAIL PROTECTED]>
* marshal.c:
(mono_marshal_emit_managed_wrapper): Level of indirection for
mono_marshal_get_managed_wrapper so that a wrapper for a
managed method
can be generated without a delegate class.
(mono_marshal_get_managed_wrapper): Move wrapper logic to
mono_marshal_emit_managed_wrapper.
Signed-off-by: Jonathan Chambers <[EMAIL PROTECTED]>
Modified: trunk/mono/mono/metadata/ChangeLog
===================================================================
--- trunk/mono/mono/metadata/ChangeLog 2006-11-28 04:03:34 UTC (rev 68550)
+++ trunk/mono/mono/metadata/ChangeLog 2006-11-28 04:04:55 UTC (rev 68551)
@@ -1,3 +1,13 @@
+2006-11-27 Jonathan Chambers <[EMAIL PROTECTED]>
+
+ * marshal.c:
+ (mono_marshal_emit_managed_wrapper): Level of indirection for
+ mono_marshal_get_managed_wrapper so that a wrapper for a
managed method
+ can be generated without a delegate class.
+ (mono_marshal_get_managed_wrapper): Move wrapper logic to
mono_marshal_emit_managed_wrapper.
+
+ Signed-off-by: Jonathan Chambers <[EMAIL PROTECTED]>
+
2006-11-27 Gonzalo Paniagua Javier <[EMAIL PROTECTED]>
* console-io.c: add the 'signal' call removed by mistake. Fixes bug
Modified: trunk/mono/mono/metadata/marshal.c
===================================================================
--- trunk/mono/mono/metadata/marshal.c 2006-11-28 04:03:34 UTC (rev 68550)
+++ trunk/mono/mono/metadata/marshal.c 2006-11-28 04:04:55 UTC (rev 68551)
@@ -7752,45 +7752,17 @@
return res;
}
-
-/*
- * generates IL code to call managed methods from unmanaged code
- */
-MonoMethod *
-mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass
*delegate_klass, MonoObject *this)
+
+/* FIXME: moving GC */
+static void
+mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature
*invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod
*method, MonoObject* this)
{
- static MonoClass *UnmanagedFunctionPointerAttribute;
- MonoMethodSignature *sig, *csig, *invoke_sig;
- MonoMethodBuilder *mb;
- MonoMethod *res, *invoke;
- MonoMarshalSpec **mspecs;
- MonoMethodPInvoke piinfo;
- GHashTable *cache;
+ MonoMethodSignature *sig, *csig;
int i, *tmp_locals;
- EmitMarshalContext m;
- g_assert (method != NULL);
- g_assert (!mono_method_signature (method)->pinvoke);
+ sig = m->sig;
+ csig = m->csig;
- /*
- * FIXME: Should cache the method+delegate type pair, since the same
method
- * could be called with different delegates, thus different marshalling
- * options.
- */
- cache = method->klass->image->managed_wrapper_cache;
- 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);
-
/* allocate local 0 (pointer) src_ptr */
mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
/* allocate local 1 (pointer) dst_ptr */
@@ -7806,73 +7778,6 @@
mono_mb_emit_icon (mb, 0);
mono_mb_emit_stloc (mb, 2);
- /* we copy the signature, so that we can modify it */
- csig = signature_dup (method->klass->image, sig);
- csig->hasthis = 0;
- csig->pinvoke = 1;
-
- m.mb = mb;
- m.sig = sig;
- m.piinfo = NULL;
- m.retobj_var = 0;
- m.csig = csig;
- m.image = method->klass->image;
-
-#ifdef PLATFORM_WIN32
- /*
- * Under windows, delegates passed to native code must use the STDCALL
- * calling convention.
- */
- csig->call_convention = MONO_CALL_STDCALL;
-#endif
-
- /* 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);
- 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);
- if (cinfo) {
- 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;
-
- csig->call_convention = attr->call_conv - 1;
- }
- if (!cinfo->cached)
- mono_custom_attrs_free (cinfo);
- }
- }
-
/* fixme: howto handle this ? */
if (sig->hasthis) {
if (this) {
@@ -7896,7 +7801,7 @@
case MONO_TYPE_ARRAY:
case MONO_TYPE_SZARRAY:
case MONO_TYPE_STRING:
- tmp_locals [i] = emit_marshal (&m, i, sig->params [i],
mspecs [i + 1], 0, &csig->params [i], MARSHAL_ACTION_MANAGED_CONV_IN);
+ tmp_locals [i] = emit_marshal (m, i, sig->params [i],
mspecs [i + 1], 0, &csig->params [i], MARSHAL_ACTION_MANAGED_CONV_IN);
break;
default:
@@ -7923,7 +7828,7 @@
mono_mb_emit_managed_call (mb, method, NULL);
if (mspecs [0] && mspecs [0]->native == MONO_NATIVE_CUSTOM) {
- emit_marshal (&m, 0, sig->ret, mspecs [0], 0, NULL,
MARSHAL_ACTION_MANAGED_CONV_RESULT);
+ emit_marshal (m, 0, sig->ret, mspecs [0], 0, NULL,
MARSHAL_ACTION_MANAGED_CONV_RESULT);
}
else
if (!sig->ret->byref) {
@@ -7949,12 +7854,12 @@
break;
case MONO_TYPE_STRING:
csig->ret = &mono_defaults.int_class->byval_arg;
- emit_marshal (&m, 0, sig->ret, mspecs [0], 0, NULL,
MARSHAL_ACTION_MANAGED_CONV_RESULT);
+ emit_marshal (m, 0, sig->ret, mspecs [0], 0, NULL,
MARSHAL_ACTION_MANAGED_CONV_RESULT);
break;
case MONO_TYPE_VALUETYPE:
case MONO_TYPE_CLASS:
case MONO_TYPE_SZARRAY:
- emit_marshal (&m, 0, sig->ret, mspecs [0], 0, NULL,
MARSHAL_ACTION_MANAGED_CONV_RESULT);
+ emit_marshal (m, 0, sig->ret, mspecs [0], 0, NULL,
MARSHAL_ACTION_MANAGED_CONV_RESULT);
break;
default:
g_warning ("return type 0x%02x unknown",
sig->ret->type);
@@ -7970,13 +7875,13 @@
MonoMarshalSpec *spec = mspecs [i + 1];
if (spec && spec->native == MONO_NATIVE_CUSTOM) {
- emit_marshal (&m, i, t, mspecs [i + 1], tmp_locals [i],
NULL, MARSHAL_ACTION_MANAGED_CONV_OUT);
+ emit_marshal (m, i, t, mspecs [i + 1], tmp_locals [i],
NULL, MARSHAL_ACTION_MANAGED_CONV_OUT);
}
else if (t->byref) {
switch (t->type) {
case MONO_TYPE_CLASS:
case MONO_TYPE_VALUETYPE:
- emit_marshal (&m, i, t, mspecs [i + 1],
tmp_locals [i], NULL, MARSHAL_ACTION_MANAGED_CONV_OUT);
+ emit_marshal (m, i, t, mspecs [i + 1],
tmp_locals [i], NULL, MARSHAL_ACTION_MANAGED_CONV_OUT);
break;
}
}
@@ -7986,7 +7891,7 @@
case MONO_TYPE_SZARRAY:
case MONO_TYPE_CLASS:
case MONO_TYPE_VALUETYPE:
- emit_marshal (&m, i, invoke_sig->params [i],
mspecs [i + 1], tmp_locals [i], NULL, MARSHAL_ACTION_MANAGED_CONV_OUT);
+ emit_marshal (m, i, invoke_sig->params [i],
mspecs [i + 1], tmp_locals [i], NULL, MARSHAL_ACTION_MANAGED_CONV_OUT);
break;
default:
g_assert_not_reached ();
@@ -7994,17 +7899,127 @@
}
}
- if (m.retobj_var) {
- mono_mb_emit_ldloc (mb, m.retobj_var);
+ if (m->retobj_var) {
+ mono_mb_emit_ldloc (mb, m->retobj_var);
mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
- mono_mb_emit_op (mb, CEE_MONO_RETOBJ, m.retobj_class);
+ mono_mb_emit_op (mb, CEE_MONO_RETOBJ, m->retobj_class);
}
else {
if (!MONO_TYPE_IS_VOID(sig->ret))
mono_mb_emit_ldloc (mb, 3);
mono_mb_emit_byte (mb, CEE_RET);
}
+}
+
+/*
+ * generates IL code to call managed methods from unmanaged code
+ */
+MonoMethod *
+mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass
*delegate_klass, MonoObject *this)
+{
+ static MonoClass *UnmanagedFunctionPointerAttribute;
+ MonoMethodSignature *sig, *csig, *invoke_sig;
+ MonoMethodBuilder *mb;
+ MonoMethod *res, *invoke;
+ MonoMarshalSpec **mspecs;
+ MonoMethodPInvoke piinfo;
+ GHashTable *cache;
+ int i;
+ EmitMarshalContext m;
+
+ g_assert (method != NULL);
+ g_assert (!mono_method_signature (method)->pinvoke);
+
+ /*
+ * FIXME: Should cache the method+delegate type pair, since the same
method
+ * could be called with different delegates, thus different marshalling
+ * options.
+ */
+ cache = method->klass->image->managed_wrapper_cache;
+ 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);
+
+
+ /* we copy the signature, so that we can modify it */
+ csig = signature_dup (method->klass->image, sig);
+ csig->hasthis = 0;
+ csig->pinvoke = 1;
+
+ m.mb = mb;
+ m.sig = sig;
+ m.piinfo = NULL;
+ m.retobj_var = 0;
+ m.csig = csig;
+ m.image = method->klass->image;
+
+#ifdef PLATFORM_WIN32
+ /*
+ * Under windows, delegates passed to native code must use the STDCALL
+ * calling convention.
+ */
+ csig->call_convention = MONO_CALL_STDCALL;
+#endif
+
+ /* 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);
+ 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);
+ if (cinfo) {
+ 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;
+
+ csig->call_convention = attr->call_conv - 1;
+ }
+ if (!cinfo->cached)
+ mono_custom_attrs_free (cinfo);
+ }
+ }
+
+ mono_marshal_emit_managed_wrapper (mb, invoke_sig, mspecs, &m, method,
this);
+
if (!this)
res = mono_mb_create_and_cache (cache, method,
mb, csig, sig->param_count + 16);
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches