Bytecode.pm 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575
  1. # B::Bytecode.pm - The bytecode compiler (.plc), loaded by ByteLoader
  2. #
  3. # Copyright (c) 1994-1999 Malcolm Beattie. All rights reserved.
  4. # Copyright (c) 2003 Enache Adrian. All rights reserved.
  5. # Copyright (c) 2008-2011 Reini Urban <rurban@cpan.org>. All rights reserved.
  6. # Copyright (c) 2011-2013 cPanel Inc. All rights reserved.
  7. # This module is free software; you can redistribute and/or modify
  8. # it under the same terms as Perl itself.
  9. # Reviving 5.6 support here is work in progress, and not yet enabled.
  10. # So far the original is used instead, even if the list of failed tests
  11. # is impressive: 3,6,8..10,12,15,16,18,25..28. Pretty broken.
  12. package B::Bytecode;
  13. our $VERSION = '1.14';
  14. use 5.008;
  15. use B qw( class main_cv main_root main_start
  16. begin_av init_av end_av cstring comppadlist
  17. OPf_SPECIAL OPf_STACKED OPf_MOD
  18. OPpLVAL_INTRO SVf_READONLY SVf_ROK );
  19. use B::Assembler qw(asm newasm endasm);
  20. BEGIN {
  21. if ( $] < 5.009 ) {
  22. require B::Asmdata;
  23. B::Asmdata->import(qw(@specialsv_name @optype));
  24. eval q[
  25. sub SVp_NOK() {}; # unused
  26. sub SVf_NOK() {}; # unused
  27. ];
  28. }
  29. else {
  30. B->import(qw(SVp_NOK SVf_NOK @specialsv_name @optype));
  31. }
  32. if ( $] > 5.007 ) {
  33. B->import(qw(defstash curstash inc_gv dowarn
  34. warnhook diehook SVt_PVGV
  35. SVf_FAKE));
  36. } else {
  37. B->import(qw(walkoptree walksymtable));
  38. }
  39. if ($] > 5.017) {
  40. B->import('SVf_IsCOW') ;
  41. } else {
  42. eval q[
  43. sub SVf_IsCOW() {}; # unused
  44. ];
  45. }
  46. if ( $] >= 5.017005 ) {
  47. @B::PAD::ISA = ('B::AV');
  48. }
  49. }
  50. use strict;
  51. use Config;
  52. use B::Concise;
  53. #################################################
  54. my $PERL56 = ( $] < 5.008001 );
  55. my $PERL510 = ( $] >= 5.009005 );
  56. my $PERL512 = ( $] >= 5.011 );
  57. #my $PERL514 = ( $] >= 5.013002 );
  58. my $PERL518 = ( $] >= 5.017006 );
  59. my $PERL520 = ( $] >= 5.019002 );
  60. my $DEBUGGING = ($Config{ccflags} =~ m/-DDEBUGGING/);
  61. our ($quiet, $includeall, $savebegins, $T_inhinc);
  62. my ( $varix, $opix, %debug, %walked, %files, @cloop );
  63. my %strtab = ( 0, 0 );
  64. my %svtab = ( 0, 0 );
  65. my %optab = ( 0, 0 );
  66. my %spectab = $PERL56 ? () : ( 0, 0 ); # we need the special Nullsv on 5.6 (?)
  67. my $tix = $PERL56 ? 0 : 1;
  68. my %ops = ( 0, 0 );
  69. my @packages; # list of packages to compile. 5.6 only
  70. # sub asm ($;$$) { }
  71. sub nice ($) { }
  72. sub nice1 ($) { }
  73. my %optype_enum;
  74. my ($SVt_PVGV, $SVf_FAKE, $POK);
  75. if ($PERL56) {
  76. sub dowarn {};
  77. $SVt_PVGV = 13;
  78. $SVf_FAKE = 0x00100000;
  79. $POK = 0x00040000 | 0x04000000;
  80. sub MAGICAL56 { $_[0]->FLAGS & 0x000E000 } #(SVs_GMG|SVs_SMG|SVs_RMG)
  81. } else {
  82. no strict 'subs';
  83. $SVt_PVGV = SVt_PVGV;
  84. $SVf_FAKE = SVf_FAKE;
  85. }
  86. { # block necessary for caller to work
  87. my $caller = caller;
  88. if ( $] > 5.017 and $] < 5.019004 and ($caller eq 'O' or $caller eq 'Od' )) {
  89. require XSLoader;
  90. XSLoader::load('B::C'); # for op->slabbed... workarounds
  91. }
  92. }
  93. for ( my $i = 0 ; $i < @optype ; $i++ ) {
  94. $optype_enum{ $optype[$i] } = $i;
  95. }
  96. BEGIN {
  97. my $ithreads = $Config::Config{'useithreads'} eq 'define';
  98. eval qq{
  99. sub ITHREADS() { $ithreads }
  100. sub VERSION() { $] }
  101. };
  102. die $@ if $@;
  103. }
  104. sub as_hex {$quiet ? undef : sprintf("0x%x",shift)}
  105. #################################################
  106. # This is for -S commented assembler output
  107. sub op_flags {
  108. return '' if $quiet;
  109. # B::Concise::op_flags($_[0]); # too terse
  110. # common flags (see BASOP.op_flags in op.h)
  111. my ($x) = @_;
  112. my (@v);
  113. push @v, "WANT_VOID" if ( $x & 3 ) == 1;
  114. push @v, "WANT_SCALAR" if ( $x & 3 ) == 2;
  115. push @v, "WANT_LIST" if ( $x & 3 ) == 3;
  116. push @v, "KIDS" if $x & 4;
  117. push @v, "PARENS" if $x & 8;
  118. push @v, "REF" if $x & 16;
  119. push @v, "MOD" if $x & 32;
  120. push @v, "STACKED" if $x & 64;
  121. push @v, "SPECIAL" if $x & 128;
  122. return join( ",", @v );
  123. }
  124. # This is also for -S commented assembler output
  125. sub sv_flags {
  126. return '' if $quiet or $B::Concise::VERSION < 0.74; # or ($] == 5.010);
  127. return '' unless $debug{Comment};
  128. return 'B::SPECIAL' if $_[0]->isa('B::SPECIAL');
  129. return 'B::PADLIST' if $_[0]->isa('B::PADLIST');
  130. return 'B::NULL' if $_[0]->isa('B::NULL');
  131. my ($sv) = @_;
  132. my %h;
  133. # TODO: Check with which Concise and B versions this works. 5.10.0 fails.
  134. # B::Concise 0.66 fails also
  135. sub B::Concise::fmt_line { return shift; }
  136. my $op = $ops{ $tix - 1 };
  137. if (ref $op and !$op->targ) { # targ assumes a valid curcv
  138. %h = B::Concise::concise_op( $op );
  139. }
  140. B::Concise::concise_sv( $_[0], \%h, 0 );
  141. }
  142. sub pvstring {
  143. my $pv = shift;
  144. defined($pv) ? cstring( $pv . "\0" ) : "\"\"";
  145. }
  146. sub pvix {
  147. my $str = pvstring shift;
  148. my $ix = $strtab{$str};
  149. defined($ix) ? $ix : do {
  150. nice1 "-PV- $tix";
  151. B::Assembler::maxsvix($tix) if $debug{A};
  152. asm "newpv", $str;
  153. asm "stpv", $strtab{$str} = $tix;
  154. $tix++;
  155. }
  156. }
  157. sub B::OP::ix {
  158. my $op = shift;
  159. my $ix = $optab{$$op};
  160. defined($ix) ? $ix : do {
  161. nice "[" . $op->name . " $tix]";
  162. $ops{$tix} = $op;
  163. # Note: This left-shift 7 encoding of the optype has nothing to do with OCSHIFT
  164. # in opcode.pl
  165. # The counterpart is hardcoded in Byteloader/bytecode.h: BSET_newopx
  166. my $arg = $PERL56 ? $optype_enum{class($op)} : $op->size | $op->type << 7;
  167. my $opsize = $PERL56 ? '?' : $op->size;
  168. if (ref($op) eq 'B::OP') { # check wrong BASEOPs
  169. # [perl #80622] Introducing the entrytry hack, needed since 5.12,
  170. # fixed with 5.13.8 a425677
  171. # ck_eval upgrades the UNOP entertry to a LOGOP, but B gets us just a
  172. # B::OP (BASEOP).
  173. # op->other points to the leavetry op, which is needed for the eval scope.
  174. if ($op->name eq 'entertry') {
  175. $opsize = $op->size + (2*$Config{ptrsize});
  176. $arg = $PERL56 ? $optype_enum{LOGOP} : $opsize | $optype_enum{LOGOP} << 7;
  177. warn "[perl #80622] Upgrading entertry from BASEOP to LOGOP...\n" unless $quiet;
  178. bless $op, 'B::LOGOP';
  179. } elsif ($op->name eq 'aelemfast') {
  180. if (0) {
  181. my $class = ITHREADS ? 'PADOP' : 'SVOP';
  182. my $type = ITHREADS ? $optype_enum{PADOP} : $optype_enum{SVOP};
  183. $opsize = $op->size + $Config{ptrsize};
  184. $arg = $PERL56 ? $type : $opsize | $type << 7;
  185. warn "Upgrading aelemfast from BASEOP to $class...\n" unless $quiet;
  186. bless $op, "B::$class";
  187. }
  188. } elsif ($DEBUGGING) { # only needed when we want to check for new wrong BASEOP's
  189. if (eval "require Opcodes;") {
  190. my $class = Opcodes::opclass($op->type);
  191. if ($class > 0) {
  192. my $classname = $optype[$class];
  193. if ($classname) {
  194. my $name = $op->name;
  195. warn "Upgrading $name BASEOP to $classname...\n" unless $quiet;
  196. bless $op, "B::".$classname;
  197. }
  198. }
  199. }
  200. }
  201. }
  202. B::Assembler::maxopix($tix) if $debug{A};
  203. asm "newopx", $arg, sprintf( "$arg=size:%s,type:%d", $opsize, $op->type );
  204. asm "stop", $tix if $PERL56;
  205. $optab{$$op} = $opix = $ix = $tix++;
  206. $op->bsave($ix);
  207. $ix;
  208. }
  209. }
  210. sub B::SPECIAL::ix {
  211. my $spec = shift;
  212. my $ix = $spectab{$$spec};
  213. defined($ix) ? $ix : do {
  214. B::Assembler::maxsvix($tix) if $debug{A};
  215. nice "[SPECIAL $tix]";
  216. asm "ldspecsvx", $$spec, $specialsv_name[$$spec];
  217. asm "stsv", $tix if $PERL56;
  218. $spectab{$$spec} = $varix = $tix++;
  219. }
  220. }
  221. sub B::SV::ix {
  222. my $sv = shift;
  223. my $ix = $svtab{$$sv};
  224. defined($ix) ? $ix : do {
  225. nice '[' . class($sv) . " $tix]";
  226. B::Assembler::maxsvix($tix) if $debug{A};
  227. my $flags = $sv->FLAGS;
  228. my $type = $flags & 0xff; # SVTYPEMASK
  229. # Set TMP_on, MY_off, not to be tidied (test 48),
  230. # otherwise pad_tidy will set PADSTALE_on and assert. Since 5.16 TMP and STALE share the same bit.
  231. #if (ref $sv eq 'B::NULL' and $sv->REFCNT > 1 and $] >= 5.016) {
  232. # $flags |= 0x00020000; # SvPADTMP_on
  233. # $flags &= ~0x00040000; # SvPADMY_off
  234. #}
  235. asm "newsvx", $flags,
  236. $debug{Comment} ? sprintf("type=%d,flags=0x%x,%s", $type, $flags, sv_flags($sv)) : '';
  237. asm "stsv", $tix if $PERL56;
  238. $svtab{$$sv} = $varix = $ix = $tix++;
  239. $sv->bsave($ix);
  240. $ix;
  241. }
  242. }
  243. sub B::PADLIST::ix {
  244. my $padl = shift;
  245. my $ix = $svtab{$$padl};
  246. defined($ix) ? $ix : do {
  247. nice '[' . class($padl) . " $tix]";
  248. B::Assembler::maxsvix($tix) if $debug{A};
  249. asm "newpadlx", 1;
  250. $svtab{$$padl} = $varix = $ix = $tix++;
  251. $padl->bsave($ix);
  252. $ix;
  253. }
  254. }
  255. sub B::GV::ix {
  256. my ( $gv, $desired ) = @_;
  257. my $ix = $svtab{$$gv};
  258. defined($ix) ? $ix : do {
  259. if ( $debug{G} and !$PERL510 ) {
  260. select *STDERR;
  261. eval "require B::Debug;";
  262. $gv->B::GV::debug;
  263. select *STDOUT;
  264. }
  265. if ( ( $PERL510 and $gv->isGV_with_GP )
  266. or ( !$PERL510 and !$PERL56 and $gv->GP ) )
  267. { # only gv with gp
  268. my ( $svix, $avix, $hvix, $cvix, $ioix, $formix );
  269. # 510 without debugging misses B::SPECIAL::NAME
  270. my $name;
  271. if ( $PERL510
  272. and ( $gv->STASH->isa('B::SPECIAL') or $gv->isa('B::SPECIAL') ) )
  273. {
  274. $name = '_';
  275. nice '[GV] # "_"';
  276. return 0;
  277. }
  278. else {
  279. $name = $gv->STASH->NAME . "::"
  280. . ( class($gv) eq 'B::SPECIAL' ? '_' : $gv->NAME );
  281. }
  282. nice "[GV $tix]";
  283. B::Assembler::maxsvix($tix) if $debug{A};
  284. asm "gv_fetchpvx", cstring $name;
  285. asm "stsv", $tix if $PERL56;
  286. $svtab{$$gv} = $varix = $ix = $tix++;
  287. asm "sv_flags", $gv->FLAGS, as_hex($gv->FLAGS);
  288. asm "sv_refcnt", $gv->REFCNT;
  289. asm "xgv_flags", $gv->GvFLAGS, as_hex($gv->GvFLAGS);
  290. asm "gp_refcnt", $gv->GvREFCNT;
  291. asm "load_glob", $ix if $name eq "CORE::GLOBAL::glob";
  292. return $ix
  293. unless $desired || desired $gv;
  294. $svix = $gv->SV->ix;
  295. $avix = $gv->AV->ix;
  296. $hvix = $gv->HV->ix;
  297. # XXX {{{{
  298. my $cv = $gv->CV;
  299. $cvix = $$cv && defined $files{ $cv->FILE } ? $cv->ix : 0;
  300. my $form = $gv->FORM;
  301. $formix = $$form && defined $files{ $form->FILE } ? $form->ix : 0;
  302. $ioix = $name !~ /STDOUT$/ ? $gv->IO->ix : 0;
  303. # }}}} XXX
  304. nice1 "-GP-", asm "ldsv", $varix = $ix, sv_flags($gv) unless $ix == $varix;
  305. asm "gp_sv", $svix, sv_flags( $gv->SV ) if $svix;
  306. asm "gp_av", $avix, sv_flags( $gv->AV ) if $avix;
  307. asm "gp_hv", $hvix, sv_flags( $gv->HV ) if $hvix;
  308. asm "gp_cv", $cvix, sv_flags( $gv->CV ) if $cvix;
  309. asm "gp_io", $ioix if $ioix;
  310. asm "gp_cvgen", $gv->CVGEN if $gv->CVGEN;
  311. asm "gp_form", $formix if $formix;
  312. asm "gp_file", pvix $gv->FILE;
  313. asm "gp_line", $gv->LINE;
  314. asm "formfeed", $svix if $name eq "main::\cL";
  315. }
  316. else {
  317. nice "[GV $tix]";
  318. B::Assembler::maxsvix($tix) if $debug{A};
  319. asm "newsvx", $gv->FLAGS, $debug{Comment} ? sv_flags($gv) : '';
  320. asm "stsv", $tix if $PERL56;
  321. $svtab{$$gv} = $varix = $ix = $tix++;
  322. if ( !$PERL510 ) {
  323. asm "xgv_flags", $gv->GvFLAGS; # GV_without_GP has no GvFlags
  324. }
  325. if ( !$PERL510 and !$PERL56 and $gv->STASH ) {
  326. my $stashix = $gv->STASH->ix;
  327. asm "xgv_stash", $stashix;
  328. }
  329. if ($PERL510 and $gv->FLAGS & 0x40000000) { # SVpbm_VALID
  330. my $bm = bless $gv, "B::BM";
  331. $bm->bsave($ix); # also saves magic
  332. } else {
  333. $gv->B::PVMG::bsave($ix);
  334. }
  335. }
  336. $ix;
  337. }
  338. }
  339. sub B::HV::ix {
  340. my $hv = shift;
  341. my $ix = $svtab{$$hv};
  342. defined($ix) ? $ix : do {
  343. my ( $ix, $i, @array );
  344. my $name = $hv->NAME;
  345. if ($name) {
  346. nice "[STASH $tix]";
  347. B::Assembler::maxsvix($tix) if $debug{A};
  348. asm "gv_stashpvx", cstring $name;
  349. asm "ldsv", $tix if $PERL56;
  350. asm "sv_flags", $hv->FLAGS, as_hex($hv->FLAGS);
  351. $svtab{$$hv} = $varix = $ix = $tix++;
  352. asm "xhv_name", pvix $name;
  353. # my $pmrootix = $hv->PMROOT->ix; # XXX
  354. asm "ldsv", $varix = $ix unless $ix == $varix;
  355. # asm "xhv_pmroot", $pmrootix; # XXX
  356. }
  357. else {
  358. nice "[HV $tix]";
  359. B::Assembler::maxsvix($tix) if $debug{A};
  360. asm "newsvx", $hv->FLAGS, $debug{Comment} ? sv_flags($hv) : '';
  361. asm "stsv", $tix if $PERL56;
  362. $svtab{$$hv} = $varix = $ix = $tix++;
  363. my $stashix = $hv->SvSTASH->ix;
  364. for ( @array = $hv->ARRAY ) {
  365. next if $i = not $i;
  366. $_ = $_->ix;
  367. }
  368. nice1 "-HV-", asm "ldsv", $varix = $ix unless $ix == $varix;
  369. ( $i = not $i ) ? asm( "newpv", pvstring $_) : asm( "hv_store", $_ )
  370. for @array;
  371. if ( VERSION < 5.009 ) {
  372. asm "xnv", $hv->NVX;
  373. }
  374. asm "xmg_stash", $stashix;
  375. asm( "xhv_riter", $hv->RITER ) if VERSION < 5.009;
  376. }
  377. asm "sv_refcnt", $hv->REFCNT;
  378. $ix;
  379. }
  380. }
  381. sub B::NULL::ix {
  382. my $sv = shift;
  383. $$sv ? $sv->B::SV::ix : 0;
  384. }
  385. sub B::NULL::opwalk { 0 }
  386. #################################################
  387. sub B::NULL::bsave {
  388. my ( $sv, $ix ) = @_;
  389. nice '-' . class($sv) . '-', asm "ldsv", $varix = $ix, sv_flags($sv)
  390. unless $ix == $varix;
  391. if ($PERL56) {
  392. asm "stsv", $ix;
  393. } else {
  394. asm "sv_refcnt", $sv->REFCNT;
  395. }
  396. }
  397. sub B::SV::bsave;
  398. *B::SV::bsave = *B::NULL::bsave;
  399. sub B::RV::bsave {
  400. my ( $sv, $ix ) = @_;
  401. my $rvix = $sv->RV->ix;
  402. $sv->B::NULL::bsave($ix);
  403. # RV with DEBUGGING already requires sv_flags before SvRV_set
  404. asm "sv_flags", $sv->FLAGS, as_hex($sv->FLAGS);
  405. asm "xrv", $rvix;
  406. }
  407. sub B::PV::bsave {
  408. my ( $sv, $ix ) = @_;
  409. $sv->B::NULL::bsave($ix);
  410. return unless $sv;
  411. if ($PERL56) {
  412. #$sv->B::SV::bsave;
  413. if ($sv->FLAGS & $POK) {
  414. asm "newpv", pvstring $sv->PV;
  415. asm "xpv";
  416. }
  417. } elsif ($PERL518 and (($sv->FLAGS & SVf_IsCOW) == SVf_IsCOW)) { # COW
  418. asm "newpv", pvstring $sv->PV;
  419. asm "xpvshared";
  420. } elsif ($PERL510 and (($sv->FLAGS & 0x09000000) == 0x09000000)) { # SHARED
  421. if ($sv->FLAGS & 0x40000000 and !($sv->FLAGS & 0x00008000)) { # pbm_VALID, !SCREAM
  422. asm "newpv", pvstring $sv->PVBM;
  423. } else {
  424. asm "newpv", pvstring $sv->PV;
  425. }
  426. asm "xpvshared";
  427. } elsif ($PERL510 and $sv->FLAGS & 0x40000000 and !($sv->FLAGS & 0x00008000)) { # pbm_VALID, !SCREAM
  428. asm "newpv", pvstring $sv->PVBM;
  429. asm "xpv";
  430. } else {
  431. asm "newpv", pvstring $sv->PV;
  432. asm "xpv";
  433. }
  434. }
  435. sub B::IV::bsave {
  436. my ( $sv, $ix ) = @_;
  437. return $sv->B::RV::bsave($ix)
  438. if $PERL512 and $sv->FLAGS & B::SVf_ROK;
  439. $sv->B::NULL::bsave($ix);
  440. if ($PERL56) {
  441. asm $sv->needs64bits ? "xiv64" : "xiv32", $sv->IVX;
  442. } else {
  443. asm "xiv", $sv->IVX;
  444. }
  445. }
  446. sub B::NV::bsave {
  447. my ( $sv, $ix ) = @_;
  448. $sv->B::NULL::bsave($ix);
  449. asm "xnv", sprintf "%.40g", $sv->NVX;
  450. }
  451. sub B::PVIV::bsave {
  452. my ( $sv, $ix ) = @_;
  453. if ($PERL56) {
  454. $sv->B::PV::bsave($ix);
  455. } else {
  456. $sv->POK ? $sv->B::PV::bsave($ix)
  457. : $sv->ROK ? $sv->B::RV::bsave($ix)
  458. : $sv->B::NULL::bsave($ix);
  459. }
  460. if ($PERL510) { # See note below in B::PVNV::bsave
  461. return if $sv->isa('B::AV');
  462. return if $sv->isa('B::HV');
  463. return if $sv->isa('B::CV');
  464. return if $sv->isa('B::GV');
  465. return if $sv->isa('B::IO');
  466. return if $sv->isa('B::FM');
  467. }
  468. bwarn( sprintf( "PVIV sv:%s flags:0x%x", class($sv), $sv->FLAGS ) )
  469. if $debug{M};
  470. if ($PERL56) {
  471. my $iv = $sv->IVX;
  472. asm $sv->needs64bits ? "xiv64" : "xiv32", $iv;
  473. } else {
  474. # PVIV GV 8009, GV flags & (4000|8000) illegal (SVpgv_GP|SVp_POK)
  475. asm "xiv", !ITHREADS
  476. && (($sv->FLAGS & ($SVf_FAKE|SVf_READONLY)) == ($SVf_FAKE|SVf_READONLY))
  477. ? "0 # but true" : $sv->IVX;
  478. }
  479. }
  480. sub B::PVNV::bsave {
  481. my ( $sv, $ix ) = @_;
  482. $sv->B::PVIV::bsave($ix);
  483. if ($PERL510) {
  484. # getting back to PVMG
  485. return if $sv->isa('B::AV');
  486. return if $sv->isa('B::HV');
  487. return if $sv->isa('B::CV');
  488. return if $sv->isa('B::FM');
  489. return if $sv->isa('B::GV');
  490. return if $sv->isa('B::IO');
  491. # cop_seq range instead of a double. (IV, NV)
  492. unless ($sv->FLAGS & (SVf_NOK|SVp_NOK)) {
  493. asm "cop_seq_low", $sv->COP_SEQ_RANGE_LOW;
  494. asm "cop_seq_high", $sv->COP_SEQ_RANGE_HIGH;
  495. return;
  496. }
  497. }
  498. asm "xnv", sprintf "%.40g", $sv->NVX;
  499. }
  500. sub B::PVMG::domagic {
  501. my ( $sv, $ix ) = @_;
  502. nice1 '-MAGICAL-'; # no empty line before
  503. my @mglist = $sv->MAGIC;
  504. my ( @mgix, @namix );
  505. for (@mglist) {
  506. my $mg = $_;
  507. push @mgix, $_->OBJ->ix;
  508. push @namix, $mg->PTR->ix if $mg->LENGTH == B::HEf_SVKEY;
  509. $_ = $mg;
  510. }
  511. nice1 '-' . class($sv) . '-', asm "ldsv", $varix = $ix unless $ix == $varix;
  512. for (@mglist) {
  513. next unless ord($_->TYPE);
  514. asm "sv_magic", ord($_->TYPE), cstring $_->TYPE;
  515. asm "mg_obj", shift @mgix; # D sets itself, see mg.c:mg_copy
  516. my $length = $_->LENGTH;
  517. if ( $length == B::HEf_SVKEY and !$PERL56) {
  518. asm "mg_namex", shift @namix;
  519. }
  520. elsif ($length) {
  521. asm "newpv", pvstring $_->PTR;
  522. $PERL56
  523. ? asm "mg_pv"
  524. : asm "mg_name";
  525. }
  526. }
  527. }
  528. sub B::PVMG::bsave {
  529. my ( $sv, $ix ) = @_;
  530. my $stashix = $sv->SvSTASH->ix;
  531. $sv->B::PVNV::bsave($ix);
  532. asm "xmg_stash", $stashix;
  533. # XXX added SV->MAGICAL to 5.6 for compat
  534. $sv->domagic($ix) if $PERL56 ? MAGICAL56($sv) : $sv->MAGICAL;
  535. }
  536. sub B::PVLV::bsave {
  537. my ( $sv, $ix ) = @_;
  538. my $targix = $sv->TARG->ix;
  539. $sv->B::PVMG::bsave($ix);
  540. asm "xlv_targ", $targix unless $PERL56; # XXX really? xlv_targ IS defined
  541. asm "xlv_targoff", $sv->TARGOFF;
  542. asm "xlv_targlen", $sv->TARGLEN;
  543. asm "xlv_type", $sv->TYPE;
  544. }
  545. sub B::BM::bsave {
  546. my ( $sv, $ix ) = @_;
  547. $sv->B::PVMG::bsave($ix);
  548. asm "xpv_cur", $sv->CUR if $] > 5.008;
  549. asm "xbm_useful", $sv->USEFUL;
  550. asm "xbm_previous", $sv->PREVIOUS;
  551. asm "xbm_rare", $sv->RARE;
  552. }
  553. sub B::IO::bsave {
  554. my ( $io, $ix ) = @_;
  555. my $topix = $io->TOP_GV->ix;
  556. my $fmtix = $io->FMT_GV->ix;
  557. my $bottomix = $io->BOTTOM_GV->ix;
  558. $io->B::PVMG::bsave($ix);
  559. asm "xio_lines", $io->LINES;
  560. asm "xio_page", $io->PAGE;
  561. asm "xio_page_len", $io->PAGE_LEN;
  562. asm "xio_lines_left", $io->LINES_LEFT;
  563. asm "xio_top_name", pvix $io->TOP_NAME;
  564. asm "xio_top_gv", $topix;
  565. asm "xio_fmt_name", pvix $io->FMT_NAME;
  566. asm "xio_fmt_gv", $fmtix;
  567. asm "xio_bottom_name", pvix $io->BOTTOM_NAME;
  568. asm "xio_bottom_gv", $bottomix;
  569. asm "xio_subprocess", $io->SUBPROCESS unless $PERL510;
  570. asm "xio_type", ord $io->IoTYPE;
  571. if ($PERL56) { # do not mess with PerlIO
  572. asm "xio_flags", $io->IoFLAGS;
  573. } else {
  574. # XXX IOf_NOLINE off was added with 5.8, but not used (?)
  575. asm "xio_flags", ord($io->IoFLAGS) & ~32; # XXX IOf_NOLINE 32
  576. }
  577. # issue93: restore std handles
  578. if (!$PERL56) {
  579. my $o = $io->object_2svref();
  580. eval "require ".ref($o).";";
  581. my $fd = $o->fileno();
  582. # use IO::Handle ();
  583. # my $fd = IO::Handle::fileno($o);
  584. bwarn( "io ix=$ix perlio no fileno for ".ref($o) ) if $fd < 0;
  585. my $i = 0;
  586. foreach (qw(stdin stdout stderr)) {
  587. if ($io->IsSTD($_) or $fd == -$i) { # negative stdout = error
  588. nice1 "-perlio_$_($fd)-";
  589. # bwarn( "io $ix perlio_$_($fd)" );
  590. asm "xio_flags", $io->IoFLAGS;
  591. asm "xio_ifp", $i;
  592. }
  593. $i++;
  594. }
  595. }
  596. }
  597. sub B::CV::bsave {
  598. my ( $cv, $ix ) = @_;
  599. my $stashix = $cv->STASH->ix;
  600. my $gvix = ($cv->GV and ref($cv->GV) ne 'B::SPECIAL') ? $cv->GV->ix : 0;
  601. my $padlistix = $cv->PADLIST->ix;
  602. my $outsideix = $cv->OUTSIDE->ix;
  603. my $startix = $cv->START->opwalk;
  604. my $rootix = $cv->ROOT->ix;
  605. # TODO 5.14 will need CvGV_set to add backref magic
  606. my $xsubanyix = ($cv->CONST and !$PERL56) ? $cv->XSUBANY->ix : 0;
  607. $cv->B::PVMG::bsave($ix);
  608. asm "xcv_stash", $stashix;
  609. asm "xcv_start", $startix;
  610. asm "xcv_root", $rootix;
  611. asm "xcv_xsubany", $xsubanyix unless $PERL56;
  612. asm "xcv_padlist", $padlistix;
  613. asm "xcv_outside", $outsideix;
  614. asm "xcv_outside_seq", $cv->OUTSIDE_SEQ unless $PERL56;
  615. asm "xcv_depth", $cv->DEPTH;
  616. # add the RC flag if there's no backref magic. eg END (48)
  617. my $cvflags = $cv->CvFLAGS;
  618. $cvflags |= 0x400 if $] >= 5.013 and !$cv->MAGIC;
  619. asm "xcv_flags", $cvflags;
  620. if ($gvix) {
  621. asm "xcv_gv", $gvix;
  622. } elsif ($] >= 5.018001 and $cv->NAME_HEK) { # ignore main_cv
  623. asm "xcv_name_hek", pvix $cv->NAME_HEK; # set name_hek for lexsub (#130)
  624. #} elsif ($] >= 5.017004) { # 5.18.0 empty name, missing B API
  625. # asm "xcv_name_hek", pvix "_";
  626. }
  627. asm "xcv_file", pvix $cv->FILE if $cv->FILE; # XXX AD
  628. }
  629. sub B::FM::bsave {
  630. my ( $form, $ix ) = @_;
  631. $form->B::CV::bsave($ix);
  632. asm "xfm_lines", $form->LINES;
  633. }
  634. sub B::PAD::bsave {
  635. my ( $av, $ix ) = @_;
  636. my @array = $av->ARRAY;
  637. $_ = $_->ix for @array; # save the elements
  638. $av->B::NULL::bsave($ix);
  639. # av_extend always allocs 3
  640. asm "av_extend", scalar @array if @array;
  641. asm "av_pushx", $_ for @array;
  642. }
  643. sub B::AV::bsave {
  644. my ( $av, $ix ) = @_;
  645. if (!$PERL56 and $av->MAGICAL) {
  646. $av->B::PVMG::bsave($ix);
  647. for ($av->MAGIC) {
  648. return if $_->TYPE eq 'P'; # 'P' tied AV has no ARRAY/FETCHSIZE,..., test 16
  649. # but e.g. 'I' (@ISA) has
  650. }
  651. }
  652. my @array = $av->ARRAY;
  653. $_ = $_->ix for @array; # hack. walks the ->ix methods to save the elements
  654. my $stashix = $av->SvSTASH->ix;
  655. nice "-AV-",
  656. asm "ldsv", $varix = $ix, sv_flags($av) unless $ix == $varix;
  657. if ($PERL56) {
  658. # SvREADONLY_off($av) w PADCONST
  659. asm "sv_flags", $av->FLAGS & ~SVf_READONLY, as_hex($av->FLAGS);
  660. $av->domagic($ix) if MAGICAL56($av);
  661. asm "xav_flags", $av->AvFLAGS, as_hex($av->AvFLAGS);
  662. asm "xav_max", -1;
  663. asm "xav_fill", -1;
  664. if ($av->FILL > -1) {
  665. asm "av_push", $_ for @array;
  666. } else {
  667. asm "av_extend", $av->MAX if $av->MAX >= 0 and $av->{ref} ne 'PAD';
  668. }
  669. asm "sv_flags", $av->FLAGS if $av->FLAGS & SVf_READONLY; # restore flags
  670. } else {
  671. #$av->domagic($ix) if $av->MAGICAL; # XXX need tests for magic arrays
  672. asm "av_extend", $av->MAX if $av->MAX >= 0;
  673. asm "av_pushx", $_ for @array;
  674. if ( !$PERL510 ) { # VERSION < 5.009
  675. asm "xav_flags", $av->AvFLAGS, as_hex($av->AvFLAGS);
  676. }
  677. # asm "xav_alloc", $av->AvALLOC if $] > 5.013002; # XXX new but not needed
  678. }
  679. asm "sv_refcnt", $av->REFCNT;
  680. asm "xmg_stash", $stashix;
  681. }
  682. sub B::PADLIST::bsave {
  683. my ( $padl, $ix ) = @_;
  684. my @array = $padl->ARRAY;
  685. bless $array[0], 'B::PAD';
  686. bless $array[1], 'B::PAD';
  687. my $ix0 = $array[0]->ix; # comppad_name
  688. my $ix1 = $array[1]->ix; # comppad syms
  689. nice "-PADLIST-",
  690. asm "ldsv", $varix = $ix unless $ix == $varix;
  691. asm "padl_name", $ix0;
  692. asm "padl_sym", $ix1;
  693. }
  694. sub B::GV::desired {
  695. my $gv = shift;
  696. my ( $cv, $form );
  697. if ( $debug{Gall} and !$PERL510 ) {
  698. select *STDERR;
  699. eval "require B::Debug;";
  700. $gv->debug;
  701. select *STDOUT;
  702. }
  703. $files{ $gv->FILE } && $gv->LINE
  704. || ${ $cv = $gv->CV } && $files{ $cv->FILE }
  705. || ${ $form = $gv->FORM } && $files{ $form->FILE };
  706. }
  707. sub B::HV::bwalk {
  708. my $hv = shift;
  709. return if $walked{$$hv}++;
  710. my %stash = $hv->ARRAY;
  711. while ( my ( $k, $v ) = each %stash ) {
  712. if ( !$PERL56 and $v->SvTYPE == $SVt_PVGV ) {
  713. my $hash = $v->HV;
  714. if ( $$hash && $hash->NAME ) {
  715. $hash->bwalk;
  716. }
  717. # B since 5.13.6 (744aaba0598) pollutes our namespace. Keep it clean
  718. # XXX This fails if our source really needs any B constant
  719. unless ($] > 5.013005 and $hv->NAME eq 'B') {
  720. $v->ix(1) if desired $v;
  721. }
  722. }
  723. else {
  724. if ($] > 5.013005 and $hv->NAME eq 'B') { # see above. omit B prototypes
  725. return;
  726. }
  727. nice "[prototype $tix]";
  728. B::Assembler::maxsvix($tix) if $debug{A};
  729. asm "gv_fetchpvx", cstring ($hv->NAME . "::" . $k);
  730. $svtab{$$v} = $varix = $tix;
  731. # we need the sv_flags before, esp. for DEBUGGING asserts
  732. asm "sv_flags", $v->FLAGS, as_hex($v->FLAGS);
  733. $v->bsave( $tix++ );
  734. }
  735. }
  736. }
  737. ######################################################
  738. sub B::OP::bsave_thin {
  739. my ( $op, $ix ) = @_;
  740. bwarn( B::peekop($op), ", ix: $ix" ) if $debug{o};
  741. my $next = $op->next;
  742. my $nextix = $optab{$$next};
  743. $nextix = 0, push @cloop, $op unless defined $nextix;
  744. if ( $ix != $opix ) {
  745. nice '-' . $op->name . '-', asm "ldop", $opix = $ix;
  746. }
  747. asm "op_flags", $op->flags, op_flags( $op->flags ) if $op->flags;
  748. asm "op_next", $nextix;
  749. asm "op_targ", $op->targ if $op->type and $op->targ; # tricky
  750. asm "op_private", $op->private if $op->private; # private concise flags?
  751. if ($] >= 5.017 and $op->can('slabbed')) {
  752. asm "op_slabbed", $op->slabbed if $op->slabbed;
  753. asm "op_savefree", $op->savefree if $op->savefree;
  754. asm "op_static", $op->static if $op->static;
  755. if ($] >= 5.019002 and $op->can('folded')) {
  756. asm "op_folded", $op->folded if $op->folded;
  757. }
  758. }
  759. }
  760. sub B::OP::bsave;
  761. *B::OP::bsave = *B::OP::bsave_thin;
  762. sub B::UNOP::bsave {
  763. my ( $op, $ix ) = @_;
  764. my $name = $op->name;
  765. my $flags = $op->flags;
  766. my $first = $op->first;
  767. my $firstix = $name =~ /fl[io]p/
  768. # that's just neat
  769. || ( !ITHREADS && $name eq 'regcomp' )
  770. # trick for /$a/o in pp_regcomp
  771. || $name eq 'rv2sv'
  772. && $op->flags & OPf_MOD
  773. && $op->private & OPpLVAL_INTRO
  774. # change #18774 (localref) made my life hard (commit 82d039840b913b4)
  775. ? $first->ix
  776. : 0;
  777. # XXX Are there more new UNOP's with first?
  778. $firstix = $first->ix if $name eq 'require'; #issue 97
  779. $op->B::OP::bsave($ix);
  780. asm "op_first", $firstix;
  781. }
  782. sub B::BINOP::bsave {
  783. my ( $op, $ix ) = @_;
  784. if ( $op->name eq 'aassign' && $op->private & B::OPpASSIGN_HASH() ) {
  785. my $last = $op->last;
  786. my $lastix = do {
  787. local *B::OP::bsave = *B::OP::bsave_fat;
  788. local *B::UNOP::bsave = *B::UNOP::bsave_fat;
  789. $last->ix;
  790. };
  791. asm "ldop", $lastix unless $lastix == $opix;
  792. asm "op_targ", $last->targ;
  793. $op->B::OP::bsave($ix);
  794. asm "op_last", $lastix;
  795. }
  796. else {
  797. $op->B::OP::bsave($ix);
  798. }
  799. }
  800. # not needed if no pseudohashes
  801. *B::BINOP::bsave = *B::OP::bsave if $PERL510; #VERSION >= 5.009;
  802. # deal with sort / formline
  803. sub B::LISTOP::bsave {
  804. my ( $op, $ix ) = @_;
  805. bwarn( B::peekop($op), ", ix: $ix" ) if $debug{o};
  806. my $name = $op->name;
  807. sub blocksort() { OPf_SPECIAL | OPf_STACKED }
  808. if ( $name eq 'sort' && ( $op->flags & blocksort ) == blocksort ) {
  809. my $first = $op->first;
  810. my $pushmark = $first->sibling;
  811. my $rvgv = $pushmark->first;
  812. my $leave = $rvgv->first;
  813. my $leaveix = $leave->ix;
  814. my $rvgvix = $rvgv->ix;
  815. asm "ldop", $rvgvix unless $rvgvix == $opix;
  816. asm "op_first", $leaveix;
  817. my $pushmarkix = $pushmark->ix;
  818. asm "ldop", $pushmarkix unless $pushmarkix == $opix;
  819. asm "op_first", $rvgvix;
  820. my $firstix = $first->ix;
  821. asm "ldop", $firstix unless $firstix == $opix;
  822. asm "op_sibling", $pushmarkix;
  823. $op->B::OP::bsave($ix);
  824. asm "op_first", $firstix;
  825. }
  826. elsif ( $name eq 'formline' ) {
  827. $op->B::UNOP::bsave_fat($ix);
  828. }
  829. elsif ( $name eq 'dbmopen' ) {
  830. require AnyDBM_File;
  831. $op->B::OP::bsave($ix);
  832. }
  833. else {
  834. $op->B::OP::bsave($ix);
  835. }
  836. }
  837. # fat versions
  838. sub B::OP::bsave_fat {
  839. my ( $op, $ix ) = @_;
  840. my $siblix = $op->sibling->ix;
  841. $op->B::OP::bsave_thin($ix);
  842. asm "op_sibling", $siblix;
  843. # asm "op_seq", -1; XXX don't allocate OPs piece by piece
  844. }
  845. sub B::UNOP::bsave_fat {
  846. my ( $op, $ix ) = @_;
  847. my $firstix = $op->first->ix;
  848. $op->B::OP::bsave($ix);
  849. asm "op_first", $firstix;
  850. }
  851. sub B::BINOP::bsave_fat {
  852. my ( $op, $ix ) = @_;
  853. my $last = $op->last;
  854. my $lastix = $op->last->ix;
  855. bwarn( B::peekop($op), ", ix: $ix $last: $last, lastix: $lastix" )
  856. if $debug{o};
  857. if ( !$PERL510 && $op->name eq 'aassign' && $last->name eq 'null' ) {
  858. asm "ldop", $lastix unless $lastix == $opix;
  859. asm "op_targ", $last->targ;
  860. }
  861. $op->B::UNOP::bsave($ix);
  862. asm "op_last", $lastix;
  863. }
  864. sub B::LOGOP::bsave {
  865. my ( $op, $ix ) = @_;
  866. my $otherix = $op->other->ix;
  867. bwarn( B::peekop($op), ", ix: $ix" ) if $debug{o};
  868. $op->B::UNOP::bsave($ix);
  869. asm "op_other", $otherix;
  870. }
  871. sub B::PMOP::bsave {
  872. my ( $op, $ix ) = @_;
  873. my ( $rrop, $rrarg, $rstart );
  874. # my $pmnextix = $op->pmnext->ix; # XXX
  875. bwarn( B::peekop($op), " ix: $ix" ) if $debug{M} or $debug{o};
  876. if (ITHREADS) {
  877. if ( $op->name eq 'subst' ) {
  878. $rrop = "op_pmreplroot";
  879. $rrarg = $op->pmreplroot->ix;
  880. $rstart = $op->pmreplstart->ix;
  881. }
  882. elsif ( $op->name eq 'pushre' ) {
  883. $rrarg = $op->pmreplroot;
  884. $rrop = "op_pmreplrootpo";
  885. }
  886. $op->B::BINOP::bsave($ix);
  887. if ( !$PERL56 and $op->pmstashpv )
  888. { # avoid empty stash? if (table) pre-compiled else re-compile
  889. if ( !$PERL510 ) {
  890. asm "op_pmstashpv", pvix $op->pmstashpv;
  891. }
  892. else {
  893. # XXX crash in 5.10, 5.11. Only used in OP_MATCH, with PMf_ONCE set
  894. if ( $op->name eq 'match' and $op->op_pmflags & 2) {
  895. asm "op_pmstashpv", pvix $op->pmstashpv;
  896. } else {
  897. bwarn("op_pmstashpv ignored") if $debug{M};
  898. }
  899. }
  900. }
  901. elsif ($PERL56) { # ignored
  902. ;
  903. }
  904. else {
  905. bwarn("op_pmstashpv main") if $debug{M};
  906. asm "op_pmstashpv", pvix "main" unless $PERL510;
  907. }
  908. } # ithreads
  909. else {
  910. $rrop = "op_pmreplrootgv";
  911. $rrarg = $op->pmreplroot->ix;
  912. $rstart = $op->pmreplstart->ix if $op->name eq 'subst';
  913. # 5.6 walks down the pmreplrootgv here
  914. # $op->pmreplroot->save($rrarg) unless $op->name eq 'pushre';
  915. my $stashix = $op->pmstash->ix unless $PERL56;
  916. $op->B::BINOP::bsave($ix);
  917. asm "op_pmstash", $stashix unless $PERL56;
  918. }
  919. asm $rrop, $rrarg if $rrop;
  920. asm "op_pmreplstart", $rstart if $rstart;
  921. if ( !$PERL510 ) {
  922. bwarn( "PMOP op_pmflags: ", $op->pmflags ) if $debug{M};
  923. asm "op_pmflags", $op->pmflags;
  924. asm "op_pmpermflags", $op->pmpermflags;
  925. asm "op_pmdynflags", $op->pmdynflags unless $PERL56;
  926. # asm "op_pmnext", $pmnextix; # XXX broken
  927. # Special sequence: This is the arg for the next pregcomp
  928. asm "newpv", pvstring $op->precomp;
  929. asm "pregcomp";
  930. }
  931. elsif ($PERL510) {
  932. # Since PMf_BASE_SHIFT we need a U32, which is a new bytecode for
  933. # backwards compat
  934. asm "op_pmflags", $op->pmflags;
  935. bwarn("PMOP op_pmflags: ", $op->pmflags) if $debug{M};
  936. my $pv = $op->precomp;
  937. asm "newpv", pvstring $pv;
  938. asm "pregcomp";
  939. # pregcomp does not set the extflags correctly, just the pmflags
  940. asm "op_reflags", $op->reflags if $pv; # so overwrite the extflags
  941. }
  942. }
  943. sub B::SVOP::bsave {
  944. my ( $op, $ix ) = @_;
  945. my $svix = $op->sv->ix;
  946. $op->B::OP::bsave($ix);
  947. asm "op_sv", $svix;
  948. }
  949. sub B::PADOP::bsave {
  950. my ( $op, $ix ) = @_;
  951. $op->B::OP::bsave($ix);
  952. # XXX crashed in 5.11 (where, why?)
  953. #if ($PERL512) {
  954. asm "op_padix", $op->padix;
  955. #}
  956. }
  957. sub B::PVOP::bsave {
  958. my ( $op, $ix ) = @_;
  959. $op->B::OP::bsave($ix);
  960. return unless my $pv = $op->pv;
  961. if ( $op->name eq 'trans' ) {
  962. asm "op_pv_tr", join ',', length($pv) / 2, unpack( "s*", $pv );
  963. }
  964. else {
  965. asm "newpv", pvstring $pv;
  966. asm "op_pv";
  967. }
  968. }
  969. sub B::LOOP::bsave {
  970. my ( $op, $ix ) = @_;
  971. my $nextix = $op->nextop->ix;
  972. my $lastix = $op->lastop->ix;
  973. my $redoix = $op->redoop->ix;
  974. $op->B::BINOP::bsave($ix);
  975. asm "op_redoop", $redoix;
  976. asm "op_nextop", $nextix;
  977. asm "op_lastop", $lastix;
  978. }
  979. sub B::COP::bsave {
  980. my ( $cop, $ix ) = @_;
  981. my $warnix = $cop->warnings->ix;
  982. if (ITHREADS) {
  983. $cop->B::OP::bsave($ix);
  984. asm "cop_stashpv", pvix $cop->stashpv, $cop->stashpv;
  985. asm "cop_file", pvix $cop->file, $cop->file;
  986. }
  987. else {
  988. my $stashix = $cop->stash->ix;
  989. my $fileix = $PERL56 ? pvix($cop->file) : $cop->filegv->ix(1);
  990. $cop->B::OP::bsave($ix);
  991. asm "cop_stash", $stashix;
  992. asm "cop_filegv", $fileix;
  993. }
  994. asm "cop_label", pvix $cop->label, $cop->label if $cop->label; # XXX AD
  995. asm "cop_seq", $cop->cop_seq;
  996. asm "cop_arybase", $cop->arybase unless $PERL510;
  997. asm "cop_line", $cop->line;
  998. asm "cop_warnings", $warnix;
  999. if ( !$PERL510 and !$PERL56 ) {
  1000. asm "cop_io", $cop->io->ix;
  1001. }
  1002. }
  1003. sub B::OP::opwalk {
  1004. my $op = shift;
  1005. my $ix = $optab{$$op};
  1006. defined($ix) ? $ix : do {
  1007. my $ix;
  1008. my @oplist = ($PERL56 and $op->isa("B::COP"))
  1009. ? () : $op->oplist; # 5.6 may be called by a COP
  1010. push @cloop, undef;
  1011. $ix = $_->ix while $_ = pop @oplist;
  1012. #print "\n# rest of cloop\n";
  1013. while ( $_ = pop @cloop ) {
  1014. asm "ldop", $optab{$$_};
  1015. asm "op_next", $optab{ ${ $_->next } };
  1016. }
  1017. $ix;
  1018. }
  1019. }
  1020. # Do run-time requires with -b savebegin and without -i includeall.
  1021. # Otherwise all side-effects of BEGIN blocks are already in the current
  1022. # compiled code.
  1023. # -b or !-i will have smaller code, but run-time access of dependent modules
  1024. # such as with python, where all modules are byte-compiled.
  1025. # With -i the behaviour is similar to the C or CC compiler, where everything
  1026. # is packed into one file.
  1027. # Redo only certain ops, such as push @INC ""; unshift @INC "" (TODO *INC)
  1028. # use/require defs and boot sections are already included.
  1029. sub save_begin {
  1030. my $av;
  1031. if ( ( $av = begin_av )->isa("B::AV") and $av->ARRAY) {
  1032. nice '<push_begin>';
  1033. if ($savebegins) {
  1034. for ( $av->ARRAY ) {
  1035. next unless $_->FILE eq $0;
  1036. asm "push_begin", $_->ix;
  1037. }
  1038. }
  1039. else {
  1040. for ( $av->ARRAY ) {
  1041. next unless $_->FILE eq $0;
  1042. # XXX BEGIN { goto A while 1; A: }
  1043. for ( my $op = $_->START ; $$op ; $op = $op->next ) {
  1044. # 1. push|unshift @INC, "libpath"
  1045. if ($op->name eq 'gv') {
  1046. my $gv = class($op) eq 'SVOP'
  1047. ? $op->gv
  1048. : ( ( $_->PADLIST->ARRAY )[1]->ARRAY )[ $op->padix ];
  1049. nice1 '<gv '.$gv->NAME.'>' if $$gv;
  1050. asm "incav", inc_gv->AV->ix if $$gv and $gv->NAME eq 'INC';
  1051. }
  1052. # 2. use|require
  1053. if (!$includeall) {
  1054. next unless $op->name eq 'require' ||
  1055. # this kludge needed for tests
  1056. $op->name eq 'gv' && do {
  1057. my $gv = class($op) eq 'SVOP'
  1058. ? $op->gv
  1059. : ( ( $_->PADLIST->ARRAY )[1]->ARRAY )[ $op->padix ];
  1060. $$gv && $gv->NAME =~ /use_ok|plan/;
  1061. };
  1062. nice1 '<require in BEGIN>';
  1063. asm "push_begin", $_->ix if $_;
  1064. last;
  1065. }
  1066. }
  1067. }
  1068. }
  1069. }
  1070. }
  1071. sub save_init_end {
  1072. my $av;
  1073. if ( ( $av = init_av )->isa("B::AV") and $av->ARRAY ) {
  1074. nice '<push_init>';
  1075. for ( $av->ARRAY ) {
  1076. next unless $_->FILE eq $0;
  1077. asm "push_init", $_->ix;
  1078. }
  1079. }
  1080. if ( ( $av = end_av )->isa("B::AV") and $av->ARRAY ) {
  1081. nice '<push_end>';
  1082. for ( $av->ARRAY ) {
  1083. next unless $_->FILE eq $0;
  1084. asm "push_end", $_->ix;
  1085. }
  1086. }
  1087. }
  1088. ################### perl 5.6 backport only ###################################
  1089. sub B::GV::bytecodecv {
  1090. my $gv = shift;
  1091. my $cv = $gv->CV;
  1092. if ( $$cv && !( $gv->FLAGS & 0x80 ) ) { # GVf_IMPORTED_CV / && !saved($cv)
  1093. if ($debug{cv}) {
  1094. warn sprintf( "saving extra CV &%s::%s (0x%x) from GV 0x%x\n",
  1095. $gv->STASH->NAME, $gv->NAME, $$cv, $$gv );
  1096. }
  1097. $gv->bsave;
  1098. }
  1099. }
  1100. sub symwalk {
  1101. no strict 'refs';
  1102. my $ok = 1
  1103. if grep { ( my $name = $_[0] ) =~ s/::$//; $_ eq $name; } @packages;
  1104. if ( grep { /^$_[0]/; } @packages ) {
  1105. walksymtable( \%{"$_[0]"}, "desired", \&symwalk, $_[0] );
  1106. }
  1107. warn "considering $_[0] ... " . ( $ok ? "accepted\n" : "rejected\n" )
  1108. if $debug{b};
  1109. $ok;
  1110. }
  1111. ################### end perl 5.6 backport ###################################
  1112. sub compile {
  1113. my ( $head, $scan, $keep_syn, $module );
  1114. my $cwd = '';
  1115. $files{$0} = 1;
  1116. $DB::single=1 if defined &DB::DB;
  1117. # includeall mode (without require):
  1118. if ($includeall) {
  1119. # add imported symbols => values %INC
  1120. $files{$_} = 1 for values %INC;
  1121. }
  1122. sub keep_syn {
  1123. $keep_syn = 1;
  1124. *B::OP::bsave = *B::OP::bsave_fat;
  1125. *B::UNOP::bsave = *B::UNOP::bsave_fat;
  1126. *B::BINOP::bsave = *B::BINOP::bsave_fat;
  1127. *B::LISTOP::bsave = *B::LISTOP::bsave_fat;
  1128. }
  1129. sub bwarn { print STDERR "Bytecode.pm: @_\n" unless $quiet; }
  1130. for (@_) {
  1131. if (/^-q(q?)/) {
  1132. $quiet = 1;
  1133. }
  1134. elsif (/^-S/) {
  1135. $debug{Comment} = 1;
  1136. $debug{-S} = 1;
  1137. *newasm = *endasm = sub { };
  1138. *asm = sub($;$$) {
  1139. undef $_[2] if defined $_[2] and $quiet;
  1140. ( defined $_[2] )
  1141. ? print $_[0], " ", $_[1], "\t# ", $_[2], "\n"
  1142. : print "@_\n";
  1143. };
  1144. *nice = sub ($) { print "\n# @_\n" unless $quiet; };
  1145. *nice1 = sub ($) { print "# @_\n" unless $quiet; };
  1146. }
  1147. elsif (/^-v/) {
  1148. warn "conflicting -q ignored" if $quiet;
  1149. *nice = sub ($) { print "\n# @_\n"; print STDERR "@_\n" };
  1150. *nice1 = sub ($) { print "# @_\n"; print STDERR "@_\n" };
  1151. }
  1152. elsif (/^-H/) {
  1153. require ByteLoader;
  1154. my $version = $ByteLoader::VERSION;
  1155. $head = "#! $^X
  1156. use ByteLoader '$ByteLoader::VERSION';
  1157. ";
  1158. # Maybe: Fix the plc reader, if 'perl -MByteLoader <.plc>' is called
  1159. }
  1160. elsif (/^-k/) {
  1161. keep_syn unless $PERL510;
  1162. }
  1163. elsif (/^-m/) {
  1164. $module = 1;
  1165. }
  1166. elsif (/^-o(.*)$/) {
  1167. open STDOUT, ">$1" or die "open $1: $!";
  1168. }
  1169. elsif (/^-F(.*)$/) {
  1170. $files{$1} = 1;
  1171. }
  1172. elsif (/^-i/) {
  1173. $includeall = 1;
  1174. }
  1175. elsif (/^-D(.*)$/) {
  1176. $debug{$1}++;
  1177. }
  1178. elsif (/^-s(.*)$/) {
  1179. $scan = length($1) ? $1 : $0;
  1180. }
  1181. elsif (/^-b/) {
  1182. $savebegins = 1;
  1183. } # this is here for the testsuite
  1184. elsif (/^-TI/) {
  1185. $T_inhinc = 1;
  1186. }
  1187. elsif (/^-TF(.*)/) {
  1188. my $thatfile = $1;
  1189. *B::COP::file = sub { $thatfile };
  1190. }
  1191. # Use -m instead for modules
  1192. elsif (/^-u(.*)/ and $PERL56) {
  1193. my $arg ||= $1;
  1194. push @packages, $arg;
  1195. }
  1196. else {
  1197. bwarn "Ignoring '$_' option";
  1198. }
  1199. }
  1200. if ($scan) {
  1201. my $f;
  1202. if ( open $f, $scan ) {
  1203. while (<$f>) {
  1204. /^#\s*line\s+\d+\s+("?)(.*)\1/ and $files{$2} = 1;
  1205. /^#/ and next;
  1206. if ( /\bgoto\b\s*[^&]/ && !$keep_syn ) {
  1207. bwarn "keeping the syntax tree: \"goto\" op found";
  1208. keep_syn;
  1209. }
  1210. }
  1211. }
  1212. else {
  1213. bwarn "cannot rescan '$scan'";
  1214. }
  1215. close $f;
  1216. }
  1217. binmode STDOUT;
  1218. return sub {
  1219. if ($debug{-S}) {
  1220. my $header = B::Assembler::gen_header_hash;
  1221. asm sprintf("#%-10s\t","magic").sprintf("0x%x",$header->{magic});
  1222. for (qw(archname blversion ivsize ptrsize byteorder longsize archflag
  1223. perlversion)) {
  1224. asm sprintf("#%-10s\t",$_).$header->{$_};
  1225. }
  1226. }
  1227. print $head if $head;
  1228. newasm sub { print @_ };
  1229. nice '<incav>' if $T_inhinc;
  1230. asm "incav", inc_gv->AV->ix if $T_inhinc;
  1231. save_begin;
  1232. #asm "incav", inc_gv->AV->ix if $T_inhinc;
  1233. nice '<end_begin>';
  1234. if (!$PERL56) {
  1235. defstash->bwalk;
  1236. } else {
  1237. if ( !@packages ) {
  1238. # support modules?
  1239. @packages = qw(main);
  1240. }
  1241. for (@packages) {
  1242. no strict qw(refs);
  1243. #B::svref_2object( \%{"$_\::"} )->bwalk;
  1244. walksymtable( \%{"$_\::"}, "bytecodecv", \&symwalk );
  1245. }
  1246. walkoptree( main_root, "bsave" ) unless ref(main_root) eq "B::NULL";
  1247. }
  1248. asm "signal", cstring "__WARN__" # XXX
  1249. if !$PERL56 and warnhook->ix;
  1250. save_init_end;
  1251. unless ($module) {
  1252. nice '<main_start>';
  1253. asm "main_start", $PERL56 ? main_start->ix : main_start->opwalk;
  1254. #asm "main_start", main_start->opwalk;
  1255. nice '<main_root>';
  1256. asm "main_root", main_root->ix;
  1257. nice '<main_cv>';
  1258. asm "main_cv", main_cv->ix;
  1259. nice '<curpad>';
  1260. asm "curpad", ( comppadlist->ARRAY )[1]->ix;
  1261. }
  1262. asm "dowarn", dowarn unless $PERL56;
  1263. {
  1264. no strict 'refs';
  1265. nice "<DATA>";
  1266. my $dh = $PERL56 ? *main::DATA : *{ defstash->NAME . "::DATA" };
  1267. unless ( eof $dh ) {
  1268. local undef $/;
  1269. asm "data", ord 'D' if !$PERL56;
  1270. print <$dh>;
  1271. }
  1272. else {
  1273. asm "ret";
  1274. }
  1275. }
  1276. endasm;
  1277. }
  1278. }
  1279. 1;
  1280. =head1 NAME
  1281. B::Bytecode - Perl compiler's bytecode backend
  1282. =head1 SYNOPSIS
  1283. B<perl -MO=Bytecode>[B<,-H>][B<,-o>I<script.plc>] I<script.pl>
  1284. =head1 DESCRIPTION
  1285. Compiles a Perl script into a bytecode format that could be loaded
  1286. later by the ByteLoader module and executed as a regular Perl script.
  1287. This saves time for the optree parsing and compilation and space for
  1288. the sourcecode in memory.
  1289. =head1 EXAMPLE
  1290. $ perl -MO=Bytecode,-H,-ohi -e 'print "hi!\n"'
  1291. $ perl hi
  1292. hi!
  1293. =head1 OPTIONS
  1294. =over 4
  1295. =item B<-H>
  1296. Prepend a C<use ByteLoader VERSION;> line to the produced bytecode.
  1297. This way you will not need to add C<-MByteLoader> to your perl command-line.
  1298. =item B<-i> includeall
  1299. Include all used packages and its symbols. Does no run-time require from
  1300. BEGIN blocks (C<use> package).
  1301. This creates bigger and more independent code, but is more error prone and
  1302. does not support pre-compiled C<.pmc> modules.
  1303. It is highly recommended to use C<-i> together with C<-b> I<safebegin>.
  1304. =item B<-b> savebegin
  1305. Save all the BEGIN blocks.
  1306. Normally only BEGIN blocks that C<require>
  1307. other files (ex. C<use Foo;>) or push|unshift
  1308. to @INC are saved.
  1309. =item B<-k>
  1310. Keep the syntax tree - it is stripped by default.
  1311. =item B<-o>I<outfile>
  1312. Put the bytecode in <outfile> instead of dumping it to STDOUT.
  1313. =item B<-s>
  1314. Scan the script for C<# line ..> directives and for <goto LABEL>
  1315. expressions. When gotos are found keep the syntax tree.
  1316. =item B<-S>
  1317. Output assembler source rather than piping it through the assembler
  1318. and outputting bytecode.
  1319. Without C<-q> the assembler source is commented.
  1320. =item B<-m>
  1321. Compile to a F<.pmc> module rather than to a single standalone F<.plc> program.
  1322. Currently this just means that the bytecodes for initialising C<main_start>,
  1323. C<main_root>, C<main_cv> and C<curpad> are omitted.
  1324. =item B<-u>I<package>
  1325. "use package." Might be needed of the package is not automatically detected.
  1326. =item B<-F>I<file>
  1327. Include file. If not C<-i> define all symbols in the given included
  1328. source file. C<-i> would all included files,
  1329. C<-F> only a certain file - full path needed.
  1330. =item B<-q>
  1331. Be quiet.
  1332. =item B<-v>
  1333. Be verbose.
  1334. =item B<-TI>
  1335. Restore full @INC for running within the CORE testsuite.
  1336. =item B<-TF> I<cop file>
  1337. Set the COP file - for running within the CORE testsuite.
  1338. =item B<-Do>
  1339. OPs, prints each OP as it's processed
  1340. =item B<-DM>
  1341. Debugging flag for more verbose STDERR output.
  1342. B<M> for Magic and Matches.
  1343. =item B<-DG>
  1344. Debug GV's
  1345. =item B<-DA>
  1346. Set developer B<A>ssertions, to help find possible obj-indices out of range.
  1347. =back
  1348. =head1 KNOWN BUGS
  1349. =over 4
  1350. =item *
  1351. 5.10 threaded fails with setting the wrong MATCH op_pmflags
  1352. 5.10 non-threaded fails calling anoncode, ...
  1353. =item *
  1354. C<BEGIN { goto A: while 1; A: }> won't even compile.
  1355. =item *
  1356. C<?...?> and C<reset> do not work as expected.
  1357. =item *
  1358. variables in C<(?{ ... })> constructs are not properly scoped.
  1359. =item *
  1360. Scripts that use source filters will fail miserably.
  1361. =item *
  1362. Special GV's fail.
  1363. =back
  1364. =head1 NOTICE
  1365. There are also undocumented bugs and options.
  1366. =head1 AUTHORS
  1367. Originally written by Malcolm Beattie 1996 and
  1368. modified by Benjamin Stuhl <sho_pi@hotmail.com>.
  1369. Rewritten by Enache Adrian <enache@rdslink.ro>, 2003 a.d.
  1370. Enhanced by Reini Urban <rurban@cpan.org>, 2008-2012
  1371. =cut
  1372. # Local Variables:
  1373. # mode: cperl
  1374. # cperl-indent-level: 2
  1375. # fill-column: 100
  1376. # End:
  1377. # vim: expandtab shiftwidth=2: