Ejemplo n.º 1
0
        internal VerifiableTracker Concat(VerifiableTracker other)
        {
            var branchTo   = BranchesAtTransitions.ContainsKey(other.BeganAt) ? BranchesAtTransitions[other.BeganAt] : Transitions.Count;
            var shouldTake = branchTo != Transitions.Count;

            var trans = new LinqList <InstructionAndTransitions>(branchTo + other.Transitions.Count);

            if (shouldTake)
            {
                for (var i = 0; i < branchTo; i++)
                {
                    trans.Add(Transitions[i]);
                }
            }
            else
            {
                trans.AddRange(Transitions);
            }

            trans.AddRange(other.Transitions);

            var canReuseCache = branchTo == Transitions.Count && IsBaseless && CachedVerifyStack != null;

            var ret =
                new VerifiableTracker(BeganAt, IsBaseless)
            {
                StartingStack     = new LinqStack <LinqList <TypeOnStack> >(StartingStack.Reverse().AsEnumerable()),
                Transitions       = trans,
                CachedVerifyStack = canReuseCache ? new LinqStack <LinqList <TypeOnStack> >(CachedVerifyStack.Reverse().AsEnumerable()) : null,
                CachedVerifyIndex = canReuseCache ? CachedVerifyIndex : null
            };

            return(ret);
        }
Ejemplo n.º 2
0
        public static LinqRoot <IGrouping <K, T> > GroupBy <T, K>(IEnumerable <T> e, SigilFunc <T, K> p)
        {
            if (e == null)
            {
                throw new ArgumentNullException("e");
            }
            if (p == null)
            {
                throw new ArgumentNullException("p");
            }

            var ret     = new LinqList <IGrouping <K, T> >();
            var gLookup = new Dictionary <K, Grouping <K, T> >();

            using (var i = e.GetEnumerator())
            {
                while (i.MoveNext())
                {
                    var             k = p(i.Current);
                    Grouping <K, T> g;

                    if (!gLookup.TryGetValue(k, out g))
                    {
                        gLookup[k] = g = new Grouping <K, T>(k);

                        ret.Add(g);
                    }

                    g.Add(i.Current);
                }
            }

            return(ret);
        }
Ejemplo n.º 3
0
        private void Add(VerifiableTracker tracker, LinqStack <LinqList <TypeOnStack> > stack)
        {
            CurrentlyInScope.Add(tracker);
            CurrentlyInScopeStacks.Add(stack);

            if (CurrentlyInScope.Count != CurrentlyInScopeStacks.Count)
            {
                throw new Exception();
            }
        }
Ejemplo n.º 4
0
        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));
        }
Ejemplo n.º 5
0
        public virtual VerificationResult UnconditionalBranch(Label to)
        {
            // If we've recorded elsewhere that the label we're branching to *must* receive
            // an empty stack, then inject a transition that expects that
            if (MustBeEmptyWhenBranchedTo.Contains(to))
            {
                var trans = new LinqList <StackTransition>();
                trans.Add(new StackTransition(sizeMustBe: 0));

                var stackIsEmpty = Transition(new InstructionAndTransitions(null, null, trans));

                if (stackIsEmpty != null)
                {
                    return(stackIsEmpty);
                }
            }

            var intoVerified = VerifyBranchInto(to);

            if (intoVerified != null)
            {
                return(intoVerified);
            }

            UpdateRestores(to);

            if (!RestoreOnMark.ContainsKey(to))
            {
                RestoreOnMark[to]       = new LinqList <VerifiableTracker>();
                RestoreStacksOnMark[to] = new LinqList <LinqStack <LinqList <TypeOnStack> > >();
            }

            if (!ExpectedStacksAtLabels.ContainsKey(to))
            {
                ExpectedStacksAtLabels[to] = new LinqList <SigilTuple <bool, LinqStack <LinqList <TypeOnStack> > > >();
            }
            ExpectedStacksAtLabels[to].Add(GetCurrentStack());

            var verify = CheckStackMatches(to);

            if (verify != null)
            {
                return(verify);
            }

            RestoreOnMark[to].AddRange(CurrentlyInScope);
            RestoreStacksOnMark[to].AddRange(CurrentlyInScopeStacks);

            EmptyCurrentScope();
            MarkCreatesNewVerifier = true;

            return(VerificationResult.Successful());
        }
Ejemplo n.º 6
0
        public VerificationResult Transition(InstructionAndTransitions legalTransitions)
        {
            Transitions.Add(legalTransitions);
            var ret = CollapseAndVerify();

            // revert!
            if (!ret.Success)
            {
                Transitions.RemoveAt(Transitions.Count - 1);
            }

            return(ret);
        }
Ejemplo n.º 7
0
        private static LinqList <Type> GetBases(Type t)
        {
            if (TypeHelpers.IsValueType(t))
            {
                return(new LinqList <Type>());
            }

            var ret = new LinqList <Type>();

            t = TypeHelpers.GetBaseType(t);

            while (t != null)
            {
                ret.Add(t);
                t = TypeHelpers.GetBaseType(t);
            }

            return(ret);
        }
