private void InvokeMultiMatch(ProcessingContext context) { int counterMarker = context.Processor.CounterMarker; BranchContext context2 = new BranchContext(context); int count = this.resultTable.Count; int num3 = 0; while (num3 < count) { ProcessingContext context3; QueryBranchResult result = this.resultTable[num3]; QueryBranch branch = result.Branch; Opcode next = branch.Branch.Next; if (next.TestFlag(OpcodeFlags.NoContextCopy)) { context3 = context; } else { context3 = context2.Create(); } this.InitResults(context3); context3.Values[context3.TopArg[result.ValIndex]].Boolean = true; while (++num3 < count) { result = this.resultTable[num3]; if (branch.ID != result.Branch.ID) { break; } context3.Values[context3.TopArg[result.ValIndex]].Boolean = true; } try { context3.EvalCodeBlock(next); } catch (XPathNavigatorException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception.Process(next)); } catch (NavigatorInvalidBodyAccessException exception2) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception2.Process(next)); } context.Processor.CounterMarker = counterMarker; } context2.Release(); }
internal void InvokeNonMatches(ProcessingContext context, QueryBranchTable nonMatchTable) { Fx.Assert(null != context && null != nonMatchTable, ""); int marker = context.Processor.CounterMarker; BranchContext branchContext = new BranchContext(context); int nonMatchIndex = 0; int matchIndex = 0; while (matchIndex < this.resultTable.Count && nonMatchIndex < nonMatchTable.Count) { int compare = this.resultTable[matchIndex].Branch.ID - nonMatchTable[nonMatchIndex].ID; if (compare > 0) { // Nonmatch < match // Invoke.. ProcessingContext newContext = branchContext.Create(); this.InvokeNonMatch(newContext, nonMatchTable[nonMatchIndex]); context.Processor.CounterMarker = marker; ++nonMatchIndex; } else if (0 == compare) { ++nonMatchIndex; } else { ++matchIndex; } } // Add remaining while (nonMatchIndex < nonMatchTable.Count) { ProcessingContext newContext = branchContext.Create(); this.InvokeNonMatch(newContext, nonMatchTable[nonMatchIndex]); context.Processor.CounterMarker = marker; ++nonMatchIndex; } branchContext.Release(); }
internal void InvokeNonMatches(ProcessingContext context, QueryBranchTable nonMatchTable) { int counterMarker = context.Processor.CounterMarker; BranchContext context2 = new BranchContext(context); int num2 = 0; int num3 = 0; while ((num3 < this.resultTable.Count) && (num2 < nonMatchTable.Count)) { QueryBranchResult result = this.resultTable[num3]; int num4 = result.Branch.ID - nonMatchTable[num2].ID; if (num4 > 0) { ProcessingContext context3 = context2.Create(); this.InvokeNonMatch(context3, nonMatchTable[num2]); context.Processor.CounterMarker = counterMarker; num2++; } else { if (num4 == 0) { num2++; continue; } num3++; } } while (num2 < nonMatchTable.Count) { ProcessingContext context4 = context2.Create(); this.InvokeNonMatch(context4, nonMatchTable[num2]); context.Processor.CounterMarker = counterMarker; num2++; } context2.Release(); }
internal override Opcode Eval(ProcessingContext context) { QueryProcessor processor = context.Processor; SeekableXPathNavigator contextNode = processor.ContextNode; int counterMarker = processor.CounterMarker; long currentPosition = contextNode.CurrentPosition; int num3 = 0; int count = this.branches.Count; try { Opcode opcode; if (context.StacksInUse) { if (--count > 0) { BranchContext context2 = new BranchContext(context); while (num3 < count) { opcode = this.branches[num3]; if ((opcode.Flags & OpcodeFlags.Fx) != OpcodeFlags.None) { opcode.Eval(context); } else { ProcessingContext context3 = context2.Create(); while (opcode != null) { opcode = opcode.Eval(context3); } } contextNode.CurrentPosition = currentPosition; processor.CounterMarker = counterMarker; num3++; } context2.Release(); } opcode = this.branches[num3]; while (opcode != null) { opcode = opcode.Eval(context); } } else { int nodeCount = context.NodeCount; while (num3 < count) { for (opcode = this.branches[num3]; opcode != null; opcode = opcode.Eval(context)) { } context.ClearContext(); context.NodeCount = nodeCount; contextNode.CurrentPosition = currentPosition; processor.CounterMarker = counterMarker; num3++; } } } catch (XPathNavigatorException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception.Process(this.branches[num3])); } catch (NavigatorInvalidBodyAccessException exception2) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception2.Process(this.branches[num3])); } processor.CounterMarker = counterMarker; return(base.next); }
internal override Opcode Eval(ProcessingContext context) { QueryProcessor processor = context.Processor; SeekableXPathNavigator contextNode = processor.ContextNode; int marker = processor.CounterMarker; long pos = contextNode.CurrentPosition; Opcode branch; int i = 0; int branchCount = this.branches.Count; try { if (context.StacksInUse) { // If we have N branches, eval N-1 in a cloned context and the remainder in the // original one if (--branchCount > 0) { // Evaluate all but the first branch with a clone of the current context // The first branch (right most) can be evaluated with the current context BranchContext branchContext = new BranchContext(context); // struct. fast for (; i < branchCount; ++i) { branch = this.branches[i]; if (0 != (branch.Flags & OpcodeFlags.Fx)) { branch.Eval(context); } else { // This allocates a solitary context and then reuses it repeatedly ProcessingContext newContext = branchContext.Create(); while (null != branch) { branch = branch.Eval(newContext); } } contextNode.CurrentPosition = pos; // restore the navigator to its original position processor.CounterMarker = marker; // and the node count marker } branchContext.Release(); } // Do the final branch with the existing context branch = branches[i]; while (null != branch) { branch = branch.Eval(context); } } else // since there is nothing on the stack, there is nothing to clone { int nodeCountSav = context.NodeCount; for (; i < branchCount; ++i) { branch = branches[i]; // Evaluate this branch while (null != branch) { branch = branch.Eval(context); } // Restore the current context to its pristine state, so we can reuse it context.ClearContext(); context.NodeCount = nodeCountSav; contextNode.CurrentPosition = pos; processor.CounterMarker = marker; } } } catch (XPathNavigatorException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(e.Process(branches[i])); } catch (NavigatorInvalidBodyAccessException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(e.Process(branches[i])); } processor.CounterMarker = marker; return(this.next); }
void InvokeMultiMatch(ProcessingContext context) { int marker = context.Processor.CounterMarker; BranchContext branchContext = new BranchContext(context); // struct. quick. int resultTableCount = this.resultTable.Count; for (int i = 0; i < resultTableCount;) { QueryBranchResult result = this.resultTable[i]; QueryBranch branch = result.Branch; // Branches can arbitrarily alter context stacks, rendering them unuseable to other branches. // Therefore, before following a branch, we have to clone the context. Cloning is relatively efficient because // can avoid allocating memory in most cases. We cannot, unfortunately, avoid Array copies. // // Optimization: // We can avoid cloning altogether when we can predict that the branch does NOT tamper with the stack, // or does so in a predictable way. If we are sure that we can restore the stack easily after the branch // completes, we have no reason to copy the stack. ProcessingContext newContext; Opcode nextOpcode = branch.Branch.Next; if (nextOpcode.TestFlag(OpcodeFlags.NoContextCopy)) { newContext = context; } else { newContext = branchContext.Create(); } this.InitResults(newContext); // // Matches are sorted by their branch ID. // It is very possible that the a literal matches multiple times, especially when the value being // compared is a sequence. A literal may match multiple items in a single sequence // OR multiple items in multiple sequences. If there were 4 context sequences, the literal may have // matched one item each in 3 of them. The branchID for that literal will be present 3 times in the // resultTable. // Sorting the matches groups them by their branch Ids. We only want to take the branch ONCE, so now we // iterate over all the duplicate matches.. // result.ValIndex will give us the index of the value that was matched. Thus if the 3rd sequence // matched, ValIndex == 2 (0 based) newContext.Values[newContext.TopArg[result.ValIndex]].Boolean = true; while (++i < resultTableCount) { result = this.resultTable[i]; if (branch.ID == result.Branch.ID) { newContext.Values[newContext.TopArg[result.ValIndex]].Boolean = true; } else { break; } } try { newContext.EvalCodeBlock(nextOpcode); } catch (XPathNavigatorException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(e.Process(nextOpcode)); } catch (NavigatorInvalidBodyAccessException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(e.Process(nextOpcode)); } context.Processor.CounterMarker = marker; } branchContext.Release(); }