本文整理汇总了C#中BoundExpression.AsReadOnlyWrap方法的典型用法代码示例。如果您正苦于以下问题:C# BoundExpression.AsReadOnlyWrap方法的具体用法?C# BoundExpression.AsReadOnlyWrap怎么用?C# BoundExpression.AsReadOnlyWrap使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类BoundExpression
的用法示例。
在下文中一共展示了BoundExpression.AsReadOnlyWrap方法的2个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: MergeArgumentsAndSideEffects
/// <summary>
/// Process tempStores and add them as sideeffects to arguments where needed. The return
/// value tells how many temps are actually needed. For unnecesary temps the corresponding
/// temp store will be cleared.
/// </summary>
private static int MergeArgumentsAndSideEffects(
ArrayBuilder<BoundAssignmentOperator> tempStores,
BoundExpression[] arguments)
{
Debug.Assert(tempStores != null);
Debug.Assert(arguments != 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(t2=B(), C()), t2, D(), 10, E()
//
// Our algorithm essentially finds temp stores that must happen before given argument load,
// and if there are any they become sideefects of the given load
//
// Constraints:
// Stores must happen before corresponding loads. Casuality.
// Stores cannot move relative to other stores. If arg was movable it would not need a temp.
// So for each argument:
// t0: emit t0 = A(), t0. ===> A()
// t2: emit t1 = B(), t2 = C(), t2. ===> SEQ{ B(), C(), t2 }
// t1: emit t1; ===> t1 //all the dependencies of t1 must be already emitted
// t4: emit t4 = D(), t4. ===> D()
// t5: emit t5 = E(), t5. ===> E()
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 sideeffects that preceed this arg, they cannot happen later.
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;
// the matched store will not need to go into sideffects, only ones before it will
// remove the store to signal that we are not using its temp.
tempStores[correspondingStore] = null;
tempsRemainedInUse--;
// no need for sideeffects?
// just combine store and load
if (correspondingStore == firstUnclaimedStore)
{
arguments[a] = value;
}
else
{
var sideffects = new BoundExpression[correspondingStore - firstUnclaimedStore];
for (int s = 0; s < sideffects.Length; s++)
{
sideffects[s] = tempStores[firstUnclaimedStore + s];
}
arguments[a] = new BoundSequence(
null,
null,
// 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.
ReadOnlyArray<LocalSymbol>.Empty,
sideffects.AsReadOnlyWrap(),
value,
value.Type);
}
firstUnclaimedStore = correspondingStore + 1;
}
}
}
Debug.Assert(firstUnclaimedStore == tempStores.Count, "not all sideeffects were claimed");
return tempsRemainedInUse;
}
示例2: RewriteArguments
//.........这里部分代码省略.........
{
refKinds.Add(RefKind.None);
}
}
ArrayBuilder<BoundAssignmentOperator> storesToTemps = null;
ArrayBuilder<BoundExpression> paramArray = null;
if (expanded)
{
paramArray = ArrayBuilder<BoundExpression>.GetInstance();
}
for (int a = 0; a < rewrittenArguments.Count; ++a)
{
var argument = rewrittenArguments[a];
var p = (argsToParamsOpt.IsNotNull) ? argsToParamsOpt[a] : a;
var refKind = argumentRefKinds.RefKinds(a);
Debug.Assert(arguments[p] == null);
if (expanded && p == parameterCount - 1)
{
paramArray.Add(argument);
Debug.Assert(refKind == RefKind.None);
}
else if (IsSafeForReordering(argument, refKind))
{
arguments[p] = argument;
if (refKinds != null)
{
refKinds[p] = refKind;
}
}
else
{
if (storesToTemps == null)
{
storesToTemps = ArrayBuilder<BoundAssignmentOperator>.GetInstance(rewrittenArguments.Count);
}
var tempStore = TempHelpers.StoreToTemp(argument, refKind, containingSymbol);
storesToTemps.Add(tempStore.Item1);
arguments[p] = tempStore.Item2;
}
}
if (expanded)
{
var paramArrayType = parameters[parameterCount - 1].Type;
var arrayArgs = paramArray.ToReadOnlyAndFree();
var int32Type = method.ContainingAssembly.GetPrimitiveType(Microsoft.Cci.PrimitiveTypeCode.Int32);
arguments[parameterCount - 1] = new BoundArrayCreation(
null,
null,
ReadOnlyArray.Singleton<BoundExpression>(
new BoundLiteral(null, null, ConstantValue.Create(arrayArgs.Count), int32Type)),
new BoundArrayInitialization(null, null, arrayArgs),
paramArrayType);
}
for (int p = 0; p < parameterCount; ++p)
{
if (arguments[p] == null)
{
Debug.Assert(parameters[p].IsOptional);
// UNDONE: Add optional arguments.
}
}
if (storesToTemps != null)
{
int tempsNeeded = MergeArgumentsAndSideEffects(storesToTemps, arguments);
if (tempsNeeded > 0)
{
var temps = new LocalSymbol[tempsNeeded];
for (int i = 0, j = 0; i < storesToTemps.Count; i++)
{
var s = storesToTemps[i];
if (s != null)
{
temps[j++] = ((BoundLocal)s.Left).LocalSymbol;
}
}
temporaries = temps.AsReadOnlyWrap();
}
storesToTemps.Free();
}
// * The rewritten list of names is now null because the arguments have been reordered.
// * The args-to-params map is now null because every argument exactly matches its parameter.
// * The call is no longer in its expanded form.
argumentRefKinds = refKinds == null ? ReadOnlyArray<RefKind>.Null : refKinds.AsReadOnly<RefKind>();
rewrittenArguments = arguments.AsReadOnlyWrap();
}