perl5 icon indicating copy to clipboard operation
perl5 copied to clipboard

Builtin stringify - Undefined subroutine &main::stringify called

Open happy-barney opened this issue 1 year ago • 7 comments

Description When using forward coderef to imported builtin current blead (sha: af9733f1e2) doesn't assign ref properly, though it does it when builtin is not used or when ref is evaluated after builtin.

Steps to Reproduce

my $coderef = \&stringify;
use builtin q (stringify);

CORE::say $coderef->({});

Hint: address of function changes:

my $coderef = \ &stringify;
use builtin q (stringify);
sub stringify ($) { q (foo) }

CORE::say q ([1] ), $coderef;
CORE::say q ([2] ), \ &stringify;

Result:

[1] CODE(0x5576ca60b648)
[2] CODE(0x5576ca639dc0)

Expected behavior When given coderef already exists in namespace import builtin so that it doesn't change symbol's refaddr.

Perl configuration

$ git log -1 --oneline
af9733f1e2 (HEAD -> blead, upstream/blead, upstream/HEAD) builtin.c: Remember to EXTEND() before using XSRETURN_{YES,NO}

$ ./perl -I lib -V
Summary of my perl5 (revision 5 version 39 subversion 8) configuration:
  Commit id: af9733f1e2152339a4db682937e7c6c6ee95b5fb
  Platform:
    osname=linux
    osvers=5.15.0-92-generic
    archname=x86_64-linux
    uname='linux happy-barney 5.15.0-92-generic #102-ubuntu smp wed jan 10 09:33:48 utc 2024 x86_64 x86_64 x86_64 gnulinux '
    config_args='-des -Dusedevel -DDEBUGGING'
    hint=previous
    useposix=true
    d_sigaction=define
    useithreads=undef
    usemultiplicity=undef
    use64bitint=define
    use64bitall=define
    uselongdouble=undef
    usemymalloc=n
    default_inc_excludes_dot=define
  Compiler:
    cc='cc'
    ccflags ='-fwrapv -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
    optimize='-O2 -g'
    cppflags='-fwrapv -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include'
    ccversion=''
    gccversion='11.4.0'
    gccosandvers=''
    intsize=4
    longsize=8
    ptrsize=8
    doublesize=8
    byteorder=12345678
    doublekind=3
    d_longlong=define
    longlongsize=8
    d_longdbl=define
    longdblsize=16
    longdblkind=3
    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-strong -L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib/x86_64-linux-gnu /usr/lib /usr/lib64
    libs=-lpthread -ldb -ldl -lm -lcrypt -lutil -lc
    perllibs=-lpthread -ldl -lm -lcrypt -lutil -lc
    libc=/lib/x86_64-linux-gnu/libc.so.6
    so=so
    useshrplib=false
    libperl=libperl.a
    gnulibc_version='2.35'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs
    dlext=so
    d_dlsymun=undef
    ccdlflags='-Wl,-E'
    cccdlflags='-fPIC'
    lddlflags='-shared -O2 -g -L/usr/local/lib -fstack-protector-strong'


