more information on how to use this function on tied arrays.
The rough perl equivalent is C<$myarray[$idx]>.
+
=cut
*/
return NULL;
}
- if (key > AvFILLp(av)) {
- if (!lval)
- return NULL;
- return av_store(av,key,newSV(0));
+ if (key > AvFILLp(av) || AvARRAY(av)[key] == &PL_sv_undef) {
+ emptyness:
+ return lval ? av_store(av,key,newSV(0)) : NULL;
}
- if (AvARRAY(av)[key] == &PL_sv_undef) {
- emptyness:
- if (lval)
- return av_store(av,key,newSV(0));
- return NULL;
- }
- else if (AvREIFY(av)
+
+ if (AvREIFY(av)
&& (!AvARRAY(av)[key] /* eg. @_ could have freed elts */
|| SvIS_FREED(AvARRAY(av)[key]))) {
AvARRAY(av)[key] = &PL_sv_undef; /* 1/2 reify */
Stores an SV in an array. The array index is specified as C<key>. The
return value will be NULL if the operation failed or if the value did not
need to be actually stored within the array (as in the case of tied
-arrays). Otherwise it can be dereferenced to get the original C<SV*>. Note
-that the caller is responsible for suitably incrementing the reference
+arrays). Otherwise, it can be dereferenced
+to get the C<SV*> that was stored
+there (= C<val>)).
+
+Note that the caller is responsible for suitably incrementing the reference
count of C<val> before the call, and decrementing it if the function
returned NULL.
+Approximate Perl equivalent: C<$myarray[$key] = $val;>.
+
See L<perlguts/"Understanding the Magic of Tied Hashes and Arrays"> for
more information on how to use this function on tied arrays.
SvREFCNT_dec(ary[key]);
ary[key] = val;
if (SvSMAGICAL(av)) {
- const MAGIC* const mg = SvMAGIC(av);
- if (val != &PL_sv_undef) {
+ const MAGIC *mg = SvMAGIC(av);
+ bool set = TRUE;
+ for (; mg; mg = mg->mg_moremagic) {
+ if (!isUPPER(mg->mg_type)) continue;
+ if (val != &PL_sv_undef) {
sv_magic(val, MUTABLE_SV(av), toLOWER(mg->mg_type), 0, key);
- }
- if (PL_delaymagic && mg->mg_type == PERL_MAGIC_isa)
+ }
+ if (PL_delaymagic && mg->mg_type == PERL_MAGIC_isa) {
PL_delaymagic |= DM_ARRAY_ISA;
- else
+ set = FALSE;
+ }
+ }
+ if (set)
mg_set(MUTABLE_SV(av));
}
return &ary[key];
/*
=for apidoc av_clear
-Clears an array, making it empty. Does not free the memory used by the
-array itself. Perl equivalent: C<@myarray = ();>.
+Clears an array, making it empty. Does not free the memory the av uses to
+store its list of scalars. If any destructors are triggered as a result,
+the av itself may be freed when this function returns.
+
+Perl equivalent: C<@myarray = ();>.
=cut
*/
{
dVAR;
I32 extra;
+ bool real;
PERL_ARGS_ASSERT_AV_CLEAR;
assert(SvTYPE(av) == SVt_PVAV);
if (AvMAX(av) < 0)
return;
- if (AvREAL(av)) {
+ if ((real = !!AvREAL(av))) {
SV** const ary = AvARRAY(av);
I32 index = AvFILLp(av) + 1;
+ ENTER;
+ SAVEFREESV(SvREFCNT_inc_simple_NN(av));
while (index) {
SV * const sv = ary[--index];
/* undef the slot before freeing the value, because a
AvARRAY(av) = AvALLOC(av);
}
AvFILLp(av) = -1;
-
+ if (real) LEAVE;
}
/*
=for apidoc av_undef
-Undefines the array. Frees the memory used by the array itself.
+Undefines the array. Frees the memory used by the av to store its list of
+scalars. If any destructors are triggered as a result, the av itself may
+be freed.
=cut
*/
void
Perl_av_undef(pTHX_ register AV *av)
{
+ bool real;
+
PERL_ARGS_ASSERT_AV_UNDEF;
assert(SvTYPE(av) == SVt_PVAV);
if (SvTIED_mg((const SV *)av, PERL_MAGIC_tied))
av_fill(av, -1);
- if (AvREAL(av)) {
+ if ((real = !!AvREAL(av))) {
register I32 key = AvFILLp(av) + 1;
+ ENTER;
+ SAVEFREESV(SvREFCNT_inc_simple_NN(av));
while (key)
SvREFCNT_dec(AvARRAY(av)[--key]);
}
AvMAX(av) = AvFILLp(av) = -1;
if(SvRMAGICAL(av)) mg_clear(MUTABLE_SV(av));
+ if(real) LEAVE;
}
/*
=for apidoc av_push
Pushes an SV onto the end of the array. The array will grow automatically
-to accommodate the addition. Like C<av_store>, this takes ownership of one
-reference count.
+to accommodate the addition. This takes ownership of one reference count.
+
+Perl equivalent: C<push @myarray, $elem;>.
=cut
*/
Pops an SV off the end of the array. Returns C<&PL_sv_undef> if the array
is empty.
+Perl equivalent: C<pop(@myarray);>
+
=cut
*/
array. The array will grow automatically to accommodate the addition. You
must then use C<av_store> to assign values to these new elements.
+Perl equivalent: C<unshift @myarray, ( (undef) x $n );>
+
=cut
*/
/*
=for apidoc av_shift
-Shifts an SV off the beginning of the array. Returns C<&PL_sv_undef> if the
+Shifts an SV off the beginning of the
+array. Returns C<&PL_sv_undef> if the
array is empty.
+Perl equivalent: C<shift(@myarray);>
+
=cut
*/