示例#1
0
        /// <summary>
        /// Calls the method being constructed by the given emit.  Emits so used must have been constructed with BuildMethod or related methods.
        /// 
        /// Pops its arguments in reverse order (left-most deepest in the stack), and pushes the return value if it is non-void.
        /// 
        /// If the given method is an instance method, the `this` reference should appear before any parameters.
        /// 
        /// Call does not respect overrides, the implementation defined by the given MethodInfo is what will be called at runtime.
        /// 
        /// To call overrides of instance methods, use CallVirtual.
        /// Recursive calls can only be performed with DynamicMethods, other passed in Emits must already have their methods created.
        /// When calling VarArgs methods, arglist should be set to the types of the extra parameters to be passed.
        /// </summary>
        public Emit Call(Emit emit, Type[] arglist = null)
        {
            if (emit == null)
            {
                throw new ArgumentNullException("emit");
            }
            
            MethodInfo methodInfo = emit.InnerEmit.MtdBuilder ?? (MethodInfo)emit.InnerEmit.DynMethod;
            if (methodInfo == null)
            {
                var dynMethod = new System.Reflection.Emit.DynamicMethod(emit.Name, emit.ReturnType, emit.ParameterTypes, emit.Module, skipVisibility: true);

                emit.InnerEmit.DynMethod = dynMethod;
                methodInfo = dynMethod;
            }

            return Call(methodInfo, arglist);
        }
示例#2
0
 /// <summary>
 /// Calls the given method virtually.  Pops its arguments in reverse order (left-most deepest in the stack), and pushes the return value if it is non-void.
 ///
 /// The `this` reference should appear before any arguments (deepest in the stack).
 ///
 /// The method invoked at runtime is determined by the type of the `this` reference.
 ///
 /// If the method invoked shouldn't vary (or if the method is static), use Call instead.
 /// </summary>
 public Emit CallVirtual(Emit emit, Type constrained = null, Type[] arglist = null)
 {
     InnerEmit.CallVirtual(emit.InnerEmit, constrained, arglist);
     return(this);
 }
示例#3
0
 internal EmitShorthand(Emit inner)
 {
     InnerEmit = inner;
 }
示例#4
0
        /// <summary>
        /// <para>Creates a new EmitNonGeneric, optionally using the provided name and module for the inner DynamicMethod.</para>
        /// <para>If name is not defined, a sane default is generated.</para>
        /// <para>If module is not defined, a module with the same trust as the executing assembly is used instead.</para>
        /// <para>
        /// If doVerify is false (default is true) Sigil will *not* throw an exception on invalid IL.  This is faster, but the benefits
        /// of Sigil are reduced to "a nicer ILGenerator interface".
        /// </para>
        /// <para>
        /// If strictBranchValidation is true (default is false) Sigil will enforce "Backward branch constraints" which are *technically* required
        /// for valid CIL, but in practice often ignored.  The most common case to set this option is if you are generating types to write to disk.
        /// </para>
        /// </summary>
        public static Emit NewDynamicMethod(Type returnType, Type[] parameterTypes, string name = null, ModuleBuilder module = null, bool doVerify = true, bool strictBranchVerification = false)
        {
            ValidateReturnAndParameterTypes(returnType, parameterTypes);

            module = module ?? Emit <NonGenericPlaceholderDelegate> .Module;

            var innerEmit = Emit <NonGenericPlaceholderDelegate> .MakeNonGenericEmit(CallingConventions.Standard, returnType, parameterTypes, Emit <NonGenericPlaceholderDelegate> .AllowsUnverifiableCode(module), doVerify, strictBranchVerification);

            var ret = new Emit(innerEmit, NonGenericEmitType.DynamicMethod);

            ret.Module         = module;
            ret.Name           = name ?? AutoNamer.Next("_DynamicMethod");
            ret.ReturnType     = returnType;
            ret.ParameterTypes = parameterTypes;

            return(ret);
        }