public virtual void Emit(EmitContext ec) { if (!IsByRef) { if (ArgType == AType.ExtensionTypeConditionalAccess) { var ie = new InstanceEmitter(Expr, false); ie.Emit(ec, true); } else { Expr.Emit(ec); } return; } AddressOp mode = AddressOp.Store; if (ArgType == AType.Ref) { mode |= AddressOp.Load; } IMemoryLocation ml = (IMemoryLocation)Expr; ml.AddressOf(ec, mode); }
public override void Emit(EmitContext ec) { if (method_group.InstanceExpression == null) { ec.EmitNull(); } else { var ie = new InstanceEmitter(method_group.InstanceExpression, false); ie.Emit(ec, method_group.ConditionalAccess); } var delegate_method = method_group.BestCandidate; // Any delegate must be sealed if (!delegate_method.DeclaringType.IsDelegate && delegate_method.IsVirtual && !method_group.IsBase) { ec.Emit(OpCodes.Dup); ec.Emit(OpCodes.Ldvirtftn, delegate_method); } else { ec.Emit(OpCodes.Ldftn, delegate_method); } ec.Emit(OpCodes.Newobj, constructor_method); }
public override void Emit(EmitContext ec) { InstanceEmitter ie; if (method_group.InstanceExpression == null) { ie = new InstanceEmitter(); ec.EmitNull(); } else { ie = new InstanceEmitter(method_group.InstanceExpression, false); ie.NullShortCircuit = method_group.NullShortCircuit; ie.Emit(ec); } var delegate_method = method_group.BestCandidate; // Any delegate must be sealed if (!delegate_method.DeclaringType.IsDelegate && delegate_method.IsVirtual && !method_group.IsBase) { ec.Emit(OpCodes.Dup); ec.Emit(OpCodes.Ldvirtftn, delegate_method); } else { ec.Emit(OpCodes.Ldftn, delegate_method); } ec.Emit(OpCodes.Newobj, constructor_method); if (method_group.NullShortCircuit) { ie.EmitResultLift(ec, type, false); } }
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); }
public override void Emit (EmitContext ec) { if (conditional_access_receiver) ec.ConditionalAccess = new ConditionalAccessContext (type, ec.DefineLabel ()); if (method_group.InstanceExpression == null) { ec.EmitNull (); } else { var ie = new InstanceEmitter (method_group.InstanceExpression, false); ie.Emit (ec, method_group.ConditionalAccess); } var delegate_method = method_group.BestCandidate; // Any delegate must be sealed if (!delegate_method.DeclaringType.IsDelegate && delegate_method.IsVirtual && !method_group.IsBase) { ec.Emit (OpCodes.Dup); ec.Emit (OpCodes.Ldvirtftn, delegate_method); } else { ec.Emit (OpCodes.Ldftn, delegate_method); } ec.Emit (OpCodes.Newobj, constructor_method); if (conditional_access_receiver) ec.CloseConditionalAccess (null); }
public override void Emit (EmitContext ec) { InstanceEmitter ie; if (method_group.InstanceExpression == null) { ie = new InstanceEmitter (); ec.EmitNull (); } else { ie = new InstanceEmitter (method_group.InstanceExpression, false); ie.NullShortCircuit = method_group.NullShortCircuit; ie.Emit (ec); } var delegate_method = method_group.BestCandidate; // Any delegate must be sealed if (!delegate_method.DeclaringType.IsDelegate && delegate_method.IsVirtual && !method_group.IsBase) { ec.Emit (OpCodes.Dup); ec.Emit (OpCodes.Ldvirtftn, delegate_method); } else { ec.Emit (OpCodes.Ldftn, delegate_method); } ec.Emit (OpCodes.Newobj, constructor_method); if (method_group.NullShortCircuit) { ie.EmitResultLift (ec, type, false); } }
public virtual void Emit (EmitContext ec) { if (!IsByRef) { if (ArgType == AType.ExtensionTypeConditionalAccess) { var ie = new InstanceEmitter (Expr, false); ie.Emit (ec, true); } else { Expr.Emit (ec); } return; } AddressOp mode = AddressOp.Store; if (ArgType == AType.Ref) mode |= AddressOp.Load; IMemoryLocation ml = (IMemoryLocation) Expr; ml.AddressOf (ec, mode); }