#include "EXTERN.h"
#define PERL_IN_AV_C
#include "perl.h"
void
Perl_av_reify(pTHX_ AV *av)
{
SSize_t key;
PERL_ARGS_ASSERT_AV_REIFY;
assert
(SvTYPE(av) == SVt_PVAV);
if
(AvREAL(av))
return
;
#ifdef DEBUGGING
if
(SvTIED_mg((
const
SV *)av, PERL_MAGIC_tied))
Perl_ck_warner_d(aTHX_ packWARN(WARN_DEBUGGING),
"av_reify called on tied array"
);
#endif
key = AvMAX(av) + 1;
while
(key > AvFILLp(av) + 1)
AvARRAY(av)[--key] = NULL;
while
(key) {
SV *
const
sv = AvARRAY(av)[--key];
if
(sv != &PL_sv_undef)
SvREFCNT_inc_simple_void(sv);
}
key = AvARRAY(av) - AvALLOC(av);
if
(key)
Zero(AvALLOC(av), key, SV*);
AvREIFY_off(av);
AvREAL_on(av);
}
void
Perl_av_extend(pTHX_ AV *av, SSize_t key)
{
MAGIC *mg;
PERL_ARGS_ASSERT_AV_EXTEND;
assert
(SvTYPE(av) == SVt_PVAV);
mg = SvTIED_mg((
const
SV *)av, PERL_MAGIC_tied);
if
(mg) {
SV *arg1 = sv_newmortal();
sv_setiv(arg1, (IV)(key + 1));
Perl_magic_methcall(aTHX_ MUTABLE_SV(av), mg, SV_CONST(EXTEND), G_DISCARD, 1,
arg1);
return
;
}
av_extend_guts(av,key,&AvMAX(av),&AvALLOC(av),&AvARRAY(av));
}
void
Perl_av_extend_guts(pTHX_ AV *av, SSize_t key, SSize_t *maxp, SV ***allocp,
SV ***arrayp)
{
PERL_ARGS_ASSERT_AV_EXTEND_GUTS;
if
(key < -1)
Perl_croak(aTHX_
"panic: av_extend_guts() negative count (%"
IVdf
")"
, (IV)key);
if
(key > *maxp) {
SSize_t ary_offset = *maxp + 1;
SSize_t to_null = 0;
SSize_t newmax = 0;
if
(av && *allocp != *arrayp) {
to_null = *arrayp - *allocp;
*maxp += to_null;
ary_offset = AvFILLp(av) + 1;
Move(*arrayp, *allocp, AvFILLp(av)+1, SV*);
if
(key > *maxp - 10) {
newmax = key + *maxp;
to_null = *maxp - AvFILLp(av);
goto
resize;
}
}
else
if
(*allocp) {
#ifdef Perl_safesysmalloc_size
newmax = Perl_safesysmalloc_size((
void
*)*allocp) /
sizeof
(
const
SV *) - 1;
if
(key <= newmax)
goto
resized;
#endif
newmax = *maxp / 5;
newmax = (key > SSize_t_MAX - newmax)
? SSize_t_MAX : key + newmax;
resize:
{
MEM_WRAP_CHECK_s(newmax, SV*,
"Out of memory during array extend"
);
}
#ifdef STRESS_REALLOC
{
SV **
const
old_alloc = *allocp;
Newx(*allocp, newmax+1, SV*);
Copy(old_alloc, *allocp, *maxp + 1, SV*);
Safefree(old_alloc);
}
#else
Renew(*allocp,newmax+1, SV*);
#endif
#ifdef Perl_safesysmalloc_size
resized:
#endif
to_null += newmax - *maxp;
*maxp = newmax;
if
(av == PL_curstack) {
PL_stack_sp = *allocp + (PL_stack_sp - PL_stack_base);
PL_stack_base = *allocp;
PL_stack_max = PL_stack_base + newmax;
}
}
else
{
*maxp = key < PERL_ARRAY_NEW_MIN_KEY ?
PERL_ARRAY_NEW_MIN_KEY : key;
{
MEM_WRAP_CHECK_s(*maxp, SV*,
"Out of memory during array extend"
);
}
Newx(*allocp, *maxp+1, SV*);
ary_offset = 0;
to_null = *maxp+1;
goto
zero;
}
if
(av && AvREAL(av)) {
zero:
Zero(*allocp + ary_offset,to_null,SV*);
}
*arrayp = *allocp;
}
}
static
bool
S_adjust_index(pTHX_ AV *av,
const
MAGIC *mg, SSize_t *keyp)
{
bool
adjust_index = 1;
if
(mg) {
SV *
const
ref = SvTIED_obj(MUTABLE_SV(av), mg);
SvGETMAGIC(ref);
if
(SvROK(ref) && SvOBJECT(SvRV(ref))) {
SV *
const
*
const
negative_indices_glob =
hv_fetchs(SvSTASH(SvRV(ref)), NEGATIVE_INDICES_VAR, 0);
if
(negative_indices_glob && isGV(*negative_indices_glob)
&& SvTRUE(GvSV(*negative_indices_glob)))
adjust_index = 0;
}
}
if
(adjust_index) {
*keyp += AvFILL(av) + 1;
if
(*keyp < 0)
return
FALSE;
}
return
TRUE;
}
SV**
Perl_av_fetch(pTHX_ AV *av, SSize_t key, I32 lval)
{
SSize_t neg;
SSize_t size;
PERL_ARGS_ASSERT_AV_FETCH;
assert
(SvTYPE(av) == SVt_PVAV);
if
(UNLIKELY(SvRMAGICAL(av))) {
const
MAGIC *
const
tied_magic
= mg_find((
const
SV *)av, PERL_MAGIC_tied);
if
(tied_magic || mg_find((
const
SV *)av, PERL_MAGIC_regdata)) {
SV *sv;
if
(key < 0) {
if
(!S_adjust_index(aTHX_ av, tied_magic, &key))
return
NULL;
}
sv = newSV_type_mortal(SVt_PVLV);
mg_copy(MUTABLE_SV(av), sv, 0, key);
if
(!tied_magic)
SvTEMP_off(sv);
LvTYPE(sv) =
't'
;
LvTARG(sv) = sv;
return
&(LvTARG(sv));
}
}
neg = (key < 0);
size = AvFILLp(av) + 1;
key += neg * size;
if
((Size_t)key >= (Size_t)size) {
if
(UNLIKELY(neg))
return
NULL;
goto
emptiness;
}
if
(!AvARRAY(av)[key]) {
emptiness:
return
lval ? av_store(av,key,newSV_type(SVt_NULL)) : NULL;
}
return
&AvARRAY(av)[key];
}
SV**
Perl_av_store(pTHX_ AV *av, SSize_t key, SV *val)
{
SV** ary;
PERL_ARGS_ASSERT_AV_STORE;
assert
(SvTYPE(av) == SVt_PVAV);
if
(SvRMAGICAL(av)) {
const
MAGIC *
const
tied_magic = mg_find((
const
SV *)av, PERL_MAGIC_tied);
if
(tied_magic) {
if
(key < 0) {
if
(!S_adjust_index(aTHX_ av, tied_magic, &key))
return
0;
}
if
(val) {
mg_copy(MUTABLE_SV(av), val, 0, key);
}
return
NULL;
}
}
if
(key < 0) {
key += AvFILL(av) + 1;
if
(key < 0)
return
NULL;
}
if
(SvREADONLY(av) && key >= AvFILL(av))
Perl_croak_no_modify();
if
(!AvREAL(av) && AvREIFY(av))
av_reify(av);
if
(key > AvMAX(av))
av_extend(av,key);
ary = AvARRAY(av);
if
(AvFILLp(av) < key) {
if
(!AvREAL(av)) {
if
(av == PL_curstack && key > PL_stack_sp - PL_stack_base)
PL_stack_sp = PL_stack_base + key;
do
{
ary[++AvFILLp(av)] = NULL;
}
while
(AvFILLp(av) < key);
}
AvFILLp(av) = key;
}
else
if
(AvREAL(av))
SvREFCNT_dec(ary[key]);
ary[key] = val;
if
(SvSMAGICAL(av)) {
const
MAGIC *mg = SvMAGIC(av);
bool
set = TRUE;
SvREFCNT_inc(val);
for
(; mg; mg = mg->mg_moremagic) {
if
(!isUPPER(mg->mg_type))
continue
;
if
(val) {
sv_magic(val, MUTABLE_SV(av), toLOWER(mg->mg_type), 0, key);
}
if
(PL_delaymagic && mg->mg_type == PERL_MAGIC_isa) {
PL_delaymagic |= DM_ARRAY_ISA;
set = FALSE;
}
}
if
(set)
mg_set(MUTABLE_SV(av));
SvREFCNT_dec(val);
}
return
&ary[key];
}
AV *
Perl_av_make(pTHX_ SSize_t size, SV **strp)
{
AV *
const
av = newAV();
PERL_ARGS_ASSERT_AV_MAKE;
assert
(SvTYPE(av) == SVt_PVAV);
if
(size) {
SV** ary;
SSize_t i;
SSize_t orig_ix;
Newx(ary,size,SV*);
AvALLOC(av) = ary;
AvARRAY(av) = ary;
AvMAX(av) = size - 1;
EXTEND_MORTAL(1);
PL_tmps_stack[++PL_tmps_ix] = (SV*)av;
orig_ix = PL_tmps_ix;
for
(i = 0; i < size; i++) {
assert
(*strp);
SvGETMAGIC(*strp);
AvFILLp(av)++;
ary[i] = newSV_type(SVt_NULL);
sv_setsv_flags(ary[i], *strp,
SV_DO_COW_SVSETSV|SV_NOSTEAL);
strp++;
}
if
(LIKELY(PL_tmps_ix == orig_ix))
PL_tmps_ix--;
else
PL_tmps_stack[orig_ix] = &PL_sv_undef;
}
return
av;
}
AV *
Perl_newAVav(pTHX_ AV *oav)
{
PERL_ARGS_ASSERT_NEWAVAV;
Size_t count = av_count(oav);
if
(UNLIKELY(!oav) || count == 0)
return
newAV();
AV *ret = newAV_alloc_x(count);
EXTEND_MORTAL(1);
PL_tmps_stack[++PL_tmps_ix] = (SV *)ret;
SSize_t ret_at_tmps_ix = PL_tmps_ix;
Size_t i;
if
(LIKELY(!SvRMAGICAL(oav) && AvREAL(oav) && (SvTYPE(oav) == SVt_PVAV))) {
for
(i = 0; i < count; i++) {
SV **svp = av_fetch_simple(oav, i, 0);
av_push_simple(ret, svp ? newSVsv(*svp) : &PL_sv_undef);
}
}
else
{
for
(i = 0; i < count; i++) {
SV **svp = av_fetch(oav, i, 0);
av_push_simple(ret, svp ? newSVsv(*svp) : &PL_sv_undef);
}
}
if
(LIKELY(PL_tmps_ix == ret_at_tmps_ix))
PL_tmps_ix--;
else
PL_tmps_stack[ret_at_tmps_ix] = &PL_sv_undef;
return
ret;
}
AV *
Perl_newAVhv(pTHX_ HV *ohv)
{
PERL_ARGS_ASSERT_NEWAVHV;
if
(UNLIKELY(!ohv))
return
newAV();
bool
tied = SvRMAGICAL(ohv) && mg_find(MUTABLE_SV(ohv), PERL_MAGIC_tied);
Size_t nkeys = hv_iterinit(ohv);
AV *ret = newAV_alloc_xz(nkeys ? nkeys * 2 : 2);
EXTEND_MORTAL(1);
PL_tmps_stack[++PL_tmps_ix] = (SV *)ret;
SSize_t ret_at_tmps_ix = PL_tmps_ix;
HE *he;
while
((he = hv_iternext(ohv))) {
if
(tied) {
av_push_simple(ret, newSVsv(hv_iterkeysv(he)));
av_push_simple(ret, newSVsv(hv_iterval(ohv, he)));
}
else
{
av_push_simple(ret, newSVhek(HeKEY_hek(he)));
av_push_simple(ret, HeVAL(he) ? newSVsv(HeVAL(he)) : &PL_sv_undef);
}
}
if
(LIKELY(PL_tmps_ix == ret_at_tmps_ix))
PL_tmps_ix--;
else
PL_tmps_stack[ret_at_tmps_ix] = &PL_sv_undef;
return
ret;
}
void
Perl_av_clear(pTHX_ AV *av)
{
bool
real;
SSize_t orig_ix = 0;
PERL_ARGS_ASSERT_AV_CLEAR;
assert
(SvTYPE(av) == SVt_PVAV);
#ifdef DEBUGGING
if
(SvREFCNT(av) == 0) {
Perl_ck_warner_d(aTHX_ packWARN(WARN_DEBUGGING),
"Attempt to clear deleted array"
);
}
#endif
if
(SvREADONLY(av))
Perl_croak_no_modify();
if
(SvRMAGICAL(av)) {
const
MAGIC*
const
mg = SvMAGIC(av);
if
(PL_delaymagic && mg && mg->mg_type == PERL_MAGIC_isa)
PL_delaymagic |= DM_ARRAY_ISA;
else
mg_clear(MUTABLE_SV(av));
}
if
(AvMAX(av) < 0)
return
;
if
((real = cBOOL(AvREAL(av)))) {
SV**
const
ary = AvARRAY(av);
SSize_t index = AvFILLp(av) + 1;
EXTEND_MORTAL(1);
PL_tmps_stack[++PL_tmps_ix] = SvREFCNT_inc_simple_NN(av);
orig_ix = PL_tmps_ix;
while
(index) {
SV *
const
sv = ary[--index];
ary[index] = NULL;
SvREFCNT_dec(sv);
}
}
AvFILLp(av) = -1;
av_remove_offset(av);
if
(real) {
if
(LIKELY(PL_tmps_ix == orig_ix))
PL_tmps_ix--;
else
PL_tmps_stack[orig_ix] = &PL_sv_undef;
SvREFCNT_dec_NN(av);
}
}
void
Perl_av_undef(pTHX_ AV *av)
{
bool
real;
SSize_t orig_ix = PL_tmps_ix;
PERL_ARGS_ASSERT_AV_UNDEF;
assert
(SvTYPE(av) == SVt_PVAV);
if
(SvTIED_mg((
const
SV *)av, PERL_MAGIC_tied))
av_fill(av, -1);
real = cBOOL(AvREAL(av));
if
(real) {
SSize_t key = AvFILLp(av) + 1;
EXTEND_MORTAL(1);
PL_tmps_stack[++PL_tmps_ix] = SvREFCNT_inc_simple_NN(av);
orig_ix = PL_tmps_ix;
while
(key)
SvREFCNT_dec(AvARRAY(av)[--key]);
}
Safefree(AvALLOC(av));
AvALLOC(av) = NULL;
AvARRAY(av) = NULL;
AvMAX(av) = AvFILLp(av) = -1;
if
(SvRMAGICAL(av)) mg_clear(MUTABLE_SV(av));
if
(real) {
if
(LIKELY(PL_tmps_ix == orig_ix))
PL_tmps_ix--;
else
PL_tmps_stack[orig_ix] = &PL_sv_undef;
SvREFCNT_dec_NN(av);
}
}
void
Perl_av_create_and_push(pTHX_ AV **
const
avp, SV *
const
val)
{
PERL_ARGS_ASSERT_AV_CREATE_AND_PUSH;
if
(!*avp)
*avp = newAV();
av_push(*avp, val);
}
void
Perl_av_push(pTHX_ AV *av, SV *val)
{
MAGIC *mg;
PERL_ARGS_ASSERT_AV_PUSH;
assert
(SvTYPE(av) == SVt_PVAV);
if
(SvREADONLY(av))
Perl_croak_no_modify();
if
((mg = SvTIED_mg((
const
SV *)av, PERL_MAGIC_tied))) {
Perl_magic_methcall(aTHX_ MUTABLE_SV(av), mg, SV_CONST(PUSH), G_DISCARD, 1,
val);
return
;
}
av_store(av,AvFILLp(av)+1,val);
}
SV *
Perl_av_pop(pTHX_ AV *av)
{
SV *retval;
MAGIC* mg;
PERL_ARGS_ASSERT_AV_POP;
assert
(SvTYPE(av) == SVt_PVAV);
if
(SvREADONLY(av))
Perl_croak_no_modify();
if
((mg = SvTIED_mg((
const
SV *)av, PERL_MAGIC_tied))) {
retval = Perl_magic_methcall(aTHX_ MUTABLE_SV(av), mg, SV_CONST(POP), 0, 0);
if
(retval)
retval = newSVsv(retval);
return
retval;
}
if
(AvFILL(av) < 0)
return
&PL_sv_undef;
retval = AvARRAY(av)[AvFILLp(av)];
AvARRAY(av)[AvFILLp(av)--] = NULL;
if
(SvSMAGICAL(av))
mg_set(MUTABLE_SV(av));
return
retval ? retval : &PL_sv_undef;
}
SV **
Perl_av_create_and_unshift_one(pTHX_ AV **
const
avp, SV *
const
val)
{
PERL_ARGS_ASSERT_AV_CREATE_AND_UNSHIFT_ONE;
if
(!*avp)
*avp = newAV();
av_unshift(*avp, 1);
return
av_store(*avp, 0, val);
}
void
Perl_av_unshift(pTHX_ AV *av, SSize_t num)
{
SSize_t i;
MAGIC* mg;
PERL_ARGS_ASSERT_AV_UNSHIFT;
assert
(SvTYPE(av) == SVt_PVAV);
if
(SvREADONLY(av))
Perl_croak_no_modify();
if
((mg = SvTIED_mg((
const
SV *)av, PERL_MAGIC_tied))) {
Perl_magic_methcall(aTHX_ MUTABLE_SV(av), mg, SV_CONST(UNSHIFT),
G_DISCARD | G_UNDEF_FILL, num);
return
;
}
if
(num <= 0)
return
;
if
(!AvREAL(av) && AvREIFY(av))
av_reify(av);
i = AvARRAY(av) - AvALLOC(av);
if
(i) {
if
(i > num)
i = num;
num -= i;
AvMAX(av) += i;
AvFILLp(av) += i;
AvARRAY(av) = AvARRAY(av) - i;
#ifdef PERL_RC_STACK
Zero(AvARRAY(av), i, SV*);
#endif
}
if
(num) {
SV **ary;
const
SSize_t i = AvFILLp(av);
const
SSize_t slide = i > 0 ? i : 0;
num += slide;
av_extend(av, i + num);
AvFILLp(av) += num;
ary = AvARRAY(av);
Move(ary, ary + num, i + 1, SV*);
do
{
ary[--num] = NULL;
}
while
(num);
AvMAX(av) -= slide;
AvFILLp(av) -= slide;
AvARRAY(av) = AvARRAY(av) + slide;
}
}
SV *
Perl_av_shift(pTHX_ AV *av)
{
SV *retval;
MAGIC* mg;
PERL_ARGS_ASSERT_AV_SHIFT;
assert
(SvTYPE(av) == SVt_PVAV);
if
(SvREADONLY(av))
Perl_croak_no_modify();
if
((mg = SvTIED_mg((
const
SV *)av, PERL_MAGIC_tied))) {
retval = Perl_magic_methcall(aTHX_ MUTABLE_SV(av), mg, SV_CONST(SHIFT), 0, 0);
if
(retval)
retval = newSVsv(retval);
return
retval;
}
if
(AvFILL(av) < 0)
return
&PL_sv_undef;
retval = *AvARRAY(av);
#ifndef PERL_RC_STACK
if
(AvREAL(av))
*AvARRAY(av) = NULL;
#endif
AvARRAY(av) = AvARRAY(av) + 1;
AvMAX(av)--;
AvFILLp(av)--;
if
(SvSMAGICAL(av))
mg_set(MUTABLE_SV(av));
return
retval ? retval : &PL_sv_undef;
}
SSize_t
Perl_av_len(pTHX_ AV *av)
{
PERL_ARGS_ASSERT_AV_LEN;
return
av_top_index(av);
}
void
Perl_av_fill(pTHX_ AV *av, SSize_t fill)
{
MAGIC *mg;
PERL_ARGS_ASSERT_AV_FILL;
assert
(SvTYPE(av) == SVt_PVAV);
if
(fill < 0)
fill = -1;
if
((mg = SvTIED_mg((
const
SV *)av, PERL_MAGIC_tied))) {
SV *arg1 = sv_newmortal();
sv_setiv(arg1, (IV)(fill + 1));
Perl_magic_methcall(aTHX_ MUTABLE_SV(av), mg, SV_CONST(STORESIZE), G_DISCARD,
1, arg1);
return
;
}
if
(fill <= AvMAX(av)) {
SSize_t key = AvFILLp(av);
SV**
const
ary = AvARRAY(av);
if
(AvREAL(av)) {
while
(key > fill) {
SvREFCNT_dec(ary[key]);
ary[key--] = NULL;
}
}
else
{
while
(key < fill)
ary[++key] = NULL;
}
AvFILLp(av) = fill;
if
(SvSMAGICAL(av))
mg_set(MUTABLE_SV(av));
}
else
(
void
)av_store(av,fill,NULL);
}
SV *
Perl_av_delete(pTHX_ AV *av, SSize_t key, I32 flags)
{
SV *sv;
PERL_ARGS_ASSERT_AV_DELETE;
assert
(SvTYPE(av) == SVt_PVAV);
if
(SvREADONLY(av))
Perl_croak_no_modify();
if
(SvRMAGICAL(av)) {
const
MAGIC *
const
tied_magic
= mg_find((
const
SV *)av, PERL_MAGIC_tied);
if
((tied_magic || mg_find((
const
SV *)av, PERL_MAGIC_regdata))) {
SV **svp;
if
(key < 0) {
if
(!S_adjust_index(aTHX_ av, tied_magic, &key))
return
NULL;
}
svp = av_fetch(av, key, TRUE);
if
(svp) {
sv = *svp;
mg_clear(sv);
if
(mg_find(sv, PERL_MAGIC_tiedelem)) {
sv_unmagic(sv, PERL_MAGIC_tiedelem);
return
sv;
}
return
NULL;
}
}
}
if
(key < 0) {
key += AvFILL(av) + 1;
if
(key < 0)
return
NULL;
}
if
(key > AvFILLp(av))
return
NULL;
else
{
if
(!AvREAL(av) && AvREIFY(av))
av_reify(av);
sv = AvARRAY(av)[key];
AvARRAY(av)[key] = NULL;
if
(key == AvFILLp(av)) {
do
{
AvFILLp(av)--;
}
while
(--key >= 0 && !AvARRAY(av)[key]);
}
if
(SvSMAGICAL(av))
mg_set(MUTABLE_SV(av));
}
if
(sv != NULL) {
if
(flags & G_DISCARD) {
SvREFCNT_dec_NN(sv);
return
NULL;
}
else
if
(AvREAL(av))
sv_2mortal(sv);
}
return
sv;
}
bool
Perl_av_exists(pTHX_ AV *av, SSize_t key)
{
PERL_ARGS_ASSERT_AV_EXISTS;
assert
(SvTYPE(av) == SVt_PVAV);
if
(SvRMAGICAL(av)) {
const
MAGIC *
const
tied_magic
= mg_find((
const
SV *)av, PERL_MAGIC_tied);
const
MAGIC *
const
regdata_magic
= mg_find((
const
SV *)av, PERL_MAGIC_regdata);
if
(tied_magic || regdata_magic) {
MAGIC *mg;
if
(key < 0) {
if
(!S_adjust_index(aTHX_ av, tied_magic, &key))
return
FALSE;
}
if
(key >= 0 && regdata_magic) {
if
(key <= AvFILL(av))
return
TRUE;
else
return
FALSE;
}
{
SV *
const
sv = sv_newmortal();
mg_copy(MUTABLE_SV(av), sv, 0, key);
mg = mg_find(sv, PERL_MAGIC_tiedelem);
if
(mg) {
magic_existspack(sv, mg);
{
I32 retbool = SvTRUE_nomg_NN(sv);
return
cBOOL(retbool);
}
}
}
}
}
if
(key < 0) {
key += AvFILL(av) + 1;
if
(key < 0)
return
FALSE;
}
if
(key <= AvFILLp(av) && AvARRAY(av)[key])
{
if
(SvSMAGICAL(AvARRAY(av)[key])
&& mg_find(AvARRAY(av)[key], PERL_MAGIC_nonelem))
return
FALSE;
return
TRUE;
}
else
return
FALSE;
}
static
MAGIC *
S_get_aux_mg(pTHX_ AV *av) {
MAGIC *mg;
PERL_ARGS_ASSERT_GET_AUX_MG;
assert
(SvTYPE(av) == SVt_PVAV);
mg = mg_find((
const
SV *)av, PERL_MAGIC_arylen_p);
if
(!mg) {
mg = sv_magicext(MUTABLE_SV(av), 0, PERL_MAGIC_arylen_p,
&PL_vtbl_arylen_p, 0, 0);
assert
(mg);
mg->mg_flags |= MGf_REFCOUNTED;
}
return
mg;
}
SV **
Perl_av_arylen_p(pTHX_ AV *av) {
MAGIC *
const
mg = get_aux_mg(av);
PERL_ARGS_ASSERT_AV_ARYLEN_P;
assert
(SvTYPE(av) == SVt_PVAV);
return
&(mg->mg_obj);
}
IV *
Perl_av_iter_p(pTHX_ AV *av) {
MAGIC *
const
mg = get_aux_mg(av);
PERL_ARGS_ASSERT_AV_ITER_P;
assert
(SvTYPE(av) == SVt_PVAV);
if
(
sizeof
(IV) ==
sizeof
(SSize_t)) {
return
(IV *)&(mg->mg_len);
}
else
{
if
(!mg->mg_ptr) {
IV *temp;
mg->mg_len = IVSIZE;
Newxz(temp, 1, IV);
mg->mg_ptr = (
char
*) temp;
}
return
(IV *)mg->mg_ptr;
}
}
SV *
Perl_av_nonelem(pTHX_ AV *av, SSize_t ix) {
SV *
const
sv = newSV_type(SVt_NULL);
PERL_ARGS_ASSERT_AV_NONELEM;
if
(!av_store(av,ix,sv))
return
sv_2mortal(sv);
sv_magic(sv, NULL, PERL_MAGIC_nonelem, NULL, 0);
return
sv;
}