| 381 | // gives the current position in the input. |cond| is a bitmask of EMPTY_* |
| 382 | // flags. |
| 383 | private Thread add(Queue q, int pc, int pos, int[] cap, int cond, Thread t) { |
| 384 | if (pc == 0) { |
| 385 | return t; |
| 386 | } |
| 387 | if (q.contains(pc)) { |
| 388 | return t; |
| 389 | } |
| 390 | int d = q.add(pc); |
| 391 | Inst inst = prog.inst[pc]; |
| 392 | switch (inst.op) { |
| 393 | default: |
| 394 | throw new IllegalStateException("unhandled"); |
| 395 | |
| 396 | case Inst.FAIL: |
| 397 | break; // nothing |
| 398 | |
| 399 | case Inst.ALT: |
| 400 | case Inst.ALT_MATCH: |
| 401 | t = add(q, inst.out, pos, cap, cond, t); |
| 402 | t = add(q, inst.arg, pos, cap, cond, t); |
| 403 | break; |
| 404 | |
| 405 | case Inst.EMPTY_WIDTH: |
| 406 | if ((inst.arg & ~cond) == 0) { |
| 407 | t = add(q, inst.out, pos, cap, cond, t); |
| 408 | } |
| 409 | break; |
| 410 | |
| 411 | case Inst.NOP: |
| 412 | t = add(q, inst.out, pos, cap, cond, t); |
| 413 | break; |
| 414 | |
| 415 | case Inst.CAPTURE: |
| 416 | if (inst.arg < ncap) { |
| 417 | int opos = cap[inst.arg]; |
| 418 | cap[inst.arg] = pos; |
| 419 | add(q, inst.out, pos, cap, cond, null); |
| 420 | cap[inst.arg] = opos; |
| 421 | } else { |
| 422 | t = add(q, inst.out, pos, cap, cond, t); |
| 423 | } |
| 424 | break; |
| 425 | |
| 426 | case Inst.MATCH: |
| 427 | case Inst.RUNE: |
| 428 | case Inst.RUNE1: |
| 429 | case Inst.RUNE_ANY: |
| 430 | case Inst.RUNE_ANY_NOT_NL: |
| 431 | if (t == null) { |
| 432 | t = alloc(inst); |
| 433 | } else { |
| 434 | t.inst = inst; |
| 435 | } |
| 436 | if (ncap > 0 && t.cap != cap) { |
| 437 | System.arraycopy(cap, 0, t.cap, 0, ncap); |
| 438 | } |
| 439 | q.denseThreads[d] = t; |
| 440 | t = null; |