estack.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /* Copyright (C) 1989, 1992, 1993, 1994, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
  2. This software is provided AS-IS with no warranty, either express or
  3. implied.
  4. This software is distributed under license and may not be copied,
  5. modified or distributed except as expressly authorized under the terms
  6. of the license contained in the file LICENSE in this distribution.
  7. For more information about licensing, please refer to
  8. http://www.ghostscript.com/licensing/. For information on
  9. commercial licensing, go to http://www.artifex.com/licensing/ or
  10. contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. San Rafael, CA 94903, U.S.A., +1(415)492-9861.
  12. */
  13. /* $Id: estack.h,v 1.6 2002/06/16 04:47:10 lpd Exp $ */
  14. /* Definitions for the execution stack */
  15. #ifndef estack_INCLUDED
  16. # define estack_INCLUDED
  17. #include "iestack.h"
  18. #include "icstate.h" /* for access to exec_stack */
  19. /* Define access to the cached current_file pointer. */
  20. #define esfile (iexec_stack.current_file)
  21. #define esfile_clear_cache() estack_clear_cache(&iexec_stack)
  22. #define esfile_set_cache(pref) estack_set_cache(&iexec_stack, pref)
  23. #define esfile_check_cache() estack_check_cache(&iexec_stack)
  24. /* Define the execution stack pointers for operators. */
  25. #define iexec_stack (i_ctx_p->exec_stack)
  26. #define e_stack (iexec_stack.stack)
  27. #define esbot (e_stack.bot)
  28. #define esp (e_stack.p)
  29. #define estop (e_stack.top)
  30. /*
  31. * The execution stack holds several different kinds of objects (refs)
  32. * related to executing PostScript code:
  33. *
  34. * - Procedures being executed are held here. They always have
  35. * type = t_array, t_mixedarray, or t_shortarray, with a_executable set.
  36. * More specifically, the e-stack holds the as yet unexecuted tail of the
  37. * procedure.
  38. *
  39. * - if, ifelse, etc. push arguments to be executed here. They may be
  40. * any kind of object whatever. Similarly, looping operators (forall, for,
  41. * etc.) push the procedure that is to be executed for each iteration.
  42. *
  43. * - Control operators (filenameforall, for, repeat, loop, forall,
  44. * pathforall, run, stopped, ...) use continuations as described below.
  45. *
  46. * Note that there are many internal operators that need to use
  47. * continuations -- for example, all the 'show' operators, since they may
  48. * call out to BuildChar procedures.
  49. */
  50. /*
  51. * Because the Ghostscript architecture doesn't allow recursive calls to the
  52. * interpreter, any operator that needs to call out to PostScript code (for
  53. * example, the 'show' operators calling a BuildChar procedure, or setscreen
  54. * sampling a spot function) must use a continuation -- an internal
  55. * "operator" procedure that continues the logical thread of execution after
  56. * the callout. Operators needing to use continuations push the following
  57. * onto the execution stack (from bottom to top):
  58. *
  59. * - An e-stack mark -- an executable null that indicates the bottom of
  60. * the block associated with a callout. (This should not be confused
  61. * with a PostScript mark, a ref of type t_mark on the operand stack.)
  62. * See make_mark_estack and push_mark_estack below. The value.opproc
  63. * member of the e-stack mark contains a procedure to execute in case
  64. * the e-stack is stripped back beyond this point by a 'stop' or
  65. * 'exit': see pop_estack in zcontrol.c for details.
  66. *
  67. * - Any number of refs holding information that the continuation
  68. * operator needs -- i.e., the saved logical state of the thread of
  69. * execution. For example, 'for' stores the procedure, the current
  70. * value, the increment, and the limit here.
  71. *
  72. * - The continuation procedure itself -- the pseudo-operator to be
  73. * called after returns from the interpreter callout. See
  74. * make_op_estack and push_op_estack below.
  75. *
  76. * - The PostScript procedure for the interpreter to execute.
  77. *
  78. * The operator then returns o_push_estack, indicating to the interpreter
  79. * that the operator has pushed information on the e-stack for the
  80. * interpreter to process.
  81. *
  82. * When the interpreter finishes executing the PostScript procedure, it pops
  83. * the next item off the e-stack, which is the continuation procedure. When
  84. * the continuation procedure gets control, the top of the e-stack (esp)
  85. * points just below the continuation procedure slot -- i.e., to the topmost
  86. * saved state item. The continuation procedure normally pops all of the
  87. * saved state, and the e-stack mark, and continues execution normally,
  88. * eventually returning o_pop_estack to tell the interpreter that the
  89. * "operator" has popped information off the e-stack. (Loop operators do
  90. * something a bit more efficient than popping the information and then
  91. * pushing it again: refer to the examples in zcontrol.c for details.)
  92. *
  93. * Continuation procedures are called just like any other operator, so they
  94. * can call each other, or be called from ordinary operator procedures, as
  95. * long as the e-stack is in the right state. The most complex example of
  96. * this is probably the Type 1 character rendering code in zchar1.c, where
  97. * continuation procedures either call each other directly or call out to
  98. * the interpreter to execute optional PostScript procedures like CDevProc.
  99. */
  100. /* Macro for marking the execution stack */
  101. #define make_mark_estack(ep, es_idx, proc)\
  102. make_tasv(ep, t_null, a_executable, es_idx, opproc, proc)
  103. #define push_mark_estack(es_idx, proc)\
  104. (++esp, make_mark_estack(esp, es_idx, proc))
  105. #define r_is_estack_mark(ep)\
  106. r_has_type_attrs(ep, t_null, a_executable)
  107. #define estack_mark_index(ep) r_size(ep)
  108. #define set_estack_mark_index(ep, es_idx) r_set_size(ep, es_idx)
  109. /* Macro for pushing an operator on the execution stack */
  110. /* to represent a continuation procedure */
  111. #define make_op_estack(ep, proc)\
  112. make_oper(ep, 0, proc)
  113. #define push_op_estack(proc)\
  114. (++esp, make_op_estack(esp, proc))
  115. /* Macro to ensure enough room on the execution stack */
  116. #define check_estack(n)\
  117. if ( esp > estop - (n) )\
  118. { int es_code_ = ref_stack_extend(&e_stack, n);\
  119. if ( es_code_ < 0 ) return es_code_;\
  120. }
  121. /* Macro to ensure enough entries on the execution stack */
  122. #define check_esp(n)\
  123. if ( esp < esbot + ((n) - 1) )\
  124. { e_stack.requested = (n); return_error(e_ExecStackUnderflow); }
  125. /* Define the various kinds of execution stack marks. */
  126. #define es_other 0 /* internal use */
  127. #define es_show 1 /* show operators */
  128. #define es_for 2 /* iteration operators */
  129. #define es_stopped 3 /* stopped operator */
  130. /*
  131. * Pop a given number of elements off the execution stack,
  132. * executing cleanup procedures as necessary.
  133. */
  134. void pop_estack(i_ctx_t *, uint);
  135. /*
  136. * The execution stack is implemented as a linked list of blocks;
  137. * operators that can push or pop an unbounded number of values, or that
  138. * access the entire e-stack, must take this into account. These are:
  139. * exit .stop .instopped countexecstack execstack currentfile
  140. * .execn
  141. * pop_estack(exit, stop, error recovery)
  142. * gs_show_find(all the show operators)
  143. * In addition, for e-stack entries created by control operators, we must
  144. * ensure that the mark and its data are never separated. We do this
  145. * by ensuring that when splitting the top block, at least N items
  146. * are kept in the new top block above the bottommost retained mark,
  147. * where N is the largest number of data items associated with a mark.
  148. * Finally, in order to avoid specific checks for underflowing a block,
  149. * we put a guard entry at the bottom of each block except the top one
  150. * that contains a procedure that returns an internal "exec stack block
  151. * underflow" error.
  152. */
  153. #endif /* estack_INCLUDED */