perl 5.0 alpha 4
[p5sagit/p5-mst-13.2.git] / scope.c
CommitLineData
79072805 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
14I32
15cxinc()
16{
17 cxstack_max = cxstack_max * 3 / 2;
18 Renew(cxstack, cxstack_max, CONTEXT);
19 return cxstack_ix + 1;
20}
21
22void
23push_return(retop)
24OP *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
33OP *
34pop_return()
35{
36 if (retstack_ix > 0)
37 return retstack[--retstack_ix];
38 else
39 return Nullop;
40}
41
42void
43push_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
53void
54pop_scope()
55{
56 I32 oldsave = scopestack[--scopestack_ix];
57 if (savestack_ix > oldsave)
58 leave_scope(oldsave);
59}
60
61void
62savestack_grow()
63{
64 savestack_max = savestack_max * 3 / 2;
65 Renew(savestack, savestack_max, ANY);
66}
67
68void
69free_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;
463ee0b2 76 if (sv) {
77#ifdef DEBUGGING
78 SvTEMP_off(sv);
79#endif
79072805 80 sv_free(sv); /* note, can modify tmps_ix!!! */
463ee0b2 81 }
79072805 82 }
83}
84
85SV *
86save_scalar(gv)
87GV *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);
93a17b20 98 if (SvTYPE(osv) >= SVt_PVMG && SvMAGIC(osv)) {
79072805 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
109void
110save_gp(gv)
111GV *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
130SV*
131save_svref(sptr)
132SV **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
153AV *
154save_ary(gv)
155GV *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
166HV *
167save_hash(gv)
168GV *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
179void
180save_item(item)
181register 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
193void
194save_int(intp)
195int *intp;
196{
197 SSCHECK(3);
198 SSPUSHINT(*intp);
199 SSPUSHPTR(intp);
200 SSPUSHINT(SAVEt_INT);
201}
202
203void
204save_I32(intp)
205I32 *intp;
206{
207 SSCHECK(3);
208 SSPUSHINT(*intp);
209 SSPUSHPTR(intp);
210 SSPUSHINT(SAVEt_I32);
211}
212
213void
214save_sptr(sptr)
215SV **sptr;
216{
217 SSCHECK(3);
218 SSPUSHPTR(*sptr);
219 SSPUSHPTR(sptr);
220 SSPUSHINT(SAVEt_SPTR);
221}
222
223void
224save_nogv(gv)
225GV *gv;
226{
227 SSCHECK(2);
228 SSPUSHPTR(gv);
229 SSPUSHINT(SAVEt_NSTAB);
230}
231
232void
233save_hptr(hptr)
234HV **hptr;
235{
236 SSCHECK(3);
237 SSPUSHINT(*hptr);
238 SSPUSHPTR(hptr);
239 SSPUSHINT(SAVEt_HPTR);
240}
241
242void
243save_aptr(aptr)
244AV **aptr;
245{
246 SSCHECK(3);
247 SSPUSHINT(*aptr);
248 SSPUSHPTR(aptr);
249 SSPUSHINT(SAVEt_APTR);
250}
251
252void
253save_list(sarg,maxsarg)
254register SV **sarg;
255I32 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
270void
271leave_scope(base)
272I32 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)
463ee0b2 282 croak("panic: corrupt saved stack index");
79072805 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;
463ee0b2 319 (void)hv_free(GvHV(gv));
79072805 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:
463ee0b2 353 croak("panic: leave_scope inconsistency");
79072805 354 }
355 }
356}