]> git.vpit.fr Git - perl/modules/indirect.git/blob - indirect.xs
Do nothing after that the thread local storage has been freed
[perl/modules/indirect.git] / indirect.xs
1 /* This file is part of the indirect Perl module.
2  * See http://search.cpan.org/dist/indirect/ */
3
4 #define PERL_NO_GET_CONTEXT
5 #include "EXTERN.h"
6 #include "perl.h"
7 #include "XSUB.h"
8
9 #define __PACKAGE__     "indirect"
10 #define __PACKAGE_LEN__ (sizeof(__PACKAGE__)-1)
11
12 /* --- Compatibility wrappers ---------------------------------------------- */
13
14 #ifndef NOOP
15 # define NOOP
16 #endif
17
18 #ifndef dNOOP
19 # define dNOOP
20 #endif
21
22 #ifndef Newx
23 # define Newx(v, n, c) New(0, v, n, c)
24 #endif
25
26 #ifndef SvPV_const
27 # define SvPV_const SvPV
28 #endif
29
30 #ifndef SvPV_nolen_const
31 # define SvPV_nolen_const SvPV_nolen
32 #endif
33
34 #ifndef SvPVX_const
35 # define SvPVX_const SvPVX
36 #endif
37
38 #ifndef SvREFCNT_inc_simple_void_NN
39 # ifdef SvREFCNT_inc_simple_NN
40 #  define SvREFCNT_inc_simple_void_NN SvREFCNT_inc_simple_NN
41 # else
42 #  define SvREFCNT_inc_simple_void_NN SvREFCNT_inc
43 # endif
44 #endif
45
46 #ifndef sv_catpvn_nomg
47 # define sv_catpvn_nomg sv_catpvn
48 #endif
49
50 #ifndef mPUSHp
51 # define mPUSHp(P, L) PUSHs(sv_2mortal(newSVpvn((P), (L))))
52 #endif
53
54 #ifndef mPUSHu
55 # define mPUSHu(U) PUSHs(sv_2mortal(newSVuv(U)))
56 #endif
57
58 #ifndef HvNAME_get
59 # define HvNAME_get(H) HvNAME(H)
60 #endif
61
62 #ifndef HvNAMELEN_get
63 # define HvNAMELEN_get(H) strlen(HvNAME_get(H))
64 #endif
65
66 #ifndef OP_SIBLING
67 # define OP_SIBLING(O) ((O)->op_sibling)
68 #endif
69
70 #define I_HAS_PERL(R, V, S) (PERL_REVISION > (R) || (PERL_REVISION == (R) && (PERL_VERSION > (V) || (PERL_VERSION == (V) && (PERL_SUBVERSION >= (S))))))
71
72 #if I_HAS_PERL(5, 10, 0) || defined(PL_parser)
73 # ifndef PL_linestr
74 #  define PL_linestr PL_parser->linestr
75 # endif
76 # ifndef PL_bufptr
77 #  define PL_bufptr PL_parser->bufptr
78 # endif
79 # ifndef PL_oldbufptr
80 #  define PL_oldbufptr PL_parser->oldbufptr
81 # endif
82 # ifndef PL_lex_inwhat
83 #  define PL_lex_inwhat PL_parser->lex_inwhat
84 # endif
85 #else
86 # ifndef PL_linestr
87 #  define PL_linestr PL_Ilinestr
88 # endif
89 # ifndef PL_bufptr
90 #  define PL_bufptr PL_Ibufptr
91 # endif
92 # ifndef PL_oldbufptr
93 #  define PL_oldbufptr PL_Ioldbufptr
94 # endif
95 # ifndef PL_lex_inwhat
96 #  define PL_lex_inwhat PL_Ilex_inwhat
97 # endif
98 #endif
99
100 #ifndef I_WORKAROUND_REQUIRE_PROPAGATION
101 # define I_WORKAROUND_REQUIRE_PROPAGATION !I_HAS_PERL(5, 10, 1)
102 #endif
103
104 /* ... Thread safety and multiplicity ...................................... */
105
106 /* Safe unless stated otherwise in Makefile.PL */
107 #ifndef I_FORKSAFE
108 # define I_FORKSAFE 1
109 #endif
110
111 #ifndef I_MULTIPLICITY
112 # if defined(MULTIPLICITY) || defined(PERL_IMPLICIT_CONTEXT)
113 #  define I_MULTIPLICITY 1
114 # else
115 #  define I_MULTIPLICITY 0
116 # endif
117 #endif
118 #if I_MULTIPLICITY && !defined(tTHX)
119 # define tTHX PerlInterpreter*
120 #endif
121
122 #if I_MULTIPLICITY && defined(USE_ITHREADS) && defined(dMY_CXT) && defined(MY_CXT) && defined(START_MY_CXT) && defined(MY_CXT_INIT) && (defined(MY_CXT_CLONE) || defined(dMY_CXT_SV))
123 # define I_THREADSAFE 1
124 # ifndef MY_CXT_CLONE
125 #  define MY_CXT_CLONE \
126     dMY_CXT_SV;                                                      \
127     my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1)); \
128     Copy(INT2PTR(my_cxt_t*, SvUV(my_cxt_sv)), my_cxtp, 1, my_cxt_t); \
129     sv_setuv(my_cxt_sv, PTR2UV(my_cxtp))
130 # endif
131 #else
132 # define I_THREADSAFE 0
133 # undef  dMY_CXT
134 # define dMY_CXT      dNOOP
135 # undef  MY_CXT
136 # define MY_CXT       indirect_globaldata
137 # undef  START_MY_CXT
138 # define START_MY_CXT STATIC my_cxt_t MY_CXT;
139 # undef  MY_CXT_INIT
140 # define MY_CXT_INIT  NOOP
141 # undef  MY_CXT_CLONE
142 # define MY_CXT_CLONE NOOP
143 #endif
144
145 #if defined(OP_CHECK_MUTEX_LOCK) && defined(OP_CHECK_MUTEX_UNLOCK)
146 # define I_CHECK_MUTEX_LOCK   OP_CHECK_MUTEX_LOCK
147 # define I_CHECK_MUTEX_UNLOCK OP_CHECK_MUTEX_UNLOCK
148 #else
149 # define I_CHECK_MUTEX_LOCK   OP_REFCNT_LOCK
150 # define I_CHECK_MUTEX_UNLOCK OP_REFCNT_UNLOCK
151 #endif
152
153 typedef OP *(*indirect_ck_t)(pTHX_ OP *);
154
155 #ifdef wrap_op_checker
156
157 # define indirect_ck_replace(T, NC, OCP) wrap_op_checker((T), (NC), (OCP))
158
159 #else
160
161 STATIC void indirect_ck_replace(pTHX_ OPCODE type, indirect_ck_t new_ck, indirect_ck_t *old_ck_p) {
162 #define indirect_ck_replace(T, NC, OCP) indirect_ck_replace(aTHX_ (T), (NC), (OCP))
163  I_CHECK_MUTEX_LOCK;
164  if (!*old_ck_p) {
165   *old_ck_p      = PL_check[type];
166   PL_check[type] = new_ck;
167  }
168  I_CHECK_MUTEX_UNLOCK;
169 }
170
171 #endif
172
173 STATIC void indirect_ck_restore(pTHX_ OPCODE type, indirect_ck_t *old_ck_p) {
174 #define indirect_ck_restore(T, OCP) indirect_ck_restore(aTHX_ (T), (OCP))
175  I_CHECK_MUTEX_LOCK;
176  if (*old_ck_p) {
177   PL_check[type] = *old_ck_p;
178   *old_ck_p      = 0;
179  }
180  I_CHECK_MUTEX_UNLOCK;
181 }
182
183 /* --- Helpers ------------------------------------------------------------- */
184
185 /* ... Thread-safe hints ................................................... */
186
187 #if I_WORKAROUND_REQUIRE_PROPAGATION
188
189 typedef struct {
190  SV *code;
191  IV  require_tag;
192 } indirect_hint_t;
193
194 #define I_HINT_STRUCT 1
195
196 #define I_HINT_CODE(H) ((H)->code)
197
198 #define I_HINT_FREE(H) {   \
199  indirect_hint_t *h = (H); \
200  SvREFCNT_dec(h->code);    \
201  PerlMemShared_free(h);    \
202 }
203
204 #else  /*  I_WORKAROUND_REQUIRE_PROPAGATION */
205
206 typedef SV indirect_hint_t;
207
208 #define I_HINT_STRUCT 0
209
210 #define I_HINT_CODE(H) (H)
211
212 #define I_HINT_FREE(H) SvREFCNT_dec(H);
213
214 #endif /* !I_WORKAROUND_REQUIRE_PROPAGATION */
215
216 #if I_THREADSAFE
217
218 #define PTABLE_NAME        ptable_hints
219 #define PTABLE_VAL_FREE(V) I_HINT_FREE(V)
220
221 #define pPTBL  pTHX
222 #define pPTBL_ pTHX_
223 #define aPTBL  aTHX
224 #define aPTBL_ aTHX_
225
226 #include "ptable.h"
227
228 #define ptable_hints_store(T, K, V) ptable_hints_store(aTHX_ (T), (K), (V))
229 #define ptable_hints_free(T)        ptable_hints_free(aTHX_ (T))
230
231 #endif /* I_THREADSAFE */
232
233 /* Define the op->str ptable here because we need to be able to clean it during
234  * thread cleanup. */
235
236 typedef struct {
237  char   *buf;
238  STRLEN  pos;
239  STRLEN  size;
240  STRLEN  len;
241  line_t  line;
242 } indirect_op_info_t;
243
244 #define PTABLE_NAME        ptable
245 #define PTABLE_VAL_FREE(V) if (V) { Safefree(((indirect_op_info_t *) (V))->buf); Safefree(V); }
246
247 #define pPTBL  pTHX
248 #define pPTBL_ pTHX_
249 #define aPTBL  aTHX
250 #define aPTBL_ aTHX_
251
252 #include "ptable.h"
253
254 #define ptable_store(T, K, V) ptable_store(aTHX_ (T), (K), (V))
255 #define ptable_delete(T, K)   ptable_delete(aTHX_ (T), (K))
256 #define ptable_clear(T)       ptable_clear(aTHX_ (T))
257 #define ptable_free(T)        ptable_free(aTHX_ (T))
258
259 #define MY_CXT_KEY __PACKAGE__ "::_guts" XS_VERSION
260
261 typedef struct {
262 #if I_THREADSAFE
263  ptable *tbl; /* It really is a ptable_hints */
264  tTHX    owner;
265 #endif
266  ptable *map;
267  SV     *global_code;
268 } my_cxt_t;
269
270 START_MY_CXT
271
272 #if I_THREADSAFE
273
274 typedef struct {
275  ptable *tbl;
276 #if I_HAS_PERL(5, 13, 2)
277  CLONE_PARAMS *params;
278 #else
279  CLONE_PARAMS params;
280 #endif
281 } indirect_ptable_clone_ud;
282
283 #if I_HAS_PERL(5, 13, 2)
284 # define indirect_ptable_clone_ud_init(U, T, O) \
285    (U).tbl    = (T); \
286    (U).params = Perl_clone_params_new((O), aTHX)
287 # define indirect_ptable_clone_ud_deinit(U) Perl_clone_params_del((U).params)
288 # define indirect_dup_inc(S, U)             SvREFCNT_inc(sv_dup((S), (U)->params))
289 #else
290 # define indirect_ptable_clone_ud_init(U, T, O) \
291    (U).tbl               = (T);     \
292    (U).params.stashes    = newAV(); \
293    (U).params.flags      = 0;       \
294    (U).params.proto_perl = (O)
295 # define indirect_ptable_clone_ud_deinit(U) SvREFCNT_dec((U).params.stashes)
296 # define indirect_dup_inc(S, U)             SvREFCNT_inc(sv_dup((S), &((U)->params)))
297 #endif
298
299 STATIC void indirect_ptable_clone(pTHX_ ptable_ent *ent, void *ud_) {
300  indirect_ptable_clone_ud *ud = ud_;
301  indirect_hint_t          *h1 = ent->val;
302  indirect_hint_t          *h2;
303
304 #if I_HINT_STRUCT
305
306  h2              = PerlMemShared_malloc(sizeof *h2);
307  h2->code        = indirect_dup_inc(h1->code, ud);
308 #if I_WORKAROUND_REQUIRE_PROPAGATION
309  h2->require_tag = PTR2IV(indirect_dup_inc(INT2PTR(SV *, h1->require_tag), ud));
310 #endif
311
312 #else  /*  I_HINT_STRUCT */
313
314  h2 = indirect_dup_inc(h1, ud);
315
316 #endif /* !I_HINT_STRUCT */
317
318  ptable_hints_store(ud->tbl, ent->key, h2);
319 }
320
321 STATIC void indirect_thread_cleanup(pTHX_ void *ud) {
322  dMY_CXT;
323
324  SvREFCNT_dec(MY_CXT.global_code);
325  MY_CXT.global_code = NULL;
326  ptable_free(MY_CXT.map);
327  MY_CXT.map = NULL;
328  ptable_hints_free(MY_CXT.tbl);
329  MY_CXT.tbl = NULL;
330 }
331
332 STATIC int indirect_endav_free(pTHX_ SV *sv, MAGIC *mg) {
333  SAVEDESTRUCTOR_X(indirect_thread_cleanup, NULL);
334
335  return 0;
336 }
337
338 STATIC MGVTBL indirect_endav_vtbl = {
339  0,
340  0,
341  0,
342  0,
343  indirect_endav_free
344 #if MGf_COPY
345  , 0
346 #endif
347 #if MGf_DUP
348  , 0
349 #endif
350 #if MGf_LOCAL
351  , 0
352 #endif
353 };
354
355 #endif /* I_THREADSAFE */
356
357 #if I_WORKAROUND_REQUIRE_PROPAGATION
358 STATIC IV indirect_require_tag(pTHX) {
359 #define indirect_require_tag() indirect_require_tag(aTHX)
360  const CV *cv, *outside;
361
362  cv = PL_compcv;
363
364  if (!cv) {
365   /* If for some reason the pragma is operational at run-time, try to discover
366    * the current cv in use. */
367   const PERL_SI *si;
368
369   for (si = PL_curstackinfo; si; si = si->si_prev) {
370    I32 cxix;
371
372    for (cxix = si->si_cxix; cxix >= 0; --cxix) {
373     const PERL_CONTEXT *cx = si->si_cxstack + cxix;
374
375     switch (CxTYPE(cx)) {
376      case CXt_SUB:
377      case CXt_FORMAT:
378       /* The propagation workaround is only needed up to 5.10.0 and at that
379        * time format and sub contexts were still identical. And even later the
380        * cv members offsets should have been kept the same. */
381       cv = cx->blk_sub.cv;
382       goto get_enclosing_cv;
383      case CXt_EVAL:
384       cv = cx->blk_eval.cv;
385       goto get_enclosing_cv;
386      default:
387       break;
388     }
389    }
390   }
391
392   cv = PL_main_cv;
393  }
394
395 get_enclosing_cv:
396  for (outside = CvOUTSIDE(cv); outside; outside = CvOUTSIDE(cv))
397   cv = outside;
398
399  return PTR2IV(cv);
400 }
401 #endif /* I_WORKAROUND_REQUIRE_PROPAGATION */
402
403 STATIC SV *indirect_tag(pTHX_ SV *value) {
404 #define indirect_tag(V) indirect_tag(aTHX_ (V))
405  indirect_hint_t *h;
406  SV              *code = NULL;
407 #if I_THREADSAFE
408  dMY_CXT;
409
410  if (!MY_CXT.tbl)
411   return newSViv(0);
412 #endif /* I_THREADSAFE */
413
414  if (SvROK(value)) {
415   value = SvRV(value);
416   if (SvTYPE(value) >= SVt_PVCV) {
417    code = value;
418    SvREFCNT_inc_simple_void_NN(code);
419   }
420  }
421
422 #if I_HINT_STRUCT
423  h = PerlMemShared_malloc(sizeof *h);
424  h->code        = code;
425 # if I_WORKAROUND_REQUIRE_PROPAGATION
426  h->require_tag = indirect_require_tag();
427 # endif /* I_WORKAROUND_REQUIRE_PROPAGATION */
428 #else  /*  I_HINT_STRUCT */
429  h = code;
430 #endif /* !I_HINT_STRUCT */
431
432 #if I_THREADSAFE
433  /* We only need for the key to be an unique tag for looking up the value later
434   * Allocated memory provides convenient unique identifiers, so that's why we
435   * use the hint as the key itself. */
436  ptable_hints_store(MY_CXT.tbl, h, h);
437 #endif /* I_THREADSAFE */
438
439  return newSViv(PTR2IV(h));
440 }
441
442 STATIC SV *indirect_detag(pTHX_ const SV *hint) {
443 #define indirect_detag(H) indirect_detag(aTHX_ (H))
444  indirect_hint_t *h;
445 #if I_THREADSAFE || I_WORKAROUND_REQUIRE_PROPAGATION
446  dMY_CXT;
447 #endif
448
449 #if I_THREADSAFE
450  if (!MY_CXT.tbl)
451   return NULL;
452 #endif /* I_THREADSAFE */
453
454  h = INT2PTR(indirect_hint_t *, SvIVX(hint));
455 #if I_THREADSAFE
456  h = ptable_fetch(MY_CXT.tbl, h);
457 #endif /* I_THREADSAFE */
458
459 #if I_WORKAROUND_REQUIRE_PROPAGATION
460  if (indirect_require_tag() != h->require_tag)
461   return MY_CXT.global_code;
462 #endif /* I_WORKAROUND_REQUIRE_PROPAGATION */
463
464  return I_HINT_CODE(h);
465 }
466
467 STATIC U32 indirect_hash = 0;
468
469 STATIC SV *indirect_hint(pTHX) {
470 #define indirect_hint() indirect_hint(aTHX)
471  SV *hint = NULL;
472
473  if (IN_PERL_RUNTIME)
474   return NULL;
475
476 #if I_HAS_PERL(5, 10, 0) || defined(PL_parser)
477  if (!PL_parser)
478   return NULL;
479 #endif
480
481 #ifdef cop_hints_fetch_pvn
482  hint = cop_hints_fetch_pvn(PL_curcop, __PACKAGE__, __PACKAGE_LEN__,
483                                                               indirect_hash, 0);
484 #elif I_HAS_PERL(5, 9, 5)
485  hint = Perl_refcounted_he_fetch(aTHX_ PL_curcop->cop_hints_hash,
486                                        NULL,
487                                        __PACKAGE__, __PACKAGE_LEN__,
488                                        0,
489                                        indirect_hash);
490 #else
491  {
492   SV **val = hv_fetch(GvHV(PL_hintgv), __PACKAGE__, __PACKAGE_LEN__, 0);
493   if (val)
494    hint = *val;
495  }
496 #endif
497
498  if (hint && SvIOK(hint))
499   return indirect_detag(hint);
500  else {
501   dMY_CXT;
502   return MY_CXT.global_code;
503  }
504 }
505
506 /* ... op -> source position ............................................... */
507
508 STATIC void indirect_map_store(pTHX_ const OP *o, STRLEN pos, SV *sv, line_t line) {
509 #define indirect_map_store(O, P, N, L) indirect_map_store(aTHX_ (O), (P), (N), (L))
510  indirect_op_info_t *oi;
511  const char *s;
512  STRLEN len;
513  dMY_CXT;
514
515  /* No need to check for MY_CXT.map != NULL because this code path is always
516   * guarded by indirect_hint(). */
517
518  if (!(oi = ptable_fetch(MY_CXT.map, o))) {
519   Newx(oi, 1, indirect_op_info_t);
520   ptable_store(MY_CXT.map, o, oi);
521   oi->buf  = NULL;
522   oi->size = 0;
523  }
524
525  if (sv) {
526   s = SvPV_const(sv, len);
527  } else {
528   s   = "{";
529   len = 1;
530  }
531
532  if (len > oi->size) {
533   Safefree(oi->buf);
534   Newx(oi->buf, len, char);
535   oi->size = len;
536  }
537  Copy(s, oi->buf, len, char);
538
539  oi->len  = len;
540  oi->pos  = pos;
541  oi->line = line;
542 }
543
544 STATIC const indirect_op_info_t *indirect_map_fetch(pTHX_ const OP *o) {
545 #define indirect_map_fetch(O) indirect_map_fetch(aTHX_ (O))
546  dMY_CXT;
547
548  /* No need to check for MY_CXT.map != NULL because this code path is always
549   * guarded by indirect_hint(). */
550
551  return ptable_fetch(MY_CXT.map, o);
552 }
553
554 STATIC void indirect_map_delete(pTHX_ const OP *o) {
555 #define indirect_map_delete(O) indirect_map_delete(aTHX_ (O))
556  dMY_CXT;
557
558  if (MY_CXT.map)
559   ptable_delete(MY_CXT.map, o);
560 }
561
562 /* --- Check functions ----------------------------------------------------- */
563
564 STATIC int indirect_find(pTHX_ SV *name_sv, const char *line_bufptr, STRLEN *name_pos) {
565 #define indirect_find(NSV, LBP, NP) indirect_find(aTHX_ (NSV), (LBP), (NP))
566  STRLEN      name_len, line_len;
567  const char *name, *name_end;
568  const char *line, *line_end;
569  const char *p;
570
571  line     = SvPV_const(PL_linestr, line_len);
572  line_end = line + line_len;
573
574  name = SvPV_const(name_sv, name_len);
575  if (name_len >= 1 && *name == '$') {
576   ++name;
577   --name_len;
578   while (line_bufptr < line_end && *line_bufptr != '$')
579    ++line_bufptr;
580   if (line_bufptr >= line_end)
581    return 0;
582  }
583  name_end = name + name_len;
584
585  p = line_bufptr;
586  while (1) {
587   p = ninstr(p, line_end, name, name_end);
588   if (!p)
589    return 0;
590   if (!isALNUM(p[name_len]))
591    break;
592   /* p points to a word that has name as prefix, skip the rest of the word */
593   p += name_len + 1;
594   while (isALNUM(*p))
595    ++p;
596  }
597
598  *name_pos = p - line;
599
600  return 1;
601 }
602
603 /* ... ck_const ............................................................ */
604
605 STATIC OP *(*indirect_old_ck_const)(pTHX_ OP *) = 0;
606
607 STATIC OP *indirect_ck_const(pTHX_ OP *o) {
608  o = indirect_old_ck_const(aTHX_ o);
609
610  if (indirect_hint()) {
611   SV *sv = cSVOPo_sv;
612
613   if (SvPOK(sv) && (SvTYPE(sv) >= SVt_PV)) {
614    STRLEN pos;
615
616    if (indirect_find(sv, PL_oldbufptr, &pos)) {
617     STRLEN len;
618
619     /* If the constant is equal to the current package name, try to look for
620      * a "__PACKAGE__" coming before what we got. We only need to check this
621      * when we already had a match because __PACKAGE__ can only appear in
622      * direct method calls ("new __PACKAGE__" is a syntax error). */
623     len = SvCUR(sv);
624     if (PL_curstash
625         && len == (STRLEN) HvNAMELEN_get(PL_curstash)
626         && memcmp(SvPVX(sv), HvNAME_get(PL_curstash), len) == 0) {
627      STRLEN pos_pkg;
628      SV    *pkg = sv_newmortal();
629      sv_setpvn(pkg, "__PACKAGE__", sizeof("__PACKAGE__")-1);
630
631      if (indirect_find(pkg, PL_oldbufptr, &pos_pkg) && pos_pkg < pos) {
632       sv  = pkg;
633       pos = pos_pkg;
634      }
635     }
636
637     indirect_map_store(o, pos, sv, CopLINE(&PL_compiling));
638     return o;
639    }
640   }
641  }
642
643  indirect_map_delete(o);
644  return o;
645 }
646
647 /* ... ck_rv2sv ............................................................ */
648
649 STATIC OP *(*indirect_old_ck_rv2sv)(pTHX_ OP *) = 0;
650
651 STATIC OP *indirect_ck_rv2sv(pTHX_ OP *o) {
652  if (indirect_hint()) {
653   OP *op = cUNOPo->op_first;
654   SV *sv;
655   const char *name = NULL;
656   STRLEN pos, len;
657   OPCODE type = (OPCODE) op->op_type;
658
659   switch (type) {
660    case OP_GV:
661    case OP_GVSV: {
662     GV *gv = cGVOPx_gv(op);
663     name = GvNAME(gv);
664     len  = GvNAMELEN(gv);
665     break;
666    }
667    default:
668     if ((PL_opargs[type] & OA_CLASS_MASK) == OA_SVOP) {
669      SV *nsv = cSVOPx_sv(op);
670      if (SvPOK(nsv) && (SvTYPE(nsv) >= SVt_PV))
671       name = SvPV_const(nsv, len);
672     }
673   }
674   if (!name)
675    goto done;
676
677   sv = sv_2mortal(newSVpvn("$", 1));
678   sv_catpvn_nomg(sv, name, len);
679   if (!indirect_find(sv, PL_oldbufptr, &pos)) {
680    /* If it failed, retry without the current stash */
681    const char *stash = HvNAME_get(PL_curstash);
682    STRLEN stashlen = HvNAMELEN_get(PL_curstash);
683
684    if ((len < stashlen + 2) || strnNE(name, stash, stashlen)
685        || name[stashlen] != ':' || name[stashlen+1] != ':') {
686     /* Failed again ? Try to remove main */
687     stash = "main";
688     stashlen = 4;
689     if ((len < stashlen + 2) || strnNE(name, stash, stashlen)
690         || name[stashlen] != ':' || name[stashlen+1] != ':')
691      goto done;
692    }
693
694    sv_setpvn(sv, "$", 1);
695    stashlen += 2;
696    sv_catpvn_nomg(sv, name + stashlen, len - stashlen);
697    if (!indirect_find(sv, PL_oldbufptr, &pos))
698     goto done;
699   }
700
701   o = indirect_old_ck_rv2sv(aTHX_ o);
702
703   indirect_map_store(o, pos, sv, CopLINE(&PL_compiling));
704   return o;
705  }
706
707 done:
708  o = indirect_old_ck_rv2sv(aTHX_ o);
709
710  indirect_map_delete(o);
711  return o;
712 }
713
714 /* ... ck_padany ........................................................... */
715
716 STATIC OP *(*indirect_old_ck_padany)(pTHX_ OP *) = 0;
717
718 STATIC OP *indirect_ck_padany(pTHX_ OP *o) {
719  o = indirect_old_ck_padany(aTHX_ o);
720
721  if (indirect_hint()) {
722   SV *sv;
723   const char *s = PL_oldbufptr, *t = PL_bufptr - 1;
724
725   while (s < t && isSPACE(*s)) ++s;
726   if (*s == '$' && ++s <= t) {
727    while (s < t && isSPACE(*s)) ++s;
728    while (s < t && isSPACE(*t)) --t;
729    sv = sv_2mortal(newSVpvn("$", 1));
730    sv_catpvn_nomg(sv, s, t - s + 1);
731    indirect_map_store(o, s - SvPVX_const(PL_linestr),
732                          sv, CopLINE(&PL_compiling));
733    return o;
734   }
735  }
736
737  indirect_map_delete(o);
738  return o;
739 }
740
741 /* ... ck_scope ............................................................ */
742
743 STATIC OP *(*indirect_old_ck_scope)  (pTHX_ OP *) = 0;
744 STATIC OP *(*indirect_old_ck_lineseq)(pTHX_ OP *) = 0;
745
746 STATIC OP *indirect_ck_scope(pTHX_ OP *o) {
747  OP *(*old_ck)(pTHX_ OP *) = 0;
748
749  switch (o->op_type) {
750   case OP_SCOPE:   old_ck = indirect_old_ck_scope;   break;
751   case OP_LINESEQ: old_ck = indirect_old_ck_lineseq; break;
752  }
753  o = old_ck(aTHX_ o);
754
755  if (indirect_hint()) {
756   indirect_map_store(o, PL_oldbufptr - SvPVX_const(PL_linestr),
757                         NULL, CopLINE(&PL_compiling));
758   return o;
759  }
760
761  indirect_map_delete(o);
762  return o;
763 }
764
765 /* We don't need to clean the map entries for leave ops because they can only
766  * be created by mutating from a lineseq. */
767
768 /* ... ck_method ........................................................... */
769
770 STATIC OP *(*indirect_old_ck_method)(pTHX_ OP *) = 0;
771
772 STATIC OP *indirect_ck_method(pTHX_ OP *o) {
773  if (indirect_hint()) {
774   OP *op = cUNOPo->op_first;
775
776   /* Indirect method call is only possible when the method is a bareword, so
777    * don't trip up on $obj->$meth. */
778   if (op && op->op_type == OP_CONST) {
779    const indirect_op_info_t *oi = indirect_map_fetch(op);
780    STRLEN pos;
781    line_t line;
782    SV *sv;
783
784    if (!oi)
785     goto done;
786
787    sv   = sv_2mortal(newSVpvn(oi->buf, oi->len));
788    pos  = oi->pos;
789    /* Keep the old line so that we really point to the first line of the
790     * expression. */
791    line = oi->line;
792
793    o = indirect_old_ck_method(aTHX_ o);
794    /* o may now be a method_named */
795
796    indirect_map_store(o, pos, sv, line);
797    return o;
798   }
799  }
800
801 done:
802  o = indirect_old_ck_method(aTHX_ o);
803
804  indirect_map_delete(o);
805  return o;
806 }
807
808 /* ... ck_method_named ..................................................... */
809
810 /* "use foo/no foo" compiles its call to import/unimport directly to a
811  * method_named op. */
812
813 STATIC OP *(*indirect_old_ck_method_named)(pTHX_ OP *) = 0;
814
815 STATIC OP *indirect_ck_method_named(pTHX_ OP *o) {
816  if (indirect_hint()) {
817   STRLEN pos;
818   line_t line;
819   SV *sv;
820
821   sv = cSVOPo_sv;
822   if (!SvPOK(sv) || (SvTYPE(sv) < SVt_PV))
823    goto done;
824   sv = sv_mortalcopy(sv);
825
826   if (!indirect_find(sv, PL_oldbufptr, &pos))
827    goto done;
828   line = CopLINE(&PL_compiling);
829
830   o = indirect_old_ck_method_named(aTHX_ o);
831
832   indirect_map_store(o, pos, sv, line);
833   return o;
834  }
835
836 done:
837  o = indirect_old_ck_method_named(aTHX_ o);
838
839  indirect_map_delete(o);
840  return o;
841 }
842
843 /* ... ck_entersub ......................................................... */
844
845 STATIC OP *(*indirect_old_ck_entersub)(pTHX_ OP *) = 0;
846
847 STATIC OP *indirect_ck_entersub(pTHX_ OP *o) {
848  SV *code = indirect_hint();
849
850  o = indirect_old_ck_entersub(aTHX_ o);
851
852  if (code) {
853   const indirect_op_info_t *moi, *ooi;
854   OP     *mop, *oop;
855   LISTOP *lop;
856
857   oop = o;
858   do {
859    lop = (LISTOP *) oop;
860    if (!(lop->op_flags & OPf_KIDS))
861     goto done;
862    oop = lop->op_first;
863   } while (oop->op_type != OP_PUSHMARK);
864   oop = OP_SIBLING(oop);
865   mop = lop->op_last;
866
867   if (!oop)
868    goto done;
869
870   switch (oop->op_type) {
871    case OP_CONST:
872    case OP_RV2SV:
873    case OP_PADSV:
874    case OP_SCOPE:
875    case OP_LEAVE:
876     break;
877    default:
878     goto done;
879   }
880
881   if (mop->op_type == OP_METHOD)
882    mop = cUNOPx(mop)->op_first;
883   else if (mop->op_type != OP_METHOD_NAMED)
884    goto done;
885
886   moi = indirect_map_fetch(mop);
887   if (!moi)
888    goto done;
889
890   ooi = indirect_map_fetch(oop);
891   if (!ooi)
892    goto done;
893
894   /* When positions are identical, the method and the object must have the
895    * same name. But it also means that it is an indirect call, as "foo->foo"
896    * results in different positions. */
897   if (   moi->line < ooi->line
898       || (moi->line == ooi->line && moi->pos <= ooi->pos)) {
899    SV *file;
900    dSP;
901
902    ENTER;
903    SAVETMPS;
904
905 #ifdef USE_ITHREADS
906    file = sv_2mortal(newSVpv(CopFILE(&PL_compiling), 0));
907 #else
908    file = sv_mortalcopy(CopFILESV(&PL_compiling));
909 #endif
910
911    PUSHMARK(SP);
912    EXTEND(SP, 4);
913    mPUSHp(ooi->buf, ooi->len);
914    mPUSHp(moi->buf, moi->len);
915    PUSHs(file);
916    mPUSHu(moi->line);
917    PUTBACK;
918
919    call_sv(code, G_VOID);
920
921    PUTBACK;
922
923    FREETMPS;
924    LEAVE;
925   }
926  }
927
928 done:
929  return o;
930 }
931
932 STATIC U32 indirect_initialized = 0;
933
934 STATIC void indirect_teardown(pTHX_ void *root) {
935  if (!indirect_initialized)
936   return;
937
938 #if I_MULTIPLICITY
939  if (aTHX != root)
940   return;
941 #endif
942
943  {
944   dMY_CXT;
945   ptable_free(MY_CXT.map);
946   MY_CXT.map = NULL;
947 #if I_THREADSAFE
948   ptable_hints_free(MY_CXT.tbl);
949   MY_CXT.tbl = NULL;
950 #endif
951  }
952
953  indirect_ck_restore(OP_CONST,   &indirect_old_ck_const);
954  indirect_ck_restore(OP_RV2SV,   &indirect_old_ck_rv2sv);
955  indirect_ck_restore(OP_PADANY,  &indirect_old_ck_padany);
956  indirect_ck_restore(OP_SCOPE,   &indirect_old_ck_scope);
957  indirect_ck_restore(OP_LINESEQ, &indirect_old_ck_lineseq);
958
959  indirect_ck_restore(OP_METHOD,       &indirect_old_ck_method);
960  indirect_ck_restore(OP_METHOD_NAMED, &indirect_old_ck_method_named);
961  indirect_ck_restore(OP_ENTERSUB,     &indirect_old_ck_entersub);
962
963  indirect_initialized = 0;
964 }
965
966 STATIC void indirect_setup(pTHX) {
967 #define indirect_setup() indirect_setup(aTHX)
968  if (indirect_initialized)
969   return;
970
971  {
972   MY_CXT_INIT;
973 #if I_THREADSAFE
974   MY_CXT.tbl         = ptable_new();
975   MY_CXT.owner       = aTHX;
976 #endif
977   MY_CXT.map         = ptable_new();
978   MY_CXT.global_code = NULL;
979  }
980
981  indirect_ck_replace(OP_CONST,   indirect_ck_const,  &indirect_old_ck_const);
982  indirect_ck_replace(OP_RV2SV,   indirect_ck_rv2sv,  &indirect_old_ck_rv2sv);
983  indirect_ck_replace(OP_PADANY,  indirect_ck_padany, &indirect_old_ck_padany);
984  indirect_ck_replace(OP_SCOPE,   indirect_ck_scope,  &indirect_old_ck_scope);
985  indirect_ck_replace(OP_LINESEQ, indirect_ck_scope,  &indirect_old_ck_lineseq);
986
987  indirect_ck_replace(OP_METHOD,       indirect_ck_method,
988                                       &indirect_old_ck_method);
989  indirect_ck_replace(OP_METHOD_NAMED, indirect_ck_method_named,
990                                       &indirect_old_ck_method_named);
991  indirect_ck_replace(OP_ENTERSUB,     indirect_ck_entersub,
992                                       &indirect_old_ck_entersub);
993
994 #if I_MULTIPLICITY
995  call_atexit(indirect_teardown, aTHX);
996 #else
997  call_atexit(indirect_teardown, NULL);
998 #endif
999
1000  indirect_initialized = 1;
1001 }
1002
1003 STATIC U32 indirect_booted = 0;
1004
1005 /* --- XS ------------------------------------------------------------------ */
1006
1007 MODULE = indirect      PACKAGE = indirect
1008
1009 PROTOTYPES: ENABLE
1010
1011 BOOT:
1012 {
1013  if (!indirect_booted++) {
1014   HV *stash;
1015
1016   PERL_HASH(indirect_hash, __PACKAGE__, __PACKAGE_LEN__);
1017
1018   stash = gv_stashpvn(__PACKAGE__, __PACKAGE_LEN__, 1);
1019   newCONSTSUB(stash, "I_THREADSAFE", newSVuv(I_THREADSAFE));
1020   newCONSTSUB(stash, "I_FORKSAFE",   newSVuv(I_FORKSAFE));
1021  }
1022
1023  indirect_setup();
1024 }
1025
1026 #if I_THREADSAFE
1027
1028 void
1029 CLONE(...)
1030 PROTOTYPE: DISABLE
1031 PREINIT:
1032  ptable *t;
1033  SV     *global_code_dup;
1034  GV     *gv;
1035 PPCODE:
1036  {
1037   indirect_ptable_clone_ud ud;
1038   dMY_CXT;
1039   t = ptable_new();
1040   indirect_ptable_clone_ud_init(ud, t, MY_CXT.owner);
1041   ptable_walk(MY_CXT.tbl, indirect_ptable_clone, &ud);
1042   global_code_dup = indirect_dup_inc(MY_CXT.global_code, &ud);
1043   indirect_ptable_clone_ud_deinit(ud);
1044  }
1045  {
1046   MY_CXT_CLONE;
1047   MY_CXT.map         = ptable_new();
1048   MY_CXT.tbl         = t;
1049   MY_CXT.owner       = aTHX;
1050   MY_CXT.global_code = global_code_dup;
1051  }
1052  gv = gv_fetchpv(__PACKAGE__ "::_THREAD_CLEANUP", 0, SVt_PVCV);
1053  if (gv) {
1054   CV *cv = GvCV(gv);
1055   if (!PL_endav)
1056    PL_endav = newAV();
1057   SvREFCNT_inc(cv);
1058   if (!av_store(PL_endav, av_len(PL_endav) + 1, (SV *) cv))
1059    SvREFCNT_dec(cv);
1060   sv_magicext((SV *) PL_endav, NULL, PERL_MAGIC_ext, &indirect_endav_vtbl, NULL, 0);
1061  }
1062  XSRETURN(0);
1063
1064 void
1065 _THREAD_CLEANUP(...)
1066 PROTOTYPE: DISABLE
1067 PPCODE:
1068  indirect_thread_cleanup(aTHX_ NULL);
1069  XSRETURN(0);
1070
1071 #endif
1072
1073 SV *
1074 _tag(SV *value)
1075 PROTOTYPE: $
1076 CODE:
1077  RETVAL = indirect_tag(value);
1078 OUTPUT:
1079  RETVAL
1080
1081 void
1082 _global(SV *code)
1083 PROTOTYPE: $
1084 PPCODE:
1085  if (!SvOK(code))
1086   code = NULL;
1087  else if (SvROK(code))
1088   code = SvRV(code);
1089  {
1090   dMY_CXT;
1091   SvREFCNT_dec(MY_CXT.global_code);
1092   MY_CXT.global_code = SvREFCNT_inc(code);
1093  }
1094  XSRETURN(0);