+STATIC void indirect_teardown(pTHX_ void *root) {
+ if (!indirect_initialized)
+ return;
+
+#if I_MULTIPLICITY
+ if (aTHX != root)
+ return;
+#endif
+
+ {
+ dMY_CXT;
+ ptable_free(MY_CXT.map);
+#if I_THREADSAFE
+ ptable_hints_free(MY_CXT.tbl);
+#endif
+ }
+
+ indirect_ck_restore(OP_CONST, &indirect_old_ck_const);
+ indirect_ck_restore(OP_RV2SV, &indirect_old_ck_rv2sv);
+ indirect_ck_restore(OP_PADANY, &indirect_old_ck_padany);
+ indirect_ck_restore(OP_SCOPE, &indirect_old_ck_scope);
+ indirect_ck_restore(OP_LINESEQ, &indirect_old_ck_lineseq);
+
+ indirect_ck_restore(OP_METHOD, &indirect_old_ck_method);
+ indirect_ck_restore(OP_METHOD_NAMED, &indirect_old_ck_method_named);
+ indirect_ck_restore(OP_ENTERSUB, &indirect_old_ck_entersub);
+
+ indirect_initialized = 0;
+}
+
+STATIC void indirect_setup(pTHX) {
+#define indirect_setup() indirect_setup(aTHX)
+ if (indirect_initialized)
+ return;
+
+ {
+ MY_CXT_INIT;
+#if I_THREADSAFE
+ MY_CXT.tbl = ptable_new();
+ MY_CXT.owner = aTHX;
+#endif
+ MY_CXT.map = ptable_new();
+ MY_CXT.global_code = NULL;
+ }
+
+ indirect_ck_replace(OP_CONST, indirect_ck_const, &indirect_old_ck_const);
+ indirect_ck_replace(OP_RV2SV, indirect_ck_rv2sv, &indirect_old_ck_rv2sv);
+ indirect_ck_replace(OP_PADANY, indirect_ck_padany, &indirect_old_ck_padany);
+ indirect_ck_replace(OP_SCOPE, indirect_ck_scope, &indirect_old_ck_scope);
+ indirect_ck_replace(OP_LINESEQ, indirect_ck_scope, &indirect_old_ck_lineseq);
+
+ indirect_ck_replace(OP_METHOD, indirect_ck_method,
+ &indirect_old_ck_method);
+ indirect_ck_replace(OP_METHOD_NAMED, indirect_ck_method_named,
+ &indirect_old_ck_method_named);
+ indirect_ck_replace(OP_ENTERSUB, indirect_ck_entersub,
+ &indirect_old_ck_entersub);
+
+#if I_MULTIPLICITY
+ call_atexit(indirect_teardown, aTHX);
+#else
+ call_atexit(indirect_teardown, NULL);
+#endif
+
+ indirect_initialized = 1;
+}
+
+STATIC U32 indirect_booted = 0;
+