C.xs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #include <EXTERN.h>
  2. #include <perl.h>
  3. #include <XSUB.h>
  4. #ifndef PM_GETRE
  5. # if defined(USE_ITHREADS) && (PERL_VERSION > 8)
  6. # define PM_GETRE(o) (INT2PTR(REGEXP*,SvIVX(PL_regex_pad[(o)->op_pmoffset])))
  7. # else
  8. # define PM_GETRE(o) ((o)->op_pmregexp)
  9. # endif
  10. #endif
  11. #ifndef RX_EXTFLAGS
  12. # define RX_EXTFLAGS(prog) ((prog)->extflags)
  13. #endif
  14. typedef struct magic *B__MAGIC;
  15. #if PERL_VERSION >= 11
  16. typedef struct p5rx *B__REGEXP;
  17. #endif
  18. #if PERL_VERSION >= 15
  19. typedef COP *B__COP;
  20. #endif
  21. static int
  22. my_runops(pTHX)
  23. {
  24. HV* regexp_hv = get_hv( "B::C::Regexp", 0 );
  25. SV* key = newSViv( 0 );
  26. DEBUG_l(Perl_deb(aTHX_ "Entering new RUNOPS level (B::C)\n"));
  27. do {
  28. #if (PERL_VERSION < 13) || ((PERL_VERSION == 13) && (PERL_SUBVERSION < 2))
  29. PERL_ASYNC_CHECK();
  30. #endif
  31. if (PL_debug) {
  32. if (PL_watchaddr && (*PL_watchaddr != PL_watchok))
  33. PerlIO_printf(Perl_debug_log,
  34. "WARNING: %"UVxf" changed from %"UVxf" to %"UVxf"\n",
  35. PTR2UV(PL_watchaddr), PTR2UV(PL_watchok),
  36. PTR2UV(*PL_watchaddr));
  37. #if defined(DEBUGGING) \
  38. && !(defined(_WIN32) || (defined(__CYGWIN__) && (__GNUC__ > 3)) || defined(AIX))
  39. # if (PERL_VERSION > 7)
  40. if (DEBUG_s_TEST_) debstack();
  41. if (DEBUG_t_TEST_) debop(PL_op);
  42. # else
  43. DEBUG_s(debstack());
  44. DEBUG_t(debop(PL_op));
  45. # endif
  46. #endif
  47. }
  48. if( PL_op->op_type == OP_QR ) {
  49. PMOP* op;
  50. REGEXP* rx = PM_GETRE( (PMOP*)PL_op );
  51. SV* rv = newSViv( 0 );
  52. New(0, op, 1, PMOP );
  53. Copy( PL_op, op, 1, PMOP );
  54. /* we need just the flags */
  55. op->op_next = NULL;
  56. op->op_sibling = NULL;
  57. op->op_first = NULL;
  58. op->op_last = NULL;
  59. #if PERL_VERSION < 10
  60. op->op_pmreplroot = NULL;
  61. op->op_pmreplstart = NULL;
  62. op->op_pmnext = NULL;
  63. #endif
  64. #if defined(USE_ITHREADS) && (PERL_VERSION > 7)
  65. op->op_pmoffset = 0;
  66. #else
  67. op->op_pmregexp = 0;
  68. #endif
  69. sv_setiv( key, PTR2IV( rx ) );
  70. sv_setref_iv( rv, "B::PMOP", PTR2IV( op ) );
  71. hv_store_ent( regexp_hv, key, rv, 0 );
  72. }
  73. } while ((PL_op = CALL_FPTR(PL_op->op_ppaddr)(aTHX)));
  74. SvREFCNT_dec( key );
  75. TAINT_NOT;
  76. return 0;
  77. }
  78. MODULE = B__MAGIC PACKAGE = B::MAGIC
  79. #if PERL_VERSION < 7
  80. SV*
  81. precomp(mg)
  82. B::MAGIC mg
  83. CODE:
  84. if (mg->mg_type == 'r') {
  85. REGEXP* rx = (REGEXP*)mg->mg_obj;
  86. RETVAL = Nullsv;
  87. if (rx)
  88. RETVAL = newSVpvn( rx->precomp, rx->prelen );
  89. }
  90. else {
  91. croak( "precomp is only meaningful on r-magic" );
  92. }
  93. OUTPUT:
  94. RETVAL
  95. #endif
  96. MODULE = B PACKAGE = B::REGEXP PREFIX = RX_
  97. #if PERL_VERSION > 10
  98. U32
  99. RX_EXTFLAGS(rx)
  100. B::REGEXP rx
  101. #endif
  102. MODULE = B PACKAGE = B::COP PREFIX = COP_
  103. #if (PERL_VERSION >= 15) && defined(USE_ITHREADS) && defined(CopSTASH_flags)
  104. #define COP_stashflags(o) CopSTASH_flags(o)
  105. U32
  106. COP_stashflags(o)
  107. B::COP o
  108. #endif
  109. MODULE=B__C PACKAGE=B::C
  110. PROTOTYPES: DISABLE
  111. #if PERL_VERSION >= 11
  112. CV*
  113. method_cv(meth, packname)
  114. SV* meth;
  115. char *packname;
  116. CODE:
  117. U32 hash;
  118. HV* stash; /* XXX from op before, also on the run-time stack */
  119. GV* gv;
  120. hash = SvSHARED_HASH(meth);
  121. stash = gv_stashpv(packname, TRUE);
  122. if (hash) {
  123. const HE* const he = hv_fetch_ent(stash, meth, 0, hash);
  124. if (he) {
  125. gv = MUTABLE_GV(HeVAL(he));
  126. if (isGV(gv) && GvCV(gv) &&
  127. (!GvCVGEN(gv) || GvCVGEN(gv)
  128. == (PL_sub_generation + HvMROMETA(stash)->cache_gen)))
  129. RETVAL = (CV*)MUTABLE_SV(GvCV(gv));
  130. return;
  131. }
  132. }
  133. /* public API since 5.11 */
  134. gv = gv_fetchmethod_flags(stash,
  135. SvPV_nolen_const(meth),
  136. GV_AUTOLOAD | GV_CROAK);
  137. assert(gv);
  138. RETVAL = isGV(gv) ? (CV*)MUTABLE_SV(GvCV(gv)) : (CV*)MUTABLE_SV(gv);
  139. OUTPUT:
  140. RETVAL
  141. #endif
  142. BOOT:
  143. PL_runops = my_runops;