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); }
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); }
private void Add(VerifiableTracker tracker, LinqStack <LinqList <TypeOnStack> > stack) { CurrentlyInScope.Add(tracker); CurrentlyInScopeStacks.Add(stack); if (CurrentlyInScope.Count != CurrentlyInScopeStacks.Count) { throw new Exception(); } }
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 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()); }
public VerificationResult Transition(InstructionAndTransitions legalTransitions) { Transitions.Add(legalTransitions); var ret = CollapseAndVerify(); // revert! if (!ret.Success) { Transitions.RemoveAt(Transitions.Count - 1); } return(ret); }
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); }
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); }
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); }
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] }); }
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] }); }
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 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); }
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); } }