22b206c46d26b7f050619f08098a1b26c32c0931
[p5sagit/p5-mst-13.2.git] / scope.c
1 /* $RCSfile: op.c,v $$Revision: 4.1 $$Date: 92/08/07 17:19:16 $
2  *
3  *    Copyright (c) 1991, 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  * $Log:        op.c,v $
9  */
10
11 #include "EXTERN.h"
12 #include "perl.h"
13
14 I32
15 cxinc()
16 {
17     cxstack_max = cxstack_max * 3 / 2;
18     Renew(cxstack, cxstack_max, CONTEXT);
19     return cxstack_ix + 1;
20 }
21
22 void
23 push_return(retop)
24 OP *retop;
25 {
26     if (retstack_ix == retstack_max) {
27         retstack_max = retstack_max * 3 / 2;
28         Renew(retstack, retstack_max, OP*);
29     }
30     retstack[retstack_ix++] = retop;
31 }
32
33 OP *
34 pop_return()
35 {
36     if (retstack_ix > 0)
37         return retstack[--retstack_ix];
38     else
39         return Nullop;
40 }
41
42 void
43 push_scope()
44 {
45     if (scopestack_ix == scopestack_max) {
46         scopestack_max = scopestack_max * 3 / 2;
47         Renew(scopestack, scopestack_max, I32);
48     }
49     scopestack[scopestack_ix++] = savestack_ix;
50
51 }
52
53 void
54 pop_scope()
55 {
56     I32 oldsave = scopestack[--scopestack_ix];
57     if (savestack_ix > oldsave)
58         leave_scope(oldsave);
59 }
60
61 void
62 savestack_grow()
63 {
64     savestack_max = savestack_max * 3 / 2;
65     Renew(savestack, savestack_max, ANY);
66 }
67
68 void
69 free_tmps()
70 {
71     /* XXX should tmps_floor live in cxstack? */
72     I32 myfloor = tmps_floor;
73     while (tmps_ix > myfloor) {      /* clean up after last statement */
74         SV* sv = tmps_stack[tmps_ix];
75         tmps_stack[tmps_ix--] = Nullsv;
76         if (sv) {
77 #ifdef DEBUGGING
78             SvTEMP_off(sv);
79 #endif
80             sv_free(sv);                /* note, can modify tmps_ix!!! */
81         }
82     }
83 }
84
85 SV *
86 save_scalar(gv)
87 GV *gv;
88 {
89     register SV *sv;
90     SV *osv = GvSV(gv);
91
92     SSCHECK(3);
93     SSPUSHPTR(gv);
94     SSPUSHPTR(osv);
95     SSPUSHINT(SAVEt_SV);
96
97     sv = GvSV(gv) = NEWSV(0,0);
98     if (SvTYPE(osv) >= SVt_PVMG && SvMAGIC(osv)) {
99         sv_upgrade(sv, SvTYPE(osv));
100         SvMAGIC(sv) = SvMAGIC(osv);
101         localizing = TRUE;
102         SvSETMAGIC(sv);
103         localizing = FALSE;
104     }
105     return sv;
106 }
107
108 #ifdef INLINED_ELSEWHERE
109 void
110 save_gp(gv)
111 GV *gv;
112 {
113     register GP *gp;
114     GP *ogp = GvGP(gv);
115
116     SSCHECK(3);
117     SSPUSHPTR(gv);
118     SSPUSHPTR(ogp);
119     SSPUSHINT(SAVEt_GP);
120
121     Newz(602,gp, 1, GP);
122     GvGP(gv) = gp;
123     GvREFCNT(gv) = 1;
124     GvSV(gv) = NEWSV(72,0);
125     GvLINE(gv) = curcop->cop_line;
126     GvEGV(gv) = gv;
127 }
128 #endif
129
130 SV*
131 save_svref(sptr)
132 SV **sptr;
133 {
134     register SV *sv;
135     SV *osv = *sptr;
136
137     SSCHECK(3);
138     SSPUSHPTR(*sptr);
139     SSPUSHPTR(sptr);
140     SSPUSHINT(SAVEt_SVREF);
141
142     sv = *sptr = NEWSV(0,0);
143     if (SvTYPE(osv) >= SVt_PVMG && SvMAGIC(sv)) {
144         sv_upgrade(sv, SvTYPE(osv));
145         SvMAGIC(sv) = SvMAGIC(osv);
146         localizing = TRUE;
147         SvSETMAGIC(sv);
148         localizing = FALSE;
149     }
150     return sv;
151 }
152
153 AV *
154 save_ary(gv)
155 GV *gv;
156 {
157     SSCHECK(3);
158     SSPUSHPTR(gv);
159     SSPUSHPTR(GvAVn(gv));
160     SSPUSHINT(SAVEt_AV);
161
162     GvAV(gv) = Null(AV*);
163     return GvAVn(gv);
164 }
165
166 HV *
167 save_hash(gv)
168 GV *gv;
169 {
170     SSCHECK(3);
171     SSPUSHPTR(gv);
172     SSPUSHPTR(GvHVn(gv));
173     SSPUSHINT(SAVEt_HV);
174
175     GvHV(gv) = Null(HV*);
176     return GvHVn(gv);
177 }
178
179 void
180 save_item(item)
181 register SV *item;
182 {
183     register SV *sv;
184
185     SSCHECK(3);
186     SSPUSHPTR(item);            /* remember the pointer */
187     sv = NEWSV(0,0);
188     sv_setsv(sv,item);
189     SSPUSHPTR(sv);              /* remember the value */
190     SSPUSHINT(SAVEt_ITEM);
191 }
192
193 void
194 save_int(intp)
195 int *intp;
196 {
197     SSCHECK(3);
198     SSPUSHINT(*intp);
199     SSPUSHPTR(intp);
200     SSPUSHINT(SAVEt_INT);
201 }
202
203 void
204 save_I32(intp)
205 I32 *intp;
206 {
207     SSCHECK(3);
208     SSPUSHINT(*intp);
209     SSPUSHPTR(intp);
210     SSPUSHINT(SAVEt_I32);
211 }
212
213 void
214 save_sptr(sptr)
215 SV **sptr;
216 {
217     SSCHECK(3);
218     SSPUSHPTR(*sptr);
219     SSPUSHPTR(sptr);
220     SSPUSHINT(SAVEt_SPTR);
221 }
222
223 void
224 save_nogv(gv)
225 GV *gv;
226 {
227     SSCHECK(2);
228     SSPUSHPTR(gv);
229     SSPUSHINT(SAVEt_NSTAB);
230 }
231
232 void
233 save_hptr(hptr)
234 HV **hptr;
235 {
236     SSCHECK(3);
237     SSPUSHINT(*hptr);
238     SSPUSHPTR(hptr);
239     SSPUSHINT(SAVEt_HPTR);
240 }
241
242 void
243 save_aptr(aptr)
244 AV **aptr;
245 {
246     SSCHECK(3);
247     SSPUSHINT(*aptr);
248     SSPUSHPTR(aptr);
249     SSPUSHINT(SAVEt_APTR);
250 }
251
252 void
253 save_list(sarg,maxsarg)
254 register SV **sarg;
255 I32 maxsarg;
256 {
257     register SV *sv;
258     register I32 i;
259
260     SSCHECK(3 * maxsarg);
261     for (i = 1; i <= maxsarg; i++) {
262         SSPUSHPTR(sarg[i]);             /* remember the pointer */
263         sv = NEWSV(0,0);
264         sv_setsv(sv,sarg[i]);
265         SSPUSHPTR(sv);                  /* remember the value */
266         SSPUSHINT(SAVEt_ITEM);
267     }
268 }
269
270 void
271 leave_scope(base)
272 I32 base;
273 {
274     register SV *sv;
275     register SV *value;
276     register GV *gv;
277     register AV *av;
278     register HV *hv;
279     register void* ptr;
280
281     if (base < -1)
282         croak("panic: corrupt saved stack index");
283     while (savestack_ix > base) {
284         switch (SSPOPINT) {
285         case SAVEt_ITEM:                        /* normal string */
286             value = (SV*)SSPOPPTR;
287             sv = (SV*)SSPOPPTR;
288             sv_replace(sv,value);
289             SvSETMAGIC(sv);
290             break;
291         case SAVEt_SV:                          /* scalar reference */
292             value = (SV*)SSPOPPTR;
293             gv = (GV*)SSPOPPTR;
294             sv = GvSV(gv);
295             if (SvTYPE(sv) >= SVt_PVMG)
296                 SvMAGIC(sv) = 0;
297             sv_free(sv);
298             GvSV(gv) = sv = value;
299             SvSETMAGIC(sv);
300             break;
301         case SAVEt_SVREF:                       /* scalar reference */
302             ptr = SSPOPPTR;
303             sv = *(SV**)ptr;
304             if (SvTYPE(sv) >= SVt_PVMG)
305                 SvMAGIC(sv) = 0;
306             sv_free(sv);
307             *(SV**)ptr = sv = (SV*)SSPOPPTR;
308             SvSETMAGIC(sv);
309             break;
310         case SAVEt_AV:                          /* array reference */
311             av = (AV*)SSPOPPTR;
312             gv = (GV*)SSPOPPTR;
313             av_free(GvAV(gv));
314             GvAV(gv) = av;
315             break;
316         case SAVEt_HV:                          /* hash reference */
317             hv = (HV*)SSPOPPTR;
318             gv = (GV*)SSPOPPTR;
319             (void)hv_free(GvHV(gv));
320             GvHV(gv) = hv;
321             break;
322         case SAVEt_INT:                         /* int reference */
323             ptr = SSPOPPTR;
324             *(int*)ptr = (int)SSPOPINT;
325             break;
326         case SAVEt_I32:                         /* I32 reference */
327             ptr = SSPOPPTR;
328             *(I32*)ptr = (I32)SSPOPINT;
329             break;
330         case SAVEt_SPTR:                        /* SV* reference */
331             ptr = SSPOPPTR;
332             *(SV**)ptr = (SV*)SSPOPPTR;
333             break;
334         case SAVEt_HPTR:                        /* HV* reference */
335             ptr = SSPOPPTR;
336             *(HV**)ptr = (HV*)SSPOPPTR;
337             break;
338         case SAVEt_APTR:                        /* AV* reference */
339             ptr = SSPOPPTR;
340             *(AV**)ptr = (AV*)SSPOPPTR;
341             break;
342         case SAVEt_NSTAB:
343             gv = (GV*)SSPOPPTR;
344             (void)sv_clear(gv);
345             break;
346         case SAVEt_GP:                          /* scalar reference */
347             ptr = SSPOPPTR;
348             gv = (GV*)SSPOPPTR;
349             gp_free(gv);
350             GvGP(gv) = (GP*)ptr;
351             break;
352         default:
353             croak("panic: leave_scope inconsistency");
354         }
355     }
356 }