1 /* Copyright (C) 2001, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
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.
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.
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
19 #ifndef _SCM_FRAMES_H_
20 #define _SCM_FRAMES_H_
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_..
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.
44 | Intermed. val. 0 | <- fp + nargs + nlocs
47 | Local variable 0 | <- fp + nargs
49 | Argument 0 | <- fp = SCM_FRAME_STACK_ADDRESS (fp)
52 | Return address | <- SCM_FRAME_UPPER_ADDRESS (fp)
54 | Dynamic link | <- fp - 4 = SCM_FRAME_DATA_ADDRESS (fp) = SCM_FRAME_LOWER_ADDRESS (fp)
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. */
62 /* This structure maps to the contents of a VM stack frame. It can
63 alias a frame directly. */
67 scm_t_uint8
*mv_return_address
;
68 scm_t_uint8
*return_address
;
70 SCM stack
[1]; /* Variable-length */
73 #define SCM_FRAME_STRUCT(fp) \
74 ((struct scm_vm_frame *) SCM_FRAME_DATA_ADDRESS (fp))
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))
81 #define SCM_FRAME_BYTE_CAST(x) ((scm_t_uint8 *) SCM_UNPACK (x))
82 #define SCM_FRAME_STACK_CAST(x) ((SCM *) SCM_UNPACK (x))
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_SET_MV_RETURN_ADDRESS(fp, mvra) \
89 SCM_FRAME_STRUCT (fp)->mv_return_address = (mvra)
90 #define SCM_FRAME_DYNAMIC_LINK(fp) \
91 (SCM_FRAME_STRUCT (fp)->dynamic_link)
92 #define SCM_FRAME_SET_DYNAMIC_LINK(fp, dl) \
93 SCM_FRAME_DYNAMIC_LINK (fp) = (dl)
94 #define SCM_FRAME_VARIABLE(fp,i) \
95 (SCM_FRAME_STRUCT (fp)->stack[i])
96 #define SCM_FRAME_PROGRAM(fp) \
97 (SCM_FRAME_STRUCT (fp)->program)
104 /* The frame format for the new RTL programs is almost like that for the
105 stack-vm programs. They differ in their handling of MV returns,
106 however. For RTL, every call is an MV call: every call has an MVRA.
107 Unlike the stack-vm programs, the MVRA for RTL programs is computable
108 from the RA -- it's always one word (4 bytes) before the RA.
110 Until we completely migrate to the RTL VM, we will also write the
113 When an RTL program returns multiple values, it will shuffle them
114 down to start contiguously from slot 0, as for a tail call. This
115 means that when the caller goes to access them, there are 2 or 3
116 empty words between the top of the caller stack and the bottom of the
117 values, corresponding to the frame that was just popped.
120 #define SCM_FRAME_RTL_RETURN_ADDRESS(fp) \
121 ((scm_t_uint32 *) SCM_FRAME_RETURN_ADDRESS (fp))
122 #define SCM_FRAME_SET_RTL_RETURN_ADDRESS(fp, ip) \
123 SCM_FRAME_SET_RETURN_ADDRESS (fp, (scm_t_uint8 *) (ip))
125 #define SCM_FRAME_SET_RTL_MV_RETURN_ADDRESS(fp, ip) \
126 SCM_FRAME_SET_MV_RETURN_ADDRESS (fp, (scm_t_uint8 *) (ip))
139 scm_t_ptrdiff offset
;
142 #define SCM_VM_FRAME_P(x) (SCM_HAS_TYP7 (x, scm_tc7_frame))
143 #define SCM_VM_FRAME_DATA(x) ((struct scm_frame*)SCM_CELL_WORD_1 (x))
144 #define SCM_VM_FRAME_STACK_HOLDER(f) SCM_VM_FRAME_DATA(f)->stack_holder
145 #define SCM_VM_FRAME_FP(f) SCM_VM_FRAME_DATA(f)->fp
146 #define SCM_VM_FRAME_SP(f) SCM_VM_FRAME_DATA(f)->sp
147 #define SCM_VM_FRAME_IP(f) SCM_VM_FRAME_DATA(f)->ip
148 #define SCM_VM_FRAME_OFFSET(f) SCM_VM_FRAME_DATA(f)->offset
149 #define SCM_VALIDATE_VM_FRAME(p,x) SCM_MAKE_VALIDATE (p, x, VM_FRAME_P)
151 SCM_API SCM
scm_c_make_frame (SCM stack_holder
, SCM
*fp
, SCM
*sp
,
152 scm_t_uint8
*ip
, scm_t_ptrdiff offset
);
153 SCM_API SCM
scm_frame_p (SCM obj
);
154 SCM_API SCM
scm_frame_procedure (SCM frame
);
155 SCM_API SCM
scm_frame_arguments (SCM frame
);
156 SCM_API SCM
scm_frame_source (SCM frame
);
157 SCM_API SCM
scm_frame_num_locals (SCM frame
);
158 SCM_API SCM
scm_frame_local_ref (SCM frame
, SCM index
);
159 SCM_API SCM
scm_frame_local_set_x (SCM frame
, SCM index
, SCM val
);
160 SCM_API SCM
scm_frame_address (SCM frame
);
161 SCM_API SCM
scm_frame_stack_pointer (SCM frame
);
162 SCM_API SCM
scm_frame_instruction_pointer (SCM frame
);
163 SCM_API SCM
scm_frame_return_address (SCM frame
);
164 SCM_API SCM
scm_frame_dynamic_link (SCM frame
);
165 SCM_API SCM
scm_frame_previous (SCM frame
);
167 SCM_INTERNAL
void scm_i_frame_print (SCM frame
, SCM port
,
168 scm_print_state
*pstate
);
169 SCM_INTERNAL
void scm_init_frames (void);
171 #endif /* _SCM_FRAMES_H_ */