Perl / perl5

šŸŖ The Perl programming language
https://dev.perl.org/perl5/
Other
1.88k stars 530 forks source link

Bleadperl breaks LEMBARK/LinkedList-Single-0.99.1.tar.gz #10165

Closed p5pRT closed 14 years ago

p5pRT commented 14 years ago

Migrated from rt.perl.org#72740 (status was 'resolved')

Searchable as RT72740$

p5pRT commented 14 years ago

From @andk

Created by sand@k81.nonet

The distribution LEMBARK/LinkedList-Single-0.99.1.tar.gz fails since commit v5.11.1-147-gf746176​:

commit f7461760003db2ce68155c97ea6c1658e96fcd27 Author​: Zefram \zefram@​fysh\.org Date​: Sun Nov 8 15​:03​:45 2009 +0100

  Bareword sub lookups

Reported on rt.cpan.org as https://rt.cpan.org/Ticket/Display.html?id=54581

The failing test looks up method names in the symbol table and then checks with ->can if the methods are available. After the above commit the method 'looks_like_number' fails this test.

Perl Info ``` Flags: category=core severity=high Site configuration information for perl 5.11.1: Configured by sand at Fri Dec 18 12:26:57 CET 2009. Summary of my perl5 (revision 5 version 11 subversion 1) configuration: Commit id: f7461760003db2ce68155c97ea6c1658e96fcd27 Platform: osname=linux, osvers=2.6.30-1-amd64, archname=x86_64-linux uname='linux k81 2.6.30-1-amd64 #1 smp sat aug 15 18:09:19 utc 2009 x86_64 gnulinux ' config_args='-Dprefix=/home/src/perl/repoperls/installed-perls/perl/v5.11.1-147-gf746176 -Dinstallusrbinperl=n -Uversiononly -Dusedevel -des -Ui_db' hint=recommended, useposix=true, d_sigaction=define useithreads=undef, usemultiplicity=undef useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef use64bitint=define, use64bitall=define, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cc', ccflags ='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-O2', cppflags='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include' ccversion='', gccversion='4.3.4', gccosandvers='' intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16 ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='cc', ldflags =' -fstack-protector -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib /lib64 /usr/lib64 libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc libc=/lib/libc-2.9.so, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='2.9' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E' cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector' Locally applied patches: @INC for perl 5.11.1: /home/src/perl/repoperls/installed-perls/perl/v5.11.1-147-gf746176/lib/site_perl/5.11.1/x86_64-linux /home/src/perl/repoperls/installed-perls/perl/v5.11.1-147-gf746176/lib/site_perl/5.11.1 /home/src/perl/repoperls/installed-perls/perl/v5.11.1-147-gf746176/lib/5.11.1/x86_64-linux /home/src/perl/repoperls/installed-perls/perl/v5.11.1-147-gf746176/lib/5.11.1 . Environment for perl 5.11.1: HOME=/home/sand LANG=en_GB.UTF-8 LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/sand/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/usr/local/perl/bin:/usr/X11/bin:/sbin:/usr/sbin PERL_BADLANG (unset) SHELL=/usr/bin/zsh -- andreas ```
p5pRT commented 14 years ago

From @obra

This is one of two known\, open RC-blockers for 5.12.0. Karl Williamson is hard at work on the other one.

Steve Hay is putting out a blead release the day after tomorrow. It'd make me so incredibly happy if we could ship 5.11.5 with no known RC-blockers.

-j

Andreas has bisected the failure​:

The distribution LEMBARK/LinkedList-Single-0.99.1.tar.gz fails since commit v5.11.1-147-gf746176​:

commit f7461760003db2ce68155c97ea6c1658e96fcd27 Author​: Zefram \zefram@​fysh\.org Date​: Sun Nov 8 15​:03​:45 2009 +0100

Bareword sub lookups

Reported on rt.cpan.org as https://rt.cpan.org/Ticket/Display.html?id=54581

The failing test looks up method names in the symbol table and then checks with ->can if the methods are available. After the above commit the method 'looks_like_number' fails this test.

p5pRT commented 14 years ago

The RT System itself - Status changed from 'new' to 'open'

p5pRT commented 14 years ago

From p5p@perl.wizbit.be

Andreas has bisected the failure​:

The distribution LEMBARK/LinkedList-Single-0.99.1.tar.gz fails since commit v5.11.1-147-gf746176​:

commit f7461760003db2ce68155c97ea6c1658e96fcd27 Author​: Zefram \zefram@​fysh\.org Date​: Sun Nov 8 15​:03​:45 2009 +0100

Bareword sub lookups

What happens is that the module contains​:

sub splice {   my $listh = shift;   my $count = shift || 1;

  looks_like_number $count   or croak "Bogus splice​: non-numeric '$count'"; ... }

But it never defines looks_like_number.

The test suite looks at the symbol table and calls ->can($_).

In perl-5.10.1 looks_like_number is not in the symbol table\, in
perl-5.11.4 it is.

A shorter test case for this​:

#!/usr/bin/perl -l

package RT_72740;

use strict; use warnings; my $f = 1;

sub s1 {   s2 $f; }

package main;

print for keys %RT_72740​::; __END__

$ perl-5.10.0 rt-72740.pl s1 BEGIN

$ perl-5.11.4 rt-72740.pl s1 s2 BEGIN

Best regards\,

Bram

p5pRT commented 14 years ago

From p5p@perl.wizbit.be

Citeren Bram \p5p@​perl\.wizbit\.be​:

Andreas has bisected the failure​:

The distribution LEMBARK/LinkedList-Single-0.99.1.tar.gz fails since commit v5.11.1-147-gf746176​:

commit f7461760003db2ce68155c97ea6c1658e96fcd27 Author​: Zefram \zefram@​fysh\.org Date​: Sun Nov 8 15​:03​:45 2009 +0100

Bareword sub lookups

What happens is that the module contains​:

sub splice { my $listh = shift; my $count = shift || 1;

looks\_like\_number $count
or croak "Bogus splice​: non\-numeric '$count'";

... }

But it never defines looks_like_number.

The test suite looks at the symbol table and calls ->can($_).

In perl-5.10.1 looks_like_number is not in the symbol table\, in perl-5.11.4 it is.

A shorter test case for this​:

#!/usr/bin/perl -l

package RT_72740;

use strict; use warnings; my $f = 1;

sub s1 { s2 $f; }

package main;

print for keys %RT_72740​::; __END__

$ perl-5.10.0 rt-72740.pl s1 BEGIN

$ perl-5.11.4 rt-72740.pl s1 s2 BEGIN

Thinking some more about it​:

There is a case in which 'looks_like_number $count'/'s2 $f' works
without s2 being defined in RT_72740 (because of indirect object
syntax)​:

#!/usr/bin/perl -l

package RT_72740;

use strict; use warnings; my $f = bless {}\, "main";;

sub s1 {   s2 $f; }

package main;

print for keys %RT_72740​::;

sub s2 {   print "a"; } RT_72740​::s1();

__END__

$ perl5.10.0 rt-72740.pl s1 BEGIN a

$ perl5.11.4 rt-72740.pl s1 s2 BEGIN a

Best regards\,

Bram

p5pRT commented 14 years ago

From @cpansprout

By fumbling around in the dark\, I was able to come up with a fix\,
which is no doubt the worst approach. But it shows where the problem
lies​: The new rv2cv created in Perl_yylex (in the bareword-handling
code) leaves an extra GV lying around\, which needs to be deleted if
the rv2cv turns out to be temporary.

All tests pass for me with this patch (except for cpan/CGI/t/http.t\,
but thatā€™s unrelated).

I donā€™t know where tests for this should go. Here is a test case​:

{   package LinkedList​::Single;   if(0) {   my $x;   looks_like_number $x;   method Package;   another_method {};   bareword;   } } is(   join("-"\, keys %LinkedList​::Single​::)\,   ""\,   'bare words or methods do not leave extra globs lying around' );

p5pRT commented 14 years ago

From @cpansprout

