void FixupJumps()
        {
            QueryBuffer <Opcode> treePath   = this.diverger.TreePath;
            QueryBuffer <Opcode> insertPath = this.diverger.InsertPath;

            for (int i = 0; i < insertPath.Count; ++i)
            {
                if (insertPath[i].TestFlag(OpcodeFlags.Jump))
                {
                    Fx.Assert(treePath[i].ID == insertPath[i].ID, "");
                    JumpOpcode insertJump = (JumpOpcode)insertPath[i];
                    // Opcodes in 'insertPath' have equivalent opcodes in the query tree: i.e. the query tree contains an
                    // an equivalent execution path (upto the point of divergence naturally) that will produce in an identical
                    // result. The remainder of the query tree (anything that lies beyond the point of divergence) represents
                    // a distinct execution path and is grafted onto the tree as a new branch. In fact, we simply break off
                    // the remainder from the query being inserted and graft it onto the query tree.
                    // If there are jumps on the insert path that jump to opcodes NOT in the insert path, then the jumps
                    // will reach opcodes in the new branch we will add(see above). However, because the actual jump opcodes
                    // are shared (used as is from the query tree), the actual jump must also be branched. One jump will
                    // continue to jump to the original opcode and the second new one will jump to an opcode in the grafted branch.
                    if (-1 == insertPath.IndexOf(insertJump.Jump, i + 1))
                    {
                        Fx.Assert(insertJump.Jump.ID == OpcodeID.BlockEnd, "");

                        BlockEndOpcode jumpTo = (BlockEndOpcode)insertJump.Jump;
                        // no longer jumping from insertJump to jumpTo
                        insertJump.RemoveJump(jumpTo);

                        // Instead, jumping from treePath[i] to jumpTo
                        JumpOpcode treeJump = (JumpOpcode)treePath[i];
                        treeJump.AddJump(jumpTo);
                    }
                }
            }
        }
Esempio n. 2
0
        private void FixupJumps()
        {
            QueryBuffer <Opcode> treePath   = this.diverger.TreePath;
            QueryBuffer <Opcode> insertPath = this.diverger.InsertPath;

            for (int i = 0; i < insertPath.Count; i++)
            {
                if (insertPath[i].TestFlag(OpcodeFlags.Jump))
                {
                    JumpOpcode opcode = (JumpOpcode)insertPath[i];
                    if (-1 == insertPath.IndexOf(opcode.Jump, i + 1))
                    {
                        BlockEndOpcode jump = (BlockEndOpcode)opcode.Jump;
                        opcode.RemoveJump(jump);
                        ((JumpOpcode)treePath[i]).AddJump(jump);
                    }
                }
            }
        }