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();
        }
Пример #4
0
        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();
        }