private ISymValue GetFieldAddress(NonNullChecker checker, ISymValue sourceobj, Field f, bool setFieldNullnessAccordingToType) { ISymValue loc = this.egraph[f, sourceobj]; if (!f.Type.IsValueType) { ISymValue val = this.egraph.TryLookup(ValueOf, loc); if (val == null) { // manifest and set abstract value according to type. // existential type: dont trust type if existential type is involved... we may do nothing // may assigning its own type. if (setFieldNullnessAccordingToType) { val = this.egraph[ValueOf, loc]; this.egraph[val] = FieldNullness(checker, f, this.typeSystem); } } } return loc; }
public bool IsFieldNull(NonNullChecker checker, Variable source, Field field) { ISymValue sourceobj; if (source != null) { sourceobj = Value(source); } else { sourceobj = Null; } ISymValue addr = GetFieldAddress(checker, sourceobj, field, true); ISymValue fieldValue = Value(addr); return this.IsNull(fieldValue); }
public void LoadFieldAddress(NonNullChecker checker, Variable source, Field field, Variable dest) { ISymValue destaddr = Address(dest); ISymValue sourceobj; if (source != null) { sourceobj = Value(source); } else { sourceobj = Null; } ISymValue addr = GetFieldAddress(checker, sourceobj, field, true); this.egraph[addr] = Lattice.AVal.NonNull; this.egraph[ValueOf, destaddr] = addr; }
public bool LoadField(NonNullChecker checker, Variable source, Field field, Variable dest, bool isDestExistentialDelayed) { ISymValue destAddr = Address(dest); ISymValue sourceobj; if (source != null) { if (source.Type.IsValueType) { sourceobj = Address(source); } else { sourceobj = Value(source); } } else { sourceobj = Null; } // existential delay ISymValue loc = GetFieldAddress(checker, sourceobj, field, !isDestExistentialDelayed); // end exitential delay CopyValue(destAddr, loc, field.Type); if (field.Type.IsValueType) { return true; } else { ISymValue val = this.egraph[ValueOf, destAddr]; if (IsNonNull(val)) return true; } if (isDestExistentialDelayed) { return false; } if (IsNonNullType(field.Type)) { return true; } else { return false; } }
public Lattice.AVal FieldNullness(NonNullChecker checker, Field field, TypeSystem ts){ if (IsNonNullType(field.Type)) { return Lattice.AVal.NonNull; } else if (field.Type != null && field.Type.IsValueType) { return Lattice.AVal.MayBeNull; } else { if (ts.FieldReadAsNonNull(checker.analyzer.CompilerOptions, field)) { // HACK HACK for now we assume fields of reference type are always non-null when read return Lattice.AVal.NonNull; } else { return Lattice.AVal.MayBeNull; } } }
/// <summary> /// Constructor. /// </summary> /// <param name="c"></param> public NonNullInstructionVisitor(NonNullChecker c) { NNChecker=c; ts=c.typeSystem; }
/// <summary> /// Entry point to check a method. /// </summary> /// <param name="t"></param> /// <param name="method"></param> public static INonNullInformation Check(TypeSystem t, Method method, Analyzer analyzer) { if(method==null) return null; NonNullChecker checker = new NonNullChecker(t, method, analyzer); ControlFlowGraph cfg = analyzer.GetCFG(method); if (cfg != null) { checker.nonNullEdgeInfo = new IFunctionalMap[cfg.BlockCount]; checker.Run(cfg, new NonNullState(t, analyzer.DelayInfo)); checker.OptimizeMethodBody(method); return checker; } return null; }
public NonNullOptimizer(NonNullChecker checker, System.Collections.Generic.Dictionary<ExpressionStatement, bool> eliminateCheck) { this.eliminateCheck = eliminateCheck; this.checker = checker; }