Example #1
0
        /// <summary>
        /// Force a variable to have a slot.  Returns -1 if the variable has an empty struct type.
        /// </summary>
        protected int GetOrCreateSlot(Symbol symbol, int containingSlot = 0)
        {
            if (symbol.Kind == SymbolKind.RangeVariable)
            {
                return(-1);
            }

            containingSlot = DescendThroughTupleRestFields(ref symbol, containingSlot, forceContainingSlotsToExist: true);

            VariableIdentifier identifier = new VariableIdentifier(symbol, containingSlot);
            int slot;

            // Since analysis may proceed in multiple passes, it is possible the slot is already assigned.
            if (!_variableSlot.TryGetValue(identifier, out slot))
            {
                var variableType = VariableType(symbol).TypeSymbol;
                if (_emptyStructTypeCache.IsEmptyStructType(variableType))
                {
                    return(-1);
                }

                slot = nextVariableSlot++;
                _variableSlot.Add(identifier, slot);
                if (slot >= variableBySlot.Length)
                {
                    Array.Resize(ref this.variableBySlot, slot * 2);
                }

                variableBySlot[slot] = identifier;
            }

            if (IsConditionalState)
            {
                Normalize(ref this.StateWhenTrue);
                Normalize(ref this.StateWhenFalse);
            }
            else
            {
                Normalize(ref this.State);
            }

            return(slot);
        }
        /// <summary>
        /// Might the given type be, or contain, managed references?  This is used to determine which
        /// fields allocated to temporaries should be cleared when the underlying variable goes out of scope, so
        /// that they do not cause unnecessary object retention.
        /// </summary>
        private bool MightContainReferences(TypeSymbol type)
        {
            if (type.IsReferenceType || type.TypeKind == TypeKind.TypeParameter)
            {
                return(true);                                                                 // type parameter or reference type
            }
            if (type.TypeKind != TypeKind.Struct)
            {
                return(false);                                  // enums, etc
            }
            if (type.SpecialType == SpecialType.System_TypedReference)
            {
                return(true);
            }
            if (type.SpecialType != SpecialType.None)
            {
                return(false);                                      // int, etc
            }
            CSharpCompilation Compilation = this.CompilationState.ModuleBuilderOpt.Compilation;

            if (type.DeclaringCompilation != Compilation)
            {
                return(true);                                          // perhaps from ref assembly
            }
            if (emptyStructTypeCache.IsEmptyStructType(type))
            {
                return(false);
            }
            foreach (var f in type.GetMembers())
            {
                if (f.Kind == SymbolKind.Field && !f.IsStatic && MightContainReferences(((FieldSymbol)f).Type))
                {
                    return(true);
                }
            }
            return(false);
        }
Example #3
0
 protected virtual bool IsEmptyStructType(TypeSymbol type)
 {
     return(_emptyStructTypeCache.IsEmptyStructType(type));
 }