1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
#if !FULL_AOT_RUNTIME
using System.Reflection.Emit;
#endif
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Text;
namespace System.Reflection
{
[Serializable]
partial class MethodBase
{
//
// This is a quick version for our own use. We should override
// it where possible so that it does not allocate an array.
// They cannot be abstract otherwise we break public contract
//
internal virtual ParameterInfo[] GetParametersInternal ()
{
// Override me
return GetParameters ();
}
internal virtual int GetParametersCount ()
{
// Override me
return GetParametersInternal ().Length;
}
internal virtual Type GetParameterType (int pos)
{
throw new NotImplementedException ();
}
internal virtual int get_next_table_index (object obj, int table, int count) {
#if !FULL_AOT_RUNTIME
if (this is MethodBuilder) {
MethodBuilder mb = (MethodBuilder)this;
return mb.get_next_table_index (obj, table, count);
}
if (this is ConstructorBuilder) {
ConstructorBuilder mb = (ConstructorBuilder)this;
return mb.get_next_table_index (obj, table, count);
}
#endif
throw new Exception ("Method is not a builder method");
}
internal virtual string FormatNameAndSig (bool serialization)
{
// Serialization uses ToString to resolve MethodInfo overloads.
StringBuilder sbName = new StringBuilder (Name);
sbName.Append ("(");
sbName.Append (ConstructParameters (GetParameterTypes (), CallingConvention, serialization));
sbName.Append (")");
return sbName.ToString ();
}
internal virtual Type[] GetParameterTypes ()
{
ParameterInfo[] paramInfo = GetParametersNoCopy ();
Type[] parameterTypes = new Type [paramInfo.Length];
for (int i = 0; i < paramInfo.Length; i++)
parameterTypes [i] = paramInfo [i].ParameterType;
return parameterTypes;
}
internal virtual ParameterInfo[] GetParametersNoCopy () => GetParameters ();
public static MethodBase GetMethodFromHandle (RuntimeMethodHandle handle)
{
if (handle.IsNullHandle ())
throw new ArgumentException (Environment.GetResourceString("Argument_InvalidHandle"));
#if MONO
MethodBase m = RuntimeMethodInfo.GetMethodFromHandleInternalType (handle.Value, IntPtr.Zero);
if (m == null)
throw new ArgumentException ("The handle is invalid.");
#else
MethodBase m = RuntimeType.GetMethodBase (handle.GetMethodInfo ());
#endif
Type declaringType = m.DeclaringType;
if (declaringType != null && declaringType.IsGenericType)
throw new ArgumentException (String.Format (
CultureInfo.CurrentCulture, Environment.GetResourceString ("Argument_MethodDeclaringTypeGeneric"),
m, declaringType.GetGenericTypeDefinition ()));
return m;
}
[System.Runtime.InteropServices.ComVisible(false)]
public static MethodBase GetMethodFromHandle (RuntimeMethodHandle handle, RuntimeTypeHandle declaringType)
{
if (handle.IsNullHandle ())
throw new ArgumentException (Environment.GetResourceString("Argument_InvalidHandle"));
#if MONO
MethodBase m = RuntimeMethodInfo.GetMethodFromHandleInternalType (handle.Value, declaringType.Value);
if (m == null)
throw new ArgumentException ("The handle is invalid.");
return m;
#else
return RuntimeType.GetMethodBase (declaringType.GetRuntimeType (), handle.GetMethodInfo ());
#endif
}
internal static string ConstructParameters (Type[] parameterTypes, CallingConventions callingConvention, bool serialization)
{
StringBuilder sbParamList = new StringBuilder ();
string comma = "";
for (int i = 0; i < parameterTypes.Length; i++) {
Type t = parameterTypes [i];
sbParamList.Append (comma);
string typeName = t.FormatTypeName (serialization);
// Legacy: Why use "ByRef" for by ref parameters? What language is this?
// VB uses "ByRef" but it should precede (not follow) the parameter name.
// Why don't we just use "&"?
if (t.IsByRef && !serialization) {
sbParamList.Append (typeName.TrimEnd (new char[] { '&' }));
sbParamList.Append (" ByRef");
} else {
sbParamList.Append (typeName);
}
comma = ", ";
}
if ((callingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs) {
sbParamList.Append (comma);
sbParamList.Append ("...");
}
return sbParamList.ToString ();
}
#if MONO
[MethodImplAttribute (MethodImplOptions.InternalCall)]
public extern static MethodBase GetCurrentMethod ();
#else
[System.Security.DynamicSecurityMethod] // Specify DynamicSecurityMethod attribute to prevent inlining of the caller.
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static MethodBase GetCurrentMethod ()
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return RuntimeMethodInfo.InternalGetCurrentMethod (ref stackMark);
}
#endif
}
}
|