/// <summary> /// Jumps at given target if instance under conditionVariable is resolved as true. /// </summary> /// <param name="conditionVariable">Variable where condition is stored.</param> /// <param name="target">Target label.</param> public override void ConditionalJump(string conditionVariable, Label target) { var condition = getVariable(conditionVariable); var conditionalJump = new ConditionalJump(condition, target); emitInstruction(conditionalJump); }
public bool Optimize(ref List <Instruction> src) { foreach (int unu in ToBeCorrected) { src[unu].Emit = false; src[unu + 1].Emit = false; } // translate labels for (int i = 0; i < src.Count; i++) { if (src[i] is ConditionalJump) { ConditionalJump cjmp = src[i] as ConditionalJump; if (lbtranslate.ContainsKey(cjmp.DestinationLabel)) { cjmp.DestinationLabel = lbtranslate[cjmp.DestinationLabel]; src[i] = cjmp; } } else if (src[i] is ConditionalJump) { Jump jmp = src[i] as Jump; if (lbtranslate.ContainsKey(jmp.DestinationLabel)) { jmp.DestinationLabel = lbtranslate[jmp.DestinationLabel]; src[i] = jmp; } } } Optimizer.Optimizations += ToBeCorrected.Count; return(ToBeCorrected.Count > 0); }
public override void visit(ConditionalJump node) { if (Convert.ToBoolean(vm.ReturnVariable.getValue())) nextNode = node.getOnTrue(); else nextNode = node.getOnFalse(); }
private static Tree FlipConditionalJumpTargets(Node operation, ConditionalJump conditionalJump) { var newOperation = new UnaryOperation(operation, AST.UnaryOperationType.Not); var newControlFlow = new ConditionalJump(conditionalJump.FalseTarget, conditionalJump.TrueTarget); return(new Tree(newOperation, newControlFlow)); }
public IEnumerable <Instruction> Visit(ConditionalJump instruction) { var simplified = Visit(instruction.Condition); return(new List <Instruction>(simplified.Instructions) { new ConditionalJump(simplified.Expression, instruction.Target) }); }
public void Visit(ConditionalJump instruction) { _ProcessInvocations(instruction.Condition); var node = _cfg.RegisterInstruction(instruction); _ConnectWithPreviousNode(node); _cfg.AddEdge(node, _cfg.RegisterInstruction(instruction.Target)); _previousNode = node; }
public static CFGNode[] ConstructCFG(List <IInstruction> instructions) { CFGNode[] nodes = new CFGNode[instructions.Count]; int end = instructions.Count - 1; for (int i = end; i >= 0; i--) { nodes[i] = new CFGNode(instructions[i], i == end ? null : nodes[i + 1]); } // Map Labels to instructions Dictionary <LabelInstruction, CFGNode> labels = new Dictionary <LabelInstruction, CFGNode>(); List <LabelInstruction> activeLabels = new List <LabelInstruction>(); for (int i = 0; i < instructions.Count; i++) { if (instructions[i] is LabelInstruction label) { activeLabels.Add(label); } else if (activeLabels.Count > 0) { foreach (var activeLabel in activeLabels) { labels[activeLabel] = nodes[i]; } activeLabels.Clear(); } } foreach (var node in nodes) { LabelInstruction?target = node.Instruction switch { ConditionalJump conditionalJump => conditionalJump.Target, UnconditionalJump unconditionalJump => unconditionalJump.Target, _ => null, }; if (target != null && labels.TryGetValue(target.Value, out var successor)) { node.Successors.Add(successor); } } return(nodes); }
private static bool ContainsJumpFrom(List <ConditionalJump> list, ConditionalJump jump) { int i = 0; int n = list.Count; for (; i < n; ++i) { ConditionalJump jumpToTest = list[i]; if (jumpToTest.pos == jump.pos) { return(true); } } return(false); }
public void NullTest() { InstructionTemplate nullTemplate = new NullTemplate(); var template = new RegisterReadTemplate(); var templates = new List <InstructionTemplate> { template, nullTemplate }; var root = new RegisterRead(new VirtualRegister()); var trueTarget = this.labelFactory.GetLabel(new Tree(new UnitImmediateValue(), new UnconditionalJump(null))); var controlFlow = new ConditionalJump(trueTarget, null); var tree = new Tree(root, controlFlow); var selector = new InstructionSelector(templates); var ins = selector.GetInstructions(tree); Assert.AreEqual(2, ins.Count()); }
private IEnumerable <NasmInstruction> CompileInstruction(int i, IInstruction instruction) { yield return(NasmInstruction.Comment(instruction.ToString())); yield return(NasmInstruction.Comment("In = { " + string.Join(", ", RegisterAllocation.GetAllInAt(i)) + " }")); foreach (var inst in instruction switch { UnaryComputationAssignment inst => CompileCore(inst), BinaryComputationAssignment inst => CompileCore(inst), ConditionalJump inst => CompileCore(inst), UnconditionalJump inst => CompileCore(inst), LabelInstruction inst => CompileCore(inst), CallInstruction inst => CompileCore(i, inst), ReturnInstruction inst => CompileCore(inst), ParameterQueryAssignment inst => CompileCore(inst), _ => throw new ArgumentException(nameof(instruction)) })
private static bool ContainsJumpFrom(List<ConditionalJump> list, ConditionalJump jump) { int i = 0; int n = list.Count; for (; i < n; ++i) { ConditionalJump jumpToTest = list[i]; if (jumpToTest.pos == jump.pos) return true; } return false; }
public static U30 CalcMaxStack(byte[] code) { ClearFlags(); uint i = 0; uint n = (uint)code.Length; int stack = 0; int maxStack = 0; bool corrupt = false; uint j = 0; List<ConditionalJump> jumps = new List<ConditionalJump>(); List<uint> unconditionalJumps = new List<uint>(); ConditionalJump cj; int jumpIndex = 0; do { while (i < n) { AVM2Command cmd = null; try { cmd = Translator.ToCommand(code[i++]); } catch (Exception) { DebugUtil.DumpOpUntilError(code); throw new Exception(String.Format("Can not translate {0} correct at {1}.", code[i - 1], i-1)); } if (null == cmd) throw new Exception(); i += cmd.ReadParameters(code, i); // There are a couple of opcodes marked "incorrect" with a comment. // The explanation is: If the index in the multiname array is a RTQName // there could be a namspace and/or namespace set on the stack as well // that would be popped. // // We do not take that in account here - in the worst case that a namespace // and namespace set is present it could add +2 to the max sack if the // stack is greater than the one we already have. // // In the calculation of the possible max stack we will therefore only remove // the number of arguments from the current value. If there are no arguments // the opcode will be listed here as incorrect without any following calculation. // // Although this is not a problem for the Flash Player. It is just not very // nice... switch (cmd.OpCode) { case (byte)Op.Jump: if (!unconditionalJumps.Contains(i)) { unconditionalJumps.Add(i); i = (uint)((int)i + (int)((S24)cmd.Parameters[0]).Value); } else { //LOOP BAAM! } break; case (byte)Op.PushByte: case (byte)Op.PushDouble: case (byte)Op.PushFalse: case (byte)Op.PushInt: case (byte)Op.PushNamespace: case (byte)Op.PushNaN: case (byte)Op.PushNull: case (byte)Op.PushShort: case (byte)Op.PushString: case (byte)Op.PushTrue: case (byte)Op.PushUInt: case (byte)Op.PushUndefined: case (byte)Op.Dup: case (byte)Op.FindProperty://incorrect case (byte)Op.FindPropertyStrict://incorrect case (byte)Op.GetGlobalScope: case (byte)Op.GetGlobalSlot: case (byte)Op.GetLex: case (byte)Op.GetLocal: case (byte)Op.GetLocal0: case (byte)Op.GetLocal1: case (byte)Op.GetLocal2: case (byte)Op.GetLocal3: case (byte)Op.GetScopeObject: case (byte)Op.HasNext2: case (byte)Op.NewActivation: case (byte)Op.NewCatch: case (byte)Op.NewFunction: ++stack; break; case (byte)Op.IfFalse: case (byte)Op.IfTrue: --stack; cj = new ConditionalJump(); cj.offset = (S24)cmd.Parameters[0]; cj.pos = i; cj.stack = stack; if(!ContainsJumpFrom(jumps, cj)) jumps.Add(cj); break; case (byte)Op.Add: case (byte)Op.AddInt: case (byte)Op.AsTypeLate: case (byte)Op.BitAnd: case (byte)Op.BitOr: case (byte)Op.BitXor: case (byte)Op.Divide: case (byte)Op.DefaultXmlNamespaceLate: case (byte)Op.Equals: case (byte)Op.GreaterEquals: case (byte)Op.GreaterThan: case (byte)Op.HasNext: case (byte)Op.In: case (byte)Op.InstanceOf: case (byte)Op.IsTypeLate: case (byte)Op.LessEquals: case (byte)Op.LessThan: case (byte)Op.LeftShift: case (byte)Op.Modulo: case (byte)Op.Multiply: case (byte)Op.MultiplyInt: case (byte)Op.NextName: case (byte)Op.NextValue: case (byte)Op.Pop: case (byte)Op.PushScope://pop from stack, push to scope stack case (byte)Op.PushWith://pop from stack, push to scope stack case (byte)Op.ReturnValue: case (byte)Op.RightShift: case (byte)Op.SetLocal: case (byte)Op.SetLocal0: case (byte)Op.SetLocal1: case (byte)Op.SetLocal2: case (byte)Op.SetLocal3: case (byte)Op.SetGlobalSlot: case (byte)Op.StrictEquals: case (byte)Op.Subtract: case (byte)Op.SubtractInt: case (byte)Op.Throw: case (byte)Op.UnsignedRightShift: --stack; break; case (byte)Op.LookupSwitch: --stack; for (int k = 2; k < cmd.ParameterCount; ++k) { cj.offset = (S24)cmd.Parameters[k]; cj.pos = i; cj.stack = stack; if (!ContainsJumpFrom(jumps, cj)) jumps.Add(cj); } break; case (byte)Op.IfEqual: case (byte)Op.IfGreaterEqual: case (byte)Op.IfGreaterThan: case (byte)Op.IfLessEqual: case (byte)Op.IfLowerThan: case (byte)Op.IfNotEqual: case (byte)Op.IfNotGreaterEqual: case (byte)Op.IfNotGreaterThan: case (byte)Op.IfNotLowerEqual: case (byte)Op.IfNotLowerThan: case (byte)Op.IfStrictEqual: case (byte)Op.IfStrictNotEqual: stack -= 2; cj = new ConditionalJump(); cj.offset = (S24)cmd.Parameters[0]; cj.pos = i; cj.stack = stack; if (!ContainsJumpFrom(jumps, cj)) jumps.Add(cj); break; case (byte)Op.InitProperty: case (byte)Op.SetProperty://incorrect case (byte)Op.SetSlot: case (byte)Op.SetSuper://incorrect stack -= 2; break; case (byte)Op.Call: case (byte)Op.ConstructSuper: stack -= 1 + (int)((U30)cmd.Parameters[0]); break; case (byte)Op.Construct: stack -= (int)((U30)cmd.Parameters[0]); ; break; case (byte)Op.NewArray: stack -= (int)((U30)cmd.Parameters[0]) - 1; break; case (byte)Op.CallMethod: case (byte)Op.CallProperty://incorrect case (byte)Op.CallPropertyLex://incorrect case (byte)Op.CallPropertyVoid://incorrect case (byte)Op.CallStatic: case (byte)Op.CallSuper://incorrect case (byte)Op.CallSuperVoid://incorrect case (byte)Op.ConstructProperty: stack -= (int)((U30)cmd.Parameters[1]); break; case (byte)Op.NewObject: stack -= ((int)((U30)cmd.Parameters[0])) << 1; break; //case (byte)Op.DeleteProperty://incorrect //case (byte)Op.GetDescendants://incorrect //case (byte)Op.GetProperty://incorrect //case (byte)Op.GetSuper://incorrect // break; } if (stack < 0) { RaiseFlag(InvalidStack); corrupt = true; Console.WriteLine("[-] Warning: Stack underflow error at operation {0} (#{1})...", cmd.StringRepresentation, j); } if (stack > maxStack) maxStack = stack; ++j; } if(jumpIndex < jumps.Count) { ConditionalJump nextScan = jumps[jumpIndex++]; i = (uint)((int)nextScan.pos + (int)nextScan.offset); stack = nextScan.stack; } else { break; } } while (true); U30 result = new U30(); result.Value = (uint)maxStack; if (corrupt) DebugUtil.DumpOpUntilError(code); return result; }
public string Visit(ConditionalJump instruction) { return($"IF {instruction.Condition} JUMP {_GetLabel(instruction.Target)}"); }
public static U30 CalcMaxStack(byte[] code) { ClearFlags(); uint i = 0; uint n = (uint)code.Length; int stack = 0; int maxStack = 0; bool corrupt = false; uint j = 0; List <ConditionalJump> jumps = new List <ConditionalJump>(); List <uint> unconditionalJumps = new List <uint>(); ConditionalJump cj; int jumpIndex = 0; do { while (i < n) { AVM2Command cmd = null; try { cmd = Translator.ToCommand(code[i++]); } catch (Exception) { DebugUtil.DumpOpUntilError(code); throw new Exception(String.Format("Can not translate {0} correct at {1}.", code[i - 1], i - 1)); } if (null == cmd) { throw new Exception(); } i += cmd.ReadParameters(code, i); // There are a couple of opcodes marked "incorrect" with a comment. // The explanation is: If the index in the multiname array is a RTQName // there could be a namspace and/or namespace set on the stack as well // that would be popped. // // We do not take that in account here - in the worst case that a namespace // and namespace set is present it could add +2 to the max sack if the // stack is greater than the one we already have. // // In the calculation of the possible max stack we will therefore only remove // the number of arguments from the current value. If there are no arguments // the opcode will be listed here as incorrect without any following calculation. // // Although this is not a problem for the Flash Player. It is just not very // nice... switch (cmd.OpCode) { case (byte)Op.Jump: if (!unconditionalJumps.Contains(i)) { unconditionalJumps.Add(i); i = (uint)((int)i + (int)((S24)cmd.Parameters[0]).Value); } else { //LOOP BAAM! } break; case (byte)Op.PushByte: case (byte)Op.PushDouble: case (byte)Op.PushFalse: case (byte)Op.PushInt: case (byte)Op.PushNamespace: case (byte)Op.PushNaN: case (byte)Op.PushNull: case (byte)Op.PushShort: case (byte)Op.PushString: case (byte)Op.PushTrue: case (byte)Op.PushUInt: case (byte)Op.PushUndefined: case (byte)Op.Dup: case (byte)Op.FindProperty: //incorrect case (byte)Op.FindPropertyStrict: //incorrect case (byte)Op.GetGlobalScope: case (byte)Op.GetGlobalSlot: case (byte)Op.GetLex: case (byte)Op.GetLocal: case (byte)Op.GetLocal0: case (byte)Op.GetLocal1: case (byte)Op.GetLocal2: case (byte)Op.GetLocal3: case (byte)Op.GetScopeObject: case (byte)Op.HasNext2: case (byte)Op.NewActivation: case (byte)Op.NewCatch: case (byte)Op.NewFunction: ++stack; break; case (byte)Op.IfFalse: case (byte)Op.IfTrue: --stack; cj = new ConditionalJump(); cj.offset = (S24)cmd.Parameters[0]; cj.pos = i; cj.stack = stack; if (!ContainsJumpFrom(jumps, cj)) { jumps.Add(cj); } break; case (byte)Op.Add: case (byte)Op.AddInt: case (byte)Op.AsTypeLate: case (byte)Op.BitAnd: case (byte)Op.BitOr: case (byte)Op.BitXor: case (byte)Op.Divide: case (byte)Op.DefaultXmlNamespaceLate: case (byte)Op.Equals: case (byte)Op.GreaterEquals: case (byte)Op.GreaterThan: case (byte)Op.HasNext: case (byte)Op.In: case (byte)Op.InstanceOf: case (byte)Op.IsTypeLate: case (byte)Op.LessEquals: case (byte)Op.LessThan: case (byte)Op.LeftShift: case (byte)Op.Modulo: case (byte)Op.Multiply: case (byte)Op.MultiplyInt: case (byte)Op.NextName: case (byte)Op.NextValue: case (byte)Op.Pop: case (byte)Op.PushScope: //pop from stack, push to scope stack case (byte)Op.PushWith: //pop from stack, push to scope stack case (byte)Op.ReturnValue: case (byte)Op.RightShift: case (byte)Op.SetLocal: case (byte)Op.SetLocal0: case (byte)Op.SetLocal1: case (byte)Op.SetLocal2: case (byte)Op.SetLocal3: case (byte)Op.SetGlobalSlot: case (byte)Op.StrictEquals: case (byte)Op.Subtract: case (byte)Op.SubtractInt: case (byte)Op.Throw: case (byte)Op.UnsignedRightShift: --stack; break; case (byte)Op.LookupSwitch: --stack; for (int k = 2; k < cmd.ParameterCount; ++k) { cj.offset = (S24)cmd.Parameters[k]; cj.pos = i; cj.stack = stack; if (!ContainsJumpFrom(jumps, cj)) { jumps.Add(cj); } } break; case (byte)Op.IfEqual: case (byte)Op.IfGreaterEqual: case (byte)Op.IfGreaterThan: case (byte)Op.IfLessEqual: case (byte)Op.IfLowerThan: case (byte)Op.IfNotEqual: case (byte)Op.IfNotGreaterEqual: case (byte)Op.IfNotGreaterThan: case (byte)Op.IfNotLowerEqual: case (byte)Op.IfNotLowerThan: case (byte)Op.IfStrictEqual: case (byte)Op.IfStrictNotEqual: stack -= 2; cj = new ConditionalJump(); cj.offset = (S24)cmd.Parameters[0]; cj.pos = i; cj.stack = stack; if (!ContainsJumpFrom(jumps, cj)) { jumps.Add(cj); } break; case (byte)Op.InitProperty: case (byte)Op.SetProperty: //incorrect case (byte)Op.SetSlot: case (byte)Op.SetSuper: //incorrect stack -= 2; break; case (byte)Op.Call: case (byte)Op.ConstructSuper: stack -= 1 + (int)((U30)cmd.Parameters[0]); break; case (byte)Op.Construct: stack -= (int)((U30)cmd.Parameters[0]);; break; case (byte)Op.NewArray: stack -= (int)((U30)cmd.Parameters[0]) - 1; break; case (byte)Op.CallMethod: case (byte)Op.CallProperty: //incorrect case (byte)Op.CallPropertyLex: //incorrect case (byte)Op.CallPropertyVoid: //incorrect case (byte)Op.CallStatic: case (byte)Op.CallSuper: //incorrect case (byte)Op.CallSuperVoid: //incorrect case (byte)Op.ConstructProperty: stack -= (int)((U30)cmd.Parameters[1]); break; case (byte)Op.NewObject: stack -= ((int)((U30)cmd.Parameters[0])) << 1; break; //case (byte)Op.DeleteProperty://incorrect //case (byte)Op.GetDescendants://incorrect //case (byte)Op.GetProperty://incorrect //case (byte)Op.GetSuper://incorrect // break; } if (stack < 0) { RaiseFlag(InvalidStack); corrupt = true; Console.WriteLine("[-] Warning: Stack underflow error at operation {0} (#{1})...", cmd.StringRepresentation, j); } if (stack > maxStack) { maxStack = stack; } ++j; } if (jumpIndex < jumps.Count) { ConditionalJump nextScan = jumps[jumpIndex++]; i = (uint)((int)nextScan.pos + (int)nextScan.offset); stack = nextScan.stack; } else { break; } } while (true); U30 result = new U30(); result.Value = (uint)maxStack; if (corrupt) { DebugUtil.DumpOpUntilError(code); } return(result); }
/// <summary> /// Create the appropriate element and the appropriate quantifier /// </summary> /// <param name="Item">The elemen to compile</param> /// <param name="Parent">The parent parsed block</param> /// <param name="Compiled">The parent compiled block</param> private void CompileElement(Parse.Element Item, Parse.Block Parent, Block Compiled) { //Just create a NOP for a null item if (Item == null) { Compiled.AddItem(new NOP()); return; } //Anotate Item's commands if (Output != null) Item.Annotation.CompiledPosition.Begin = Output.Length; _OutIdent++; OutComment(Item.GetType().Name + Item.Quantifier); //Check for quantifier QuantifierBefore qb = null; if (!Item.Quantifier.IsDefault()) { if (Item.Quantifier.IsIfAny()) { //Nothing, just add NOP after } else if (Item.Quantifier.IsAsMany() && !Item.Quantifier.Additive) { //Nothing, just add a ConditionalJump after } else if (Item.Quantifier.IsNever()) { //Nothing, add a Fail and a NOP after } else { qb = new QuantifierBefore(Item.Quantifier); Compiled.AddItem(qb); } } int first_runnable_execution_index = Compiled.Count; //Find item's type if (Item is Parse.Block) { Parse.Block pabl = (Parse.Block)Item; Block bl; //New block if it is unnamed, or get the stub if (pabl.Name == null) bl = new Block(this); else bl = _BlocksByName[pabl.Name]; //Compile it CompileBlock(pabl, bl); //Create a call to the block Compiled.AddItem(new CallBlock(bl.ExecuteBlock)); //Update it's index bl.ExecuteIndex = Compiled.Items[first_runnable_execution_index]; } else if (Item is Parse.TextSearch) CETextSearch((Parse.TextSearch) Item, Parent, Compiled); else if (Item is Parse.Literal) CELiterall((Parse.Literal) Item, Compiled); else if (Item is Parse.Variable) CEVariable((Parse.Variable) Item, Parent, Compiled); else if (Item is Parse.ControlFlow) CEControlFlow((Parse.ControlFlow) Item, Parent, Compiled); else if (Item is Parse.FunctionCall) CEFunctionCall((Parse.FunctionCall) Item, Parent, Compiled); else if (Item is Parse.BinaryOperator) CEBinaryOperator((Parse.BinaryOperator) Item, Parent, Compiled); else { Compiled.AddItem(new NOP()); ThrowParseError("Unkown type " + Item.GetType().Name, Item.Annotation.SourcePosition); } int last_runnable_execute_index = Compiled.Count - 1; //Check for quantifier if (!Item.Quantifier.IsDefault()) { if (Item.Quantifier.IsIfAny()) { //On failure jump here var nop = new NOP(); Compiled.AddItem(nop); //Update Runnables CESetOnJumpFailTo(Compiled, first_runnable_execution_index, last_runnable_execute_index, nop); } else if (Item.Quantifier.IsAsMany() && !Item.Quantifier.Additive) { //On failure jump here var cj = new ConditionalJump(Compiled.Items[first_runnable_execution_index]); Compiled.AddItem(cj); //Update Runnables CESetOnJumpFailTo(Compiled, first_runnable_execution_index, last_runnable_execute_index, cj); } else if (Item.Quantifier.IsNever()) { //Fail if the item succeeds Compiled.AddItem(new ReturnBlock(0, false)); //On failure jump here var nop = new NOP(); Compiled.AddItem(nop); //Update Runnables CESetOnJumpFailTo(Compiled, first_runnable_execution_index, last_runnable_execute_index, nop); } else { //On failure jump here var qa = new QuantifierAfter(qb); Compiled.AddItem(qa); //Update Runnables CESetOnJumpFailTo(Compiled, first_runnable_execution_index, last_runnable_execute_index, qa); } } //Anotate Item's commands if (Output != null) Item.Annotation.CompiledPosition.End = Output.Length; _OutIdent--; Item.Annotation.FirstRunnable = Compiled.Items[first_runnable_execution_index]; Item.Annotation.RunnablesCount = Compiled.Count - first_runnable_execution_index; Item.Annotation.RunnableParentBlock = Compiled.ExecuteBlock; for (int i = first_runnable_execution_index ; i < Compiled.Count ; i++) { var rn = Compiled.Items[i]; if (rn.Annotation.Element == null) { rn.Annotation.Element = Item; rn.Annotation.SourcePosition = Item.Annotation.SourcePosition; rn.Annotation.TreeViewNode = Item.Annotation.TreeViewNode; } } IDE.CompiledAnnotations.Add(Item.Annotation.CompiledPosition, Item.Annotation); }
public void Visit(ConditionalJump instruction) { _CollectReadAccesses(instruction.Condition); }
/// <summary> /// Create the appropriate element and the appropriate quantifier /// </summary> /// <param name="Item">The elemen to compile</param> /// <param name="Parent">The parent parsed block</param> /// <param name="Compiled">The parent compiled block</param> private void CompileElement(Parse.Element Item, Parse.Block Parent, Block Compiled) { //Just create a NOP for a null item if (Item == null) { Compiled.AddItem(new NOP()); return; } //Anotate Item's commands if (Output != null) { Item.Annotation.CompiledPosition.Begin = Output.Length; } _OutIdent++; OutComment(Item.GetType().Name + Item.Quantifier); //Check for quantifier QuantifierBefore qb = null; if (!Item.Quantifier.IsDefault()) { if (Item.Quantifier.IsIfAny()) { //Nothing, just add NOP after } else if (Item.Quantifier.IsAsMany() && !Item.Quantifier.Additive) { //Nothing, just add a ConditionalJump after } else if (Item.Quantifier.IsNever()) { //Nothing, add a Fail and a NOP after } else { qb = new QuantifierBefore(Item.Quantifier); Compiled.AddItem(qb); } } int first_runnable_execution_index = Compiled.Count; //Find item's type if (Item is Parse.Block) { Parse.Block pabl = (Parse.Block)Item; Block bl; //New block if it is unnamed, or get the stub if (pabl.Name == null) { bl = new Block(this); } else { bl = _BlocksByName[pabl.Name]; } //Compile it CompileBlock(pabl, bl); //Create a call to the block Compiled.AddItem(new CallBlock(bl.ExecuteBlock)); //Update it's index bl.ExecuteIndex = Compiled.Items[first_runnable_execution_index]; } else if (Item is Parse.TextSearch) { CETextSearch((Parse.TextSearch)Item, Parent, Compiled); } else if (Item is Parse.Literal) { CELiterall((Parse.Literal)Item, Compiled); } else if (Item is Parse.Variable) { CEVariable((Parse.Variable)Item, Parent, Compiled); } else if (Item is Parse.ControlFlow) { CEControlFlow((Parse.ControlFlow)Item, Parent, Compiled); } else if (Item is Parse.FunctionCall) { CEFunctionCall((Parse.FunctionCall)Item, Parent, Compiled); } else if (Item is Parse.BinaryOperator) { CEBinaryOperator((Parse.BinaryOperator)Item, Parent, Compiled); } else { Compiled.AddItem(new NOP()); ThrowParseError("Unkown type " + Item.GetType().Name, Item.Annotation.SourcePosition); } int last_runnable_execute_index = Compiled.Count - 1; //Check for quantifier if (!Item.Quantifier.IsDefault()) { if (Item.Quantifier.IsIfAny()) { //On failure jump here var nop = new NOP(); Compiled.AddItem(nop); //Update Runnables CESetOnJumpFailTo(Compiled, first_runnable_execution_index, last_runnable_execute_index, nop); } else if (Item.Quantifier.IsAsMany() && !Item.Quantifier.Additive) { //On failure jump here var cj = new ConditionalJump(Compiled.Items[first_runnable_execution_index]); Compiled.AddItem(cj); //Update Runnables CESetOnJumpFailTo(Compiled, first_runnable_execution_index, last_runnable_execute_index, cj); } else if (Item.Quantifier.IsNever()) { //Fail if the item succeeds Compiled.AddItem(new ReturnBlock(0, false)); //On failure jump here var nop = new NOP(); Compiled.AddItem(nop); //Update Runnables CESetOnJumpFailTo(Compiled, first_runnable_execution_index, last_runnable_execute_index, nop); } else { //On failure jump here var qa = new QuantifierAfter(qb); Compiled.AddItem(qa); //Update Runnables CESetOnJumpFailTo(Compiled, first_runnable_execution_index, last_runnable_execute_index, qa); } } //Anotate Item's commands if (Output != null) { Item.Annotation.CompiledPosition.End = Output.Length; } _OutIdent--; Item.Annotation.FirstRunnable = Compiled.Items[first_runnable_execution_index]; Item.Annotation.RunnablesCount = Compiled.Count - first_runnable_execution_index; Item.Annotation.RunnableParentBlock = Compiled.ExecuteBlock; for (int i = first_runnable_execution_index; i < Compiled.Count; i++) { var rn = Compiled.Items[i]; if (rn.Annotation.Element == null) { rn.Annotation.Element = Item; rn.Annotation.SourcePosition = Item.Annotation.SourcePosition; rn.Annotation.TreeViewNode = Item.Annotation.TreeViewNode; } } IDE.CompiledAnnotations.Add(Item.Annotation.CompiledPosition, Item.Annotation); }
public abstract void visit(ConditionalJump node);
public void Visit(ConditionalJump node) { }
public void Visit(ConditionalJump instruction) { instruction.Condition.Accept(this); }
public ISet <VariableDescriptor> Visit(ConditionalJump instruction) { return(_inputKnowledge); }
public Instruction Visit(ConditionalJump instruction) { var condition = instruction.Condition.Accept(this); return(condition == instruction.Condition ? instruction : new ConditionalJump(condition, instruction.Target)); }