1=head1 NAME 2 3HACKERS - Devel::PPPort internals for hackers 4 5=head1 SYNOPSIS 6 7So you probably want to hack C<Devel::PPPort>? 8 9Well, here's some information to get you started with what's 10lying around in this distribution. 11 12=head1 DESCRIPTION 13 14=head2 How to backport something 15 16First, make sure that what you want to backport is documented. If it's worth 17backporting, it surely is worth documenting. Submit a documentation patch to 18L<https://github.com/Perl/perl5/issues> if necessary. Also, C<Devel::PPPort> 19cannot automatically generate proper information about the item without at 20least knowing its API prototype. It can get this from F<embed.fnc> if the item 21is a function, but if it is a macro, there needs to be at least a S<C<=for 22apidoc>> line for C<Devel::PPPort> to be able to figure things out on its own. 23 24Next, figure out where to place your implementation. Look at all the files in 25F<parts/inc/> for one that fits what you're planning. If there isn't one, 26just start a new one and remember to include it from within F<PPPort_pm.PL>. 27If you do create a new file, it's usually the best approach to just copy an 28existing file and use it as a template. 29 30Each file holds all relevant data for implementing a certain part 31of the API: 32 33=over 2 34 35=item * 36 37A list of the provided API in the C<=provides> section. 38 39=item * 40 41The optional C<=dontwarn> section is used to suppress warnings about particular 42API elements. Don't use this unless you get such a warning, and be sure to 43think about using other other alternatives before resorting to adding something 44in this section. 45 46=item * 47 48The implementation to add to F<ppport.h> in the C<=implementation> 49section. See L</Implementation Section Details>. 50 51=item * 52 53The code required to add to PPPort.xs for testing the implementation. 54This code goes into the C<=xshead>, C<=xsinit>, C<=xsmisc>, C<=xsboot> 55and C<=xsubs> section. Have a look at the template at the bottom 56of F<RealPPPort_xs.PL> to see where the code ends up. 57 58=item * 59 60The tests in the C<=tests> section. Remember not to use any fancy 61modules or syntax elements, as the test code needs to be able to run 62with Perl 5.003. (This is because Devel::PPPort itself will run all test files 63in the process of generating the information about when a feature came into 64existence.) This means, for example 65 66=over 67 68=item C<my> isn't supported in C<for>-loops 69 70 for my $x (1, 2, 3) { } # won't work with 5.003 71 72Instead declare C<$x> just before the statement 73 74=item The postfix C<for> statement modifier isn't supported 75 76 foo for 1..2 77 78won't compile. Instead enclose C<foo> in a loop. 79 80=item You can't use plain C<qr//> 81 82Instead, wrap it in a string eval C<eval "qr//">, and be sure it's skipped at 83execution time on perls earlier than 5.005 84 85=back 86 87As of version 3.56 of Devel::PPPort, the old Test style tests have been 88replaced with the more modern Test::More style, with some limitations. This 89means, for example, that C<is> is finally available, as well as 90C<done_testing>. You can pass the number of tests to C<skip>, instead of 91having to have your own C<for> loop. 92 93There is no C<like> nor C<unlike> (as those require C<qr> which didn't exist in 94the earliest perls that Devel::PPPort runs on). 95 96C<skip> doesn't do a S<C<last SKIP>>. (Perhaps it could, but that would mean 97converting all the skips in the existing tests.) 98 99The existing tests have been changed only as much as necessary so as to get 100things to work. But feel free to use the full functionality for any new tests 101you write. 102 103Here's a list of the supported functions: 104 105 cmp_ok 106 curr_test 107 diag 108 display 109 done_testing 110 eq_array 111 eq_hash 112 fail 113 is 114 isnt 115 next_test 116 note 117 ok 118 pass 119 plan 120 skip 121 skip_all 122 within 123 124These are copied from F<t/test.pl> in the perl distribution. Not all of them 125have been tested back as far as Devel::PPPort supports. Bug reports welcome. 126 127It's fine to backport an element only as far as convenient and necessary. But 128remember that your test file will end up being called on all perl versions 129available, likely including ones earlier than your backport. That may mean 130that elements in the C<=xs> sections will have to be C<#idef>'d out so that the 131object will not get missing symbols when loaded. 132 133It also means you have to check for and skip tests that aren't relevant to this 134version. The recommended way to do this is like: 135 136 if (ivers($]) < ivers(5.6)) { # No quotes needed 137 skip "reason", $count; 138 } 139 elsif (if (ivers($]) > ivers("5.5.4") { 140 # Quotes needed for double-dotted versions prior to 5.6.0 141 skip "other reason", $count; 142 } 143 else { 144 do_the_test 145 } 146 147C<ivers()> is a function automatically made available to all F<.t> files. It 148converts any reasonble expression of a version number into an integer, which 149can reliably be compared using numeric comparison operators, with the output of 150a second C<ivers()> call on a different version number, like in the result above. 151 152It's worth emphasizing that, due to bugs in early perl parsing, if you use a 153version number containing two dots on a version befor 5.6.0, it has to be 154quoted. 155 156=back 157 158In all sections, lines that begin with C<##> are completely ignored. 159 160=head2 Implementation Section Details 161 162You can implement API elements via C functions or macros, or simple variables. 163It is preferable to use a macro if feasible. Otherwise, the user must 164explicitly request that it get loaded, by defining a C<NEED_I<function>> (or 165I<variable>) as described in F<ppport.h>. If a function, I<foo> is required, 166place its body in this C<=implementation> section, like so: 167 168 #if { NEED foo } 169 170 char * 171 foo(pTHX_ const U8 *arg1, const U32 arg2, ...) 172 { 173 ... 174 } 175 176 #endif 177 178Similarly for a variable. 179 180It's obviously best to use a macro if at all feasible. Sometimes what once 181was implemented with a macro now requires a function; perhaps an edge case was 182overlooked. Doing so will cause the new F<ppport.h> to not be drop-in 183compatible with the older version, and can hence cause breakage. This 184incompatiblity (while easily solved) really needs to be stressed in 185documentation. 186 187=over 188 189=item __UNDEFINED__ 190 191If you add the line C<__UNDEFINED__> to the C<=provides> section, you can use 192lines like this in the C<=implementation> section: 193 194 __UNDEFINED__ macro some definition 195 196to both define C<macro> and indicate that it is provided by F<ppport.h>. This 197replaces these C<=implementation> section lines: 198 199 #ifndef macro 200 # define macro some definition 201 #endif 202 203besides automagically making it be considered to be provided. C<macro> can 204have optional arguments and the definition can even span multiple lines, like 205in 206 207 __UNDEFINED__ SvMAGIC_set(sv, val) \ 208 STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \ 209 (((XPVMG*) SvANY(sv))->xmg_magic = (val)); } \ 210 STMT_END 211 212This usually makes the code more compact and readable. 213 214But you should only use this on things that you plan to publicly provide. If 215something, such as a mnemonic for a constant needs to be defined but isn't 216really needed for the public at large to know about, you should use 217 218 __UNDEF_NOT_PROVIDED__ macro some definition 219 220instead. To avoid name space conflicts, follow what's in L</Helper macros>, 221below. 222 223=item __REDEFINE__ 224 225If you add the line C<__REDEFINE__> to the C<=provides> section, you can use 226lines like this in the C<=implementation> section: 227 228 __REDEFINE__ macro some definition 229 230to both redefine C<macro> and indicate that it is provided by F<ppport.h>. This 231replaces these C<=implementation> section lines: 232 233 #undef macro 234 #ifndef macro 235 # define macro some definition 236 #endif 237 238 239=item Helper macros 240 241If you need to define a helper macro which is not part of C<Devel::PPPort> API 242and its usage is only for the definition of other C<Devel::PPPort> macros, then 243use the C<D_PPP_> prefix for this macro name (e.g. C<D_PPP_SVPV_NOLEN_LP_ARG>). 244This suppresses any warnings when a macro is defined which is not part of the 245Perl public API. 246 247=item Version numbers 248 249Version checking used to be tricky to get correct (besides being buggy in some 250perl versions). 251C<ivers()> is used in the C<=tests> section to overcome this. and constructs 252like the following in the C language sections. 253 254 #if { VERSION < 5.9.3 } 255 256You SHOULD be using this construct or the alternatives listed below for ALL 257version checks, and not come up with something on your own. 258 259In this form, the version number can be either of the new form C<5.x.y> or the 260older form C<5.00x_yy>. Both are translated into the correct preprocessor 261statements. It is also possible to combine this with other statements: 262 263 #if { VERSION >= 5.004 } && !defined(sv_vcatpvf) 264 /* a */ 265 #elif { VERSION < 5.004_63 } && { VERSION != 5.004_05 } 266 /* b */ 267 #endif 268 269This not only works in the C<=implementation> section, but also in 270the C<=xsubs>, C<=xsinit>, C<=xsmisc>, C<=xshead> and C<=xsboot> sections. 271 272Alternatively, you can use the forms now available in regular Perl: 273 274 #if PERL_VERSION_EQ(5,9,3) 275 #if PERL_VERSION_NE(5,9,3) 276 #if PERL_VERSION_LT(5,9,3) 277 #if PERL_VERSION_GT(5,9,3) 278 #if PERL_VERSION_LE(5,9,3) 279 #if PERL_VERSION_GE(5,9,3) 280 281These forms have the advantage over the '{ VERSION ... }' form in that you may 282use the special value '*' for the final number to mean ALL possible values for 283it. Thus, 284 285 #if PERL_VERSION_EQ(5,31,'*') 286 287means all perls in the 5.31 series. And 288 289 #if PERL_VERSION_NE(5,24,'*') 290 291means all perls EXCEPT 5.24 ones. And 292 293 #if PERL_VERSION_LE(5,9,'*') 294 295is effectively 296 297 #if PERL_VERSION_LT(5,10,0) 298 299=item Hints 300 301If you add a comment like so: 302 303 /* Hint: PL_expect, PL_copline, PL_rsfp 304 paragraphs of stuff you want to have shown when ppport.h outputs 305 something about any one of PL_expect, PL_copline, or PL_rsfp 306 */ 307 308Earlier versions of F<ppport.h> required an asterisk at the beginning of every 309continuation line, or else the content would be silently dropped. 310 311=item Warnings 312 313A more serious caution can be displayed by instead saying 314 315 /* Warning: PL_expect, PL_copline, PL_rsfp 316 paragraphs of stuff you want to have shown when ppport.h outputs 317 something about any one of PL_expect, PL_copline, or PL_rsfp 318 */ 319 320Earlier versions of F<ppport.h> required an asterisk at the beginning of every 321continuation line, or else the content would be silently dropped. 322 323=item Replace 324 325When F<ppport.h> is run on a file(s), you can cause it to automatically flag 326occurrences of the constructs you specify, encouraging the author to replace 327them with different (presumably better) ones. These also are used in any 328suggested edits and generated patches. 329 330There are three ways to do this 331 332=over 4 333 334=item in-line comment 335 336You can add a trailing comment like so: 337 338 #define bar foo /* Replace */ 339 __UNDEFINED__ bar foo /* Replace */ 340 341These say that C<foo> should be replaced by C<bar>. NOT the other way around. 342 343=item separate comment 344 345For situations not amenable to the above, you can say 346 347 /* Replace foo with bar */ 348 349=item define a replacement region 350 351It you have several replacements, you can group them together like so: 352 353 /* Replace: 1 */ 354 #define foo bar 355 #define bat baz 356 /* Replace: 0 */ 357 358These replace C<bar> with C<foo>; C<baz> with C<bat>. NOT the other way 359around. 360 361=back 362 363=item Dependencies 364 365F<ppport.h> automatically gathers information as to what functions are 366dependent on what other things from inspecting the source, but if this is 367insufficient for you, you can add lines like the following: 368 369 /* foo, bar depends on baz, bat */ 370 371Each of C<foo>, C<bar> depends on each of C<baz>, C<bat>. 372 373=back 374 375=head2 Testing 376 377After you have furnished your implementation, you need to test it. 378 379=head2 Special Makefile targets 380 381You can use 382 383 make regen 384 385to regenerate all of the autogenerated files. To get rid of all 386generated files (except for F<parts/todo/*> and F<parts/base/*>), 387use 388 389 make purge_all 390 391That's it. 392 393To automatically test C<Devel::PPPort> with lots of different Perl 394versions, you can use the F<soak> script. Just pass it a list of 395all Perl binaries you want to test. 396 397=head2 Regenerating F<ppport.h> and F<PPPort.pm> 398 399C<Devel::PPPort> keeps two directories of generated files, in F<parts/base> and 400F<parts/todo>. The files in each are named after Perl version numbers. When a 401function or macro came into existence is indicated by placing its name in the 402corresponding file in F<parts/base>. The files in F<parts/todo> are the same, 403except they indicate the earliest release that F<ppport.h> supports the 404element. The delta is effectively what F<ppport.h> buys you. 405 406The generation process described in this section creates these files. It does 407so by examining as many perl versions as are available to it. It tries to make 408sure each element actually compiles, and it runs the test scripts you have 409furnished on every version. 410 411Ideally, this should be done before every release that includes new backporting 412and/or when blead has added new public API. At a minimum, it should be done as 413the next major Perl release comes out. 414 415The process isn't platform independent. It has currently been tested only under 416Linux, and it definitely requires at least C<gcc> and the C<nm> utility. 417The process used to be problematic, with random failures. But it has now been 418fixed to be reliable. 419 420Before starting the regeneration, you need to have gathered certain data. 421(Options listed below apply to the tools that eventually will use the data, and 422which are described further below). 423 424=over 4 425 426=item * 427 428You will first need a whole bunch of different Perls, the more, the better, but 429only one per version tag (which one is random) will actually get used. 430dromedary has a sufficient set. They should all have the same Configure 431options with respect to what functions and macros are enabled. For example, 432they should all be threaded, or all non-threaded. A mixture will screw up the 433results. Similarly, they should all or none have quad math (at least as far 434back as that became available). You can use F<devel/buildperl.pl> to build 435them. 436 437Previous maintainers of this module kept those perls in 438F</tmp/perl/install/default>, so most of the tools use this as a default, but 439you'll likely simply use the C<--install=> option to specify where. This 440should be a path where a S<C<make install>> has been done, so has immediate 441subdirectories of C</bin> and C</lib>. C</bin> should contain the binaries. 442It will use all files in this directory whose names begin with C<perl5>. 443 444Actually, not all the binaries need be in this directory. You can specify 445additional places to look since C<--install=> takes a comma separated list of 446directories. 447 448=item * 449 450You also need a freshly built bleadperl. The C<--blead=I<path>> option should 451be used to specify it. (Some of the tools have a default of C<bleadperl-debug> 452if this option is omitted.) Again, it needs the same Configure options as the 453earlier versions had. Using C<-DNO_MATHOMS> will change the results, and 454probably should be avoided. True, these functions are allegedly on their way 455out, so it could be argued that they shouldn't be encouraged in any way; but 456some of these have been in limbo for many years, so should be documented. 457 458=item * 459 460And you will need updated API information. Copy the latest F<embed.fnc> file 461from bleadperl to the F<parts> directory and run F<devel/mkapidoc.pl> to 462collect the remaining information in F<parts/apidoc.fnc>. This needs to be 463done after the perl has been compiled, as there are generated files that feed 464it. 465 466=item * 467 468The final step before regenerating everything is to run 469F<devel/mkppport_fnc.pl> to update the F</parts/ppport.fnc> file. 470 471=back 472 473Having done this, run F<devel/regenerate> which wraps the following steps 474(which you could instead do by hand, but it's easy to forget things): 475 476=over 477 478=item * 479 480It first does some sanity checking 481 482=item * 483 484Then it asks you if it's ok to remove all existing todo files in the 485F<parts/base> and F<parts/todo> directories. If you answer no, the process 486aborts. 487 488This is crtical to getting accurate results. 489 490=item * 491 492It builds the new baseline by running 493 494 perl devel/mktodo --base 495 496in the root directory of the distribution. 497 498If there are warnings in blead, it will ask you to examine them, and to ok if 499it's all right to go ahead. If there are issues with blead, everything 500following could be wrong. 501 502=item * 503 504It builds the new todo files by running 505 506 perl devel/mktodo 507 508in the root directory of the distribution. 509 510=item * 511 512Finally, it adds the remaining information by running 513 514 perl Makefile.PL && make 515 perl devel/scanprov --mode=write 516 517=back 518 519=head2 How to build gobs of versions of Perl 520 521C<Devel::PPPort> supports Perl versions between 5.003 and bleadperl. 522To guarantee this support, its good to have as many versions as possible to 523test on. dromedary currently has many such versions. 524 525There is a tool to build all the different 526versions and configurations. You can find it in F<devel/buildperl.pl>. 527It can currently build the following Perl releases: 528 529 5.003 530 5.004 - 5.004_05 531 5.005 - 5.005_04 532 5.6.x 533 5.7.x 534 5.8.x 535 5.9.x 536 5.1x.x 537 5.2x.x 538 5.3x.x 539 540=head2 Implementation 541 542Knowing which parts of the API are not backwards compatible and 543probably need C<Devel::PPPort> support is another problem that's 544not easy to deal with manually. If you run 545 546 perl Makefile.PL --with-apicheck 547 548a C file is generated by F<parts/apicheck.pl> that is compiled 549and linked with C<Devel::PPPort>. This C file has the purpose of 550using each of the public API functions/macros once. 551 552The required information is derived from F<parts/embed.fnc> (just 553a copy of bleadperl's F<embed.fnc>), F<parts/apidoc.fnc> (which 554is generated by F<devel/mkapidoc.pl> and simply collects the rest 555of the apidoc entries spread over the Perl source code) and 556F<parts/ppport.fnc> (which lists the API provided purely by 557Devel::PPPort, along with other elements that are tested only using 558F<ppport.h>). 559 560The generated C file (usually, F<apicheck.c>) won't compile as-is 561with older perls. And even if it compiles, there's still a good chance of the 562dynamic linker failing at C<make test> time. But that's on purpose! 563 564We can use these failures to find changes in the API automatically. 565The Perl script F<devel/mktodo> calls another script F<devel/mktodo.pl> 566repeatedly to run C<Devel::PPPort> on version after version of perl, in 567decreasing version order, so we start with blead and work backwards. The 568latter script generates an F<apicheck.c>. It starts with the code that 569successfully worked in the previously tested Perl version, which should be the 570version one higher than the current one. Call the current one I<n>, and the 571previous one I<n+1>. The items that fail to compile in I<n>, but did compile 572in I<n+1> must have become available in I<n+1>. We run the Linux command C<nm> 573to find those undefined symbols in I<n>. We change F<apicheck.c> to ignore 574(through C<#ifdef>'s) those and recompile, repeating until F<apicheck.c> 575successfully compiles, the dynamic linker is happy, and C<make test> runs on 576this version. Then we repeat the process for I<n-1>, and so on. (Actually, 577this process may generate false positives, so by default each failing API call 578is checked again. If possible, this is done by generating an F<apicheck.c> for 579just the one failing API.) Note that the make test is run using F<ppport.h> 580during both passes. 581 582Running F<devel/mktodo> currently takes a couple hours on dromedary. 583 584If you run it with the C<--nocheck> option, it won't recheck the API calls 585that failed in the compilation stage and it'll take significantly less time. 586No one currently associated with maintaining this module understands under what 587circumstances it is safe to run with C<--nocheck>. 588 589By repeating the process over and over, we build up information on when every 590element first became supported. This information is stored in files in the 591F<parts/base> directory, one file per version. The file for version I<n+1> is 592generated by running version I<n> of perl. 593 594We actually want a second piece of information, which is how much F<ppport.h> 595buys you. What happens when regenerating is actually two entire runs through 596all the perls. The first is accomplished by calling F<devel/mktodo> with the 597C<--base> option. It automically will call F<devel/mktodo.pl> with each 598version of perl, NOT using anything in F<ppport.h>. When done the results 599indicate when each API element became available in stock perl, without using 600F<ppport.h>. 601 602And then the whole process is repeated, but this time F<ppport.h> is included. 603The files are placed in F<parts/todo>. Thus, at the end, we know when each 604element became available in modified perl, using F<ppport.h>. 605 606However, only the public API that is implemented as functions (and must appear 607in F<embed.fnc>) plus macros whose calling sequence is documented can be 608checked this way. The final step in the process is calling F<devel/scanprov>. 609It looks through the header files for when all the symbols provided by 610C<Devel::PPPort> first became defined. It doesn't test the symbols or try to 611compile them, as it doesn't generally know the API, but it can tell that 612something exists in release I<n+1> but not I<n> (by scanning the include files 613in the F<CORE> directory of various Perl versions). (It does know if a macro 614has zero arguments or non-zero arguments, so it does get extra information from 615the zero argument ones.) 616 617=head2 Files 618 619Residing in F<parts/inc/> is the "heart" of C<Devel::PPPort>. Each 620of the files implements a part of the supported API, along with 621hints, dependency information, XS code and tests. 622The files are in a POD-like format that is parsed using the 623functions in F<parts/ppptools.pl>. 624 625The scripts F<PPPort_pm.PL>, F<RealPPPort_xs.PL> and F<mktests.PL> all 626use the information in F<parts/inc/> to generate the main module 627F<PPPort.pm>, the XS code in F<RealPPPort.xs> and various test files 628in F<t/>. 629 630You can get extra information from F<PPPort_pm.PL> by setting the environment 631variable C<DPPP_CHECK_LEVEL> to 1 or 2. 632 633All of these files could be generated on the fly while building 634C<Devel::PPPort>, but not having the tests in F<t/> will confuse 635TEST/harness in the core. Not having F<PPPort.pm> will be bad for 636viewing the docs on C<search.cpan.org>. So unfortunately, it's 637unavoidable to put some redundancy into the package. 638 639=head2 Submitting Patches 640 641If you've added some functionality to C<Devel::PPPort>, please 642consider submitting a patch with your work to P5P by sending a pull request to 643 644L<https://github.com/Dual-Life/Devel-PPPort/pulls>. 645 646When submitting patches, please only add the relevant changes 647and don't include the differences of the generated files. You 648can use the C<purge_all> target to delete all autogenerated 649files. 650 651=head2 Integrating into the Perl core 652 653When integrating this module into the Perl core, be sure to 654remove the following files from the distribution. They are 655either not needed or generated on the fly when building this 656module in the core: 657 658 MANIFEST 659 META.yml 660 PPPort.pm 661 662=head1 BUGS 663 664No known bugs. 665 666=head1 COPYRIGHT 667 668Version 3.x, Copyright (C) 2004-2020, Marcus Holland-Moritz 669and Perl 5 porters 670 671Version 2.x, Copyright (C) 2001, Paul Marquess. 672 673Version 1.x, Copyright (C) 1999, Kenneth Albanowski. 674 675This program is free software; you can redistribute it and/or 676modify it under the same terms as Perl itself. 677 678=head1 SEE ALSO 679 680See F<ppport.h> and F<devel/regenerate>. 681 682=cut 683