[System.Private.CoreLib] Fix the type conflicts with corefx types
[mono-project.git] / mcs / class / System.Private.CoreLib / System.Reflection.Emit / MethodBuilder.cs
blob4e4d90da99597072ed7a14d998bf9f51312300ec
1 //
2 // System.Reflection.Emit/MethodBuilder.cs
3 //
4 // Author:
5 // Paolo Molaro (lupus@ximian.com)
6 //
7 // (C) 2001 Ximian, Inc. http://www.ximian.com
8 //
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 #if MONO_FEATURE_SRE
34 using System;
35 using System.Reflection;
36 using System.Reflection.Emit;
37 using System.Globalization;
38 using System.Runtime.CompilerServices;
39 using System.Runtime.InteropServices;
40 using System.Diagnostics.SymbolStore;
41 using System.Collections.Generic;
43 namespace System.Reflection.Emit
45 [StructLayout (LayoutKind.Sequential)]
46 public sealed partial class MethodBuilder : MethodInfo
48 #pragma warning disable 169, 414
49 private RuntimeMethodHandle mhandle;
50 private Type rtype;
51 internal Type[] parameters;
52 private MethodAttributes attrs; /* It's used directly by MCS */
53 private MethodImplAttributes iattrs;
54 private string name;
55 private int table_idx;
56 private byte[] code;
57 private ILGenerator ilgen;
58 private TypeBuilder type;
59 internal ParameterBuilder[] pinfo;
60 private CustomAttributeBuilder[] cattrs;
61 private MethodInfo[] override_methods;
62 private string pi_dll;
63 private string pi_entry;
64 private CharSet charset;
65 private uint extra_flags; /* this encodes set_last_error etc */
66 private CallingConvention native_cc;
67 private CallingConventions call_conv;
68 private bool init_locals = true;
69 private IntPtr generic_container;
70 internal GenericTypeParameterBuilder[] generic_params;
71 private Type[] returnModReq;
72 private Type[] returnModOpt;
73 private Type[][] paramModReq;
74 private Type[][] paramModOpt;
75 private object permissions;
76 #pragma warning restore 169, 414
77 RuntimeMethodInfo created;
79 internal MethodBuilder (TypeBuilder tb, string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnModReq, Type[] returnModOpt, Type[] parameterTypes, Type[][] paramModReq, Type[][] paramModOpt)
81 this.name = name;
82 this.attrs = attributes;
83 this.call_conv = callingConvention;
84 this.rtype = returnType;
85 this.returnModReq = returnModReq;
86 this.returnModOpt = returnModOpt;
87 this.paramModReq = paramModReq;
88 this.paramModOpt = paramModOpt;
89 // The MSDN docs does not specify this, but the MS MethodBuilder
90 // appends a HasThis flag if the method is not static
91 if ((attributes & MethodAttributes.Static) == 0)
92 this.call_conv |= CallingConventions.HasThis;
93 if (parameterTypes != null) {
94 for (int i = 0; i < parameterTypes.Length; ++i)
95 if (parameterTypes [i] == null)
96 throw new ArgumentException ("Elements of the parameterTypes array cannot be null", "parameterTypes");
98 this.parameters = new Type [parameterTypes.Length];
99 System.Array.Copy (parameterTypes, this.parameters, parameterTypes.Length);
101 type = tb;
102 table_idx = get_next_table_index (this, 0x06, 1);
104 ((ModuleBuilder)tb.Module).RegisterToken (this, GetToken ().Token);
107 internal MethodBuilder (TypeBuilder tb, string name, MethodAttributes attributes,
108 CallingConventions callingConvention, Type returnType, Type[] returnModReq, Type[] returnModOpt, Type[] parameterTypes, Type[][] paramModReq, Type[][] paramModOpt,
109 String dllName, String entryName, CallingConvention nativeCConv, CharSet nativeCharset)
110 : this (tb, name, attributes, callingConvention, returnType, returnModReq, returnModOpt, parameterTypes, paramModReq, paramModOpt)
112 pi_dll = dllName;
113 pi_entry = entryName;
114 native_cc = nativeCConv;
115 charset = nativeCharset;
118 public override bool ContainsGenericParameters {
119 get { throw new NotSupportedException (); }
122 public bool InitLocals {
123 get {return init_locals;}
124 set {init_locals = value;}
127 internal TypeBuilder TypeBuilder {
128 get {return type;}
131 public override RuntimeMethodHandle MethodHandle {
132 get {
133 throw NotSupported ();
137 internal RuntimeMethodHandle MethodHandleInternal {
138 get {
139 return mhandle;
143 public override Type ReturnType {
144 get { return rtype; }
147 public override Type ReflectedType {
148 get { return type; }
151 public override Type DeclaringType {
152 get { return type; }
155 public override string Name {
156 get { return name; }
159 public override MethodAttributes Attributes {
160 get { return attrs; }
163 public override ICustomAttributeProvider ReturnTypeCustomAttributes {
164 get { return null; }
167 public override CallingConventions CallingConvention {
168 get { return call_conv; }
171 // FIXME: "Not implemented"
172 public string Signature {
173 get {
174 throw new NotImplementedException ();
178 /* Used by mcs */
179 internal bool BestFitMapping {
180 set {
181 extra_flags = (uint) ((extra_flags & ~0x30) | (uint)(value ? 0x10 : 0x20));
185 /* Used by mcs */
186 internal bool ThrowOnUnmappableChar {
187 set {
188 extra_flags = (uint) ((extra_flags & ~0x3000) | (uint)(value ? 0x1000 : 0x2000));
192 /* Used by mcs */
193 internal bool ExactSpelling {
194 set {
195 extra_flags = (uint) ((extra_flags & ~0x01) | (uint)(value ? 0x01 : 0x00));
199 /* Used by mcs */
200 internal bool SetLastError {
201 set {
202 extra_flags = (uint) ((extra_flags & ~0x40) | (uint)(value ? 0x40 : 0x00));
206 public MethodToken GetToken()
208 return new MethodToken(0x06000000 | table_idx);
211 public override MethodInfo GetBaseDefinition()
213 return this;
216 public override MethodImplAttributes GetMethodImplementationFlags()
218 return iattrs;
221 public override ParameterInfo[] GetParameters()
223 if (!type.is_created)
224 throw NotSupported ();
226 return GetParametersInternal ();
229 internal override ParameterInfo[] GetParametersInternal ()
231 if (parameters == null)
232 return null;
234 ParameterInfo[] retval = new ParameterInfo [parameters.Length];
235 for (int i = 0; i < parameters.Length; i++) {
236 retval [i] = RuntimeParameterInfo.New (pinfo?[i + 1], parameters [i], this, i + 1);
238 return retval;
241 internal override int GetParametersCount ()
243 if (parameters == null)
244 return 0;
246 return parameters.Length;
249 internal override Type GetParameterType (int pos) {
250 return parameters [pos];
253 internal MethodBase RuntimeResolve () {
254 return type.RuntimeResolve ().GetMethod (this);
257 public Module GetModule ()
259 return type.Module;
262 public void CreateMethodBody (byte[] il, int count)
264 if ((il != null) && ((count < 0) || (count > il.Length)))
265 throw new ArgumentOutOfRangeException ("Index was out of range. Must be non-negative and less than the size of the collection.");
267 if ((code != null) || type.is_created)
268 throw new InvalidOperationException ("Type definition of the method is complete.");
270 if (il == null)
271 code = null;
272 else {
273 code = new byte [count];
274 System.Array.Copy(il, code, count);
278 public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
280 throw NotSupported ();
283 public override bool IsDefined (Type attributeType, bool inherit)
285 throw NotSupported ();
288 public override object[] GetCustomAttributes (bool inherit)
291 * On MS.NET, this always returns not_supported, but we can't do this
292 * since there would be no way to obtain custom attributes of
293 * dynamically created ctors.
295 if (type.is_created)
296 return MonoCustomAttrs.GetCustomAttributes (this, inherit);
297 else
298 throw NotSupported ();
301 public override object[] GetCustomAttributes (Type attributeType, bool inherit)
303 if (type.is_created)
304 return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
305 else
306 throw NotSupported ();
309 public ILGenerator GetILGenerator ()
311 return GetILGenerator (64);
314 public ILGenerator GetILGenerator (int size)
316 if (((iattrs & MethodImplAttributes.CodeTypeMask) !=
317 MethodImplAttributes.IL) ||
318 ((iattrs & MethodImplAttributes.ManagedMask) !=
319 MethodImplAttributes.Managed))
320 throw new InvalidOperationException ("Method body should not exist.");
321 if (ilgen != null)
322 return ilgen;
323 ilgen = new ILGenerator (type.Module, ((ModuleBuilder)type.Module).GetTokenGenerator (), size);
324 return ilgen;
327 public ParameterBuilder DefineParameter (int position, ParameterAttributes attributes, string strParamName)
329 RejectIfCreated ();
332 // Extension: Mono allows position == 0 for the return attribute
334 if ((position < 0) || parameters == null || (position > parameters.Length))
335 throw new ArgumentOutOfRangeException ("position");
337 ParameterBuilder pb = new ParameterBuilder (this, position, attributes, strParamName);
338 if (pinfo == null)
339 pinfo = new ParameterBuilder [parameters.Length + 1];
340 pinfo [position] = pb;
341 return pb;
344 internal void check_override ()
346 if (override_methods != null) {
347 foreach (var m in override_methods) {
348 if (m.IsVirtual && !IsVirtual)
349 throw new TypeLoadException (String.Format("Method '{0}' override '{1}' but it is not virtual", name, m));
354 internal void fixup ()
356 if (((attrs & (MethodAttributes.Abstract | MethodAttributes.PinvokeImpl)) == 0) && ((iattrs & (MethodImplAttributes.Runtime | MethodImplAttributes.InternalCall)) == 0)) {
357 // do not allow zero length method body on MS.NET 2.0 (and higher)
358 if (((ilgen == null) || (ilgen.ILOffset == 0)) && (code == null || code.Length == 0))
359 throw new InvalidOperationException (
360 String.Format ("Method '{0}.{1}' does not have a method body.",
361 DeclaringType.FullName, Name));
363 if (ilgen != null)
364 ilgen.label_fixup (this);
367 internal void ResolveUserTypes () {
368 rtype = TypeBuilder.ResolveUserType (rtype);
369 TypeBuilder.ResolveUserTypes (parameters);
370 TypeBuilder.ResolveUserTypes (returnModReq);
371 TypeBuilder.ResolveUserTypes (returnModOpt);
372 if (paramModReq != null) {
373 foreach (var types in paramModReq)
374 TypeBuilder.ResolveUserTypes (types);
376 if (paramModOpt != null) {
377 foreach (var types in paramModOpt)
378 TypeBuilder.ResolveUserTypes (types);
382 internal void GenerateDebugInfo (ISymbolWriter symbolWriter)
384 if (ilgen != null && ilgen.HasDebugInfo) {
385 SymbolToken token = new SymbolToken (GetToken().Token);
386 symbolWriter.OpenMethod (token);
387 symbolWriter.SetSymAttribute (token, "__name", System.Text.Encoding.UTF8.GetBytes (Name));
388 ilgen.GenerateDebugInfo (symbolWriter);
389 symbolWriter.CloseMethod ();
393 public void SetCustomAttribute (CustomAttributeBuilder customBuilder)
395 if (customBuilder == null)
396 throw new ArgumentNullException ("customBuilder");
398 switch (customBuilder.Ctor.ReflectedType.FullName) {
399 case "System.Runtime.CompilerServices.MethodImplAttribute":
400 byte[] data = customBuilder.Data;
401 int impla; // the (stupid) ctor takes a short or an int ...
402 impla = (int)data [2];
403 impla |= ((int)data [3]) << 8;
404 iattrs |= (MethodImplAttributes)impla;
405 return;
407 case "System.Runtime.InteropServices.DllImportAttribute":
408 CustomAttributeBuilder.CustomAttributeInfo attr = CustomAttributeBuilder.decode_cattr (customBuilder);
409 bool preserveSig = true;
412 * It would be easier to construct a DllImportAttribute from
413 * the custom attribute builder, but the DllImportAttribute
414 * does not contain all the information required here, ie.
415 * - some parameters, like BestFitMapping has three values
416 * ("on", "off", "missing"), but DllImportAttribute only
417 * contains two (on/off).
418 * - PreserveSig is true by default, while it is false by
419 * default in DllImportAttribute.
422 pi_dll = (string)attr.ctorArgs[0];
423 if (pi_dll == null || pi_dll.Length == 0)
424 throw new ArgumentException ("DllName cannot be empty");
426 native_cc = System.Runtime.InteropServices.CallingConvention.Winapi;
428 for (int i = 0; i < attr.namedParamNames.Length; ++i) {
429 string name = attr.namedParamNames [i];
430 object value = attr.namedParamValues [i];
432 if (name == "CallingConvention")
433 native_cc = (CallingConvention)value;
434 else if (name == "CharSet")
435 charset = (CharSet)value;
436 else if (name == "EntryPoint")
437 pi_entry = (string)value;
438 else if (name == "ExactSpelling")
439 ExactSpelling = (bool)value;
440 else if (name == "SetLastError")
441 SetLastError = (bool)value;
442 else if (name == "PreserveSig")
443 preserveSig = (bool)value;
444 else if (name == "BestFitMapping")
445 BestFitMapping = (bool)value;
446 else if (name == "ThrowOnUnmappableChar")
447 ThrowOnUnmappableChar = (bool)value;
450 attrs |= MethodAttributes.PinvokeImpl;
451 if (preserveSig)
452 iattrs |= MethodImplAttributes.PreserveSig;
453 return;
455 case "System.Runtime.InteropServices.PreserveSigAttribute":
456 iattrs |= MethodImplAttributes.PreserveSig;
457 return;
458 case "System.Runtime.CompilerServices.SpecialNameAttribute":
459 attrs |= MethodAttributes.SpecialName;
460 return;
461 case "System.Security.SuppressUnmanagedCodeSecurityAttribute":
462 attrs |= MethodAttributes.HasSecurity;
463 break;
466 if (cattrs != null) {
467 CustomAttributeBuilder[] new_array = new CustomAttributeBuilder [cattrs.Length + 1];
468 cattrs.CopyTo (new_array, 0);
469 new_array [cattrs.Length] = customBuilder;
470 cattrs = new_array;
471 } else {
472 cattrs = new CustomAttributeBuilder [1];
473 cattrs [0] = customBuilder;
477 [ComVisible (true)]
478 public void SetCustomAttribute (ConstructorInfo con, byte[] binaryAttribute)
480 if (con == null)
481 throw new ArgumentNullException ("con");
482 if (binaryAttribute == null)
483 throw new ArgumentNullException ("binaryAttribute");
484 SetCustomAttribute (new CustomAttributeBuilder (con, binaryAttribute));
487 public void SetImplementationFlags (MethodImplAttributes attributes)
489 RejectIfCreated ();
490 iattrs = attributes;
493 [Obsolete ("An alternate API is available: Emit the MarshalAs custom attribute instead.")]
494 public void SetMarshal (UnmanagedMarshal unmanagedMarshal)
496 RejectIfCreated ();
497 throw new NotImplementedException ();
500 // FIXME:
501 public void SetSymCustomAttribute (string name, byte[] data)
503 RejectIfCreated ();
504 throw new NotImplementedException ();
507 public override string ToString()
509 return "MethodBuilder [" + type.Name + "::" + name + "]";
512 // FIXME:
513 public override bool Equals (object obj)
515 return base.Equals (obj);
518 public override int GetHashCode ()
520 return name.GetHashCode ();
523 internal override int get_next_table_index (object obj, int table, int count)
525 return type.get_next_table_index (obj, table, count);
528 void ExtendArray<T> (ref T[] array, T elem) {
529 if (array == null) {
530 array = new T [1];
531 } else {
532 var newa = new T [array.Length + 1];
533 Array.Copy (array, newa, array.Length);
534 array = newa;
536 array [array.Length - 1] = elem;
539 internal void set_override (MethodInfo mdecl)
541 ExtendArray<MethodInfo> (ref override_methods, mdecl);
544 private void RejectIfCreated ()
546 if (type.is_created)
547 throw new InvalidOperationException ("Type definition of the method is complete.");
550 private Exception NotSupported ()
552 return new NotSupportedException ("The invoked member is not supported in a dynamic module.");
555 public override MethodInfo MakeGenericMethod (params Type [] typeArguments)
557 if (!IsGenericMethodDefinition)
558 throw new InvalidOperationException ("Method is not a generic method definition");
559 if (typeArguments == null)
560 throw new ArgumentNullException ("typeArguments");
561 if (generic_params.Length != typeArguments.Length)
562 throw new ArgumentException ("Incorrect length", "typeArguments");
563 foreach (Type type in typeArguments) {
564 if (type == null)
565 throw new ArgumentNullException ("typeArguments");
568 return new MethodOnTypeBuilderInst (this, typeArguments);
571 public override bool IsGenericMethodDefinition {
572 get {
573 return generic_params != null;
577 public override bool IsGenericMethod {
578 get {
579 return generic_params != null;
583 public override MethodInfo GetGenericMethodDefinition ()
585 if (!IsGenericMethodDefinition)
586 throw new InvalidOperationException ();
588 return this;
591 public override Type[] GetGenericArguments ()
593 if (generic_params == null)
594 return null;
596 Type[] result = new Type [generic_params.Length];
597 for (int i = 0; i < generic_params.Length; i++)
598 result [i] = generic_params [i];
600 return result;
603 public GenericTypeParameterBuilder[] DefineGenericParameters (params string[] names)
605 if (names == null)
606 throw new ArgumentNullException ("names");
607 if (names.Length == 0)
608 throw new ArgumentException ("names");
610 generic_params = new GenericTypeParameterBuilder [names.Length];
611 for (int i = 0; i < names.Length; i++) {
612 string item = names [i];
613 if (item == null)
614 throw new ArgumentNullException ("names");
615 generic_params [i] = new GenericTypeParameterBuilder (type, this, item, i);
618 return generic_params;
621 public void SetReturnType (Type returnType)
623 rtype = returnType;
626 public void SetParameters (params Type[] parameterTypes)
628 if (parameterTypes != null) {
629 for (int i = 0; i < parameterTypes.Length; ++i)
630 if (parameterTypes [i] == null)
631 throw new ArgumentException ("Elements of the parameterTypes array cannot be null", "parameterTypes");
633 this.parameters = new Type [parameterTypes.Length];
634 System.Array.Copy (parameterTypes, this.parameters, parameterTypes.Length);
638 public void SetSignature (Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
640 SetReturnType (returnType);
641 SetParameters (parameterTypes);
642 this.returnModReq = returnTypeRequiredCustomModifiers;
643 this.returnModOpt = returnTypeOptionalCustomModifiers;
644 this.paramModReq = parameterTypeRequiredCustomModifiers;
645 this.paramModOpt = parameterTypeOptionalCustomModifiers;
648 public override Module Module {
649 get {
650 return GetModule ();
654 public override ParameterInfo ReturnParameter {
655 get {
656 if (!type.is_created)
657 throw new InvalidOperationException (SR.InvalidOperation_TypeNotCreated);
658 if (created == null)
659 created = (RuntimeMethodInfo)MethodBase.GetMethodFromHandle (mhandle);
660 return created.ReturnParameter;
665 [StructLayout(LayoutKind.Sequential)]
666 readonly struct ExceptionHandler : IEquatable<ExceptionHandler>
668 internal readonly int m_exceptionClass;
669 internal readonly int m_tryStartOffset;
670 internal readonly int m_tryEndOffset;
671 internal readonly int m_filterOffset;
672 internal readonly int m_handlerStartOffset;
673 internal readonly int m_handlerEndOffset;
674 internal readonly ExceptionHandlingClauseOptions m_kind;
676 public int ExceptionTypeToken
678 get { return m_exceptionClass; }
681 public int TryOffset
683 get { return m_tryStartOffset; }
686 public int TryLength
688 get { return m_tryEndOffset - m_tryStartOffset; }
691 public int FilterOffset
693 get { return m_filterOffset; }
696 public int HandlerOffset
698 get { return m_handlerStartOffset; }
701 public int HandlerLength
703 get { return m_handlerEndOffset - m_handlerStartOffset; }
706 public ExceptionHandlingClauseOptions Kind
708 get { return m_kind; }
711 internal ExceptionHandler(int tryStartOffset, int tryEndOffset, int filterOffset, int handlerStartOffset, int handlerEndOffset,
712 int kind, int exceptionTypeToken)
714 m_tryStartOffset = tryStartOffset;
715 m_tryEndOffset = tryEndOffset;
716 m_filterOffset = filterOffset;
717 m_handlerStartOffset = handlerStartOffset;
718 m_handlerEndOffset = handlerEndOffset;
719 m_kind = (ExceptionHandlingClauseOptions)kind;
720 m_exceptionClass = exceptionTypeToken;
723 private static bool IsValidKind(ExceptionHandlingClauseOptions kind)
725 switch (kind)
727 case ExceptionHandlingClauseOptions.Clause:
728 case ExceptionHandlingClauseOptions.Filter:
729 case ExceptionHandlingClauseOptions.Finally:
730 case ExceptionHandlingClauseOptions.Fault:
731 return true;
733 default:
734 return false;
738 public override int GetHashCode()
740 return m_exceptionClass ^ m_tryStartOffset ^ m_tryEndOffset ^ m_filterOffset ^ m_handlerStartOffset ^ m_handlerEndOffset ^ (int)m_kind;
743 public override bool Equals(Object obj)
745 return obj is ExceptionHandler && Equals((ExceptionHandler)obj);
748 public bool Equals(ExceptionHandler other)
750 return
751 other.m_exceptionClass == m_exceptionClass &&
752 other.m_tryStartOffset == m_tryStartOffset &&
753 other.m_tryEndOffset == m_tryEndOffset &&
754 other.m_filterOffset == m_filterOffset &&
755 other.m_handlerStartOffset == m_handlerStartOffset &&
756 other.m_handlerEndOffset == m_handlerEndOffset &&
757 other.m_kind == m_kind;
760 public static bool operator ==(ExceptionHandler left, ExceptionHandler right)
762 return left.Equals(right);
765 public static bool operator !=(ExceptionHandler left, ExceptionHandler right)
767 return !left.Equals(right);
771 #endif