Beispiel #1
0
        private void Add(VerifiableTracker tracker, LinqStack<LinqList<TypeOnStack>> stack)
        {
            CurrentlyInScope.Add(tracker);
            CurrentlyInScopeStacks.Add(stack);

            if (CurrentlyInScope.Count != CurrentlyInScopeStacks.Count)
            {
                throw new Exception();
            }
        }
Beispiel #2
0
        public VerifiableTracker(Label beganAt, bool baseless = false, VerifiableTracker createdFrom = null)
        {
            IsBaseless = baseless;
            BeganAt = beganAt;

            MarkedLabelsAtTransitions[beganAt] = 0;

            if (createdFrom != null)
            {
                StartingStack = GetStack(createdFrom);
            }
        }
        public static VerificationResult FailureStackMismatch(VerifiableTracker verifier, LinqStack<LinqList<TypeOnStack>> expected, LinqStack<LinqList<TypeOnStack>> incoming)
        {
            return
                new VerificationResult
                {
                    Success = false,

                    Verifier = verifier.Clone(),

                    IsStackMismatch = true,
                    ExpectedStack = expected,
                    IncomingStack = incoming
                };
        }
        public static VerificationResult FailureUnderflow(VerifiableTracker verifier, int transitionIndex, int expectedSize, LinqStack<LinqList<TypeOnStack>> stack)
        {
            return
                new VerificationResult
                {
                    Success = false,

                    Verifier = verifier.Clone(),
                    TransitionIndex = transitionIndex,

                    IsStackUnderflow = true,
                    ExpectedStackSize = expectedSize,
                    Stack = stack
                };
        }
Beispiel #5
0
        private static void PrintStack(LinqStack <LinqList <TypeOnStack> > stack, StringBuilder sb, string mark = null, int?markAt = null)
        {
            if (stack.Count == 0)
            {
                sb.AppendLine("--empty--");
                return;
            }

            for (var i = 0; i < stack.Count; i++)
            {
                var asStr =
                    string.Join(", or",
                                stack.ElementAt(i).Select(s => s.ToString()).ToArray()
                                );

                if (i == markAt)
                {
                    asStr += "  " + mark;
                }

                sb.AppendLine(asStr);
            }
        }
Beispiel #6
0
        private LinqStack<LinqList<TypeOnStack>> CopyStack(LinqStack<LinqList<TypeOnStack>> toCopy)
        {
            var ret = new LinqStack<LinqList<TypeOnStack>>(toCopy.Count);

            for (var i = toCopy.Count - 1; i >= 0; i--)
            {
                ret.Push(toCopy.ElementAt(i));
            }

            return ret;
        }
        private static LinqStack<LinqList<TypeOnStack>> GetStack(VerifiableTracker tracker)
        {
            var retStack = new LinqStack<LinqList<TypeOnStack>>(tracker.StartingStack.Reverse());

            foreach (var t in tracker.Transitions.AsEnumerable())
            {
                UpdateStack(retStack, t, tracker.IsBaseless);
            }

            return retStack;
        }
        // Returns the current stack *if* it can be inferred down to single types *and* is either based or verifiable to the given depth
        public LinqStack<TypeOnStack> InferStack(int ofDepth)
        {
            var res = CollapseAndVerify();

            if(res.Stack.Count < ofDepth) return null;

            var ret = new LinqStack<TypeOnStack>();
            for (var i = ofDepth - 1; i >= 0; i--)
            {
                var couldBe = res.Stack.ElementAt(i);

                if (couldBe.Count() > 1) return null;

                ret.Push(couldBe.Single());
            }

            return ret;
        }
        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");
        }
