Adds ip to the work queue, following empty arrows according to flag.
| 810 | |
| 811 | // Adds ip to the work queue, following empty arrows according to flag. |
| 812 | void DFA::AddToQueue(Workq* q, int id, uint32_t flag) { |
| 813 | |
| 814 | // Use stack_ to hold our stack of instructions yet to process. |
| 815 | // It was preallocated as follows: |
| 816 | // one entry per Capture; |
| 817 | // one entry per EmptyWidth; and |
| 818 | // one entry per Nop. |
| 819 | // This reflects the maximum number of stack pushes that each can |
| 820 | // perform. (Each instruction can be processed at most once.) |
| 821 | // When using marks, we also added nmark == prog_->size(). |
| 822 | // (Otherwise, nmark == 0.) |
| 823 | int* stk = stack_.data(); |
| 824 | int nstk = 0; |
| 825 | |
| 826 | stk[nstk++] = id; |
| 827 | while (nstk > 0) { |
| 828 | DCHECK_LE(nstk, stack_.size()); |
| 829 | id = stk[--nstk]; |
| 830 | |
| 831 | Loop: |
| 832 | if (id == Mark) { |
| 833 | q->mark(); |
| 834 | continue; |
| 835 | } |
| 836 | |
| 837 | if (id == 0) |
| 838 | continue; |
| 839 | |
| 840 | // If ip is already on the queue, nothing to do. |
| 841 | // Otherwise add it. We don't actually keep all the |
| 842 | // ones that get added, but adding all of them here |
| 843 | // increases the likelihood of q->contains(id), |
| 844 | // reducing the amount of duplicated work. |
| 845 | if (q->contains(id)) |
| 846 | continue; |
| 847 | q->insert_new(id); |
| 848 | |
| 849 | // Process instruction. |
| 850 | Prog::Inst* ip = prog_->inst(id); |
| 851 | switch (ip->opcode()) { |
| 852 | default: |
| 853 | LOG(DFATAL) << "unhandled opcode: " << ip->opcode(); |
| 854 | break; |
| 855 | |
| 856 | case kInstByteRange: // just save these on the queue |
| 857 | case kInstMatch: |
| 858 | if (ip->last()) |
| 859 | break; |
| 860 | id = id+1; |
| 861 | goto Loop; |
| 862 | |
| 863 | case kInstCapture: // DFA treats captures as no-ops. |
| 864 | case kInstNop: |
| 865 | if (!ip->last()) |
| 866 | stk[nstk++] = id+1; |
| 867 | |
| 868 | // If this instruction is the [00-FF]* loop at the beginning of |
| 869 | // a leftmost-longest unanchored search, separate with a Mark so |
nothing calls this directly
no test coverage detected