tweaks for printing programs
[bpt/guile.git] / libguile / programs.c
1 /* Copyright (C) 2001 Free Software Foundation, Inc.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
17 *
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
20 *
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
26 *
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
29 *
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
37 *
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
40 * If you do not wish that, delete this exception notice. */
41
42 #if HAVE_CONFIG_H
43 # include <config.h>
44 #endif
45
46 #include <string.h>
47 #include "vm-bootstrap.h"
48 #include "instructions.h"
49 #include "modules.h"
50 #include "programs.h"
51 #include "vm.h"
52
53 \f
54 scm_t_bits scm_tc16_program;
55
56 static SCM zero_vector;
57 static SCM write_program = SCM_BOOL_F;
58
59 SCM
60 scm_c_make_program (void *addr, size_t size, SCM holder)
61 #define FUNC_NAME "scm_c_make_program"
62 {
63 struct scm_program *p = scm_gc_malloc (sizeof (struct scm_program),
64 "program");
65 p->size = size;
66 p->nargs = 0;
67 p->nrest = 0;
68 p->nlocs = 0;
69 p->nexts = 0;
70 p->meta = SCM_BOOL_F;
71 p->objs = zero_vector;
72 p->external = SCM_EOL;
73 p->holder = holder;
74 p->module = scm_current_module ();
75
76 /* If nobody holds bytecode's address, then allocate a new memory */
77 if (SCM_FALSEP (holder))
78 {
79 p->base = scm_gc_malloc (size, "program-base");
80 memcpy (p->base, addr, size);
81 }
82 else
83 p->base = addr;
84
85 SCM_RETURN_NEWSMOB (scm_tc16_program, p);
86 }
87 #undef FUNC_NAME
88
89 SCM
90 scm_c_make_closure (SCM program, SCM external)
91 {
92 SCM prog = scm_c_make_program (0, 0, program);
93 *SCM_PROGRAM_DATA (prog) = *SCM_PROGRAM_DATA (program);
94 SCM_PROGRAM_DATA (prog)->external = external;
95 return prog;
96 }
97
98 static SCM
99 program_mark (SCM obj)
100 {
101 struct scm_program *p = SCM_PROGRAM_DATA (obj);
102 scm_gc_mark (p->meta);
103 scm_gc_mark (p->objs);
104 scm_gc_mark (p->external);
105 scm_gc_mark (p->module);
106 return p->holder;
107 }
108
109 static scm_sizet
110 program_free (SCM obj)
111 {
112 struct scm_program *p = SCM_PROGRAM_DATA (obj);
113 scm_sizet size = (sizeof (struct scm_program));
114
115 if (SCM_FALSEP (p->holder))
116 scm_gc_free (p->base, p->size, "program-base");
117
118 scm_gc_free (p, size, "program");
119
120 return 0;
121 }
122
123 static SCM
124 program_apply (SCM program, SCM args)
125 {
126 return scm_vm_apply (scm_the_vm (), program, args);
127 }
128
129 static int
130 program_print (SCM program, SCM port, scm_print_state *pstate)
131 {
132 static int print_error = 0;
133
134 if (SCM_FALSEP (write_program))
135 write_program = scm_module_local_variable
136 (scm_c_resolve_module ("system vm program"),
137 scm_from_locale_symbol ("write-program"));
138
139 if (SCM_FALSEP (write_program) || print_error)
140 return scm_smob_print (program, port, pstate);
141
142 print_error = 1;
143 scm_call_2 (SCM_VARIABLE_REF (write_program), program, port);
144 print_error = 0;
145 return 1;
146 }
147
148 \f
149 /*
150 * Scheme interface
151 */
152
153 SCM_DEFINE (scm_program_p, "program?", 1, 0, 0,
154 (SCM obj),
155 "")
156 #define FUNC_NAME s_scm_program_p
157 {
158 return SCM_BOOL (SCM_PROGRAM_P (obj));
159 }
160 #undef FUNC_NAME
161
162 SCM_DEFINE (scm_program_base, "program-base", 1, 0, 0,
163 (SCM program),
164 "")
165 #define FUNC_NAME s_scm_program_base
166 {
167 SCM_VALIDATE_PROGRAM (1, program);
168
169 return scm_from_ulong ((unsigned long) SCM_PROGRAM_DATA (program)->base);
170 }
171 #undef FUNC_NAME
172
173 SCM_DEFINE (scm_program_arity, "program-arity", 1, 0, 0,
174 (SCM program),
175 "")
176 #define FUNC_NAME s_scm_program_arity
177 {
178 struct scm_program *p;
179
180 SCM_VALIDATE_PROGRAM (1, program);
181
182 p = SCM_PROGRAM_DATA (program);
183 return SCM_LIST4 (SCM_I_MAKINUM (p->nargs),
184 SCM_I_MAKINUM (p->nrest),
185 SCM_I_MAKINUM (p->nlocs),
186 SCM_I_MAKINUM (p->nexts));
187 }
188 #undef FUNC_NAME
189
190 SCM_DEFINE (scm_program_meta, "program-meta", 1, 0, 0,
191 (SCM program),
192 "")
193 #define FUNC_NAME s_scm_program_meta
194 {
195 SCM_VALIDATE_PROGRAM (1, program);
196 return SCM_PROGRAM_DATA (program)->meta;
197 }
198 #undef FUNC_NAME
199
200 SCM_DEFINE (scm_program_objects, "program-objects", 1, 0, 0,
201 (SCM program),
202 "")
203 #define FUNC_NAME s_scm_program_objects
204 {
205 SCM_VALIDATE_PROGRAM (1, program);
206 return SCM_PROGRAM_DATA (program)->objs;
207 }
208 #undef FUNC_NAME
209
210 SCM_DEFINE (scm_program_module, "program-module", 1, 0, 0,
211 (SCM program),
212 "")
213 #define FUNC_NAME s_scm_program_module
214 {
215 SCM_VALIDATE_PROGRAM (1, program);
216 return SCM_PROGRAM_DATA (program)->module;
217 }
218 #undef FUNC_NAME
219
220 SCM_DEFINE (scm_program_external, "program-external", 1, 0, 0,
221 (SCM program),
222 "")
223 #define FUNC_NAME s_scm_program_external
224 {
225 SCM_VALIDATE_PROGRAM (1, program);
226 return SCM_PROGRAM_DATA (program)->external;
227 }
228 #undef FUNC_NAME
229
230 SCM_DEFINE (scm_program_external_set_x, "program-external-set!", 2, 0, 0,
231 (SCM program, SCM external),
232 "Modify the list of closure variables of @var{program} (for "
233 "debugging purposes).")
234 #define FUNC_NAME s_scm_program_external_set_x
235 {
236 SCM_VALIDATE_PROGRAM (1, program);
237 SCM_VALIDATE_LIST (2, external);
238 SCM_PROGRAM_DATA (program)->external = external;
239 return SCM_UNSPECIFIED;
240 }
241 #undef FUNC_NAME
242
243 SCM_DEFINE (scm_program_bytecode, "program-bytecode", 1, 0, 0,
244 (SCM program),
245 "Return a u8vector containing @var{program}'s bytecode.")
246 #define FUNC_NAME s_scm_program_bytecode
247 {
248 size_t size;
249 scm_t_uint8 *c_bytecode;
250
251 SCM_VALIDATE_PROGRAM (1, program);
252
253 size = SCM_PROGRAM_DATA (program)->size;
254 c_bytecode = malloc (size);
255 if (!c_bytecode)
256 return SCM_BOOL_F;
257
258 memcpy (c_bytecode, SCM_PROGRAM_DATA (program)->base, size);
259
260 return scm_take_u8vector (c_bytecode, size);
261 }
262 #undef FUNC_NAME
263
264
265 \f
266 void
267 scm_bootstrap_programs (void)
268 {
269 zero_vector = scm_permanent_object (scm_c_make_vector (0, SCM_BOOL_F));
270
271 scm_tc16_program = scm_make_smob_type ("program", 0);
272 scm_set_smob_mark (scm_tc16_program, program_mark);
273 scm_set_smob_free (scm_tc16_program, program_free);
274 scm_set_smob_apply (scm_tc16_program, program_apply, 0, 0, 1);
275 scm_set_smob_print (scm_tc16_program, program_print);
276 }
277
278 void
279 scm_init_programs (void)
280 {
281 scm_bootstrap_vm ();
282
283 #ifndef SCM_MAGIC_SNARFER
284 #include "programs.x"
285 #endif
286 }
287
288 /*
289 Local Variables:
290 c-file-style: "gnu"
291 End:
292 */