/// <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); }
/// <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); }
internal EmitShorthand(Emit inner) { InnerEmit = inner; }
/// <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); }