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