Ejemplo n.º 8
0
        private static LinqList <Type> GetBases(Type t)
        {
            if (t.IsValueType)
            {
                return(new LinqList <Type>());
            }

            var ret = new LinqList <Type>();

            t = t.BaseType;

            while (t != null)
            {
                ret.Add(t);
                t = t.BaseType;
            }

            return(ret);
        }
Ejemplo n.º 9
0
        public virtual VerificationResult Transition(InstructionAndTransitions legalTransitions)
        {
            var stacks = new LinqList <LinqStack <LinqList <TypeOnStack> > >();

            VerificationResult last = null;

            foreach (var x in CurrentlyInScope.AsEnumerable())
            {
                var inner = x.Transition(legalTransitions);

                if (!inner.Success)
                {
                    return(inner);
                }

                last = inner;
                stacks.Add(CopyStack(inner.Stack));
            }

            CurrentlyInScopeStacks = stacks;

            return(last);
        }
Ejemplo n.º 10
0
        public void Emit(OpCode op)
        {
            InstructionSizes.Add(() => InstructionSize.Get(op));

            LengthCache.Clear();

            Buffer.Add(
                (il, logOnly, log) =>
            {
                if (!logOnly)
                {
                    il.Emit(op);
                }

                if (ExtensionMethods.IsPrefix(op))
                {
                    log.Append(op.ToString());
                }
                else
                {
                    log.AppendLine(op.ToString());
                }
            }
                );

            TraversableBuffer.Add(new BufferedILInstruction {
                IsInstruction = op
            });

            Operations.Add(new Operation <DelegateType> {
                OpCode = op, Parameters = new object[0]
            });
        }
Ejemplo n.º 11
0
        public void Insert(int ix, OpCode op)
        {
            if (ix < 0 || ix > Buffer.Count)
            {
                throw new ArgumentOutOfRangeException("ix", "Expected value between 0 and " + Buffer.Count);
            }

            LengthCache.Clear();

            InstructionSizes.Insert(ix, () => InstructionSize.Get(op));

            Buffer.Insert(
                ix,
                (il, logOnly, log) =>
            {
                if (!logOnly)
                {
                    il.Emit(op);
                }

                if (ExtensionMethods.IsPrefix(op))
                {
                    log.Append(op.ToString());
                }
                else
                {
                    log.AppendLine(op.ToString());
                }
            }
                );

            TraversableBuffer.Insert(
                ix,
                new BufferedILInstruction
            {
                IsInstruction = op
            }
                );

            Operations.Add(new Operation <DelegateType> {
                OpCode = op, Parameters = new object[0]
            });
        }
Ejemplo n.º 12
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);
        }
Ejemplo n.º 13
0
        private LinqList <StackTransition> GetLegalTransitions(LinqList <StackTransition> ops, LinqStack <LinqList <TypeOnStack> > runningStack)
        {
            var ret = new LinqList <StackTransition>(ops.Count);

            for (var i = 0; i < ops.Count; i++)
            {
                var w = ops[i];

                if (LinqAlternative.All(w.PoppedFromStack, u => u == TypeOnStack.Get <PopAllType>()))
                {
                    ret.Add(w);
                    continue;
                }

                var onStack = runningStack.Peek(IsBaseless, w.PoppedCount);

                if (onStack == null)
                {
                    continue;
                }

                if (LinqAlternative.Any(w.PushedToStack, p => p == TypeOnStack.Get <SamePointerType>()))
                {
                    if (w.PushedToStack.Length > 1)
                    {
                        throw new Exception("SamePointerType can be only product of a transition which contains it");
                    }

                    var shouldBePointer = LinqAlternative.SelectMany(onStack, p => p.Where(x => x.IsPointer || x == TypeOnStack.Get <WildcardType>()).AsEnumerable()).Distinct().ToList();

                    if (shouldBePointer.Count == 0)
                    {
                        continue;
                    }
                    w = new StackTransition(w.PoppedFromStack, new [] { shouldBePointer.Single() });
                }

                if (LinqAlternative.Any(w.PushedToStack, p => p == TypeOnStack.Get <SameByRefType>()))
                {
                    if (w.PushedToStack.Length > 1)
                    {
                        throw new Exception("SameByRefType can be only product of a transition which contains it");
                    }

                    var shouldBeByRef = LinqAlternative.SelectMany(onStack, p => p.Where(x => x.IsReference || x == TypeOnStack.Get <WildcardType>()).AsEnumerable()).Distinct().ToList();

                    if (shouldBeByRef.Count == 0)
                    {
                        continue;
                    }
                    w = new StackTransition(w.PoppedFromStack, new[] { shouldBeByRef.Single() });
                }

                bool outerContinue = false;

                for (var j = 0; j < w.PoppedCount; j++)
                {
                    var shouldBe   = w.PoppedFromStack[j];
                    var actuallyIs = onStack[j];

                    if (!actuallyIs.Any(a => shouldBe.IsAssignableFrom(a)))
                    {
                        outerContinue = true;
                        break;
                    }
                }

                if (outerContinue)
                {
                    continue;
                }

                ret.Add(w);
            }

            return(ret);
        }
Ejemplo n.º 14
0
        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);
            }
        }