private void EmitComplexConditionalReceiverAddress(BoundComplexConditionalReceiver expression) { Debug.Assert(!expression.Type.IsReferenceType); Debug.Assert(!expression.Type.IsValueType); var receiverType = expression.Type; var whenValueTypeLabel = new Object(); var doneLabel = new Object(); EmitInitObj(receiverType, true, expression.Syntax); EmitBox(receiverType, expression.Syntax); _builder.EmitBranch(ILOpCode.Brtrue, whenValueTypeLabel); var receiverTemp = EmitAddress(expression.ReferenceTypeReceiver, AddressKind.ReadOnly); Debug.Assert(receiverTemp == null); _builder.EmitBranch(ILOpCode.Br, doneLabel); _builder.AdjustStack(-1); _builder.MarkLabel(whenValueTypeLabel); // we will not write through this receiver, but it could be a target of mutating calls EmitReceiverRef(expression.ValueTypeReceiver, AddressKind.Constrained); _builder.MarkLabel(doneLabel); }
private void EmitComplexConditionalReceiverAddress(BoundComplexConditionalReceiver expression) { Debug.Assert(!expression.Type.IsReferenceType); Debug.Assert(!expression.Type.IsValueType); var receiverType = expression.Type; var whenValueTypeLabel = new Object(); var doneLabel = new Object(); EmitInitObj(receiverType, true, expression.Syntax); EmitBox(receiverType, expression.Syntax); _builder.EmitBranch(ILOpCode.Brtrue, whenValueTypeLabel); var receiverTemp = EmitAddress(expression.ReferenceTypeReceiver, addressKind: AddressKind.ReadOnly); Debug.Assert(receiverTemp == null); _builder.EmitBranch(ILOpCode.Br, doneLabel); _builder.AdjustStack(-1); _builder.MarkLabel(whenValueTypeLabel); EmitReceiverRef(expression.ValueTypeReceiver, isAccessConstrained: true); _builder.MarkLabel(doneLabel); }
private void EmitComplexConditionalReceiver(BoundComplexConditionalReceiver expression, bool used) { Debug.Assert(!expression.Type.IsReferenceType); Debug.Assert(!expression.Type.IsValueType); var receiverType = expression.Type; var whenValueTypeLabel = new object(); var doneLabel = new object(); EmitInitObj(receiverType, true, expression.Syntax); EmitBox(receiverType, expression.Syntax); _builder.EmitBranch(ILOpCode.Brtrue, whenValueTypeLabel); EmitExpression(expression.ReferenceTypeReceiver, used); _builder.EmitBranch(ILOpCode.Br, doneLabel); _builder.AdjustStack(-1); _builder.MarkLabel(whenValueTypeLabel); EmitExpression(expression.ValueTypeReceiver, used); _builder.MarkLabel(doneLabel); }
public override BoundNode VisitComplexConditionalReceiver(BoundComplexConditionalReceiver node) { EnsureOnlyEvalStack(); var origStack = StackDepth(); PushEvalStack(null, ExprContext.Value); var cookie = GetStackStateCookie(); // implicit goto here SetStackDepth(origStack); // consequence is evaluated with original stack var valueTypeReceiver = (BoundExpression)this.Visit(node.ValueTypeReceiver); EnsureStackState(cookie); // implicit label here SetStackDepth(origStack); // alternative is evaluated with original stack var referenceTypeReceiver = (BoundExpression)this.Visit(node.ReferenceTypeReceiver); EnsureStackState(cookie); // implicit label here return node.Update(valueTypeReceiver, referenceTypeReceiver, node.Type); }
private void EmitComplexConditionalReceiverAddress(BoundComplexConditionalReceiver expression) { Debug.Assert(!expression.Type.IsReferenceType); Debug.Assert(!expression.Type.IsValueType); var receiverType = expression.Type; var whenValueTypeLabel = new Object(); var doneLabel = new Object(); EmitInitObj(receiverType, true, expression.Syntax); EmitBox(receiverType, expression.Syntax); _builder.EmitBranch(ILOpCode.Brtrue, whenValueTypeLabel); var receiverTemp = EmitAddress(expression.ReferenceTypeReceiver, addressKind: AddressKind.ReadOnly); Debug.Assert(receiverTemp == null); _builder.EmitBranch(ILOpCode.Br, doneLabel); _builder.AdjustStack(-1); _builder.MarkLabel(whenValueTypeLabel); EmitReceiverRef(expression.ValueTypeReceiver, isAccessConstrained: true); _builder.MarkLabel(doneLabel); }