/* av.c
*
* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- * 2000, 2001, 2002, 2003, by Larry Wall and others
+ * 2000, 2001, 2002, 2003, 2004, 2005 by Larry Wall and others
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
Perl_av_reify(pTHX_ AV *av)
{
I32 key;
- SV* sv;
if (AvREAL(av))
return;
while (key > AvFILLp(av) + 1)
AvARRAY(av)[--key] = &PL_sv_undef;
while (key) {
- sv = AvARRAY(av)[--key];
+ SV * const sv = AvARRAY(av)[--key];
assert(sv);
if (sv != &PL_sv_undef)
(void)SvREFCNT_inc(sv);
tmp = AvARRAY(av) - AvALLOC(av);
Move(AvARRAY(av), AvALLOC(av), AvFILLp(av)+1, SV*);
AvMAX(av) += tmp;
- SvPVX(av) = (char*)AvALLOC(av);
+ SvPV_set(av, (char*)AvALLOC(av));
if (AvREAL(av)) {
while (tmp)
ary[--tmp] = &PL_sv_undef;
}
}
else {
+#ifdef PERL_MALLOC_WRAP
+ static const char oom_array_extend[] =
+ "Out of memory during array extend"; /* Duplicated in pp_hot.c */
+#endif
+
if (AvALLOC(av)) {
#if !defined(STRANGE_MALLOC) && !defined(MYMALLOC)
MEM_SIZE bytes;
#endif
newmax = key + AvMAX(av) / 5;
resize:
- MEM_WRAP_CHECK_1(newmax+1, SV*, "panic: array extend");
+ MEM_WRAP_CHECK_1(newmax+1, SV*, oom_array_extend);
#if defined(STRANGE_MALLOC) || defined(MYMALLOC)
Renew(AvALLOC(av),newmax+1, SV*);
#else
}
else {
newmax = key < 3 ? 3 : key;
- MEM_WRAP_CHECK_1(newmax+1, SV*, "panic: array extend");
+ MEM_WRAP_CHECK_1(newmax+1, SV*, oom_array_extend);
New(2,AvALLOC(av), newmax+1, SV*);
ary = AvALLOC(av) + 1;
tmp = newmax;
ary[--tmp] = &PL_sv_undef;
}
- SvPVX(av) = (char*)AvALLOC(av);
+ SvPV_set(av, (char*)AvALLOC(av));
AvMAX(av) = newmax;
}
}
return 0;
if (SvRMAGICAL(av)) {
- MAGIC *tied_magic = mg_find((SV*)av, PERL_MAGIC_tied);
+ const MAGIC * const tied_magic = mg_find((SV*)av, PERL_MAGIC_tied);
if (tied_magic || mg_find((SV*)av, PERL_MAGIC_regdata)) {
U32 adjust_index = 1;
val = &PL_sv_undef;
if (SvRMAGICAL(av)) {
- MAGIC *tied_magic = mg_find((SV*)av, PERL_MAGIC_tied);
+ const MAGIC * const tied_magic = mg_find((SV*)av, PERL_MAGIC_tied);
if (tied_magic) {
/* Handle negative array indices 20020222 MJD */
if (key < 0) {
sv_upgrade((SV *)av, SVt_PVAV);
AvREAL_on(av);
AvALLOC(av) = 0;
- SvPVX(av) = 0;
+ SvPV_set(av, (char*)0);
AvMAX(av) = AvFILLp(av) = -1;
return av;
}
Perl_av_make(pTHX_ register I32 size, register SV **strp)
{
register AV *av;
- register I32 i;
- register SV** ary;
av = (AV*)NEWSV(8,0);
sv_upgrade((SV *) av,SVt_PVAV);
- AvFLAGS(av) = AVf_REAL;
- if (size) { /* `defined' was returning undef for size==0 anyway. */
+ AvREAL_only(av);
+ if (size) { /* "defined" was returning undef for size==0 anyway. */
+ register SV** ary;
+ register I32 i;
New(4,ary,size,SV*);
AvALLOC(av) = ary;
- SvPVX(av) = (char*)ary;
+ SvPV_set(av, (char*)ary);
AvFILLp(av) = size - 1;
AvMAX(av) = size - 1;
for (i = 0; i < size; i++) {
New(4,ary,size+1,SV*);
AvALLOC(av) = ary;
Copy(strp,ary,size,SV*);
- AvFLAGS(av) = AVf_REIFY;
- SvPVX(av) = (char*)ary;
+ AvREIFY_only(av);
+ SvPV_set(av, (char*)ary);
AvFILLp(av) = size - 1;
AvMAX(av) = size - 1;
while (size--) {
Perl_av_clear(pTHX_ register AV *av)
{
register I32 key;
- SV** ary;
#ifdef DEBUGGING
if (SvREFCNT(av) == 0 && ckWARN_d(WARN_DEBUGGING)) {
return;
if (AvREAL(av)) {
- ary = AvARRAY(av);
+ SV** ary = AvARRAY(av);
key = AvFILLp(av) + 1;
while (key) {
SV * sv = ary[--key];
}
if ((key = AvARRAY(av) - AvALLOC(av))) {
AvMAX(av) += key;
- SvPVX(av) = (char*)AvALLOC(av);
+ SvPV_set(av, (char*)AvALLOC(av));
}
AvFILLp(av) = -1;
void
Perl_av_undef(pTHX_ register AV *av)
{
- register I32 key;
-
if (!av)
return;
/*SUPPRESS 560*/
av_fill(av, -1); /* mg_clear() ? */
if (AvREAL(av)) {
- key = AvFILLp(av) + 1;
+ register I32 key = AvFILLp(av) + 1;
while (key)
SvREFCNT_dec(AvARRAY(av)[--key]);
}
Safefree(AvALLOC(av));
AvALLOC(av) = 0;
- SvPVX(av) = 0;
+ SvPV_set(av, (char*)0);
AvMAX(av) = AvFILLp(av) = -1;
- if (AvARYLEN(av)) {
- SvREFCNT_dec(AvARYLEN(av));
- AvARYLEN(av) = 0;
- }
+ /* It's in magic - it must already be gone. */
+ assert (!AvARYLEN(av));
}
/*
void
Perl_av_push(pTHX_ register AV *av, SV *val)
{
+ dVAR;
MAGIC *mg;
if (!av)
return;
SV *
Perl_av_pop(pTHX_ register AV *av)
{
+ dVAR;
SV *retval;
MAGIC* mg;
void
Perl_av_unshift(pTHX_ register AV *av, register I32 num)
{
+ dVAR;
register I32 i;
- register SV **ary;
MAGIC* mg;
- I32 slide;
if (!av)
return;
AvMAX(av) += i;
AvFILLp(av) += i;
- SvPVX(av) = (char*)(AvARRAY(av) - i);
+ SvPV_set(av, (char*)(AvARRAY(av) - i));
}
if (num) {
+ register SV **ary;
+ I32 slide;
i = AvFILLp(av);
/* Create extra elements */
slide = i > 0 ? i : 0;
/* Make extra elements into a buffer */
AvMAX(av) -= slide;
AvFILLp(av) -= slide;
- SvPVX(av) = (char*)(AvARRAY(av) + slide);
+ SvPV_set(av, (char*)(AvARRAY(av) + slide));
}
}
SV *
Perl_av_shift(pTHX_ register AV *av)
{
+ dVAR;
SV *retval;
MAGIC* mg;
retval = *AvARRAY(av);
if (AvREAL(av))
*AvARRAY(av) = &PL_sv_undef;
- SvPVX(av) = (char*)(AvARRAY(av) + 1);
+ SvPV_set(av, (char*)(AvARRAY(av) + 1));
AvMAX(av)--;
AvFILLp(av)--;
if (SvSMAGICAL(av))
*/
I32
-Perl_av_len(pTHX_ register AV *av)
+Perl_av_len(pTHX_ const register AV *av)
{
return AvFILL(av);
}
void
Perl_av_fill(pTHX_ register AV *av, I32 fill)
{
+ dVAR;
MAGIC *mg;
if (!av)
Perl_croak(aTHX_ "panic: null array");
=for apidoc av_delete
Deletes the element indexed by C<key> from the array. Returns the
-deleted element. C<flags> is currently ignored.
+deleted element. If C<flags> equals C<G_DISCARD>, the element is freed
+and null is returned.
=cut
*/
Perl_croak(aTHX_ PL_no_modify);
if (SvRMAGICAL(av)) {
- MAGIC *tied_magic = mg_find((SV*)av, PERL_MAGIC_tied);
- SV **svp;
+ const MAGIC * const tied_magic = mg_find((SV*)av, PERL_MAGIC_tied);
if ((tied_magic || mg_find((SV*)av, PERL_MAGIC_regdata))) {
/* Handle negative array indices 20020222 MJD */
+ SV **svp;
if (key < 0) {
unsigned adjust_index = 1;
if (tied_magic) {
if (key > AvFILLp(av))
return Nullsv;
else {
+ if (!AvREAL(av) && AvREIFY(av))
+ av_reify(av);
sv = AvARRAY(av)[key];
if (key == AvFILLp(av)) {
AvARRAY(av)[key] = &PL_sv_undef;
SvREFCNT_dec(sv);
sv = Nullsv;
}
+ else if (AvREAL(av))
+ sv = sv_2mortal(sv);
return sv;
}
if (SvRMAGICAL(av)) {
- MAGIC *tied_magic = mg_find((SV*)av, PERL_MAGIC_tied);
+ const MAGIC * const tied_magic = mg_find((SV*)av, PERL_MAGIC_tied);
if (tied_magic || mg_find((SV*)av, PERL_MAGIC_regdata)) {
SV *sv = sv_newmortal();
MAGIC *mg;
else
return FALSE;
}
+
+SV **
+Perl_av_arylen_p(pTHX_ AV *av) {
+ dVAR;
+ MAGIC *mg = mg_find((SV*)av, PERL_MAGIC_arylen_p);
+
+ if (!mg) {
+ mg = sv_magicext((SV*)av, 0, PERL_MAGIC_arylen_p, &PL_vtbl_arylen_p,
+ 0, 0);
+
+ if (!mg) {
+ Perl_die(aTHX_ "panic: av_arylen_p");
+ }
+ /* sv_magicext won't set this for us because we pass in a NULL obj */
+ mg->mg_flags |= MGf_REFCOUNTED;
+ }
+ return &(mg->mg_obj);
+}
+
+/*
+ * Local variables:
+ * c-indentation-style: bsd
+ * c-basic-offset: 4
+ * indent-tabs-mode: t
+ * End:
+ *
+ * ex: set ts=8 sts=4 sw=4 noet:
+ */