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(); }
private void InvokeSingleMatch(ProcessingContext context) { int counterMarker = context.Processor.CounterMarker; QueryBranchResult result = this.resultTable[0]; this.InitResults(context); context.Values[context.TopArg[result.ValIndex]].Boolean = true; try { context.EvalCodeBlock(result.Branch.Branch.Next); } catch (XPathNavigatorException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception.Process(result.Branch.Branch.Next)); } catch (NavigatorInvalidBodyAccessException exception2) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception2.Process(result.Branch.Branch.Next)); } context.Processor.CounterMarker = counterMarker; }
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(); }
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(); }