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