Characteristics of this binary (from libperl): 
  Compile-time options:
    DEBUGGING
    HAS_LONG_DOUBLE
    HAS_STRTOLD
    HAS_TIMES
    PERLIO_LAYERS
    PERL_COPY_ON_WRITE
    PERL_DONT_CREATE_GVSV
    PERL_HASH_FUNC_SIPHASH13
    PERL_HASH_USE_SBOX32
    PERL_MALLOC_WRAP
    PERL_OP_PARENT
    PERL_PRESERVE_IVUV
    PERL_USE_DEVEL
    PERL_USE_SAFE_PUTENV
    USE_64_BIT_ALL
    USE_64_BIT_INT
    USE_LARGE_FILES
    USE_LOCALE
    USE_LOCALE_COLLATE
    USE_LOCALE_CTYPE
    USE_LOCALE_NUMERIC
    USE_LOCALE_TIME
    USE_PERLIO
    USE_PERL_ATOF
  Built under linux
  Compiled at Jan 27 2024 21:20:48
  %ENV:
    PERL5LIB="/home/brano/lib/perl5/:/home/brano/lib/perl5/:/home/brano/lib/perl5/"
    PERLBREW_HOME="/home/brano/.perlbrew"
    PERLBREW_PATH="/home/brano/.cache/perlbrew/bin"
    PERLBREW_ROOT="/home/brano/.cache/perlbrew"
    PERLBREW_SHELLRC_VERSION="0.86"
    PERLBREW_VERSION="0.94"
  @INC:
    lib
    /home/brano/lib/perl5/
    /home/brano/lib/perl5/
    /home/brano/lib/perl5/
    /home/brano/.cache/perlbrew/perls/latest_blead/lib/site_perl/5.39.8/x86_64-linux
    /home/brano/.cache/perlbrew/perls/latest_blead/lib/site_perl/5.39.8
    /home/brano/.cache/perlbrew/perls/latest_blead/lib/5.39.8/x86_64-linux
    /home/brano/.cache/perlbrew/perls/latest_blead/lib/5.39.8

happy-barney avatar Jan 27 '24 20:01 happy-barney

I can confirm that when, in blead, I run the program in @happy-barney's 2nd code block above, I get the results he displayed in his 3rd code block. I can also confirm that when I built at 7c60f1f796a4c23bbfc43b25f2e159ffea14300b -- the commit whose message indicates that it was the place where builtin::stringify was implemented on Sep 8 2023 -- that I get similar results.

I don't know enough about builtin to comment further.

jkeenan avatar Jan 27 '24 22:01 jkeenan

This isn't really a builtin thing, but a lexical subs thing. In fact, it's just a general lexical thing, with subs only being different because you are allowed to bind to them without declaring them even under strict.

use strict;
use warnings;

my $coderef = \&code;
my sub code { 1 }

print q(code:), "\n";
print q([1] ), $coderef, "\n";
print q([2] ), \&code, "\n";


no strict 'vars';
no warnings 'once';
my $scalarref = \$scalar;
my $scalar = 1;

print q(scalar:), "\n";
print q([1] ), $scalarref, "\n";
print q([2] ), \$scalar, "\n";

__END__
code:
[1] CODE(0x13f80ae10)
[2] CODE(0x13f824500)
scalar:
[1] SCALAR(0x13f865b80)
[2] SCALAR(0x13f824578)

haarg avatar Jan 27 '24 23:01 haarg

Perhaps builtin::import could check if the sub already has a definition in the calling package/pad.

tonycoz avatar Jan 31 '24 03:01 tonycoz

As far as it looks like that root caused directly by builtin::import I'd suggest to experiment with source code finding combinations where behaviour is "very different from expected" or inconsistent between different versions and different entity types (eg variables vs functions) and fix (aka well define) it.

happy-barney avatar Jan 31 '24 05:01 happy-barney

This seems to me to be acting as expected.

haarg avatar Jan 31 '24 09:01 haarg

It behaves how I expect.

It would be good if we could warn here, but I'm not sure how practical it is.

tonycoz avatar Jan 31 '24 22:01 tonycoz

Furthermore, while the odd use of the \&stringify coderef from before either sub was created does not yield a warning, with the new warning code added by my #21915 it now warns in either order of sub creation, so at least you'd be aware that something strange is afoot:

$ ./perl -Ilib -Mwarnings -e 'use builtin q(stringify); sub stringify($) {}'
Subroutine stringify redefined at -e line 1.

$ ./perl -Ilib -Mwarnings -e 'sub stringify($) {} use builtin q(stringify)'
Lexical subroutine &stringify masks previously declared package subroutine at -e line 1.

It would be good if we could warn here, but I'm not sure how practical it is.

@tonycoz this is now what #21915 does

leonerd avatar Jan 31 '24 23:01 leonerd

Closing as not-a-bug

leonerd avatar Mar 14 '24 17:03 leonerd