3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // <OWNER>Microsoft</OWNER>
9 namespace System.Reflection.Emit
12 using System.Collections.Generic;
13 using CultureInfo = System.Globalization.CultureInfo;
14 using System.Reflection;
15 using System.Security;
16 using System.Security.Permissions;
17 using System.Threading;
18 using System.Runtime.CompilerServices;
19 using System.Runtime.Versioning;
20 using System.Diagnostics.Contracts;
21 using System.Runtime.InteropServices;
23 [System.Runtime.InteropServices.ComVisible(true)]
24 public sealed class DynamicMethod : MethodInfo
26 private RuntimeType[] m_parameterTypes;
27 internal IRuntimeMethodInfo m_methodHandle;
28 private RuntimeType m_returnType;
29 private DynamicILGenerator m_ilGenerator;
31 [System.Security.SecurityCritical] // auto-generated
33 private DynamicILInfo m_DynamicILInfo;
34 private bool m_fInitLocals;
35 private RuntimeModule m_module;
36 internal bool m_skipVisibility;
37 internal RuntimeType m_typeOwner; // can be null
39 // We want the creator of the DynamicMethod to control who has access to the
40 // DynamicMethod (just like we do for delegates). However, a user can get to
41 // the corresponding RTDynamicMethod using Exception.TargetSite, StackFrame.GetMethod, etc.
42 // If we allowed use of RTDynamicMethod, the creator of the DynamicMethod would
43 // not be able to bound access to the DynamicMethod. Hence, we need to ensure that
44 // we do not allow direct use of RTDynamicMethod.
45 private RTDynamicMethod m_dynMethod;
47 // needed to keep the object alive during jitting
48 // assigned by the DynamicResolver ctor
49 internal DynamicResolver m_resolver;
51 // Always false unless we are in an immersive (non dev mode) process.
53 private bool m_profileAPICheck;
55 private RuntimeAssembly m_creatorAssembly;
58 internal bool m_restrictedSkipVisibility;
59 // The context when the method was created. We use this to do the RestrictedMemberAccess checks.
60 // These checks are done when the method is compiled. This can happen at an arbitrary time,
61 // when CreateDelegate or Invoke is called, or when another DynamicMethod executes OpCodes.Call.
62 // We capture the creation context so that we can do the checks against the same context,
63 // irrespective of when the method gets compiled. Note that the DynamicMethod does not know when
64 // it is ready for use since there is not API which indictates that IL generation has completed.
65 #if FEATURE_COMPRESSEDSTACK
66 internal CompressedStack m_creationContext;
67 #endif // FEATURE_COMPRESSEDSTACK
68 private static volatile InternalModuleBuilder s_anonymouslyHostedDynamicMethodsModule;
69 private static readonly object s_anonymouslyHostedDynamicMethodsModuleLock = new object();
72 // class initialization (ctor and init)
75 private DynamicMethod() { }
77 [System.Security.SecuritySafeCritical] // auto-generated
78 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
79 public DynamicMethod(string name,
81 Type[] parameterTypes)
83 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
86 MethodAttributes.Public | MethodAttributes.Static,
87 CallingConventions.Standard,
92 false, // skipVisibility
94 ref stackMark); // transparentMethod
97 [System.Security.SecuritySafeCritical] // auto-generated
98 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
99 public DynamicMethod(string name,
101 Type[] parameterTypes,
102 bool restrictedSkipVisibility)
104 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
107 MethodAttributes.Public | MethodAttributes.Static,
108 CallingConventions.Standard,
113 restrictedSkipVisibility,
115 ref stackMark); // transparentMethod
119 [System.Security.SecurityCritical] // auto-generated
121 [System.Security.SecuritySafeCritical]
123 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
124 public DynamicMethod(string name,
126 Type[] parameterTypes,
128 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
129 PerformSecurityCheck(m, ref stackMark, false);
131 MethodAttributes.Public | MethodAttributes.Static,
132 CallingConventions.Standard,
137 false, // skipVisibility
139 ref stackMark); // transparentMethod
143 [System.Security.SecurityCritical] // auto-generated
145 [System.Security.SecuritySafeCritical]
147 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
148 public DynamicMethod(string name,
150 Type[] parameterTypes,
152 bool skipVisibility) {
153 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
154 PerformSecurityCheck(m, ref stackMark, skipVisibility);
156 MethodAttributes.Public | MethodAttributes.Static,
157 CallingConventions.Standard,
164 ref stackMark); // transparentMethod
168 [System.Security.SecurityCritical] // auto-generated
170 [System.Security.SecuritySafeCritical]
172 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
173 public DynamicMethod(string name,
174 MethodAttributes attributes,
175 CallingConventions callingConvention,
177 Type[] parameterTypes,
179 bool skipVisibility) {
180 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
181 PerformSecurityCheck(m, ref stackMark, skipVisibility);
191 ref stackMark); // transparentMethod
195 [System.Security.SecurityCritical] // auto-generated
197 [System.Security.SecuritySafeCritical]
199 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
200 public DynamicMethod(string name,
202 Type[] parameterTypes,
204 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
205 PerformSecurityCheck(owner, ref stackMark, false);
207 MethodAttributes.Public | MethodAttributes.Static,
208 CallingConventions.Standard,
213 false, // skipVisibility
215 ref stackMark); // transparentMethod
219 [System.Security.SecurityCritical] // auto-generated
221 [System.Security.SecuritySafeCritical]
223 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
224 public DynamicMethod(string name,
226 Type[] parameterTypes,
228 bool skipVisibility) {
229 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
230 PerformSecurityCheck(owner, ref stackMark, skipVisibility);
232 MethodAttributes.Public | MethodAttributes.Static,
233 CallingConventions.Standard,
240 ref stackMark); // transparentMethod
244 [System.Security.SecurityCritical] // auto-generated
246 [System.Security.SecuritySafeCritical]
248 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
249 public DynamicMethod(string name,
250 MethodAttributes attributes,
251 CallingConventions callingConvention,
253 Type[] parameterTypes,
255 bool skipVisibility) {
256 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
257 PerformSecurityCheck(owner, ref stackMark, skipVisibility);
267 ref stackMark); // transparentMethod
270 // helpers for intialization
272 static private void CheckConsistency(MethodAttributes attributes, CallingConventions callingConvention) {
273 // only static public for method attributes
274 if ((attributes & ~MethodAttributes.MemberAccessMask) != MethodAttributes.Static)
275 throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags"));
276 if ((attributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public)
277 throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags"));
278 Contract.EndContractBlock();
280 // only standard or varargs supported
281 if (callingConvention != CallingConventions.Standard && callingConvention != CallingConventions.VarArgs)
282 throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags"));
284 // vararg is not supported at the moment
285 if (callingConvention == CallingConventions.VarArgs)
286 throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags"));
289 // We create a transparent assembly to host DynamicMethods. Since the assembly does not have any
290 // non-public fields (or any fields at all), it is a safe anonymous assembly to host DynamicMethods
291 [System.Security.SecurityCritical] // auto-generated
292 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
293 private static RuntimeModule GetDynamicMethodsModule()
295 if (s_anonymouslyHostedDynamicMethodsModule != null)
296 return s_anonymouslyHostedDynamicMethodsModule;
298 lock (s_anonymouslyHostedDynamicMethodsModuleLock)
300 if (s_anonymouslyHostedDynamicMethodsModule != null)
301 return s_anonymouslyHostedDynamicMethodsModule;
303 ConstructorInfo transparencyCtor = typeof(SecurityTransparentAttribute).GetConstructor(Type.EmptyTypes);
304 CustomAttributeBuilder transparencyAttribute = new CustomAttributeBuilder(transparencyCtor, EmptyArray<Object>.Value);
305 List<CustomAttributeBuilder> assemblyAttributes = new List<CustomAttributeBuilder>();
306 assemblyAttributes.Add(transparencyAttribute);
308 // On the desktop, we need to use the security rule set level 1 for anonymously hosted
309 // dynamic methods. In level 2, transparency rules are strictly enforced, which leads to
310 // errors when a fully trusted application causes a dynamic method to be generated that tries
311 // to call a method with a LinkDemand or a SecurityCritical method. To retain compatibility
312 // with the v2.0 and v3.x frameworks, these calls should be allowed.
314 // If this rule set was not explicitly called out, then the anonymously hosted dynamic methods
315 // assembly would inherit the rule set from the creating assembly - which would cause it to
316 // be level 2 because mscorlib.dll is using the level 2 rules.
317 ConstructorInfo securityRulesCtor = typeof(SecurityRulesAttribute).GetConstructor(new Type[] { typeof(SecurityRuleSet) });
318 CustomAttributeBuilder securityRulesAttribute =
319 new CustomAttributeBuilder(securityRulesCtor, new object[] { SecurityRuleSet.Level1 });
320 assemblyAttributes.Add(securityRulesAttribute);
321 #endif // !FEATURE_CORECLR
323 AssemblyName assemblyName = new AssemblyName("Anonymously Hosted DynamicMethods Assembly");
324 StackCrawlMark stackMark = StackCrawlMark.LookForMe;
326 AssemblyBuilder assembly = AssemblyBuilder.InternalDefineDynamicAssembly(
328 AssemblyBuilderAccess.Run,
329 null, null, null, null, null,
332 SecurityContextSource.CurrentAssembly);
334 AppDomain.PublishAnonymouslyHostedDynamicMethodsAssembly(assembly.GetNativeHandle());
336 // this always gets the internal module.
337 s_anonymouslyHostedDynamicMethodsModule = (InternalModuleBuilder)assembly.ManifestModule;
340 return s_anonymouslyHostedDynamicMethodsModule;
343 [System.Security.SecurityCritical] // auto-generated
344 private unsafe void Init(String name,
345 MethodAttributes attributes,
346 CallingConventions callingConvention,
352 bool transparentMethod,
353 ref StackCrawlMark stackMark)
355 DynamicMethod.CheckConsistency(attributes, callingConvention);
357 // check and store the signature
358 if (signature != null) {
359 m_parameterTypes = new RuntimeType[signature.Length];
360 for (int i = 0; i < signature.Length; i++) {
361 if (signature[i] == null)
362 throw new ArgumentException(Environment.GetResourceString("Arg_InvalidTypeInSignature"));
363 m_parameterTypes[i] = signature[i].UnderlyingSystemType as RuntimeType;
364 if ( m_parameterTypes[i] == null || !(m_parameterTypes[i] is RuntimeType) || m_parameterTypes[i] == (RuntimeType)typeof(void) )
365 throw new ArgumentException(Environment.GetResourceString("Arg_InvalidTypeInSignature"));
369 m_parameterTypes = new RuntimeType[0];
372 // check and store the return value
373 m_returnType = (returnType == null) ? (RuntimeType)typeof(void) : returnType.UnderlyingSystemType as RuntimeType;
374 if ( (m_returnType == null) || !(m_returnType is RuntimeType) || m_returnType.IsByRef )
375 throw new NotSupportedException(Environment.GetResourceString("Arg_InvalidTypeInRetType"));
377 if (transparentMethod)
379 Contract.Assert(owner == null && m == null, "owner and m cannot be set for transparent methods");
380 m_module = GetDynamicMethodsModule();
383 m_restrictedSkipVisibility = true;
386 #if FEATURE_COMPRESSEDSTACK
387 m_creationContext = CompressedStack.Capture();
388 #endif // FEATURE_COMPRESSEDSTACK
392 Contract.Assert(m != null || owner != null, "PerformSecurityCheck should ensure that either m or owner is set");
393 Contract.Assert(m == null || !m.Equals(s_anonymouslyHostedDynamicMethodsModule), "The user cannot explicitly use this assembly");
394 Contract.Assert(m == null || owner == null, "m and owner cannot both be set");
397 m_module = m.ModuleHandle.GetRuntimeModule(); // this returns the underlying module for all RuntimeModule and ModuleBuilder objects.
400 RuntimeType rtOwner = null;
402 rtOwner = owner.UnderlyingSystemType as RuntimeType;
406 if (rtOwner.HasElementType || rtOwner.ContainsGenericParameters
407 || rtOwner.IsGenericParameter || rtOwner.IsInterface)
408 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidTypeForDynamicMethod"));
410 m_typeOwner = rtOwner;
411 m_module = rtOwner.GetRuntimeModule();
415 m_skipVisibility = skipVisibility;
418 // initialize remaining fields
419 m_ilGenerator = null;
420 m_fInitLocals = true;
421 m_methodHandle = null;
424 throw new ArgumentNullException("name");
427 if (AppDomain.ProfileAPICheck)
429 if (m_creatorAssembly == null)
430 m_creatorAssembly = RuntimeAssembly.GetExecutingAssembly(ref stackMark);
432 if (m_creatorAssembly != null && !m_creatorAssembly.IsFrameworkAssembly())
433 m_profileAPICheck = true;
435 #endif // FEATURE_APPX
437 m_dynMethod = new RTDynamicMethod(this, name, attributes, callingConvention);
440 [System.Security.SecurityCritical] // auto-generated
441 private void PerformSecurityCheck(Module m, ref StackCrawlMark stackMark, bool skipVisibility)
444 throw new ArgumentNullException("m");
445 Contract.EndContractBlock();
447 RuntimeModule rtModule;
448 ModuleBuilder mb = m as ModuleBuilder;
450 rtModule = mb.InternalModule;
452 rtModule = m as RuntimeModule;
454 if (rtModule == null)
456 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeModule"), "m");
459 // The user cannot explicitly use this assembly
460 if (rtModule == s_anonymouslyHostedDynamicMethodsModule)
461 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"), "m");
463 // ask for member access if skip visibility
465 new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand();
468 // ask for control evidence if outside of the caller assembly
469 RuntimeType callingType = RuntimeMethodHandle.GetCallerType(ref stackMark);
470 m_creatorAssembly = callingType.GetRuntimeAssembly();
471 if (m.Assembly != m_creatorAssembly)
473 // Demand the permissions of the assembly where the DynamicMethod will live
474 CodeAccessSecurityEngine.ReflectionTargetDemandHelper(PermissionType.SecurityControlEvidence,
475 m.Assembly.PermissionSet);
477 #else //FEATURE_CORECLR
478 #pragma warning disable 618
479 new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
480 #pragma warning restore 618
481 #endif //FEATURE_CORECLR
484 [System.Security.SecurityCritical] // auto-generated
485 private void PerformSecurityCheck(Type owner, ref StackCrawlMark stackMark, bool skipVisibility)
488 throw new ArgumentNullException("owner");
490 RuntimeType rtOwner = owner as RuntimeType;
492 rtOwner = owner.UnderlyingSystemType as RuntimeType;
495 throw new ArgumentNullException("owner", Environment.GetResourceString("Argument_MustBeRuntimeType"));
497 // get the type the call is coming from
498 RuntimeType callingType = RuntimeMethodHandle.GetCallerType(ref stackMark);
500 // ask for member access if skip visibility
502 new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand();
505 // if the call is not coming from the same class ask for member access
506 if (callingType != rtOwner)
507 new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand();
510 m_creatorAssembly = callingType.GetRuntimeAssembly();
512 // ask for control evidence if outside of the caller module
513 if (rtOwner.Assembly != m_creatorAssembly)
515 // Demand the permissions of the assembly where the DynamicMethod will live
516 CodeAccessSecurityEngine.ReflectionTargetDemandHelper(PermissionType.SecurityControlEvidence,
517 owner.Assembly.PermissionSet);
519 #else //FEATURE_CORECLR
520 #pragma warning disable 618
521 new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
522 #pragma warning restore 618
523 #endif //FEATURE_CORECLR
527 // Delegate and method creation
530 [System.Security.SecuritySafeCritical] // auto-generated
531 [System.Runtime.InteropServices.ComVisible(true)]
532 public sealed override Delegate CreateDelegate(Type delegateType) {
533 if (m_restrictedSkipVisibility)
535 // Compile the method since accessibility checks are done as part of compilation.
536 GetMethodDescriptor();
537 System.Runtime.CompilerServices.RuntimeHelpers._CompileMethod(m_methodHandle);
540 MulticastDelegate d = (MulticastDelegate)Delegate.CreateDelegateNoSecurityCheck(delegateType, null, GetMethodDescriptor());
541 // stash this MethodInfo by brute force.
542 d.StoreDynamicMethod(GetMethodInfo());
546 [System.Security.SecuritySafeCritical] // auto-generated
547 [System.Runtime.InteropServices.ComVisible(true)]
548 public sealed override Delegate CreateDelegate(Type delegateType, Object target) {
549 if (m_restrictedSkipVisibility)
551 // Compile the method since accessibility checks are done as part of compilation
552 GetMethodDescriptor();
553 System.Runtime.CompilerServices.RuntimeHelpers._CompileMethod(m_methodHandle);
556 MulticastDelegate d = (MulticastDelegate)Delegate.CreateDelegateNoSecurityCheck(delegateType, target, GetMethodDescriptor());
557 // stash this MethodInfo by brute force.
558 d.StoreDynamicMethod(GetMethodInfo());
563 internal bool ProfileAPICheck
567 return m_profileAPICheck;
570 [FriendAccessAllowed]
573 m_profileAPICheck = value;
578 // This is guaranteed to return a valid handle
579 [System.Security.SecurityCritical] // auto-generated
580 internal unsafe RuntimeMethodHandle GetMethodDescriptor() {
581 if (m_methodHandle == null) {
583 if (m_methodHandle == null) {
584 if (m_DynamicILInfo != null)
585 m_DynamicILInfo.GetCallableMethod(m_module, this);
587 if (m_ilGenerator == null || m_ilGenerator.ILOffset == 0)
588 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadEmptyMethodBody", Name));
590 m_ilGenerator.GetCallableMethod(m_module, this);
595 return new RuntimeMethodHandle(m_methodHandle);
599 // MethodInfo api. They mostly forward to RTDynamicMethod
602 public override String ToString() { return m_dynMethod.ToString(); }
604 public override String Name { get { return m_dynMethod.Name; } }
606 public override Type DeclaringType { get { return m_dynMethod.DeclaringType; } }
608 public override Type ReflectedType { get { return m_dynMethod.ReflectedType; } }
610 public override Module Module { get { return m_dynMethod.Module; } }
612 // we cannot return a MethodHandle because we cannot track it via GC so this method is off limits
613 public override RuntimeMethodHandle MethodHandle { get { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod")); } }
615 public override MethodAttributes Attributes { get { return m_dynMethod.Attributes; } }
617 public override CallingConventions CallingConvention { get { return m_dynMethod.CallingConvention; } }
619 public override MethodInfo GetBaseDefinition() { return this; }
622 public override ParameterInfo[] GetParameters() { return m_dynMethod.GetParameters(); }
624 public override MethodImplAttributes GetMethodImplementationFlags() { return m_dynMethod.GetMethodImplementationFlags(); }
627 // Security transparency accessors
629 // Since the dynamic method may not be JITed yet, we don't always have the runtime method handle
630 // which is needed to determine the official runtime transparency status of the dynamic method. We
631 // fall back to saying that the dynamic method matches the transparency of its containing module
632 // until we get a JITed version, since dynamic methods cannot have attributes of their own.
635 public override bool IsSecurityCritical
637 [SecuritySafeCritical]
640 if (m_methodHandle != null)
642 return RuntimeMethodHandle.IsSecurityCritical(m_methodHandle);
644 else if (m_typeOwner != null)
646 RuntimeAssembly assembly = m_typeOwner.Assembly as RuntimeAssembly;
647 Contract.Assert(assembly != null);
649 return assembly.IsAllSecurityCritical();
653 RuntimeAssembly assembly = m_module.Assembly as RuntimeAssembly;
654 Contract.Assert(assembly != null);
656 return assembly.IsAllSecurityCritical();
661 public override bool IsSecuritySafeCritical
663 [SecuritySafeCritical]
666 if (m_methodHandle != null)
668 return RuntimeMethodHandle.IsSecuritySafeCritical(m_methodHandle);
670 else if (m_typeOwner != null)
672 RuntimeAssembly assembly = m_typeOwner.Assembly as RuntimeAssembly;
673 Contract.Assert(assembly != null);
675 return assembly.IsAllPublicAreaSecuritySafeCritical();
679 RuntimeAssembly assembly = m_module.Assembly as RuntimeAssembly;
680 Contract.Assert(assembly != null);
682 return assembly.IsAllSecuritySafeCritical();
687 public override bool IsSecurityTransparent
689 [SecuritySafeCritical]
692 if (m_methodHandle != null)
694 return RuntimeMethodHandle.IsSecurityTransparent(m_methodHandle);
696 else if (m_typeOwner != null)
698 RuntimeAssembly assembly = m_typeOwner.Assembly as RuntimeAssembly;
699 Contract.Assert(assembly != null);
701 return !assembly.IsAllSecurityCritical();
705 RuntimeAssembly assembly = m_module.Assembly as RuntimeAssembly;
706 Contract.Assert(assembly != null);
708 return !assembly.IsAllSecurityCritical();
713 [System.Security.SecuritySafeCritical] // auto-generated
714 public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) {
715 if ((CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs)
716 throw new NotSupportedException(Environment.GetResourceString("NotSupported_CallToVarArg"));
717 Contract.EndContractBlock();
720 // We do not demand any permission here because the caller already has access
721 // to the current DynamicMethod object, and it could just as easily emit another
722 // Transparent DynamicMethod to call the current DynamicMethod.
725 RuntimeMethodHandle method = GetMethodDescriptor();
726 // ignore obj since it's a static method
728 // create a signature object
729 Signature sig = new Signature(
730 this.m_methodHandle, m_parameterTypes, m_returnType, CallingConvention);
734 int formalCount = sig.Arguments.Length;
735 int actualCount = (parameters != null) ? parameters.Length : 0;
736 if (formalCount != actualCount)
737 throw new TargetParameterCountException(Environment.GetResourceString("Arg_ParmCnt"));
739 // if we are here we passed all the previous checks. Time to look at the arguments
740 Object retValue = null;
743 Object[] arguments = CheckArguments(parameters, binder, invokeAttr, culture, sig);
744 retValue = RuntimeMethodHandle.InvokeMethod(null, arguments, sig, false);
745 // copy out. This should be made only if ByRef are present.
746 for (int index = 0; index < arguments.Length; index++)
747 parameters[index] = arguments[index];
751 retValue = RuntimeMethodHandle.InvokeMethod(null, null, sig, false);
758 public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
760 return m_dynMethod.GetCustomAttributes(attributeType, inherit);
763 public override Object[] GetCustomAttributes(bool inherit) { return m_dynMethod.GetCustomAttributes(inherit); }
765 public override bool IsDefined(Type attributeType, bool inherit) { return m_dynMethod.IsDefined(attributeType, inherit); }
767 public override Type ReturnType { get { return m_dynMethod.ReturnType; } }
769 public override ParameterInfo ReturnParameter { get { return m_dynMethod.ReturnParameter; } }
771 public override ICustomAttributeProvider ReturnTypeCustomAttributes { get { return m_dynMethod.ReturnTypeCustomAttributes; } }
774 // DynamicMethod specific methods
777 public ParameterBuilder DefineParameter(int position, ParameterAttributes attributes, String parameterName) {
778 if (position < 0 || position > m_parameterTypes.Length)
779 throw new ArgumentOutOfRangeException(Environment.GetResourceString("ArgumentOutOfRange_ParamSequence"));
780 position--; // it's 1 based. 0 is the return value
783 ParameterInfo[] parameters = m_dynMethod.LoadParameters();
784 parameters[position].SetName(parameterName);
785 parameters[position].SetAttributes(attributes);
790 [System.Security.SecuritySafeCritical] // auto-generated
791 public DynamicILInfo GetDynamicILInfo()
793 #pragma warning disable 618
794 new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
795 #pragma warning restore 618
797 if (m_DynamicILInfo != null)
798 return m_DynamicILInfo;
800 return GetDynamicILInfo(new DynamicScope());
803 [System.Security.SecurityCritical] // auto-generated
804 internal DynamicILInfo GetDynamicILInfo(DynamicScope scope)
806 if (m_DynamicILInfo == null)
808 byte[] methodSignature = SignatureHelper.GetMethodSigHelper(
809 null, CallingConvention, ReturnType, null, null, m_parameterTypes, null, null).GetSignature(true);
810 m_DynamicILInfo = new DynamicILInfo(scope, this, methodSignature);
813 return m_DynamicILInfo;
816 public ILGenerator GetILGenerator() {
817 return GetILGenerator(64);
820 [System.Security.SecuritySafeCritical] // auto-generated
821 public ILGenerator GetILGenerator(int streamSize)
823 if (m_ilGenerator == null)
825 byte[] methodSignature = SignatureHelper.GetMethodSigHelper(
826 null, CallingConvention, ReturnType, null, null, m_parameterTypes, null, null).GetSignature(true);
827 m_ilGenerator = new DynamicILGenerator(this, methodSignature, streamSize);
829 return m_ilGenerator;
832 public bool InitLocals {
833 get {return m_fInitLocals;}
834 set {m_fInitLocals = value;}
841 internal MethodInfo GetMethodInfo() {
845 //////////////////////////////////////////////////////////////////////////////////////////////
848 // this is actually the real runtime instance of a method info that gets used for invocation
849 // We need this so we never leak the DynamicMethod out via an exception.
850 // This way the DynamicMethod creator is the only one responsible for DynamicMethod access,
851 // and can control exactly who gets access to it.
853 internal class RTDynamicMethod : MethodInfo {
855 internal DynamicMethod m_owner;
856 ParameterInfo[] m_parameters;
858 MethodAttributes m_attributes;
859 CallingConventions m_callingConvention;
864 private RTDynamicMethod() {}
866 internal RTDynamicMethod(DynamicMethod owner, String name, MethodAttributes attributes, CallingConventions callingConvention) {
869 m_attributes = attributes;
870 m_callingConvention = callingConvention;
876 public override String ToString() {
877 return ReturnType.FormatTypeName() + " " + FormatNameAndSig();
880 public override String Name {
881 get { return m_name; }
884 public override Type DeclaringType {
888 public override Type ReflectedType {
892 public override Module Module {
893 get { return m_owner.m_module; }
896 public override RuntimeMethodHandle MethodHandle {
897 get { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod")); }
900 public override MethodAttributes Attributes {
901 get { return m_attributes; }
904 public override CallingConventions CallingConvention {
905 get { return m_callingConvention; }
908 public override MethodInfo GetBaseDefinition() {
913 public override ParameterInfo[] GetParameters() {
914 ParameterInfo[] privateParameters = LoadParameters();
915 ParameterInfo[] parameters = new ParameterInfo[privateParameters.Length];
916 Array.Copy(privateParameters, parameters, privateParameters.Length);
920 public override MethodImplAttributes GetMethodImplementationFlags() {
921 return MethodImplAttributes.IL | MethodImplAttributes.NoInlining;
924 public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) {
925 // We want the creator of the DynamicMethod to control who has access to the
926 // DynamicMethod (just like we do for delegates). However, a user can get to
927 // the corresponding RTDynamicMethod using Exception.TargetSite, StackFrame.GetMethod, etc.
928 // If we allowed use of RTDynamicMethod, the creator of the DynamicMethod would
929 // not be able to bound access to the DynamicMethod. Hence, we do not allow
930 // direct use of RTDynamicMethod.
931 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "this");
934 public override Object[] GetCustomAttributes(Type attributeType, bool inherit) {
935 if (attributeType == null)
936 throw new ArgumentNullException("attributeType");
937 Contract.EndContractBlock();
939 if (attributeType.IsAssignableFrom(typeof(MethodImplAttribute)))
940 return new Object[] { new MethodImplAttribute(GetMethodImplementationFlags()) };
942 return EmptyArray<Object>.Value;
945 public override Object[] GetCustomAttributes(bool inherit) {
946 // support for MethodImplAttribute PCA
947 return new Object[] { new MethodImplAttribute(GetMethodImplementationFlags()) };
950 public override bool IsDefined(Type attributeType, bool inherit) {
951 if (attributeType == null)
952 throw new ArgumentNullException("attributeType");
953 Contract.EndContractBlock();
955 if (attributeType.IsAssignableFrom(typeof(MethodImplAttribute)))
961 public override bool IsSecurityCritical
963 get { return m_owner.IsSecurityCritical; }
966 public override bool IsSecuritySafeCritical
968 get { return m_owner.IsSecuritySafeCritical; }
971 public override bool IsSecurityTransparent
973 get { return m_owner.IsSecurityTransparent; }
976 public override Type ReturnType
980 return m_owner.m_returnType;
984 public override ParameterInfo ReturnParameter {
988 public override ICustomAttributeProvider ReturnTypeCustomAttributes {
989 get { return GetEmptyCAHolder(); }
993 // private implementation
996 internal ParameterInfo[] LoadParameters() {
997 if (m_parameters == null) {
998 Type[] parameterTypes = m_owner.m_parameterTypes;
999 ParameterInfo[] parameters = new ParameterInfo[parameterTypes.Length];
1000 for (int i = 0; i < parameterTypes.Length; i++)
1001 parameters[i] = new RuntimeParameterInfo(this, null, parameterTypes[i], i);
1002 if (m_parameters == null)
1003 // should we interlockexchange?
1004 m_parameters = parameters;
1006 return m_parameters;
1009 // private implementation of CA for the return type
1010 private ICustomAttributeProvider GetEmptyCAHolder() {
1011 return new EmptyCAHolder();
1014 ///////////////////////////////////////////////////
1016 private class EmptyCAHolder : ICustomAttributeProvider {
1017 internal EmptyCAHolder() {}
1019 Object[] ICustomAttributeProvider.GetCustomAttributes(Type attributeType, bool inherit) {
1020 return EmptyArray<Object>.Value;
1023 Object[] ICustomAttributeProvider.GetCustomAttributes(bool inherit) {
1024 return EmptyArray<Object>.Value;
1027 bool ICustomAttributeProvider.IsDefined (Type attributeType, bool inherit) {