-STATIC void indirect_map_clean_kids(pTHX_ const OP *o) {
-#define indirect_map_clean_kids(O) indirect_map_clean_kids(aTHX_ (O))
- if (o->op_flags & OPf_KIDS) {
- const OP *kid = ((const UNOP *) o)->op_first;
- for (; kid; kid = kid->op_sibling) {
- indirect_map_clean_kids(kid);
- indirect_map_delete(kid);
+#define indirect_detag(H) (((H) && SvOK(H)) ? INT2PTR(SV *, SvUVX(H)) : NULL)
+
+#endif /* I_THREADSAFE || I_WORKAROUND_REQUIRE_PROPAGATION */
+
+STATIC U32 indirect_hash = 0;
+
+STATIC SV *indirect_hint(pTHX) {
+#define indirect_hint() indirect_hint(aTHX)
+ SV *hint;
+
+ if (IN_PERL_RUNTIME)
+ return NULL;
+
+#if I_HAS_PERL(5, 9, 5)
+ hint = Perl_refcounted_he_fetch(aTHX_ PL_curcop->cop_hints_hash,
+ NULL,
+ __PACKAGE__, __PACKAGE_LEN__,
+ 0,
+ indirect_hash);
+#else
+ {
+ SV **val = hv_fetch(GvHV(PL_hintgv), __PACKAGE__, __PACKAGE_LEN__,
+ indirect_hash);
+ if (!val)
+ return 0;
+ hint = *val;
+ }
+#endif
+ return indirect_detag(hint);
+}
+
+/* ... op -> source position ............................................... */
+
+STATIC void indirect_map_store(pTHX_ const OP *o, const char *src, SV *sv, line_t line) {
+#define indirect_map_store(O, S, N, L) indirect_map_store(aTHX_ (O), (S), (N), (L))
+ indirect_op_info_t *oi;
+ const char *s;
+ STRLEN len;
+ dMY_CXT;
+
+ /* When lex_inwhat is set, we're in a quotelike environment (qq, qr, but not q)
+ * In this case the linestr has temporarly changed, but the old buffer should
+ * still be alive somewhere. */
+
+ if (!PL_lex_inwhat) {
+ const char *pl_linestr = SvPVX_const(PL_linestr);
+ if (MY_CXT.linestr != pl_linestr) {
+ ptable_clear(MY_CXT.map);
+ MY_CXT.linestr = pl_linestr;