Merge remote-tracking branch 'origin/stable-2.0'
[bpt/guile.git] / libguile / frames.h
1 /* Copyright (C) 2001, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
2 * *
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public License
5 * as published by the Free Software Foundation; either version 3 of
6 * the License, or (at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 * 02110-1301 USA
17 */
18
19 #ifndef _SCM_FRAMES_H_
20 #define _SCM_FRAMES_H_
21
22 #include <libguile.h>
23 #include "programs.h"
24
25 \f
26 /*
27 * VM frames
28 */
29
30 /*
31 * It's a little confusing, but there are two representations of frames in this
32 * file: frame pointers and Scheme objects wrapping those frame pointers. The
33 * former uses the SCM_FRAME_... macro prefix, the latter SCM_VM_FRAME_..
34 * prefix.
35 *
36 * The confusing thing is that only Scheme frame objects have functions that use
37 * them, and they use the scm_frame_.. prefix. Hysterical raisins.
38 */
39
40 /* VM Frame Layout
41 ---------------
42
43 | ... |
44 | Intermed. val. 0 | <- fp + nargs + nlocs
45 +------------------+
46 | Local variable 1 |
47 | Local variable 0 | <- fp + nargs
48 | Argument 1 |
49 | Argument 0 | <- fp = SCM_FRAME_STACK_ADDRESS (fp)
50 | Program | <- fp - 1
51 +==================+
52 | Return address | <- SCM_FRAME_UPPER_ADDRESS (fp)
53 | MV return address|
54 | Dynamic link | <- fp - 4 = SCM_FRAME_DATA_ADDRESS (fp) = SCM_FRAME_LOWER_ADDRESS (fp)
55 +==================+
56 | |
57
58 As can be inferred from this drawing, it is assumed that
59 `sizeof (SCM *) == sizeof (SCM)', since pointers (the `link' parts) are
60 assumed to be as long as SCM objects. */
61
62 /* This structure maps to the contents of a VM stack frame. It can
63 alias a frame directly. */
64 struct scm_vm_frame
65 {
66 SCM *dynamic_link;
67 scm_t_uint8 *mv_return_address;
68 scm_t_uint8 *return_address;
69 SCM program;
70 SCM stack[1]; /* Variable-length */
71 };
72
73 #define SCM_FRAME_STRUCT(fp) \
74 ((struct scm_vm_frame *) SCM_FRAME_DATA_ADDRESS (fp))
75
76 #define SCM_FRAME_DATA_ADDRESS(fp) (((SCM *) (fp)) - 4)
77 #define SCM_FRAME_STACK_ADDRESS(fp) (SCM_FRAME_STRUCT (fp)->stack)
78 #define SCM_FRAME_UPPER_ADDRESS(fp) ((SCM*)&SCM_FRAME_STRUCT (fp)->return_address)
79 #define SCM_FRAME_LOWER_ADDRESS(fp) ((SCM*)SCM_FRAME_STRUCT (fp))
80
81 #define SCM_FRAME_BYTE_CAST(x) ((scm_t_uint8 *) SCM_UNPACK (x))
82 #define SCM_FRAME_STACK_CAST(x) ((SCM *) SCM_UNPACK (x))
83
84 #define SCM_FRAME_RETURN_ADDRESS(fp) \
85 (SCM_FRAME_STRUCT (fp)->return_address)
86 #define SCM_FRAME_SET_RETURN_ADDRESS(fp, ra) \
87 SCM_FRAME_STRUCT (fp)->return_address = (ra)
88 #define SCM_FRAME_MV_RETURN_ADDRESS(fp) \
89 (SCM_FRAME_STRUCT (fp)->mv_return_address)
90 #define SCM_FRAME_SET_MV_RETURN_ADDRESS(fp, mvra) \
91 SCM_FRAME_STRUCT (fp)->mv_return_address = (mvra)
92 #define SCM_FRAME_DYNAMIC_LINK(fp) \
93 (SCM_FRAME_STRUCT (fp)->dynamic_link)
94 #define SCM_FRAME_SET_DYNAMIC_LINK(fp, dl) \
95 SCM_FRAME_DYNAMIC_LINK (fp) = (dl)
96 #define SCM_FRAME_VARIABLE(fp,i) \
97 (SCM_FRAME_STRUCT (fp)->stack[i])
98 #define SCM_FRAME_PROGRAM(fp) \
99 (SCM_FRAME_STRUCT (fp)->program)
100
101 \f
102 /*
103 * RTL frames
104 */
105
106 /* The frame format for the new RTL programs is almost like that for the
107 stack-vm programs. They differ in their handling of MV returns,
108 however. For RTL, every call is an MV call: every call has an MVRA.
109 Unlike the stack-vm programs, the MVRA for RTL programs is computable
110 from the RA -- it's always one word (4 bytes) before the RA.
111
112 Until we completely migrate to the RTL VM, we will also write the
113 MVRA to the stack.
114
115 When an RTL program returns multiple values, it will shuffle them
116 down to start contiguously from slot 0, as for a tail call. This
117 means that when the caller goes to access them, there are 2 or 3
118 empty words between the top of the caller stack and the bottom of the
119 values, corresponding to the frame that was just popped.
120 */
121
122 #define SCM_FRAME_RTL_RETURN_ADDRESS(fp) \
123 ((scm_t_uint32 *) SCM_FRAME_RETURN_ADDRESS (fp))
124 #define SCM_FRAME_SET_RTL_RETURN_ADDRESS(fp, ip) \
125 SCM_FRAME_SET_RETURN_ADDRESS (fp, (scm_t_uint8 *) (ip))
126
127 #define SCM_FRAME_RTL_MV_RETURN_ADDRESS(fp) \
128 ((scm_t_uint32 *) SCM_FRAME_MV_RETURN_ADDRESS (fp))
129 #define SCM_FRAME_SET_RTL_MV_RETURN_ADDRESS(fp, ip) \
130 SCM_FRAME_SET_MV_RETURN_ADDRESS (fp, (scm_t_uint8 *) (ip))
131
132 \f
133 /*
134 * Heap frames
135 */
136
137 struct scm_frame
138 {
139 SCM stack_holder;
140 SCM *fp;
141 SCM *sp;
142 scm_t_uint8 *ip;
143 scm_t_ptrdiff offset;
144 };
145
146 #define SCM_VM_FRAME_P(x) (SCM_HAS_TYP7 (x, scm_tc7_frame))
147 #define SCM_VM_FRAME_DATA(x) ((struct scm_frame*)SCM_CELL_WORD_1 (x))
148 #define SCM_VM_FRAME_STACK_HOLDER(f) SCM_VM_FRAME_DATA(f)->stack_holder
149 #define SCM_VM_FRAME_FP(f) SCM_VM_FRAME_DATA(f)->fp
150 #define SCM_VM_FRAME_SP(f) SCM_VM_FRAME_DATA(f)->sp
151 #define SCM_VM_FRAME_IP(f) SCM_VM_FRAME_DATA(f)->ip
152 #define SCM_VM_FRAME_OFFSET(f) SCM_VM_FRAME_DATA(f)->offset
153 #define SCM_VALIDATE_VM_FRAME(p,x) SCM_MAKE_VALIDATE (p, x, VM_FRAME_P)
154
155 SCM_API SCM scm_c_make_frame (SCM stack_holder, SCM *fp, SCM *sp,
156 scm_t_uint8 *ip, scm_t_ptrdiff offset);
157 SCM_API SCM scm_frame_p (SCM obj);
158 SCM_API SCM scm_frame_procedure (SCM frame);
159 SCM_API SCM scm_frame_arguments (SCM frame);
160 SCM_API SCM scm_frame_source (SCM frame);
161 SCM_API SCM scm_frame_num_locals (SCM frame);
162 SCM_API SCM scm_frame_local_ref (SCM frame, SCM index);
163 SCM_API SCM scm_frame_local_set_x (SCM frame, SCM index, SCM val);
164 SCM_API SCM scm_frame_address (SCM frame);
165 SCM_API SCM scm_frame_stack_pointer (SCM frame);
166 SCM_API SCM scm_frame_instruction_pointer (SCM frame);
167 SCM_API SCM scm_frame_return_address (SCM frame);
168 SCM_API SCM scm_frame_mv_return_address (SCM frame);
169 SCM_API SCM scm_frame_dynamic_link (SCM frame);
170 SCM_API SCM scm_frame_previous (SCM frame);
171
172 SCM_INTERNAL void scm_i_frame_print (SCM frame, SCM port,
173 scm_print_state *pstate);
174 SCM_INTERNAL void scm_init_frames (void);
175
176 #endif /* _SCM_FRAMES_H_ */
177
178 /*
179 Local Variables:
180 c-file-style: "gnu"
181 End:
182 */