Beispiel #10
0
        public VerificationResult CollapseAndVerify()
        {
            var runningStack = CachedVerifyStack ?? new LinqStack<LinqList<TypeOnStack>>(StartingStack.Reverse());

            int i = CachedVerifyIndex ?? 0;

            for (; i < Transitions.Count; i++)
            {
                var wrapped = Transitions[i];
                var ops = wrapped.Transitions;

                if(ops.Any(o => o.StackSizeMustBe.HasValue))
                {
                    if (ops.Count > 1)
                    {
                        throw new Exception("Shouldn't have multiple 'must be size' transitions at the same point");
                    }

                    var doIt = ops[0];

                    if(doIt.StackSizeMustBe != runningStack.Count)
                    {
                        return VerificationResult.FailureStackSize(this, i, doIt.StackSizeMustBe.Value);
                    }
                }

                var legal = GetLegalTransitions(ops, runningStack);

                if (legal.Count == 0)
                {
                    var wouldPop = ops.GroupBy(g => g.PoppedFromStack.Length).Single().Key;

                    if (runningStack.Count < wouldPop)
                    {
                        return VerificationResult.FailureUnderflow(this, i, wouldPop, runningStack);
                    }

                    IEnumerable<TypeOnStack> expected;
                    var stackI = FindStackFailureIndex(runningStack, ops.AsEnumerable(), out expected);

                    return VerificationResult.FailureTypeMismatch(this, i, stackI, expected, runningStack);
                }

                if (legal.GroupBy(g => new { a = g.PoppedCount, b = g.PushedToStack.Length }).Count() > 1)
                {
                    throw new Exception("Shouldn't be possible; legal transitions should have same push/pop #s");
                }

                // No reason to do all this work again
                Transitions[i] = new InstructionAndTransitions(wrapped.Instruction, wrapped.InstructionIndex, legal);

                bool popAll = legal.Any(l => ((LinqArray<TypeOnStack>)l.PoppedFromStack).Contains(TypeOnStack.Get<PopAllType>()));
                if (popAll && legal.Count() != 1)
                {
                    throw new Exception("PopAll cannot coexist with any other transitions");
                }

                if(!popAll)
                {
                    var toPop = legal.First().PoppedCount;

                    if (toPop > runningStack.Count && !IsBaseless)
                    {
                        return VerificationResult.FailureUnderflow(this, i, toPop, runningStack);
                    }
                }

                bool isDuplicate = legal.Any(l => l.IsDuplicate);
                if (isDuplicate && legal.Count() > 1)
                {
                    throw new Exception("Duplicate must be only transition");
                }

                if (isDuplicate)
                {
                    if (!IsBaseless && runningStack.Count == 0) return VerificationResult.FailureUnderflow(this, i, 1, runningStack);

                    var toPush = runningStack.Count > 0 ? runningStack.Peek() : new LinqList<TypeOnStack>(new[] { TypeOnStack.Get<WildcardType>() });

                    UpdateStack(runningStack, new InstructionAndTransitions(wrapped.Instruction, wrapped.InstructionIndex, new LinqList<StackTransition>(new[] { new StackTransition(new TypeOnStack[0], toPush.AsEnumerable()) })), IsBaseless);
                }
                else
                {
                    UpdateStack(runningStack, new InstructionAndTransitions(wrapped.Instruction, wrapped.InstructionIndex, legal), IsBaseless);
                }
            }

            CachedVerifyIndex = i;
            CachedVerifyStack = runningStack;

            return VerificationResult.Successful(this, runningStack);
        }
Beispiel #11
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;
        }
Beispiel #12
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);
            }
        }
 public static VerificationResult Successful(VerifiableTracker verifier, LinqStack<LinqList<TypeOnStack>> stack)
 {
     return new VerificationResult { Success = true, Stack = stack, Verifier = verifier };
 }
        public static VerificationResult FailureTypeMismatch(VerifiableTracker verifier, int transitionIndex, int stackIndex, IEnumerable<TypeOnStack> expectedTypes, LinqStack<LinqList<TypeOnStack>> stack)
        {
            return
                new VerificationResult
                {
                    Success = false,

                    Verifier = verifier.Clone(),
                    TransitionIndex = transitionIndex,

                    IsTypeMismatch = true,
                    StackIndex = stackIndex,
                    ExpectedAtStackIndex = LinqEnumerable<TypeOnStack>.For(expectedTypes),
                    Stack = stack
                };
        }
        private static void PrintStack(LinqStack<LinqList<TypeOnStack>> stack, StringBuilder sb, string mark = null, int? markAt = null)
        {
            if (stack.Count == 0)
            {
                sb.AppendLine("--empty--");
                return;
            }

            for (var i = 0; i < stack.Count; i++)
            {
                var asStr =
                    string.Join(", or",
                        stack.ElementAt(i).Select(s => s.ToString()).ToArray()
                    );

                if (i == markAt)
                {
                    asStr += "  " + mark;
                }

                sb.AppendLine(asStr);
            }
        }