Exemple #1
0
        public virtual VerificationResult Mark(Label label)
        {
            // This is, effectively, "follows an unconditional branch & hasn't been seen before"
            if (MarkCreatesNewVerifier && UsesStrictBranchVerification && !ExpectedStacksAtLabels.ContainsKey(label))
            {
                MustBeEmptyWhenBranchedTo.Add(label);
            }

            if (CurrentlyInScope.Count > 0)
            {
                StacksAtLabels[label] = GetCurrentStack();

                var verify = CheckStackMatches(label);
                if (verify != null)
                {
                    return(verify);
                }
            }

            if (MarkCreatesNewVerifier)
            {
                var newVerifier = new VerifiableTracker(label, baseless: true);
                Add(newVerifier, new LinqStack <LinqList <TypeOnStack> >());
                MarkCreatesNewVerifier = false;
            }

            LinqList <VerifiableTracker> restore;

            if (RestoreOnMark.TryGetValue(label, out restore))
            {
                // don't copy, we want the *exact* same verifiers restore here
                AddRange(restore, RestoreStacksOnMark[label]);
                RestoreOnMark.Remove(label);
                RestoreStacksOnMark.Remove(label);
            }

            var based = CurrentlyInScope.FirstOrDefault(f => !f.IsBaseless);

            based = based ?? CurrentlyInScope.First();

            var fromLabel = new VerifiableTracker(label, based.IsBaseless, based);
            var fromStack = CurrentlyInScopeStacks[CurrentlyInScope.IndexOf(based)];

            Add(fromLabel, CopyStack(fromStack));

            if (!VerifyFromLabel.ContainsKey(label))
            {
                VerifyFromLabel[label] = new LinqList <VerifiableTracker>();
            }

            VerifyFromLabel[label].Add(fromLabel);

            RemoveUnnecessaryVerifiers();

            return(VerificationResult.Successful());
        }
Exemple #2
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());
        }
Exemple #3
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);
        }
Exemple #4
0
        private VerificationResult CheckStackMatches(Label atLabel)
        {
            if (!StacksAtLabels.ContainsKey(atLabel) || !ExpectedStacksAtLabels.ContainsKey(atLabel))
            {
                return(null);
            }

            var actual       = StacksAtLabels[atLabel];
            var expectations = ExpectedStacksAtLabels[atLabel];

            foreach (var exp in expectations.AsEnumerable())
            {
                var mismatch = CompareStacks(atLabel, actual, exp);
                if (mismatch != null)
                {
                    return(mismatch);
                }
            }

            return(null);
        }