Remove stack programs, objcode, and the old VM.
[bpt/guile.git] / libguile / programs.c
1 /* Copyright (C) 2001, 2009, 2010, 2011, 2012, 2013 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 #if HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include <string.h>
24 #include "_scm.h"
25 #include "modules.h"
26 #include "programs.h"
27 #include "procprop.h" /* scm_sym_name */
28 #include "vm.h"
29
30 \f
31 static SCM write_program = SCM_BOOL_F;
32
33 SCM_DEFINE (scm_make_rtl_program, "make-rtl-program", 1, 2, 0,
34 (SCM bytevector, SCM byte_offset, SCM free_variables),
35 "")
36 #define FUNC_NAME s_scm_make_rtl_program
37 {
38 scm_t_uint8 *code;
39 scm_t_uint32 offset;
40
41 if (!scm_is_bytevector (bytevector))
42 scm_wrong_type_arg (FUNC_NAME, 1, bytevector);
43 if (SCM_UNBNDP (byte_offset))
44 offset = 0;
45 else
46 {
47 offset = scm_to_uint32 (byte_offset);
48 if (offset > SCM_BYTEVECTOR_LENGTH (bytevector))
49 SCM_OUT_OF_RANGE (2, byte_offset);
50 }
51
52 code = (scm_t_uint8*) SCM_BYTEVECTOR_CONTENTS (bytevector) + offset;
53 if (((scm_t_uintptr) code) % 4)
54 SCM_OUT_OF_RANGE (2, byte_offset);
55
56 if (SCM_UNBNDP (free_variables) || scm_is_false (free_variables))
57 return scm_cell (scm_tc7_rtl_program, (scm_t_bits) code);
58 else
59 abort ();
60 }
61 #undef FUNC_NAME
62
63 SCM_DEFINE (scm_rtl_program_code, "rtl-program-code", 1, 0, 0,
64 (SCM program),
65 "")
66 #define FUNC_NAME s_scm_rtl_program_code
67 {
68 SCM_VALIDATE_RTL_PROGRAM (1, program);
69
70 return scm_from_uintptr_t ((scm_t_uintptr) SCM_RTL_PROGRAM_CODE (program));
71 }
72 #undef FUNC_NAME
73
74 SCM
75 scm_i_rtl_program_name (SCM program)
76 {
77 static SCM rtl_program_name = SCM_BOOL_F;
78
79 if (SCM_PRIMITIVE_P (program))
80 return SCM_SUBR_NAME (program);
81
82 if (scm_is_false (rtl_program_name) && scm_module_system_booted_p)
83 rtl_program_name =
84 scm_c_private_variable ("system vm program", "rtl-program-name");
85
86 return scm_call_1 (scm_variable_ref (rtl_program_name), program);
87 }
88
89 SCM
90 scm_i_rtl_program_documentation (SCM program)
91 {
92 static SCM rtl_program_documentation = SCM_BOOL_F;
93
94 if (SCM_PRIMITIVE_P (program))
95 return SCM_BOOL_F;
96
97 if (scm_is_false (rtl_program_documentation) && scm_module_system_booted_p)
98 rtl_program_documentation =
99 scm_c_private_variable ("system vm program",
100 "rtl-program-documentation");
101
102 return scm_call_1 (scm_variable_ref (rtl_program_documentation), program);
103 }
104
105 SCM
106 scm_i_rtl_program_properties (SCM program)
107 {
108 static SCM rtl_program_properties = SCM_BOOL_F;
109
110 if (SCM_PRIMITIVE_P (program))
111 {
112 SCM name = scm_i_rtl_program_name (program);
113 if (scm_is_false (name))
114 return SCM_EOL;
115 return scm_acons (scm_sym_name, name, SCM_EOL);
116 }
117
118 if (scm_is_false (rtl_program_properties) && scm_module_system_booted_p)
119 rtl_program_properties =
120 scm_c_private_variable ("system vm program", "rtl-program-properties");
121
122 return scm_call_1 (scm_variable_ref (rtl_program_properties), program);
123 }
124
125 void
126 scm_i_program_print (SCM program, SCM port, scm_print_state *pstate)
127 {
128 static int print_error = 0;
129
130 if (scm_is_false (write_program) && scm_module_system_booted_p)
131 write_program = scm_c_private_variable ("system vm program",
132 "write-program");
133
134 if (SCM_PROGRAM_IS_CONTINUATION (program))
135 {
136 /* twingliness */
137 scm_puts_unlocked ("#<continuation ", port);
138 scm_uintprint (SCM_UNPACK (program), 16, port);
139 scm_putc_unlocked ('>', port);
140 }
141 else if (SCM_PROGRAM_IS_PARTIAL_CONTINUATION (program))
142 {
143 /* twingliness */
144 scm_puts_unlocked ("#<partial-continuation ", port);
145 scm_uintprint (SCM_UNPACK (program), 16, port);
146 scm_putc_unlocked ('>', port);
147 }
148 else if (scm_is_false (write_program) || print_error)
149 {
150 scm_puts_unlocked ("#<rtl-program ", port);
151 scm_uintprint (SCM_UNPACK (program), 16, port);
152 scm_putc_unlocked (' ', port);
153 scm_uintprint ((scm_t_uintptr) SCM_RTL_PROGRAM_CODE (program), 16, port);
154 scm_putc_unlocked ('>', port);
155 }
156 else
157 {
158 print_error = 1;
159 scm_call_2 (SCM_VARIABLE_REF (write_program), program, port);
160 print_error = 0;
161 }
162 }
163
164 \f
165 /*
166 * Scheme interface
167 */
168
169 SCM_DEFINE (scm_rtl_program_p, "rtl-program?", 1, 0, 0,
170 (SCM obj),
171 "")
172 #define FUNC_NAME s_scm_rtl_program_p
173 {
174 return scm_from_bool (SCM_RTL_PROGRAM_P (obj));
175 }
176 #undef FUNC_NAME
177
178 SCM_DEFINE (scm_primitive_p, "primitive?", 1, 0, 0,
179 (SCM obj),
180 "")
181 #define FUNC_NAME s_scm_primitive_p
182 {
183 return scm_from_bool (SCM_PRIMITIVE_P (obj));
184 }
185 #undef FUNC_NAME
186
187 SCM_DEFINE (scm_primitive_call_ip, "primitive-call-ip", 1, 0, 0,
188 (SCM prim),
189 "")
190 #define FUNC_NAME s_scm_primitive_p
191 {
192 SCM_MAKE_VALIDATE (1, prim, PRIMITIVE_P);
193
194 return scm_from_uintptr_t (scm_i_primitive_call_ip (prim));
195 }
196 #undef FUNC_NAME
197
198 SCM
199 scm_find_source_for_addr (SCM ip)
200 {
201 static SCM source_for_addr = SCM_BOOL_F;
202
203 if (scm_is_false (source_for_addr)) {
204 if (!scm_module_system_booted_p)
205 return SCM_BOOL_F;
206
207 source_for_addr =
208 scm_c_private_variable ("system vm program", "source-for-addr");
209 }
210
211 return scm_call_1 (scm_variable_ref (source_for_addr), ip);
212 }
213
214 SCM
215 scm_program_source (SCM program, SCM ip, SCM sources)
216 {
217 static SCM program_source = SCM_BOOL_F;
218
219 if (scm_is_false (program_source)) {
220 if (!scm_module_system_booted_p)
221 return SCM_BOOL_F;
222
223 program_source =
224 scm_c_private_variable ("system vm program", "program-source");
225 }
226
227 if (SCM_UNBNDP (sources))
228 return scm_call_2 (scm_variable_ref (program_source), program, ip);
229 else
230 return scm_call_3 (scm_variable_ref (program_source), program, ip, sources);
231 }
232
233 SCM_DEFINE (scm_program_num_free_variables, "program-num-free-variables", 1, 0, 0,
234 (SCM program),
235 "")
236 #define FUNC_NAME s_scm_program_num_free_variables
237 {
238 SCM_VALIDATE_RTL_PROGRAM (1, program);
239
240 return scm_from_ulong (SCM_RTL_PROGRAM_NUM_FREE_VARIABLES (program));
241 }
242 #undef FUNC_NAME
243
244 SCM_DEFINE (scm_program_free_variable_ref, "program-free-variable-ref", 2, 0, 0,
245 (SCM program, SCM i),
246 "")
247 #define FUNC_NAME s_scm_program_free_variable_ref
248 {
249 unsigned long idx;
250
251 SCM_VALIDATE_RTL_PROGRAM (1, program);
252 SCM_VALIDATE_ULONG_COPY (2, i, idx);
253 if (idx >= SCM_RTL_PROGRAM_NUM_FREE_VARIABLES (program))
254 SCM_OUT_OF_RANGE (2, i);
255 return SCM_RTL_PROGRAM_FREE_VARIABLE_REF (program, idx);
256 }
257 #undef FUNC_NAME
258
259 SCM_DEFINE (scm_program_free_variable_set_x, "program-free-variable-set!", 3, 0, 0,
260 (SCM program, SCM i, SCM x),
261 "")
262 #define FUNC_NAME s_scm_program_free_variable_set_x
263 {
264 unsigned long idx;
265
266 SCM_VALIDATE_RTL_PROGRAM (1, program);
267 SCM_VALIDATE_ULONG_COPY (2, i, idx);
268 if (idx >= SCM_RTL_PROGRAM_NUM_FREE_VARIABLES (program))
269 SCM_OUT_OF_RANGE (2, i);
270 SCM_RTL_PROGRAM_FREE_VARIABLE_SET (program, idx, x);
271 return SCM_UNSPECIFIED;
272 }
273 #undef FUNC_NAME
274
275 int
276 scm_i_program_arity (SCM program, int *req, int *opt, int *rest)
277 {
278 static SCM rtl_program_minimum_arity = SCM_BOOL_F;
279 SCM l;
280
281 if (SCM_PRIMITIVE_P (program))
282 return scm_i_primitive_arity (program, req, opt, rest);
283
284 if (SCM_PROGRAM_IS_FOREIGN (program))
285 return scm_i_foreign_arity (program, req, opt, rest);
286
287 if (SCM_PROGRAM_IS_CONTINUATION (program)
288 || SCM_PROGRAM_IS_PARTIAL_CONTINUATION (program))
289 {
290 *req = *opt = 0;
291 *rest = 1;
292 return 1;
293 }
294
295 if (scm_is_false (rtl_program_minimum_arity) && scm_module_system_booted_p)
296 rtl_program_minimum_arity =
297 scm_c_private_variable ("system vm program",
298 "rtl-program-minimum-arity");
299
300 l = scm_call_1 (scm_variable_ref (rtl_program_minimum_arity), program);
301 if (scm_is_false (l))
302 return 0;
303
304 *req = scm_to_int (scm_car (l));
305 *opt = scm_to_int (scm_cadr (l));
306 *rest = scm_is_true (scm_caddr (l));
307
308 return 1;
309 }
310
311 \f
312
313 void
314 scm_bootstrap_programs (void)
315 {
316 scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
317 "scm_init_programs",
318 (scm_t_extension_init_func)scm_init_programs, NULL);
319 }
320
321 void
322 scm_init_programs (void)
323 {
324 #ifndef SCM_MAGIC_SNARFER
325 #include "libguile/programs.x"
326 #endif
327 }
328
329 /*
330 Local Variables:
331 c-file-style: "gnu"
332 End:
333 */