Inline Patch ```diff diff -Nurp blead/toke.c blead-72740/toke.c --- blead/toke.c 2010-02-03 10:00:10.000000000 -0800 +++ blead-72740/toke.c 2010-02-15 18:18:03.000000000 -0800 @@ -6073,6 +6073,47 @@ Perl_yylex(pTHX) } } + /* If the rv2cv_op turns out to be temporary, when we free + it we need to delete the gv that it created, if any. */ +#define free_rv2cv_op \ + STMT_START { \ + op_free(rv2cv_op); \ + if (!gv) { \ + char *namecursor = PL_tokenbuf; \ + char *nameend \ + = PL_tokenbuf + ( \ + len ? len : strlen(PL_tokenbuf) \ + ); \ + char *nsplit = NULL; \ + char *name = PL_tokenbuf; \ + HV *stash; \ + for (; namecursor < nameend; namecursor++) { \ + if (*namecursor == '\'') { \ + nsplit = namecursor; \ + name = namecursor + 1; \ + } \ + else if ( *namecursor == ':' \ + && namecursor < nameend - 1 \ + && *(namecursor + 1) == ':' \ + ) { \ + nsplit = namecursor++; \ + name = namecursor + 1; \ + } \ + } \ + if (nsplit) \ + stash \ + = gv_stashpvn( \ + PL_tokenbuf, nsplit - PL_tokenbuf, 0 \ + ); \ + else stash = PL_curstash; \ + if (stash) \ + (void*)hv_delete( \ + stash, name, nameend - name, G_DISCARD \ + ); \ + } \ + } STMT_END + + /* See if it's the indirect object for a list operator. */ if (PL_oldoldbufptr && @@ -6095,7 +6136,7 @@ Perl_yylex(pTHX) if ((isIDFIRST_lazy_if(s,UTF) || *s == '$') && (tmp = intuit_method(s, gv, cv))) { - op_free(rv2cv_op); + free_rv2cv_op; return REPORT(tmp); } @@ -6128,7 +6169,7 @@ Perl_yylex(pTHX) /* Is this a word before a => operator? */ if (*s == '=' && s[1] == '>' && !pkgname) { - op_free(rv2cv_op); + free_rv2cv_op; CLINE; sv_setpv(((SVOP*)pl_yylval.opval)->op_sv, PL_tokenbuf); if (UTF && !IN_BYTES && is_utf8_string((U8*)PL_tokenbuf, len)) @@ -6164,7 +6205,7 @@ Perl_yylex(pTHX) PL_thistoken = newSVpvs(""); } #endif - op_free(rv2cv_op); + free_rv2cv_op; force_next(WORD); pl_yylval.ival = 0; TOKEN('&'); @@ -6173,7 +6214,7 @@ Perl_yylex(pTHX) /* If followed by var or block, call it a method (unless sub) */ if ((*s == '$' || *s == '{') && !cv) { - op_free(rv2cv_op); + free_rv2cv_op; PL_last_lop = PL_oldbufptr; PL_last_lop_op = OP_METHOD; PREBLOCK(METHOD); @@ -6184,7 +6225,7 @@ Perl_yylex(pTHX) if (!orig_keyword && (isIDFIRST_lazy_if(s,UTF) || *s == '$') && (tmp = intuit_method(s, gv, cv))) { - op_free(rv2cv_op); + free_rv2cv_op; return REPORT(tmp); } @@ -6198,7 +6239,7 @@ Perl_yylex(pTHX) /* Check for a constant sub */ if ((sv = cv_const_sv(cv))) { its_constant: - op_free(rv2cv_op); + free_rv2cv_op; SvREFCNT_dec(((SVOP*)pl_yylval.opval)->op_sv); ((SVOP*)pl_yylval.opval)->op_sv = SvREFCNT_inc_simple(sv); pl_yylval.opval->op_private = 0; @@ -6326,7 +6367,9 @@ Perl_yylex(pTHX) } } } - op_free(rv2cv_op); + free_rv2cv_op; + +#undef free_rv2cv_op; safe_bareword: if ((lastchar == '*' || lastchar == '%' || lastchar == '&')) { ```
p5pRT commented 14 years ago

From zefram@fysh.org

Father Chrysostomos wrote​:

new rv2cv created in Perl_yylex (in the bareword-handling code) leaves an extra GV lying around\, which needs to be deleted if the rv2cv turns out to be temporary.

Yes\, that's probably going to be the best approach. I think you put the deletion in the wrong place\, though\, and it would be better to do it automatically in gv.c\, the same way that GVs get automatically downgraded to the optimised form for const subs. Also got a bit of concern about the used-once warnings\, mediated through the GvMULTI flag.

-zefram

p5pRT commented 14 years ago

From gerard@ggoossen.net

Attached patch fixes the bug by reverting the patch inserting rv2cv into the lexer.

The reverted patch didn't fix any real bugs. Instead of doing difficult to make the rv2cv hack work\, instead a proper hook should be develop to allow hooking into the function lookup.

Gerard Goossen

On Thu\, Feb 18\, 2010 at 11​:31​:56AM -0800\, Jesse Vincent wrote​:

This is one of two known\, open RC-blockers for 5.12.0. Karl Williamson is hard at work on the other one.

Steve Hay is putting out a blead release the day after tomorrow. It'd make me so incredibly happy if we could ship 5.11.5 with no known RC-blockers.

-j

Andreas has bisected the failure​:

The distribution LEMBARK/LinkedList-Single-0.99.1.tar.gz fails since commit v5.11.1-147-gf746176​:

commit f7461760003db2ce68155c97ea6c1658e96fcd27 Author​: Zefram \zefram@&#8203;fysh\.org Date​: Sun Nov 8 15​:03​:45 2009 +0100

Bareword sub lookups

Reported on rt.cpan.org as https://rt.cpan.org/Ticket/Display.html?id=54581

The failing test looks up method names in the symbol table and then checks with ->can if the methods are available. After the above commit the method 'looks_like_number' fails this test.

p5pRT commented 14 years ago

From gerard@ggoossen.net

