I32 key;
SV* sv;
- if (AvREAL(av))
- return;
+ if (AvREAL(av))
+ return;
#ifdef DEBUGGING
- if (SvRMAGICAL(av) && mg_find((SV*)av,'P'))
+ if (SvRMAGICAL(av) && mg_find((SV*)av,'P'))
warn("av_reify called on tied array");
#endif
key = AvMAX(av) + 1;
dSP;
ENTER;
SAVETMPS;
- PUSHMARK(sp);
- EXTEND(sp,2);
+ PUSHSTACKi(PERLSI_MAGIC);
+ PUSHMARK(SP);
+ EXTEND(SP,2);
PUSHs(mg->mg_obj);
PUSHs(sv_2mortal(newSViv(key+1)));
PUTBACK;
perl_call_method("EXTEND", G_SCALAR|G_DISCARD);
+ POPSTACK;
FREETMPS;
LEAVE;
return;
U32 bytes;
#endif
+#ifdef MYMALLOC
+ newmax = malloced_size((void*)AvALLOC(av))/sizeof(SV*) - 1;
+
+ if (key <= newmax)
+ goto resized;
+#endif
newmax = key + AvMAX(av) / 5;
resize:
-#ifdef STRANGE_MALLOC
+#if defined(STRANGE_MALLOC) || defined(MYMALLOC)
Renew(AvALLOC(av),newmax+1, SV*);
#else
bytes = (newmax + 1) * sizeof(SV*);
Safefree(AvALLOC(av));
AvALLOC(av) = ary;
#endif
+ resized:
ary = AvALLOC(av) + AvMAX(av) + 1;
tmp = newmax - AvMAX(av);
if (av == curstack) { /* Oops, grew stack (via av_store()?) */
}
}
else {
- newmax = key < 4 ? 4 : key;
+ newmax = key < 3 ? 3 : key;
New(2,AvALLOC(av), newmax+1, SV*);
ary = AvALLOC(av) + 1;
tmp = newmax;
dTHR;
sv = sv_newmortal();
mg_copy((SV*)av, sv, 0, key);
- Sv = sv;
- return &Sv;
+ av_fetch_sv = sv;
+ return &av_fetch_sv;
}
}
return;
/*SUPPRESS 560*/
+ if (SvREADONLY(av))
+ croak(no_modify);
+
/* Give any tie a chance to cleanup first */
if (SvRMAGICAL(av))
mg_clear((SV*)av);
SvREFCNT_dec(AvARRAY(av)[--key]);
}
Safefree(AvALLOC(av));
-#ifdef PERL_OBJECT
- (((XPVAV*) SvANY(av))->xav_array) = 0;
- /* the following line is is a problem with VC */
- /* AvARRAY(av) = 0; */
-#else
- AvARRAY(av) = 0;
-#endif
AvALLOC(av) = 0;
SvPVX(av) = 0;
AvMAX(av) = AvFILLp(av) = -1;
if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
dSP;
- PUSHMARK(sp);
- EXTEND(sp,2);
+ PUSHSTACKi(PERLSI_MAGIC);
+ PUSHMARK(SP);
+ EXTEND(SP,2);
PUSHs(mg->mg_obj);
PUSHs(val);
PUTBACK;
ENTER;
perl_call_method("PUSH", G_SCALAR|G_DISCARD);
LEAVE;
+ POPSTACK;
return;
}
av_store(av,AvFILLp(av)+1,val);
croak(no_modify);
if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
dSP;
- PUSHMARK(sp);
+ PUSHSTACKi(PERLSI_MAGIC);
+ PUSHMARK(SP);
XPUSHs(mg->mg_obj);
PUTBACK;
ENTER;
retval = &sv_undef;
}
LEAVE;
+ POPSTACK;
return retval;
}
retval = AvARRAY(av)[AvFILLp(av)];
if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
dSP;
- PUSHMARK(sp);
- EXTEND(sp,1+num);
+ PUSHSTACKi(PERLSI_MAGIC);
+ PUSHMARK(SP);
+ EXTEND(SP,1+num);
PUSHs(mg->mg_obj);
while (num-- > 0) {
PUSHs(&sv_undef);
ENTER;
perl_call_method("UNSHIFT", G_SCALAR|G_DISCARD);
LEAVE;
+ POPSTACK;
return;
}
AvFILLp(av) += i;
SvPVX(av) = (char*)(AvARRAY(av) - i);
}
- if (num) {
+ if (num) {
i = AvFILLp(av);
av_extend(av, i + num);
AvFILLp(av) += num;
croak(no_modify);
if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
dSP;
- PUSHMARK(sp);
+ PUSHSTACKi(PERLSI_MAGIC);
+ PUSHMARK(SP);
XPUSHs(mg->mg_obj);
PUTBACK;
ENTER;
retval = &sv_undef;
}
LEAVE;
+ POPSTACK;
return retval;
}
retval = *AvARRAY(av);
dSP;
ENTER;
SAVETMPS;
- PUSHMARK(sp);
- EXTEND(sp,2);
+ PUSHSTACKi(PERLSI_MAGIC);
+ PUSHMARK(SP);
+ EXTEND(SP,2);
PUSHs(mg->mg_obj);
PUSHs(sv_2mortal(newSViv(fill+1)));
PUTBACK;
perl_call_method("STORESIZE", G_SCALAR|G_DISCARD);
+ POPSTACK;
FREETMPS;
LEAVE;
return;
(void)av_store(av,fill,&sv_undef);
}
-
+
+/* AVHV: Support for treating arrays as if they were hashes. The
+ * first element of the array should be a hash reference that maps
+ * hash keys to array indices.
+ */
+
+STATIC I32
+avhv_index_sv(SV* sv)
+{
+ I32 index = SvIV(sv);
+ if (index < 1)
+ croak("Bad index while coercing array into hash");
+ return index;
+}
+
HV*
avhv_keys(AV *av)
{
- SV **keysp;
- HV *keys = Nullhv;
-
- keysp = av_fetch(av, 0, FALSE);
+ SV **keysp = av_fetch(av, 0, FALSE);
if (keysp) {
SV *sv = *keysp;
if (SvGMAGICAL(sv))
if (SvROK(sv)) {
sv = SvRV(sv);
if (SvTYPE(sv) == SVt_PVHV)
- keys = (HV*)sv;
+ return (HV*)sv;
}
}
- if (!keys)
- croak("Can't coerce array into hash");
- return keys;
-}
-
-SV**
-avhv_fetch(AV *av, char *key, U32 klen, I32 lval)
-{
- SV **indsvp;
- HV *keys = avhv_keys(av);
- I32 ind;
-
- indsvp = hv_fetch(keys, key, klen, FALSE);
- if (indsvp) {
- ind = SvIV(*indsvp);
- if (ind < 1)
- croak("Bad index while coercing array into hash");
- } else {
- if (!lval)
- return 0;
-
- ind = AvFILL(av) + 1;
- hv_store(keys, key, klen, newSViv(ind), 0);
- }
- return av_fetch(av, ind, lval);
+ croak("Can't coerce array into hash");
+ return Nullhv;
}
SV**
SV **indsvp;
HV *keys = avhv_keys(av);
HE *he;
- I32 ind;
-
- he = hv_fetch_ent(keys, keysv, FALSE, hash);
- if (he) {
- ind = SvIV(HeVAL(he));
- if (ind < 1)
- croak("Bad index while coercing array into hash");
- } else {
- if (!lval)
- return 0;
-
- ind = AvFILL(av) + 1;
- hv_store_ent(keys, keysv, newSViv(ind), 0);
- }
- return av_fetch(av, ind, lval);
-}
-
-SV**
-avhv_store(AV *av, char *key, U32 klen, SV *val, U32 hash)
-{
- SV **indsvp;
- HV *keys = avhv_keys(av);
- I32 ind;
-
- indsvp = hv_fetch(keys, key, klen, FALSE);
- if (indsvp) {
- ind = SvIV(*indsvp);
- if (ind < 1)
- croak("Bad index while coercing array into hash");
- } else {
- ind = AvFILL(av) + 1;
- hv_store(keys, key, klen, newSViv(ind), hash);
- }
- return av_store(av, ind, val);
-}
-
-SV**
-avhv_store_ent(AV *av, SV *keysv, SV *val, U32 hash)
-{
- HV *keys = avhv_keys(av);
- HE *he;
- I32 ind;
he = hv_fetch_ent(keys, keysv, FALSE, hash);
- if (he) {
- ind = SvIV(HeVAL(he));
- if (ind < 1)
- croak("Bad index while coercing array into hash");
- } else {
- ind = AvFILL(av) + 1;
- hv_store_ent(keys, keysv, newSViv(ind), hash);
- }
- return av_store(av, ind, val);
+ if (!he)
+ croak("No such array field");
+ return av_fetch(av, avhv_index_sv(HeVAL(he)), lval);
}
bool
return hv_exists_ent(keys, keysv, hash);
}
-bool
-avhv_exists(AV *av, char *key, U32 klen)
-{
- HV *keys = avhv_keys(av);
- return hv_exists(keys, key, klen);
-}
-
-/* avhv_delete leaks. Caller can re-index and compress if so desired. */
-SV *
-avhv_delete(AV *av, char *key, U32 klen, I32 flags)
-{
- HV *keys = avhv_keys(av);
- SV *sv;
- SV **svp;
- I32 ind;
-
- sv = hv_delete(keys, key, klen, 0);
- if (!sv)
- return Nullsv;
- ind = SvIV(sv);
- if (ind < 1)
- croak("Bad index while coercing array into hash");
- svp = av_fetch(av, ind, FALSE);
- if (!svp)
- return Nullsv;
- if (flags & G_DISCARD) {
- sv = Nullsv;
- SvREFCNT_dec(*svp);
- } else {
- sv = sv_2mortal(*svp);
- }
- *svp = &sv_undef;
- return sv;
-}
-
-/* avhv_delete_ent leaks. Caller can re-index and compress if so desired. */
-SV *
-avhv_delete_ent(AV *av, SV *keysv, I32 flags, U32 hash)
-{
- HV *keys = avhv_keys(av);
- SV *sv;
- SV **svp;
- I32 ind;
-
- sv = hv_delete_ent(keys, keysv, 0, hash);
- if (!sv)
- return Nullsv;
- ind = SvIV(sv);
- if (ind < 1)
- croak("Bad index while coercing array into hash");
- svp = av_fetch(av, ind, FALSE);
- if (!svp)
- return Nullsv;
- if (flags & G_DISCARD) {
- sv = Nullsv;
- SvREFCNT_dec(*svp);
- } else {
- sv = sv_2mortal(*svp);
- }
- *svp = &sv_undef;
- return sv;
-}
-
-I32
-avhv_iterinit(AV *av)
-{
- HV *keys = avhv_keys(av);
- return hv_iterinit(keys);
-}
-
HE *
avhv_iternext(AV *av)
{
SV *
avhv_iterval(AV *av, register HE *entry)
{
- HV *keys = avhv_keys(av);
- SV *sv;
- I32 ind;
-
- sv = hv_iterval(keys, entry);
- ind = SvIV(sv);
- if (ind < 1)
- croak("Bad index while coercing array into hash");
- return *av_fetch(av, ind, TRUE);
-}
-
-SV *
-avhv_iternextsv(AV *av, char **key, I32 *retlen)
-{
- HV *keys = avhv_keys(av);
- HE *he;
- SV *sv;
- I32 ind;
-
- he = hv_iternext(keys);
- if (!he)
- return Nullsv;
- *key = hv_iterkey(he, retlen);
- sv = hv_iterval(keys, he);
- ind = SvIV(sv);
- if (ind < 1)
- croak("Bad index while coercing array into hash");
- return *av_fetch(av, ind, TRUE);
+ SV *sv = hv_iterval(avhv_keys(av), entry);
+ return *av_fetch(av, avhv_index_sv(sv), TRUE);
}