X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=scope.h;h=6a1c90e3ca7a2c7aeab7b10809a0323d37d96e43;hb=fabdb6c0879db76333e970b6c67260c877fc17b3;hp=71703651cc4a3776fef2a1297655684861f26412;hpb=1163b5c41f1e1e2856ca82fef1598bfbb6c54d72;p=p5sagit%2Fp5-mst-13.2.git diff --git a/scope.h b/scope.h index 7170365..6a1c90e 100644 --- a/scope.h +++ b/scope.h @@ -1,239 +1,216 @@ -#define SAVEt_ITEM 0 -#define SAVEt_SV 1 -#define SAVEt_AV 2 -#define SAVEt_HV 3 -#define SAVEt_INT 4 -#define SAVEt_LONG 5 -#define SAVEt_I32 6 -#define SAVEt_IV 7 -#define SAVEt_SPTR 8 -#define SAVEt_APTR 9 -#define SAVEt_HPTR 10 -#define SAVEt_PPTR 11 -#define SAVEt_NSTAB 12 -#define SAVEt_SVREF 13 -#define SAVEt_GP 14 -#define SAVEt_FREESV 15 -#define SAVEt_FREEOP 16 -#define SAVEt_FREEPV 17 -#define SAVEt_CLEARSV 18 -#define SAVEt_DELETE 19 -#define SAVEt_DESTRUCTOR 20 -#define SAVEt_REGCONTEXT 21 -#define SAVEt_STACK_POS 22 -#define SAVEt_I16 23 -#define SAVEt_AELEM 24 -#define SAVEt_HELEM 25 -#define SAVEt_OP 26 - -#define SSCHECK(need) if (savestack_ix + need > savestack_max) savestack_grow() -#define SSPUSHINT(i) (savestack[savestack_ix++].any_i32 = (I32)(i)) -#define SSPUSHLONG(i) (savestack[savestack_ix++].any_long = (long)(i)) -#define SSPUSHIV(i) (savestack[savestack_ix++].any_iv = (IV)(i)) -#define SSPUSHPTR(p) (savestack[savestack_ix++].any_ptr = (void*)(p)) -#define SSPUSHDPTR(p) (savestack[savestack_ix++].any_dptr = (p)) -#define SSPOPINT (savestack[--savestack_ix].any_i32) -#define SSPOPLONG (savestack[--savestack_ix].any_long) -#define SSPOPIV (savestack[--savestack_ix].any_iv) -#define SSPOPPTR (savestack[--savestack_ix].any_ptr) -#define SSPOPDPTR (savestack[--savestack_ix].any_dptr) - -#define SAVETMPS save_int((int*)&tmps_floor), tmps_floor = tmps_ix -#define FREETMPS if (tmps_ix > tmps_floor) free_tmps() +/* scope.h + * + * Copyright (C) 1993, 1994, 1996, 1997, 1998, 1999, + * 2000, 2001, 2002, 2004, 2005 by Larry Wall and others + * + * You may distribute under the terms of either the GNU General Public + * License or the Artistic License, as specified in the README file. + * + */ + +#define SAVEt_ITEM 0 +#define SAVEt_SV 1 +#define SAVEt_AV 2 +#define SAVEt_HV 3 +#define SAVEt_INT 4 +#define SAVEt_LONG 5 +#define SAVEt_I32 6 +#define SAVEt_IV 7 +#define SAVEt_SPTR 8 +#define SAVEt_APTR 9 +#define SAVEt_HPTR 10 +#define SAVEt_PPTR 11 +#define SAVEt_NSTAB 12 +#define SAVEt_SVREF 13 +#define SAVEt_GP 14 +#define SAVEt_FREESV 15 +#define SAVEt_FREEOP 16 +#define SAVEt_FREEPV 17 +#define SAVEt_CLEARSV 18 +#define SAVEt_DELETE 19 +#define SAVEt_DESTRUCTOR 20 +#define SAVEt_REGCONTEXT 21 +#define SAVEt_STACK_POS 22 +#define SAVEt_I16 23 +#define SAVEt_AELEM 24 +#define SAVEt_HELEM 25 +#define SAVEt_OP 26 +#define SAVEt_HINTS 27 +#define SAVEt_ALLOC 28 +#define SAVEt_GENERIC_SVREF 29 +#define SAVEt_DESTRUCTOR_X 30 +#define SAVEt_VPTR 31 +#define SAVEt_I8 32 +#define SAVEt_COMPPAD 33 +#define SAVEt_GENERIC_PVREF 34 +#define SAVEt_PADSV 35 +#define SAVEt_MORTALIZESV 36 +#define SAVEt_SHARED_PVREF 37 +#define SAVEt_BOOL 38 +#define SAVEt_SET_SVFLAGS 39 +#define SAVEt_SAVESWITCHSTACK 40 + +#ifndef SCOPE_SAVES_SIGNAL_MASK +#define SCOPE_SAVES_SIGNAL_MASK 0 +#endif + +#define SSCHECK(need) if (PL_savestack_ix + (need) > PL_savestack_max) savestack_grow() +#define SSGROW(need) if (PL_savestack_ix + (need) > PL_savestack_max) savestack_grow_cnt(need) +#define SSPUSHINT(i) (PL_savestack[PL_savestack_ix++].any_i32 = (I32)(i)) +#define SSPUSHLONG(i) (PL_savestack[PL_savestack_ix++].any_long = (long)(i)) +#define SSPUSHBOOL(p) (PL_savestack[PL_savestack_ix++].any_bool = (p)) +#define SSPUSHIV(i) (PL_savestack[PL_savestack_ix++].any_iv = (IV)(i)) +#define SSPUSHPTR(p) (PL_savestack[PL_savestack_ix++].any_ptr = (void*)(p)) +#define SSPUSHDPTR(p) (PL_savestack[PL_savestack_ix++].any_dptr = (p)) +#define SSPUSHDXPTR(p) (PL_savestack[PL_savestack_ix++].any_dxptr = (p)) +#define SSPOPINT (PL_savestack[--PL_savestack_ix].any_i32) +#define SSPOPLONG (PL_savestack[--PL_savestack_ix].any_long) +#define SSPOPBOOL (PL_savestack[--PL_savestack_ix].any_bool) +#define SSPOPIV (PL_savestack[--PL_savestack_ix].any_iv) +#define SSPOPPTR (PL_savestack[--PL_savestack_ix].any_ptr) +#define SSPOPDPTR (PL_savestack[--PL_savestack_ix].any_dptr) +#define SSPOPDXPTR (PL_savestack[--PL_savestack_ix].any_dxptr) + +/* +=head1 Callback Functions + +=for apidoc Ams||SAVETMPS +Opening bracket for temporaries on a callback. See C and +L. + +=for apidoc Ams||FREETMPS +Closing bracket for temporaries on a callback. See C and +L. + +=for apidoc Ams||ENTER +Opening bracket on a callback. See C and L. + +=for apidoc Ams||LEAVE +Closing bracket on a callback. See C and L. + +=cut +*/ + +#define SAVETMPS save_int((int*)&PL_tmps_floor), PL_tmps_floor = PL_tmps_ix +#define FREETMPS if (PL_tmps_ix > PL_tmps_floor) free_tmps() #ifdef DEBUGGING #define ENTER \ STMT_START { \ push_scope(); \ - DEBUG_l(WITH_THR(deb("ENTER scope %ld at %s:%d\n", \ - scopestack_ix, __FILE__, __LINE__))); \ + DEBUG_SCOPE("ENTER") \ } STMT_END #define LEAVE \ STMT_START { \ - DEBUG_l(WITH_THR(deb("LEAVE scope %ld at %s:%d\n", \ - scopestack_ix, __FILE__, __LINE__))); \ + DEBUG_SCOPE("LEAVE") \ pop_scope(); \ } STMT_END #else #define ENTER push_scope() #define LEAVE pop_scope() #endif -#define LEAVE_SCOPE(old) if (savestack_ix > old) leave_scope(old) +#define LEAVE_SCOPE(old) if (PL_savestack_ix > old) leave_scope(old) /* - * Not using SOFT_CAST on SAVEFREESV and SAVEFREESV + * Not using SOFT_CAST on SAVESPTR, SAVEGENERICSV and SAVEFREESV * because these are used for several kinds of pointer values */ +#define SAVEI8(i) save_I8(SOFT_CAST(I8*)&(i)) #define SAVEI16(i) save_I16(SOFT_CAST(I16*)&(i)) #define SAVEI32(i) save_I32(SOFT_CAST(I32*)&(i)) #define SAVEINT(i) save_int(SOFT_CAST(int*)&(i)) #define SAVEIV(i) save_iv(SOFT_CAST(IV*)&(i)) #define SAVELONG(l) save_long(SOFT_CAST(long*)&(l)) +#define SAVEBOOL(b) save_bool(SOFT_CAST(bool*)&(b)) #define SAVESPTR(s) save_sptr((SV**)&(s)) #define SAVEPPTR(s) save_pptr(SOFT_CAST(char**)&(s)) +#define SAVEVPTR(s) save_vptr((void*)&(s)) +#define SAVEPADSV(s) save_padsv(s) #define SAVEFREESV(s) save_freesv((SV*)(s)) +#define SAVEMORTALIZESV(s) save_mortalizesv((SV*)(s)) #define SAVEFREEOP(o) save_freeop(SOFT_CAST(OP*)(o)) #define SAVEFREEPV(p) save_freepv(SOFT_CAST(char*)(p)) #define SAVECLEARSV(sv) save_clearsv(SOFT_CAST(SV**)&(sv)) +#define SAVEGENERICSV(s) save_generic_svref((SV**)&(s)) +#define SAVEGENERICPV(s) save_generic_pvref((char**)&(s)) +#define SAVESHAREDPV(s) save_shared_pvref((char**)&(s)) +#define SAVESETSVFLAGS(sv,mask,val) save_set_svflags(sv,mask,val) #define SAVEDELETE(h,k,l) \ save_delete(SOFT_CAST(HV*)(h), SOFT_CAST(char*)(k), (I32)(l)) -#ifdef PERL_OBJECT -#define CALLDESTRUCTOR this->*SSPOPDPTR -#define SAVEDESTRUCTOR(f,p) \ - save_destructor((DESTRUCTORFUNC)(FUNC_NAME_TO_PTR(f)), \ - SOFT_CAST(void*)(p)) -#else -#define CALLDESTRUCTOR *SSPOPDPTR #define SAVEDESTRUCTOR(f,p) \ - save_destructor(SOFT_CAST(void(*)_((void*)))(FUNC_NAME_TO_PTR(f)), \ - SOFT_CAST(void*)(p)) -#endif -#define SAVESTACK_POS() STMT_START { \ - SSCHECK(2); \ - SSPUSHINT(stack_sp - stack_base); \ - SSPUSHINT(SAVEt_STACK_POS); \ - } STMT_END -#define SAVEOP() save_op() + save_destructor((DESTRUCTORFUNC_NOCONTEXT_t)(f), SOFT_CAST(void*)(p)) -/* A jmpenv packages the state required to perform a proper non-local jump. - * Note that there is a start_env initialized when perl starts, and top_env - * points to this initially, so top_env should always be non-null. - * - * Existence of a non-null top_env->je_prev implies it is valid to call - * (*je_jump)() at that runlevel. Always use the macros below! They - * manage most of the complexity for you. - * - * je_mustcatch, when set at any runlevel to TRUE, means eval ops must - * establish a local jmpenv to handle exception traps. Care must be taken - * to restore the previous value of je_mustcatch before exiting the - * stack frame iff JMPENV_PUSH was not called in that stack frame. - * - * The support for C++ try/throw causes a small loss of flexibility. - * No longer is it possible to place the body of exception-protected - * code in the same C function as JMPENV_PUSH &etc. Older code that - * does this will continue to work with set/longjmp, but cannot use - * C++ exceptions. - * - * GSAR 19970327 - * JPRIT 19980613 (C++ update) - */ - -#define JMP_NORMAL 0 -#define JMP_ABNORMAL 1 /* shouldn't happen */ -#define JMP_MYEXIT 2 /* exit */ -#define JMP_EXCEPTION 3 /* die */ - -/* None of the JMPENV fields should be accessed directly. - Please use the macros below! */ -struct jmpenv { - struct jmpenv * je_prev; - int je_stat; /* JMP_* reason for setjmp() */ - bool je_mustcatch; /* will need a new TRYBLOCK? */ - void (*je_jump) _((CPERLproto)); -}; -typedef struct jmpenv JMPENV; - -struct tryvtbl { - /* [0] executed before JMPENV_POP - [1] executed after JMPENV_POP - (NULL pointers are OK) */ - char *try_context; - void (*try_normal [2]) _((CPERLproto_ void*)); - void (*try_abnormal [2]) _((CPERLproto_ void*)); - void (*try_exception [2]) _((CPERLproto_ void*)); - void (*try_myexit [2]) _((CPERLproto_ void*)); -}; -typedef struct tryvtbl TRYVTBL; - -typedef void (*tryblock_f) _((CPERLproto_ TRYVTBL *vtbl, void *locals)); -#define TRYBLOCK(mytry,vars) \ - (*tryblock_function)(PERL_OBJECT_THIS_ &mytry, &vars) - -#ifdef OP_IN_REGISTER -#define OP_REG_TO_MEM opsave = op -#define OP_MEM_TO_REG op = opsave -#else -#define OP_REG_TO_MEM NOOP -#define OP_MEM_TO_REG NOOP -#endif +#define SAVEDESTRUCTOR_X(f,p) \ + save_destructor_x((DESTRUCTORFUNC_t)(f), SOFT_CAST(void*)(p)) -#define JMPENV_TOPINIT(top) \ -STMT_START { \ - top.je_prev = NULL; \ - top.je_stat = JMP_ABNORMAL; \ - top.je_mustcatch = TRUE; \ - top_env = ⊤ \ -} STMT_END - -#define JMPENV_INIT(env, jmp) \ -STMT_START { \ - ((JMPENV*)&env)->je_prev = top_env; \ - ((JMPENV*)&env)->je_stat = JMP_NORMAL; \ - ((JMPENV*)&env)->je_jump = jmp; \ - OP_REG_TO_MEM; \ -} STMT_END - -#define JMPENV_TRY(env) \ -STMT_START { \ - OP_MEM_TO_REG; \ - ((JMPENV*)&env)->je_mustcatch = FALSE; \ - top_env = (JMPENV*)&env; \ -} STMT_END - -#define JMPENV_POP_JE(env) \ -STMT_START { \ - assert(top_env == (JMPENV*)&env); \ - top_env = ((JMPENV*)&env)->je_prev; \ -} STMT_END - -#define JMPENV_STAT(env) ((JMPENV*)&env)->je_stat - -#define JMPENV_JUMP(v) \ - STMT_START { \ - assert((v) != JMP_NORMAL); \ - OP_REG_TO_MEM; \ - if (top_env->je_prev) { \ - top_env->je_stat = (v); \ - (*top_env->je_jump)(PERL_OBJECT_THIS); \ - } \ - if ((v) == JMP_MYEXIT) \ - PerlProc_exit(STATUS_NATIVE_EXPORT); \ - PerlIO_printf(PerlIO_stderr(), no_top_env); \ - PerlProc_exit(1); \ +#define SAVESTACK_POS() \ + STMT_START { \ + SSCHECK(2); \ + SSPUSHINT(PL_stack_sp - PL_stack_base); \ + SSPUSHINT(SAVEt_STACK_POS); \ } STMT_END - -#define CATCH_GET (top_env->je_mustcatch) -#define CATCH_SET(v) (top_env->je_mustcatch = (v)) +#define SAVEOP() save_op() +#define SAVEHINTS() \ + STMT_START { \ + SSCHECK(3); \ + if (PL_hints & HINT_LOCALIZE_HH) { \ + SSPUSHPTR(GvHV(PL_hintgv)); \ + GvHV(PL_hintgv) = newHVhv(GvHV(PL_hintgv)); \ + } \ + SSPUSHINT(PL_hints); \ + SSPUSHINT(SAVEt_HINTS); \ + } STMT_END -/******************************************************************* - * JMPENV_PUSH is the old depreciated API. See perl.c for examples - * of the new API. - */ +#define SAVECOMPPAD() \ + STMT_START { \ + SSCHECK(2); \ + SSPUSHPTR((SV*)PL_comppad); \ + SSPUSHINT(SAVEt_COMPPAD); \ + } STMT_END -struct setjmpenv { - /* move to scope.c once JMPENV_PUSH is no longer needed XXX */ - JMPENV je0; - Sigjmp_buf je_buf; -}; -typedef struct setjmpenv SETJMPENV; +#define SAVESWITCHSTACK(f,t) \ + STMT_START { \ + SSCHECK(3); \ + SSPUSHPTR((SV*)(f)); \ + SSPUSHPTR((SV*)(t)); \ + SSPUSHINT(SAVEt_SAVESWITCHSTACK); \ + SWITCHSTACK((f),(t)); \ + PL_curstackinfo->si_stack = (t); \ + } STMT_END + +#ifdef USE_ITHREADS +# define SAVECOPSTASH(c) SAVEPPTR(CopSTASHPV(c)) +# define SAVECOPSTASH_FREE(c) SAVESHAREDPV(CopSTASHPV(c)) +# define SAVECOPFILE(c) SAVEPPTR(CopFILE(c)) +# define SAVECOPFILE_FREE(c) SAVESHAREDPV(CopFILE(c)) +#else +# define SAVECOPSTASH(c) SAVESPTR(CopSTASH(c)) +# define SAVECOPSTASH_FREE(c) SAVECOPSTASH(c) /* XXX not refcounted */ +# define SAVECOPFILE(c) SAVESPTR(CopFILEGV(c)) +# define SAVECOPFILE_FREE(c) SAVEGENERICSV(CopFILEGV(c)) +#endif -#define dJMPENV SETJMPENV cur_env +#define SAVECOPLINE(c) SAVEI32(CopLINE(c)) -extern void setjmp_jump(); +/* SSNEW() temporarily allocates a specified number of bytes of data on the + * savestack. It returns an integer index into the savestack, because a + * pointer would get broken if the savestack is moved on reallocation. + * SSNEWa() works like SSNEW(), but also aligns the data to the specified + * number of bytes. MEM_ALIGNBYTES is perhaps the most useful. The + * alignment will be preserved therough savestack reallocation *only* if + * realloc returns data aligned to a size divisible by "align"! + * + * SSPTR() converts the index returned by SSNEW/SSNEWa() into a pointer. + */ -#define JMPENV_PUSH(v) \ - STMT_START { \ - JMPENV_INIT(cur_env, setjmp_jump); \ - PerlProc_setjmp(cur_env.je_buf, 1); \ - JMPENV_TRY(cur_env); \ - (v) = JMPENV_STAT(cur_env); \ - } STMT_END +#define SSNEW(size) Perl_save_alloc(aTHX_ (size), 0) +#define SSNEWt(n,t) SSNEW((n)*sizeof(t)) +#define SSNEWa(size,align) Perl_save_alloc(aTHX_ (size), \ + (align - ((int)((caddr_t)&PL_savestack[PL_savestack_ix]) % align)) % align) +#define SSNEWat(n,t,align) SSNEWa((n)*sizeof(t), align) -#define JMPENV_POP \ -STMT_START { \ - assert(top_env == (JMPENV*) &cur_env); \ - top_env = cur_env.je0.je_prev; \ -} STMT_END +#define SSPTR(off,type) ((type) ((char*)PL_savestack + off)) +#define SSPTRt(off,type) ((type*) ((char*)PL_savestack + off))