This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Grow zero length scalars
[perl5.git] / scope.c
1 /*    scope.c
2  *
3  *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
4  *    2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by Larry Wall and others
5  *
6  *    You may distribute under the terms of either the GNU General Public
7  *    License or the Artistic License, as specified in the README file.
8  *
9  */
10
11 /*
12  * For the fashion of Minas Tirith was such that it was built on seven
13  * levels...
14  *
15  *     [p.751 of _The Lord of the Rings_, V/i: "Minas Tirith"]
16  */
17
18 /* This file contains functions to manipulate several of Perl's stacks;
19  * in particular it contains code to push various types of things onto
20  * the savestack, then to pop them off and perform the correct restorative
21  * action for each one. This corresponds to the cleanup Perl does at
22  * each scope exit.
23  */
24
25 #include "EXTERN.h"
26 #define PERL_IN_SCOPE_C
27 #include "perl.h"
28
29 SV**
30 Perl_stack_grow(pTHX_ SV **sp, SV **p, int n)
31 {
32     dVAR;
33
34     PERL_ARGS_ASSERT_STACK_GROW;
35
36     PL_stack_sp = sp;
37 #ifndef STRESS_REALLOC
38     av_extend(PL_curstack, (p - PL_stack_base) + (n) + 128);
39 #else
40     av_extend(PL_curstack, (p - PL_stack_base) + (n) + 1);
41 #endif
42     return PL_stack_sp;
43 }
44
45 #ifndef STRESS_REALLOC
46 #define GROW(old) ((old) * 3 / 2)
47 #else
48 #define GROW(old) ((old) + 1)
49 #endif
50
51 PERL_SI *
52 Perl_new_stackinfo(pTHX_ I32 stitems, I32 cxitems)
53 {
54     dVAR;
55     PERL_SI *si;
56     Newx(si, 1, PERL_SI);
57     si->si_stack = newAV();
58     AvREAL_off(si->si_stack);
59     av_extend(si->si_stack, stitems > 0 ? stitems-1 : 0);
60     AvALLOC(si->si_stack)[0] = &PL_sv_undef;
61     AvFILLp(si->si_stack) = 0;
62     si->si_prev = 0;
63     si->si_next = 0;
64     si->si_cxmax = cxitems - 1;
65     si->si_cxix = -1;
66     si->si_type = PERLSI_UNDEF;
67     Newx(si->si_cxstack, cxitems, PERL_CONTEXT);
68     /* Without any kind of initialising PUSHSUBST()
69      * in pp_subst() will read uninitialised heap. */
70     PoisonNew(si->si_cxstack, cxitems, PERL_CONTEXT);
71     return si;
72 }
73
74 I32
75 Perl_cxinc(pTHX)
76 {
77     dVAR;
78     const IV old_max = cxstack_max;
79     cxstack_max = GROW(cxstack_max);
80     Renew(cxstack, cxstack_max + 1, PERL_CONTEXT);      /* XXX should fix CXINC macro */
81     /* Without any kind of initialising deep enough recursion
82      * will end up reading uninitialised PERL_CONTEXTs. */
83     PoisonNew(cxstack + old_max + 1, cxstack_max - old_max, PERL_CONTEXT);
84     return cxstack_ix + 1;
85 }
86
87 void
88 Perl_push_scope(pTHX)
89 {
90     dVAR;
91     if (PL_scopestack_ix == PL_scopestack_max) {
92         PL_scopestack_max = GROW(PL_scopestack_max);
93         Renew(PL_scopestack, PL_scopestack_max, I32);
94     }
95     PL_scopestack[PL_scopestack_ix++] = PL_savestack_ix;
96
97 }
98
99 void
100 Perl_pop_scope(pTHX)
101 {
102     dVAR;
103     const I32 oldsave = PL_scopestack[--PL_scopestack_ix];
104     LEAVE_SCOPE(oldsave);
105 }
106
107 void
108 Perl_markstack_grow(pTHX)
109 {
110     dVAR;
111     const I32 oldmax = PL_markstack_max - PL_markstack;
112     const I32 newmax = GROW(oldmax);
113
114     Renew(PL_markstack, newmax, I32);
115     PL_markstack_ptr = PL_markstack + oldmax;
116     PL_markstack_max = PL_markstack + newmax;
117 }
118
119 void
120 Perl_savestack_grow(pTHX)
121 {
122     dVAR;
123     PL_savestack_max = GROW(PL_savestack_max) + 4;
124     Renew(PL_savestack, PL_savestack_max, ANY);
125 }
126
127 void
128 Perl_savestack_grow_cnt(pTHX_ I32 need)
129 {
130     dVAR;
131     PL_savestack_max = PL_savestack_ix + need;
132     Renew(PL_savestack, PL_savestack_max, ANY);
133 }
134
135 #undef GROW
136
137 void
138 Perl_tmps_grow(pTHX_ I32 n)
139 {
140     dVAR;
141 #ifndef STRESS_REALLOC
142     if (n < 128)
143         n = (PL_tmps_max < 512) ? 128 : 512;
144 #endif
145     PL_tmps_max = PL_tmps_ix + n + 1;
146     Renew(PL_tmps_stack, PL_tmps_max, SV*);
147 }
148
149
150 void
151 Perl_free_tmps(pTHX)
152 {
153     dVAR;
154     /* XXX should tmps_floor live in cxstack? */
155     const I32 myfloor = PL_tmps_floor;
156     while (PL_tmps_ix > myfloor) {      /* clean up after last statement */
157         SV* const sv = PL_tmps_stack[PL_tmps_ix];
158         PL_tmps_stack[PL_tmps_ix--] = NULL;
159         if (sv && sv != &PL_sv_undef) {
160             SvTEMP_off(sv);
161             SvREFCNT_dec(sv);           /* note, can modify tmps_ix!!! */
162         }
163     }
164 }
165
166 STATIC SV *
167 S_save_scalar_at(pTHX_ SV **sptr, const U32 flags)
168 {
169     dVAR;
170     SV * osv;
171     register SV *sv;
172
173     PERL_ARGS_ASSERT_SAVE_SCALAR_AT;
174
175     osv = *sptr;
176     sv  = (flags & SAVEf_KEEPOLDELEM) ? osv : (*sptr = newSV(0));
177
178     if (SvTYPE(osv) >= SVt_PVMG && SvMAGIC(osv) && SvTYPE(osv) != SVt_PVGV) {
179         if (SvGMAGICAL(osv)) {
180             const bool oldtainted = PL_tainted;
181             SvFLAGS(osv) |= (SvFLAGS(osv) &
182                (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
183             PL_tainted = oldtainted;
184         }
185         if (!(flags & SAVEf_KEEPOLDELEM))
186             mg_localize(osv, sv, (flags & SAVEf_SETMAGIC) != 0);
187     }
188
189     return sv;
190 }
191
192 void
193 Perl_save_pushptrptr(pTHX_ void *const ptr1, void *const ptr2, const int type)
194 {
195     dVAR;
196     SSCHECK(3);
197     SSPUSHPTR(ptr1);
198     SSPUSHPTR(ptr2);
199     SSPUSHINT(type);
200 }
201
202 SV *
203 Perl_save_scalar(pTHX_ GV *gv)
204 {
205     dVAR;
206     SV ** const sptr = &GvSVn(gv);
207
208     PERL_ARGS_ASSERT_SAVE_SCALAR;
209
210     PL_localizing = 1;
211     SvGETMAGIC(*sptr);
212     PL_localizing = 0;
213     save_pushptrptr(SvREFCNT_inc_simple(gv), SvREFCNT_inc(*sptr), SAVEt_SV);
214     return save_scalar_at(sptr, SAVEf_SETMAGIC); /* XXX - FIXME - see #60360 */
215 }
216
217 /* Like save_sptr(), but also SvREFCNT_dec()s the new value.  Can be used to
218  * restore a global SV to its prior contents, freeing new value. */
219 void
220 Perl_save_generic_svref(pTHX_ SV **sptr)
221 {
222     dVAR;
223
224     PERL_ARGS_ASSERT_SAVE_GENERIC_SVREF;
225
226     save_pushptrptr(sptr, SvREFCNT_inc(*sptr), SAVEt_GENERIC_SVREF);
227 }
228
229 /* Like save_pptr(), but also Safefree()s the new value if it is different
230  * from the old one.  Can be used to restore a global char* to its prior
231  * contents, freeing new value. */
232 void
233 Perl_save_generic_pvref(pTHX_ char **str)
234 {
235     dVAR;
236
237     PERL_ARGS_ASSERT_SAVE_GENERIC_PVREF;
238
239     save_pushptrptr(*str, str, SAVEt_GENERIC_PVREF);
240 }
241
242 /* Like save_generic_pvref(), but uses PerlMemShared_free() rather than Safefree().
243  * Can be used to restore a shared global char* to its prior
244  * contents, freeing new value. */
245 void
246 Perl_save_shared_pvref(pTHX_ char **str)
247 {
248     dVAR;
249
250     PERL_ARGS_ASSERT_SAVE_SHARED_PVREF;
251
252     save_pushptrptr(str, *str, SAVEt_SHARED_PVREF);
253 }
254
255 /* set the SvFLAGS specified by mask to the values in val */
256
257 void
258 Perl_save_set_svflags(pTHX_ SV* sv, U32 mask, U32 val)
259 {
260     dVAR;
261
262     PERL_ARGS_ASSERT_SAVE_SET_SVFLAGS;
263
264     SSCHECK(4);
265     SSPUSHPTR(sv);
266     SSPUSHINT(mask);
267     SSPUSHINT(val);
268     SSPUSHINT(SAVEt_SET_SVFLAGS);
269 }
270
271 void
272 Perl_save_gp(pTHX_ GV *gv, I32 empty)
273 {
274     dVAR;
275
276     PERL_ARGS_ASSERT_SAVE_GP;
277
278     save_pushptrptr(SvREFCNT_inc(gv), GvGP(gv), SAVEt_GP);
279
280     if (empty) {
281         GP *gp = Perl_newGP(aTHX_ gv);
282
283         if (GvCVu(gv))
284             mro_method_changed_in(GvSTASH(gv)); /* taking a method out of circulation ("local")*/
285         if (GvIOp(gv) && (IoFLAGS(GvIOp(gv)) & IOf_ARGV)) {
286             gp->gp_io = newIO();
287             IoFLAGS(gp->gp_io) |= IOf_ARGV|IOf_START;
288         }
289 #ifdef PERL_DONT_CREATE_GVSV
290         if (gv == PL_errgv) {
291             /* We could scatter this logic everywhere by changing the
292                definition of ERRSV from GvSV() to GvSVn(), but it seems more
293                efficient to do this check once here.  */
294             gp->gp_sv = newSV(0);
295         }
296 #endif
297         GvGP(gv) = gp;
298     }
299     else {
300         gp_ref(GvGP(gv));
301         GvINTRO_on(gv);
302     }
303 }
304
305 AV *
306 Perl_save_ary(pTHX_ GV *gv)
307 {
308     dVAR;
309     AV * const oav = GvAVn(gv);
310     AV *av;
311
312     PERL_ARGS_ASSERT_SAVE_ARY;
313
314     if (!AvREAL(oav) && AvREIFY(oav))
315         av_reify(oav);
316     save_pushptrptr(gv, oav, SAVEt_AV);
317
318     GvAV(gv) = NULL;
319     av = GvAVn(gv);
320     if (SvMAGIC(oav))
321         mg_localize(MUTABLE_SV(oav), MUTABLE_SV(av), TRUE);
322     return av;
323 }
324
325 HV *
326 Perl_save_hash(pTHX_ GV *gv)
327 {
328     dVAR;
329     HV *ohv, *hv;
330
331     PERL_ARGS_ASSERT_SAVE_HASH;
332
333     save_pushptrptr(gv, (ohv = GvHVn(gv)), SAVEt_HV);
334
335     GvHV(gv) = NULL;
336     hv = GvHVn(gv);
337     if (SvMAGIC(ohv))
338         mg_localize(MUTABLE_SV(ohv), MUTABLE_SV(hv), TRUE);
339     return hv;
340 }
341
342 void
343 Perl_save_item(pTHX_ register SV *item)
344 {
345     dVAR;
346     register SV * const sv = newSVsv(item);
347
348     PERL_ARGS_ASSERT_SAVE_ITEM;
349
350     save_pushptrptr(item, /* remember the pointer */
351                     sv,   /* remember the value */
352                     SAVEt_ITEM);
353 }
354
355 void
356 Perl_save_bool(pTHX_ bool *boolp)
357 {
358     dVAR;
359
360     PERL_ARGS_ASSERT_SAVE_BOOL;
361
362     SSCHECK(3);
363     SSPUSHBOOL(*boolp);
364     SSPUSHPTR(boolp);
365     SSPUSHINT(SAVEt_BOOL);
366 }
367
368 void
369 Perl_save_pushi32ptr(pTHX_ const I32 i, void *const ptr, const int type)
370 {
371     dVAR;
372     SSCHECK(3);
373     SSPUSHINT(i);
374     SSPUSHPTR(ptr);
375     SSPUSHINT(type);
376 }
377
378 void
379 Perl_save_int(pTHX_ int *intp)
380 {
381     dVAR;
382
383     PERL_ARGS_ASSERT_SAVE_INT;
384
385     save_pushi32ptr(*intp, intp, SAVEt_INT);
386 }
387
388 void
389 Perl_save_I8(pTHX_ I8 *bytep)
390 {
391     dVAR;
392
393     PERL_ARGS_ASSERT_SAVE_I8;
394
395     save_pushi32ptr(*bytep, bytep, SAVEt_I8);
396 }
397
398 void
399 Perl_save_I16(pTHX_ I16 *intp)
400 {
401     dVAR;
402
403     PERL_ARGS_ASSERT_SAVE_I16;
404
405     save_pushi32ptr(*intp, intp, SAVEt_I16);
406 }
407
408 void
409 Perl_save_I32(pTHX_ I32 *intp)
410 {
411     dVAR;
412
413     PERL_ARGS_ASSERT_SAVE_I32;
414
415     save_pushi32ptr(*intp, intp, SAVEt_I32);
416 }
417
418 /* Cannot use save_sptr() to store a char* since the SV** cast will
419  * force word-alignment and we'll miss the pointer.
420  */
421 void
422 Perl_save_pptr(pTHX_ char **pptr)
423 {
424     dVAR;
425
426     PERL_ARGS_ASSERT_SAVE_PPTR;
427
428     save_pushptrptr(*pptr, pptr, SAVEt_PPTR);
429 }
430
431 void
432 Perl_save_vptr(pTHX_ void *ptr)
433 {
434     dVAR;
435
436     PERL_ARGS_ASSERT_SAVE_VPTR;
437
438     save_pushptrptr(*(char**)ptr, ptr, SAVEt_VPTR);
439 }
440
441 void
442 Perl_save_sptr(pTHX_ SV **sptr)
443 {
444     dVAR;
445
446     PERL_ARGS_ASSERT_SAVE_SPTR;
447
448     save_pushptrptr(*sptr, sptr, SAVEt_SPTR);
449 }
450
451 void
452 Perl_save_padsv_and_mortalize(pTHX_ PADOFFSET off)
453 {
454     dVAR;
455     SSCHECK(4);
456     ASSERT_CURPAD_ACTIVE("save_padsv");
457     SSPUSHPTR(SvREFCNT_inc_simple_NN(PL_curpad[off]));
458     SSPUSHPTR(PL_comppad);
459     SSPUSHLONG((long)off);
460     SSPUSHINT(SAVEt_PADSV_AND_MORTALIZE);
461 }
462
463 void
464 Perl_save_hptr(pTHX_ HV **hptr)
465 {
466     dVAR;
467
468     PERL_ARGS_ASSERT_SAVE_HPTR;
469
470     save_pushptrptr(*hptr, hptr, SAVEt_HPTR);
471 }
472
473 void
474 Perl_save_aptr(pTHX_ AV **aptr)
475 {
476     dVAR;
477
478     PERL_ARGS_ASSERT_SAVE_APTR;
479
480     save_pushptrptr(*aptr, aptr, SAVEt_APTR);
481 }
482
483 void
484 Perl_save_pushptr(pTHX_ void *const ptr, const int type)
485 {
486     dVAR;
487     SSCHECK(2);
488     SSPUSHPTR(ptr);
489     SSPUSHINT(type);
490 }
491
492 void
493 Perl_save_clearsv(pTHX_ SV **svp)
494 {
495     dVAR;
496
497     PERL_ARGS_ASSERT_SAVE_CLEARSV;
498
499     ASSERT_CURPAD_ACTIVE("save_clearsv");
500     SSCHECK(2);
501     SSPUSHLONG((long)(svp-PL_curpad));
502     SSPUSHINT(SAVEt_CLEARSV);
503     SvPADSTALE_off(*svp); /* mark lexical as active */
504 }
505
506 void
507 Perl_save_delete(pTHX_ HV *hv, char *key, I32 klen)
508 {
509     dVAR;
510
511     PERL_ARGS_ASSERT_SAVE_DELETE;
512
513     save_pushptri32ptr(key, klen, SvREFCNT_inc_simple(hv), SAVEt_DELETE);
514 }
515
516 void
517 Perl_save_hdelete(pTHX_ HV *hv, SV *keysv)
518 {
519     STRLEN len;
520     I32 klen;
521     const char *key;
522
523     PERL_ARGS_ASSERT_SAVE_HDELETE;
524
525     key  = SvPV_const(keysv, len);
526     klen = SvUTF8(keysv) ? -(I32)len : (I32)len;
527     SvREFCNT_inc_simple_void_NN(hv);
528     save_pushptri32ptr(savepvn(key, len), klen, hv, SAVEt_DELETE);
529 }
530
531 void
532 Perl_save_adelete(pTHX_ AV *av, I32 key)
533 {
534     dVAR;
535
536     PERL_ARGS_ASSERT_SAVE_ADELETE;
537
538     SvREFCNT_inc_void(av);
539     save_pushi32ptr(key, av, SAVEt_ADELETE);
540 }
541
542 void
543 Perl_save_destructor(pTHX_ DESTRUCTORFUNC_NOCONTEXT_t f, void* p)
544 {
545     dVAR;
546
547     PERL_ARGS_ASSERT_SAVE_DESTRUCTOR;
548
549     SSCHECK(3);
550     SSPUSHDPTR(f);
551     SSPUSHPTR(p);
552     SSPUSHINT(SAVEt_DESTRUCTOR);
553 }
554
555 void
556 Perl_save_destructor_x(pTHX_ DESTRUCTORFUNC_t f, void* p)
557 {
558     dVAR;
559     SSCHECK(3);
560     SSPUSHDXPTR(f);
561     SSPUSHPTR(p);
562     SSPUSHINT(SAVEt_DESTRUCTOR_X);
563 }
564
565 void
566 Perl_save_hints(pTHX)
567 {
568     dVAR;
569     if (PL_compiling.cop_hints_hash) {
570         HINTS_REFCNT_LOCK;
571             PL_compiling.cop_hints_hash->refcounted_he_refcnt++;
572             HINTS_REFCNT_UNLOCK;
573     }
574     if (PL_hints & HINT_LOCALIZE_HH) {
575         save_pushptri32ptr(GvHV(PL_hintgv), PL_hints,
576                            PL_compiling.cop_hints_hash, SAVEt_HINTS);
577         GvHV(PL_hintgv) = Perl_hv_copy_hints_hv(aTHX_ GvHV(PL_hintgv));
578     } else {
579         save_pushi32ptr(PL_hints, PL_compiling.cop_hints_hash, SAVEt_HINTS);
580     }
581 }
582
583 static void
584 S_save_pushptri32ptr(pTHX_ void *const ptr1, const I32 i, void *const ptr2,
585                         const int type)
586 {
587     SSCHECK(4);
588     SSPUSHPTR(ptr1);
589     SSPUSHINT(i);
590     SSPUSHPTR(ptr2);
591     SSPUSHINT(type);
592 }
593
594 void
595 Perl_save_aelem_flags(pTHX_ AV *av, I32 idx, SV **sptr, const U32 flags)
596 {
597     dVAR;
598     SV *sv;
599
600     PERL_ARGS_ASSERT_SAVE_AELEM_FLAGS;
601
602     SvGETMAGIC(*sptr);
603     save_pushptri32ptr(SvREFCNT_inc_simple(av), idx, SvREFCNT_inc(*sptr),
604                        SAVEt_AELEM);
605     /* if it gets reified later, the restore will have the wrong refcnt */
606     if (!AvREAL(av) && AvREIFY(av))
607         SvREFCNT_inc_void(*sptr);
608     save_scalar_at(sptr, flags); /* XXX - FIXME - see #60360 */
609     if (flags & SAVEf_KEEPOLDELEM)
610         return;
611     sv = *sptr;
612     /* If we're localizing a tied array element, this new sv
613      * won't actually be stored in the array - so it won't get
614      * reaped when the localize ends. Ensure it gets reaped by
615      * mortifying it instead. DAPM */
616     if (SvTIED_mg(sv, PERL_MAGIC_tiedelem))
617         sv_2mortal(sv);
618 }
619
620 void
621 Perl_save_helem_flags(pTHX_ HV *hv, SV *key, SV **sptr, const U32 flags)
622 {
623     dVAR;
624     SV *sv;
625
626     PERL_ARGS_ASSERT_SAVE_HELEM_FLAGS;
627
628     SvGETMAGIC(*sptr);
629     SSCHECK(4);
630     SSPUSHPTR(SvREFCNT_inc_simple(hv));
631     SSPUSHPTR(newSVsv(key));
632     SSPUSHPTR(SvREFCNT_inc(*sptr));
633     SSPUSHINT(SAVEt_HELEM);
634     save_scalar_at(sptr, flags);
635     if (flags & SAVEf_KEEPOLDELEM)
636         return;
637     sv = *sptr;
638     /* If we're localizing a tied hash element, this new sv
639      * won't actually be stored in the hash - so it won't get
640      * reaped when the localize ends. Ensure it gets reaped by
641      * mortifying it instead. DAPM */
642     if (SvTIED_mg(sv, PERL_MAGIC_tiedelem))
643         sv_2mortal(sv);
644 }
645
646 SV*
647 Perl_save_svref(pTHX_ SV **sptr)
648 {
649     dVAR;
650
651     PERL_ARGS_ASSERT_SAVE_SVREF;
652
653     SvGETMAGIC(*sptr);
654     save_pushptrptr(sptr, SvREFCNT_inc(*sptr), SAVEt_SVREF);
655     return save_scalar_at(sptr, SAVEf_SETMAGIC); /* XXX - FIXME - see #60360 */
656 }
657
658 I32
659 Perl_save_alloc(pTHX_ I32 size, I32 pad)
660 {
661     dVAR;
662     register const I32 start = pad + ((char*)&PL_savestack[PL_savestack_ix]
663                                 - (char*)PL_savestack);
664     register const I32 elems = 1 + ((size + pad - 1) / sizeof(*PL_savestack));
665
666     SSGROW(elems + 2);
667
668     PL_savestack_ix += elems;
669     SSPUSHINT(elems);
670     SSPUSHINT(SAVEt_ALLOC);
671     return start;
672 }
673
674 void
675 Perl_leave_scope(pTHX_ I32 base)
676 {
677     dVAR;
678     register SV *sv;
679     register SV *value;
680     register GV *gv;
681     register AV *av;
682     register HV *hv;
683     void* ptr;
684     register char* str;
685     I32 i;
686     /* Localise the effects of the TAINT_NOT inside the loop.  */
687     const bool was = PL_tainted;
688
689     if (base < -1)
690         Perl_croak(aTHX_ "panic: corrupt saved stack index");
691     while (PL_savestack_ix > base) {
692         TAINT_NOT;
693
694         switch (SSPOPINT) {
695         case SAVEt_ITEM:                        /* normal string */
696             value = MUTABLE_SV(SSPOPPTR);
697             sv = MUTABLE_SV(SSPOPPTR);
698             sv_replace(sv,value);
699             PL_localizing = 2;
700             SvSETMAGIC(sv);
701             PL_localizing = 0;
702             break;
703         case SAVEt_SV:                          /* scalar reference */
704             value = MUTABLE_SV(SSPOPPTR);
705             gv = MUTABLE_GV(SSPOPPTR);
706             ptr = &GvSV(gv);
707             av = MUTABLE_AV(gv); /* what to refcnt_dec */
708         restore_sv:
709             sv = *(SV**)ptr;
710             *(SV**)ptr = value;
711             SvREFCNT_dec(sv);
712             PL_localizing = 2;
713             SvSETMAGIC(value);
714             PL_localizing = 0;
715             SvREFCNT_dec(value);
716             if (av) /* actually an av, hv or gv */
717                 SvREFCNT_dec(av);
718             break;
719         case SAVEt_GENERIC_PVREF:               /* generic pv */
720             ptr = SSPOPPTR;
721             str = (char*)SSPOPPTR;
722             if (*(char**)ptr != str) {
723                 Safefree(*(char**)ptr);
724                 *(char**)ptr = str;
725             }
726             break;
727         case SAVEt_SHARED_PVREF:                /* shared pv */
728             str = (char*)SSPOPPTR;
729             ptr = SSPOPPTR;
730             if (*(char**)ptr != str) {
731 #ifdef NETWARE
732                 PerlMem_free(*(char**)ptr);
733 #else
734                 PerlMemShared_free(*(char**)ptr);
735 #endif
736                 *(char**)ptr = str;
737             }
738             break;
739         case SAVEt_GENERIC_SVREF:               /* generic sv */
740             value = MUTABLE_SV(SSPOPPTR);
741             ptr = SSPOPPTR;
742             sv = *(SV**)ptr;
743             *(SV**)ptr = value;
744             SvREFCNT_dec(sv);
745             SvREFCNT_dec(value);
746             break;
747         case SAVEt_AV:                          /* array reference */
748             av = MUTABLE_AV(SSPOPPTR);
749             gv = MUTABLE_GV(SSPOPPTR);
750             SvREFCNT_dec(GvAV(gv));
751             GvAV(gv) = av;
752             if (SvMAGICAL(av)) {
753                 PL_localizing = 2;
754                 SvSETMAGIC(MUTABLE_SV(av));
755                 PL_localizing = 0;
756             }
757             break;
758         case SAVEt_HV:                          /* hash reference */
759             hv = MUTABLE_HV(SSPOPPTR);
760             gv = MUTABLE_GV(SSPOPPTR);
761             SvREFCNT_dec(GvHV(gv));
762             GvHV(gv) = hv;
763             if (SvMAGICAL(hv)) {
764                 PL_localizing = 2;
765                 SvSETMAGIC(MUTABLE_SV(hv));
766                 PL_localizing = 0;
767             }
768             break;
769         case SAVEt_INT:                         /* int reference */
770             ptr = SSPOPPTR;
771             *(int*)ptr = (int)SSPOPINT;
772             break;
773         case SAVEt_BOOL:                        /* bool reference */
774             ptr = SSPOPPTR;
775             *(bool*)ptr = (bool)SSPOPBOOL;
776             break;
777         case SAVEt_I32:                         /* I32 reference */
778             ptr = SSPOPPTR;
779 #ifdef PERL_DEBUG_READONLY_OPS
780             {
781                 const I32 val = SSPOPINT;
782                 if (*(I32*)ptr != val)
783                     *(I32*)ptr = val;
784             }
785 #else
786             *(I32*)ptr = (I32)SSPOPINT;
787 #endif
788             break;
789         case SAVEt_SPTR:                        /* SV* reference */
790             ptr = SSPOPPTR;
791             *(SV**)ptr = MUTABLE_SV(SSPOPPTR);
792             break;
793         case SAVEt_VPTR:                        /* random* reference */
794         case SAVEt_PPTR:                        /* char* reference */
795             ptr = SSPOPPTR;
796             *(char**)ptr = (char*)SSPOPPTR;
797             break;
798         case SAVEt_HPTR:                        /* HV* reference */
799             ptr = SSPOPPTR;
800             *(HV**)ptr = MUTABLE_HV(SSPOPPTR);
801             break;
802         case SAVEt_APTR:                        /* AV* reference */
803             ptr = SSPOPPTR;
804             *(AV**)ptr = MUTABLE_AV(SSPOPPTR);
805             break;
806         case SAVEt_GP:                          /* scalar reference */
807             ptr = SSPOPPTR;
808             gv = MUTABLE_GV(SSPOPPTR);
809             gp_free(gv);
810             GvGP(gv) = (GP*)ptr;
811             /* putting a method back into circulation ("local")*/
812             if (GvCVu(gv) && (hv=GvSTASH(gv)) && HvNAME_get(hv))
813                 mro_method_changed_in(hv);
814             SvREFCNT_dec(gv);
815             break;
816         case SAVEt_FREESV:
817             ptr = SSPOPPTR;
818             SvREFCNT_dec(MUTABLE_SV(ptr));
819             break;
820         case SAVEt_MORTALIZESV:
821             ptr = SSPOPPTR;
822             sv_2mortal(MUTABLE_SV(ptr));
823             break;
824         case SAVEt_FREEOP:
825             ptr = SSPOPPTR;
826             ASSERT_CURPAD_LEGAL("SAVEt_FREEOP"); /* XXX DAPM tmp */
827             op_free((OP*)ptr);
828             break;
829         case SAVEt_FREEPV:
830             ptr = SSPOPPTR;
831             Safefree(ptr);
832             break;
833         case SAVEt_CLEARSV:
834             ptr = (void*)&PL_curpad[SSPOPLONG];
835             sv = *(SV**)ptr;
836
837             DEBUG_Xv(PerlIO_printf(Perl_debug_log,
838              "Pad 0x%"UVxf"[0x%"UVxf"] clearsv: %ld sv=0x%"UVxf"<%"IVdf"> %s\n",
839                 PTR2UV(PL_comppad), PTR2UV(PL_curpad),
840                 (long)((SV **)ptr-PL_curpad), PTR2UV(sv), (IV)SvREFCNT(sv),
841                 (SvREFCNT(sv) <= 1 && !SvOBJECT(sv)) ? "clear" : "abandon"
842             ));
843
844             /* Can clear pad variable in place? */
845             if (SvREFCNT(sv) <= 1 && !SvOBJECT(sv)) {
846                 /*
847                  * if a my variable that was made readonly is going out of
848                  * scope, we want to remove the readonlyness so that it can
849                  * go out of scope quietly
850                  */
851                 if (SvPADMY(sv) && !SvFAKE(sv))
852                     SvREADONLY_off(sv);
853
854                 if (SvTHINKFIRST(sv))
855                     sv_force_normal_flags(sv, SV_IMMEDIATE_UNREF);
856                 if (SvMAGICAL(sv))
857                     mg_free(sv);
858
859                 switch (SvTYPE(sv)) {
860                 case SVt_NULL:
861                     break;
862                 case SVt_PVAV:
863                     av_clear(MUTABLE_AV(sv));
864                     break;
865                 case SVt_PVHV:
866                     hv_clear(MUTABLE_HV(sv));
867                     break;
868                 case SVt_PVCV:
869                     Perl_croak(aTHX_ "panic: leave_scope pad code");
870                 default:
871                     SvOK_off(sv);
872                     break;
873                 }
874                 SvPADSTALE_on(sv); /* mark as no longer live */
875             }
876             else {      /* Someone has a claim on this, so abandon it. */
877                 const U32 padflags = SvFLAGS(sv) & (SVs_PADMY|SVs_PADTMP);
878                 switch (SvTYPE(sv)) {   /* Console ourselves with a new value */
879                 case SVt_PVAV:  *(SV**)ptr = MUTABLE_SV(newAV());       break;
880                 case SVt_PVHV:  *(SV**)ptr = MUTABLE_SV(newHV());       break;
881                 default:        *(SV**)ptr = newSV(0);          break;
882                 }
883                 SvREFCNT_dec(sv);       /* Cast current value to the winds. */
884                 /* preserve pad nature, but also mark as not live
885                  * for any closure capturing */
886                 SvFLAGS(*(SV**)ptr) |= padflags | SVs_PADSTALE;
887             }
888             break;
889         case SAVEt_DELETE:
890             ptr = SSPOPPTR;
891             hv = MUTABLE_HV(ptr);
892             i = SSPOPINT;
893             ptr = SSPOPPTR;
894             (void)hv_delete(hv, (char*)ptr, i, G_DISCARD);
895             SvREFCNT_dec(hv);
896             Safefree(ptr);
897             break;
898         case SAVEt_ADELETE:
899             ptr = SSPOPPTR;
900             av = MUTABLE_AV(ptr);
901             i = SSPOPINT;
902             (void)av_delete(av, i, G_DISCARD);
903             SvREFCNT_dec(av);
904             break;
905         case SAVEt_DESTRUCTOR_X:
906             ptr = SSPOPPTR;
907             (*SSPOPDXPTR)(aTHX_ ptr);
908             break;
909         case SAVEt_REGCONTEXT:
910         case SAVEt_ALLOC:
911             i = SSPOPINT;
912             PL_savestack_ix -= i;       /* regexp must have croaked */
913             break;
914         case SAVEt_STACK_POS:           /* Position on Perl stack */
915             i = SSPOPINT;
916             PL_stack_sp = PL_stack_base + i;
917             break;
918         case SAVEt_STACK_CXPOS:         /* blk_oldsp on context stack */
919             i = SSPOPINT;
920             cxstack[i].blk_oldsp = SSPOPINT;
921             break;
922         case SAVEt_AELEM:               /* array element */
923             value = MUTABLE_SV(SSPOPPTR);
924             i = SSPOPINT;
925             av = MUTABLE_AV(SSPOPPTR);
926             ptr = av_fetch(av,i,1);
927             if (!AvREAL(av) && AvREIFY(av)) /* undo reify guard */
928                 SvREFCNT_dec(value);
929             if (ptr) {
930                 sv = *(SV**)ptr;
931                 if (sv && sv != &PL_sv_undef) {
932                     if (SvTIED_mg((const SV *)av, PERL_MAGIC_tied))
933                         SvREFCNT_inc_void_NN(sv);
934                     goto restore_sv;
935                 }
936             }
937             SvREFCNT_dec(av);
938             SvREFCNT_dec(value);
939             break;
940         case SAVEt_HELEM:               /* hash element */
941             value = MUTABLE_SV(SSPOPPTR);
942             sv = MUTABLE_SV(SSPOPPTR);
943             hv = MUTABLE_HV(SSPOPPTR);
944             ptr = hv_fetch_ent(hv, sv, 1, 0);
945             SvREFCNT_dec(sv);
946             if (ptr) {
947                 const SV * const oval = HeVAL((HE*)ptr);
948                 if (oval && oval != &PL_sv_undef) {
949                     ptr = &HeVAL((HE*)ptr);
950                     if (SvTIED_mg((const SV *)hv, PERL_MAGIC_tied))
951                         SvREFCNT_inc_void(*(SV**)ptr);
952                     av = MUTABLE_AV(hv); /* what to refcnt_dec */
953                     goto restore_sv;
954                 }
955             }
956             SvREFCNT_dec(hv);
957             SvREFCNT_dec(value);
958             break;
959         case SAVEt_OP:
960             PL_op = (OP*)SSPOPPTR;
961             break;
962         case SAVEt_HINTS:
963             if ((PL_hints & HINT_LOCALIZE_HH) && GvHV(PL_hintgv)) {
964                 SvREFCNT_dec(MUTABLE_SV(GvHV(PL_hintgv)));
965                 GvHV(PL_hintgv) = NULL;
966             }
967             Perl_refcounted_he_free(aTHX_ PL_compiling.cop_hints_hash);
968             PL_compiling.cop_hints_hash = (struct refcounted_he *) SSPOPPTR;
969             *(I32*)&PL_hints = (I32)SSPOPINT;
970             if (PL_hints & HINT_LOCALIZE_HH) {
971                 SvREFCNT_dec(MUTABLE_SV(GvHV(PL_hintgv)));
972                 GvHV(PL_hintgv) = MUTABLE_HV(SSPOPPTR);
973                 assert(GvHV(PL_hintgv));
974             } else if (!GvHV(PL_hintgv)) {
975                 /* Need to add a new one manually, else gv_fetchpv() can
976                    add one in this code:
977                    
978                    if (SvTYPE(gv) == SVt_PVGV) {
979                        if (add) {
980                        GvMULTI_on(gv);
981                        gv_init_sv(gv, sv_type);
982                        if (*name=='!' && sv_type == SVt_PVHV && len==1)
983                            require_errno(gv);
984                        }
985                        return gv;
986                    }
987
988                    and it won't have the magic set.  */
989
990                 HV *const hv = newHV();
991                 hv_magic(hv, NULL, PERL_MAGIC_hints);
992                 GvHV(PL_hintgv) = hv;
993             }
994             assert(GvHV(PL_hintgv));
995             break;
996         case SAVEt_COMPPAD:
997             PL_comppad = (PAD*)SSPOPPTR;
998             if (PL_comppad)
999                 PL_curpad = AvARRAY(PL_comppad);
1000             else
1001                 PL_curpad = NULL;
1002             break;
1003         case SAVEt_PADSV_AND_MORTALIZE:
1004             {
1005                 const PADOFFSET off = (PADOFFSET)SSPOPLONG;
1006                 SV **svp;
1007                 ptr = SSPOPPTR;
1008                 assert (ptr);
1009                 svp = AvARRAY((PAD*)ptr) + off;
1010                 /* This mortalizing used to be done by POPLOOP() via itersave.
1011                    But as we have all the information here, we can do it here,
1012                    save even having to have itersave in the struct.  */
1013                 sv_2mortal(*svp);
1014                 *svp = MUTABLE_SV(SSPOPPTR);
1015             }
1016             break;
1017         case SAVEt_SAVESWITCHSTACK:
1018             {
1019                 dSP;
1020                 AV *const t = MUTABLE_AV(SSPOPPTR);
1021                 AV *const f = MUTABLE_AV(SSPOPPTR);
1022                 SWITCHSTACK(t,f);
1023                 PL_curstackinfo->si_stack = f;
1024             }
1025             break;
1026         case SAVEt_SET_SVFLAGS:
1027             {
1028                 const U32 val  = (U32)SSPOPINT;
1029                 const U32 mask = (U32)SSPOPINT;
1030                 sv = MUTABLE_SV(SSPOPPTR);
1031                 SvFLAGS(sv) &= ~mask;
1032                 SvFLAGS(sv) |= val;
1033             }
1034             break;
1035
1036             /* This would be a mathom, but Perl_save_svref() calls a static
1037                function, S_save_scalar_at(), so has to stay in this file.  */
1038         case SAVEt_SVREF:                       /* scalar reference */
1039             value = MUTABLE_SV(SSPOPPTR);
1040             ptr = SSPOPPTR;
1041             av = NULL; /* what to refcnt_dec */
1042             goto restore_sv;
1043
1044             /* These are only saved in mathoms.c */
1045         case SAVEt_NSTAB:
1046             gv = MUTABLE_GV(SSPOPPTR);
1047             (void)sv_clear(MUTABLE_SV(gv));
1048             break;
1049         case SAVEt_LONG:                        /* long reference */
1050             ptr = SSPOPPTR;
1051             *(long*)ptr = (long)SSPOPLONG;
1052             break;
1053         case SAVEt_IV:                          /* IV reference */
1054             ptr = SSPOPPTR;
1055             *(IV*)ptr = (IV)SSPOPIV;
1056             break;
1057
1058         case SAVEt_I16:                         /* I16 reference */
1059             ptr = SSPOPPTR;
1060             *(I16*)ptr = (I16)SSPOPINT;
1061             break;
1062         case SAVEt_I8:                          /* I8 reference */
1063             ptr = SSPOPPTR;
1064             *(I8*)ptr = (I8)SSPOPINT;
1065             break;
1066         case SAVEt_DESTRUCTOR:
1067             ptr = SSPOPPTR;
1068             (*SSPOPDPTR)(ptr);
1069             break;
1070         case SAVEt_COP_ARYBASE:
1071             ptr = SSPOPPTR;
1072             i = SSPOPINT;
1073             CopARYBASE_set((COP *)ptr, i);
1074             break;
1075         case SAVEt_COMPILE_WARNINGS:
1076             ptr = SSPOPPTR;
1077
1078             if (!specialWARN(PL_compiling.cop_warnings))
1079                 PerlMemShared_free(PL_compiling.cop_warnings);
1080
1081             PL_compiling.cop_warnings = (STRLEN*)ptr;
1082             break;
1083         case SAVEt_RE_STATE:
1084             {
1085                 const struct re_save_state *const state
1086                     = (struct re_save_state *)
1087                     (PL_savestack + PL_savestack_ix
1088                      - SAVESTACK_ALLOC_FOR_RE_SAVE_STATE);
1089                 PL_savestack_ix -= SAVESTACK_ALLOC_FOR_RE_SAVE_STATE;
1090
1091                 if (PL_reg_start_tmp != state->re_state_reg_start_tmp) {
1092                     Safefree(PL_reg_start_tmp);
1093                 }
1094                 if (PL_reg_poscache != state->re_state_reg_poscache) {
1095                     Safefree(PL_reg_poscache);
1096                 }
1097                 Copy(state, &PL_reg_state, 1, struct re_save_state);
1098             }
1099             break;
1100         case SAVEt_PARSER:
1101             ptr = SSPOPPTR;
1102             parser_free((yy_parser *) ptr);
1103             break;
1104         default:
1105             Perl_croak(aTHX_ "panic: leave_scope inconsistency");
1106         }
1107     }
1108
1109     PL_tainted = was;
1110 }
1111
1112 void
1113 Perl_cx_dump(pTHX_ PERL_CONTEXT *cx)
1114 {
1115     dVAR;
1116
1117     PERL_ARGS_ASSERT_CX_DUMP;
1118
1119 #ifdef DEBUGGING
1120     PerlIO_printf(Perl_debug_log, "CX %ld = %s\n", (long)(cx - cxstack), PL_block_type[CxTYPE(cx)]);
1121     if (CxTYPE(cx) != CXt_SUBST) {
1122         PerlIO_printf(Perl_debug_log, "BLK_OLDSP = %ld\n", (long)cx->blk_oldsp);
1123         PerlIO_printf(Perl_debug_log, "BLK_OLDCOP = 0x%"UVxf"\n",
1124                       PTR2UV(cx->blk_oldcop));
1125         PerlIO_printf(Perl_debug_log, "BLK_OLDMARKSP = %ld\n", (long)cx->blk_oldmarksp);
1126         PerlIO_printf(Perl_debug_log, "BLK_OLDSCOPESP = %ld\n", (long)cx->blk_oldscopesp);
1127         PerlIO_printf(Perl_debug_log, "BLK_OLDPM = 0x%"UVxf"\n",
1128                       PTR2UV(cx->blk_oldpm));
1129         PerlIO_printf(Perl_debug_log, "BLK_GIMME = %s\n", cx->blk_gimme ? "LIST" : "SCALAR");
1130     }
1131     switch (CxTYPE(cx)) {
1132     case CXt_NULL:
1133     case CXt_BLOCK:
1134         break;
1135     case CXt_FORMAT:
1136         PerlIO_printf(Perl_debug_log, "BLK_FORMAT.CV = 0x%"UVxf"\n",
1137                 PTR2UV(cx->blk_format.cv));
1138         PerlIO_printf(Perl_debug_log, "BLK_FORMAT.GV = 0x%"UVxf"\n",
1139                 PTR2UV(cx->blk_format.gv));
1140         PerlIO_printf(Perl_debug_log, "BLK_FORMAT.DFOUTGV = 0x%"UVxf"\n",
1141                 PTR2UV(cx->blk_format.dfoutgv));
1142         PerlIO_printf(Perl_debug_log, "BLK_FORMAT.HASARGS = %d\n",
1143                       (int)CxHASARGS(cx));
1144         PerlIO_printf(Perl_debug_log, "BLK_FORMAT.RETOP = 0x%"UVxf"\n",
1145                 PTR2UV(cx->blk_format.retop));
1146         break;
1147     case CXt_SUB:
1148         PerlIO_printf(Perl_debug_log, "BLK_SUB.CV = 0x%"UVxf"\n",
1149                 PTR2UV(cx->blk_sub.cv));
1150         PerlIO_printf(Perl_debug_log, "BLK_SUB.OLDDEPTH = %ld\n",
1151                 (long)cx->blk_sub.olddepth);
1152         PerlIO_printf(Perl_debug_log, "BLK_SUB.HASARGS = %d\n",
1153                 (int)CxHASARGS(cx));
1154         PerlIO_printf(Perl_debug_log, "BLK_SUB.LVAL = %d\n", (int)CxLVAL(cx));
1155         PerlIO_printf(Perl_debug_log, "BLK_SUB.RETOP = 0x%"UVxf"\n",
1156                 PTR2UV(cx->blk_sub.retop));
1157         break;
1158     case CXt_EVAL:
1159         PerlIO_printf(Perl_debug_log, "BLK_EVAL.OLD_IN_EVAL = %ld\n",
1160                 (long)CxOLD_IN_EVAL(cx));
1161         PerlIO_printf(Perl_debug_log, "BLK_EVAL.OLD_OP_TYPE = %s (%s)\n",
1162                 PL_op_name[CxOLD_OP_TYPE(cx)],
1163                 PL_op_desc[CxOLD_OP_TYPE(cx)]);
1164         if (cx->blk_eval.old_namesv)
1165             PerlIO_printf(Perl_debug_log, "BLK_EVAL.OLD_NAME = %s\n",
1166                           SvPVX_const(cx->blk_eval.old_namesv));
1167         PerlIO_printf(Perl_debug_log, "BLK_EVAL.OLD_EVAL_ROOT = 0x%"UVxf"\n",
1168                 PTR2UV(cx->blk_eval.old_eval_root));
1169         PerlIO_printf(Perl_debug_log, "BLK_EVAL.RETOP = 0x%"UVxf"\n",
1170                 PTR2UV(cx->blk_eval.retop));
1171         break;
1172
1173     case CXt_LOOP_LAZYIV:
1174     case CXt_LOOP_LAZYSV:
1175     case CXt_LOOP_FOR:
1176     case CXt_LOOP_PLAIN:
1177         PerlIO_printf(Perl_debug_log, "BLK_LOOP.LABEL = %s\n", CxLABEL(cx));
1178         PerlIO_printf(Perl_debug_log, "BLK_LOOP.RESETSP = %ld\n",
1179                 (long)cx->blk_loop.resetsp);
1180         PerlIO_printf(Perl_debug_log, "BLK_LOOP.MY_OP = 0x%"UVxf"\n",
1181                 PTR2UV(cx->blk_loop.my_op));
1182         PerlIO_printf(Perl_debug_log, "BLK_LOOP.NEXT_OP = 0x%"UVxf"\n",
1183                 PTR2UV(CX_LOOP_NEXTOP_GET(cx)));
1184         /* XXX: not accurate for LAZYSV/IV */
1185         PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERARY = 0x%"UVxf"\n",
1186                 PTR2UV(cx->blk_loop.state_u.ary.ary));
1187         PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERIX = %ld\n",
1188                 (long)cx->blk_loop.state_u.ary.ix);
1189         PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERVAR = 0x%"UVxf"\n",
1190                 PTR2UV(CxITERVAR(cx)));
1191         break;
1192
1193     case CXt_SUBST:
1194         PerlIO_printf(Perl_debug_log, "SB_ITERS = %ld\n",
1195                 (long)cx->sb_iters);
1196         PerlIO_printf(Perl_debug_log, "SB_MAXITERS = %ld\n",
1197                 (long)cx->sb_maxiters);
1198         PerlIO_printf(Perl_debug_log, "SB_RFLAGS = %ld\n",
1199                 (long)cx->sb_rflags);
1200         PerlIO_printf(Perl_debug_log, "SB_ONCE = %ld\n",
1201                 (long)CxONCE(cx));
1202         PerlIO_printf(Perl_debug_log, "SB_ORIG = %s\n",
1203                 cx->sb_orig);
1204         PerlIO_printf(Perl_debug_log, "SB_DSTR = 0x%"UVxf"\n",
1205                 PTR2UV(cx->sb_dstr));
1206         PerlIO_printf(Perl_debug_log, "SB_TARG = 0x%"UVxf"\n",
1207                 PTR2UV(cx->sb_targ));
1208         PerlIO_printf(Perl_debug_log, "SB_S = 0x%"UVxf"\n",
1209                 PTR2UV(cx->sb_s));
1210         PerlIO_printf(Perl_debug_log, "SB_M = 0x%"UVxf"\n",
1211                 PTR2UV(cx->sb_m));
1212         PerlIO_printf(Perl_debug_log, "SB_STREND = 0x%"UVxf"\n",
1213                 PTR2UV(cx->sb_strend));
1214         PerlIO_printf(Perl_debug_log, "SB_RXRES = 0x%"UVxf"\n",
1215                 PTR2UV(cx->sb_rxres));
1216         break;
1217     }
1218 #else
1219     PERL_UNUSED_CONTEXT;
1220     PERL_UNUSED_ARG(cx);
1221 #endif  /* DEBUGGING */
1222 }
1223
1224 /*
1225  * Local variables:
1226  * c-indentation-style: bsd
1227  * c-basic-offset: 4
1228  * indent-tabs-mode: t
1229  * End:
1230  *
1231  * ex: set ts=8 sts=4 sw=4 noet:
1232  */