This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Pacify picky VMS compiler.
[perl5.git] / scope.h
1 #define SAVEt_ITEM              0
2 #define SAVEt_SV                1
3 #define SAVEt_AV                2
4 #define SAVEt_HV                3
5 #define SAVEt_INT               4
6 #define SAVEt_LONG              5
7 #define SAVEt_I32               6
8 #define SAVEt_IV                7
9 #define SAVEt_SPTR              8
10 #define SAVEt_APTR              9
11 #define SAVEt_HPTR              10
12 #define SAVEt_PPTR              11
13 #define SAVEt_NSTAB             12
14 #define SAVEt_SVREF             13
15 #define SAVEt_GP                14
16 #define SAVEt_FREESV            15
17 #define SAVEt_FREEOP            16
18 #define SAVEt_FREEPV            17
19 #define SAVEt_CLEARSV           18
20 #define SAVEt_DELETE            19
21 #define SAVEt_DESTRUCTOR        20
22 #define SAVEt_REGCONTEXT        21
23 #define SAVEt_STACK_POS         22
24 #define SAVEt_I16               23
25 #define SAVEt_AELEM             24
26 #define SAVEt_HELEM             25
27 #define SAVEt_OP                26
28 #define SAVEt_HINTS             27
29 #define SAVEt_ALLOC             28
30 #define SAVEt_GENERIC_SVREF     29
31 #define SAVEt_DESTRUCTOR_X      30
32 #define SAVEt_VPTR              31
33 #define SAVEt_I8                32
34 #define SAVEt_COMPPAD           33
35 #define SAVEt_GENERIC_PVREF     34
36 #define SAVEt_PADSV             35
37
38 #define SSCHECK(need) if (PL_savestack_ix + need > PL_savestack_max) savestack_grow()
39 #define SSPUSHINT(i) (PL_savestack[PL_savestack_ix++].any_i32 = (I32)(i))
40 #define SSPUSHLONG(i) (PL_savestack[PL_savestack_ix++].any_long = (long)(i))
41 #define SSPUSHIV(i) (PL_savestack[PL_savestack_ix++].any_iv = (IV)(i))
42 #define SSPUSHPTR(p) (PL_savestack[PL_savestack_ix++].any_ptr = (void*)(p))
43 #define SSPUSHDPTR(p) (PL_savestack[PL_savestack_ix++].any_dptr = (p))
44 #define SSPUSHDXPTR(p) (PL_savestack[PL_savestack_ix++].any_dxptr = (p))
45 #define SSPOPINT (PL_savestack[--PL_savestack_ix].any_i32)
46 #define SSPOPLONG (PL_savestack[--PL_savestack_ix].any_long)
47 #define SSPOPIV (PL_savestack[--PL_savestack_ix].any_iv)
48 #define SSPOPPTR (PL_savestack[--PL_savestack_ix].any_ptr)
49 #define SSPOPDPTR (PL_savestack[--PL_savestack_ix].any_dptr)
50 #define SSPOPDXPTR (PL_savestack[--PL_savestack_ix].any_dxptr)
51
52 /*
53 =for apidoc Ams||SAVETMPS
54 Opening bracket for temporaries on a callback.  See C<FREETMPS> and
55 L<perlcall>.
56
57 =for apidoc Ams||FREETMPS
58 Closing bracket for temporaries on a callback.  See C<SAVETMPS> and
59 L<perlcall>.
60
61 =for apidoc Ams||ENTER
62 Opening bracket on a callback.  See C<LEAVE> and L<perlcall>.
63
64 =for apidoc Ams||LEAVE
65 Closing bracket on a callback.  See C<ENTER> and L<perlcall>.
66
67 =cut
68 */
69
70 #define SAVETMPS save_int((int*)&PL_tmps_floor), PL_tmps_floor = PL_tmps_ix
71 #define FREETMPS if (PL_tmps_ix > PL_tmps_floor) free_tmps()
72
73 #ifdef DEBUGGING
74 #define ENTER                                                   \
75     STMT_START {                                                \
76         push_scope();                                           \
77         DEBUG_l(WITH_THR(Perl_deb(aTHX_ "ENTER scope %ld at %s:%d\n",   \
78                     PL_scopestack_ix, __FILE__, __LINE__)));    \
79     } STMT_END
80 #define LEAVE                                                   \
81     STMT_START {                                                \
82         DEBUG_l(WITH_THR(Perl_deb(aTHX_ "LEAVE scope %ld at %s:%d\n",   \
83                     PL_scopestack_ix, __FILE__, __LINE__)));    \
84         pop_scope();                                            \
85     } STMT_END
86 #else
87 #define ENTER push_scope()
88 #define LEAVE pop_scope()
89 #endif
90 #define LEAVE_SCOPE(old) if (PL_savestack_ix > old) leave_scope(old)
91
92 /*
93  * Not using SOFT_CAST on SAVESPTR, SAVEGENERICSV and SAVEFREESV
94  * because these are used for several kinds of pointer values
95  */
96 #define SAVEI8(i)       save_I8(SOFT_CAST(I8*)&(i))
97 #define SAVEI16(i)      save_I16(SOFT_CAST(I16*)&(i))
98 #define SAVEI32(i)      save_I32(SOFT_CAST(I32*)&(i))
99 #define SAVEINT(i)      save_int(SOFT_CAST(int*)&(i))
100 #define SAVEIV(i)       save_iv(SOFT_CAST(IV*)&(i))
101 #define SAVELONG(l)     save_long(SOFT_CAST(long*)&(l))
102 #define SAVESPTR(s)     save_sptr((SV**)&(s))
103 #define SAVEPPTR(s)     save_pptr(SOFT_CAST(char**)&(s))
104 #define SAVEVPTR(s)     save_vptr((void*)&(s))
105 #define SAVEPADSV(s)    save_padsv(s)
106 #define SAVEFREESV(s)   save_freesv((SV*)(s))
107 #define SAVEFREEOP(o)   save_freeop(SOFT_CAST(OP*)(o))
108 #define SAVEFREEPV(p)   save_freepv(SOFT_CAST(char*)(p))
109 #define SAVECLEARSV(sv) save_clearsv(SOFT_CAST(SV**)&(sv))
110 #define SAVEGENERICSV(s)        save_generic_svref((SV**)&(s))
111 #define SAVEGENERICPV(s)        save_generic_pvref((char**)&(s))
112 #define SAVEDELETE(h,k,l) \
113           save_delete(SOFT_CAST(HV*)(h), SOFT_CAST(char*)(k), (I32)(l))
114 #define SAVEDESTRUCTOR(f,p) \
115           save_destructor((DESTRUCTORFUNC_NOCONTEXT_t)(f), SOFT_CAST(void*)(p))
116
117 #define SAVEDESTRUCTOR_X(f,p) \
118           save_destructor_x((DESTRUCTORFUNC_t)(f), SOFT_CAST(void*)(p))
119
120 #define SAVESTACK_POS() \
121     STMT_START {                                \
122         SSCHECK(2);                             \
123         SSPUSHINT(PL_stack_sp - PL_stack_base); \
124         SSPUSHINT(SAVEt_STACK_POS);             \
125     } STMT_END
126
127 #define SAVEOP()        save_op()
128
129 #define SAVEHINTS() \
130     STMT_START {                                \
131         if (PL_hints & HINT_LOCALIZE_HH)        \
132             save_hints();                       \
133         else {                                  \
134             SSCHECK(2);                         \
135             SSPUSHINT(PL_hints);                \
136             SSPUSHINT(SAVEt_HINTS);             \
137         }                                       \
138     } STMT_END
139
140 #define SAVECOMPPAD() \
141     STMT_START {                                                \
142         if (PL_comppad && PL_curpad == AvARRAY(PL_comppad)) {   \
143             SSCHECK(2);                                         \
144             SSPUSHPTR((SV*)PL_comppad);                         \
145             SSPUSHINT(SAVEt_COMPPAD);                           \
146         }                                                       \
147         else {                                                  \
148             SAVEVPTR(PL_curpad);                                \
149             SAVESPTR(PL_comppad);                               \
150         }                                                       \
151     } STMT_END
152
153 #ifdef USE_ITHREADS
154 #  define SAVECOPSTASH(c)       SAVEPPTR(CopSTASHPV(c))
155 #  define SAVECOPSTASH_FREE(c)  SAVEGENERICPV(CopSTASHPV(c))
156 #  define SAVECOPFILE(c)        SAVEPPTR(CopFILE(c))
157 #  define SAVECOPFILE_FREE(c)   SAVEGENERICPV(CopFILE(c))
158 #else
159 #  define SAVECOPSTASH(c)       SAVESPTR(CopSTASH(c))
160 #  define SAVECOPSTASH_FREE(c)  SAVECOPSTASH(c) /* XXX not refcounted */
161 #  define SAVECOPFILE(c)        SAVESPTR(CopFILEGV(c))
162 #  define SAVECOPFILE_FREE(c)   SAVEGENERICSV(CopFILEGV(c))
163 #endif
164
165 #define SAVECOPLINE(c)          SAVEI16(CopLINE(c))
166
167 /* SSNEW() temporarily allocates a specified number of bytes of data on the
168  * savestack.  It returns an integer index into the savestack, because a
169  * pointer would get broken if the savestack is moved on reallocation.
170  * SSNEWa() works like SSNEW(), but also aligns the data to the specified
171  * number of bytes.  MEM_ALIGNBYTES is perhaps the most useful.  The
172  * alignment will be preserved therough savestack reallocation *only* if
173  * realloc returns data aligned to a size divisible by `align'!
174  *
175  * SSPTR() converts the index returned by SSNEW/SSNEWa() into a pointer.
176  */
177
178 #define SSNEW(size)             Perl_save_alloc(aTHX_ (size), 0)
179 #define SSNEWt(n,t)             SSNEW((n)*sizeof(t))
180 #define SSNEWa(size,align)      Perl_save_alloc(aTHX_ (size), \
181     (align - ((int)((caddr_t)&PL_savestack[PL_savestack_ix]) % align)) % align)
182 #define SSNEWat(n,t,align)      SSNEWa((n)*sizeof(t), align)
183
184 #define SSPTR(off,type)         ((type)  ((char*)PL_savestack + off))
185 #define SSPTRt(off,type)        ((type*) ((char*)PL_savestack + off))
186
187 /* A jmpenv packages the state required to perform a proper non-local jump.
188  * Note that there is a start_env initialized when perl starts, and top_env
189  * points to this initially, so top_env should always be non-null.
190  *
191  * Existence of a non-null top_env->je_prev implies it is valid to call
192  * longjmp() at that runlevel (we make sure start_env.je_prev is always
193  * null to ensure this).
194  *
195  * je_mustcatch, when set at any runlevel to TRUE, means eval ops must
196  * establish a local jmpenv to handle exception traps.  Care must be taken
197  * to restore the previous value of je_mustcatch before exiting the
198  * stack frame iff JMPENV_PUSH was not called in that stack frame.
199  * GSAR 97-03-27
200  */
201
202 struct jmpenv {
203     struct jmpenv *     je_prev;
204     Sigjmp_buf          je_buf;         /* only for use if !je_throw */
205     int                 je_ret;         /* last exception thrown */
206     bool                je_mustcatch;   /* need to call longjmp()? */
207 #ifdef PERL_FLEXIBLE_EXCEPTIONS
208     void                (*je_throw)(int v); /* last for bincompat */
209     bool                je_noset;       /* no need for setjmp() */
210 #endif
211 };
212
213 typedef struct jmpenv JMPENV;
214
215 #ifdef OP_IN_REGISTER
216 #define OP_REG_TO_MEM   PL_opsave = op
217 #define OP_MEM_TO_REG   op = PL_opsave
218 #else
219 #define OP_REG_TO_MEM   NOOP
220 #define OP_MEM_TO_REG   NOOP
221 #endif
222
223 /*
224  * How to build the first jmpenv.
225  *
226  * top_env needs to be non-zero. It points to an area
227  * in which longjmp() stuff is stored, as C callstack
228  * info there at least is thread specific this has to
229  * be per-thread. Otherwise a 'die' in a thread gives
230  * that thread the C stack of last thread to do an eval {}!
231  */
232
233 #define JMPENV_BOOTSTRAP \
234     STMT_START {                                \
235         Zero(&PL_start_env, 1, JMPENV);         \
236         PL_start_env.je_ret = -1;               \
237         PL_start_env.je_mustcatch = TRUE;       \
238         PL_top_env = &PL_start_env;             \
239     } STMT_END
240
241 #ifdef PERL_FLEXIBLE_EXCEPTIONS
242
243 /*
244  * These exception-handling macros are split up to
245  * ease integration with C++ exceptions.
246  *
247  * To use C++ try+catch to catch Perl exceptions, an extension author
248  * needs to first write an extern "C" function to throw an appropriate
249  * exception object; typically it will be or contain an integer,
250  * because Perl's internals use integers to track exception types:
251  *    extern "C" { static void thrower(int i) { throw i; } }
252  *
253  * Then (as shown below) the author needs to use, not the simple
254  * JMPENV_PUSH, but several of its constitutent macros, to arrange for
255  * the Perl internals to call thrower() rather than longjmp() to
256  * report exceptions:
257  *
258  *    dJMPENV;
259  *    JMPENV_PUSH_INIT(thrower);
260  *    try {
261  *        ... stuff that may throw exceptions ...
262  *    }
263  *    catch (int why) {  // or whatever matches thrower()
264  *        JMPENV_POST_CATCH;
265  *        EXCEPT_SET(why);
266  *        switch (why) {
267  *          ... // handle various Perl exception codes
268  *        }
269  *    }
270  *    JMPENV_POP;  // don't forget this!
271  */
272
273 /*
274  * Function that catches/throws, and its callback for the
275  *  body of protected processing.
276  */
277 typedef void *(CPERLscope(*protect_body_t)) (pTHX_ va_list);
278 typedef void *(CPERLscope(*protect_proc_t)) (pTHX_ volatile JMPENV *pcur_env,
279                                              int *, protect_body_t, ...);
280
281 #define dJMPENV JMPENV cur_env; \
282                 volatile JMPENV *pcur_env = ((cur_env.je_noset = 0),&cur_env)
283
284 #define JMPENV_PUSH_INIT_ENV(ce,THROWFUNC) \
285     STMT_START {                                        \
286         (ce).je_throw = (THROWFUNC);                    \
287         (ce).je_ret = -1;                               \
288         (ce).je_mustcatch = FALSE;                      \
289         (ce).je_prev = PL_top_env;                      \
290         PL_top_env = &(ce);                             \
291         OP_REG_TO_MEM;                                  \
292     } STMT_END
293
294 #define JMPENV_PUSH_INIT(THROWFUNC) JMPENV_PUSH_INIT_ENV(*(JMPENV*)pcur_env,THROWFUNC)
295
296 #define JMPENV_POST_CATCH_ENV(ce) \
297     STMT_START {                                        \
298         OP_MEM_TO_REG;                                  \
299         PL_top_env = &(ce);                             \
300     } STMT_END
301
302 #define JMPENV_POST_CATCH JMPENV_POST_CATCH_ENV(*(JMPENV*)pcur_env)
303
304 #define JMPENV_PUSH_ENV(ce,v) \
305     STMT_START {                                                \
306         if (!(ce).je_noset) {                                   \
307             DEBUG_l(Perl_deb(aTHX_ "Setting up jumplevel %p, was %p\n", \
308                              ce, PL_top_env));                  \
309             JMPENV_PUSH_INIT_ENV(ce,NULL);                      \
310             EXCEPT_SET_ENV(ce,PerlProc_setjmp((ce).je_buf, 1));\
311             (ce).je_noset = 1;                                  \
312         }                                                       \
313         else                                                    \
314             EXCEPT_SET_ENV(ce,0);                               \
315         JMPENV_POST_CATCH_ENV(ce);                              \
316         (v) = EXCEPT_GET_ENV(ce);                               \
317     } STMT_END
318
319 #define JMPENV_PUSH(v) JMPENV_PUSH_ENV(*(JMPENV*)pcur_env,v)
320
321 #define JMPENV_POP_ENV(ce) \
322     STMT_START {                                                \
323         if (PL_top_env == &(ce))                                \
324             PL_top_env = (ce).je_prev;                          \
325     } STMT_END
326
327 #define JMPENV_POP  JMPENV_POP_ENV(*(JMPENV*)pcur_env)
328
329 #define JMPENV_JUMP(v) \
330     STMT_START {                                                \
331         OP_REG_TO_MEM;                                          \
332         if (PL_top_env->je_prev) {                              \
333             if (PL_top_env->je_throw)                           \
334                 PL_top_env->je_throw(v);                        \
335             else                                                \
336                 PerlProc_longjmp(PL_top_env->je_buf, (v));      \
337         }                                                       \
338         if ((v) == 2)                                           \
339             PerlProc_exit(STATUS_NATIVE_EXPORT);                \
340         PerlIO_printf(Perl_error_log, "panic: top_env\n");      \
341         PerlProc_exit(1);                                       \
342     } STMT_END
343
344 #define EXCEPT_GET_ENV(ce)      ((ce).je_ret)
345 #define EXCEPT_GET              EXCEPT_GET_ENV(*(JMPENV*)pcur_env)
346 #define EXCEPT_SET_ENV(ce,v)    ((ce).je_ret = (v))
347 #define EXCEPT_SET(v)           EXCEPT_SET_ENV(*(JMPENV*)pcur_env,v)
348
349 #else /* !PERL_FLEXIBLE_EXCEPTIONS */
350
351 #define dJMPENV         JMPENV cur_env
352
353 #define JMPENV_PUSH(v) \
354     STMT_START {                                                        \
355         DEBUG_l(Perl_deb(aTHX_ "Setting up jumplevel %p, was %p\n",     \
356                          &cur_env, PL_top_env));                        \
357         cur_env.je_prev = PL_top_env;                                   \
358         OP_REG_TO_MEM;                                                  \
359         cur_env.je_ret = PerlProc_setjmp(cur_env.je_buf, 1);            \
360         OP_MEM_TO_REG;                                                  \
361         PL_top_env = &cur_env;                                          \
362         cur_env.je_mustcatch = FALSE;                                   \
363         (v) = cur_env.je_ret;                                           \
364     } STMT_END
365
366 #define JMPENV_POP \
367     STMT_START { PL_top_env = cur_env.je_prev; } STMT_END
368
369 #define JMPENV_JUMP(v) \
370     STMT_START {                                                \
371         OP_REG_TO_MEM;                                          \
372         if (PL_top_env->je_prev)                                \
373             PerlProc_longjmp(PL_top_env->je_buf, (v));          \
374         if ((v) == 2)                                           \
375             PerlProc_exit(STATUS_NATIVE_EXPORT);                \
376         PerlIO_printf(PerlIO_stderr(), "panic: top_env\n");     \
377         PerlProc_exit(1);                                       \
378     } STMT_END
379
380 #endif /* PERL_FLEXIBLE_EXCEPTIONS */
381
382 #define CATCH_GET               (PL_top_env->je_mustcatch)
383 #define CATCH_SET(v)            (PL_top_env->je_mustcatch = (v))