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 (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); }