public void Match(SymbolicReference.ApplyingContext context, SymbolicReference rootSummaryEntity) { if (IsConstAfterSimplification()) { return; } MaterializeFields(); if (IsConstAfterSimplification()) { return; } //MergeEntities() rootSummaryEntity.Match(context, entities[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]); }
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); } }
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); }
// 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 }; }
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); } }
public bool IsVisited(SymbolicReference item) => IsVisited(item.entity);
public void Visit(SymbolicReference item) => Visit(item.entity);
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); }
public SymbolicSlot(SymbolicReference entity) { entities = new [] { entity }; }