From 776965836b42cce655373b0ba3917a1799f44c01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= Date: Wed, 6 May 2015 10:36:13 +0200 Subject: [PATCH] Upgrade to 3.28 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The perlxs*.pod files are omitted because they have alwayes lived in perl sources only. Signed-off-by: Petr Písař --- Changes | 4 ++ lib/ExtUtils/ParseXS.pm | 138 +++++++++++++++++++++++++++---------- lib/ExtUtils/ParseXS/Constants.pm | 2 +- lib/ExtUtils/ParseXS/CountLines.pm | 2 +- lib/ExtUtils/ParseXS/Eval.pm | 2 +- lib/ExtUtils/ParseXS/Utilities.pm | 23 ++++--- lib/ExtUtils/Typemaps.pm | 3 +- lib/ExtUtils/Typemaps/Cmd.pm | 2 +- lib/ExtUtils/Typemaps/InputMap.pm | 2 +- lib/ExtUtils/Typemaps/OutputMap.pm | 4 +- lib/ExtUtils/Typemaps/Type.pm | 2 +- t/109-standard_XS_defs.t | 3 +- 12 files changed, 127 insertions(+), 60 deletions(-) diff --git a/Changes b/Changes index 41966fd..233a8a1 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,9 @@ Revision history for Perl extension ExtUtils::ParseXS. +3.26 - not released yet + - Support added for XS handshake API introduced in 5.21.6. + - backported S_croak_xs_usage optimized on threaded builds + 3.24 - Wed Mar 5 18:20:00 CET 2014 - Native Android build fixes - More lenient syntax for embedded TYPEMAP blocks in XS: diff --git a/lib/ExtUtils/ParseXS.pm b/lib/ExtUtils/ParseXS.pm index 25d3175..0987500 100644 --- a/lib/ExtUtils/ParseXS.pm +++ b/lib/ExtUtils/ParseXS.pm @@ -11,7 +11,7 @@ use Symbol; our $VERSION; BEGIN { - $VERSION = '3.24'; + $VERSION = '3.28'; } use ExtUtils::ParseXS::Constants $VERSION; use ExtUtils::ParseXS::CountLines $VERSION; @@ -797,12 +797,15 @@ EOF # EOF - $self->{newXS} = "newXS"; $self->{proto} = ""; - + unless($self->{ProtoThisXSUB}) { + $self->{newXS} = "newXS_deffile"; + $self->{file} = ""; + } + else { # Build the prototype string for the xsub - if ($self->{ProtoThisXSUB}) { $self->{newXS} = "newXSproto_portable"; + $self->{file} = ", file"; if ($self->{ProtoThisXSUB} eq 2) { # User has specified empty prototype @@ -831,14 +834,14 @@ EOF foreach my $xname (sort keys %{ $self->{XsubAliases} }) { my $value = $self->{XsubAliases}{$xname}; push(@{ $self->{InitFileCode} }, Q(<<"EOF")); -# cv = $self->{newXS}(\"$xname\", XS_$self->{Full_func_name}, file$self->{proto}); +# cv = $self->{newXS}(\"$xname\", XS_$self->{Full_func_name}$self->{file}$self->{proto}); # XSANY.any_i32 = $value; EOF } } elsif (@{ $self->{Attributes} }) { push(@{ $self->{InitFileCode} }, Q(<<"EOF")); -# cv = $self->{newXS}(\"$self->{pname}\", XS_$self->{Full_func_name}, file$self->{proto}); +# cv = $self->{newXS}(\"$self->{pname}\", XS_$self->{Full_func_name}$self->{file}$self->{proto}); # apply_attrs_string("$self->{Package}", cv, "@{ $self->{Attributes} }", 0); EOF } @@ -847,18 +850,18 @@ EOF my $value = $self->{Interfaces}{$yname}; $yname = "$self->{Package}\::$yname" unless $yname =~ /::/; push(@{ $self->{InitFileCode} }, Q(<<"EOF")); -# cv = $self->{newXS}(\"$yname\", XS_$self->{Full_func_name}, file$self->{proto}); +# cv = $self->{newXS}(\"$yname\", XS_$self->{Full_func_name}$self->{file}$self->{proto}); # $self->{interface_macro_set}(cv,$value); EOF } } - elsif($self->{newXS} eq 'newXS'){ # work around P5NCI's empty newXS macro + elsif($self->{newXS} eq 'newXS_deffile'){ # work around P5NCI's empty newXS macro push(@{ $self->{InitFileCode} }, - " $self->{newXS}(\"$self->{pname}\", XS_$self->{Full_func_name}, file$self->{proto});\n"); + " $self->{newXS}(\"$self->{pname}\", XS_$self->{Full_func_name}$self->{file}$self->{proto});\n"); } else { push(@{ $self->{InitFileCode} }, - " (void)$self->{newXS}(\"$self->{pname}\", XS_$self->{Full_func_name}, file$self->{proto});\n"); + " (void)$self->{newXS}(\"$self->{pname}\", XS_$self->{Full_func_name}$self->{file}$self->{proto});\n"); } } # END 'PARAGRAPH' 'while' loop @@ -876,7 +879,7 @@ EOF /* Making a sub named "$self->{Package}::()" allows the package */ /* to be findable via fetchmethod(), and causes */ /* overload::Overloaded("$self->{Package}") to return true. */ - (void)$self->{newXS}("$self->{Package}::()", XS_$self->{Packid}_nil, file$self->{proto}); + (void)$self->{newXS}("$self->{Package}::()", XS_$self->{Packid}_nil$self->{file}$self->{proto}); MAKE_FETCHMETHOD_WORK } @@ -891,11 +894,13 @@ EOF print Q(<<"EOF"); #XS_EXTERNAL(boot_$self->{Module_cname}); /* prototype to pass -Wmissing-prototypes */ #XS_EXTERNAL(boot_$self->{Module_cname}) -EOF - - print Q(<<"EOF"); #[[ +##if PERL_VERSION_LE(5, 21, 5) # dVAR; dXSARGS; +##else +# dVAR; ${\($self->{WantVersionChk} ? + 'dXSBOOTARGSXSAPIVERCHK;' : 'dXSBOOTARGSAPIVERCHK;')} +##endif EOF #Under 5.8.x and lower, newXS is declared in proto.h as expecting a non-const @@ -909,6 +914,8 @@ EOF ##else # const char* file = __FILE__; ##endif +# +# PERL_UNUSED_VAR(file); EOF print Q("#\n"); @@ -916,15 +923,26 @@ EOF print Q(<<"EOF"); # PERL_UNUSED_VAR(cv); /* -W */ # PERL_UNUSED_VAR(items); /* -W */ -##ifdef XS_APIVERSION_BOOTCHECK +EOF + + if( $self->{WantVersionChk}){ + print Q(<<"EOF") ; +##if PERL_VERSION_LE(5, 21, 5) +# XS_VERSION_BOOTCHECK; +## ifdef XS_APIVERSION_BOOTCHECK # XS_APIVERSION_BOOTCHECK; +## endif ##endif + EOF + } else { + print Q(<<"EOF") ; +##if PERL_VERSION_LE(5, 21, 5) && defined(XS_APIVERSION_BOOTCHECK) +# XS_APIVERSION_BOOTCHECK; +##endif - print Q(<<"EOF") if $self->{WantVersionChk}; -# XS_VERSION_BOOTCHECK; -# EOF + } print Q(<<"EOF") if defined $self->{XsubAliases} or defined $self->{interfaces}; # { @@ -960,14 +978,15 @@ EOF } print Q(<<'EOF'); -##if (PERL_REVISION == 5 && PERL_VERSION >= 9) -# if (PL_unitcheckav) -# call_list(PL_scopestack_ix, PL_unitcheckav); -##endif -EOF - - print Q(<<"EOF"); +##if PERL_VERSION_LE(5, 21, 5) +## if PERL_VERSION_GE(5, 9, 0) +# if (PL_unitcheckav) +# call_list(PL_scopestack_ix, PL_unitcheckav); +## endif # XSRETURN_YES; +##else +# Perl_xs_boot_epilog(aTHX_ ax); +##endif #]] # EOF @@ -1322,7 +1341,7 @@ sub OVERLOAD_handler { $self->{Overload} = 1 unless $self->{Overload}; my $overload = "$self->{Package}\::(".$1; push(@{ $self->{InitFileCode} }, - " (void)$self->{newXS}(\"$overload\", XS_$self->{Full_func_name}, file$self->{proto});\n"); + " (void)$self->{newXS}(\"$overload\", XS_$self->{Full_func_name}$self->{file}$self->{proto});\n"); } } } @@ -1848,7 +1867,10 @@ sub generate_init { my $typem = $typemaps->get_typemap(ctype => $type); my $xstype = $typem->xstype; - $xstype =~ s/OBJ$/REF/ if $self->{func_name} =~ /DESTROY$/; + #this is an optimization from perl 5.0 alpha 6, class check is skipped + #T_REF_IV_REF is missing since it has no untyped analog at the moment + $xstype =~ s/OBJ$/REF/ || $xstype =~ s/^T_REF_IV_PTR$/T_PTRREF/ + if $self->{func_name} =~ /DESTROY$/; if ($xstype eq 'T_PV' and exists $self->{lengthof}->{$var}) { print "\t$var" unless $printed_name; print " = ($type)SvPV($arg, STRLEN_length_of_$var);\n"; @@ -2002,36 +2024,78 @@ sub generate_output { print "\t\tSvSETMAGIC(ST(ix_$var));\n" if $do_setmagic; } elsif ($var eq 'RETVAL') { + my $orig_arg = $arg; + my $indent; + my $use_RETVALSV = 1; + my $do_mortal = 0; + my $do_copy_tmp = 1; + my $pre_expr; + local $eval_vars->{arg} = $arg = 'RETVALSV'; my $evalexpr = $self->eval_output_typemap_code("qq\a$expr\a", $eval_vars); + if ($expr =~ /^\t\Q$arg\E = new/) { # We expect that $arg has refcnt 1, so we need to # mortalize it. - print $evalexpr; - print "\tsv_2mortal(ST($num));\n"; - print "\tSvSETMAGIC(ST($num));\n" if $do_setmagic; + $do_mortal = 1; } # If RETVAL is immortal, don't mortalize it. This code is not perfect: # It won't detect a func or expression that only returns immortals, for # example, this RE must be tried before next elsif. elsif ($evalexpr =~ /^\t\Q$arg\E\s*=\s*(boolSV\(|(&PL_sv_yes|&PL_sv_no|&PL_sv_undef)\s*;)/) { - print $evalexpr; + $do_copy_tmp = 0; #$arg will be a ST(X), no SV* RETVAL, no RETVALSV + $use_RETVALSV = 0; } elsif ($evalexpr =~ /^\s*\Q$arg\E\s*=/) { # We expect that $arg has refcnt >=1, so we need # to mortalize it! - print $evalexpr; - print "\tsv_2mortal(ST(0));\n"; - print "\tSvSETMAGIC(ST(0));\n" if $do_setmagic; + $use_RETVALSV = 0 if $ntype eq "SVPtr";#reuse SV* RETVAL vs open new block + $do_mortal = 1; } else { # Just hope that the entry would safely write it # over an already mortalized value. By - # coincidence, something like $arg = &sv_undef + # coincidence, something like $arg = &PL_sv_undef # works too, but should be caught above. - print "\tST(0) = sv_newmortal();\n"; - print $evalexpr; + $pre_expr = "RETVALSV = sv_newmortal();\n"; # new mortals don't have set magic + $do_setmagic = 0; + } + if($use_RETVALSV) { + print "\t{\n\t SV * RETVALSV;\n"; + $indent = "\t "; + } else { + $indent = "\t"; + } + print $indent.$pre_expr if $pre_expr; + + if($use_RETVALSV) { + #take control of 1 layer of indent, may or may not indent more + $evalexpr =~ s/^(\t| )/$indent/gm; + #"\t \t" doesn't draw right in some IDEs + #break down all \t into spaces + $evalexpr =~ s/\t/ /g; + #rebuild back into \t'es, \t==8 spaces, indent==4 spaces + $evalexpr =~ s/ /\t/g; + } + else { + if($do_mortal || $do_setmagic) { + #typemap entry evaled with RETVALSV, if we aren't using RETVALSV replace + $evalexpr =~ s/RETVALSV/RETVAL/g; #all uses with RETVAL for prettier code + } + else { #if no extra boilerplate (no mortal, no set magic) is needed + #after $evalexport, get rid of RETVALSV's visual cluter and change + $evalexpr =~ s/RETVALSV/$orig_arg/g;#the lvalue to ST(X) + } } + #stop " RETVAL = RETVAL;" for SVPtr type + print $evalexpr if $evalexpr !~ /^\s*RETVAL = RETVAL;$/; + print $indent.'RETVAL'.($use_RETVALSV ? 'SV':'') + .' = sv_2mortal(RETVAL'.($use_RETVALSV ? 'SV':'').");\n" if $do_mortal; + print $indent.'SvSETMAGIC(RETVAL'.($use_RETVALSV ? 'SV':'').");\n" if $do_setmagic; + #dont do "RETVALSV = boolSV(RETVAL); ST(0) = RETVALSV;", it is visual clutter + print $indent."$orig_arg = RETVAL".($use_RETVALSV ? 'SV':'').";\n" + if $do_mortal || $do_setmagic || $do_copy_tmp; + print "\t}\n" if $use_RETVALSV; } elsif ($do_push) { print "\tPUSHs(sv_newmortal());\n"; diff --git a/lib/ExtUtils/ParseXS/Constants.pm b/lib/ExtUtils/ParseXS/Constants.pm index 34fbc21..5603613 100644 --- a/lib/ExtUtils/ParseXS/Constants.pm +++ b/lib/ExtUtils/ParseXS/Constants.pm @@ -3,7 +3,7 @@ use strict; use warnings; use Symbol; -our $VERSION = '3.24'; +our $VERSION = '3.28'; =head1 NAME diff --git a/lib/ExtUtils/ParseXS/CountLines.pm b/lib/ExtUtils/ParseXS/CountLines.pm index 473f531..b30812c 100644 --- a/lib/ExtUtils/ParseXS/CountLines.pm +++ b/lib/ExtUtils/ParseXS/CountLines.pm @@ -1,7 +1,7 @@ package ExtUtils::ParseXS::CountLines; use strict; -our $VERSION = '3.24'; +our $VERSION = '3.28'; our $SECTION_END_MARKER; diff --git a/lib/ExtUtils/ParseXS/Eval.pm b/lib/ExtUtils/ParseXS/Eval.pm index 4b8cbd6..b4f41cb 100644 --- a/lib/ExtUtils/ParseXS/Eval.pm +++ b/lib/ExtUtils/ParseXS/Eval.pm @@ -2,7 +2,7 @@ package ExtUtils::ParseXS::Eval; use strict; use warnings; -our $VERSION = '3.24'; +our $VERSION = '3.28'; =head1 NAME diff --git a/lib/ExtUtils/ParseXS/Utilities.pm b/lib/ExtUtils/ParseXS/Utilities.pm index ae384fd..37094cb 100644 --- a/lib/ExtUtils/ParseXS/Utilities.pm +++ b/lib/ExtUtils/ParseXS/Utilities.pm @@ -3,10 +3,9 @@ use strict; use warnings; use Exporter; use File::Spec; -use lib qw( lib ); use ExtUtils::ParseXS::Constants (); -our $VERSION = '3.24'; +our $VERSION = '3.28'; our (@ISA, @EXPORT_OK); @ISA = qw(Exporter); @@ -453,10 +452,10 @@ EOF /* prototype to pass -Wmissing-prototypes */ STATIC void -S_croak_xs_usage(pTHX_ const CV *const cv, const char *const params); +S_croak_xs_usage(const CV *const cv, const char *const params); STATIC void -S_croak_xs_usage(pTHX_ const CV *const cv, const char *const params) +S_croak_xs_usage(const CV *const cv, const char *const params) { const GV *const gv = CvGV(cv); @@ -468,21 +467,17 @@ S_croak_xs_usage(pTHX_ const CV *const cv, const char *const params) const char *const hvname = stash ? HvNAME(stash) : NULL; if (hvname) - Perl_croak(aTHX_ "Usage: %s::%s(%s)", hvname, gvname, params); + Perl_croak_nocontext("Usage: %s::%s(%s)", hvname, gvname, params); else - Perl_croak(aTHX_ "Usage: %s(%s)", gvname, params); + Perl_croak_nocontext("Usage: %s(%s)", gvname, params); } else { /* Pants. I don't think that it should be possible to get here. */ - Perl_croak(aTHX_ "Usage: CODE(0x%"UVxf")(%s)", PTR2UV(cv), params); + Perl_croak_nocontext("Usage: CODE(0x%"UVxf")(%s)", PTR2UV(cv), params); } } #undef PERL_ARGS_ASSERT_CROAK_XS_USAGE -#ifdef PERL_IMPLICIT_CONTEXT -#define croak_xs_usage(a,b) S_croak_xs_usage(aTHX_ a,b) -#else #define croak_xs_usage S_croak_xs_usage -#endif #endif @@ -495,6 +490,12 @@ S_croak_xs_usage(pTHX_ const CV *const cv, const char *const params) #define newXSproto_portable(name, c_impl, file, proto) (PL_Sv=(SV*)newXS(name, c_impl, file), sv_setpv(PL_Sv, proto), (CV*)PL_Sv) #endif /* !defined(newXS_flags) */ +#if PERL_VERSION_LE(5, 21, 5) +# define newXS_deffile(a,b) Perl_newXS(aTHX_ a,b,file) +#else +# define newXS_deffile(a,b) Perl_newXS_deffile(aTHX_ a,b) +#endif + EOF return 1; } diff --git a/lib/ExtUtils/Typemaps.pm b/lib/ExtUtils/Typemaps.pm index 8bc04af..f9b568d 100644 --- a/lib/ExtUtils/Typemaps.pm +++ b/lib/ExtUtils/Typemaps.pm @@ -2,8 +2,7 @@ package ExtUtils::Typemaps; use 5.006001; use strict; use warnings; -our $VERSION = '3.24'; -#use Carp qw(croak); +our $VERSION = '3.28'; require ExtUtils::ParseXS; require ExtUtils::ParseXS::Constants; diff --git a/lib/ExtUtils/Typemaps/Cmd.pm b/lib/ExtUtils/Typemaps/Cmd.pm index a0be008..c0d13c6 100644 --- a/lib/ExtUtils/Typemaps/Cmd.pm +++ b/lib/ExtUtils/Typemaps/Cmd.pm @@ -2,7 +2,7 @@ package ExtUtils::Typemaps::Cmd; use 5.006001; use strict; use warnings; -our $VERSION = '3.24'; +our $VERSION = '3.28'; use ExtUtils::Typemaps; diff --git a/lib/ExtUtils/Typemaps/InputMap.pm b/lib/ExtUtils/Typemaps/InputMap.pm index 3a60035..3a7c6fe 100644 --- a/lib/ExtUtils/Typemaps/InputMap.pm +++ b/lib/ExtUtils/Typemaps/InputMap.pm @@ -2,7 +2,7 @@ package ExtUtils::Typemaps::InputMap; use 5.006001; use strict; use warnings; -our $VERSION = '3.24'; +our $VERSION = '3.28'; =head1 NAME diff --git a/lib/ExtUtils/Typemaps/OutputMap.pm b/lib/ExtUtils/Typemaps/OutputMap.pm index 8a01969..758ad5e 100644 --- a/lib/ExtUtils/Typemaps/OutputMap.pm +++ b/lib/ExtUtils/Typemaps/OutputMap.pm @@ -2,7 +2,7 @@ package ExtUtils::Typemaps::OutputMap; use 5.006001; use strict; use warnings; -our $VERSION = '3.24'; +our $VERSION = '3.28'; =head1 NAME @@ -108,7 +108,7 @@ eligible for using the C-related macros to optimize this. Thus the name of the method: C. If this optimization is applicable, C will -emit a C definition at the start of the generate XSUB code, +emit a C definition at the start of the generated XSUB code, and type (see below) dependent code to set C and push it on the stack at the end of the generated XSUB code. diff --git a/lib/ExtUtils/Typemaps/Type.pm b/lib/ExtUtils/Typemaps/Type.pm index fa0ca69..47a2662 100644 --- a/lib/ExtUtils/Typemaps/Type.pm +++ b/lib/ExtUtils/Typemaps/Type.pm @@ -4,7 +4,7 @@ use strict; use warnings; require ExtUtils::Typemaps; -our $VERSION = '3.24'; +our $VERSION = '3.28'; =head1 NAME diff --git a/t/109-standard_XS_defs.t b/t/109-standard_XS_defs.t index 0d11c47..da03920 100644 --- a/t/109-standard_XS_defs.t +++ b/t/109-standard_XS_defs.t @@ -2,7 +2,7 @@ use strict; use warnings; $| = 1; -use Test::More tests => 5; +use Test::More tests => 4; use File::Spec; use lib (-d 't' ? File::Spec->catdir(qw(t lib)) : 'lib'); use ExtUtils::ParseXS::Utilities qw( @@ -13,7 +13,6 @@ use PrimitiveCapture; my @statements = ( '#ifndef PERL_UNUSED_VAR', '#ifndef PERL_ARGS_ASSERT_CROAK_XS_USAGE', - '#ifdef PERL_IMPLICIT_CONTEXT', '#ifdef newXS_flags', ); -- 2.1.0