while (key) {
sv = AvARRAY(av)[--key];
assert(sv);
- if (sv != &sv_undef)
+ if (sv != &sv_undef) {
+ dTHR;
(void)SvREFCNT_inc(sv);
+ }
}
key = AvARRAY(av) - AvALLOC(av);
while (key)
AV *av;
I32 key;
{
+ dTHR; /* only necessary if we have to extend stack */
if (key > AvMAX(av)) {
SV** ary;
I32 tmp;
if (SvRMAGICAL(av)) {
if (mg_find((SV*)av,'P')) {
+ dTHR;
sv = sv_newmortal();
mg_copy((SV*)av, sv, 0, key);
Sv = sv;
ary = AvARRAY(av);
if (AvFILL(av) < key) {
if (!AvREAL(av)) {
+ dTHR;
if (av == curstack && key > stack_sp - stack_base)
stack_sp = stack_base + key; /* XPUSH in disguise */
do
}
SV**
+avhv_fetch_ent(av, keysv, lval, hash)
+AV *av;
+SV *keysv;
+I32 lval;
+U32 hash;
+{
+ SV **keys, **indsvp;
+ HE *he;
+ I32 ind;
+
+ keys = av_fetch(av, 0, FALSE);
+ if (!keys || !SvROK(*keys) || SvTYPE(SvRV(*keys)) != SVt_PVHV)
+ croak("Can't coerce array into hash");
+ he = hv_fetch_ent((HV*)SvRV(*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((HV*)SvRV(*keys), keysv, newSViv(ind), 0);
+ }
+ return av_fetch(av, ind, lval);
+}
+
+SV**
avhv_store(av, key, klen, val, hash)
AV *av;
char *key;
return av_store(av, ind, val);
}
+SV**
+avhv_store_ent(av, keysv, val, hash)
+AV *av;
+SV *keysv;
+SV *val;
+U32 hash;
+{
+ SV **keys;
+ HE *he;
+ I32 ind;
+
+ keys = av_fetch(av, 0, FALSE);
+ if (!keys || !SvROK(*keys) || SvTYPE(SvRV(*keys)) != SVt_PVHV)
+ croak("Can't coerce array into hash");
+ he = hv_fetch_ent((HV*)SvRV(*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((HV*)SvRV(*keys), keysv, newSViv(ind), hash);
+ }
+ return av_store(av, ind, val);
+}
+
+bool
+avhv_exists_ent(av, keysv, hash)
+AV *av;
+SV *keysv;
+U32 hash;
+{
+ SV **keys;
+
+ keys = av_fetch(av, 0, FALSE);
+ if (!keys || !SvROK(*keys) || SvTYPE(SvRV(*keys)) != SVt_PVHV)
+ croak("Can't coerce array into hash");
+ return hv_exists_ent((HV*)SvRV(*keys), keysv, hash);
+}
+
bool
avhv_exists(av, key, klen)
AV *av;
return sv;
}
+/* avhv_delete_ent leaks. Caller can re-index and compress if so desired. */
+SV *
+avhv_delete_ent(av, keysv, flags, hash)
+AV *av;
+SV *keysv;
+I32 flags;
+U32 hash;
+{
+ SV **keys;
+ SV *sv;
+ SV **svp;
+ I32 ind;
+
+ keys = av_fetch(av, 0, FALSE);
+ if (!keys || !SvROK(*keys) || SvTYPE(SvRV(*keys)) != SVt_PVHV)
+ croak("Can't coerce array into hash");
+ sv = hv_delete_ent((HV*)SvRV(*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 *av;