Skip to content

Commit

Permalink
Import from builtin version bundles should be idempotent on existin…
Browse files Browse the repository at this point in the history
…g symbols
  • Loading branch information
leonerd committed Jan 23, 2024
1 parent 8e21936 commit 39cdd68
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
33 changes: 29 additions & 4 deletions builtin.c
Original file line number Diff line number Diff line change
Expand Up @@ -596,12 +596,37 @@ static void S_import_sym(pTHX_ SV *sym)
export_lexical(ampname, (SV *)cv);
}

#define import_builtin_bundle(ver) S_import_builtin_bundle(aTHX_ ver)
static void S_import_builtin_bundle(pTHX_ U16 ver)
#define cv_is_builtin(cv) S_cv_is_builtin(aTHX_ cv)
static bool S_cv_is_builtin(pTHX_ CV *cv)
{
char *file = CvFILE(cv);
return file && strEQ(file, __FILE__);
}

#define import_builtin_bundle(ver, do_unimport) S_import_builtin_bundle(aTHX_ ver, do_unimport)
static void S_import_builtin_bundle(pTHX_ U16 ver, bool do_unimport)
{
SV *ampname = sv_newmortal();

for(int i = 0; builtins[i].name; i++) {
if(builtins[i].since_ver <= ver)
sv_setpvf(ampname, "&%s", builtins[i].name);

bool want = (builtins[i].since_ver <= ver);

bool got = false;
PADOFFSET off = pad_findmy_sv(ampname, 0);
CV *cv;
if(off != NOT_IN_PAD &&
SvTYPE((cv = (CV *)PL_curpad[off])) == SVt_PVCV &&
cv_is_builtin(cv))
got = true;

if(!got && want) {
import_sym(newSVpvn_flags(builtins[i].name, strlen(builtins[i].name), SVs_TEMP));
}
else if(do_unimport && got && !want) {
pad_add_name_sv(ampname, padadd_STATE|padadd_TOMBSTONE, 0, 0);
}
}
}

Expand Down Expand Up @@ -636,7 +661,7 @@ XS(XS_builtin_import)
Perl_croak(aTHX_ "Builtin version bundle \"%s\" is not supported by Perl " PERL_VERSION_STRING,
sympv);

import_builtin_bundle(want_ver);
import_builtin_bundle(want_ver, false);

continue;
}
Expand Down
6 changes: 6 additions & 0 deletions t/lib/warnings/builtin
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,9 @@ indexed 1..3;
EXPECT
Useless use of builtin::indexed in scalar context at - line 6.
Useless use of builtin::indexed in void context at - line 7.
########
# builtin.c - import from bundles is idempotent
use builtin qw(true false);
use builtin ':5.39';
use builtin ':5.39';
EXPECT

0 comments on commit 39cdd68

Please sign in to comment.