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.
Apd |void |sv_force_normal_flags|NN SV *const sv|const U32 flags
pX |SSize_t|tmps_grow_p |SSize_t ix
Apd |SV* |sv_rvweaken |NN SV *const sv
+Apd |SV* |sv_rvunweaken |NN SV *const sv
AnpMd |SV* |sv_get_backrefs|NN SV *const sv
: This is indirectly referenced by globals.c. This is somewhat annoying.
p |int |magic_killbackrefs|NN SV *sv|NN MAGIC *mg
#define sv_replace(a,b) Perl_sv_replace(aTHX_ a,b)
#define sv_report_used() Perl_sv_report_used(aTHX)
#define sv_reset(a,b) Perl_sv_reset(aTHX_ a,b)
+#define sv_rvunweaken(a) Perl_sv_rvunweaken(aTHX_ a)
#define sv_rvweaken(a) Perl_sv_rvweaken(aTHX_ a)
#define sv_set_undef(a) Perl_sv_set_undef(aTHX_ a)
#define sv_setiv(a,b) Perl_sv_setiv(aTHX_ a,b)
value that prints out looking like SCALAR(0xdecaf). Use the $1 form
instead.
+=item Can't unweaken a nonreference
+
+(F) You attempted to unweaken something that was not a reference. Only
+references can be unweakened.
+
=item Can't weaken a nonreference
(F) You attempted to weaken something that was not a reference. Only
(W misc) You have attempted to weaken a reference that is already weak.
Doing so has no effect.
+=item Reference is not weak
+
+(W misc) You have attempted to unweaken a reference that is not weak.
+Doing so has no effect.
+
=item Reference to invalid group 0 in regex; marked by S<<-- HERE> in m/%s/
(F) You used C<\g0> or similar in a regular expression. You may refer
#define PERL_ARGS_ASSERT_SV_RESET \
assert(s)
PERL_CALLCONV void Perl_sv_resetpvn(pTHX_ const char* s, STRLEN len, HV *const stash);
+PERL_CALLCONV SV* Perl_sv_rvunweaken(pTHX_ SV *const sv);
+#define PERL_ARGS_ASSERT_SV_RVUNWEAKEN \
+ assert(sv)
PERL_CALLCONV SV* Perl_sv_rvweaken(pTHX_ SV *const sv);
#define PERL_ARGS_ASSERT_SV_RVWEAKEN \
assert(sv)
referred-to SV C<PERL_MAGIC_backref> magic if it hasn't already; and
push a back-reference to this RV onto the array of backreferences
associated with that magic. If the RV is magical, set magic will be
-called after the RV is cleared.
+called after the RV is cleared. Silently ignores C<undef> and warns
+on already-weak references.
=cut
*/
}
/*
+=for apidoc sv_rvunweaken
+
+Unweaken a reference: Clear the C<SvWEAKREF> flag on this RV; remove
+the backreference to this RV from the array of backreferences
+associated with the target SV, increment the refcount of the target.
+Silently ignores C<undef> and warns on non-weak references.
+
+=cut
+*/
+
+SV *
+Perl_sv_rvunweaken(pTHX_ SV *const sv)
+{
+ SV *tsv;
+
+ PERL_ARGS_ASSERT_SV_RVUNWEAKEN;
+
+ if (!SvOK(sv)) /* let undefs pass */
+ return sv;
+ if (!SvROK(sv))
+ Perl_croak(aTHX_ "Can't unweaken a nonreference");
+ else if (!SvWEAKREF(sv)) {
+ Perl_ck_warner(aTHX_ packWARN(WARN_MISC), "Reference is not weak");
+ return sv;
+ }
+ else if (SvREADONLY(sv)) croak_no_modify();
+
+ tsv = SvRV(sv);
+ SvWEAKREF_off(sv);
+ SvROK_on(sv);
+ SvREFCNT_inc_NN(tsv);
+ Perl_sv_del_backref(aTHX_ tsv, sv);
+ return sv;
+}
+
+/*
=for apidoc sv_get_backrefs
If C<sv> is the target of a weak reference then it returns the back