-/* An op sequencer. We visit the ops in the order they're to execute. */
-
-STATIC void
-S_sequence(pTHX_ register const OP *o)
-{
- dVAR;
- const OP *oldop = NULL;
-
- if (!o)
- return;
-
-#ifdef PERL_MAD
- if (o->op_next == 0)
- return;
-#endif
-
- if (!Sequence)
- Sequence = newHV();
-
- for (; o; o = o->op_next) {
- STRLEN len;
- SV * const op = newSVuv(PTR2UV(o));
- const char * const key = SvPV_const(op, len);
-
- if (hv_exists(Sequence, key, len))
- break;
-
- switch (o->op_type) {
- case OP_STUB:
- if ((o->op_flags & OPf_WANT) != OPf_WANT_LIST) {
- (void)hv_store(Sequence, key, len, newSVuv(++PL_op_seq), 0);
- break;
- }
- goto nothin;
- case OP_NULL:
-#ifdef PERL_MAD
- if (o == o->op_next)
- return;
-#endif
- if (oldop && o->op_next)
- continue;
- break;
- case OP_SCALAR:
- case OP_LINESEQ:
- case OP_SCOPE:
- nothin:
- if (oldop && o->op_next)
- continue;
- (void)hv_store(Sequence, key, len, newSVuv(++PL_op_seq), 0);
- break;
-
- case OP_MAPWHILE:
- case OP_GREPWHILE:
- case OP_AND:
- case OP_OR:
- case OP_DOR:
- case OP_ANDASSIGN:
- case OP_ORASSIGN:
- case OP_DORASSIGN:
- case OP_COND_EXPR:
- case OP_RANGE:
- (void)hv_store(Sequence, key, len, newSVuv(++PL_op_seq), 0);
- sequence_tail(cLOGOPo->op_other);
- break;
-
- case OP_ENTERLOOP:
- case OP_ENTERITER:
- (void)hv_store(Sequence, key, len, newSVuv(++PL_op_seq), 0);
- sequence_tail(cLOOPo->op_redoop);
- sequence_tail(cLOOPo->op_nextop);
- sequence_tail(cLOOPo->op_lastop);
- break;
-
- case OP_SUBST:
- (void)hv_store(Sequence, key, len, newSVuv(++PL_op_seq), 0);
- sequence_tail(cPMOPo->op_pmstashstartu.op_pmreplstart);
- break;
-
- case OP_QR:
- case OP_MATCH:
- case OP_HELEM:
- break;
-
- default:
- (void)hv_store(Sequence, key, len, newSVuv(++PL_op_seq), 0);
- break;
- }
- oldop = o;
- }
-}
-
-static void
-S_sequence_tail(pTHX_ const OP *o)
-{
- while (o && (o->op_type == OP_NULL))
- o = o->op_next;
- sequence(o);
-}