0001-Revert-Bareword-sub-lookups.patch ```diff From dde8cec27bb9ae775aca91d2c9128a104d94cce4 Mon Sep 17 00:00:00 2001 From: Gerard Goossen Date: Mon, 8 Mar 2010 18:21:42 +0100 Subject: [PATCH] Revert "Bareword sub lookups" This reverts commit f7461760003db2ce68155c97ea6c1658e96fcd27. Fixes [perl #72740] Conflicts: op.c pod/perl5112delta.pod --- embed.fnc | 1 - embed.h | 2 - global.sym | 1 - gv.c | 47 -------------------------------- op.c | 64 +++++++++---------------------------------- pod/perl5112delta.pod | 10 ------- proto.h | 5 --- toke.c | 71 ++++++++++++++++++++---------------------------- 8 files changed, 44 insertions(+), 157 deletions(-) diff --git a/embed.fnc b/embed.fnc index 0e4ec03..e94dec9 100644 --- a/embed.fnc +++ b/embed.fnc @@ -438,7 +438,6 @@ Ap |void |gv_fullname4 |NN SV* sv|NN const GV* gv|NULLOK const char* prefix|bool pMox |GP * |newGP |NN GV *const gv Ap |void |gv_init |NN GV* gv|NULLOK HV* stash|NN const char* name|STRLEN len|int multi Ap |void |gv_name_set |NN GV* gv|NN const char *name|U32 len|U32 flags -Apd |void |gv_try_downgrade|NN GV* gv Apd |HV* |gv_stashpv |NN const char* name|I32 flags Apd |HV* |gv_stashpvn |NN const char* name|U32 namelen|I32 flags Apd |HV* |gv_stashsv |NN SV* sv|I32 flags diff --git a/embed.h b/embed.h index 4858c56..eae15f4 100644 --- a/embed.h +++ b/embed.h @@ -294,7 +294,6 @@ #define gv_fullname4 Perl_gv_fullname4 #define gv_init Perl_gv_init #define gv_name_set Perl_gv_name_set -#define gv_try_downgrade Perl_gv_try_downgrade #define gv_stashpv Perl_gv_stashpv #define gv_stashpvn Perl_gv_stashpvn #define gv_stashsv Perl_gv_stashsv @@ -2696,7 +2695,6 @@ #endif #define gv_init(a,b,c,d,e) Perl_gv_init(aTHX_ a,b,c,d,e) #define gv_name_set(a,b,c,d) Perl_gv_name_set(aTHX_ a,b,c,d) -#define gv_try_downgrade(a) Perl_gv_try_downgrade(aTHX_ a) #define gv_stashpv(a,b) Perl_gv_stashpv(aTHX_ a,b) #define gv_stashpvn(a,b,c) Perl_gv_stashpvn(aTHX_ a,b,c) #define gv_stashsv(a,b) Perl_gv_stashsv(aTHX_ a,b) diff --git a/global.sym b/global.sym index 7788338..69027ac 100644 --- a/global.sym +++ b/global.sym @@ -149,7 +149,6 @@ Perl_gv_fullname3 Perl_gv_fullname4 Perl_gv_init Perl_gv_name_set -Perl_gv_try_downgrade Perl_gv_stashpv Perl_gv_stashpvn Perl_gv_stashsv diff --git a/gv.c b/gv.c index dfcb376..d54563b 100644 --- a/gv.c +++ b/gv.c @@ -2362,53 +2362,6 @@ Perl_gv_name_set(pTHX_ GV *gv, const char *name, U32 len, U32 flags) } /* -=for apidoc gv_try_downgrade - -If C is a typeglob containing only a constant sub, and is only -referenced from its package, and both the typeglob and the sub are -sufficiently ordinary, replace the typeglob (in the package) with a -placeholder that more compactly represents the same thing. This is meant -to be used when a placeholder has been upgraded, most likely because -something wanted to look at a proper code object, and it has turned out -to be a constant sub to which a proper reference is no longer required. - -=cut -*/ - -void -Perl_gv_try_downgrade(pTHX_ GV *gv) -{ - HV *stash; - CV *cv; - HEK *namehek; - SV **gvp; - PERL_ARGS_ASSERT_GV_TRY_DOWNGRADE; - if (SvREFCNT(gv) == 1 && SvTYPE(gv) == SVt_PVGV && !SvFAKE(gv) && - !SvOBJECT(gv) && !SvMAGICAL(gv) && !SvREADONLY(gv) && - isGV_with_GP(gv) && GvGP(gv) && - GvMULTI(gv) && !GvINTRO(gv) && GvREFCNT(gv) == 1 && - !GvSV(gv) && !GvAV(gv) && !GvHV(gv) && !GvIOp(gv) && !GvFORM(gv) && - GvEGV(gv) == gv && (stash = GvSTASH(gv)) && (cv = GvCV(gv)) && - !SvOBJECT(cv) && !SvMAGICAL(cv) && !SvREADONLY(cv) && - CvSTASH(cv) == stash && CvGV(cv) == gv && - CvCONST(cv) && !CvMETHOD(cv) && !CvLVALUE(cv) && !CvUNIQUE(cv) && - !CvNODEBUG(cv) && !CvCLONE(cv) && !CvCLONED(cv) && !CvANON(cv) && - (namehek = GvNAME_HEK(gv)) && - (gvp = hv_fetch(stash, HEK_KEY(namehek), - HEK_LEN(namehek)*(HEK_UTF8(namehek) ? -1 : 1), 0)) && - *gvp == (SV*)gv) { - SV *value = SvREFCNT_inc(CvXSUBANY(cv).any_ptr); - SvREFCNT(gv) = 0; - sv_clear((SV*)gv); - SvREFCNT(gv) = 1; - SvFLAGS(gv) = SVt_IV|SVf_ROK; - SvANY(gv) = (XPVGV*)((char*)&(gv->sv_u.svu_iv) - - STRUCT_OFFSET(XPVIV, xiv_iv)); - SvRV_set(gv, value); - } -} - -/* * Local variables: * c-indentation-style: bsd * c-basic-offset: 4 diff --git a/op.c b/op.c index c4289ce..67816c3 100644 --- a/op.c +++ b/op.c @@ -575,29 +575,6 @@ Perl_op_clear(pTHX_ OP *o) case OP_AELEMFAST: if (! (o->op_type == OP_AELEMFAST && o->op_flags & OPf_SPECIAL)) { /* not an OP_PADAV replacement */ - GV *gv = (o->op_type == OP_GV || o->op_type == OP_GVSV) -#ifdef USE_ITHREADS - && PL_curpad -#endif - ? cGVOPo_gv : NULL; - /* It's possible during global destruction that the GV is freed - before the optree. Whilst the SvREFCNT_inc is happy to bump from - 0 to 1 on a freed SV, the corresponding SvREFCNT_dec from 1 to 0 - will trigger an assertion failure, because the entry to sv_clear - checks that the scalar is not already freed. A check of for - !SvIS_FREED(gv) turns out to be invalid, because during global - destruction the reference count can be forced down to zero - (with SVf_BREAK set). In which case raising to 1 and then - dropping to 0 triggers cleanup before it should happen. I - *think* that this might actually be a general, systematic, - weakness of the whole idea of SVf_BREAK, in that code *is* - allowed to raise and lower references during global destruction, - so any *valid* code that happens to do this during global - destruction might well trigger premature cleanup. */ - bool still_valid = gv && SvREFCNT(gv); - - if (still_valid) - SvREFCNT_inc_simple_void(gv); #ifdef USE_ITHREADS if (cPADOPo->op_padix > 0) { /* No GvIN_PAD_off(cGVOPo_gv) here, because other references @@ -609,12 +586,6 @@ Perl_op_clear(pTHX_ OP *o) SvREFCNT_dec(cSVOPo->op_sv); cSVOPo->op_sv = NULL; #endif - if (still_valid) { - int try_downgrade = SvREFCNT(gv) == 2; - SvREFCNT_dec(gv); - if (try_downgrade) - gv_try_downgrade(gv); - } } break; case OP_METHOD_NAMED: @@ -8022,29 +7993,22 @@ Perl_ck_subr(pTHX_ OP *o) o->op_private |= OPpENTERSUB_HASTARG; for (cvop = o2; cvop->op_sibling; cvop = cvop->op_sibling) ; if (cvop->op_type == OP_RV2CV) { + SVOP* tmpop; o->op_private |= (cvop->op_private & OPpENTERSUB_AMPER); op_null(cvop); /* disable rv2cv */ - if (!(o->op_private & OPpENTERSUB_AMPER)) { - SVOP *tmpop = (SVOP*)((UNOP*)cvop)->op_first; - GV *gv = NULL; - switch (tmpop->op_type) { - case OP_GV: { - gv = cGVOPx_gv(tmpop); - cv = GvCVu(gv); - if (!cv) - tmpop->op_private |= OPpEARLY_CV; - } break; - case OP_CONST: { - SV *sv = cSVOPx_sv(tmpop); - if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVCV) - cv = (CV*)SvRV(sv); - } break; - } - if (cv && SvPOK(cv)) { - STRLEN len; - namegv = gv && CvANON(cv) ? gv : CvGV(cv); - proto = SvPV(MUTABLE_SV(cv), len); - proto_end = proto + len; + tmpop = (SVOP*)((UNOP*)cvop)->op_first; + if (tmpop->op_type == OP_GV && !(o->op_private & OPpENTERSUB_AMPER)) { + GV *gv = cGVOPx_gv(tmpop); + cv = GvCVu(gv); + if (!cv) + tmpop->op_private |= OPpEARLY_CV; + else { + if (SvPOK(cv)) { + STRLEN len; + namegv = CvANON(cv) ? gv : CvGV(cv); + proto = SvPV(MUTABLE_SV(cv), len); + proto_end = proto + len; + } } } } diff --git a/pod/perl5112delta.pod b/pod/perl5112delta.pod index c53a622..729decd 100644 --- a/pod/perl5112delta.pod +++ b/pod/perl5112delta.pod @@ -43,16 +43,6 @@ necessary to take full advantage of the core's facilities in these areas. It is intended that the Perl 5.13 development cycle will see the addition of a full range of clean, supported interfaces. -=head2 Overridable function lookup - -Where an extension module hooks the creation of rv2cv ops to modify the -subroutine lookup process, this now works correctly for bareword -subroutine calls. This means that prototypes on subroutines referenced -this way will be processed correctly. (Previously bareword subroutine -names were initially looked up, for parsing purposes, by an unhookable -mechanism, so extensions could only properly influence subroutine names -that appeared with an C<&> sigil.) - =head1 Modules and Pragmata =head2 New Modules and Pragmata diff --git a/proto.h b/proto.h index 979076f..281d844 100644 --- a/proto.h +++ b/proto.h @@ -950,11 +950,6 @@ PERL_CALLCONV void Perl_gv_name_set(pTHX_ GV* gv, const char *name, U32 len, U32 #define PERL_ARGS_ASSERT_GV_NAME_SET \ assert(gv); assert(name) -PERL_CALLCONV void Perl_gv_try_downgrade(pTHX_ GV* gv) - __attribute__nonnull__(pTHX_1); -#define PERL_ARGS_ASSERT_GV_TRY_DOWNGRADE \ - assert(gv) - PERL_CALLCONV HV* Perl_gv_stashpv(pTHX_ const char* name, I32 flags) __attribute__nonnull__(pTHX_1); #define PERL_ARGS_ASSERT_GV_STASHPV \ diff --git a/toke.c b/toke.c index a7a71a4..85dfd01 100644 --- a/toke.c +++ b/toke.c @@ -6213,7 +6213,6 @@ Perl_yylex(pTHX) SV *sv; int pkgname = 0; const char lastchar = (PL_bufptr == PL_oldoldbufptr ? 0 : PL_bufptr[-1]); - OP *rv2cv_op; CV *cv; #ifdef PERL_MAD SV *nextPL_nextwhite = 0; @@ -6307,29 +6306,19 @@ Perl_yylex(pTHX) if (len) goto safe_bareword; - cv = NULL; - { - OP *const_op = newSVOP(OP_CONST, 0, SvREFCNT_inc(sv)); - const_op->op_private = OPpCONST_BARE; - rv2cv_op = newCVREF(0, const_op); - } - if (rv2cv_op->op_type == OP_RV2CV && - (rv2cv_op->op_flags & OPf_KIDS)) { - OP *rv_op = cUNOPx(rv2cv_op)->op_first; - switch (rv_op->op_type) { - case OP_CONST: { - SV *sv = cSVOPx_sv(rv_op); - if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVCV) - cv = (CV*)SvRV(sv); - } break; - case OP_GV: { - GV *gv = cGVOPx_gv(rv_op); - CV *maybe_cv = GvCVu(gv); - if (maybe_cv && SvTYPE((SV*)maybe_cv) == SVt_PVCV) - cv = maybe_cv; - } break; - } - } + /* Do the explicit type check so that we don't need to force + the initialisation of the symbol table to have a real GV. + Beware - gv may not really be a PVGV, cv may not really be + a PVCV, (because of the space optimisations that gv_init + understands) But they're true if for this symbol there is + respectively a typeglob and a subroutine. + */ + cv = gv ? ((SvTYPE(gv) == SVt_PVGV) + /* Real typeglob, so get the real subroutine: */ + ? GvCVu(gv) + /* A proxy for a subroutine in this package? */ + : SvOK(gv) ? MUTABLE_CV(gv) : NULL) + : NULL; /* See if it's the indirect object for a list operator. */ @@ -6352,10 +6341,8 @@ Perl_yylex(pTHX) /* Two barewords in a row may indicate method call. */ if ((isIDFIRST_lazy_if(s,UTF) || *s == '$') && - (tmp = intuit_method(s, gv, cv))) { - op_free(rv2cv_op); + (tmp = intuit_method(s, gv, cv))) return REPORT(tmp); - } /* If not a declared subroutine, it's an indirect object. */ /* (But it's an indir obj regardless for sort.) */ @@ -6363,7 +6350,7 @@ Perl_yylex(pTHX) if ( ( !immediate_paren && (PL_last_lop_op == OP_SORT || - (!cv && + ((!gv || !cv) && (PL_last_lop_op != OP_MAPSTART && PL_last_lop_op != OP_GREPSTART)))) || (PL_tokenbuf[0] == '_' && PL_tokenbuf[1] == '\0' @@ -6386,7 +6373,6 @@ Perl_yylex(pTHX) /* Is this a word before a => operator? */ if (*s == '=' && s[1] == '>' && !pkgname) { - op_free(rv2cv_op); CLINE; sv_setpv(((SVOP*)pl_yylval.opval)->op_sv, PL_tokenbuf); if (UTF && !IN_BYTES && is_utf8_string((U8*)PL_tokenbuf, len)) @@ -6401,7 +6387,7 @@ Perl_yylex(pTHX) d = s + 1; while (SPACE_OR_TAB(*d)) d++; - if (*d == ')' && (sv = cv_const_sv(cv))) { + if (*d == ')' && (sv = gv_const_sv(gv))) { s = d + 1; goto its_constant; } @@ -6422,7 +6408,6 @@ Perl_yylex(pTHX) PL_thistoken = newSVpvs(""); } #endif - op_free(rv2cv_op); force_next(WORD); pl_yylval.ival = 0; TOKEN('&'); @@ -6430,8 +6415,7 @@ Perl_yylex(pTHX) /* If followed by var or block, call it a method (unless sub) */ - if ((*s == '$' || *s == '{') && !cv) { - op_free(rv2cv_op); + if ((*s == '$' || *s == '{') && (!gv || !cv)) { PL_last_lop = PL_oldbufptr; PL_last_lop_op = OP_METHOD; PREBLOCK(METHOD); @@ -6441,10 +6425,8 @@ Perl_yylex(pTHX) if (!orig_keyword && (isIDFIRST_lazy_if(s,UTF) || *s == '$') - && (tmp = intuit_method(s, gv, cv))) { - op_free(rv2cv_op); + && (tmp = intuit_method(s, gv, cv))) return REPORT(tmp); - } /* Not a method, so call it a subroutine (if defined) */ @@ -6454,17 +6436,25 @@ Perl_yylex(pTHX) "Ambiguous use of -%s resolved as -&%s()", PL_tokenbuf, PL_tokenbuf); /* Check for a constant sub */ - if ((sv = cv_const_sv(cv))) { + if ((sv = gv_const_sv(gv))) { its_constant: - op_free(rv2cv_op); SvREFCNT_dec(((SVOP*)pl_yylval.opval)->op_sv); ((SVOP*)pl_yylval.opval)->op_sv = SvREFCNT_inc_simple(sv); pl_yylval.opval->op_private = 0; TOKEN(WORD); } + /* Resolve to GV now. */ + if (SvTYPE(gv) != SVt_PVGV) { + gv = gv_fetchpv(PL_tokenbuf, 0, SVt_PVCV); + assert (SvTYPE(gv) == SVt_PVGV); + /* cv must have been some sort of placeholder, so + now needs replacing with a real code reference. */ + cv = GvCV(gv); + } + op_free(pl_yylval.opval); - pl_yylval.opval = rv2cv_op; + pl_yylval.opval = newCVREF(0, newGVOP(OP_GV, 0, gv)); pl_yylval.opval->op_private |= OPpENTERSUB_NOPAREN; PL_last_lop = PL_oldbufptr; PL_last_lop_op = OP_ENTERSUB; @@ -6532,7 +6522,7 @@ Perl_yylex(pTHX) if (probable_sub) { gv = gv_fetchpv(PL_tokenbuf, GV_ADD, SVt_PVCV); op_free(pl_yylval.opval); - pl_yylval.opval = rv2cv_op; + pl_yylval.opval = newCVREF(0, newGVOP(OP_GV, 0, gv)); pl_yylval.opval->op_private |= OPpENTERSUB_NOPAREN; PL_last_lop = PL_oldbufptr; PL_last_lop_op = OP_ENTERSUB; @@ -6584,7 +6574,6 @@ Perl_yylex(pTHX) } } } - op_free(rv2cv_op); safe_bareword: if ((lastchar == '*' || lastchar == '%' || lastchar == '&')) { -- 1.7.0 ```
p5pRT commented 14 years ago

