private MethodInfo original_method_info;
private DelegateData data;
+
+ private bool method_is_virtual;
#pragma warning restore 169, 414, 649
#endregion
return method_info;
} else {
if (method != IntPtr.Zero) {
- method_info = (MethodInfo)MethodBase.GetMethodFromHandleNoGenericCheck (new RuntimeMethodHandle (method));
+ if (!method_is_virtual)
+ method_info = (MethodInfo)MethodBase.GetMethodFromHandleNoGenericCheck (new RuntimeMethodHandle (method));
+ else
+ method_info = GetVirtualMethod_internal ();
}
return method_info;
}
}
}
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ extern MethodInfo GetVirtualMethod_internal ();
+
public object Target {
get {
return m_target;
ICALL_TYPE(DELEGATE, "System.Delegate", DELEGATE_1)
ICALL(DELEGATE_1, "AllocDelegateLike_internal", ves_icall_System_Delegate_AllocDelegateLike_internal)
ICALL(DELEGATE_2, "CreateDelegate_internal", ves_icall_System_Delegate_CreateDelegate_internal)
+ICALL(DELEGATE_3, "GetVirtualMethod_internal", ves_icall_System_Delegate_GetVirtualMethod_internal)
ICALL_TYPE(DEBUGR, "System.Diagnostics.Debugger", DEBUGR_1)
ICALL(DEBUGR_1, "IsAttached_internal", ves_icall_System_Diagnostics_Debugger_IsAttached_internal)
return ret;
}
+ICALL_EXPORT MonoReflectionMethod*
+ves_icall_System_Delegate_GetVirtualMethod_internal (MonoDelegate *delegate)
+{
+ return mono_method_get_object (mono_domain_get (), mono_object_get_virtual_method (delegate->target, delegate->method), mono_object_class (delegate->target));
+}
+
/* System.Buffer */
static inline gint32
MonoReflectionMethod *method_info;
MonoReflectionMethod *original_method_info;
MonoObject *data;
+ MonoBoolean method_is_virtual;
};
typedef struct _MonoMulticastDelegate MonoMulticastDelegate;
DECL_OFFSET(MonoDelegate, invoke_impl)
DECL_OFFSET(MonoDelegate, method)
DECL_OFFSET(MonoDelegate, method_code)
+DECL_OFFSET(MonoDelegate, method_is_virtual)
DECL_OFFSET(MonoInternalThread, tid)
DECL_OFFSET(MonoInternalThread, small_id)
MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, obj->dreg, MONO_STRUCT_OFFSET (MonoDelegate, method_ptr), dreg);
}
+ dreg = alloc_preg (cfg);
+ MONO_EMIT_NEW_ICONST (cfg, dreg, virtual ? 1 : 0);
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, obj->dreg, MONO_STRUCT_OFFSET (MonoDelegate, method_is_virtual), dreg);
+
/* All the checks which are in mono_delegate_ctor () are done by the delegate trampoline */
return obj;
delegate9.cs \
delegate10.cs \
delegate11.cs \
+ delegate12.cs \
remoting1.cs \
remoting2.cs \
remoting3.cs \
--- /dev/null
+using System;
+
+class MainClass
+{
+ public static int Main(string[] args)
+ {
+ DerivedClass o = new DerivedClass();
+
+ Func<string> del1 = GetDel1 (o);
+ Func<string> del2 = GetDel2 (o);
+
+
+ Console.WriteLine("Action\n======\nReflected type: {0}\nDeclaring type: {1}\nAttributes: {2}\nResult: {3}",
+ del1.Method.ReflectedType, del1.Method.DeclaringType, del1.Method.Attributes, del1 ());
+
+ Console.WriteLine ();
+
+ Console.WriteLine("Delegate\n========\nReflected type: {0}\nDeclaring type: {1}\nAttributes: {2}\nResult: {3}",
+ del2.Method.ReflectedType, del2.Method.DeclaringType, del2.Method.Attributes, del2 ());
+
+ if (del1.Method.ReflectedType != typeof (DerivedClass))
+ return 10;
+ if (del1.Method.DeclaringType != typeof (DerivedClass))
+ return 11;
+ if (del1 () != "Derived method")
+ return 12;
+
+ if (del2.Method.ReflectedType != typeof (DerivedClass))
+ return 20;
+ if (del2.Method.DeclaringType != typeof (DerivedClass))
+ return 21;
+ if (del2 () != "Derived method")
+ return 22;
+
+ return 0;
+ }
+
+ static Func<string> GetDel1 (DerivedClass o)
+ {
+ return o.GetMethod();
+ }
+
+ static Func<string> GetDel2 (DerivedClass o)
+ {
+ return (Func<string>) Delegate.CreateDelegate(typeof(Func<string>), o, o.GetMethod().Method);
+ }
+}
+
+class BaseClass
+{
+ public Func<string> GetMethod()
+ {
+ return MyMethod;
+ }
+
+ public virtual string MyMethod()
+ {
+ return "Base method";
+ }
+}
+
+class DerivedClass : BaseClass
+{
+ public override string MyMethod()
+ {
+ return "Derived method";
+ }
+}