public static T Pop <T>(this ArrayBuilder <T> builder) { var e = builder.Peek(); builder.RemoveAt(builder.Count - 1); return(e); }
/// <summary> /// Converts the expression for creating a tuple instance into an expression creating a ValueTuple (if short) or nested ValueTuples (if longer). /// /// For instance, for a long tuple we'll generate: /// creationExpression(ctor=largestCtor, args=firstArgs+(nested creationExpression for remainder, with smaller ctor and next few args)) /// </summary> private BoundNode RewriteTupleCreationExpression(BoundTupleExpression node, ImmutableArray <BoundExpression> rewrittenArguments) { NamedTypeSymbol underlyingTupleType = node.Type.TupleUnderlyingType; ArrayBuilder <NamedTypeSymbol> underlyingTupleTypeChain = ArrayBuilder <NamedTypeSymbol> .GetInstance(); TupleTypeSymbol.GetUnderlyingTypeChain(underlyingTupleType, underlyingTupleTypeChain); try { // make a creation expression for the smallest type NamedTypeSymbol smallestType = underlyingTupleTypeChain.Pop(); ImmutableArray <BoundExpression> smallestCtorArguments = ImmutableArray.Create(rewrittenArguments, underlyingTupleTypeChain.Count * (TupleTypeSymbol.RestPosition - 1), smallestType.Arity); var smallestCtor = (MethodSymbol)TupleTypeSymbol.GetWellKnownMemberInType(smallestType.OriginalDefinition, TupleTypeSymbol.GetTupleCtor(smallestType.Arity), _diagnostics, node.Syntax); if ((object)smallestCtor == null) { return(node); } MethodSymbol smallestConstructor = smallestCtor.AsMember(smallestType); BoundObjectCreationExpression currentCreation = new BoundObjectCreationExpression(node.Syntax, smallestConstructor, smallestCtorArguments); if (underlyingTupleTypeChain.Count > 0) { NamedTypeSymbol tuple8Type = underlyingTupleTypeChain.Peek(); var tuple8Ctor = (MethodSymbol)TupleTypeSymbol.GetWellKnownMemberInType(tuple8Type.OriginalDefinition, TupleTypeSymbol.GetTupleCtor(TupleTypeSymbol.RestPosition), _diagnostics, node.Syntax); if ((object)tuple8Ctor == null) { return(node); } // make successively larger creation expressions containing the previous one do { ImmutableArray <BoundExpression> ctorArguments = ImmutableArray.Create(rewrittenArguments, (underlyingTupleTypeChain.Count - 1) * (TupleTypeSymbol.RestPosition - 1), TupleTypeSymbol.RestPosition - 1) .Add(currentCreation); MethodSymbol constructor = tuple8Ctor.AsMember(underlyingTupleTypeChain.Pop()); currentCreation = new BoundObjectCreationExpression(node.Syntax, constructor, ctorArguments); }while (underlyingTupleTypeChain.Count > 0); } return(currentCreation); } finally { underlyingTupleTypeChain.Free(); } }
public bool TryPeek(out Discriminator discriminator) { if (discriminatorStack.Count == 0) { discriminator = Discriminator.Invalid; return(false); } discriminator = discriminatorStack.Peek(); return(true); }
private void EmitAllElementInitializersRecursive( ArrayTypeSymbol arrayType, ArrayBuilder <IndexDesc> indices, bool includeConstants ) { var top = indices.Peek(); var inits = top.Initializers; if (IsMultidimensionalInitializer(inits)) { // emit initializers for the less significant indices recursively for (int i = 0; i < inits.Length; i++) { indices.Push( new IndexDesc(i, ((BoundArrayInitialization)inits[i]).Initializers) ); EmitAllElementInitializersRecursive(arrayType, indices, includeConstants); } } else { // leaf case for (int i = 0; i < inits.Length; i++) { var init = inits[i]; if (ShouldEmitInitExpression(includeConstants, init)) { // emit array ref _builder.EmitOpCode(ILOpCode.Dup); Debug.Assert(indices.Count == arrayType.Rank - 1); // emit values of all indices that are in progress foreach (var row in indices) { _builder.EmitIntConstant(row.Index); } // emit the leaf index _builder.EmitIntConstant(i); var initExpr = inits[i]; EmitExpression(initExpr, true); EmitArrayElementStore(arrayType, init.Syntax); } } } indices.Pop(); }
/// <summary> /// Emits all initializers that match indices on the stack recursively. /// /// Example: /// if array has [0..2, 0..3, 0..2] shape /// and we have {1, 2} indices on the stack /// initializers for /// [1, 2, 0] /// [1, 2, 1] /// [1, 2, 2] /// /// will be emitted and the top index will be pushed off the stack /// as at that point we would be completely done with emitting initializers /// corresponding to that index. /// </summary> private void EmitAllElementInitializersRecursive(ArrayTypeSymbol arrayType, ArrayBuilder<IndexDesc> indices, bool includeConstants) { var top = indices.Peek(); var inits = top.Initializers; if (IsMultidimensionalInitializer(inits)) { // emit initializers for the less significant indices recursively for (int i = 0; i < inits.Length; i++) { indices.Push(new IndexDesc(i, ((BoundArrayInitialization)inits[i]).Initializers)); EmitAllElementInitializersRecursive(arrayType, indices, includeConstants); } } else { // leaf case for (int i = 0; i < inits.Length; i++) { var init = inits[i]; if (ShouldEmitInitExpression(includeConstants, init)) { // emit array ref _builder.EmitOpCode(ILOpCode.Dup); Debug.Assert(indices.Count == arrayType.Rank - 1); // emit values of all indices that are in progress foreach (var row in indices) { _builder.EmitIntConstant(row.Index); } // emit the leaf index _builder.EmitIntConstant(i); var initExpr = inits[i]; EmitExpression(initExpr, true); EmitArrayElementStore(arrayType, init.Syntax); } } } indices.Pop(); }
private BoundExpression MakeTupleCreationExpression(SyntaxNode syntax, NamedTypeSymbol type, ImmutableArray <BoundExpression> rewrittenArguments) { NamedTypeSymbol underlyingTupleType = type.TupleUnderlyingType ?? type; Debug.Assert(underlyingTupleType.IsTupleCompatible()); ArrayBuilder <NamedTypeSymbol> underlyingTupleTypeChain = ArrayBuilder <NamedTypeSymbol> .GetInstance(); TupleTypeSymbol.GetUnderlyingTypeChain(underlyingTupleType, underlyingTupleTypeChain); try { // make a creation expression for the smallest type NamedTypeSymbol smallestType = underlyingTupleTypeChain.Pop(); ImmutableArray <BoundExpression> smallestCtorArguments = ImmutableArray.Create(rewrittenArguments, underlyingTupleTypeChain.Count * (TupleTypeSymbol.RestPosition - 1), smallestType.Arity); var smallestCtor = (MethodSymbol)TupleTypeSymbol.GetWellKnownMemberInType(smallestType.OriginalDefinition, TupleTypeSymbol.GetTupleCtor(smallestType.Arity), _diagnostics, syntax); if ((object)smallestCtor == null) { return(_factory.BadExpression(type)); } MethodSymbol smallestConstructor = smallestCtor.AsMember(smallestType); BoundObjectCreationExpression currentCreation = new BoundObjectCreationExpression(syntax, smallestConstructor, null, smallestCtorArguments); if (underlyingTupleTypeChain.Count > 0) { NamedTypeSymbol tuple8Type = underlyingTupleTypeChain.Peek(); var tuple8Ctor = (MethodSymbol)TupleTypeSymbol.GetWellKnownMemberInType(tuple8Type.OriginalDefinition, TupleTypeSymbol.GetTupleCtor(TupleTypeSymbol.RestPosition), _diagnostics, syntax); if ((object)tuple8Ctor == null) { return(_factory.BadExpression(type)); } // make successively larger creation expressions containing the previous one do { ImmutableArray <BoundExpression> ctorArguments = ImmutableArray.Create(rewrittenArguments, (underlyingTupleTypeChain.Count - 1) * (TupleTypeSymbol.RestPosition - 1), TupleTypeSymbol.RestPosition - 1) .Add(currentCreation); MethodSymbol constructor = tuple8Ctor.AsMember(underlyingTupleTypeChain.Pop()); currentCreation = new BoundObjectCreationExpression(syntax, constructor, null, ctorArguments); }while (underlyingTupleTypeChain.Count > 0); } currentCreation = currentCreation.Update( currentCreation.Constructor, currentCreation.Arguments, currentCreation.ArgumentNamesOpt, currentCreation.ArgumentRefKindsOpt, currentCreation.Expanded, currentCreation.ArgsToParamsOpt, currentCreation.ConstantValue, currentCreation.InitializerExpressionOpt, currentCreation.BinderOpt, type); return(currentCreation); } finally { underlyingTupleTypeChain.Free(); } }
public override BoundNode VisitLabelStatement(BoundLabelStatement node) { _labelsInScope.Peek().Add(node.Label); _scopesAfterLabel.Add(node.Label, ArrayBuilder <Scope> .GetInstance()); return(base.VisitLabelStatement(node)); }
public Which PeekNext() { Debug.Assert(_discriminatorStack is object); return(_discriminatorStack.Peek()); }
// Bucketing algorithm: // Start with empty stack of buckets. // While there are still labels // If bucket from remaining labels is dense // Create a newBucket from remaining labels // Else // Create a singleton newBucket from the next label // While the top bucket on stack can be merged with newBucket into a dense bucket // merge top bucket on stack into newBucket, and pop bucket from stack // End While // Push newBucket on stack // End While private ImmutableArray <SwitchBucket> GenerateSwitchBuckets(int startLabelIndex, int endLabelIndex) { Debug.Assert(startLabelIndex >= 0 && startLabelIndex <= endLabelIndex); Debug.Assert(_sortedCaseLabels.Length > endLabelIndex); // Start with empty stack of buckets. ArrayBuilder <SwitchBucket> switchBucketsStack = ArrayBuilder <SwitchBucket> .GetInstance(); int curStartLabelIndex = startLabelIndex; // While there are still labels while (curStartLabelIndex <= endLabelIndex) { SwitchBucket newBucket = CreateNextBucket(curStartLabelIndex, endLabelIndex); // While the top bucket on stack can be merged with newBucket into a dense bucket // merge top bucket on stack into newBucket, and pop bucket from stack // End While while (!switchBucketsStack.IsEmpty()) { // get the bucket at top of the stack SwitchBucket prevBucket = switchBucketsStack.Peek(); if (newBucket.TryMergeWith(prevBucket)) { // pop the previous bucket from the stack switchBucketsStack.Pop(); } else { // merge failed break; } } // Push newBucket on stack switchBucketsStack.Push(newBucket); // update curStartLabelIndex curStartLabelIndex++; } Debug.Assert(!switchBucketsStack.IsEmpty()); // crumble leaf buckets into degenerate buckets where possible ArrayBuilder <SwitchBucket> crumbled = ArrayBuilder <SwitchBucket> .GetInstance(); foreach (SwitchBucket uncrumbled in switchBucketsStack) { int degenerateSplit = uncrumbled.DegenerateBucketSplit; switch (degenerateSplit) { case -1: // cannot be split crumbled.Add(uncrumbled); break; case 0: // already degenerate crumbled.Add(new SwitchBucket(_sortedCaseLabels, uncrumbled.StartLabelIndex, uncrumbled.EndLabelIndex, isDegenerate: true)); break; default: // can split crumbled.Add(new SwitchBucket(_sortedCaseLabels, uncrumbled.StartLabelIndex, degenerateSplit - 1, isDegenerate: true)); crumbled.Add(new SwitchBucket(_sortedCaseLabels, degenerateSplit, uncrumbled.EndLabelIndex, isDegenerate: true)); break; } } switchBucketsStack.Free(); return(crumbled.ToImmutableAndFree()); }