Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

385 lines
13 KiB

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