本文整理汇总了C#中BoundSequence类的典型用法代码示例。如果您正苦于以下问题:C# BoundSequence类的具体用法?C# BoundSequence怎么用?C# BoundSequence使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
BoundSequence类属于命名空间,在下文中一共展示了BoundSequence类的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C#代码示例。
示例1: AddSequence
internal void AddSequence(SyntheticBoundNodeFactory F, BoundSequence sequence)
{
locals.AddRange(sequence.Locals);
foreach (var sideEffect in sequence.SideEffects)
{
statements.Add(F.ExpressionStatement(sideEffect));
}
}
开发者ID:EkardNT,项目名称:Roslyn,代码行数:8,代码来源:SpillBuilder.cs
示例2: VisitSequence
public override BoundNode VisitSequence(BoundSequence node)
{
ReadOnlyArray<BoundExpression> sideEffects = (ReadOnlyArray<BoundExpression>)this.VisitList(node.SideEffects);
BoundExpression value = (BoundExpression)this.Visit(node.Value);
TypeSymbol type = this.VisitType(node.Type);
if (!RequiresSpill(sideEffects) && value.Kind != BoundKind.SpillSequence)
{
return node.Update(node.Locals, sideEffects, value, type);
}
var spillBuilder = new SpillBuilder();
spillBuilder.Locals.AddRange(node.Locals);
foreach (var sideEffect in sideEffects)
{
spillBuilder.Statements.Add(
(sideEffect.Kind == BoundKind.SpillSequence)
? RewriteSpillSequenceAsBlock((BoundSpillSequence)sideEffect)
: F.ExpressionStatement(sideEffect));
}
BoundExpression newValue;
if (value.Kind == BoundKind.SpillSequence)
{
var awaitEffect = (BoundSpillSequence)value;
spillBuilder.AddSpill(awaitEffect);
newValue = awaitEffect.Value;
}
else
{
newValue = value;
}
return spillBuilder.BuildSequenceAndFree(F, newValue);
}
开发者ID:modulexcite,项目名称:pattern-matching-csharp,代码行数:37,代码来源:AwaitLoweringRewriterPass1.cs
示例3: VisitSequence
public override BoundNode VisitSequence(BoundSequence node)
{
var newLocals = RewriteLocals(node.Locals);
var newSideEffects = VisitList<BoundExpression>(node.SideEffects);
var newValue = (BoundExpression)this.Visit(node.Value);
var newType = this.VisitType(node.Type);
return node.Update(newLocals, newSideEffects, newValue, newType);
}
开发者ID:XieShuquan,项目名称:roslyn,代码行数:8,代码来源:MethodToClassRewriter.cs
示例4: EmitSideEffects
private void EmitSideEffects(BoundSequence sequence)
{
var sideEffects = sequence.SideEffects;
if (!sideEffects.IsDefaultOrEmpty)
{
foreach (var se in sideEffects)
{
EmitExpression(se, false);
}
}
}
开发者ID:tvsonar,项目名称:roslyn,代码行数:11,代码来源:EmitExpression.cs
示例5: DefineLocals
private void DefineLocals(BoundSequence sequence)
{
if (sequence.Locals.IsEmpty)
{
return;
}
_builder.OpenLocalScope();
foreach (var local in sequence.Locals)
{
DefineLocal(local, sequence.Syntax);
}
}
开发者ID:tvsonar,项目名称:roslyn,代码行数:14,代码来源:EmitExpression.cs
示例6: VisitSequence
public override BoundNode VisitSequence(BoundSequence node)
{
BoundSpillSequence2 ss2 = null;
var value = VisitExpression(ref ss2, node.Value);
BoundSpillSequence2 ss1 = null;
var sideEffects = VisitExpressionList(ref ss1, node.SideEffects, forceSpill: ss2 != null, sideEffectsOnly: true);
if (ss1 == null && ss2 == null)
{
return node.Update(node.Locals, sideEffects, value, node.Type);
}
if (ss1 == null) ss1 = new BoundSpillSequence2(); // possible if sideEffects is empty
ss1.AddRange(sideEffects, MakeExpressionStatement);
ss1.AddRange(node.Locals);
ss1.IncludeSequence(ss2);
return ss1.Update(value);
}
开发者ID:EkardNT,项目名称:Roslyn,代码行数:19,代码来源:AwaitLiftingRewriter.cs
示例7: VisitSequence
// here we have a case of indirect assignment: *t1 = expr;
// normally we would need to push t1 and that will cause spilling of t2
//
// TODO: an interesting case arises in unused x[i]++ and ++x[i] :
// we have trees that look like:
//
// t1 = &(x[0])
// t2 = *t1
// *t1 = t2 + 1
//
// t1 = &(x[0])
// t2 = *t1 + 1
// *t1 = t2
//
// in these cases, we could keep t2 on stack (dev10 does).
// we are dealing with exactly 2 locals and access them in strict order
// t1, t2, t1, t2 and we are not using t2 after that.
// We may consider detecting exactly these cases and pretend that we do not need
// to push either t1 or t2 in this case.
//
public override BoundNode VisitSequence(BoundSequence node)
{
// Normally we can only use stack for local scheduling if stack is not used for evaluation.
// In a context of a regular block that simply means that eval stack must be empty.
// Sequences, can be entered on a nonempty evaluation stack
// Ex:
// a.b = Seq{var y, y = 1, y} // a is on the stack for the duration of the sequence.
//
// However evaluation stack at the entry cannot be used inside the sequence, so such stack
// works as effective "empty" for locals declared in sequence.
// Therefore sequence locals can be stack scheduled at same stack as at the entry to the sequence.
// it may seem attractive to relax the stack requirement to be:
// "all uses must agree on stack depth".
// The following example illustrates a case where x is safely used at "declarationStack + 1"
// Ex:
// Seq{var x; y.a = Seq{x = 1; x}; y} // x is used while y is on the eval stack
//
// It is, however not safe assumption in general since eval stack may be accessed between usages.
// Ex:
// Seq{var x; y.a = Seq{x = 1; x}; y.z = x; y} // x blocks access to y
//
// There is one case where we want to tweak the "use at declaration stack" rule - in the case of
// compound assignment that involves ByRef operand captures (like: x[y]++ ) .
//
// Those cases produce specific sequences of the shapes:
//
// prefix: Seq{var temp, ref operand; operand initializers; *operand = Seq{temp = (T)(operand + 1); temp;} result: temp}
// postfix: Seq{var temp, ref operand; operand initializers; *operand = Seq{temp = operand; ; (T)(temp + 1);} result: temp}
//
// 1) temp is used as the result of the sequence (and that is the only reason why it is declared in the outer sequence).
// 2) all side-effects except the last one do not use the temp.
// 3) last side-effect is an indirect assignment of a sequence (and target does not involve the temp).
//
// Note that in a case of side-effects context, the result value will be ignored and therefore
// all usages of the nested temp will be confined to the nested sequence that is executed at +1 stack.
//
// We will detect such case and indicate +1 as the desired stack depth at local accesses.
//
var declarationStack = StackDepth();
var locals = node.Locals;
if (!locals.IsDefaultOrEmpty)
{
if (_context == ExprContext.Sideeffects)
{
foreach (var local in locals)
{
if (IsNestedLocalOfCompoundOperator(local, node))
{
// special case
DeclareLocal(local, declarationStack + 1);
}
else
{
DeclareLocal(local, declarationStack);
}
}
}
else
{
DeclareLocals(locals, declarationStack);
}
}
// rewrite operands
var origContext = _context;
var sideeffects = node.SideEffects;
ArrayBuilder<BoundExpression> rewrittenSideeffects = null;
if (!sideeffects.IsDefault)
{
for (int i = 0; i < sideeffects.Length; i++)
{
var sideeffect = sideeffects[i];
var rewrittenSideeffect = this.VisitExpression(sideeffect, ExprContext.Sideeffects);
if (rewrittenSideeffects == null && rewrittenSideeffect != sideeffect)
//.........这里部分代码省略.........
开发者ID:rosslyn-cuongle,项目名称:roslyn,代码行数:101,代码来源:Optimizer.cs
示例8: EmitSequenceCondBranch
private void EmitSequenceCondBranch(BoundSequence sequence, ref object dest, bool sense)
{
DefineLocals(sequence);
EmitSideEffects(sequence);
EmitCondBranch(sequence.Value, ref dest, sense);
// sequence is used as a value, can release all locals
FreeLocals(sequence, doNotRelease: null);
}
开发者ID:jkotas,项目名称:roslyn,代码行数:9,代码来源:EmitStatement.cs
示例9: MergeArgumentsAndSideEffects
/// <summary>
/// Process tempStores and add them as side-effects to arguments where needed. The return
/// value tells how many temps are actually needed. For unnecessary temps the corresponding
/// temp store will be cleared.
/// </summary>
private static int MergeArgumentsAndSideEffects(
BoundExpression[] arguments,
ArrayBuilder<RefKind> refKinds,
ArrayBuilder<BoundAssignmentOperator> tempStores)
{
Debug.Assert(arguments != null);
Debug.Assert(refKinds != null);
Debug.Assert(tempStores != null);
int tempsRemainedInUse = tempStores.Count;
// Suppose we've got temporaries: t0 = A(), t1 = B(), t2 = C(), t4 = D(), t5 = E()
// and arguments: t0, t2, t1, t4, 10, t5
//
// We wish to produce arguments list: A(), SEQ(t1=B(), C()), t1, D(), 10, E()
//
// Our algorithm essentially finds temp stores that must happen before given argument
// load, and if there are any they become side effects of the given load.
// Stores immediately followed by loads of the same thing can be eliminated.
//
// Constraints:
// Stores must happen before corresponding loads.
// Stores cannot move relative to other stores. If arg was movable it would not need a temp.
int firstUnclaimedStore = 0;
for (int a = 0; a < arguments.Length; ++a)
{
var argument = arguments[a];
// if argument is a load, search for corresponding store. if store is found, extract
// the actual expression we were storing and add it as an argument - this one does
// not need a temp. if there are any unclaimed stores before the found one, add them
// as side effects that precede this arg, they cannot happen later.
// NOTE: missing optional parameters are not filled yet and therefore nulls - no need to do anything for them
if (argument?.Kind == BoundKind.Local)
{
var correspondingStore = -1;
for (int i = firstUnclaimedStore; i < tempStores.Count; i++)
{
if (tempStores[i].Left == argument)
{
correspondingStore = i;
break;
}
}
// store found?
if (correspondingStore != -1)
{
var value = tempStores[correspondingStore].Right;
// When we created the temp, we dropped the argument RefKind
// since the local contained its own RefKind. Since we're removing
// the temp, the argument RefKind needs to be restored.
refKinds[a] = ((BoundLocal)argument).LocalSymbol.RefKind;
// the matched store will not need to go into side-effects, only ones before it will
// remove the store to signal that we are not using its temp.
tempStores[correspondingStore] = null;
tempsRemainedInUse--;
// no need for side-effects?
// just combine store and load
if (correspondingStore == firstUnclaimedStore)
{
arguments[a] = value;
}
else
{
var sideeffects = new BoundExpression[correspondingStore - firstUnclaimedStore];
for (int s = 0; s < sideeffects.Length; s++)
{
sideeffects[s] = tempStores[firstUnclaimedStore + s];
}
arguments[a] = new BoundSequence(
value.Syntax,
// this sequence does not own locals. Note that temps that
// we use for the rewrite are stored in one arg and loaded
// in another so they must live in a scope above.
ImmutableArray<LocalSymbol>.Empty,
sideeffects.AsImmutableOrNull(),
value,
value.Type);
}
firstUnclaimedStore = correspondingStore + 1;
}
}
}
Debug.Assert(firstUnclaimedStore == tempStores.Count, "not all side-effects were claimed");
return tempsRemainedInUse;
}
开发者ID:jkotas,项目名称:roslyn,代码行数:100,代码来源:LocalRewriter_Call.cs
示例10: RewriteArgumentsForComCall
// Omit ref feature for COM interop: We can pass arguments by value for ref parameters if we are calling a method/property on an instance of a COM imported type.
// We should have ignored the 'ref' on the parameter during overload resolution for the given method call.
// If we had any ref omitted argument for the given call, we create a temporary local and
// replace the argument with the following BoundSequence: { side-effects: { temp = argument }, value = { ref temp } }
// NOTE: The temporary local must be scoped to live across the entire BoundCall node,
// otherwise the codegen optimizer might re-use the same temporary for multiple ref-omitted arguments for this call.
private void RewriteArgumentsForComCall(
ImmutableArray<ParameterSymbol> parameters,
BoundExpression[] actualArguments, //already re-ordered to match parameters
ArrayBuilder<RefKind> argsRefKindsBuilder,
ArrayBuilder<LocalSymbol> temporariesBuilder)
{
Debug.Assert(actualArguments != null);
Debug.Assert(actualArguments.Length == parameters.Length);
Debug.Assert(argsRefKindsBuilder == null || argsRefKindsBuilder.Count == parameters.Length);
var argsCount = actualArguments.Length;
for (int argIndex = 0; argIndex < argsCount; ++argIndex)
{
RefKind paramRefKind = parameters[argIndex].RefKind;
RefKind argRefKind = argsRefKindsBuilder[argIndex];
// Rewrite only if the argument was passed with no ref/out and the
// parameter was declared ref.
if (argRefKind != RefKind.None || paramRefKind != RefKind.Ref)
{
continue;
}
var argument = actualArguments[argIndex];
if (argument.Kind == BoundKind.Local)
{
var localRefKind = ((BoundLocal)argument).LocalSymbol.RefKind;
if (localRefKind == RefKind.Ref)
{
// Already passing an address from the ref local.
continue;
}
Debug.Assert(localRefKind == RefKind.None);
}
BoundAssignmentOperator boundAssignmentToTemp;
BoundLocal boundTemp = _factory.StoreToTemp(argument, out boundAssignmentToTemp);
actualArguments[argIndex] = new BoundSequence(
argument.Syntax,
locals: ImmutableArray<LocalSymbol>.Empty,
sideEffects: ImmutableArray.Create<BoundExpression>(boundAssignmentToTemp),
value: boundTemp,
type: boundTemp.Type);
argsRefKindsBuilder[argIndex] = RefKind.Ref;
temporariesBuilder.Add(boundTemp.LocalSymbol);
}
}
开发者ID:jkotas,项目名称:roslyn,代码行数:58,代码来源:LocalRewriter_Call.cs
示例11: EmitSequenceExpression
private void EmitSequenceExpression(BoundSequence sequence, bool used)
{
var hasLocals = !sequence.Locals.IsEmpty;
if (hasLocals)
{
builder.OpenLocalScope();
foreach (var local in sequence.Locals)
{
DefineLocal(local, sequence.Syntax);
}
}
EmitSideEffects(sequence);
// CONSIDER: LocalRewriter.RewriteNestedObjectOrCollectionInitializerExpression may create a bound sequence with an unused BoundTypeExpression as the value,
// CONSIDER: which must be ignored by codegen. See comments in RewriteNestedObjectOrCollectionInitializerExpression for details and an example.
// CONSIDER: We may want to instead consider making the Value field of BoundSequence node optional to allow a sequence with
// CONSIDER: only side effects and no value. Note that VB's BoundSequence node has an optional value field.
// CONSIDER: This will allow us to remove the below check before emitting the value.
Debug.Assert(sequence.Value.Kind != BoundKind.TypeExpression || !used);
if (sequence.Value.Kind != BoundKind.TypeExpression)
{
EmitExpression(sequence.Value, used);
}
if (hasLocals)
{
builder.CloseLocalScope();
foreach (var local in sequence.Locals)
{
FreeLocal(local);
}
}
}
开发者ID:riversky,项目名称:roslyn,代码行数:38,代码来源:EmitExpression.cs
示例12: FreeLocals
private void FreeLocals(BoundSequence sequence)
{
if (sequence.Locals.IsEmpty)
{
return;
}
builder.CloseLocalScope();
foreach (var local in sequence.Locals)
{
FreeLocal(local);
}
}
开发者ID:EkardNT,项目名称:Roslyn,代码行数:14,代码来源:EmitExpression.cs
示例13: VisitObjectCreationExpression
public override BoundNode VisitObjectCreationExpression(BoundObjectCreationExpression node)
{
Debug.Assert(node != null);
// Rewrite the arguments.
// NOTE: We may need additional argument rewriting such as generating a params array,
// re-ordering arguments based on argsToParamsOpt map, inserting arguments for optional parameters, etc.
// NOTE: This is done later by MakeArguments, for now we just lower each argument.
var rewrittenArguments = VisitList(node.Arguments);
// We have already lowered each argument, but we may need some additional rewriting for the arguments,
// such as generating a params array, re-ordering arguments based on argsToParamsOpt map, inserting arguments for optional parameters, etc.
ImmutableArray<LocalSymbol> temps;
ImmutableArray<RefKind> argumentRefKindsOpt = node.ArgumentRefKindsOpt;
rewrittenArguments = MakeArguments(node.Syntax, rewrittenArguments, node.Constructor, node.Constructor, node.Expanded, node.ArgsToParamsOpt, ref argumentRefKindsOpt, out temps);
BoundExpression rewrittenObjectCreation;
if (_inExpressionLambda)
{
if (!temps.IsDefaultOrEmpty)
{
throw ExceptionUtilities.UnexpectedValue(temps.Length);
}
rewrittenObjectCreation = node.UpdateArgumentsAndInitializer(rewrittenArguments, MakeObjectCreationInitializerForExpressionTree(node.InitializerExpressionOpt), changeTypeOpt: node.Constructor.ContainingType);
if (node.Type.IsInterfaceType())
{
Debug.Assert(rewrittenObjectCreation.Type == ((NamedTypeSymbol)node.Type).ComImportCoClass);
rewrittenObjectCreation = MakeConversion(rewrittenObjectCreation, node.Type, false, false);
}
return rewrittenObjectCreation;
}
rewrittenObjectCreation = node.UpdateArgumentsAndInitializer(rewrittenArguments, newInitializerExpression: null, changeTypeOpt: node.Constructor.ContainingType);
// replace "new S()" with a default struct ctor with "default(S)"
if (node.Constructor.IsDefaultValueTypeConstructor())
{
rewrittenObjectCreation = new BoundDefaultOperator(rewrittenObjectCreation.Syntax, rewrittenObjectCreation.Type);
}
if (!temps.IsDefaultOrEmpty)
{
rewrittenObjectCreation = new BoundSequence(
node.Syntax,
temps,
ImmutableArray<BoundExpression>.Empty,
rewrittenObjectCreation,
node.Type);
}
if (node.Type.IsInterfaceType())
{
Debug.Assert(rewrittenObjectCreation.Type == ((NamedTypeSymbol)node.Type).ComImportCoClass);
rewrittenObjectCreation = MakeConversion(rewrittenObjectCreation, node.Type, false, false);
}
if (node.InitializerExpressionOpt == null || node.InitializerExpressionOpt.HasErrors)
{
return rewrittenObjectCreation;
}
return MakeObjectCreationWithInitializer(node.Syntax, rewrittenObjectCreation, node.InitializerExpressionOpt, node.Type);
}
开发者ID:RoryVL,项目名称:roslyn,代码行数:67,代码来源:LocalRewriter_ObjectCreationExpression.cs
示例14: EmitSequenceCondBranch
private void EmitSequenceCondBranch(BoundSequence sequence, ref object dest, bool sense)
{
var hasLocals = !sequence.Locals.IsEmpty;
if (hasLocals)
{
builder.OpenLocalScope();
foreach (var local in sequence.Locals)
{
DefineLocal(local, sequence.Syntax);
}
}
EmitSideEffects(sequence);
EmitCondBranch(sequence.Value, ref dest, sense);
if (hasLocals)
{
builder.CloseLocalScope();
foreach (var local in sequence.Locals)
{
FreeLocal(local);
}
}
}
开发者ID:afrog33k,项目名称:csnative,代码行数:27,代码来源:EmitStatement.cs
示例15: DigForValueLocal
// if sequence value is a local scoped to the sequence, return that local
private LocalSymbol DigForValueLocal(BoundSequence topSequence)
{
return DigForValueLocal(topSequence, topSequence.Value);
}
开发者ID:xier2012,项目名称:roslyn,代码行数:5,代码来源:EmitAddress.cs
示例16: VisitSequence
public override BoundNode VisitSequence(BoundSequence node)
{
// Spilled local temps do not appear here in a sequence expression, because any temps in a
// sequence expression that need to be spilled would have been moved up to the
// statement level by the AwaitLiftingRewriter.
if (!node.Locals.IsDefaultOrEmpty)
{
foreach (var local in node.Locals)
{
Debug.Assert(!VariablesCaptured.Contains(local) || proxies.ContainsKey(local));
}
}
return base.VisitSequence(node);
}
开发者ID:nagyist,项目名称:roslyn,代码行数:15,代码来源:StateMachineMethodToClassRewriter.cs
示例17: VisitSequence
public override BoundNode VisitSequence(BoundSequence node)
{
AddVariables(node.Locals);
return base.VisitSequence(node);
}
开发者ID:ehsansajjad465,项目名称:roslyn,代码行数:5,代码来源:IteratorAndAsyncCaptureWalker.cs
示例18: RewriteWithRefOperand
private BoundNode RewriteWithRefOperand(
bool isPrefix,
bool isChecked,
ArrayBuilder<LocalSymbol> tempSymbols,
ArrayBuilder<BoundExpression> tempInitializers,
CSharpSyntaxNode syntax,
BoundExpression operand,
TypeSymbol operandType,
BoundExpression boundTemp,
BoundExpression newValue)
{
var tempValue = isPrefix ? newValue : MakeRValue(operand);
var tempAssignment = MakeAssignmentOperator(syntax, boundTemp, tempValue, operandType, used: false, isChecked: isChecked, isCompoundAssignment: false);
var operandValue = isPrefix ? boundTemp : newValue;
var tempAssignedAndOperandValue = new BoundSequence(
syntax,
ImmutableArray<LocalSymbol>.Empty,
ImmutableArray.Create<BoundExpression>(tempAssignment),
operandValue,
tempValue.Type);
// prefix: operand = Seq{temp = (T)(operand + 1); temp;}
// postfix: operand = Seq{temp = operand; ; (T)(temp + 1);}
BoundExpression operandAssignment = MakeAssignmentOperator(syntax, operand, tempAssignedAndOperandValue, operandType, used: false, isChecked: isChecked, isCompoundAssignment: false);
// prefix: Seq{operand initializers; operand = Seq{temp = (T)(operand + 1); temp;} result: temp}
// postfix: Seq{operand initializers; operand = Seq{temp = operand; ; (T)(temp + 1);} result: temp}
tempInitializers.Add(operandAssignment);
return new BoundSequence(
syntax: syntax,
locals: tempSymbols.ToImmutableAndFree(),
sideEffects: tempInitializers.ToImmutableAndFree(),
value: boundTemp,
type: operandType);
}
开发者ID:Rickinio,项目名称:roslyn,代码行数:36,代码来源:LocalRewriter_UnaryOperator.cs
示例19: IsNestedLocalOfCompoundOperator
// detect a pattern used in compound operators
// where a temp is declared in the outer sequence
// only because it must be returned, otherwise all uses are
// confined to the nested sequence that is assigned indirectly of to an instance field (and therefore has +1 stack)
// in such case the desired stack for this local is +1
private static bool IsNestedLocalOfCompoundOperator(LocalSymbol local, BoundSequence node)
{
var value = node.Value;
// local must be used as the value of the sequence.
if (value != null && value.Kind == BoundKind.Local && ((BoundLocal)value).LocalSymbol == local)
{
var sideeffects = node.SideEffects;
var lastSideeffect = sideeffects.LastOrDefault();
if (lastSideeffect != null)
{
// last side-effect must be an indirect assignment of a sequence.
if (lastSideeffect.Kind == BoundKind.AssignmentOperator)
{
var assignment = (BoundAssignmentOperator)lastSideeffect;
if (IsIndirectOrInstanceFieldAssignment(assignment) &&
assignment.Right.Kind == BoundKind.Sequence)
{
// and no other side-effects should use the variable
var localUsedWalker = new LocalUsedWalker(local);
for (int i = 0; i < sideeffects.Length - 1; i++)
{
if (localUsedWalker.IsLocalUsedIn(sideeffects[i]))
{
return false;
}
}
// and local is not used on the left of the assignment
// (extra check, but better be safe)
if (localUsedWalker.IsLocalUsedIn(assignment.Left))
{
return false;
}
// it should be used somewhere
Debug.Assert(localUsedWalker.IsLocalUsedIn(assignment.Right), "who assigns the temp?");
return true;
}
}
}
}
return false;
}
开发者ID:rosslyn-cuongle,项目名称:roslyn,代码行数:52,代码来源:Optimizer.cs
示例20: EmitSequenceAddress
/// <summary>
/// May introduce a temp which it will return. (otherwise returns null)
/// </summary>
private LocalDefinition EmitSequenceAddress(BoundSequence sequence, AddressKind addressKind)
{
var hasLocals = !sequence.Locals.IsEmpty;
if (hasLocals)
{
builder.OpenLocalScope();
foreach (var local in sequence.Locals)
{
DefineLocal(local, sequence.Syntax);
}
}
EmitSideEffects(sequence);
var tempOpt = EmitAddress(sequence.Value, addressKind);
// when a sequence is happened to be a byref receiver
// we may need to extend the life time of the target until we are done accessing it
// {.v ; v = Foo(); v}.Bar() // v should be released after Bar() is over.
LocalSymbol doNotRelease = null;
if (tempOpt == null)
{
BoundLocal referencedLocal = DigForLocal(sequence.Value);
if (referencedLocal != null)
{
doNotRelease = referencedLocal.LocalSymbol;
}
}
if (hasLocals)
{
builder.CloseLocalScope();
foreach (var local in sequence.Locals)
{
if (local != doNotRelease)
{
FreeLocal(local);
}
else
{
tempOpt = GetLocal(doNotRelease);
}
}
}
return tempOpt;
}
开发者ID:EkardNT,项目名称:Roslyn,代码行数:52,代码来源:EmitAddress.cs
注:本文中的BoundSequence类示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论