xref: /plan9/sys/src/cmd/gs/src/ostack.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1991, 1994, 1996, 1998, 1999 Aladdin Enterprises.  All rights reserved.
2 
3   This software is provided AS-IS with no warranty, either express or
4   implied.
5 
6   This software is distributed under license and may not be copied,
7   modified or distributed except as expressly authorized under the terms
8   of the license contained in the file LICENSE in this distribution.
9 
10   For more information about licensing, please refer to
11   http://www.ghostscript.com/licensing/. For information on
12   commercial licensing, go to http://www.artifex.com/licensing/ or
13   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15 */
16 
17 /* $Id: ostack.h,v 1.4 2002/02/21 22:24:53 giles Exp $ */
18 /* Definitions for Ghostscript operand stack */
19 
20 #ifndef ostack_INCLUDED
21 #  define ostack_INCLUDED
22 
23 #include "iostack.h"
24 #include "icstate.h"		/* for access to op_stack */
25 
26 /* Define the operand stack pointers for operators. */
27 #define iop_stack (i_ctx_p->op_stack)
28 #define o_stack (iop_stack.stack)
29 
30 #define osbot (o_stack.bot)
31 #define osp (o_stack.p)
32 #define ostop (o_stack.top)
33 
34 /* Macro to ensure enough room on the operand stack */
35 #define check_ostack(n)\
36   if ( ostop - osp < (n) )\
37     { o_stack.requested = (n); return_error(e_stackoverflow); }
38 
39 /* Operand stack manipulation. */
40 
41 /* Note that push sets osp to (the new value of) op. */
42 #define push(n)\
43   BEGIN\
44     if ( (op += (n)) > ostop )\
45       { o_stack.requested = (n); return_error(e_stackoverflow); }\
46     else osp = op;\
47   END
48 
49 /*
50  * Note that the pop macro only decrements osp, not op.  For this reason,
51  *
52  *      >>>     pop should only be used just before returning,  <<<
53  *      >>>     or else op must be decremented explicitly.      <<<
54  */
55 #define pop(n) (osp -= (n))
56 
57 /*
58  * Note that the interpreter does not check for operand stack underflow
59  * before calling the operator procedure.  There are "guard" entries
60  * with invalid types and attributes just below the bottom of the
61  * operand stack: if the operator returns with a typecheck error,
62  * the interpreter checks for underflow at that time.
63  * Operators that don't typecheck their arguments must check for
64  * operand stack underflow explicitly; operators that take a variable
65  * number of arguments must also check for stack underflow in those cases
66  * where they expect more than their minimum number of arguments.
67  * (This is because the interpreter can only recognize that a typecheck
68  * is really a stackunderflow when the stack has fewer than the
69  * operator's declared minimum number of entries.)
70  */
71 #define check_op(nargs)\
72   if ( op < osbot + ((nargs) - 1) ) return_error(e_stackunderflow)
73 /*
74  * Similarly, in order to simplify some overflow checks, we allocate
75  * a few guard entries just above the top of the o-stack.
76  */
77 
78 /*
79  * The operand stack is implemented as a linked list of blocks:
80  * operators that can push or pop an unbounded number of values, or that
81  * access the entire o-stack, must take this into account.  These are:
82  *      (int)copy  index  roll  clear  count  cleartomark
83  *      counttomark  aload  astore  packedarray
84  *      .get/.putdeviceparams .gethardwareparams
85  */
86 
87 #endif /* ostack_INCLUDED */
88