Beispiel #1
0
        public void Match(SymbolicReference.ApplyingContext context, SymbolicReference rootSummaryEntity)
        {
            if (IsConstAfterSimplification())
            {
                return;
            }

            MaterializeFields();
            if (IsConstAfterSimplification())
            {
                return;
            }

            //MergeEntities()
            rootSummaryEntity.Match(context, entities[0]);
        }
Beispiel #2
0
        public SymbolicReference MergeEntities()
        {
            MaterializeFields();
            if (IsConstAfterSimplification())
            {
                return(entities[0]);
            }

            if (entities.Length > 1)
            {
                var newEntity = SymbolicReference.Merge(entities);
                entities = new[] { newEntity };
            }

            return(entities[0]);
        }
Beispiel #3
0
        public void Apply(SymbolicReference.ApplyingContext context, SymbolicReference rootSummaryEntity, DataFlowAnalysisResult result)
        {
            if (IsConstAfterSimplification())
            {
                return;
            }

            MaterializeFields();
            if (IsConstAfterSimplification())
            {
                return;
            }

            for (int i = 0; i < entities.Length; i++)
            {
                var entity = entities[i];
                entity.Apply(context, rootSummaryEntity, result);
            }
        }
Beispiel #4
0
        public bool IsConstAfterSimplification()
        {
            if (entities != null && entities.Length > 0)
            {
                var constantsCount = 0;
                for (int i = 0; i < entities.Length; i++)
                {
                    if (entities[i].IsConst)
                    {
                        constantsCount++;
                    }
                }

                if (constantsCount == entities.Length)
                {
                    if (entities.Length == 1)
                    {
                        return(true);
                    }

                    entities = new[] { entities[0] };
                    return(true);
                }

                var newEntities = new SymbolicReference[entities.Length - constantsCount];
                var newIndex    = 0;
                for (int i = 0; i < entities.Length; i++)
                {
                    if (!entities[i].IsConst)
                    {
                        newEntities[newIndex++] = entities[i];
                    }
                }

                entities = newEntities;
            }

            return(false);
        }
Beispiel #5
0
        // store by address
        public void Store(SymbolicSlot value)
        {
            if (IsConstAfterSimplification() || value.IsConstAfterSimplification())
            {
                return;
            }

            // store like a field because we should create a snapshot in the moment
            // and avoid cycled references in the "values" field
            MaterializeFields();
            value.MaterializeFields();

            if (IsConstAfterSimplification() || value.IsConstAfterSimplification())
            {
                return;
            }

            var mergedEntity = SymbolicReference.Merge(entities, value.entities);

            entities       = new[] { mergedEntity };
            value.entities = new[] { mergedEntity };
        }
Beispiel #6
0
        public void StoreField(string name, SymbolicSlot value)
        {
            if (IsConstAfterSimplification() || value.IsConstAfterSimplification())
            {
                return;
            }

            MaterializeFields();
            value.MaterializeFields();

            if (IsConstAfterSimplification() || value.IsConstAfterSimplification())
            {
                return;
            }

            var targetEntity = SymbolicReference.Merge(value.entities);

            for (int i = 0; i < entities.Length; i++)
            {
                var entity = entities[i];
                entity.StoreField(name, targetEntity);
            }
        }
Beispiel #7
0
 public bool IsVisited(SymbolicReference item) => IsVisited(item.entity);
Beispiel #8
0
 public void Visit(SymbolicReference item) => Visit(item.entity);
Beispiel #9
0
        private static void Merge(SymbolicSlot first, SymbolicSlot second, SymbolicSlot result)
        {
            if (first.fields == null && second.fields == null)
            {
                if (first.entities != null && second.entities != null)
                {
                    Debug.Assert(first.entities.Length > 0 && second.entities.Length > 0);
                    Debug.Assert(first.values == null && second.values == null);

                    var newEntities = new SymbolicReference[first.entities.Length + second.entities.Length];
                    Array.Copy(first.entities, newEntities, first.entities.Length);
                    Array.Copy(second.entities, 0, newEntities, first.entities.Length, second.entities.Length);
                    result.Reset(newEntities, null, null);
                    return;
                }

                if (first.entities != null)
                {
                    Debug.Assert(first.entities.Length > 0 && second.entities == null);
                    Debug.Assert(first.values == null && second.values != null);

                    var newValues = new SymbolicSlot[second.values.Length + 1];
                    Array.Copy(second.values, newValues, second.values.Length);
                    newValues[newValues.Length - 1] = new SymbolicSlot(first.entities, null, null);
                    result.Reset(null, newValues, null);
                    return;
                }

                if (second.entities != null)
                {
                    Debug.Assert(first.entities == null && second.entities.Length > 0);
                    Debug.Assert(first.values != null && second.values == null);

                    var newValues = new SymbolicSlot[first.values.Length + 1];
                    Array.Copy(first.values, newValues, first.values.Length);
                    newValues[newValues.Length - 1] = new SymbolicSlot(second.entities, null, null);
                    result.Reset(null, newValues, null);
                    return;
                }

                {
                    Debug.Assert(first.entities == null && second.entities == null);
                    Debug.Assert(first.values != null && second.values != null);
                    Debug.Assert(first.values.Length > 0 && second.values.Length > 0);

                    var newValues = new SymbolicSlot[first.values.Length + second.values.Length];
                    Array.Copy(first.values, newValues, first.values.Length);
                    Array.Copy(second.values, 0, newValues, first.values.Length, second.values.Length);
                    result.Reset(null, newValues, null);
                    return;
                }
            }

            if (first.fields == null && first.values != null)
            {
                Debug.Assert(first.entities == null);
                Debug.Assert(first.values.Length > 0);

                var newValues = new SymbolicSlot[first.values.Length + 1];
                Array.Copy(first.values, newValues, first.values.Length);
                newValues[newValues.Length - 1] = second;
                result.Reset(null, newValues, null);
                return;
            }

            if (second.fields == null && second.values != null)
            {
                Debug.Assert(second.entities == null);
                Debug.Assert(second.values.Length > 0);

                var newValues = new SymbolicSlot[second.values.Length + 1];
                Array.Copy(second.values, newValues, second.values.Length);
                newValues[newValues.Length - 1] = first;
                result.Reset(null, newValues, null);
                return;
            }

            result.Reset(null, new [] { first, second }, null);
        }
Beispiel #10
0
 public SymbolicSlot(SymbolicReference entity)
 {
     entities = new [] { entity };
 }