ICSharpCode.NRefactory.MonoCSharp.Arguments.Emit C# (CSharp) Method

Emit() public method

public Emit ( EmitContext ec, bool dup_args, bool prepareAwait ) : Arguments
ec EmitContext
dup_args bool
prepareAwait bool
return Arguments
		public virtual Arguments Emit (EmitContext ec, bool dup_args, bool prepareAwait)
		{
			List<Argument> dups;

			if ((dup_args && Count != 0) || prepareAwait)
				dups = new List<Argument> (Count);
			else
				dups = null;

			LocalTemporary lt;
			foreach (Argument a in args) {
				if (prepareAwait) {
					dups.Add (a.EmitToField (ec, true));
					continue;
				}
				
				a.Emit (ec);

				if (!dup_args) {
					continue;
				}

				if (a.Expr.IsSideEffectFree) {
					//
					// No need to create a temporary variable for side effect free expressions. I assume
					// all side-effect free expressions are cheap, this has to be tweaked when we become
					// more aggressive on detection
					//
					dups.Add (a);
				} else {
					ec.Emit (OpCodes.Dup);

					// TODO: Release local temporary on next Emit
					// Need to add a flag to argument to indicate this
					lt = new LocalTemporary (a.Type);
					lt.Store (ec);

					dups.Add (new Argument (lt, a.ArgType));
				}
			}

			if (dups != null)
				return new Arguments (dups);

			return null;
		}

Same methods

Arguments::Emit ( EmitContext ec ) : void

Usage Example

Example #1
0
        public void EmitPredefined(EmitContext ec, MethodSpec method, Arguments Arguments, bool statement = false, Location?loc = null)
        {
            Expression instance_copy = null;

            if (!HasAwaitArguments && ec.HasSet(BuilderContext.Options.AsyncBody))
            {
                HasAwaitArguments = Arguments != null && Arguments.ContainsEmitWithAwait();
                if (HasAwaitArguments && InstanceExpressionOnStack)
                {
                    throw new NotSupportedException();
                }
            }

            OpCode         call_op;
            LocalTemporary lt = null;

            if (method.IsStatic)
            {
                call_op = OpCodes.Call;
            }
            else
            {
                call_op = IsVirtualCallRequired(InstanceExpression, method) ? OpCodes.Callvirt : OpCodes.Call;

                if (HasAwaitArguments)
                {
                    instance_copy = InstanceExpression.EmitToField(ec);
                    var ie = new InstanceEmitter(instance_copy, IsAddressCall(instance_copy, call_op, method.DeclaringType));

                    if (Arguments == null)
                    {
                        ie.EmitLoad(ec, true);
                    }
                }
                else if (!InstanceExpressionOnStack)
                {
                    var ie = new InstanceEmitter(InstanceExpression, IsAddressCall(InstanceExpression, call_op, method.DeclaringType));
                    ie.Emit(ec, ConditionalAccess);

                    if (DuplicateArguments)
                    {
                        ec.Emit(OpCodes.Dup);
                        if (Arguments != null && Arguments.Count != 0)
                        {
                            lt = new LocalTemporary(ie.GetStackType(ec));
                            lt.Store(ec);
                            instance_copy = lt;
                        }
                    }
                }
            }

            if (Arguments != null && !InstanceExpressionOnStack)
            {
                EmittedArguments = Arguments.Emit(ec, DuplicateArguments, HasAwaitArguments);
                if (EmittedArguments != null)
                {
                    if (instance_copy != null)
                    {
                        var ie = new InstanceEmitter(instance_copy, IsAddressCall(instance_copy, call_op, method.DeclaringType));
                        ie.Emit(ec, ConditionalAccess);

                        if (lt != null)
                        {
                            lt.Release(ec);
                        }
                    }

                    EmittedArguments.Emit(ec);
                }
            }

            if (call_op == OpCodes.Callvirt && (InstanceExpression.Type.IsGenericParameter || InstanceExpression.Type.IsStructOrEnum))
            {
                ec.Emit(OpCodes.Constrained, InstanceExpression.Type);
            }

            if (loc != null)
            {
                //
                // Emit explicit sequence point for expressions like Foo.Bar () to help debugger to
                // break at right place when LHS expression can be stepped-into
                //
                ec.MarkCallEntry(loc.Value);
            }

            //
            // Set instance expression to actual result expression. When it contains await it can be
            // picked up by caller
            //
            InstanceExpression = instance_copy;

            if (method.Parameters.HasArglist)
            {
                var varargs_types = GetVarargsTypes(method, Arguments);
                ec.Emit(call_op, method, varargs_types);
            }
            else
            {
                //
                // If you have:
                // this.DoFoo ();
                // and DoFoo is not virtual, you can omit the callvirt,
                // because you don't need the null checking behavior.
                //
                ec.Emit(call_op, method);
            }

            //
            // Pop the return value if there is one and stack should be empty
            //
            if (statement && method.ReturnType.Kind != MemberKind.Void)
            {
                ec.Emit(OpCodes.Pop);
            }
        }
All Usage Examples Of ICSharpCode.NRefactory.MonoCSharp.Arguments::Emit