Exemplo n.º 1
0
        /// <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);
        }
Exemplo n.º 2
0
 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();
 }
Exemplo n.º 4
0
        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)
                });
            }
Exemplo n.º 6
0
        public void Visit(ConditionalJump instruction)
        {
            _ProcessInvocations(instruction.Condition);

            var node = _cfg.RegisterInstruction(instruction);

            _ConnectWithPreviousNode(node);
            _cfg.AddEdge(node, _cfg.RegisterInstruction(instruction.Target));
            _previousNode = node;
        }
Exemplo n.º 7
0
        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);
        }
Exemplo n.º 8
0
        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);
        }
Exemplo n.º 9
0
        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());
        }
Exemplo n.º 10
0
        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))
            })
Exemplo n.º 11
0
        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;
        }
Exemplo n.º 12
0
        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;
        }
Exemplo n.º 13
0
 public string Visit(ConditionalJump instruction)
 {
     return($"IF {instruction.Condition} JUMP {_GetLabel(instruction.Target)}");
 }
Exemplo n.º 14
0
        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);
 }
Exemplo n.º 17
0
        /// <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);
Exemplo n.º 19
0
 public void Visit(ConditionalJump node)
 {
 }
Exemplo n.º 20
0
 public void Visit(ConditionalJump instruction)
 {
     instruction.Condition.Accept(this);
 }
Exemplo n.º 21
0
 public ISet <VariableDescriptor> Visit(ConditionalJump instruction)
 {
     return(_inputKnowledge);
 }
Exemplo n.º 22
0
            public Instruction Visit(ConditionalJump instruction)
            {
                var condition = instruction.Condition.Accept(this);

                return(condition == instruction.Condition ? instruction : new ConditionalJump(condition, instruction.Target));
            }