C.xs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. #define PERL_NO_GET_CONTEXT
  2. #include <EXTERN.h>
  3. #include <perl.h>
  4. #include <XSUB.h>
  5. #ifndef PM_GETRE
  6. # if defined(USE_ITHREADS) && (PERL_VERSION > 8)
  7. # define PM_GETRE(o) (INT2PTR(REGEXP*,SvIVX(PL_regex_pad[(o)->op_pmoffset])))
  8. # else
  9. # define PM_GETRE(o) ((o)->op_pmregexp)
  10. # endif
  11. #endif
  12. #ifndef RX_EXTFLAGS
  13. # define RX_EXTFLAGS(prog) ((prog)->extflags)
  14. #endif
  15. #if PERL_VERSION > 17 && (PERL_VERSION < 19 || (PERL_VERSION == 19 && PERL_SUBVERSION < 4))
  16. #define need_op_slabbed
  17. #endif
  18. #if PERL_VERSION == 19 && (PERL_SUBVERSION >=2 && PERL_SUBVERSION <= 4)
  19. #define need_op_folded
  20. #endif
  21. typedef struct magic *B__MAGIC;
  22. #if PERL_VERSION >= 11
  23. typedef struct p5rx *B__REGEXP;
  24. #endif
  25. typedef COP *B__COP;
  26. typedef OP *B__OP;
  27. typedef HV *B__HV;
  28. STATIC U32 a_hash = 0;
  29. typedef struct {
  30. U32 bits;
  31. IV require_tag;
  32. } a_hint_t;
  33. #if PERL_VERSION >= 10
  34. static const char* const svclassnames[] = {
  35. "B::NULL",
  36. #if PERL_VERSION < 19
  37. "B::BIND",
  38. #endif
  39. "B::IV",
  40. "B::NV",
  41. #if PERL_VERSION <= 10
  42. "B::RV",
  43. #endif
  44. "B::PV",
  45. #if PERL_VERSION >= 19
  46. "B::INVLIST",
  47. #endif
  48. "B::PVIV",
  49. "B::PVNV",
  50. "B::PVMG",
  51. #if PERL_VERSION >= 11
  52. "B::REGEXP",
  53. #endif
  54. "B::GV",
  55. "B::PVLV",
  56. "B::AV",
  57. "B::HV",
  58. "B::CV",
  59. "B::FM",
  60. "B::IO",
  61. };
  62. #define MY_CXT_KEY "B::C::_guts" XS_VERSION
  63. typedef struct {
  64. int x_walkoptree_debug; /* Flag for walkoptree debug hook */
  65. SV * x_specialsv_list[7];
  66. } my_cxt_t;
  67. START_MY_CXT
  68. #define walkoptree_debug (MY_CXT.x_walkoptree_debug)
  69. #define specialsv_list (MY_CXT.x_specialsv_list)
  70. static SV *
  71. make_sv_object(pTHX_ SV *sv)
  72. {
  73. SV *const arg = sv_newmortal();
  74. const char *type = 0;
  75. IV iv;
  76. dMY_CXT;
  77. for (iv = 0; iv < (IV)(sizeof(specialsv_list)/sizeof(SV*)); iv++) {
  78. if (sv == specialsv_list[iv]) {
  79. type = "B::SPECIAL";
  80. break;
  81. }
  82. }
  83. if (!type) {
  84. type = svclassnames[SvTYPE(sv)];
  85. iv = PTR2IV(sv);
  86. }
  87. sv_setiv(newSVrv(arg, type), iv);
  88. return arg;
  89. }
  90. #endif
  91. static int
  92. my_runops(pTHX)
  93. {
  94. HV* regexp_hv = get_hv( "B::C::Regexp", 0 );
  95. SV* key = newSViv( 0 );
  96. DEBUG_l(Perl_deb(aTHX_ "Entering new RUNOPS level (B::C)\n"));
  97. do {
  98. #if (PERL_VERSION < 13) || ((PERL_VERSION == 13) && (PERL_SUBVERSION < 2))
  99. PERL_ASYNC_CHECK();
  100. #endif
  101. if (PL_debug) {
  102. if (PL_watchaddr && (*PL_watchaddr != PL_watchok))
  103. PerlIO_printf(Perl_debug_log,
  104. "WARNING: %"UVxf" changed from %"UVxf" to %"UVxf"\n",
  105. PTR2UV(PL_watchaddr), PTR2UV(PL_watchok),
  106. PTR2UV(*PL_watchaddr));
  107. #if defined(DEBUGGING) \
  108. && !(defined(_WIN32) || (defined(__CYGWIN__) && (__GNUC__ > 3)) || defined(AIX))
  109. # if (PERL_VERSION > 7)
  110. if (DEBUG_s_TEST_) debstack();
  111. if (DEBUG_t_TEST_) debop(PL_op);
  112. # else
  113. DEBUG_s(debstack());
  114. DEBUG_t(debop(PL_op));
  115. # endif
  116. #endif
  117. }
  118. if( PL_op->op_type == OP_QR ) {
  119. PMOP* op;
  120. REGEXP* rx = PM_GETRE( (PMOP*)PL_op );
  121. SV* rv = newSViv( 0 );
  122. New(0, op, 1, PMOP );
  123. Copy( PL_op, op, 1, PMOP );
  124. /* we need just the flags */
  125. op->op_next = NULL;
  126. op->op_sibling = NULL;
  127. op->op_first = NULL;
  128. op->op_last = NULL;
  129. #if PERL_VERSION < 10
  130. op->op_pmreplroot = NULL;
  131. op->op_pmreplstart = NULL;
  132. op->op_pmnext = NULL;
  133. #endif
  134. #if defined(USE_ITHREADS) && (PERL_VERSION > 7)
  135. op->op_pmoffset = 0;
  136. #else
  137. op->op_pmregexp = 0;
  138. #endif
  139. sv_setiv( key, PTR2IV( rx ) );
  140. sv_setref_iv( rv, "B::PMOP", PTR2IV( op ) );
  141. hv_store_ent( regexp_hv, key, rv, 0 );
  142. }
  143. } while ((PL_op = CALL_FPTR(PL_op->op_ppaddr)(aTHX)));
  144. SvREFCNT_dec( key );
  145. TAINT_NOT;
  146. return 0;
  147. }
  148. MODULE = B__MAGIC PACKAGE = B::MAGIC
  149. #if PERL_VERSION < 7
  150. SV*
  151. precomp(mg)
  152. B::MAGIC mg
  153. CODE:
  154. if (mg->mg_type == 'r') {
  155. REGEXP* rx = (REGEXP*)mg->mg_obj;
  156. RETVAL = Nullsv;
  157. if (rx)
  158. RETVAL = newSVpvn( rx->precomp, rx->prelen );
  159. }
  160. else {
  161. croak( "precomp is only meaningful on r-magic" );
  162. }
  163. OUTPUT:
  164. RETVAL
  165. #endif
  166. MODULE = B PACKAGE = B::REGEXP PREFIX = RX_
  167. #if PERL_VERSION > 10
  168. U32
  169. RX_EXTFLAGS(rx)
  170. B::REGEXP rx
  171. #endif
  172. MODULE = B PACKAGE = B::COP PREFIX = COP_
  173. #if (PERL_VERSION >= 15) && defined(USE_ITHREADS) && defined(CopSTASH_flags)
  174. #define COP_stashflags(o) CopSTASH_flags(o)
  175. U32
  176. COP_stashflags(o)
  177. B::COP o
  178. #endif
  179. MODULE = B__CC PACKAGE = B::CC
  180. PROTOTYPES: DISABLE
  181. # Perl_ck_null is not exported on Windows, so disable autovivification optimizations there
  182. U32
  183. _autovivification(cop)
  184. B::COP cop
  185. CODE:
  186. {
  187. SV *hint;
  188. IV h;
  189. RETVAL = 1;
  190. if (PL_check[OP_PADSV] != PL_check[0]) {
  191. char *package = CopSTASHPV(cop);
  192. #ifdef cop_hints_fetch_pvn
  193. hint = cop_hints_fetch_pvn(cop, "autovivification", strlen("autovivification"), a_hash, 0);
  194. #elif PERL_VERSION > 9
  195. hint = Perl_refcounted_he_fetch(aTHX_ cop->cop_hints_hash,
  196. NULL, "autovivification", strlen("autovivification"), 0, a_hash);
  197. #else
  198. SV **val = hv_fetch(GvHV(PL_hintgv), "autovivification", strlen("autovivification"), 0);
  199. if (!val)
  200. return;
  201. hint = *val;
  202. #endif
  203. if (!(hint && SvIOK(hint)))
  204. return;
  205. h = SvIVX(hint);
  206. if (h & 4) /* A_HINT_FETCH 4 */
  207. RETVAL = 0;
  208. }
  209. }
  210. OUTPUT:
  211. RETVAL
  212. MODULE = B__OP PACKAGE = B::OP PREFIX = op_
  213. #ifdef need_op_slabbed
  214. I32
  215. op_slabbed(op)
  216. B::OP op
  217. PPCODE:
  218. PUSHi(op->op_slabbed);
  219. I32
  220. op_savefree(op)
  221. B::OP op
  222. PPCODE:
  223. PUSHi(op->op_savefree);
  224. I32
  225. op_static(op)
  226. B::OP op
  227. PPCODE:
  228. PUSHi(op->op_static);
  229. #endif
  230. #ifdef need_op_folded
  231. I32
  232. op_folded(op)
  233. B::OP op
  234. PPCODE:
  235. PUSHi(op->op_folded);
  236. #endif
  237. MODULE = B PACKAGE = B::HV PREFIX = Hv
  238. #if PERL_VERSION >= 10
  239. void
  240. HvARRAY_utf8(hv)
  241. B::HV hv
  242. PPCODE:
  243. if (HvKEYS(hv) > 0) {
  244. HE *he;
  245. (void)hv_iterinit(hv);
  246. EXTEND(sp, HvKEYS(hv) * 2);
  247. while ((he = hv_iternext(hv))) {
  248. if (HeSVKEY(he)) {
  249. mPUSHs(HeSVKEY(he));
  250. } else if (HeKUTF8(he)) {
  251. PUSHs(newSVpvn_flags(HeKEY(he), HeKLEN(he), SVf_UTF8|SVs_TEMP));
  252. } else {
  253. mPUSHp(HeKEY(he), HeKLEN(he));
  254. }
  255. PUSHs(make_sv_object(aTHX_ HeVAL(he)));
  256. }
  257. }
  258. #endif
  259. MODULE = B__C PACKAGE = B::C
  260. PROTOTYPES: DISABLE
  261. #if PERL_VERSION >= 11
  262. CV*
  263. method_cv(meth, packname)
  264. SV* meth;
  265. char *packname;
  266. CODE:
  267. U32 hash;
  268. HV* stash; /* XXX from op before, also on the run-time stack */
  269. GV* gv;
  270. hash = SvSHARED_HASH(meth);
  271. stash = gv_stashpv(packname, TRUE);
  272. if (hash) {
  273. const HE* const he = hv_fetch_ent(stash, meth, 0, hash);
  274. if (he) {
  275. gv = MUTABLE_GV(HeVAL(he));
  276. if (isGV(gv) && GvCV(gv) &&
  277. (!GvCVGEN(gv) || GvCVGEN(gv)
  278. == (PL_sub_generation + HvMROMETA(stash)->cache_gen)))
  279. RETVAL = (CV*)MUTABLE_SV(GvCV(gv));
  280. return;
  281. }
  282. }
  283. /* public API since 5.11 */
  284. gv = gv_fetchmethod_flags(stash,
  285. SvPV_nolen_const(meth),
  286. GV_AUTOLOAD | GV_CROAK);
  287. assert(gv);
  288. RETVAL = isGV(gv) ? (CV*)MUTABLE_SV(GvCV(gv)) : (CV*)MUTABLE_SV(gv);
  289. OUTPUT:
  290. RETVAL
  291. #endif
  292. BOOT:
  293. #if PERL_VERSION >= 10
  294. {
  295. MY_CXT_INIT;
  296. #endif
  297. PL_runops = my_runops;
  298. #if PERL_VERSION >= 10
  299. {
  300. dMY_CXT;
  301. specialsv_list[0] = Nullsv;
  302. specialsv_list[1] = &PL_sv_undef;
  303. specialsv_list[2] = &PL_sv_yes;
  304. specialsv_list[3] = &PL_sv_no;
  305. specialsv_list[4] = (SV *) pWARN_ALL;
  306. specialsv_list[5] = (SV *) pWARN_NONE;
  307. specialsv_list[6] = (SV *) pWARN_STD;
  308. }
  309. }
  310. #endif