Skip to content

Commit ae2cf9f

Browse files
committed
Add new API function sv_rvunweaken
Needed to fix in-place sort of weak references in a future commit. Stolen from Scalar::Util::unweaken, which will be made to use this when available via CPAN upstream.
1 parent 5609e95 commit ae2cf9f

File tree

5 files changed

+53
-1
lines changed

5 files changed

+53
-1
lines changed

embed.fnc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1980,6 +1980,7 @@ Apdmb |void |sv_force_normal|NN SV *sv
19801980
Apd |void |sv_force_normal_flags|NN SV *const sv|const U32 flags
19811981
pX |SSize_t|tmps_grow_p |SSize_t ix
19821982
Apd |SV* |sv_rvweaken |NN SV *const sv
1983+
Apd |SV* |sv_rvunweaken |NN SV *const sv
19831984
AnpMd |SV* |sv_get_backrefs|NN SV *const sv
19841985
: This is indirectly referenced by globals.c. This is somewhat annoying.
19851986
p |int |magic_killbackrefs|NN SV *sv|NN MAGIC *mg

embed.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,7 @@
663663
#define sv_replace(a,b) Perl_sv_replace(aTHX_ a,b)
664664
#define sv_report_used() Perl_sv_report_used(aTHX)
665665
#define sv_reset(a,b) Perl_sv_reset(aTHX_ a,b)
666+
#define sv_rvunweaken(a) Perl_sv_rvunweaken(aTHX_ a)
666667
#define sv_rvweaken(a) Perl_sv_rvweaken(aTHX_ a)
667668
#define sv_set_undef(a) Perl_sv_set_undef(aTHX_ a)
668669
#define sv_setiv(a,b) Perl_sv_setiv(aTHX_ a,b)

pod/perldiag.pod

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1524,6 +1524,11 @@ expression pattern. Trying to do this in ordinary Perl code produces a
15241524
value that prints out looking like SCALAR(0xdecaf). Use the $1 form
15251525
instead.
15261526

1527+
=item Can't unweaken a nonreference
1528+
1529+
(F) You attempted to unweaken something that was not a reference. Only
1530+
references can be unweakened.
1531+
15271532
=item Can't weaken a nonreference
15281533

15291534
(F) You attempted to weaken something that was not a reference. Only
@@ -5204,6 +5209,11 @@ to use parens. In any case, a hash requires key/value B<pairs>.
52045209
(W misc) You have attempted to weaken a reference that is already weak.
52055210
Doing so has no effect.
52065211

5212+
=item Reference is not weak
5213+
5214+
(W misc) You have attempted to unweaken a reference that is not weak.
5215+
Doing so has no effect.
5216+
52075217
=item Reference to invalid group 0 in regex; marked by S<<-- HERE> in m/%s/
52085218

52095219
(F) You used C<\g0> or similar in a regular expression. You may refer

proto.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3297,6 +3297,9 @@ PERL_CALLCONV void Perl_sv_reset(pTHX_ const char* s, HV *const stash);
32973297
#define PERL_ARGS_ASSERT_SV_RESET \
32983298
assert(s)
32993299
PERL_CALLCONV void Perl_sv_resetpvn(pTHX_ const char* s, STRLEN len, HV *const stash);
3300+
PERL_CALLCONV SV* Perl_sv_rvunweaken(pTHX_ SV *const sv);
3301+
#define PERL_ARGS_ASSERT_SV_RVUNWEAKEN \
3302+
assert(sv)
33003303
PERL_CALLCONV SV* Perl_sv_rvweaken(pTHX_ SV *const sv);
33013304
#define PERL_ARGS_ASSERT_SV_RVWEAKEN \
33023305
assert(sv)

sv.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5961,7 +5961,8 @@ Weaken a reference: set the C<SvWEAKREF> flag on this RV; give the
59615961
referred-to SV C<PERL_MAGIC_backref> magic if it hasn't already; and
59625962
push a back-reference to this RV onto the array of backreferences
59635963
associated with that magic. If the RV is magical, set magic will be
5964-
called after the RV is cleared.
5964+
called after the RV is cleared. Silently ignores C<undef> and warns
5965+
on already-weak references.
59655966
59665967
=cut
59675968
*/
@@ -5989,6 +5990,42 @@ Perl_sv_rvweaken(pTHX_ SV *const sv)
59895990
return sv;
59905991
}
59915992

5993+
/*
5994+
=for apidoc sv_rvunweaken
5995+
5996+
Unweaken a reference: Clear the C<SvWEAKREF> flag on this RV; remove
5997+
the backreference to this RV from the array of backreferences
5998+
associated with the target SV, increment the refcount of the target.
5999+
Silently ignores C<undef> and warns on non-weak references.
6000+
6001+
=cut
6002+
*/
6003+
6004+
SV *
6005+
Perl_sv_rvunweaken(pTHX_ SV *const sv)
6006+
{
6007+
SV *tsv;
6008+
6009+
PERL_ARGS_ASSERT_SV_RVUNWEAKEN;
6010+
6011+
if (!SvOK(sv)) /* let undefs pass */
6012+
return sv;
6013+
if (!SvROK(sv))
6014+
Perl_croak(aTHX_ "Can't unweaken a nonreference");
6015+
else if (!SvWEAKREF(sv)) {
6016+
Perl_ck_warner(aTHX_ packWARN(WARN_MISC), "Reference is not weak");
6017+
return sv;
6018+
}
6019+
else if (SvREADONLY(sv)) croak_no_modify();
6020+
6021+
tsv = SvRV(sv);
6022+
SvWEAKREF_off(sv);
6023+
SvROK_on(sv);
6024+
SvREFCNT_inc_NN(tsv);
6025+
Perl_sv_del_backref(aTHX_ tsv, sv);
6026+
return sv;
6027+
}
6028+
59926029
/*
59936030
=for apidoc sv_get_backrefs
59946031

0 commit comments

Comments
 (0)