public Emit ( EmitContext ec, bool dup_args, bool prepareAwait ) : Arguments | ||
ec | EmitContext | |
dup_args | bool | |
prepareAwait | bool | |
Résultat | Arguments |
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); } }
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); }