From zefram@fysh.org

Gerard Goossen wrote​:

Attached patch fixes the bug by reverting the patch inserting rv2cv into the lexer.

I object to this approach. The rv2cv patch has real value\, and the "proper hook" for function lookup that you refer to is in fact the op checker for rv2cv. The patch is not a hack\, it's a cleanup of pre-existing hacks.

I'll work on #72740 myself.

-zefram

p5pRT commented 14 years ago

From zefram@fysh.org

Jesse Vincent wrote​:

The distribution LEMBARK/LinkedList-Single-0.99.1.tar.gz fails since commit v5.11.1-147-gf746176​:

Fixed by the attached patch.

The issue is that speculative function lookups were leaving detritus consisting of empty GVs in the stash. These didn't affect normal functioning\, but code that looks inside the stash could see them\, and code that makes unreliable assumptions about the format of the stash can be broken. This is the same general mode of failure that we saw with namespace​::clean.

LinkedList-Single's failing test was using direct stash access poorly\, in a way that made for a poor test\, quite apart from making too many assumptions about stash structure. In the latest version of the package\, 0.99.6\, the test has been changed to a much better form\, which actually tests what it meant to and incidentally doesn't read the stash at all.

Although they don't affect normal functioning\, the empty GVs shouldn't be there. It's much like the upgraded constant subs\, which we concluded ought to be downgraded when the upgraded form is no longer required\, in order to save memory. The solution here is similar​: delete the empty GV when it is detected that a real GV is no longer required. The present patch does this at the same time as checking for constant-sub downgradability.

-zefram

p5pRT commented 14 years ago

From zefram@fysh.org

Inline Patch ```diff diff --git a/gv.c b/gv.c index dfcb376..becd1e9 100644 --- a/gv.c +++ b/gv.c @@ -2364,13 +2364,19 @@ Perl_gv_name_set(pTHX_ GV *gv, const char *name, U32 len, U32 flags) /* =for apidoc gv_try_downgrade -If C is a typeglob containing only a constant sub, and is only -referenced from its package, and both the typeglob and the sub are -sufficiently ordinary, replace the typeglob (in the package) with a -placeholder that more compactly represents the same thing. This is meant -to be used when a placeholder has been upgraded, most likely because -something wanted to look at a proper code object, and it has turned out -to be a constant sub to which a proper reference is no longer required. +If the typeglob C can be expressed more succinctly, by having +something other than a real GV in its place in the stash, replace it +with the optimised form. Basic requirements for this are that C +is a real typeglob, is sufficiently ordinary, and is only referenced +from its package. This function is meant to be used when a GV has been +looked up in part to see what was there, causing upgrading, but based +on what was found it turns out that the real GV isn't required after all. + +If C is a completely empty typeglob, it is deleted from the stash. + +If C is a typeglob containing only a sufficiently-ordinary constant +sub, the typeglob is replaced with a scalar-reference placeholder that +more compactly represents the same thing. =cut */ @@ -2383,12 +2389,19 @@ Perl_gv_try_downgrade(pTHX_ GV *gv) HEK *namehek; SV **gvp; PERL_ARGS_ASSERT_GV_TRY_DOWNGRADE; - if (SvREFCNT(gv) == 1 && SvTYPE(gv) == SVt_PVGV && !SvFAKE(gv) && + if (!(SvREFCNT(gv) == 1 && SvTYPE(gv) == SVt_PVGV && !SvFAKE(gv) && !SvOBJECT(gv) && !SvMAGICAL(gv) && !SvREADONLY(gv) && isGV_with_GP(gv) && GvGP(gv) && - GvMULTI(gv) && !GvINTRO(gv) && GvREFCNT(gv) == 1 && + !GvINTRO(gv) && GvREFCNT(gv) == 1 && !GvSV(gv) && !GvAV(gv) && !GvHV(gv) && !GvIOp(gv) && !GvFORM(gv) && - GvEGV(gv) == gv && (stash = GvSTASH(gv)) && (cv = GvCV(gv)) && + GvEGV(gv) == gv && (stash = GvSTASH(gv)))) + return; + cv = GvCV(gv); + if (!cv) { + HEK *gvnhek = GvNAME_HEK(gv); + (void)hv_delete(stash, HEK_KEY(gvnhek), + HEK_UTF8(gvnhek) ? -HEK_LEN(gvnhek) : HEK_LEN(gvnhek), G_DISCARD); + } else if (GvMULTI(gv) && cv && !SvOBJECT(cv) && !SvMAGICAL(cv) && !SvREADONLY(cv) && CvSTASH(cv) == stash && CvGV(cv) == gv && CvCONST(cv) && !CvMETHOD(cv) && !CvLVALUE(cv) && !CvUNIQUE(cv) && diff --git a/t/op/gv.t b/t/op/gv.t index 6f16ce2..382e3f0 100644 --- a/t/op/gv.t +++ b/t/op/gv.t @@ -12,7 +12,7 @@ BEGIN { use warnings; require './test.pl'; -plan( tests => 182 ); +plan( tests => 188 ); # type coersion on assignment $foo = 'foo'; @@ -592,6 +592,28 @@ foreach my $type (qw(integer number string)) { ); } +# [perl #72740] - indirect object syntax, heuristically imputed due to +# the non-existence of a function, should not cause a stash entry to be +# created for the non-existent function. +{ + package RT72740a; + my $f = bless({}, RT72740b); + sub s1 { s2 $f; } + our $s4; + sub s3 { s4 $f; } +} +{ + package RT72740b; + sub s2 { "RT72740b::s2" } + sub s4 { "RT72740b::s4" } +} +ok(exists($RT72740a::{s1}), "RT72740a::s1 exists"); +ok(!exists($RT72740a::{s2}), "RT72740a::s2 does not exist"); +ok(exists($RT72740a::{s3}), "RT72740a::s3 exists"); +ok(exists($RT72740a::{s4}), "RT72740a::s4 exists"); +is(RT72740a::s1(), "RT72740b::s2", "RT72740::s1 parsed correctly"); +is(RT72740a::s3(), "RT72740b::s4", "RT72740::s3 parsed correctly"); + __END__ Perl Rules ```
p5pRT commented 14 years ago

From bitcard@profvince.com

Thanks\, this patch was applied to blead as 2867cdbcac19071f99ab71a81d63dbd894cebd3b by Dave. I've checked that it fixes the issue for LinkedList​::Single 0.99.1\, so I'm closing the bug.

Vincent.

p5pRT commented 14 years ago

From [Unknown Contact. See original ticket]

Thanks\, this patch was applied to blead as 2867cdbcac19071f99ab71a81d63dbd894cebd3b by Dave. I've checked that it fixes the issue for LinkedList​::Single 0.99.1\, so I'm closing the bug.

Vincent.

p5pRT commented 14 years ago

bitcard@profvince.com - Status changed from 'open' to 'resolved'

p5pRT commented 14 years ago

From @iabyn

On Tue\, Mar 09\, 2010 at 12​:22​:10AM +0000\, Zefram wrote​:

Jesse Vincent wrote​:

The distribution LEMBARK/LinkedList-Single-0.99.1.tar.gz fails since commit v5.11.1-147-gf746176​:

Fixed by the attached patch.

The issue is that speculative function lookups were leaving detritus consisting of empty GVs in the stash. These didn't affect normal functioning\, but code that looks inside the stash could see them\, and code that makes unreliable assumptions about the format of the stash can be broken. This is the same general mode of failure that we saw with namespace​::clean.

