/// <summary> /// Adds a monitored field to the database. Updates two kinds of hashmaps /// a. Field to Method mapper, which gives what the methods modifying a given field /// b. Method to Field mapper, which gives what fields are modified by each method (later used to identify a minimized set of methods) /// </summary> /// <param name="tm"></param> /// <param name="method"></param> /// <param name="f"></param> /// <param name="indices"></param> /// <param name="fieldValue"></param> public void AddMonitoredField(TermManager tm, Method method, Field f, Term[] indices, Term fieldValue, Term initialValue) { string arrayIndex = ""; using (PexMeTermRewriter pexmeRewriter = new PexMeTermRewriter(tm)) { fieldValue = pexmeRewriter.VisitTerm(default(TVoid), fieldValue); //update the field value to accomodate array-type field //if (indices.Length == 0) //not an array-type field if (indices.Length == 1) //is an array-type field { arrayIndex = " at index of " + indices[0].UniqueIndex.ToString(); } if (initialValue != null) { initialValue = pexmeRewriter.VisitTerm(default(TVoid), initialValue); } } //Updating the method store MethodStore ms; if (!methodDic.TryGetValue(method, out ms)) { ms = new MethodStore(); ms.methodName = method; methodDic[method] = ms; } ms.WriteFields.Add(f); //TODO: Gather information of read fields //Updating the field store FieldStore fs; if (!fieldDic.TryGetValue(f, out fs)) { fs = new FieldStore(); fs.FieldName = f; fieldDic[f] = fs; } TypeEx declaringType; if (!method.TryGetDeclaringType(out declaringType)) { this.Log.LogError(WikiTopics.MissingWikiTopic, "monitorfield", "Failed to get the declaring type for the method " + method.FullName); return; } SafeSet <Method> writeMethods; if (!fs.WriteMethods.TryGetValue(declaringType, out writeMethods)) { writeMethods = new SafeSet <Method>(); fs.WriteMethods[declaringType] = writeMethods; } writeMethods.Add(method); var sb = new SafeStringBuilder(); var swriter = new TermSExpWriter(tm, new SafeStringWriter(sb), true, false); swriter.Write(fieldValue); sb.Append(arrayIndex); int value; if (tm.TryGetI4Constant(fieldValue, out value)) { int initialval; if (initialValue != null) { tm.TryGetI4Constant(initialValue, out initialval); } else { initialval = 0; } sb.Append(" constant value: " + value); if (f.Type.ToString() != "System.Boolean") { if (value < initialval) { fs.ModificationTypeDictionary[method] = FieldModificationType.DECREMENT; } else if (value > initialval) { fs.ModificationTypeDictionary[method] = FieldModificationType.INCREMENT; if (value == initialval + 1) { fs.PreciseModificationTypeDictionary[method] = FieldModificationType.INCREMENT_ONE; } } else { fs.ModificationTypeDictionary[method] = FieldModificationType.UNKNOWN; } } else { if (value == 0) { fs.ModificationTypeDictionary[method] = FieldModificationType.FALSE_SET; } else { fs.ModificationTypeDictionary[method] = FieldModificationType.TRUE_SET; } } } else if (tm.IsDefaultValue(fieldValue)) { if (initialValue != null && !tm.IsDefaultValue(initialValue)) { fs.ModificationTypeDictionary[method] = FieldModificationType.NULL_SET; } else { fs.ModificationTypeDictionary[method] = FieldModificationType.UNKNOWN; } sb.Append(" null reference "); } else { if (initialValue == null) { fs.ModificationTypeDictionary[method] = FieldModificationType.NON_NULL_SET; } else { fs.ModificationTypeDictionary[method] = FieldModificationType.UNKNOWN; } sb.Append(" not-null reference "); } fs.FieldValues.Add(sb.ToString()); }
/// <summary> /// Adds a monitored field to the database. Updates two kinds of hashmaps /// a. Field to Method mapper, which gives what the methods modifying a given field /// b. Method to Field mapper, which gives what fields are modified by each method (later used to identify a minimized set of methods) /// </summary> /// <param name="tm"></param> /// <param name="method"></param> /// <param name="f"></param> /// <param name="indices"></param> /// <param name="fieldValue"></param> public void AddMonitoredField(TermManager tm, Method method, Field f, Term[] indices, Term fieldValue, Term initialValue) { string arrayIndex = ""; using (PexMeTermRewriter pexmeRewriter = new PexMeTermRewriter(tm)) { fieldValue = pexmeRewriter.VisitTerm(default(TVoid), fieldValue); //update the field value to accomodate array-type field //if (indices.Length == 0) //not an array-type field if (indices.Length == 1) //is an array-type field { arrayIndex = " at index of " + indices[0].UniqueIndex.ToString(); } if(initialValue != null) initialValue = pexmeRewriter.VisitTerm(default(TVoid), initialValue); } //Updating the method store MethodStore ms; if(!methodDic.TryGetValue(method, out ms)) { ms = new MethodStore(); ms.methodName = method; methodDic[method] = ms; } ms.WriteFields.Add(f); //TODO: Gather information of read fields //Updating the field store FieldStore fs; if (!fieldDic.TryGetValue(f, out fs)) { fs = new FieldStore(); fs.FieldName = f; fieldDic[f] = fs; } TypeEx declaringType; if (!method.TryGetDeclaringType(out declaringType)) { this.Log.LogError(WikiTopics.MissingWikiTopic, "monitorfield", "Failed to get the declaring type for the method " + method.FullName); return; } SafeSet<Method> writeMethods; if (!fs.WriteMethods.TryGetValue(declaringType, out writeMethods)) { writeMethods = new SafeSet<Method>(); fs.WriteMethods[declaringType] = writeMethods; } writeMethods.Add(method); var sb = new SafeStringBuilder(); var swriter = new TermSExpWriter(tm, new SafeStringWriter(sb), true, false); swriter.Write(fieldValue); sb.Append(arrayIndex); int value; if (tm.TryGetI4Constant(fieldValue, out value)) { int initialval; if (initialValue != null) tm.TryGetI4Constant(initialValue, out initialval); else initialval = 0; sb.Append(" constant value: " + value); if (f.Type.ToString() != "System.Boolean") { if (value < initialval) fs.ModificationTypeDictionary[method] = FieldModificationType.DECREMENT; else if (value > initialval) { fs.ModificationTypeDictionary[method] = FieldModificationType.INCREMENT; if (value == initialval + 1) fs.PreciseModificationTypeDictionary[method] = FieldModificationType.INCREMENT_ONE; } else fs.ModificationTypeDictionary[method] = FieldModificationType.UNKNOWN; } else { if (value == 0) fs.ModificationTypeDictionary[method] = FieldModificationType.FALSE_SET; else fs.ModificationTypeDictionary[method] = FieldModificationType.TRUE_SET; } } else if (tm.IsDefaultValue(fieldValue)) { if (initialValue != null && !tm.IsDefaultValue(initialValue)) fs.ModificationTypeDictionary[method] = FieldModificationType.NULL_SET; else fs.ModificationTypeDictionary[method] = FieldModificationType.UNKNOWN; sb.Append(" null reference "); } else { if (initialValue == null) fs.ModificationTypeDictionary[method] = FieldModificationType.NON_NULL_SET; else fs.ModificationTypeDictionary[method] = FieldModificationType.UNKNOWN; sb.Append(" not-null reference "); } fs.FieldValues.Add(sb.ToString()); }