This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
integrate vmsperl contents into mainline (no actual changes, since
[perl5.git] / av.c
1 /*    av.c
2  *
3  *    Copyright (c) 1991-2000, Larry Wall
4  *
5  *    You may distribute under the terms of either the GNU General Public
6  *    License or the Artistic License, as specified in the README file.
7  *
8  */
9
10 /*
11  * "...for the Entwives desired order, and plenty, and peace (by which they
12  * meant that things should remain where they had set them)." --Treebeard
13  */
14
15 #include "EXTERN.h"
16 #define PERL_IN_AV_C
17 #include "perl.h"
18
19 void
20 Perl_av_reify(pTHX_ AV *av)
21 {
22     I32 key;
23     SV* sv;
24
25     if (AvREAL(av))
26         return;
27 #ifdef DEBUGGING
28     if (SvTIED_mg((SV*)av, 'P') && ckWARN_d(WARN_DEBUGGING))
29         Perl_warner(aTHX_ WARN_DEBUGGING, "av_reify called on tied array");
30 #endif
31     key = AvMAX(av) + 1;
32     while (key > AvFILLp(av) + 1)
33         AvARRAY(av)[--key] = &PL_sv_undef;
34     while (key) {
35         sv = AvARRAY(av)[--key];
36         assert(sv);
37         if (sv != &PL_sv_undef) {
38             dTHR;
39             (void)SvREFCNT_inc(sv);
40         }
41     }
42     key = AvARRAY(av) - AvALLOC(av);
43     while (key)
44         AvALLOC(av)[--key] = &PL_sv_undef;
45     AvREIFY_off(av);
46     AvREAL_on(av);
47 }
48
49 /*
50 =for apidoc av_extend
51
52 Pre-extend an array.  The C<key> is the index to which the array should be
53 extended.
54
55 =cut
56 */
57
58 void
59 Perl_av_extend(pTHX_ AV *av, I32 key)
60 {
61     dTHR;                       /* only necessary if we have to extend stack */
62     MAGIC *mg;
63     if ((mg = SvTIED_mg((SV*)av, 'P'))) {
64         dSP;
65         ENTER;
66         SAVETMPS;
67         PUSHSTACKi(PERLSI_MAGIC);
68         PUSHMARK(SP);
69         EXTEND(SP,2);
70         PUSHs(SvTIED_obj((SV*)av, mg));
71         PUSHs(sv_2mortal(newSViv(key+1)));
72         PUTBACK;
73         call_method("EXTEND", G_SCALAR|G_DISCARD);
74         POPSTACK;
75         FREETMPS;
76         LEAVE;
77         return;
78     }
79     if (key > AvMAX(av)) {
80         SV** ary;
81         I32 tmp;
82         I32 newmax;
83
84         if (AvALLOC(av) != AvARRAY(av)) {
85             ary = AvALLOC(av) + AvFILLp(av) + 1;
86             tmp = AvARRAY(av) - AvALLOC(av);
87             Move(AvARRAY(av), AvALLOC(av), AvFILLp(av)+1, SV*);
88             AvMAX(av) += tmp;
89             SvPVX(av) = (char*)AvALLOC(av);
90             if (AvREAL(av)) {
91                 while (tmp)
92                     ary[--tmp] = &PL_sv_undef;
93             }
94             
95             if (key > AvMAX(av) - 10) {
96                 newmax = key + AvMAX(av);
97                 goto resize;
98             }
99         }
100         else {
101             if (AvALLOC(av)) {
102 #ifndef STRANGE_MALLOC
103                 MEM_SIZE bytes;
104                 IV itmp;
105 #endif
106
107 #if defined(MYMALLOC) && !defined(LEAKTEST)
108                 newmax = malloced_size((void*)AvALLOC(av))/sizeof(SV*) - 1;
109
110                 if (key <= newmax) 
111                     goto resized;
112 #endif 
113                 newmax = key + AvMAX(av) / 5;
114               resize:
115 #if defined(STRANGE_MALLOC) || defined(MYMALLOC)
116                 Renew(AvALLOC(av),newmax+1, SV*);
117 #else
118                 bytes = (newmax + 1) * sizeof(SV*);
119 #define MALLOC_OVERHEAD 16
120                 itmp = MALLOC_OVERHEAD;
121                 while (itmp - MALLOC_OVERHEAD < bytes)
122                     itmp += itmp;
123                 itmp -= MALLOC_OVERHEAD;
124                 itmp /= sizeof(SV*);
125                 assert(itmp > newmax);
126                 newmax = itmp - 1;
127                 assert(newmax >= AvMAX(av));
128                 New(2,ary, newmax+1, SV*);
129                 Copy(AvALLOC(av), ary, AvMAX(av)+1, SV*);
130                 if (AvMAX(av) > 64)
131                     offer_nice_chunk(AvALLOC(av), (AvMAX(av)+1) * sizeof(SV*));
132                 else
133                     Safefree(AvALLOC(av));
134                 AvALLOC(av) = ary;
135 #endif
136               resized:
137                 ary = AvALLOC(av) + AvMAX(av) + 1;
138                 tmp = newmax - AvMAX(av);
139                 if (av == PL_curstack) {        /* Oops, grew stack (via av_store()?) */
140                     PL_stack_sp = AvALLOC(av) + (PL_stack_sp - PL_stack_base);
141                     PL_stack_base = AvALLOC(av);
142                     PL_stack_max = PL_stack_base + newmax;
143                 }
144             }
145             else {
146                 newmax = key < 3 ? 3 : key;
147                 New(2,AvALLOC(av), newmax+1, SV*);
148                 ary = AvALLOC(av) + 1;
149                 tmp = newmax;
150                 AvALLOC(av)[0] = &PL_sv_undef;  /* For the stacks */
151             }
152             if (AvREAL(av)) {
153                 while (tmp)
154                     ary[--tmp] = &PL_sv_undef;
155             }
156             
157             SvPVX(av) = (char*)AvALLOC(av);
158             AvMAX(av) = newmax;
159         }
160     }
161 }
162
163 /*
164 =for apidoc av_fetch
165
166 Returns the SV at the specified index in the array.  The C<key> is the
167 index.  If C<lval> is set then the fetch will be part of a store.  Check
168 that the return value is non-null before dereferencing it to a C<SV*>.
169
170 See L<perlguts/"Understanding the Magic of Tied Hashes and Arrays"> for
171 more information on how to use this function on tied arrays. 
172
173 =cut
174 */
175
176 SV**
177 Perl_av_fetch(pTHX_ register AV *av, I32 key, I32 lval)
178 {
179     SV *sv;
180
181     if (!av)
182         return 0;
183
184     if (key < 0) {
185         key += AvFILL(av) + 1;
186         if (key < 0)
187             return 0;
188     }
189
190     if (SvRMAGICAL(av)) {
191         if (mg_find((SV*)av,'P') || mg_find((SV*)av,'D')) {
192             dTHR;
193             sv = sv_newmortal();
194             mg_copy((SV*)av, sv, 0, key);
195             PL_av_fetch_sv = sv;
196             return &PL_av_fetch_sv;
197         }
198     }
199
200     if (key > AvFILLp(av)) {
201         if (!lval)
202             return 0;
203         sv = NEWSV(5,0);
204         return av_store(av,key,sv);
205     }
206     if (AvARRAY(av)[key] == &PL_sv_undef) {
207     emptyness:
208         if (lval) {
209             sv = NEWSV(6,0);
210             return av_store(av,key,sv);
211         }
212         return 0;
213     }
214     else if (AvREIFY(av)
215              && (!AvARRAY(av)[key]      /* eg. @_ could have freed elts */
216                  || SvTYPE(AvARRAY(av)[key]) == SVTYPEMASK)) {
217         AvARRAY(av)[key] = &PL_sv_undef;        /* 1/2 reify */
218         goto emptyness;
219     }
220     return &AvARRAY(av)[key];
221 }
222
223 /*
224 =for apidoc av_store
225
226 Stores an SV in an array.  The array index is specified as C<key>.  The
227 return value will be NULL if the operation failed or if the value did not
228 need to be actually stored within the array (as in the case of tied
229 arrays). Otherwise it can be dereferenced to get the original C<SV*>.  Note
230 that the caller is responsible for suitably incrementing the reference
231 count of C<val> before the call, and decrementing it if the function
232 returned NULL.
233
234 See L<perlguts/"Understanding the Magic of Tied Hashes and Arrays"> for
235 more information on how to use this function on tied arrays.
236
237 =cut
238 */
239
240 SV**
241 Perl_av_store(pTHX_ register AV *av, I32 key, SV *val)
242 {
243     SV** ary;
244
245     if (!av)
246         return 0;
247     if (!val)
248         val = &PL_sv_undef;
249
250     if (key < 0) {
251         key += AvFILL(av) + 1;
252         if (key < 0)
253             return 0;
254     }
255
256     if (SvREADONLY(av) && key >= AvFILL(av))
257         Perl_croak(aTHX_ PL_no_modify);
258
259     if (SvRMAGICAL(av)) {
260         if (mg_find((SV*)av,'P')) {
261             if (val != &PL_sv_undef) {
262                 mg_copy((SV*)av, val, 0, key);
263             }
264             return 0;
265         }
266     }
267
268     if (!AvREAL(av) && AvREIFY(av))
269         av_reify(av);
270     if (key > AvMAX(av))
271         av_extend(av,key);
272     ary = AvARRAY(av);
273     if (AvFILLp(av) < key) {
274         if (!AvREAL(av)) {
275             dTHR;
276             if (av == PL_curstack && key > PL_stack_sp - PL_stack_base)
277                 PL_stack_sp = PL_stack_base + key;      /* XPUSH in disguise */
278             do
279                 ary[++AvFILLp(av)] = &PL_sv_undef;
280             while (AvFILLp(av) < key);
281         }
282         AvFILLp(av) = key;
283     }
284     else if (AvREAL(av))
285         SvREFCNT_dec(ary[key]);
286     ary[key] = val;
287     if (SvSMAGICAL(av)) {
288         if (val != &PL_sv_undef) {
289             MAGIC* mg = SvMAGIC(av);
290             sv_magic(val, (SV*)av, toLOWER(mg->mg_type), 0, key);
291         }
292         mg_set((SV*)av);
293     }
294     return &ary[key];
295 }
296
297 /*
298 =for apidoc newAV
299
300 Creates a new AV.  The reference count is set to 1.
301
302 =cut
303 */
304
305 AV *
306 Perl_newAV(pTHX)
307 {
308     register AV *av;
309
310     av = (AV*)NEWSV(3,0);
311     sv_upgrade((SV *)av, SVt_PVAV);
312     AvREAL_on(av);
313     AvALLOC(av) = 0;
314     SvPVX(av) = 0;
315     AvMAX(av) = AvFILLp(av) = -1;
316     return av;
317 }
318
319 /*
320 =for apidoc av_make
321
322 Creates a new AV and populates it with a list of SVs.  The SVs are copied
323 into the array, so they may be freed after the call to av_make.  The new AV
324 will have a reference count of 1.
325
326 =cut
327 */
328
329 AV *
330 Perl_av_make(pTHX_ register I32 size, register SV **strp)
331 {
332     register AV *av;
333     register I32 i;
334     register SV** ary;
335
336     av = (AV*)NEWSV(8,0);
337     sv_upgrade((SV *) av,SVt_PVAV);
338     AvFLAGS(av) = AVf_REAL;
339     if (size) {         /* `defined' was returning undef for size==0 anyway. */
340         New(4,ary,size,SV*);
341         AvALLOC(av) = ary;
342         SvPVX(av) = (char*)ary;
343         AvFILLp(av) = size - 1;
344         AvMAX(av) = size - 1;
345         for (i = 0; i < size; i++) {
346             assert (*strp);
347             ary[i] = NEWSV(7,0);
348             sv_setsv(ary[i], *strp);
349             strp++;
350         }
351     }
352     return av;
353 }
354
355 AV *
356 Perl_av_fake(pTHX_ register I32 size, register SV **strp)
357 {
358     register AV *av;
359     register SV** ary;
360
361     av = (AV*)NEWSV(9,0);
362     sv_upgrade((SV *)av, SVt_PVAV);
363     New(4,ary,size+1,SV*);
364     AvALLOC(av) = ary;
365     Copy(strp,ary,size,SV*);
366     AvFLAGS(av) = AVf_REIFY;
367     SvPVX(av) = (char*)ary;
368     AvFILLp(av) = size - 1;
369     AvMAX(av) = size - 1;
370     while (size--) {
371         assert (*strp);
372         SvTEMP_off(*strp);
373         strp++;
374     }
375     return av;
376 }
377
378 /*
379 =for apidoc av_clear
380
381 Clears an array, making it empty.  Does not free the memory used by the
382 array itself.
383
384 =cut
385 */
386
387 void
388 Perl_av_clear(pTHX_ register AV *av)
389 {
390     register I32 key;
391     SV** ary;
392
393 #ifdef DEBUGGING
394     if (SvREFCNT(av) == 0 && ckWARN_d(WARN_DEBUGGING)) {
395         Perl_warner(aTHX_ WARN_DEBUGGING, "Attempt to clear deleted array");
396     }
397 #endif
398     if (!av)
399         return;
400     /*SUPPRESS 560*/
401
402     if (SvREADONLY(av))
403         Perl_croak(aTHX_ PL_no_modify);
404
405     /* Give any tie a chance to cleanup first */
406     if (SvRMAGICAL(av))
407         mg_clear((SV*)av); 
408
409     if (AvMAX(av) < 0)
410         return;
411
412     if (AvREAL(av)) {
413         ary = AvARRAY(av);
414         key = AvFILLp(av) + 1;
415         while (key) {
416             SvREFCNT_dec(ary[--key]);
417             ary[key] = &PL_sv_undef;
418         }
419     }
420     if ((key = AvARRAY(av) - AvALLOC(av))) {
421         AvMAX(av) += key;
422         SvPVX(av) = (char*)AvALLOC(av);
423     }
424     AvFILLp(av) = -1;
425
426 }
427
428 /*
429 =for apidoc av_undef
430
431 Undefines the array.  Frees the memory used by the array itself.
432
433 =cut
434 */
435
436 void
437 Perl_av_undef(pTHX_ register AV *av)
438 {
439     register I32 key;
440
441     if (!av)
442         return;
443     /*SUPPRESS 560*/
444
445     /* Give any tie a chance to cleanup first */
446     if (SvTIED_mg((SV*)av, 'P')) 
447         av_fill(av, -1);   /* mg_clear() ? */
448
449     if (AvREAL(av)) {
450         key = AvFILLp(av) + 1;
451         while (key)
452             SvREFCNT_dec(AvARRAY(av)[--key]);
453     }
454     Safefree(AvALLOC(av));
455     AvALLOC(av) = 0;
456     SvPVX(av) = 0;
457     AvMAX(av) = AvFILLp(av) = -1;
458     if (AvARYLEN(av)) {
459         SvREFCNT_dec(AvARYLEN(av));
460         AvARYLEN(av) = 0;
461     }
462 }
463
464 /*
465 =for apidoc av_push
466
467 Pushes an SV onto the end of the array.  The array will grow automatically
468 to accommodate the addition.
469
470 =cut
471 */
472
473 void
474 Perl_av_push(pTHX_ register AV *av, SV *val)
475 {             
476     MAGIC *mg;
477     if (!av)
478         return;
479     if (SvREADONLY(av))
480         Perl_croak(aTHX_ PL_no_modify);
481
482     if ((mg = SvTIED_mg((SV*)av, 'P'))) {
483         dSP;
484         PUSHSTACKi(PERLSI_MAGIC);
485         PUSHMARK(SP);
486         EXTEND(SP,2);
487         PUSHs(SvTIED_obj((SV*)av, mg));
488         PUSHs(val);
489         PUTBACK;
490         ENTER;
491         call_method("PUSH", G_SCALAR|G_DISCARD);
492         LEAVE;
493         POPSTACK;
494         return;
495     }
496     av_store(av,AvFILLp(av)+1,val);
497 }
498
499 /*
500 =for apidoc av_pop
501
502 Pops an SV off the end of the array.  Returns C<&PL_sv_undef> if the array
503 is empty.
504
505 =cut
506 */
507
508 SV *
509 Perl_av_pop(pTHX_ register AV *av)
510 {
511     SV *retval;
512     MAGIC* mg;
513
514     if (!av || AvFILL(av) < 0)
515         return &PL_sv_undef;
516     if (SvREADONLY(av))
517         Perl_croak(aTHX_ PL_no_modify);
518     if ((mg = SvTIED_mg((SV*)av, 'P'))) {
519         dSP;    
520         PUSHSTACKi(PERLSI_MAGIC);
521         PUSHMARK(SP);
522         XPUSHs(SvTIED_obj((SV*)av, mg));
523         PUTBACK;
524         ENTER;
525         if (call_method("POP", G_SCALAR)) {
526             retval = newSVsv(*PL_stack_sp--);    
527         } else {    
528             retval = &PL_sv_undef;
529         }
530         LEAVE;
531         POPSTACK;
532         return retval;
533     }
534     retval = AvARRAY(av)[AvFILLp(av)];
535     AvARRAY(av)[AvFILLp(av)--] = &PL_sv_undef;
536     if (SvSMAGICAL(av))
537         mg_set((SV*)av);
538     return retval;
539 }
540
541 /*
542 =for apidoc av_unshift
543
544 Unshift the given number of C<undef> values onto the beginning of the
545 array.  The array will grow automatically to accommodate the addition.  You
546 must then use C<av_store> to assign values to these new elements.
547
548 =cut
549 */
550
551 void
552 Perl_av_unshift(pTHX_ register AV *av, register I32 num)
553 {
554     register I32 i;
555     register SV **ary;
556     MAGIC* mg;
557
558     if (!av || num <= 0)
559         return;
560     if (SvREADONLY(av))
561         Perl_croak(aTHX_ PL_no_modify);
562
563     if ((mg = SvTIED_mg((SV*)av, 'P'))) {
564         dSP;
565         PUSHSTACKi(PERLSI_MAGIC);
566         PUSHMARK(SP);
567         EXTEND(SP,1+num);
568         PUSHs(SvTIED_obj((SV*)av, mg));
569         while (num-- > 0) {
570             PUSHs(&PL_sv_undef);
571         }
572         PUTBACK;
573         ENTER;
574         call_method("UNSHIFT", G_SCALAR|G_DISCARD);
575         LEAVE;
576         POPSTACK;
577         return;
578     }
579
580     if (!AvREAL(av) && AvREIFY(av))
581         av_reify(av);
582     i = AvARRAY(av) - AvALLOC(av);
583     if (i) {
584         if (i > num)
585             i = num;
586         num -= i;
587     
588         AvMAX(av) += i;
589         AvFILLp(av) += i;
590         SvPVX(av) = (char*)(AvARRAY(av) - i);
591     }
592     if (num) {
593         i = AvFILLp(av);
594         av_extend(av, i + num);
595         AvFILLp(av) += num;
596         ary = AvARRAY(av);
597         Move(ary, ary + num, i + 1, SV*);
598         do {
599             ary[--num] = &PL_sv_undef;
600         } while (num);
601     }
602 }
603
604 /*
605 =for apidoc av_shift
606
607 Shifts an SV off the beginning of the array.
608
609 =cut
610 */
611
612 SV *
613 Perl_av_shift(pTHX_ register AV *av)
614 {
615     SV *retval;
616     MAGIC* mg;
617
618     if (!av || AvFILL(av) < 0)
619         return &PL_sv_undef;
620     if (SvREADONLY(av))
621         Perl_croak(aTHX_ PL_no_modify);
622     if ((mg = SvTIED_mg((SV*)av, 'P'))) {
623         dSP;
624         PUSHSTACKi(PERLSI_MAGIC);
625         PUSHMARK(SP);
626         XPUSHs(SvTIED_obj((SV*)av, mg));
627         PUTBACK;
628         ENTER;
629         if (call_method("SHIFT", G_SCALAR)) {
630             retval = newSVsv(*PL_stack_sp--);            
631         } else {    
632             retval = &PL_sv_undef;
633         }     
634         LEAVE;
635         POPSTACK;
636         return retval;
637     }
638     retval = *AvARRAY(av);
639     if (AvREAL(av))
640         *AvARRAY(av) = &PL_sv_undef;
641     SvPVX(av) = (char*)(AvARRAY(av) + 1);
642     AvMAX(av)--;
643     AvFILLp(av)--;
644     if (SvSMAGICAL(av))
645         mg_set((SV*)av);
646     return retval;
647 }
648
649 /*
650 =for apidoc av_len
651
652 Returns the highest index in the array.  Returns -1 if the array is
653 empty.
654
655 =cut
656 */
657
658 I32
659 Perl_av_len(pTHX_ register AV *av)
660 {
661     return AvFILL(av);
662 }
663
664 void
665 Perl_av_fill(pTHX_ register AV *av, I32 fill)
666 {
667     MAGIC *mg;
668     if (!av)
669         Perl_croak(aTHX_ "panic: null array");
670     if (fill < 0)
671         fill = -1;
672     if ((mg = SvTIED_mg((SV*)av, 'P'))) {
673         dSP;            
674         ENTER;
675         SAVETMPS;
676         PUSHSTACKi(PERLSI_MAGIC);
677         PUSHMARK(SP);
678         EXTEND(SP,2);
679         PUSHs(SvTIED_obj((SV*)av, mg));
680         PUSHs(sv_2mortal(newSViv(fill+1)));
681         PUTBACK;
682         call_method("STORESIZE", G_SCALAR|G_DISCARD);
683         POPSTACK;
684         FREETMPS;
685         LEAVE;
686         return;
687     }
688     if (fill <= AvMAX(av)) {
689         I32 key = AvFILLp(av);
690         SV** ary = AvARRAY(av);
691
692         if (AvREAL(av)) {
693             while (key > fill) {
694                 SvREFCNT_dec(ary[key]);
695                 ary[key--] = &PL_sv_undef;
696             }
697         }
698         else {
699             while (key < fill)
700                 ary[++key] = &PL_sv_undef;
701         }
702             
703         AvFILLp(av) = fill;
704         if (SvSMAGICAL(av))
705             mg_set((SV*)av);
706     }
707     else
708         (void)av_store(av,fill,&PL_sv_undef);
709 }
710
711 SV *
712 Perl_av_delete(pTHX_ AV *av, I32 key, I32 flags)
713 {
714     SV *sv;
715
716     if (!av)
717         return Nullsv;
718     if (SvREADONLY(av))
719         Perl_croak(aTHX_ PL_no_modify);
720     if (key < 0) {
721         key += AvFILL(av) + 1;
722         if (key < 0)
723             return Nullsv;
724     }
725     if (SvRMAGICAL(av)) {
726         SV **svp;
727         if ((mg_find((SV*)av,'P') || mg_find((SV*)av,'D'))
728             && (svp = av_fetch(av, key, TRUE)))
729         {
730             sv = *svp;
731             mg_clear(sv);
732             if (mg_find(sv, 'p')) {
733                 sv_unmagic(sv, 'p');            /* No longer an element */
734                 return sv;
735             }
736             return Nullsv;                      /* element cannot be deleted */
737         }
738     }
739     if (key > AvFILLp(av))
740         return Nullsv;
741     else {
742         sv = AvARRAY(av)[key];
743         if (key == AvFILLp(av)) {
744             do {
745                 AvFILLp(av)--;
746             } while (--key >= 0 && AvARRAY(av)[key] == &PL_sv_undef);
747         }
748         else
749             AvARRAY(av)[key] = &PL_sv_undef;
750         if (SvSMAGICAL(av))
751             mg_set((SV*)av);
752     }
753     if (flags & G_DISCARD) {
754         SvREFCNT_dec(sv);
755         sv = Nullsv;
756     }
757     return sv;
758 }
759
760 /*
761  * This relies on the fact that uninitialized array elements
762  * are set to &PL_sv_undef.
763  */
764
765 bool
766 Perl_av_exists(pTHX_ AV *av, I32 key)
767 {
768     if (!av)
769         return FALSE;
770     if (key < 0) {
771         key += AvFILL(av) + 1;
772         if (key < 0)
773             return FALSE;
774     }
775     if (SvRMAGICAL(av)) {
776         if (mg_find((SV*)av,'P') || mg_find((SV*)av,'D')) {
777             SV *sv = sv_newmortal();
778             mg_copy((SV*)av, sv, 0, key);
779             magic_existspack(sv, mg_find(sv, 'p'));
780             return SvTRUE(sv);
781         }
782     }
783     if (key <= AvFILLp(av) && AvARRAY(av)[key] != &PL_sv_undef
784         && AvARRAY(av)[key])
785     {
786         return TRUE;
787     }
788     else
789         return FALSE;
790 }
791
792 /* AVHV: Support for treating arrays as if they were hashes.  The
793  * first element of the array should be a hash reference that maps
794  * hash keys to array indices.
795  */
796
797 STATIC I32
798 S_avhv_index_sv(pTHX_ SV* sv)
799 {
800     I32 index = SvIV(sv);
801     if (index < 1)
802         Perl_croak(aTHX_ "Bad index while coercing array into hash");
803     return index;    
804 }
805
806 STATIC I32
807 S_avhv_index(pTHX_ AV *av, SV *keysv, U32 hash)
808 {
809     HV *keys;
810     HE *he;
811     STRLEN n_a;
812
813     keys = avhv_keys(av);
814     he = hv_fetch_ent(keys, keysv, FALSE, hash);
815     if (!he)
816         Perl_croak(aTHX_ "No such pseudo-hash field \"%s\"", SvPV(keysv,n_a));
817     return avhv_index_sv(HeVAL(he));
818 }
819
820 HV*
821 Perl_avhv_keys(pTHX_ AV *av)
822 {
823     SV **keysp = av_fetch(av, 0, FALSE);
824     if (keysp) {
825         SV *sv = *keysp;
826         if (SvGMAGICAL(sv))
827             mg_get(sv);
828         if (SvROK(sv)) {
829             sv = SvRV(sv);
830             if (SvTYPE(sv) == SVt_PVHV)
831                 return (HV*)sv;
832         }
833     }
834     Perl_croak(aTHX_ "Can't coerce array into hash");
835     return Nullhv;
836 }
837
838 SV**
839 Perl_avhv_store_ent(pTHX_ AV *av, SV *keysv, SV *val, U32 hash)
840 {
841     return av_store(av, avhv_index(av, keysv, hash), val);
842 }
843
844 SV**
845 Perl_avhv_fetch_ent(pTHX_ AV *av, SV *keysv, I32 lval, U32 hash)
846 {
847     return av_fetch(av, avhv_index(av, keysv, hash), lval);
848 }
849
850 SV *
851 Perl_avhv_delete_ent(pTHX_ AV *av, SV *keysv, I32 flags, U32 hash)
852 {
853     HV *keys = avhv_keys(av);
854     HE *he;
855         
856     he = hv_fetch_ent(keys, keysv, FALSE, hash);
857     if (!he || !SvOK(HeVAL(he)))
858         return Nullsv;
859
860     return av_delete(av, avhv_index_sv(HeVAL(he)), flags);
861 }
862
863 /* Check for the existence of an element named by a given key.
864  *
865  */
866 bool
867 Perl_avhv_exists_ent(pTHX_ AV *av, SV *keysv, U32 hash)
868 {
869     HV *keys = avhv_keys(av);
870     HE *he;
871         
872     he = hv_fetch_ent(keys, keysv, FALSE, hash);
873     if (!he || !SvOK(HeVAL(he)))
874         return FALSE;
875
876     return av_exists(av, avhv_index_sv(HeVAL(he)));
877 }
878
879 HE *
880 Perl_avhv_iternext(pTHX_ AV *av)
881 {
882     HV *keys = avhv_keys(av);
883     return hv_iternext(keys);
884 }
885
886 SV *
887 Perl_avhv_iterval(pTHX_ AV *av, register HE *entry)
888 {
889     SV *sv = hv_iterval(avhv_keys(av), entry);
890     return *av_fetch(av, avhv_index_sv(sv), TRUE);
891 }