LinkedList-Single's failing test was using direct stash access poorly\, in a way that made for a poor test\, quite apart from making too many assumptions about stash structure. In the latest version of the package\, 0.99.6\, the test has been changed to a much better form\, which actually tests what it meant to and incidentally doesn't read the stash at all.

Although they don't affect normal functioning\, the empty GVs shouldn't be there. It's much like the upgraded constant subs\, which we concluded ought to be downgraded when the upgraded form is no longer required\, in order to save memory. The solution here is similar​: delete the empty GV when it is detected that a real GV is no longer required. The present patch does this at the same time as checking for constant-sub downgradability.

Thanks\, I've applied this as 2867cdbcac19071f99ab71a81d63dbd894cebd3b.

However\, I have some concerns about the original work\, f7461760003db2ce68155c97ea6c1658e96fcd27.

Having spent a few hours now trying to understand that patch and that bit of toke.c (and not entirely succeeding)\, your original patch looks rather hackish\, from the point of view that not all the logic is located within that one section of yylex; in particular I don't like the extra logic in op_clear() and the call to gv_try_downgrade().

My understanding of your patch is that it speculatively does

  rv2cv_op = newCVREF(0\, const_op)  
earlier on in the barewod processing logic than before\, before the lexer has had a chance to decide whether the bareword is indeed a function call or something else (like BAREWORD => foo ). Doing this earlier means the PL_check hook gets called earlier\, which gives Lexical​::Var etc a chance to tell the lexer that it should indeed treat this as function\, even if it wouldn't normally. If the hook doesn't tell the lexer this\, then the lexer gets to go on with its original bareword processing instead\, and if it decides it's something boring and non-functionish\, it does

  op_clear(rv2cv_op)

just before returning\, thus freeing the unneeded op. However\, the newCVREF() may have also created a glob entry\, which needs to be undone if we clear rv2cv_op. So\, you've added some code to op_clear() which says "if this is an OP_GV or OP_GVSV we're freeing\, then try to downgrade the associated GV on the grounds that it might have been accidentally vivified earlier by the lexer.

Now then​:

surely it would be better for the lexer to decide for itself whether it touched the GV by checking its status prior to calling newCVREF()\, then if necessary undoing its mess at the same time as calling op_clear()\, rather than this leaking out into unrelated areas of code?

Anyway\, whether that turns out to be a sensible idea or not\, it's really something for post-5.12.

But something for before 5.12​:

You've added a new function\, Perl_gv_try_downgrade\, and its marked as being part of the public API. I can't see any reason why it needs to be. Tthere's a difference between merely exporting it\, and advertising it as public in the docs​: stuff that goes in the API can not (easily) be removed or have its functionality changed.

I intend soon to re-mark it as non-API and experimental someone convinces me otherwise.

-- In the 70's we wore flares because we didn't know any better. What possible excuse does the current generation have?

p5pRT commented 14 years ago

From zefram@fysh.org

Dave Mitchell wrote​:

PL_check hook gets called earlier\, which gives Lexical​::Var etc a chance to tell the lexer that it should indeed treat this as function\, even if it wouldn't normally.

Not quite. If the bareword is followed by a fat comma\, it doesn't get treated as a function call\, regardless of what the rv2cv op turns up. This hook doesn't change syntax.

The point of the change is that the possible function is looked up only through rv2cv ops. Whatever the op identifies as being the function (or lack of function) referenced by that bareword gets used as such\, for all purposes\, including particularly for prototype processing. Formerly the lexer had an inconsistent view of functions​: it used rv2cv ops to reference functions for execution\, but would look directly in packages to reference them for prototype processing and to decide whether a bareword refers to a function at all. (The latter is relevant for things like "foo $x"\, which is either a function call or indirect object syntax depending on whether "foo" exists as a function.)

newCVREF() may have also created a glob entry\, which needs to be undone if we clear rv2cv_op.

Yes. Except that "need" is a bit strong. newCVREF() may have implicitly created a GV in order to reference a currently-undefined function\, and it may have implicitly upgraded a constant-sub placeholder into a GV in order to have a first-class CV to reference. These upgradings don't change the nominal content of the package\, and so nominally don't need to be undone. It's more than anything else just a waste of memory to keep the upgraded GVs around when they're no longer required to be first-class. And\, of course\, the lexer's previous behaviour of looking directly in the package enabled it to avoid upgrading them at all.

              So\, you've added some code to op\_clear\(\) which says

"if this is an OP_GV or OP_GVSV we're freeing\, then try to downgrade the associated GV on the grounds that it might have been accidentally vivified earlier by the lexer.

Yes\, pretty much. In principle\, anything that deletes a reference to a GV could sensibly do the same thing. It's done only in op freeing because that's a sensible tradeoff to get the original memory behaviour back with minimum fuss.

surely it would be better for the lexer to decide for itself whether it touched the GV by checking its status prior to calling newCVREF()\, then if necessary undoing its mess at the same time as calling op_clear()\, rather than this leaking out into unrelated areas of code?

Not as sensible as it first seems. The op construction code knows\, and always did know\, where to find the GV. So the op code is hardly "unrelated"\, and it's pretty sensible for the op destruction code to know about special requirements upon deleting GV references. It is really the lexer that was the unrelated code into which knowledge of GVs leaked.

