public VerificationResult Transition(InstructionAndTransitions legalTransitions) { Transitions.Add(legalTransitions); var ret = CollapseAndVerify(); // revert! if (!ret.Success) { Transitions.RemoveAt(Transitions.Count - 1); } return ret; }
public VerificationResult Transition(InstructionAndTransitions legalTransitions) { Transitions.Add(legalTransitions); var ret = CollapseAndVerify(); // revert! if (!ret.Success) { Transitions.RemoveAt(Transitions.Count - 1); } 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 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 override VerificationResult Transition(InstructionAndTransitions legalTransitions) { return VerificationResult.Successful(); }
/// <summary> /// Call to indicate that something on the stack was used /// as the #{index}'d (starting at 0) parameter to the {code} /// opcode. /// </summary> public void Mark(InstructionAndTransitions instr, int index) { UsedBy.Add(SigilTuple.Create(instr, index)); }
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); }
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 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)); }
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 override VerificationResult Transition(InstructionAndTransitions legalTransitions) { return(VerificationResult.Successful()); }