internal Opcode Build(Opcode tree, OpcodeBlock newBlock)
 {
     if (tree == null)
     {
         this.lastOpcode = newBlock.Last;
         return newBlock.First;
     }
     this.diverger = new Diverger(tree, newBlock.First);
     if (!this.diverger.Find())
     {
         this.lastOpcode = this.diverger.TreePath[this.diverger.TreePath.Count - 1];
         return tree;
     }
     if (this.diverger.TreeOpcode == null)
     {
         this.diverger.TreePath[this.diverger.TreePath.Count - 1].Attach(this.diverger.InsertOpcode);
     }
     else
     {
         this.diverger.TreeOpcode.Add(this.diverger.InsertOpcode);
     }
     this.lastOpcode = newBlock.Last;
     if (this.diverger.InsertOpcode.IsMultipleResult())
     {
         if (OpcodeID.Branch == this.diverger.TreeOpcode.ID)
         {
             OpcodeList branches = ((BranchOpcode) this.diverger.TreeOpcode).Branches;
             int num = 0;
             int count = branches.Count;
             while (num < count)
             {
                 if (branches[num].IsMultipleResult())
                 {
                     this.lastOpcode = branches[num];
                     break;
                 }
                 num++;
             }
         }
         else if (this.diverger.TreeOpcode.IsMultipleResult())
         {
             this.lastOpcode = this.diverger.TreeOpcode;
         }
     }
     this.FixupJumps();
     return tree;
 }
예제 #2
0
 internal Opcode Build(Opcode tree, OpcodeBlock newBlock)
 {
     if (tree == null)
     {
         this.lastOpcode = newBlock.Last;
         return(newBlock.First);
     }
     this.diverger = new Diverger(tree, newBlock.First);
     if (!this.diverger.Find())
     {
         this.lastOpcode = this.diverger.TreePath[this.diverger.TreePath.Count - 1];
         return(tree);
     }
     if (this.diverger.TreeOpcode == null)
     {
         this.diverger.TreePath[this.diverger.TreePath.Count - 1].Attach(this.diverger.InsertOpcode);
     }
     else
     {
         this.diverger.TreeOpcode.Add(this.diverger.InsertOpcode);
     }
     this.lastOpcode = newBlock.Last;
     if (this.diverger.InsertOpcode.IsMultipleResult())
     {
         if (OpcodeID.Branch == this.diverger.TreeOpcode.ID)
         {
             OpcodeList branches = ((BranchOpcode)this.diverger.TreeOpcode).Branches;
             int        num      = 0;
             int        count    = branches.Count;
             while (num < count)
             {
                 if (branches[num].IsMultipleResult())
                 {
                     this.lastOpcode = branches[num];
                     break;
                 }
                 num++;
             }
         }
         else if (this.diverger.TreeOpcode.IsMultipleResult())
         {
             this.lastOpcode = this.diverger.TreeOpcode;
         }
     }
     this.FixupJumps();
     return(tree);
 }
        internal Opcode Build(Opcode tree, OpcodeBlock newBlock)
        {
            if (null == tree)
            {
                this.lastOpcode = newBlock.Last;
                return newBlock.First;
            }

            this.diverger = new Diverger(tree, newBlock.First);

            if (!this.diverger.Find())
            {
                // The opcodes in newBlock already have equivalents or identical opcodes
                // in the query tree that can do the job
                Fx.Assert(this.diverger.TreePath.Count > 0, "");
                this.lastOpcode = this.diverger.TreePath[this.diverger.TreePath.Count - 1];
                return tree;
            }

            Fx.Assert(this.diverger.TreePath.Count == this.diverger.InsertPath.Count, "");

            // We can reuse opcodes upto this.diverger.TreePath[this.diverger.TreePath.Count - 1]
            // The remainder of the code in newBlock must be executed as is...
            if (null == this.diverger.TreeOpcode)
            {
                // We reached a leaf in the query tree
                // Simply add the remainder of the inserted code to the end of the tree path..
                this.diverger.TreePath[this.diverger.TreePath.Count - 1].Attach(this.diverger.InsertOpcode);
            }
            else
            {
                // Merge in the remaider of the new code block into the query tree
                // The first diverging opcodes follow the last entry in each path
                this.diverger.TreeOpcode.Add(this.diverger.InsertOpcode);
            }
            
            this.lastOpcode = newBlock.Last;
            if (this.diverger.InsertOpcode.IsMultipleResult())
            {
                // The complete new block was merged in, except for the the actual result opcode, which never
                // automatically merges. This means that the new block found all of its opcodes in common with 
                // the tree
                if (OpcodeID.Branch == this.diverger.TreeOpcode.ID)
                {
                    OpcodeList branches = (((BranchOpcode) this.diverger.TreeOpcode).Branches); 
                    for (int i = 0, count = branches.Count; i < count; ++i)
                    {
                        if (branches[i].IsMultipleResult())
                        {
                            this.lastOpcode = branches[i];
                            break;
                        }
                    }
                }
                else if (this.diverger.TreeOpcode.IsMultipleResult())
                {
                    this.lastOpcode = this.diverger.TreeOpcode;
                }
            }

            // Since we'll be diverging, any jumps that preceeded and leapt past the divergence point
            // will have to be branched
            this.FixupJumps();

            return tree;
        }
        internal Opcode Build(Opcode tree, OpcodeBlock newBlock)
        {
            if (null == tree)
            {
                this.lastOpcode = newBlock.Last;
                return(newBlock.First);
            }

            this.diverger = new Diverger(tree, newBlock.First);

            if (!this.diverger.Find())
            {
                // The opcodes in newBlock already have equivalents or identical opcodes
                // in the query tree that can do the job
                Fx.Assert(this.diverger.TreePath.Count > 0, "");
                this.lastOpcode = this.diverger.TreePath[this.diverger.TreePath.Count - 1];
                return(tree);
            }

            Fx.Assert(this.diverger.TreePath.Count == this.diverger.InsertPath.Count, "");

            // We can reuse opcodes upto this.diverger.TreePath[this.diverger.TreePath.Count - 1]
            // The remainder of the code in newBlock must be executed as is...
            if (null == this.diverger.TreeOpcode)
            {
                // We reached a leaf in the query tree
                // Simply add the remainder of the inserted code to the end of the tree path..
                this.diverger.TreePath[this.diverger.TreePath.Count - 1].Attach(this.diverger.InsertOpcode);
            }
            else
            {
                // Merge in the remaider of the new code block into the query tree
                // The first diverging opcodes follow the last entry in each path
                this.diverger.TreeOpcode.Add(this.diverger.InsertOpcode);
            }

            this.lastOpcode = newBlock.Last;
            if (this.diverger.InsertOpcode.IsMultipleResult())
            {
                // The complete new block was merged in, except for the the actual result opcode, which never
                // automatically merges. This means that the new block found all of its opcodes in common with
                // the tree
                if (OpcodeID.Branch == this.diverger.TreeOpcode.ID)
                {
                    OpcodeList branches = (((BranchOpcode)this.diverger.TreeOpcode).Branches);
                    for (int i = 0, count = branches.Count; i < count; ++i)
                    {
                        if (branches[i].IsMultipleResult())
                        {
                            this.lastOpcode = branches[i];
                            break;
                        }
                    }
                }
                else if (this.diverger.TreeOpcode.IsMultipleResult())
                {
                    this.lastOpcode = this.diverger.TreeOpcode;
                }
            }

            // Since we'll be diverging, any jumps that preceeded and leapt past the divergence point
            // will have to be branched
            this.FixupJumps();

            return(tree);
        }