In the new system\, that part of the lexer is quite insulated from knowledge of GV lookups. The code that did know what GV was involved is precisely what was being moved out of the lexer in order to improve pluggability. Now the knowledge of how to look up GVs for function references is localised to the op code. Indeed\, the op code now gets to decide whether a GV is to be involved at all (it isn't when Lexical​::Var takes over)\, and a non-core rv2cv checker could decide to look up GVs somewhere other than the core logic says. The only way of being sure about which GV wants downgrading is to look in the op that was actually created and which is being discarded.

You've added a new function\, Perl_gv_try_downgrade\, and its marked as being part of the public API. I can't see any reason why it needs to be.

The intention is that things other than the lexer might do similar kinds of speculative GV lookup\, and might thus want to do similar downgrading when deleting GV references. I don't have anything that does this\, and it's not a critical capability\, but I saw no reason to restrict it to the core and some use in not so restricting it.

If we eventually find that we don't want this sort of downgrading\, or we tackle it in a completely different way\, gv_try_downgrade() can safely become a no-op. It's not tying us to a way of working that might turn out to be inconvenient\, other than the existence of GVs\, which has been pretty inconvenient but is established by a lot more of the API than this function.

-zefram

p5pRT commented 14 years ago

From @iabyn

On Wed\, Mar 10\, 2010 at 09​:10​:04PM +0000\, Zefram wrote​:

You've added a new function\, Perl_gv_try_downgrade\, and its marked as being part of the public API. I can't see any reason why it needs to be.

The intention is that things other than the lexer might do similar kinds of speculative GV lookup\, and might thus want to do similar downgrading when deleting GV references. I don't have anything that does this\, and it's not a critical capability\, but I saw no reason to restrict it to the core and some use in not so restricting it.

If we eventually find that we don't want this sort of downgrading\, or we tackle it in a completely different way\, gv_try_downgrade() can safely become a no-op. It's not tying us to a way of working that might turn out to be inconvenient\, other than the existence of GVs\, which has been pretty inconvenient but is established by a lot more of the API than this function.

The trouble is that anything that's added to the public API immediately ties our hands. IMO there's already far too much stuff in the API\, and its one of the things that makes the perl core so hard to work on​: anything you want to change or improve will probably break someone's XS somewhere.

Anyway\, for now I've removed it from the public API with

  4c1069378194cb28b7554e5db5a450e0595b43f4

The thing about this is that we can always add it back to the API at a later date\, but not vice-versa.

-- Wesley Crusher gets beaten up by his classmates for being a smarmy git\, and consequently has a go at making some friends of his own age for a change.   -- Things That Never Happen in "Star Trek" #18

p5pRT commented 14 years ago

From @rurban

2010/3/11 Dave Mitchell \davem@&#8203;iabyn\.com​:

On Wed\, Mar 10\, 2010 at 09​:10​:04PM +0000\, Zefram wrote​:

You've added a new function\, Perl_gv_try_downgrade\, and its marked as being part of the public API. I can't see any reason why it needs to be.

The intention is that things other than the lexer might do similar kinds of speculative GV lookup\, and might thus want to do similar downgrading when deleting GV references. Ā I don't have anything that does this\, and it's not a critical capability\, but I saw no reason to restrict it to the core and some use in not so restricting it.

If we eventually find that we don't want this sort of downgrading\, or we tackle it in a completely different way\, gv_try_downgrade() can safely become a no-op. Ā It's not tying us to a way of working that might turn out to be inconvenient\, other than the existence of GVs\, which has been pretty inconvenient but is established by a lot more of the API than this function.

The trouble is that anything that's added to the public API immediately ties our hands. IMO there's already far too much stuff in the API\, and its one of the things that makes the perl core so hard to work on​: anything you want to change or improve will probably break someone's XS somewhere.

Anyway\, for now I've removed it from the public API with

Ā  Ā 4c1069378194cb28b7554e5db5a450e0595b43f4

The thing about this is that we can always add it back to the API at a later date\, but not vice-versa.

For what its worth​: There were more XS API breakages by *removing* some exports from the public API than breaking the API somehow.

It's just that porters mostly don't care about export-strict platforms\, as AIX\, cygwin\, MsWin32\, mingw\, which fail on missing exports\, whereas most other platforms just export all symbols regardless of the export list. Maybe delete an export only if you can test it on a platform which detects such a deletion..

From my experience​: 1 API breakage by removing op_seq and opt_op_seqmax for optimizer. 3 API deletions broke B​::Generate for those platforms. Perl_pad_alloc\, Perl_fold_constants\, Perl_cv_clone not exported. CPAN #28912

There were several more deletion issues which I forgot. As long as only windows and AIX is affected nobody cares. -- Reini Urban http​://phpwiki.org/ http​://murbreak.at/

p5pRT commented 14 years ago

From @nwc10

On Mon\, Mar 15\, 2010 at 07​:24​:52AM +0100\, Reini Urban wrote​:

For what its worth​: There were more XS API breakages by *removing* some exports from the public API than breaking the API somehow.

It's just that porters mostly don't care about export-strict platforms\, as AIX\, cygwin\, MsWin32\, mingw\, which fail on missing exports\, whereas most other platforms just export all symbols regardless of the export list. Maybe delete an export only if you can test it on a platform which detects such a deletion..

From my experience​: 1 API breakage by removing op_seq and opt_op_seqmax for optimizer. 3 API deletions broke B​::Generate for those platforms. Perl_pad_alloc\, Perl_fold_constants\, Perl_cv_clone not exported. CPAN #28912

There were several more deletion issues which I forgot. As long as only windows and AIX is affected nobody cares.

Until such functions are in the public API\, modules using them are buggy. That they happen to work on some platforms is unfortunate.

*I repeat*​:

Functions can be added to the public API if they have tests and documentation.

Patches welcome.

No-one cares to do *that* either.

Nicholas Clark

p5pRT commented 14 years ago

From @obra

It's just that porters mostly don't care about export-strict platforms\, as AIX\, cygwin\, MsWin32\, mingw\, which fail on missing exports\, whereas most other platforms just export all symbols regardless of the export list.

It's not that we don't care\, it's that most of us are much less experienced with those platforms _and_ they're harder to get access to / develop on for many of us. It's definitely a self-reinforcing problem.

I know that Curtis Jewell is doing some very nice stuff to make it easier for those of us who aren't well versed in Win32 to smoke locally. It's my hope that that will help catch these sort of issues faster and in a more...widely distributed fashion\, rather than leaning on much smaller set of porters who use Win32 as their primary platform.

p5pRT commented 14 years ago

From @tux

On Mon\, 15 Mar 2010 04​:42​:14 -0400\, jesse \jesse@&#8203;fsck\.com wrote​:

It's just that porters mostly don't care about export-strict platforms\, as AIX\, cygwin\, MsWin32\, mingw\, which fail on missing exports\, whereas most other platforms just export all symbols regardless of the export list.

It's not that we don't care\, it's that most of us are much less experienced with those platforms _and_ they're harder to get access to / develop on for many of us. It's definitely a self-reinforcing problem.

I know that Curtis Jewell is doing some very nice stuff to make it easier for those of us who aren't well versed in Win32 to smoke locally. It's my hope that that will help catch these sort of issues faster and in a more...widely distributed fashion\, rather than leaning on much smaller set of porters who use Win32 as their primary platform.

On 20 Oct 2008\, I wrote the attached mail\, which got NO response at all. The included code in that mail might be not very well portable\, but it might well do nicely as a base for some sort of API test\, which we currently do not have.

If I run that perl script again today on Linux-64bit with DEBUGGING\, I get the following list​:

Symbol perl_alloc_using not found in libperl.so Symbol perl_clone not found in libperl.so Symbol perl_clone_using not found in libperl.so Symbol Perl_my_chsize not found in libperl.so Symbol Perl_croak_nocontext not found in libperl.so Symbol Perl_die_nocontext not found in libperl.so Symbol Perl_deb_nocontext not found in libperl.so Symbol Perl_form_nocontext not found in libperl.so Symbol Perl_load_module_nocontext not found in libperl.so Symbol Perl_mess_nocontext not found in libperl.so Symbol Perl_warn_nocontext not found in libperl.so Symbol Perl_warner_nocontext not found in libperl.so Symbol Perl_newSVpvf_nocontext not found in libperl.so Symbol Perl_sv_catpvf_nocontext not found in libperl.so Symbol Perl_sv_setpvf_nocontext not found in libperl.so Symbol Perl_sv_catpvf_mg_nocontext not found in libperl.so Symbol Perl_sv_setpvf_mg_nocontext not found in libperl.so Symbol Perl_do_aspawn not found in libperl.so Symbol Perl_do_spawn not found in libperl.so Symbol Perl_do_spawn_nowait not found in libperl.so Symbol Perl_dump_fds not found in libperl.so Symbol Perl_my_bcopy not found in libperl.so Symbol Perl_my_bzero not found in libperl.so Symbol Perl_my_memcmp not found in libperl.so Symbol Perl_my_memset not found in libperl.so Symbol Perl_my_swap not found in libperl.so Symbol Perl_my_htonl not found in libperl.so Symbol Perl_my_ntohl not found in libperl.so Symbol Perl_newPADOP not found in libperl.so Symbol Perl_regdupe_internal not found in libperl.so Symbol Perl_unlnk not found in libperl.so Symbol Perl_dump_mstats not found in libperl.so Symbol Perl_get_mstats not found in libperl.so Symbol Perl_GetVars not found in libperl.so Symbol Perl_init_global_struct not found in libperl.so Symbol Perl_free_global_struct not found in libperl.so Symbol Perl_cx_dup not found in libperl.so Symbol Perl_si_dup not found in libperl.so Symbol Perl_ss_dup not found in libperl.so Symbol Perl_any_dup not found in libperl.so Symbol Perl_he_dup not found in libperl.so Symbol Perl_hek_dup not found in libperl.so Symbol Perl_re_dup_guts not found in libperl.so Symbol Perl_fp_dup not found in libperl.so Symbol Perl_dirp_dup not found in libperl.so Symbol Perl_gp_dup not found in libperl.so Symbol Perl_mg_dup not found in libperl.so Symbol Perl_sv_dup not found in libperl.so Symbol Perl_rvpv_dup not found in libperl.so Symbol Perl_parser_dup not found in libperl.so Symbol Perl_sys_intern_dup not found in libperl.so Symbol Perl_sys_intern_clear not found in libperl.so Symbol Perl_sys_intern_init not found in libperl.so Symbol Perl_Slab_Alloc not found in libperl.so Symbol Perl_Slab_Free not found in libperl.so Symbol Perl_sv_setsv_cow not found in libperl.so Symbol Perl_stashpv_hvname_match not found in libperl.so Symbol Perl_my_sprintf not found in libperl.so Symbol Perl_my_cxt_init not found in libperl.so Symbol Perl_my_cxt_index not found in libperl.so Symbol Perl_signbit not found in libperl.so

--8\<--- globals.pl #!/pro/bin/perl

qx{make global.sym};

my $nm; if (my @​lp = glob "libperl.*") {   $nm = $lp[0];   } else {   $nm = "perl";   } my %sym; open my $nl\, "-|"\, "nm $nm" or die "Cannot execute $nm​: $!\n"; while (\<$nl>) {   my ($sym) = (m/ [DT] (.*)/) or next;   ($sym) = (m/^\.?(\S+)/) if $sym =~ m/^[0-9]+$/; # AIX nm format   $sym{$1}++;   }

open my $gs\, "\<"\, "global.sym" or die "global.sym​: $!\n"; while (\<$gs>) {   m/^\s*#/ and next;   chomp;   exists $sym{$_} or print "Symbol $_ not found in $nm\n";   } -->8---

-- H.Merijn Brand http​://tux.nl Perl Monger http​://amsterdam.pm.org/ using & porting perl 5.6.2\, 5.8.x\, 5.10.x\, 5.11.x on HP-UX 10.20\, 11.00\, 11.11\, 11.23\, and 11.31\, OpenSuSE 10.3\, 11.0\, and 11.1\, AIX 5.2 and 5.3. http​://mirrors.develooper.com/hpux/ http​://www.test-smoke.org/ http​://qa.perl.org http​://www.goldmark.org/jeff/stupid-disclaimers/

p5pRT commented 14 years ago

From @tux

Message RFC822: MIME-Version: 1.0 X-Xs4all-Spam-Score: 0.0 () none List-Post: mailto:perl5-porters@perl.org X-Spam-Status: No, hits=0.0 required=8.0 tests= X-Mailer: Claws Mail 3.5.0cvs121 (GTK+ 2.12.0; x86_64-unknown-linux-gnu) Envelope-To: h.m.brand@xs4all.nl List-Help: mailto:perl5-porters-help@perl.org X-Xs4all-Spam: NO X-List-Archive: http://nntp.perl.org/group/perl.perl5.porters/140776 X-Virus-Checked: Checked X-Xs4all-DNSBL-Checked: mxdrop216.xs4all.nl checked 63.251.223.186 against DNS blacklists Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwEAIAAACI8LKTAAAACXBIWXMAAABIAAAASABGyWs+AAAC JElEQVRo3u2aMY4CMQxFczZ6RItEzRm4DBINDbRUSPRInIRbsNK6+dJfezN4kokn48IaCSjysL8d e9Knoj2fr9f9/gllqQ6U9/vxWK3EdwdIEGjRIVCu18NhuxUfK46SH81+fzrdbuKPx/P5ctHQdAdI TKAgpvV6s9ntBEfXEYSGgMQzIHnuFBBjkshCNJ2KtJZ04hHNAugP8bZr3NIHhbcF0AKoK0CoaHXU LUWBIs1n+jV+Fl8CVqOApEXAwyMO/DSR4XVntoAYDR7eBjQupuYAYTMph8Rj21D4m7MChN02tpqs NSnb/KqU2oHCXu5xDCgflj/RAgBiKBIXnICzAsSjWBsTz5K4/HeXYvb8yK5lY3VGEwPi2aONKT+5 AlcxrTPOwcTiraGRChgMEKJh0bVVifGVTq6qgBiNVl8QE29EsK6VE+YJAOG2wz5AvsqUS6uqgHCA n4NGvBYpnJ64Jgg27sCtxtBk1CJIA4S/GhdWKh07QxUB48jWGhZ4jKamRRr/T8/M0AaEyctry6YB 4dTGj9iWZNs3DahES5kPCJOu0RQbF/fQOBprsB9gaO9JtPDzII9U5ySXX7AnuIt91y54AAW7rPpT LCe5gt3F+CLqr2UarGB3MXvMylWGq4+9RCx3TW1oJq1t3HPQlFs6N1fFNEB4s8dn7Ne7ACSm7TPQ I5quAWmw6qBpulHM33B0Csge4Nd8JTTYG2b1XyRe3lH8x34ABJ6aePuQ2N4AAAAASUVORK5CYII= Message-ID: 20081020141630.50e2a92a@pc09.procura.nl Content-Type: text/plain; charset="utf-8" X-Virus-Scanned: by XS4ALL Virus Scanner X-RT-Original-Encoding: utf-8 Received: from lists.develooper.com (x6.develooper.com [63.251.223.186]) by mxdrop216.xs4all.nl (8.13.8/8.13.8) with SMTP id m9KCGpCc053046 for h.m.brand@xs4all.nl; Mon, 20 Oct 2008 14:16:54 +0200 (CEST) (envelope-from perl5-porters-return-140776-h.m.brand=xs4all.nl@perl.org) Received: (qmail 18875 invoked by uid 514); 20 Oct 2008 12:16:47 -0000 Received: (qmail 18863 invoked from network); 20 Oct 2008 12:16:47 -0000 Delivered-To: mailing list perl5-porters@perl.org Delivered-To: perl5-porters@perl.org Subject: Exported symbols: the perl API X-CNFS-Analysis: v=1.0 c=1 a=y5E4-Y8cAAAA:8 a=kMH87Q7bAAAA:8 a=xiKuzzWyAAAA:8 a=_IEhM8lNAAAA:8 a=qnD2cK_NAAAA:8 a=soeUKm9BJnQ_E9ObvqgA:9 a=_B0mzIMB8GEyr2rfugEA:7 a=97s7vhpIQ84qvKMX8RCHr4YSqSoA:4 a=RUW1g8P72R0A:10 a=8N6igchGCLUA:10 a=QLm6itZTqP8A:10 a=8Yd0Br3-97kA:10 Return-Path: perl5-porters-return-140776-h.m.brand=xs4all.nl@perl.org X-Spam-Check-BY: la.mx.develooper.com Date: Mon, 20 Oct 2008 14:16:30 +0200 Mailing-List: contact perl5-porters-help@perl.org; run by ezmlm Precedence: bulk To: Perl5 Porters perl5-porters@perl.org List-ID: List-Unsubscribe: mailto:perl5-porters-unsubscribe@perl.org Content-Transfer-Encoding: 7bit From: "H.Merijn Brand" h.m.brand@xs4all.nl Content-Length: 6002

embed.pl generates global.sym, which contains a list of all the functions that are documented to be in the perl API. There is currently however no test to check if all those are actually available, and it turns out that if you build with -Duseshrplib, many are indeed not available. Example:

$ grep signbit embed.fnc AMdnoP |int |Perl_signbit |NV f $ grep signbit global.sym Perl_signbit $ nm libperl.so | grep signbit Exit 1 $

and Perl_signbit is not explicitly skipped in makedef.pl - that is only used for aix win32 wince os2 MacOS netware - so I expect it to be in libperl.{so|sl|a|dll}

An (unportable) simple test case: --8<--- globals.pl

!/pro/bin/perl

qx{make global.sym};

my $nm; if (my @lp = glob "libperl.") { $nm = $lp[0]; } else { $nm = "perl"; } my %sym; open my $nl, "-|", "nm $nm" or die "Cannot execute $nm: $!\n"; while (<$nl>) { m/ [DT] (.)/ and $sym{$1}++; }

open my $gs, "<", "global.sym" or die "global.sym: $!\n"; while (<$gs>) { m/^\s*#/ and next; chomp; exists $sym{$} or print "Symbol $ not found in $nm\n"; } -->8---

showed me a complete list on Linux and AIX:

Linux $ /pro/bin/perl global.pl Symbol perl_alloc_using not found in libperl.so Symbol perl_clone not found in libperl.so Symbol perl_clone_using not found in libperl.so Symbol Perl_my_chsize not found in libperl.so Symbol Perl_croak_nocontext not found in libperl.so Symbol Perl_die_nocontext not found in libperl.so Symbol Perl_deb_nocontext not found in libperl.so Symbol Perl_form_nocontext not found in libperl.so Symbol Perl_load_module_nocontext not found in libperl.so Symbol Perl_mess_nocontext not found in libperl.so Symbol Perl_warn_nocontext not found in libperl.so Symbol Perl_warner_nocontext not found in libperl.so Symbol Perl_newSVpvf_nocontext not found in libperl.so Symbol Perl_sv_catpvf_nocontext not found in libperl.so Symbol Perl_sv_setpvf_nocontext not found in libperl.so Symbol Perl_sv_catpvf_mg_nocontext not found in libperl.so Symbol Perl_sv_setpvf_mg_nocontext not found in libperl.so Symbol Perl_do_aspawn not found in libperl.so Symbol Perl_do_spawn not found in libperl.so Symbol Perl_do_spawn_nowait not found in libperl.so Symbol Perl_dump_fds not found in libperl.so Symbol Perl_my_bcopy not found in libperl.so Symbol Perl_my_bzero not found in libperl.so Symbol Perl_my_memcmp not found in libperl.so Symbol Perl_my_memset not found in libperl.so Symbol Perl_my_swap not found in libperl.so Symbol Perl_my_htonl not found in libperl.so Symbol Perl_my_ntohl not found in libperl.so Symbol Perl_newPADOP not found in libperl.so Symbol Perl_regdupe_internal not found in libperl.so Symbol Perl_unlnk not found in libperl.so Symbol Perl_dump_mstats not found in libperl.so Symbol Perl_get_mstats not found in libperl.so Symbol Perl_GetVars not found in libperl.so Symbol Perl_init_global_struct not found in libperl.so Symbol Perl_free_global_struct not found in libperl.so Symbol Perl_cx_dup not found in libperl.so Symbol Perl_si_dup not found in libperl.so Symbol Perl_ss_dup not found in libperl.so Symbol Perl_any_dup not found in libperl.so Symbol Perl_he_dup not found in libperl.so Symbol Perl_hek_dup not found in libperl.so Symbol Perl_re_dup_guts not found in libperl.so Symbol Perl_fp_dup not found in libperl.so Symbol Perl_dirp_dup not found in libperl.so Symbol Perl_gp_dup not found in libperl.so Symbol Perl_mg_dup not found in libperl.so Symbol Perl_sv_dup not found in libperl.so Symbol Perl_rvpv_dup not found in libperl.so Symbol Perl_parser_dup not found in libperl.so Symbol Perl_sys_intern_dup not found in libperl.so Symbol Perl_sys_intern_clear not found in libperl.so Symbol Perl_sys_intern_init not found in libperl.so Symbol Perl_Slab_Alloc not found in libperl.so Symbol Perl_Slab_Free not found in libperl.so Symbol Perl_sv_setsv_cow not found in libperl.so Symbol Perl_stashpv_hvname_match not found in libperl.so Symbol Perl_my_sprintf not found in libperl.so Symbol Perl_my_cxt_init not found in libperl.so Symbol Perl_my_cxt_index not found in libperl.so Symbol Perl_signbit not found in libperl.so Linux $

And on AIX:

$ /pro/bin/perl /tmp/global.pl Symbol perl_alloc_using not found in libperl.a Symbol perl_clone_using not found in libperl.a Symbol Perl_my_chsize not found in libperl.a Symbol Perl_do_aspawn not found in libperl.a Symbol Perl_do_spawn not found in libperl.a Symbol Perl_do_spawn_nowait not found in libperl.a Symbol Perl_dump_fds not found in libperl.a Symbol Perl_my_bcopy not found in libperl.a Symbol Perl_my_bzero not found in libperl.a Symbol Perl_my_memcmp not found in libperl.a Symbol Perl_my_memset not found in libperl.a Symbol Perl_my_swap not found in libperl.a Symbol Perl_my_htonl not found in libperl.a Symbol Perl_my_ntohl not found in libperl.a Symbol Perl_unlnk not found in libperl.a Symbol Perl_dump_mstats not found in libperl.a Symbol Perl_get_mstats not found in libperl.a Symbol Perl_GetVars not found in libperl.a Symbol Perl_init_global_struct not found in libperl.a Symbol Perl_free_global_struct not found in libperl.a Symbol Perl_sys_intern_dup not found in libperl.a Symbol Perl_sys_intern_clear not found in libperl.a Symbol Perl_sys_intern_init not found in libperl.a Symbol Perl_Slab_Alloc not found in libperl.a Symbol Perl_Slab_Free not found in libperl.a Symbol Perl_sv_setsv_cow not found in libperl.a Symbol Perl_my_sprintf not found in libperl.a Symbol Perl_my_cxt_index not found in libperl.a Symbol Perl_signbit not found in libperl.a $

Note that the list on AIX is actually shorter

BTW I'm extremely interested in a way to portably do this on win32

-- H.Merijn Brand Amsterdam Perl Mongers http://amsterdam.pm.org/ using & porting perl 5.6.2, 5.8.x, 5.10.x, 5.11.x on HP-UX 10.20, 11.00, 11.11, 11.23, and 11.31, SuSE 10.1, 10.2, and 10.3, AIX 5.2, and Cygwin. http://mirrors.develooper.com/hpux/ http://www.test-smoke.org/ http://qa.perl.org http://www.goldmark.org/jeff/stupid-disclaimers/

p5pRT commented 14 years ago

From @tux

embed.pl generates global.sym\, which contains a list of all the functions that are documented to be in the perl API. There is currently however no test to check if all those are actually available\, and it turns out that if you build with -Duseshrplib\, many are indeed not available. Example​:

$ grep signbit embed.fnc AMdnoP |int |Perl_signbit |NV f $ grep signbit global.sym Perl_signbit $ nm libperl.so | grep signbit Exit 1 $

and Perl_signbit is not explicitly skipped in makedef.pl - that is only used for aix win32 wince os2 MacOS netware - so I expect it to be in libperl.{so|sl|a|dll}

An (unportable) simple test case​: --8\<--- globals.pl #!/pro/bin/perl

qx{make global.sym};

my $nm; if (my @​lp = glob "libperl.*") {   $nm = $lp[0];   } else {   $nm = "perl";   } my %sym; open my $nl\, "-|"\, "nm $nm" or die "Cannot execute $nm​: $!\n"; while (\<$nl>) {   m/ [DT] (.*)/ and $sym{$1}++;   }

open my $gs\, "\<"\, "global.sym" or die "global.sym​: $!\n"; while (\<$gs>) {   m/^\s*#/ and next;   chomp;   exists $sym{$_} or print "Symbol $_ not found in $nm\n";   } -->8---

showed me a complete list on Linux and AIX​:

Linux $ /pro/bin/perl global.pl Symbol perl_alloc_using not found in libperl.so Symbol perl_clone not found in libperl.so Symbol perl_clone_using not found in libperl.so Symbol Perl_my_chsize not found in libperl.so Symbol Perl_croak_nocontext not found in libperl.so Symbol Perl_die_nocontext not found in libperl.so Symbol Perl_deb_nocontext not found in libperl.so Symbol Perl_form_nocontext not found in libperl.so Symbol Perl_load_module_nocontext not found in libperl.so Symbol Perl_mess_nocontext not found in libperl.so Symbol Perl_warn_nocontext not found in libperl.so Symbol Perl_warner_nocontext not found in libperl.so Symbol Perl_newSVpvf_nocontext not found in libperl.so Symbol Perl_sv_catpvf_nocontext not found in libperl.so Symbol Perl_sv_setpvf_nocontext not found in libperl.so Symbol Perl_sv_catpvf_mg_nocontext not found in libperl.so Symbol Perl_sv_setpvf_mg_nocontext not found in libperl.so Symbol Perl_do_aspawn not found in libperl.so Symbol Perl_do_spawn not found in libperl.so Symbol Perl_do_spawn_nowait not found in libperl.so Symbol Perl_dump_fds not found in libperl.so Symbol Perl_my_bcopy not found in libperl.so Symbol Perl_my_bzero not found in libperl.so Symbol Perl_my_memcmp not found in libperl.so Symbol Perl_my_memset not found in libperl.so Symbol Perl_my_swap not found in libperl.so Symbol Perl_my_htonl not found in libperl.so Symbol Perl_my_ntohl not found in libperl.so Symbol Perl_newPADOP not found in libperl.so Symbol Perl_regdupe_internal not found in libperl.so Symbol Perl_unlnk not found in libperl.so Symbol Perl_dump_mstats not found in libperl.so Symbol Perl_get_mstats not found in libperl.so Symbol Perl_GetVars not found in libperl.so Symbol Perl_init_global_struct not found in libperl.so Symbol Perl_free_global_struct not found in libperl.so Symbol Perl_cx_dup not found in libperl.so Symbol Perl_si_dup not found in libperl.so Symbol Perl_ss_dup not found in libperl.so Symbol Perl_any_dup not found in libperl.so Symbol Perl_he_dup not found in libperl.so Symbol Perl_hek_dup not found in libperl.so Symbol Perl_re_dup_guts not found in libperl.so Symbol Perl_fp_dup not found in libperl.so Symbol Perl_dirp_dup not found in libperl.so Symbol Perl_gp_dup not found in libperl.so Symbol Perl_mg_dup not found in libperl.so Symbol Perl_sv_dup not found in libperl.so Symbol Perl_rvpv_dup not found in libperl.so Symbol Perl_parser_dup not found in libperl.so Symbol Perl_sys_intern_dup not found in libperl.so Symbol Perl_sys_intern_clear not found in libperl.so Symbol Perl_sys_intern_init not found in libperl.so Symbol Perl_Slab_Alloc not found in libperl.so Symbol Perl_Slab_Free not found in libperl.so Symbol Perl_sv_setsv_cow not found in libperl.so Symbol Perl_stashpv_hvname_match not found in libperl.so Symbol Perl_my_sprintf not found in libperl.so Symbol Perl_my_cxt_init not found in libperl.so Symbol Perl_my_cxt_index not found in libperl.so Symbol Perl_signbit not found in libperl.so Linux $

And on AIX​:

$ /pro/bin/perl /tmp/global.pl Symbol perl_alloc_using not found in libperl.a Symbol perl_clone_using not found in libperl.a Symbol Perl_my_chsize not found in libperl.a Symbol Perl_do_aspawn not found in libperl.a Symbol Perl_do_spawn not found in libperl.a Symbol Perl_do_spawn_nowait not found in libperl.a Symbol Perl_dump_fds not found in libperl.a Symbol Perl_my_bcopy not found in libperl.a Symbol Perl_my_bzero not found in libperl.a Symbol Perl_my_memcmp not found in libperl.a Symbol Perl_my_memset not found in libperl.a Symbol Perl_my_swap not found in libperl.a Symbol Perl_my_htonl not found in libperl.a Symbol Perl_my_ntohl not found in libperl.a Symbol Perl_unlnk not found in libperl.a Symbol Perl_dump_mstats not found in libperl.a Symbol Perl_get_mstats not found in libperl.a Symbol Perl_GetVars not found in libperl.a Symbol Perl_init_global_struct not found in libperl.a Symbol Perl_free_global_struct not found in libperl.a Symbol Perl_sys_intern_dup not found in libperl.a Symbol Perl_sys_intern_clear not found in libperl.a Symbol Perl_sys_intern_init not found in libperl.a Symbol Perl_Slab_Alloc not found in libperl.a Symbol Perl_Slab_Free not found in libperl.a Symbol Perl_sv_setsv_cow not found in libperl.a Symbol Perl_my_sprintf not found in libperl.a Symbol Perl_my_cxt_index not found in libperl.a Symbol Perl_signbit not found in libperl.a $

Note that the list on AIX is actually shorter

BTW I'm extremely interested in a way to portably do this on win32

-- H.Merijn Brand Amsterdam Perl Mongers http​://amsterdam.pm.org/ using & porting perl 5.6.2\, 5.8.x\, 5.10.x\, 5.11.x on HP-UX 10.20\, 11.00\, 11.11\, 11.23\, and 11.31\, SuSE 10.1\, 10.2\, and 10.3\, AIX 5.2\, and Cygwin. http​://mirrors.develooper.com/hpux/ http​://www.test-smoke.org/ http​://qa.perl.org http​://www.goldmark.org/jeff/stupid-disclaimers/

p5pRT commented 14 years ago

From @rurban

2010/3/15 Nicholas Clark \nick@&#8203;ccl4\.org​:

On Mon\, Mar 15\, 2010 at 07​:24​:52AM +0100\, Reini Urban wrote​:

For what its worth​: There were more XS API breakages by *removing* some exports from the public API than breaking the API somehow.

It's just that porters mostly don't care about export-strict platforms\, as AIX\, cygwin\, MsWin32\, mingw\, which fail on missing exports\, whereas most other platforms just export all symbols regardless of the export list. Maybe delete an export only if you can test it on a platform which detects such a deletion..

From my experience​: 1 API breakage by removing op_seq and opt_op_seqmax for optimizer. 3 API deletions broke B​::Generate for those platforms. Perl_pad_alloc\, Perl_fold_constants\, Perl_cv_clone not exported. CPAN #28912

There were several more deletion issues which I forgot. As long as only windows and AIX is affected nobody cares.

Until such functions are in the public API\, modules using them are buggy. That they happen to work on some platforms is unfortunate.

Thing is that at the time B​::Generate was written those functions were public\, until you made them non-public and B​::Generate stopped working on win32/cygwin/AIX.

This happened with a lot of B modules. I had time to take care for some\, but not all. Not taking care about B modules means not taking care about future perl5 optimizations.

*I repeat*​:

Functions can be added to the public API if they have tests and documentation.

Patches welcome.

No-one cares to do *that* either.

I'm with Marc Lehman here. I really have not enough time fix such core issues. I didn't remove the A flag and I'm not familiar enough with those functions.

I rather fixed the module to leave out certain features the original authors had indented. -- Reini Urban http​://phpwiki.org/ http​://murbreak.at/

p5pRT commented 14 years ago

From @nwc10

On Tue\, Mar 16\, 2010 at 09​:39​:28AM +0100\, Reini Urban wrote​:

2010/3/15 Nicholas Clark \nick@&#8203;ccl4\.org​:

Thing is that at the time B​::Generate was written those functions were public\, until you made them non-public and B​::Generate stopped working on win32/cygwin/AIX.

They have never been public. This is 5.6.0​:

http​://perl5.git.perl.org/perl.git/blob/perl-5.6.0​:/embed.pl

1421 p |CV* |cv_clone |CV* proto 1508 p |OP* |fold_constants |OP* arg 1792 p |PADOFFSET|pad_alloc |I32 optype|U32 tmptype

This happened with a lot of B modules. I had time to take care for some\, but not all. Not taking care about B modules means not taking care about future perl5 optimizations.

My experience is that it's *very* hard to make op-level changes that have any significant speed up on perl generally. I don't agree with the *generalisation* implied by your statement.

*I repeat*​:

Functions can be added to the public API if they have tests and documentation.

Patches welcome.

No-one cares to do *that* either.

I'm with Marc Lehman here. I really have not enough time fix such core issues. I didn't remove the A flag and I'm not familiar enough with those functions.

I rather fixed the module to leave out certain features the original authors had indented.

No-one removed the A flag. They were never public. They were never exported. The original author *wrote* a broken module.

You're a volunteer too - there's no obligation for you (or anyone else) to fix this.

But as no-one *is* volunteering\, it's not going to change.

Nicholas Clark