1 // ==++==
2 //
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 //
5 // ==--==
6 // <OWNER>Microsoft</OWNER>
7 //
8 
9 namespace System.Reflection.Emit
10 {
11     using System.Text;
12     using System;
13     using CultureInfo = System.Globalization.CultureInfo;
14     using System.Diagnostics.SymbolStore;
15     using System.Reflection;
16     using System.Security;
17     using System.Collections;
18     using System.Collections.Generic;
19     using System.Security.Permissions;
20     using System.Runtime.InteropServices;
21     using System.Diagnostics.Contracts;
22 #if !MONO
23     [HostProtection(MayLeakOnAbort = true)]
24     [ClassInterface(ClassInterfaceType.None)]
25     [ComDefaultInterface(typeof(_MethodBuilder))]
26 [System.Runtime.InteropServices.ComVisible(true)]
27     public sealed class MethodBuilder : MethodInfo, _MethodBuilder
28     {
29         #region Private Data Members
30         // Identity
31         internal String m_strName; // The name of the method
32         private MethodToken m_tkMethod; // The token of this method
33         private ModuleBuilder m_module;
34         internal TypeBuilder m_containingType;
35 
36         // IL
37         private int[] m_mdMethodFixups;              // The location of all of the token fixups. Null means no fixups.
38         private byte[] m_localSignature;             // Local signature if set explicitly via DefineBody. Null otherwise.
39         internal LocalSymInfo m_localSymInfo;        // keep track debugging local information
40         internal ILGenerator m_ilGenerator;          // Null if not used.
41         private byte[] m_ubBody;                     // The IL for the method
42         private ExceptionHandler[] m_exceptions; // Exception handlers or null if there are none.
43         private const int DefaultMaxStack = 16;
44         private int m_maxStack = DefaultMaxStack;
45 
46         // Flags
47         internal bool m_bIsBaked;
48         private bool m_bIsGlobalMethod;
49         private bool m_fInitLocals; // indicating if the method stack frame will be zero initialized or not.
50 
51         // Attributes
52         private MethodAttributes m_iAttributes;
53         private CallingConventions m_callingConvention;
54         private MethodImplAttributes m_dwMethodImplFlags;
55 
56         // Parameters
57         private SignatureHelper m_signature;
58         internal Type[] m_parameterTypes;
59         private ParameterBuilder m_retParam;
60         private Type m_returnType;
61         private Type[] m_returnTypeRequiredCustomModifiers;
62         private Type[] m_returnTypeOptionalCustomModifiers;
63         private Type[][] m_parameterTypeRequiredCustomModifiers;
64         private Type[][] m_parameterTypeOptionalCustomModifiers;
65 
66         // Generics
67         private GenericTypeParameterBuilder[] m_inst;
68         private bool m_bIsGenMethDef;
69         #endregion
70 
71         #region Constructor
MethodBuilder(String name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, ModuleBuilder mod, TypeBuilder type, bool bIsGlobalMethod)72         internal MethodBuilder(String name, MethodAttributes attributes, CallingConventions callingConvention,
73             Type returnType, Type[] parameterTypes, ModuleBuilder mod, TypeBuilder type, bool bIsGlobalMethod)
74         {
75             Init(name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null, mod, type, bIsGlobalMethod);
76         }
77 
MethodBuilder(String name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers, ModuleBuilder mod, TypeBuilder type, bool bIsGlobalMethod)78         internal MethodBuilder(String name, MethodAttributes attributes, CallingConventions callingConvention,
79             Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
80             Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers,
81             ModuleBuilder mod, TypeBuilder type, bool bIsGlobalMethod)
82         {
83             Init(name, attributes, callingConvention,
84                 returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers,
85                 parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers,
86                 mod, type, bIsGlobalMethod);
87         }
88 
Init(String name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers, ModuleBuilder mod, TypeBuilder type, bool bIsGlobalMethod)89         private void Init(String name, MethodAttributes attributes, CallingConventions callingConvention,
90             Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
91             Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers,
92             ModuleBuilder mod, TypeBuilder type, bool bIsGlobalMethod)
93         {
94             if (name == null)
95                 throw new ArgumentNullException("name");
96 
97             if (name.Length == 0)
98                 throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
99 
100             if (name[0] == '\0')
101                 throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), "name");
102 
103             if (mod == null)
104                 throw new ArgumentNullException("mod");
105             Contract.EndContractBlock();
106 
107             if (parameterTypes != null)
108             {
109                 foreach(Type t in parameterTypes)
110                 {
111                     if (t == null)
112                         throw new ArgumentNullException("parameterTypes");
113                 }
114             }
115 
116             m_strName = name;
117             m_module = mod;
118             m_containingType = type;
119 
120             //
121             //if (returnType == null)
122             //{
123             //    m_returnType = typeof(void);
124             //}
125             //else
126             {
127                 m_returnType = returnType;
128             }
129 
130             if ((attributes & MethodAttributes.Static) == 0)
131             {
132                 // turn on the has this calling convention
133                 callingConvention = callingConvention | CallingConventions.HasThis;
134             }
135             else if ((attributes & MethodAttributes.Virtual) != 0)
136             {
137                 // A method can't be both static and virtual
138                 throw new ArgumentException(Environment.GetResourceString("Arg_NoStaticVirtual"));
139             }
140 
141             if ((attributes & MethodAttributes.SpecialName) != MethodAttributes.SpecialName)
142             {
143                 if ((type.Attributes & TypeAttributes.Interface) == TypeAttributes.Interface)
144                 {
145                     // methods on interface have to be abstract + virtual except special name methods such as type initializer
146                     if ((attributes & (MethodAttributes.Abstract | MethodAttributes.Virtual)) !=
147                         (MethodAttributes.Abstract | MethodAttributes.Virtual) &&
148                         (attributes & MethodAttributes.Static) == 0)
149                         throw new ArgumentException(Environment.GetResourceString("Argument_BadAttributeOnInterfaceMethod"));
150                 }
151             }
152 
153             m_callingConvention = callingConvention;
154 
155             if (parameterTypes != null)
156             {
157                 m_parameterTypes = new Type[parameterTypes.Length];
158                 Array.Copy(parameterTypes, m_parameterTypes, parameterTypes.Length);
159             }
160             else
161             {
162                 m_parameterTypes = null;
163             }
164 
165             m_returnTypeRequiredCustomModifiers = returnTypeRequiredCustomModifiers;
166             m_returnTypeOptionalCustomModifiers = returnTypeOptionalCustomModifiers;
167             m_parameterTypeRequiredCustomModifiers = parameterTypeRequiredCustomModifiers;
168             m_parameterTypeOptionalCustomModifiers = parameterTypeOptionalCustomModifiers;
169 
170 //            m_signature = SignatureHelper.GetMethodSigHelper(mod, callingConvention,
171 //                returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers,
172 //                parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);
173 
174             m_iAttributes = attributes;
175             m_bIsGlobalMethod = bIsGlobalMethod;
176             m_bIsBaked = false;
177             m_fInitLocals = true;
178 
179             m_localSymInfo = new LocalSymInfo();
180             m_ubBody = null;
181             m_ilGenerator = null;
182 
183             // Default is managed IL. Manged IL has bit flag 0x0020 set off
184             m_dwMethodImplFlags = MethodImplAttributes.IL;
185         }
186 
187         #endregion
188 
189         #region Internal Members
190 
CheckContext(params Type[][] typess)191         internal void CheckContext(params Type[][] typess)
192         {
193             m_module.CheckContext(typess);
194         }
195 
CheckContext(params Type[] types)196         internal void CheckContext(params Type[] types)
197         {
198             m_module.CheckContext(types);
199         }
200 
201         [System.Security.SecurityCritical]  // auto-generated
CreateMethodBodyHelper(ILGenerator il)202         internal void CreateMethodBodyHelper(ILGenerator il)
203         {
204             // Sets the IL of the method.  An ILGenerator is passed as an argument and the method
205             // queries this instance to get all of the information which it needs.
206             if (il == null)
207             {
208                 throw new ArgumentNullException("il");
209             }
210             Contract.EndContractBlock();
211 
212             __ExceptionInfo[]   excp;
213             int                 counter=0;
214             int[]               filterAddrs;
215             int[]               catchAddrs;
216             int[]               catchEndAddrs;
217             Type[]              catchClass;
218             int[]               type;
219             int                 numCatch;
220             int                 start, end;
221             ModuleBuilder       dynMod = (ModuleBuilder) m_module;
222 
223             m_containingType.ThrowIfCreated();
224 
225             if (m_bIsBaked)
226             {
227                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MethodHasBody"));
228             }
229 
230             if (il.m_methodBuilder != this && il.m_methodBuilder != null)
231             {
232                 // you don't need to call DefineBody when you get your ILGenerator
233                 // through MethodBuilder::GetILGenerator.
234                 //
235 
236                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadILGeneratorUsage"));
237             }
238 
239             ThrowIfShouldNotHaveBody();
240 
241             if (il.m_ScopeTree.m_iOpenScopeCount != 0)
242             {
243                 // There are still unclosed local scope
244                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_OpenLocalVariableScope"));
245             }
246 
247 
248             m_ubBody = il.BakeByteArray();
249 
250             m_mdMethodFixups = il.GetTokenFixups();
251 
252             //Okay, now the fun part.  Calculate all of the exceptions.
253             excp = il.GetExceptions();
254             int numExceptions = CalculateNumberOfExceptions(excp);
255             if (numExceptions > 0)
256             {
257                 m_exceptions = new ExceptionHandler[numExceptions];
258 
259                 for (int i = 0; i < excp.Length; i++)
260                 {
261                     filterAddrs = excp[i].GetFilterAddresses();
262                     catchAddrs = excp[i].GetCatchAddresses();
263                     catchEndAddrs = excp[i].GetCatchEndAddresses();
264                     catchClass = excp[i].GetCatchClass();
265 
266                     numCatch = excp[i].GetNumberOfCatches();
267                     start = excp[i].GetStartAddress();
268                     end = excp[i].GetEndAddress();
269                     type = excp[i].GetExceptionTypes();
270                     for (int j = 0; j < numCatch; j++)
271                     {
272                         int tkExceptionClass = 0;
273                         if (catchClass[j] != null)
274                         {
275                             tkExceptionClass = dynMod.GetTypeTokenInternal(catchClass[j]).Token;
276                         }
277 
278                         switch (type[j])
279                         {
280                             case __ExceptionInfo.None:
281                             case __ExceptionInfo.Fault:
282                             case __ExceptionInfo.Filter:
283                                 m_exceptions[counter++] = new ExceptionHandler(start, end, filterAddrs[j], catchAddrs[j], catchEndAddrs[j], type[j], tkExceptionClass);
284                                 break;
285 
286                             case __ExceptionInfo.Finally:
287                                 m_exceptions[counter++] = new ExceptionHandler(start, excp[i].GetFinallyEndAddress(), filterAddrs[j], catchAddrs[j], catchEndAddrs[j], type[j], tkExceptionClass);
288                                 break;
289                         }
290                     }
291 
292                 }
293             }
294 
295 
296             m_bIsBaked=true;
297 
298             if (dynMod.GetSymWriter() != null)
299             {
300 
301                 // set the debugging information such as scope and line number
302                 // if it is in a debug module
303                 //
304                 SymbolToken  tk = new SymbolToken(MetadataTokenInternal);
305                 ISymbolWriter symWriter = dynMod.GetSymWriter();
306 
307                 // call OpenMethod to make this method the current method
308                 symWriter.OpenMethod(tk);
309 
310                 // call OpenScope because OpenMethod no longer implicitly creating
311                 // the top-levelsmethod scope
312                 //
313                 symWriter.OpenScope(0);
314 
315                 if (m_symCustomAttrs != null)
316                 {
317                     foreach(SymCustomAttr symCustomAttr in m_symCustomAttrs)
318                         dynMod.GetSymWriter().SetSymAttribute(
319                         new SymbolToken (MetadataTokenInternal),
320                             symCustomAttr.m_name,
321                             symCustomAttr.m_data);
322                 }
323 
324                 if (m_localSymInfo != null)
325                     m_localSymInfo.EmitLocalSymInfo(symWriter);
326                 il.m_ScopeTree.EmitScopeTree(symWriter);
327                 il.m_LineNumberInfo.EmitLineNumberInfo(symWriter);
328                 symWriter.CloseScope(il.ILOffset);
329                 symWriter.CloseMethod();
330             }
331         }
332 
333         // This is only called from TypeBuilder.CreateType after the method has been created
ReleaseBakedStructures()334         internal void ReleaseBakedStructures()
335         {
336             if (!m_bIsBaked)
337             {
338                 // We don't need to do anything here if we didn't baked the method body
339                 return;
340             }
341 
342             m_ubBody = null;
343             m_localSymInfo = null;
344             m_mdMethodFixups = null;
345             m_localSignature = null;
346             m_exceptions = null;
347         }
348 
GetParameterTypes()349         internal override Type[] GetParameterTypes()
350         {
351             if (m_parameterTypes == null)
352                 m_parameterTypes = EmptyArray<Type>.Value;
353 
354             return m_parameterTypes;
355         }
356 
GetMethodBaseReturnType(MethodBase method)357         internal static Type GetMethodBaseReturnType(MethodBase method)
358         {
359             MethodInfo mi = null;
360             ConstructorInfo ci = null;
361 
362             if ( (mi = method as MethodInfo) != null )
363             {
364                 return mi.ReturnType;
365             }
366             else if ( (ci = method as ConstructorInfo) != null)
367             {
368                 return ci.GetReturnType();
369             }
370             else
371             {
372                 Contract.Assert(false, "We should never get here!");
373                 return null;
374             }
375         }
376 
SetToken(MethodToken token)377         internal void SetToken(MethodToken token)
378         {
379             m_tkMethod = token;
380         }
381 
GetBody()382         internal byte[] GetBody()
383         {
384             // Returns the il bytes of this method.
385             // This il is not valid until somebody has called BakeByteArray
386             return m_ubBody;
387         }
388 
GetTokenFixups()389         internal int[] GetTokenFixups()
390         {
391             return m_mdMethodFixups;
392         }
393 
394         [System.Security.SecurityCritical]  // auto-generated
GetMethodSignature()395         internal SignatureHelper GetMethodSignature()
396         {
397             if (m_parameterTypes == null)
398                 m_parameterTypes = EmptyArray<Type>.Value;
399 
400             m_signature = SignatureHelper.GetMethodSigHelper (m_module, m_callingConvention, m_inst != null ? m_inst.Length : 0,
401                 m_returnType == null ? typeof(void) : m_returnType, m_returnTypeRequiredCustomModifiers, m_returnTypeOptionalCustomModifiers,
402                 m_parameterTypes, m_parameterTypeRequiredCustomModifiers, m_parameterTypeOptionalCustomModifiers);
403 
404             return m_signature;
405         }
406 
407         // Returns a buffer whose initial signatureLength bytes contain encoded local signature.
GetLocalSignature(out int signatureLength)408         internal byte[] GetLocalSignature(out int signatureLength)
409         {
410             if (m_localSignature != null)
411             {
412                 signatureLength = m_localSignature.Length;
413                 return m_localSignature;
414             }
415 
416             if (m_ilGenerator != null)
417             {
418                 if (m_ilGenerator.m_localCount != 0)
419                 {
420                     // If user is using ILGenerator::DeclareLocal, then get local signaturefrom there.
421                     return m_ilGenerator.m_localSignature.InternalGetSignature(out signatureLength);
422                 }
423             }
424 
425             return SignatureHelper.GetLocalVarSigHelper(m_module).InternalGetSignature(out signatureLength);
426         }
427 
GetMaxStack()428         internal int GetMaxStack()
429         {
430             if (m_ilGenerator != null)
431             {
432                 return m_ilGenerator.GetMaxStackSize() + ExceptionHandlerCount;
433             }
434             else
435             {
436                 // this is the case when client provide an array of IL byte stream rather than going through ILGenerator.
437                 return m_maxStack;
438             }
439         }
440 
GetExceptionHandlers()441         internal ExceptionHandler[] GetExceptionHandlers()
442         {
443             return m_exceptions;
444         }
445 
446         internal int ExceptionHandlerCount
447         {
448             get { return m_exceptions != null ? m_exceptions.Length : 0; }
449         }
450 
CalculateNumberOfExceptions(__ExceptionInfo[] excp)451         internal int CalculateNumberOfExceptions(__ExceptionInfo[] excp)
452         {
453             int num=0;
454 
455             if (excp==null)
456             {
457                 return 0;
458             }
459 
460             for (int i=0; i<excp.Length; i++)
461             {
462                 num+=excp[i].GetNumberOfCatches();
463             }
464 
465             return num;
466         }
467 
IsTypeCreated()468         internal bool IsTypeCreated()
469         {
470             return (m_containingType != null && m_containingType.IsCreated());
471         }
472 
GetTypeBuilder()473         internal TypeBuilder GetTypeBuilder()
474         {
475             return m_containingType;
476         }
477 
GetModuleBuilder()478         internal ModuleBuilder GetModuleBuilder()
479         {
480             return m_module;
481         }
482         #endregion
483 
484         #region Object Overrides
485         [System.Security.SecuritySafeCritical]  // auto-generated
Equals(Object obj)486         public override bool Equals(Object obj) {
487             if (!(obj is MethodBuilder)) {
488                 return false;
489             }
490             if (!(this.m_strName.Equals(((MethodBuilder)obj).m_strName))) {
491                 return false;
492             }
493 
494             if (m_iAttributes!=(((MethodBuilder)obj).m_iAttributes)) {
495                 return false;
496             }
497 
498             SignatureHelper thatSig = ((MethodBuilder)obj).GetMethodSignature();
499             if (thatSig.Equals(GetMethodSignature())) {
500                 return true;
501             }
502             return false;
503         }
504 
GetHashCode()505         public override int GetHashCode()
506         {
507             return this.m_strName.GetHashCode();
508         }
509 
510         [System.Security.SecuritySafeCritical]  // auto-generated
ToString()511         public override String ToString()
512         {
513             StringBuilder sb = new StringBuilder(1000);
514             sb.Append("Name: " + m_strName + " " + Environment.NewLine);
515             sb.Append("Attributes: " + (int)m_iAttributes + Environment.NewLine);
516             sb.Append("Method Signature: " + GetMethodSignature() + Environment.NewLine);
517             sb.Append(Environment.NewLine);
518             return sb.ToString();
519         }
520 
521         #endregion
522 
523         #region MemberInfo Overrides
524         public override String Name
525         {
526             get
527             {
528                 return m_strName;
529             }
530         }
531 
532         internal int MetadataTokenInternal
533         {
534             get
535             {
536                 return GetToken().Token;
537             }
538         }
539 
540         public override Module Module
541         {
542             get
543             {
544                 return m_containingType.Module;
545             }
546         }
547 
548         public override Type DeclaringType
549         {
550             get
551             {
552                 if (m_containingType.m_isHiddenGlobalType == true)
553                     return null;
554                 return m_containingType;
555             }
556         }
557 
558         public override ICustomAttributeProvider ReturnTypeCustomAttributes
559         {
560             get
561             {
562                 return null;
563             }
564         }
565 
566         public override Type ReflectedType
567         {
568             get
569             {
570                 return DeclaringType;
571             }
572         }
573 
574         #endregion
575 
576         #region MethodBase Overrides
Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)577         public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
578         {
579             throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
580         }
581 
GetMethodImplementationFlags()582         public override MethodImplAttributes GetMethodImplementationFlags()
583         {
584             return m_dwMethodImplFlags;
585         }
586 
587         public override MethodAttributes Attributes
588         {
589             get { return m_iAttributes; }
590         }
591 
592         public override CallingConventions CallingConvention
593         {
594             get {return m_callingConvention;}
595         }
596 
597         public override RuntimeMethodHandle MethodHandle
598         {
599             get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); }
600         }
601 
602         public override bool IsSecurityCritical
603         {
604             get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); }
605         }
606 
607         public override bool IsSecuritySafeCritical
608         {
609             get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); }
610         }
611 
612         public override bool IsSecurityTransparent
613         {
614             get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); }
615         }
616         #endregion
617 
618         #region MethodInfo Overrides
GetBaseDefinition()619         public override MethodInfo GetBaseDefinition()
620         {
621             return this;
622         }
623 
624         public override Type ReturnType
625         {
626             get
627             {
628                 return m_returnType;
629             }
630         }
631 
632         [Pure]
GetParameters()633         public override ParameterInfo[] GetParameters()
634         {
635             if (!m_bIsBaked || m_containingType == null || m_containingType.BakedRuntimeType == null)
636                 throw new NotSupportedException(Environment.GetResourceString("InvalidOperation_TypeNotCreated"));
637 
638             MethodInfo rmi = m_containingType.GetMethod(m_strName, m_parameterTypes);
639 
640             return rmi.GetParameters();
641         }
642 
643         public override ParameterInfo ReturnParameter
644         {
645             get
646             {
647                 if (!m_bIsBaked || m_containingType == null || m_containingType.BakedRuntimeType == null)
648                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_TypeNotCreated"));
649 
650                 MethodInfo rmi = m_containingType.GetMethod(m_strName, m_parameterTypes);
651 
652                 return rmi.ReturnParameter;
653             }
654         }
655         #endregion
656 
657         #region ICustomAttributeProvider Implementation
GetCustomAttributes(bool inherit)658         public override Object[] GetCustomAttributes(bool inherit)
659         {
660 
661             throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
662         }
663 
GetCustomAttributes(Type attributeType, bool inherit)664         public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
665         {
666 
667             throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
668         }
669 
IsDefined(Type attributeType, bool inherit)670         public override bool IsDefined(Type attributeType, bool inherit)
671         {
672 
673             throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
674         }
675 
676         #endregion
677 
678         #region Generic Members
679         public override bool IsGenericMethodDefinition { get { return m_bIsGenMethDef; } }
680 
681         public override bool ContainsGenericParameters { get { throw new NotSupportedException(); } }
682 
GetGenericMethodDefinition()683         public override MethodInfo GetGenericMethodDefinition() { if (!IsGenericMethod) throw new InvalidOperationException(); return this; }
684 
685         public override bool IsGenericMethod { get { return m_inst != null; } }
686 
GetGenericArguments()687         public override Type[] GetGenericArguments() { return m_inst; }
688 
MakeGenericMethod(params Type[] typeArguments)689         public override MethodInfo MakeGenericMethod(params Type[] typeArguments)
690         {
691             return MethodBuilderInstantiation.MakeGenericMethod(this, typeArguments);
692         }
693 
694 
DefineGenericParameters(params string[] names)695         public GenericTypeParameterBuilder[] DefineGenericParameters (params string[] names)
696         {
697             if (names == null)
698                 throw new ArgumentNullException("names");
699 
700             if (names.Length == 0)
701                 throw new ArgumentException(Environment.GetResourceString("Arg_EmptyArray"), "names");
702             Contract.EndContractBlock();
703 
704             if (m_inst != null)
705                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_GenericParametersAlreadySet"));
706 
707             for (int i = 0; i < names.Length; i ++)
708                 if (names[i] == null)
709                     throw new ArgumentNullException("names");
710 
711             if (m_tkMethod.Token != 0)
712                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MethodBuilderBaked"));
713 
714             m_bIsGenMethDef = true;
715             m_inst = new GenericTypeParameterBuilder[names.Length];
716             for (int i = 0; i < names.Length;  i ++)
717                 m_inst[i] = new GenericTypeParameterBuilder(new TypeBuilder(names[i], i, this));
718 
719             return m_inst;
720         }
721 
ThrowIfGeneric()722         internal void ThrowIfGeneric () { if (IsGenericMethod && !IsGenericMethodDefinition) throw new InvalidOperationException (); }
723         #endregion
724 
725         #region Public Members
726         [System.Security.SecuritySafeCritical]  // auto-generated
GetToken()727         public MethodToken GetToken()
728         {
729             // We used to always "tokenize" a MethodBuilder when it is constructed. After change list 709498
730             // we only "tokenize" a method when requested. But the order in which the methods are tokenized
731             // didn't change: the same order the MethodBuilders are constructed. The recursion introduced
732             // will overflow the stack when there are many methods on the same type (10000 in my experiment).
733             // The change also introduced race conditions. Before the code change GetToken is called from
734             // the MethodBuilder .ctor which is protected by lock(ModuleBuilder.SyncRoot). Now it
735             // could be called more than once on the the same method introducing duplicate (invalid) tokens.
736             // I don't fully understand this change. So I will keep the logic and only fix the recursion and
737             // the race condition.
738 
739             if (m_tkMethod.Token != 0)
740             {
741                 return m_tkMethod;
742             }
743 
744             MethodBuilder currentMethod = null;
745             MethodToken currentToken = new MethodToken(0);
746             int i;
747 
748             // We need to lock here to prevent a method from being "tokenized" twice.
749             // We don't need to synchronize this with Type.DefineMethod because it only appends newly
750             // constructed MethodBuilders to the end of m_listMethods
751             lock (m_containingType.m_listMethods)
752             {
753                 if (m_tkMethod.Token != 0)
754                 {
755                     return m_tkMethod;
756                 }
757 
758                 // If m_tkMethod is still 0 when we obtain the lock, m_lastTokenizedMethod must be smaller
759                 // than the index of the current method.
760                 for (i = m_containingType.m_lastTokenizedMethod + 1; i < m_containingType.m_listMethods.Count; ++i)
761                 {
762                     currentMethod = m_containingType.m_listMethods[i];
763                     currentToken = currentMethod.GetTokenNoLock();
764 
765                     if (currentMethod == this)
766                         break;
767                 }
768 
769                 m_containingType.m_lastTokenizedMethod = i;
770             }
771 
772             Contract.Assert(currentMethod == this, "We should have found this method in m_containingType.m_listMethods");
773             Contract.Assert(currentToken.Token != 0, "The token should not be 0");
774 
775             return currentToken;
776         }
777 
778         [System.Security.SecurityCritical]  // auto-generated
GetTokenNoLock()779         private MethodToken GetTokenNoLock()
780         {
781             Contract.Assert(m_tkMethod.Token == 0, "m_tkMethod should not have been initialized");
782 
783             int sigLength;
784             byte[] sigBytes = GetMethodSignature().InternalGetSignature(out sigLength);
785 
786             int token = TypeBuilder.DefineMethod(m_module.GetNativeHandle(), m_containingType.MetadataTokenInternal, m_strName, sigBytes, sigLength, Attributes);
787             m_tkMethod = new MethodToken(token);
788 
789             if (m_inst != null)
790                 foreach (GenericTypeParameterBuilder tb in m_inst)
791                     if (!tb.m_type.IsCreated()) tb.m_type.CreateType();
792 
793             TypeBuilder.SetMethodImpl(m_module.GetNativeHandle(), token, m_dwMethodImplFlags);
794 
795             return m_tkMethod;
796         }
797 
SetParameters(params Type[] parameterTypes)798         public void SetParameters (params Type[] parameterTypes)
799         {
800             CheckContext(parameterTypes);
801 
802             SetSignature (null, null, null, parameterTypes, null, null);
803         }
804 
SetReturnType(Type returnType)805         public void SetReturnType (Type returnType)
806         {
807             CheckContext(returnType);
808 
809             SetSignature (returnType, null, null, null, null, null);
810         }
811 
SetSignature( Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)812         public void SetSignature(
813             Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
814             Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
815         {
816             // We should throw InvalidOperation_MethodBuilderBaked here if the method signature has been baked.
817             // But we cannot because that would be a breaking change from V2.
818             if (m_tkMethod.Token != 0)
819                 return;
820 
821             CheckContext(returnType);
822             CheckContext(returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes);
823             CheckContext(parameterTypeRequiredCustomModifiers);
824             CheckContext(parameterTypeOptionalCustomModifiers);
825 
826             ThrowIfGeneric();
827 
828             if (returnType != null)
829             {
830                 m_returnType = returnType;
831             }
832 
833             if (parameterTypes != null)
834             {
835                 m_parameterTypes = new Type[parameterTypes.Length];
836                 Array.Copy (parameterTypes, m_parameterTypes, parameterTypes.Length);
837             }
838 
839             m_returnTypeRequiredCustomModifiers = returnTypeRequiredCustomModifiers;
840             m_returnTypeOptionalCustomModifiers = returnTypeOptionalCustomModifiers;
841             m_parameterTypeRequiredCustomModifiers = parameterTypeRequiredCustomModifiers;
842             m_parameterTypeOptionalCustomModifiers = parameterTypeOptionalCustomModifiers;
843         }
844 
845 
846         [System.Security.SecuritySafeCritical]  // auto-generated
DefineParameter(int position, ParameterAttributes attributes, String strParamName)847         public ParameterBuilder DefineParameter(int position, ParameterAttributes attributes, String strParamName)
848         {
849             if (position < 0)
850                 throw new ArgumentOutOfRangeException(Environment.GetResourceString("ArgumentOutOfRange_ParamSequence"));
851             Contract.EndContractBlock();
852 
853             ThrowIfGeneric();
854             m_containingType.ThrowIfCreated ();
855 
856             if (position > 0 && (m_parameterTypes == null || position > m_parameterTypes.Length))
857                 throw new ArgumentOutOfRangeException(Environment.GetResourceString("ArgumentOutOfRange_ParamSequence"));
858 
859             attributes = attributes & ~ParameterAttributes.ReservedMask;
860             return new ParameterBuilder(this, position, attributes, strParamName);
861         }
862 
863         [System.Security.SecuritySafeCritical]  // auto-generated
864         [Obsolete("An alternate API is available: Emit the MarshalAs custom attribute instead. http://go.microsoft.com/fwlink/?linkid=14202")]
SetMarshal(UnmanagedMarshal unmanagedMarshal)865         public void SetMarshal(UnmanagedMarshal unmanagedMarshal)
866         {
867             ThrowIfGeneric ();
868 
869             // set Marshal info for the return type
870 
871             m_containingType.ThrowIfCreated();
872 
873             if (m_retParam == null)
874             {
875                 m_retParam = new ParameterBuilder(this, 0, 0, null);
876             }
877 
878             m_retParam.SetMarshal(unmanagedMarshal);
879         }
880 
881         private List<SymCustomAttr> m_symCustomAttrs;
882         private struct SymCustomAttr
883         {
SymCustomAttrSystem.Reflection.Emit.MethodBuilder.SymCustomAttr884             public SymCustomAttr(String name, byte[] data)
885             {
886                 m_name = name;
887                 m_data = data;
888             }
889             public String m_name;
890             public byte[] m_data;
891         }
892 
SetSymCustomAttribute(String name, byte[] data)893         public void SetSymCustomAttribute(String name, byte[] data)
894         {
895             // Note that this API is rarely used.  Support for custom attributes in PDB files was added in
896             // Whidbey and as of 8/2007 the only known user is the C# compiler.  There seems to be little
897             // value to this for Reflection.Emit users since they can always use metadata custom attributes.
898             // Some versions of the symbol writer used in the CLR will ignore these entirely.  This API has
899             // been removed from the Silverlight API surface area, but we should also consider removing it
900             // from future desktop product versions as well.
901 
902             ThrowIfGeneric ();
903 
904             // This is different from CustomAttribute. This is stored into the SymWriter.
905             m_containingType.ThrowIfCreated();
906 
907             ModuleBuilder dynMod = (ModuleBuilder) m_module;
908             if ( dynMod.GetSymWriter() == null)
909             {
910                 // Cannot SetSymCustomAttribute when it is not a debug module
911                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule"));
912             }
913 
914             if (m_symCustomAttrs == null)
915                 m_symCustomAttrs = new List<SymCustomAttr>();
916 
917             m_symCustomAttrs.Add(new SymCustomAttr(name, data));
918         }
919 
920 #if FEATURE_CAS_POLICY
921         [System.Security.SecuritySafeCritical]  // auto-generated
AddDeclarativeSecurity(SecurityAction action, PermissionSet pset)922         public void AddDeclarativeSecurity(SecurityAction action, PermissionSet pset)
923         {
924             if (pset == null)
925                 throw new ArgumentNullException("pset");
926             Contract.EndContractBlock();
927 
928             ThrowIfGeneric ();
929 
930 #pragma warning disable 618
931             if (!Enum.IsDefined(typeof(SecurityAction), action) ||
932                 action == SecurityAction.RequestMinimum ||
933                 action == SecurityAction.RequestOptional ||
934                 action == SecurityAction.RequestRefuse)
935             {
936                 throw new ArgumentOutOfRangeException("action");
937             }
938 #pragma warning restore 618
939 
940             // cannot declarative security after type is created
941             m_containingType.ThrowIfCreated();
942 
943             // Translate permission set into serialized format (uses standard binary serialization format).
944             byte[] blob = null;
945             int length = 0;
946             if (!pset.IsEmpty())
947             {
948                 blob = pset.EncodeXml();
949                 length = blob.Length;
950             }
951 
952             // Write the blob into the metadata.
953             TypeBuilder.AddDeclarativeSecurity(m_module.GetNativeHandle(), MetadataTokenInternal, action, blob, length);
954         }
955 #endif // FEATURE_CAS_POLICY
956 
957         #if FEATURE_CORECLR
958         [System.Security.SecurityCritical] // auto-generated
959         #endif
SetMethodBody(byte[] il, int maxStack, byte[] localSignature, IEnumerable<ExceptionHandler> exceptionHandlers, IEnumerable<int> tokenFixups)960         public void SetMethodBody(byte[] il, int maxStack, byte[] localSignature, IEnumerable<ExceptionHandler> exceptionHandlers, IEnumerable<int> tokenFixups)
961         {
962             if (il == null)
963             {
964                 throw new ArgumentNullException("il", Environment.GetResourceString("ArgumentNull_Array"));
965             }
966             if (maxStack < 0)
967             {
968                 throw new ArgumentOutOfRangeException("maxStack", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
969             }
970             Contract.EndContractBlock();
971 
972             if (m_bIsBaked)
973             {
974                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MethodBaked"));
975             }
976 
977             m_containingType.ThrowIfCreated();
978             ThrowIfGeneric();
979 
980             byte[] newLocalSignature = null;
981             ExceptionHandler[] newHandlers = null;
982             int[] newTokenFixups = null;
983 
984             byte[] newIL = (byte[])il.Clone();
985 
986             if (localSignature != null)
987             {
988                 newLocalSignature = (byte[])localSignature.Clone();
989             }
990 
991             if (exceptionHandlers != null)
992             {
993                 newHandlers = ToArray(exceptionHandlers);
994                 CheckExceptionHandlerRanges(newHandlers, newIL.Length);
995 
996                 // Note: Fixup entries for type tokens stored in ExceptionHandlers are added by the method body emitter.
997             }
998 
999             if (tokenFixups != null)
1000             {
1001                 newTokenFixups = ToArray(tokenFixups);
1002                 int maxTokenOffset = newIL.Length - 4;
1003 
1004                 for (int i = 0; i < newTokenFixups.Length; i++)
1005                 {
1006                     // Check that fixups are within the range of this method's IL, otherwise some random memory might get "fixed up".
1007                     if (newTokenFixups[i] < 0 || newTokenFixups[i] > maxTokenOffset)
1008                     {
1009                         throw new ArgumentOutOfRangeException("tokenFixups[" + i + "]", Environment.GetResourceString("ArgumentOutOfRange_Range", 0, maxTokenOffset));
1010                     }
1011                 }
1012             }
1013 
1014             m_ubBody = newIL;
1015             m_localSignature = newLocalSignature;
1016             m_exceptions = newHandlers;
1017             m_mdMethodFixups = newTokenFixups;
1018             m_maxStack = maxStack;
1019 
1020             // discard IL generator, all information stored in it is now irrelevant
1021             m_ilGenerator = null;
1022             m_bIsBaked = true;
1023         }
1024 
ToArray(IEnumerable<T> sequence)1025         private static T[] ToArray<T>(IEnumerable<T> sequence)
1026         {
1027             T[] array = sequence as T[];
1028             if (array != null)
1029             {
1030                 return (T[])array.Clone();
1031             }
1032 
1033             return new List<T>(sequence).ToArray();
1034         }
1035 
CheckExceptionHandlerRanges(ExceptionHandler[] exceptionHandlers, int maxOffset)1036         private static void CheckExceptionHandlerRanges(ExceptionHandler[] exceptionHandlers, int maxOffset)
1037         {
1038             // Basic checks that the handler ranges are within the method body (ranges are end-exclusive).
1039             // Doesn't verify that the ranges are otherwise correct - it is very well possible to emit invalid IL.
1040             for (int i = 0; i < exceptionHandlers.Length; i++)
1041             {
1042                 var handler = exceptionHandlers[i];
1043                 if (handler.m_filterOffset > maxOffset || handler.m_tryEndOffset > maxOffset || handler.m_handlerEndOffset > maxOffset)
1044                 {
1045                     throw new ArgumentOutOfRangeException("exceptionHandlers[" + i + "]", Environment.GetResourceString("ArgumentOutOfRange_Range", 0, maxOffset));
1046                 }
1047 
1048                 // Type token might be 0 if the ExceptionHandler was created via a default constructor.
1049                 // Other tokens migth also be invalid. We only check nil tokens as the implementation (SectEH_Emit in corhlpr.cpp) requires it,
1050                 // and we can't check for valid tokens until the module is baked.
1051                 if (handler.Kind == ExceptionHandlingClauseOptions.Clause && handler.ExceptionTypeToken == 0)
1052                 {
1053                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidTypeToken", handler.ExceptionTypeToken), "exceptionHandlers[" + i + "]");
1054                 }
1055             }
1056         }
1057 
1058         /// <summary>
1059         /// Obsolete.
1060         /// </summary>
1061         #if FEATURE_CORECLR
1062         [System.Security.SecurityCritical] // auto-generated
1063         #endif
CreateMethodBody(byte[] il, int count)1064         public void CreateMethodBody(byte[] il, int count)
1065         {
1066             ThrowIfGeneric();
1067 
1068             // Note that when user calls this function, there are a few information that client is
1069             // not able to supply: local signature, exception handlers, max stack size, a list of Token fixup, a list of RVA fixup
1070 
1071             if (m_bIsBaked)
1072             {
1073                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MethodBaked"));
1074             }
1075 
1076             m_containingType.ThrowIfCreated();
1077 
1078             if (il != null && (count < 0 || count > il.Length))
1079             {
1080                 throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Index"));
1081             }
1082 
1083             if (il == null)
1084             {
1085                 m_ubBody = null;
1086                 return;
1087             }
1088 
1089             m_ubBody = new byte[count];
1090             Array.Copy(il,m_ubBody,count);
1091 
1092             m_localSignature = null;
1093             m_exceptions = null;
1094             m_mdMethodFixups = null;
1095             m_maxStack = DefaultMaxStack;
1096 
1097             m_bIsBaked = true;
1098         }
1099 
1100         [System.Security.SecuritySafeCritical]  // auto-generated
SetImplementationFlags(MethodImplAttributes attributes)1101         public void SetImplementationFlags(MethodImplAttributes attributes)
1102         {
1103             ThrowIfGeneric ();
1104 
1105             m_containingType.ThrowIfCreated ();
1106 
1107             m_dwMethodImplFlags = attributes;
1108 
1109             m_canBeRuntimeImpl = true;
1110 
1111             TypeBuilder.SetMethodImpl(m_module.GetNativeHandle(), MetadataTokenInternal, attributes);
1112         }
1113 
GetILGenerator()1114         public ILGenerator GetILGenerator() {
1115             Contract.Ensures(Contract.Result<ILGenerator>() != null);
1116 
1117             ThrowIfGeneric();
1118             ThrowIfShouldNotHaveBody();
1119 
1120             if (m_ilGenerator == null)
1121                 m_ilGenerator = new ILGenerator(this);
1122             return m_ilGenerator;
1123         }
1124 
GetILGenerator(int size)1125         public ILGenerator GetILGenerator(int size) {
1126             Contract.Ensures(Contract.Result<ILGenerator>() != null);
1127 
1128             ThrowIfGeneric ();
1129             ThrowIfShouldNotHaveBody();
1130 
1131             if (m_ilGenerator == null)
1132                 m_ilGenerator = new ILGenerator(this, size);
1133             return m_ilGenerator;
1134         }
1135 
ThrowIfShouldNotHaveBody()1136         private void ThrowIfShouldNotHaveBody() {
1137             if ((m_dwMethodImplFlags & MethodImplAttributes.CodeTypeMask) != MethodImplAttributes.IL ||
1138                 (m_dwMethodImplFlags & MethodImplAttributes.Unmanaged) != 0 ||
1139                 (m_iAttributes & MethodAttributes.PinvokeImpl) != 0 ||
1140                 m_isDllImport)
1141             {
1142                 // cannot attach method body if methodimpl is marked not marked as managed IL
1143                 //
1144                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ShouldNotHaveMethodBody"));
1145             }
1146         }
1147 
1148 
1149         public bool InitLocals
1150         {
1151             // Property is set to true if user wishes to have zero initialized stack frame for this method. Default to false.
1152             get { ThrowIfGeneric (); return m_fInitLocals; }
1153             set { ThrowIfGeneric (); m_fInitLocals = value; }
1154         }
1155 
GetModule()1156         public Module GetModule()
1157         {
1158             return GetModuleBuilder();
1159         }
1160 
1161         public String Signature
1162         {
1163             [System.Security.SecuritySafeCritical]  // auto-generated
1164             get
1165             {
1166                 return GetMethodSignature().ToString();
1167             }
1168         }
1169 
1170 
1171 #if FEATURE_CORECLR
1172 [System.Security.SecurityCritical] // auto-generated
1173 #else
1174 [System.Security.SecuritySafeCritical]
1175 #endif
1176 [System.Runtime.InteropServices.ComVisible(true)]
SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)1177         public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
1178         {
1179             if (con == null)
1180                 throw new ArgumentNullException("con");
1181             if (binaryAttribute == null)
1182                 throw new ArgumentNullException("binaryAttribute");
1183             Contract.EndContractBlock();
1184 
1185             ThrowIfGeneric();
1186 
1187             TypeBuilder.DefineCustomAttribute(m_module, MetadataTokenInternal,
1188                 ((ModuleBuilder)m_module).GetConstructorToken(con).Token,
1189                 binaryAttribute,
1190                 false, false);
1191 
1192             if (IsKnownCA(con))
1193                 ParseCA(con, binaryAttribute);
1194         }
1195 
1196         [System.Security.SecuritySafeCritical]  // auto-generated
SetCustomAttribute(CustomAttributeBuilder customBuilder)1197         public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
1198         {
1199             if (customBuilder == null)
1200                 throw new ArgumentNullException("customBuilder");
1201             Contract.EndContractBlock();
1202 
1203             ThrowIfGeneric();
1204 
1205             customBuilder.CreateCustomAttribute((ModuleBuilder)m_module, MetadataTokenInternal);
1206 
1207             if (IsKnownCA(customBuilder.m_con))
1208                 ParseCA(customBuilder.m_con, customBuilder.m_blob);
1209         }
1210 
1211         // this method should return true for any and every ca that requires more work
1212         // than just setting the ca
IsKnownCA(ConstructorInfo con)1213         private bool IsKnownCA(ConstructorInfo con)
1214         {
1215             Type caType = con.DeclaringType;
1216             if (caType == typeof(System.Runtime.CompilerServices.MethodImplAttribute)) return true;
1217             else if (caType == typeof(DllImportAttribute)) return true;
1218             else return false;
1219         }
1220 
ParseCA(ConstructorInfo con, byte[] blob)1221         private void ParseCA(ConstructorInfo con, byte[] blob)
1222         {
1223             Type caType = con.DeclaringType;
1224             if (caType == typeof(System.Runtime.CompilerServices.MethodImplAttribute))
1225             {
1226                 // dig through the blob looking for the MethodImplAttributes flag
1227                 // that must be in the MethodCodeType field
1228 
1229                 // for now we simply set a flag that relaxes the check when saving and
1230                 // allows this method to have no body when any kind of MethodImplAttribute is present
1231                 m_canBeRuntimeImpl = true;
1232             }
1233             else if (caType == typeof(DllImportAttribute)) {
1234                 m_canBeRuntimeImpl = true;
1235                 m_isDllImport = true;
1236             }
1237 
1238         }
1239 
1240         internal bool m_canBeRuntimeImpl = false;
1241         internal bool m_isDllImport = false;
1242 
1243         #endregion
1244 
1245 #if !FEATURE_CORECLR
_MethodBuilder.GetTypeInfoCount(out uint pcTInfo)1246         void _MethodBuilder.GetTypeInfoCount(out uint pcTInfo)
1247         {
1248             throw new NotImplementedException();
1249         }
1250 
_MethodBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)1251         void _MethodBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
1252         {
1253             throw new NotImplementedException();
1254         }
1255 
_MethodBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)1256         void _MethodBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
1257         {
1258             throw new NotImplementedException();
1259         }
1260 
_MethodBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)1261         void _MethodBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
1262         {
1263             throw new NotImplementedException();
1264         }
1265 #endif
1266 
1267     }
1268 
1269     internal class LocalSymInfo
1270     {
1271         // This class tracks the local variable's debugging information
1272         // and namespace information with a given active lexical scope.
1273 
1274         #region Internal Data Members
1275         internal String[]       m_strName;
1276         internal byte[][]       m_ubSignature;
1277         internal int[]          m_iLocalSlot;
1278         internal int[]          m_iStartOffset;
1279         internal int[]          m_iEndOffset;
1280         internal int            m_iLocalSymCount;         // how many entries in the arrays are occupied
1281         internal String[]       m_namespace;
1282         internal int            m_iNameSpaceCount;
1283         internal const int      InitialSize = 16;
1284         #endregion
1285 
1286         #region Constructor
LocalSymInfo()1287         internal LocalSymInfo()
1288         {
1289             // initialize data variables
1290             m_iLocalSymCount = 0;
1291             m_iNameSpaceCount = 0;
1292         }
1293         #endregion
1294 
1295         #region Private Members
EnsureCapacityNamespace()1296         private void EnsureCapacityNamespace()
1297         {
1298             if (m_iNameSpaceCount == 0)
1299             {
1300                 m_namespace = new String[InitialSize];
1301             }
1302             else if (m_iNameSpaceCount == m_namespace.Length)
1303             {
1304                 String [] strTemp = new String [checked(m_iNameSpaceCount * 2)];
1305                 Array.Copy(m_namespace, strTemp, m_iNameSpaceCount);
1306                 m_namespace = strTemp;
1307             }
1308         }
1309 
EnsureCapacity()1310         private void EnsureCapacity()
1311         {
1312             if (m_iLocalSymCount == 0)
1313             {
1314                 // First time. Allocate the arrays.
1315                 m_strName = new String[InitialSize];
1316                 m_ubSignature = new byte[InitialSize][];
1317                 m_iLocalSlot = new int[InitialSize];
1318                 m_iStartOffset = new int[InitialSize];
1319                 m_iEndOffset = new int[InitialSize];
1320             }
1321             else if (m_iLocalSymCount == m_strName.Length)
1322             {
1323                 // the arrays are full. Enlarge the arrays
1324                 // why aren't we just using lists here?
1325                 int newSize = checked(m_iLocalSymCount * 2);
1326                 int[] temp = new int [newSize];
1327                 Array.Copy(m_iLocalSlot, temp, m_iLocalSymCount);
1328                 m_iLocalSlot = temp;
1329 
1330                 temp = new int [newSize];
1331                 Array.Copy(m_iStartOffset, temp, m_iLocalSymCount);
1332                 m_iStartOffset = temp;
1333 
1334                 temp = new int [newSize];
1335                 Array.Copy(m_iEndOffset, temp, m_iLocalSymCount);
1336                 m_iEndOffset = temp;
1337 
1338                 String [] strTemp = new String [newSize];
1339                 Array.Copy(m_strName, strTemp, m_iLocalSymCount);
1340                 m_strName = strTemp;
1341 
1342                 byte[][] ubTemp = new byte[newSize][];
1343                 Array.Copy(m_ubSignature, ubTemp, m_iLocalSymCount);
1344                 m_ubSignature = ubTemp;
1345 
1346             }
1347         }
1348 
1349         #endregion
1350 
1351         #region Internal Members
AddLocalSymInfo(String strName,byte[] signature,int slot,int startOffset,int endOffset)1352         internal void AddLocalSymInfo(String strName,byte[] signature,int slot,int startOffset,int endOffset)
1353         {
1354             // make sure that arrays are large enough to hold addition info
1355             EnsureCapacity();
1356             m_iStartOffset[m_iLocalSymCount] = startOffset;
1357             m_iEndOffset[m_iLocalSymCount] = endOffset;
1358             m_iLocalSlot[m_iLocalSymCount] = slot;
1359             m_strName[m_iLocalSymCount] = strName;
1360             m_ubSignature[m_iLocalSymCount] = signature;
1361             checked {m_iLocalSymCount++; }
1362         }
1363 
AddUsingNamespace(String strNamespace)1364         internal void AddUsingNamespace(String strNamespace)
1365         {
1366             EnsureCapacityNamespace();
1367             m_namespace[m_iNameSpaceCount] = strNamespace;
1368             checked { m_iNameSpaceCount++; }
1369         }
1370 
1371         #if FEATURE_CORECLR
1372         [System.Security.SecurityCritical] // auto-generated
1373         #endif
EmitLocalSymInfo(ISymbolWriter symWriter)1374         internal virtual void EmitLocalSymInfo(ISymbolWriter symWriter)
1375         {
1376             int         i;
1377 
1378             for (i = 0; i < m_iLocalSymCount; i ++)
1379             {
1380                 symWriter.DefineLocalVariable(
1381                             m_strName[i],
1382                             FieldAttributes.PrivateScope,
1383                             m_ubSignature[i],
1384                             SymAddressKind.ILOffset,
1385                             m_iLocalSlot[i],
1386                             0,          // addr2 is not used yet
1387                             0,          // addr3 is not used
1388                             m_iStartOffset[i],
1389                             m_iEndOffset[i]);
1390             }
1391             for (i = 0; i < m_iNameSpaceCount; i ++)
1392             {
1393                 symWriter.UsingNamespace(m_namespace[i]);
1394             }
1395         }
1396 
1397         #endregion
1398     }
1399 #endif
1400 
1401     /// <summary>
1402     /// Describes exception handler in a method body.
1403     /// </summary>
1404     [StructLayout(LayoutKind.Sequential)]
1405     [ComVisible(false)]
1406     public struct ExceptionHandler : IEquatable<ExceptionHandler>
1407     {
1408         // Keep in sync with unmanged structure.
1409         internal readonly int m_exceptionClass;
1410         internal readonly int m_tryStartOffset;
1411         internal readonly int m_tryEndOffset;
1412         internal readonly int m_filterOffset;
1413         internal readonly int m_handlerStartOffset;
1414         internal readonly int m_handlerEndOffset;
1415         internal readonly ExceptionHandlingClauseOptions m_kind;
1416 
1417         public int ExceptionTypeToken
1418         {
1419             get { return m_exceptionClass; }
1420         }
1421 
1422         public int TryOffset
1423         {
1424             get { return m_tryStartOffset; }
1425         }
1426 
1427         public int TryLength
1428         {
1429             get { return m_tryEndOffset - m_tryStartOffset; }
1430         }
1431 
1432         public int FilterOffset
1433         {
1434             get { return m_filterOffset; }
1435         }
1436 
1437         public int HandlerOffset
1438         {
1439             get { return m_handlerStartOffset; }
1440         }
1441 
1442         public int HandlerLength
1443         {
1444             get { return m_handlerEndOffset - m_handlerStartOffset; }
1445         }
1446 
1447         public ExceptionHandlingClauseOptions Kind
1448         {
1449             get { return m_kind; }
1450         }
1451 
1452         #region Constructors
1453 
1454         /// <summary>
1455         /// Creates a description of an exception handler.
1456         /// </summary>
1457         /// <param name="tryOffset">The offset of the first instruction protected by this handler.</param>
1458         /// <param name="tryLength">The number of bytes protected by this handler.</param>
1459         /// <param name="filterOffset">The filter code begins at the specified offset and ends at the first instruction of the handler block. Specify 0 if not applicable (this is not a filter handler).</param>
1460         /// <param name="handlerOffset">The offset of the first instruction of this handler.</param>
1461         /// <param name="handlerLength">The number of bytes of the handler.</param>
1462         /// <param name="kind">The kind of handler, the handler might be a catch handler, filter handler, fault handler, or finally handler.</param>
1463         /// <param name="exceptionTypeToken">The token of the exception type handled by this handler. Specify 0 if not applicable (this is finally handler).</param>
1464         /// <exception cref="ArgumentOutOfRangeException">
1465         /// Some of the instruction offset is negative,
1466         /// the end offset of specified range is less than its start offset,
1467         /// or <paramref name="kind"/> has an invalid value.
1468         /// </exception>
ExceptionHandlerSystem.Reflection.Emit.ExceptionHandler1469         public ExceptionHandler(int tryOffset, int tryLength, int filterOffset, int handlerOffset, int handlerLength,
1470             ExceptionHandlingClauseOptions kind, int exceptionTypeToken)
1471         {
1472             if (tryOffset < 0)
1473             {
1474                 throw new ArgumentOutOfRangeException("tryOffset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1475             }
1476 
1477             if (tryLength < 0)
1478             {
1479                 throw new ArgumentOutOfRangeException("tryLength", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1480             }
1481 
1482             if (filterOffset < 0)
1483             {
1484                 throw new ArgumentOutOfRangeException("filterOffset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1485             }
1486 
1487             if (handlerOffset < 0)
1488             {
1489                 throw new ArgumentOutOfRangeException("handlerOffset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1490             }
1491 
1492             if (handlerLength < 0)
1493             {
1494                 throw new ArgumentOutOfRangeException("handlerLength", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1495             }
1496 
1497             if ((long)tryOffset + tryLength > Int32.MaxValue)
1498             {
1499                 throw new ArgumentOutOfRangeException("tryLength", Environment.GetResourceString("ArgumentOutOfRange_Range", 0, Int32.MaxValue - tryOffset));
1500             }
1501 
1502             if ((long)handlerOffset + handlerLength > Int32.MaxValue)
1503             {
1504                 throw new ArgumentOutOfRangeException("handlerLength", Environment.GetResourceString("ArgumentOutOfRange_Range", 0, Int32.MaxValue - handlerOffset));
1505             }
1506 
1507             // Other tokens migth also be invalid. We only check nil tokens as the implementation (SectEH_Emit in corhlpr.cpp) requires it,
1508             // and we can't check for valid tokens until the module is baked.
1509             if (kind == ExceptionHandlingClauseOptions.Clause && (exceptionTypeToken & 0x00FFFFFF) == 0)
1510             {
1511                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidTypeToken", exceptionTypeToken), "exceptionTypeToken");
1512             }
1513 
1514             Contract.EndContractBlock();
1515 
1516             if (!IsValidKind(kind))
1517             {
1518                 throw new ArgumentOutOfRangeException("kind", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
1519             }
1520 
1521             m_tryStartOffset = tryOffset;
1522             m_tryEndOffset = tryOffset + tryLength;
1523             m_filterOffset = filterOffset;
1524             m_handlerStartOffset = handlerOffset;
1525             m_handlerEndOffset = handlerOffset + handlerLength;
1526             m_kind = kind;
1527             m_exceptionClass = exceptionTypeToken;
1528         }
1529 
ExceptionHandlerSystem.Reflection.Emit.ExceptionHandler1530         internal ExceptionHandler(int tryStartOffset, int tryEndOffset, int filterOffset, int handlerStartOffset, int handlerEndOffset,
1531             int kind, int exceptionTypeToken)
1532         {
1533             Contract.Assert(tryStartOffset >= 0);
1534             Contract.Assert(tryEndOffset >= 0);
1535             Contract.Assert(filterOffset >= 0);
1536             Contract.Assert(handlerStartOffset >= 0);
1537             Contract.Assert(handlerEndOffset >= 0);
1538             Contract.Assert(IsValidKind((ExceptionHandlingClauseOptions)kind));
1539             Contract.Assert(kind != (int)ExceptionHandlingClauseOptions.Clause || (exceptionTypeToken & 0x00FFFFFF) != 0);
1540 
1541             m_tryStartOffset = tryStartOffset;
1542             m_tryEndOffset = tryEndOffset;
1543             m_filterOffset = filterOffset;
1544             m_handlerStartOffset = handlerStartOffset;
1545             m_handlerEndOffset = handlerEndOffset;
1546             m_kind = (ExceptionHandlingClauseOptions)kind;
1547             m_exceptionClass = exceptionTypeToken;
1548         }
1549 
IsValidKindSystem.Reflection.Emit.ExceptionHandler1550         private static bool IsValidKind(ExceptionHandlingClauseOptions kind)
1551         {
1552             switch (kind)
1553             {
1554                 case ExceptionHandlingClauseOptions.Clause:
1555                 case ExceptionHandlingClauseOptions.Filter:
1556                 case ExceptionHandlingClauseOptions.Finally:
1557                 case ExceptionHandlingClauseOptions.Fault:
1558                     return true;
1559 
1560                 default:
1561                     return false;
1562             }
1563         }
1564 
1565         #endregion
1566 
1567         #region Equality
1568 
GetHashCodeSystem.Reflection.Emit.ExceptionHandler1569         public override int GetHashCode()
1570         {
1571             return m_exceptionClass ^ m_tryStartOffset ^ m_tryEndOffset ^ m_filterOffset ^ m_handlerStartOffset ^ m_handlerEndOffset ^ (int)m_kind;
1572         }
1573 
EqualsSystem.Reflection.Emit.ExceptionHandler1574         public override bool Equals(Object obj)
1575         {
1576             return obj is ExceptionHandler && Equals((ExceptionHandler)obj);
1577         }
1578 
EqualsSystem.Reflection.Emit.ExceptionHandler1579         public bool Equals(ExceptionHandler other)
1580         {
1581             return
1582                 other.m_exceptionClass == m_exceptionClass &&
1583                 other.m_tryStartOffset == m_tryStartOffset &&
1584                 other.m_tryEndOffset == m_tryEndOffset &&
1585                 other.m_filterOffset == m_filterOffset &&
1586                 other.m_handlerStartOffset == m_handlerStartOffset &&
1587                 other.m_handlerEndOffset == m_handlerEndOffset &&
1588                 other.m_kind == m_kind;
1589         }
1590 
operator ==System.Reflection.Emit.ExceptionHandler1591         public static bool operator ==(ExceptionHandler left, ExceptionHandler right)
1592         {
1593             return left.Equals(right);
1594         }
1595 
operator !=System.Reflection.Emit.ExceptionHandler1596         public static bool operator !=(ExceptionHandler left, ExceptionHandler right)
1597         {
1598             return !left.Equals(right);
1599         }
1600 
1601         #endregion
1602     }
1603 }
1604 
1605 
1606 
1607 
1608 
1609 
1610 
1611 
1612 
1613 
1614