public ReturnTracerResult Verify() { var firstLabel = Marks.OrderBy(o => o.Value).First().Key; var firstIx = Marks[firstLabel]; var path = new LinqList <Label>(); path.Add(firstLabel); var pathLookup = new LinqHashSet <Label>(path.AsEnumerable()); return(TraceFrom(firstIx, path, pathLookup)); }
public RollingVerifier(Label beginAt, bool strictBranchVerification) { UsesStrictBranchVerification = strictBranchVerification; RestoreOnMark = new LinqDictionary <Label, LinqList <VerifiableTracker> >(); RestoreStacksOnMark = new LinqDictionary <Label, LinqList <LinqStack <LinqList <TypeOnStack> > > >(); VerifyFromLabel = new LinqDictionary <Label, LinqList <VerifiableTracker> >(); StacksAtLabels = new LinqDictionary <Label, SigilTuple <bool, LinqStack <LinqList <TypeOnStack> > > >(); ExpectedStacksAtLabels = new LinqDictionary <Label, LinqList <SigilTuple <bool, LinqStack <LinqList <TypeOnStack> > > > >(); MustBeEmptyWhenBranchedTo = new LinqHashSet <Label>(); EmptyCurrentScope(); Add(new VerifiableTracker(beginAt), new LinqStack <LinqList <TypeOnStack> >()); }
private ReturnTracerResult TraceFrom(int startAt, LinqList <Label> path, LinqHashSet <Label> pathLookup) { ReturnTracerResult cached; if (Cache.TryGetValue(startAt, out cached)) { return(cached); } var nextBranches = Branches.Where(b => b.Item3 >= startAt).GroupBy(g => g.Item3).OrderBy(x => x.Key).FirstOrDefault(); var orReturn = Returns.Where(ix => ix >= startAt && (nextBranches != null ? ix < nextBranches.Key : true)).Count(); var orThrow = Throws.Where(ix => ix >= startAt && (nextBranches != null ? ix < nextBranches.Key : true)).Count(); if (orReturn != 0) { Cache[startAt] = cached = ReturnTracerResult.Success(); return(cached); } if (orThrow != 0) { Cache[startAt] = cached = ReturnTracerResult.Success(); return(cached); } if (nextBranches == null) { Cache[startAt] = cached = ReturnTracerResult.Failure(path); return(cached); } var ret = new LinqList <ReturnTracerResult>(); foreach (var nextBranch in nextBranches) { if (pathLookup.Contains(nextBranch.Item2)) { Cache[startAt] = cached = ReturnTracerResult.Success(); ret.Add(cached); continue; } var branchOp = nextBranch.Item1; var branchTo = Marks[nextBranch.Item2]; var removeFromPathAt = path.Count; path.Add(nextBranch.Item2); pathLookup.Add(nextBranch.Item2); var fromFollowingBranch = TraceFrom(branchTo, path, pathLookup); path.RemoveAt(removeFromPathAt); pathLookup.Remove(nextBranch.Item2); if (IsUnconditionalBranch(branchOp)) { Cache[startAt] = cached = fromFollowingBranch; //return cached; ret.Add(cached); continue; } var fromFallingThrough = TraceFrom(startAt + 1, path, pathLookup); Cache[startAt] = cached = ReturnTracerResult.Combo(fromFallingThrough, fromFollowingBranch); ret.Add(cached); } Cache[startAt] = cached = ReturnTracerResult.Combo(ret.ToArray()); return(cached); }
private static void UpdateStack(LinqStack <LinqList <TypeOnStack> > stack, InstructionAndTransitions wrapped, bool isBaseless) { var legal = wrapped.Transitions; var instr = wrapped.Instruction; var legalSize = 0; legal.Each( t => { legalSize += t.PushedToStack.Length; if (t.Before != null) { t.Before(stack, isBaseless); } } ); if (legal.Any(l => LinqAlternative.Any(l.PoppedFromStack, u => u == TypeOnStack.Get <PopAllType>()))) { if (instr.HasValue) { for (var i = 0; i < stack.Count; i++) { var ix = stack.Count - i - 1; stack.ElementAt(i).Each(y => y.Mark(wrapped, ix)); } } stack.Clear(); } else { var toPop = legal.First().PoppedCount; for (var j = 0; j < toPop && stack.Count > 0; j++) { var popped = stack.Pop(); if (instr.HasValue) { var ix = toPop - j - 1; popped.Each(y => y.Mark(wrapped, ix)); } } } var toPush = new LinqList <TypeOnStack>(legalSize); var pushed = new LinqHashSet <TypeOnStack>(); for (var i = 0; i < legal.Count; i++) { foreach (var p in legal[i].PushedToStack) { if (pushed.Contains(p)) { continue; } toPush.Add(p); pushed.Add(p); } } if (toPush.Count > 0) { stack.Push(toPush); } }