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();
        }
예제 #2
0
        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();
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
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();
        }