本文整理汇总了C#中BoundAssignmentOperator.Update方法的典型用法代码示例。如果您正苦于以下问题:C# BoundAssignmentOperator.Update方法的具体用法?C# BoundAssignmentOperator.Update怎么用?C# BoundAssignmentOperator.Update使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类BoundAssignmentOperator
的用法示例。
在下文中一共展示了BoundAssignmentOperator.Update方法的5个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: EmitStore
private void EmitStore(BoundAssignmentOperator assignment)
{
BoundExpression expression = assignment.Left;
switch (expression.Kind)
{
case BoundKind.FieldAccess:
EmitFieldStore((BoundFieldAccess)expression);
break;
case BoundKind.Local:
// If we are doing a 'normal' local assignment like 'int t = 10;', or
// if we are initializing a temporary like 'ref int t = ref M().s;' then
// we just emit a local store. If we are doing an assignment through
// a ref local temporary then we assume that the instruction to load
// the address is already on the stack, and we must indirect through it.
// See the comments in EmitAssignmentExpression above for details.
BoundLocal local = (BoundLocal)expression;
if (local.LocalSymbol.RefKind != RefKind.None && assignment.RefKind == RefKind.None)
{
EmitIndirectStore(local.LocalSymbol.Type, local.Syntax);
}
else
{
if (IsStackLocal(local.LocalSymbol))
{
// assign to stack var == leave original value on stack
break;
}
else
{
_builder.EmitLocalStore(GetLocal(local));
}
}
break;
case BoundKind.ArrayAccess:
var array = ((BoundArrayAccess)expression).Expression;
var arrayType = (ArrayTypeSymbol)array.Type;
EmitArrayElementStore(arrayType, expression.Syntax);
break;
case BoundKind.ThisReference:
EmitThisStore((BoundThisReference)expression);
break;
case BoundKind.Parameter:
EmitParameterStore((BoundParameter)expression);
break;
case BoundKind.Dup:
Debug.Assert(((BoundDup)expression).RefKind != RefKind.None);
EmitIndirectStore(expression.Type, expression.Syntax);
break;
case BoundKind.RefValueOperator:
case BoundKind.PointerIndirectionOperator:
case BoundKind.PseudoVariable:
EmitIndirectStore(expression.Type, expression.Syntax);
break;
case BoundKind.Sequence:
{
var sequence = (BoundSequence)expression;
EmitStore(assignment.Update(sequence.Value, assignment.Right, assignment.RefKind, assignment.Type));
var notReleased = DigForValueLocal(sequence);
if (notReleased != null)
{
FreeLocal(notReleased);
}
}
break;
case BoundKind.Call:
Debug.Assert(((BoundCall)expression).Method.RefKind != RefKind.None);
EmitIndirectStore(expression.Type, expression.Syntax);
break;
case BoundKind.ModuleVersionId:
EmitModuleVersionIdStore((BoundModuleVersionId)expression);
break;
case BoundKind.InstrumentationPayloadRoot:
EmitInstrumentationPayloadRootStore((BoundInstrumentationPayloadRoot)expression);
break;
case BoundKind.PreviousSubmissionReference:
// Script references are lowered to a this reference and a field access.
default:
throw ExceptionUtilities.UnexpectedValue(expression.Kind);
}
}
示例2: EmitAssignmentPreamble
//.........这里部分代码省略.........
// For now analyzer asserts that indirect writes are final reads of
// a ref local. And we never need a dup here.
// builder.EmitOpCode(ILOpCode.Dup);
}
lhsUsesStack = true;
}
}
break;
case BoundKind.ArrayAccess:
{
var left = (BoundArrayAccess)assignmentTarget;
EmitExpression(left.Expression, used: true);
EmitArrayIndices(left.Indices);
lhsUsesStack = true;
}
break;
case BoundKind.ThisReference:
{
var left = (BoundThisReference)assignmentTarget;
var temp = EmitAddress(left, AddressKind.Writeable);
Debug.Assert(temp == null, "taking ref of this should not create a temp");
lhsUsesStack = true;
}
break;
case BoundKind.Dup:
{
var left = (BoundDup)assignmentTarget;
var temp = EmitAddress(left, AddressKind.Writeable);
Debug.Assert(temp == null, "taking ref of Dup should not create a temp");
lhsUsesStack = true;
}
break;
case BoundKind.PointerIndirectionOperator:
{
var left = (BoundPointerIndirectionOperator)assignmentTarget;
EmitExpression(left.Operand, used: true);
lhsUsesStack = true;
}
break;
case BoundKind.Sequence:
{
var sequence = (BoundSequence)assignmentTarget;
DefineLocals(sequence);
EmitSideEffects(sequence);
lhsUsesStack = EmitAssignmentPreamble(assignmentOperator.Update(sequence.Value, assignmentOperator.Right, assignmentOperator.RefKind, assignmentOperator.Type));
// doNotRelease will be released in EmitStore after we are done with the whole assignment.
var doNotRelease = DigForValueLocal(sequence);
FreeLocals(sequence, doNotRelease);
}
break;
case BoundKind.Call:
{
var left = (BoundCall)assignmentTarget;
Debug.Assert(left.Method.RefKind != RefKind.None);
EmitCallExpression(left, UseKind.UsedAsAddress);
lhsUsesStack = true;
}
break;
case BoundKind.PropertyAccess:
case BoundKind.IndexerAccess:
// Property access should have been rewritten.
case BoundKind.PreviousSubmissionReference:
// Script references are lowered to a this reference and a field access.
throw ExceptionUtilities.UnexpectedValue(assignmentTarget.Kind);
case BoundKind.PseudoVariable:
EmitPseudoVariableAddress((BoundPseudoVariable)assignmentTarget);
lhsUsesStack = true;
break;
case BoundKind.ModuleVersionId:
case BoundKind.InstrumentationPayloadRoot:
break;
default:
throw ExceptionUtilities.UnexpectedValue(assignmentTarget.Kind);
}
return lhsUsesStack;
}
示例3: VisitAssignmentOperator
public override BoundNode VisitAssignmentOperator(BoundAssignmentOperator node)
{
var sequence = node.Left as BoundSequence;
if (sequence != null)
{
// assigning to a sequence is uncommon, but could happen in a
// case if LHS was a declaration expression.
//
// Just rewrite {se1, se2, se3, val} = something
// into ==> {se1, se2, se3, val = something}
BoundExpression rewritten = sequence.Update(sequence.Locals,
sequence.SideEffects,
node.Update(sequence.Value, node.Right, node.RefKind, node.Type),
sequence.Type);
rewritten = (BoundExpression)Visit(rewritten);
// do not count the assignment twice
_counter--;
return rewritten;
}
var isIndirectAssignment = IsIndirectAssignment(node);
var left = VisitExpression(node.Left, isIndirectAssignment ?
ExprContext.Address :
ExprContext.AssignmentTarget);
// must delay recording a write until after RHS is evaluated
var assignmentLocal = _assignmentLocal;
_assignmentLocal = null;
Debug.Assert(_context != ExprContext.AssignmentTarget, "assignment expression cannot be a target of another assignment");
ExprContext rhsContext;
if (node.RefKind != RefKind.None ||
_context == ExprContext.Address)
{
// we need the address of rhs one way or another so we cannot have it on the stack.
rhsContext = ExprContext.Address;
}
else
{
Debug.Assert(_context == ExprContext.Value ||
_context == ExprContext.Box ||
_context == ExprContext.Sideeffects, "assignment expression cannot be a target of another assignment");
// we only need a value of rhs, so if otherwise possible it can be a stack value.
rhsContext = ExprContext.Value;
}
// if right is a struct ctor, it may be optimized into in-place call
// Such call will push the receiver ref before the arguments
// so we need to ensure that arguments cannot use stack temps
BoundExpression right = node.Right;
object rhsCookie = null;
if (right.Kind == BoundKind.ObjectCreationExpression &&
right.Type.IsVerifierValue() &&
((BoundObjectCreationExpression)right).Constructor.ParameterCount != 0)
{
rhsCookie = this.GetStackStateCookie();
}
right = VisitExpression(node.Right, rhsContext);
// if assigning to a local, now it is the time to record the Write
if (assignmentLocal != null)
{
// This assert will fire if code relies on implicit CLR coercions
// - i.e assigns int value to a short local.
// in that case we should force lhs to be a real local.
Debug.Assert(
node.Left.Type.Equals(node.Right.Type, ignoreCustomModifiersAndArraySizesAndLowerBounds: true, ignoreDynamic: true),
@"type of the assignment value is not the same as the type of assignment target.
This is not expected by the optimizer and is typically a result of a bug somewhere else.");
Debug.Assert(!isIndirectAssignment, "indirect assignment is a read, not a write");
LocalSymbol localSymbol = assignmentLocal.LocalSymbol;
// Special Case: If the RHS is a pointer conversion, then the assignment functions as
// a conversion (because the RHS will actually be typed as a native u/int in IL), so
// we should not optimize away the local (i.e. schedule it on the stack).
if (CanScheduleToStack(localSymbol) &&
assignmentLocal.Type.IsPointerType() && right.Kind == BoundKind.Conversion &&
((BoundConversion)right).ConversionKind.IsPointerConversion())
{
ShouldNotSchedule(localSymbol);
}
RecordVarWrite(localSymbol);
assignmentLocal = null;
}
if (rhsCookie != null)
{
// we currently have the rhs on stack, adjust for that.
PopEvalStack();
this.EnsureStackState(rhsCookie);
//.........这里部分代码省略.........
示例4: VisitAssignmentOperator
public override BoundNode VisitAssignmentOperator(BoundAssignmentOperator node)
{
BoundExpression originalLeft = node.Left;
if (originalLeft.Kind != BoundKind.Local)
{
return base.VisitAssignmentOperator(node);
}
var leftLocal = (BoundLocal)originalLeft;
BoundExpression originalRight = node.Right;
if (leftLocal.LocalSymbol.RefKind != RefKind.None &&
node.RefKind != RefKind.None &&
NeedsProxy(leftLocal.LocalSymbol))
{
Debug.Assert(!proxies.ContainsKey(leftLocal.LocalSymbol));
Debug.Assert(!IsStackAlloc(originalRight));
//spilling ref local variables
throw ExceptionUtilities.Unreachable;
}
if (NeedsProxy(leftLocal.LocalSymbol) && !proxies.ContainsKey(leftLocal.LocalSymbol))
{
Debug.Assert(leftLocal.LocalSymbol.DeclarationKind == LocalDeclarationKind.None);
// spilling temp variables
throw ExceptionUtilities.Unreachable;
}
BoundExpression rewrittenLeft = (BoundExpression)this.Visit(leftLocal);
BoundExpression rewrittenRight = (BoundExpression)this.Visit(originalRight);
TypeSymbol rewrittenType = VisitType(node.Type);
// Check if we're assigning the result of stackalloc to a hoisted local.
// If we are, we need to store the result in a temp local and then assign
// the value of the local to the field corresponding to the hoisted local.
// If the receiver of the field is on the stack when the stackalloc happens,
// popping it will free the memory (?) or otherwise cause verification issues.
// DevDiv Bugs 59454
if (rewrittenLeft.Kind != BoundKind.Local && IsStackAlloc(originalRight))
{
// From ILGENREC::genAssign:
// DevDiv Bugs 59454: Handle hoisted local initialized with a stackalloc
// NOTE: Need to check for cast of stackalloc on RHS.
// If LHS isLocal, then genAddr is a noop so regular case works fine.
SyntheticBoundNodeFactory factory = new SyntheticBoundNodeFactory(this.CurrentMethod, rewrittenLeft.Syntax, this.CompilationState, this.Diagnostics);
BoundAssignmentOperator tempAssignment;
BoundLocal tempLocal = factory.StoreToTemp(rewrittenRight, out tempAssignment);
Debug.Assert(node.RefKind == RefKind.None);
BoundAssignmentOperator rewrittenAssignment = node.Update(rewrittenLeft, tempLocal, node.RefKind, rewrittenType);
return new BoundSequence(
node.Syntax,
ImmutableArray.Create<LocalSymbol>(tempLocal.LocalSymbol),
ImmutableArray.Create<BoundExpression>(tempAssignment),
rewrittenAssignment,
rewrittenType);
}
return node.Update(rewrittenLeft, rewrittenRight, node.RefKind, rewrittenType);
}
示例5: IsIndirectAssignment
// indirect assignment is assignment to a value referenced indirectly
// it may only happen if
// 1) lhs is a reference (must be a parameter or a local)
// 2) it is not a ref/out assignment where the reference itself would be assigned
private static bool IsIndirectAssignment(BoundAssignmentOperator node)
{
var lhs = node.Left;
Debug.Assert(node.RefKind == RefKind.None || (lhs as BoundLocal)?.LocalSymbol.RefKind == RefKind.Ref,
"only ref locals can be a target of a ref assignment");
switch (lhs.Kind)
{
case BoundKind.ThisReference:
Debug.Assert(lhs.Type.IsValueType, "'this' is assignable only in structs");
return true;
case BoundKind.Parameter:
if (((BoundParameter)lhs).ParameterSymbol.RefKind != RefKind.None)
{
bool isIndirect = node.RefKind == RefKind.None;
return isIndirect;
}
return false;
case BoundKind.Local:
if (((BoundLocal)lhs).LocalSymbol.RefKind != RefKind.None)
{
bool isIndirect = node.RefKind == RefKind.None;
return isIndirect;
}
return false;
case BoundKind.Call:
Debug.Assert(((BoundCall)lhs).Method.RefKind == RefKind.Ref, "only ref returning methods are assignable");
return true;
case BoundKind.AssignmentOperator:
Debug.Assert(((BoundAssignmentOperator)lhs).RefKind == RefKind.Ref, "only ref assignments are assignable");
return true;
case BoundKind.Sequence:
Debug.Assert(!IsIndirectAssignment(node.Update(((BoundSequence)node.Left).Value, node.Right, node.RefKind, node.Type)),
"indirect assignment to a sequence is unexpected");
return false;
case BoundKind.RefValueOperator:
case BoundKind.PointerIndirectionOperator:
case BoundKind.PseudoVariable:
return true;
case BoundKind.ModuleVersionId:
case BoundKind.InstrumentationPayloadRoot:
// these are just stores into special static fields
goto case BoundKind.FieldAccess;
case BoundKind.FieldAccess:
case BoundKind.ArrayAccess:
// always symbolic stores
return false;
default:
throw ExceptionUtilities.UnexpectedValue(lhs.Kind);
}
}