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