private static LinqDictionary <int, Local> GetInScopeAt(LinqList <Local> allLocals, int ix)
 {
     return
         (allLocals
          .Where(
              l =>
              l.DeclaredAtIndex <= ix &&
              (l.ReleasedAtIndex == null || l.ReleasedAtIndex > ix)
              ).ToDictionary(d => (int)d.Index, d => d));
 }
Exemple #2
0
        private int FindStackFailureIndex(LinqStack <LinqList <TypeOnStack> > types, IEnumerable <StackTransition> ops, out IEnumerable <TypeOnStack> expected)
        {
            var stillLegal = new LinqList <StackTransition>(ops);

            for (var i = 0; i < types.Count; i++)
            {
                var actuallyIs = types.ElementAt(i);

                var legal = stillLegal.Where(l => actuallyIs.Any(a => l.PoppedFromStack[i].IsAssignableFrom(a))).ToList();

                if (legal.Count == 0)
                {
                    expected = stillLegal.Select(l => l.PoppedFromStack[i]).Distinct().ToList().AsEnumerable();
                    return(i);
                }

                stillLegal = new LinqList <StackTransition>(legal);
            }

            throw new Exception("Shouldn't be possible");
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        // Looks at CurrentlyInScope and removes any verifiers that are not necessary going forward
        private void RemoveUnnecessaryVerifiers()
        {
            // if anything's rooted, we only need one of them (since the IL stream being currently valid means they must in the future)
            var rooted = CurrentlyInScope.Where(c => !c.IsBaseless && c.CanBePruned).ToList();

            if (rooted.Count >= 2)
            {
                for (var i = 1; i < rooted.Count; i++)
                {
                    var toRemove = rooted[i];
                    var ix       = CurrentlyInScope.IndexOf(toRemove);

                    RemoveAt(ix);
                }
            }

            // remove any verifiers that have duplicate terminal stack states; we know that another verifier will do just as well, no need to verify the whole instruction stream again
            for (var i = CurrentlyInScope.Count - 1; i >= 0; i--)
            {
                var curStack = CurrentlyInScopeStacks[i];

                var otherMatch =
                    CurrentlyInScopeStacks
                    .Select(
                        (cx, ix) =>
                {
                    if (ix == i)
                    {
                        return(-1);
                    }

                    if (curStack.Count != cx.Count)
                    {
                        return(-1);
                    }

                    if (!CurrentlyInScope[ix].CanBePruned)
                    {
                        return(-1);
                    }

                    for (var j = 0; j < curStack.Count; j++)
                    {
                        var curFrame = curStack.ElementAt(j);
                        var cxFrame  = cx.ElementAt(j);

                        if (curFrame.Count != cxFrame.Count)
                        {
                            return(-1);
                        }

                        curFrame = curFrame.OrderBy(_ => _).ToList();
                        cxFrame  = cxFrame.OrderBy(_ => _).ToList();

                        for (var k = 0; k < curFrame.Count; k++)
                        {
                            var curT = curFrame[k];
                            var cxT  = cxFrame[k];

                            if (curT != cxT)
                            {
                                return(-1);
                            }
                        }
                    }

                    return(ix);
                }
                        ).Where(x => x != -1).OrderByDescending(_ => _).ToList();

                foreach (var o in otherMatch.AsEnumerable())
                {
                    RemoveAt(o);

                    if (o < i)
                    {
                        i--;
                    }
                }
            }
        }