adjust VM copyright notices to LGPL, use SCM_INTERNAL/API properly
[bpt/guile.git] / libguile / programs.c
CommitLineData
8f5cfc81 1/* Copyright (C) 2001 Free Software Foundation, Inc.
17e90c5e 2 *
560b9c25
AW
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
17e90c5e 7 *
560b9c25
AW
8 * This library 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 GNU
11 * Lesser General Public License for more details.
17e90c5e 12 *
560b9c25
AW
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 02110-1301 USA
16 */
17e90c5e 17
13c47753
AW
18#if HAVE_CONFIG_H
19# include <config.h>
20#endif
21
17e90c5e 22#include <string.h>
560b9c25 23#include "_scm.h"
83495480 24#include "vm-bootstrap.h"
17e90c5e 25#include "instructions.h"
8e367074 26#include "modules.h"
17e90c5e 27#include "programs.h"
e311f5fa 28#include "procprop.h" // scm_sym_name
028e3d06 29#include "srcprop.h" // scm_sym_filename
17e90c5e
KN
30#include "vm.h"
31
32\f
f9e8c09d 33scm_t_bits scm_tc16_program;
17e90c5e 34
e6fea618 35static SCM write_program = SCM_BOOL_F;
17e90c5e 36
53e28ed9
AW
37SCM_DEFINE (scm_make_program, "make-program", 1, 2, 0,
38 (SCM objcode, SCM objtable, SCM external),
39 "")
40#define FUNC_NAME s_scm_make_program
17e90c5e 41{
53e28ed9
AW
42 SCM_VALIDATE_OBJCODE (1, objcode);
43 if (SCM_UNLIKELY (SCM_UNBNDP (objtable)))
44 objtable = SCM_BOOL_F;
45 else if (scm_is_true (objtable))
46 SCM_VALIDATE_VECTOR (2, objtable);
47 if (SCM_UNLIKELY (SCM_UNBNDP (external)))
48 external = SCM_EOL;
17e90c5e 49 else
7edf2001
AW
50 /* FIXME: currently this test is quite expensive (can be 2-3% of total
51 execution time in programs that make many closures). We could remove it,
52 yes, but we'd get much better gains if we used some other method, like
53 just capturing the variables that we need instead of all heap-allocated
54 variables. Dunno. Keeping the check for now, as it's a user-callable
55 function, and inlining the op in the vm's make-closure operation. */
53e28ed9 56 SCM_VALIDATE_LIST (3, external);
17e90c5e 57
53e28ed9 58 SCM_RETURN_NEWSMOB3 (scm_tc16_program, objcode, objtable, external);
17e90c5e
KN
59}
60#undef FUNC_NAME
61
17e90c5e
KN
62static SCM
63program_mark (SCM obj)
64{
53e28ed9
AW
65 if (scm_is_true (SCM_PROGRAM_OBJTABLE (obj)))
66 scm_gc_mark (SCM_PROGRAM_OBJTABLE (obj));
67 if (!scm_is_null (SCM_PROGRAM_EXTERNALS (obj)))
68 scm_gc_mark (SCM_PROGRAM_EXTERNALS (obj));
69 return SCM_PROGRAM_OBJCODE (obj);
17e90c5e
KN
70}
71
17e90c5e
KN
72static SCM
73program_apply (SCM program, SCM args)
74{
499a4c07 75 return scm_vm_apply (scm_the_vm (), program, args);
17e90c5e
KN
76}
77
df8cd091
AW
78static SCM
79program_apply_0 (SCM program)
80{
81 return scm_c_vm_run (scm_the_vm (), program, NULL, 0);
82}
83
84static SCM
85program_apply_1 (SCM program, SCM a)
86{
87 return scm_c_vm_run (scm_the_vm (), program, &a, 1);
88}
89
90static SCM
91program_apply_2 (SCM program, SCM a, SCM b)
92{
93 SCM args[2];
94 args[0] = a;
95 args[1] = b;
96 return scm_c_vm_run (scm_the_vm (), program, args, 2);
97}
98
e6fea618
AW
99static int
100program_print (SCM program, SCM port, scm_print_state *pstate)
101{
0ba8bb71
AW
102 static int print_error = 0;
103
28106f54 104 if (SCM_FALSEP (write_program) && scm_module_system_booted_p)
e6fea618
AW
105 write_program = scm_module_local_variable
106 (scm_c_resolve_module ("system vm program"),
107 scm_from_locale_symbol ("write-program"));
108
0ba8bb71 109 if (SCM_FALSEP (write_program) || print_error)
e6fea618
AW
110 return scm_smob_print (program, port, pstate);
111
0ba8bb71 112 print_error = 1;
e6fea618 113 scm_call_2 (SCM_VARIABLE_REF (write_program), program, port);
0ba8bb71 114 print_error = 0;
e6fea618
AW
115 return 1;
116}
117
17e90c5e
KN
118\f
119/*
120 * Scheme interface
121 */
122
123SCM_DEFINE (scm_program_p, "program?", 1, 0, 0,
124 (SCM obj),
125 "")
126#define FUNC_NAME s_scm_program_p
127{
128 return SCM_BOOL (SCM_PROGRAM_P (obj));
129}
130#undef FUNC_NAME
131
ac99cb0c
KN
132SCM_DEFINE (scm_program_base, "program-base", 1, 0, 0,
133 (SCM program),
134 "")
135#define FUNC_NAME s_scm_program_base
136{
137 SCM_VALIDATE_PROGRAM (1, program);
138
f41cb00c 139 return scm_from_ulong ((unsigned long) SCM_PROGRAM_DATA (program)->base);
ac99cb0c
KN
140}
141#undef FUNC_NAME
142
17e90c5e
KN
143SCM_DEFINE (scm_program_arity, "program-arity", 1, 0, 0,
144 (SCM program),
145 "")
146#define FUNC_NAME s_scm_program_arity
ac99cb0c 147{
53e28ed9 148 struct scm_objcode *p;
ac99cb0c
KN
149
150 SCM_VALIDATE_PROGRAM (1, program);
151
152 p = SCM_PROGRAM_DATA (program);
da8b4747
LC
153 return scm_list_4 (SCM_I_MAKINUM (p->nargs),
154 SCM_I_MAKINUM (p->nrest),
155 SCM_I_MAKINUM (p->nlocs),
156 SCM_I_MAKINUM (p->nexts));
ac99cb0c
KN
157}
158#undef FUNC_NAME
159
53e28ed9
AW
160SCM_DEFINE (scm_program_objects, "program-objects", 1, 0, 0,
161 (SCM program),
162 "")
163#define FUNC_NAME s_scm_program_objects
164{
165 SCM_VALIDATE_PROGRAM (1, program);
166 return SCM_PROGRAM_OBJTABLE (program);
167}
168#undef FUNC_NAME
169
170SCM_DEFINE (scm_program_module, "program-module", 1, 0, 0,
171 (SCM program),
172 "")
173#define FUNC_NAME s_scm_program_module
174{
175 SCM objs;
176 SCM_VALIDATE_PROGRAM (1, program);
177 objs = SCM_PROGRAM_OBJTABLE (program);
178 return scm_is_true (objs) ? scm_c_vector_ref (objs, 0) : SCM_BOOL_F;
179}
180#undef FUNC_NAME
181
ac99cb0c
KN
182SCM_DEFINE (scm_program_meta, "program-meta", 1, 0, 0,
183 (SCM program),
184 "")
185#define FUNC_NAME s_scm_program_meta
17e90c5e 186{
ac47d5f6
AW
187 SCM metaobj;
188
17e90c5e 189 SCM_VALIDATE_PROGRAM (1, program);
ac47d5f6
AW
190
191 metaobj = scm_objcode_meta (SCM_PROGRAM_OBJCODE (program));
192 if (scm_is_true (metaobj))
193 return scm_make_program (metaobj, SCM_BOOL_F, SCM_EOL);
194 else
195 return SCM_BOOL_F;
17e90c5e
KN
196}
197#undef FUNC_NAME
198
e311f5fa
AW
199SCM_DEFINE (scm_program_bindings, "program-bindings", 1, 0, 0,
200 (SCM program),
201 "")
202#define FUNC_NAME s_scm_program_bindings
9a9f6487 203{
e311f5fa
AW
204 SCM meta;
205
206 SCM_VALIDATE_PROGRAM (1, program);
9a9f6487 207
53e28ed9 208 meta = scm_program_meta (program);
2fda0242 209 if (scm_is_false (meta))
9a9f6487 210 return SCM_BOOL_F;
e311f5fa
AW
211
212 return scm_car (scm_call_0 (meta));
213}
214#undef FUNC_NAME
215
216SCM_DEFINE (scm_program_sources, "program-sources", 1, 0, 0,
217 (SCM program),
218 "")
219#define FUNC_NAME s_scm_program_sources
220{
028e3d06 221 SCM meta, sources, ret, filename;
e311f5fa
AW
222
223 SCM_VALIDATE_PROGRAM (1, program);
224
225 meta = scm_program_meta (program);
9a9f6487 226 if (scm_is_false (meta))
e311f5fa
AW
227 return SCM_EOL;
228
028e3d06
AW
229 filename = SCM_BOOL_F;
230 ret = SCM_EOL;
231 for (sources = scm_cadr (scm_call_0 (meta)); !scm_is_null (sources);
232 sources = scm_cdr (sources))
233 {
234 SCM x = scm_car (sources);
235 if (scm_is_pair (x))
236 {
237 if (scm_is_number (scm_car (x)))
238 {
239 SCM addr = scm_car (x);
240 ret = scm_acons (addr, scm_cons (filename, scm_cdr (x)),
241 ret);
242 }
243 else if (scm_is_eq (scm_car (x), scm_sym_filename))
244 filename = scm_cdr (x);
245 }
246 }
247 return scm_reverse_x (ret, SCM_UNDEFINED);
e311f5fa
AW
248}
249#undef FUNC_NAME
250
251SCM_DEFINE (scm_program_properties, "program-properties", 1, 0, 0,
252 (SCM program),
253 "")
254#define FUNC_NAME s_scm_program_properties
255{
256 SCM meta;
257
258 SCM_VALIDATE_PROGRAM (1, program);
259
260 meta = scm_program_meta (program);
261 if (scm_is_false (meta))
262 return SCM_EOL;
263
264 return scm_cddr (scm_call_0 (meta));
265}
266#undef FUNC_NAME
267
268SCM_DEFINE (scm_program_name, "program-name", 1, 0, 0,
269 (SCM program),
270 "")
271#define FUNC_NAME s_scm_program_name
272{
273 SCM_VALIDATE_PROGRAM (1, program);
274 return scm_assq_ref (scm_program_properties (program), scm_sym_name);
275}
276#undef FUNC_NAME
277
028e3d06
AW
278SCM_DEFINE (scm_program_source, "program-source", 2, 0, 0,
279 (SCM program, SCM ip),
280 "")
281#define FUNC_NAME s_scm_program_source
282{
283 SCM_VALIDATE_PROGRAM (1, program);
284 return scm_c_program_source (program, scm_to_size_t (ip));
285}
286#undef FUNC_NAME
287
e311f5fa
AW
288extern SCM
289scm_c_program_source (SCM program, size_t ip)
290{
028e3d06 291 SCM sources, source = SCM_BOOL_F;
9a9f6487 292
028e3d06
AW
293 for (sources = scm_program_sources (program);
294 !scm_is_null (sources)
295 && scm_to_size_t (scm_caar (sources)) <= ip;
296 sources = scm_cdr (sources))
297 source = scm_car (sources);
298
299 return source; /* (addr . (filename . (line . column))) */
9a9f6487
AW
300}
301
17e90c5e
KN
302SCM_DEFINE (scm_program_external, "program-external", 1, 0, 0,
303 (SCM program),
304 "")
305#define FUNC_NAME s_scm_program_external
306{
307 SCM_VALIDATE_PROGRAM (1, program);
53e28ed9 308 return SCM_PROGRAM_EXTERNALS (program);
17e90c5e
KN
309}
310#undef FUNC_NAME
311
62082959
LC
312SCM_DEFINE (scm_program_external_set_x, "program-external-set!", 2, 0, 0,
313 (SCM program, SCM external),
314 "Modify the list of closure variables of @var{program} (for "
315 "debugging purposes).")
316#define FUNC_NAME s_scm_program_external_set_x
317{
318 SCM_VALIDATE_PROGRAM (1, program);
319 SCM_VALIDATE_LIST (2, external);
53e28ed9 320 SCM_PROGRAM_EXTERNALS (program) = external;
62082959
LC
321 return SCM_UNSPECIFIED;
322}
323#undef FUNC_NAME
324
53e28ed9 325SCM_DEFINE (scm_program_objcode, "program-objcode", 1, 0, 0,
17e90c5e 326 (SCM program),
53e28ed9
AW
327 "Return a @var{program}'s object code.")
328#define FUNC_NAME s_scm_program_objcode
17e90c5e
KN
329{
330 SCM_VALIDATE_PROGRAM (1, program);
fa19602c 331
53e28ed9 332 return SCM_PROGRAM_OBJCODE (program);
17e90c5e
KN
333}
334#undef FUNC_NAME
335
fa19602c 336
17e90c5e
KN
337\f
338void
07e56b27 339scm_bootstrap_programs (void)
17e90c5e 340{
17e90c5e
KN
341 scm_tc16_program = scm_make_smob_type ("program", 0);
342 scm_set_smob_mark (scm_tc16_program, program_mark);
17e90c5e 343 scm_set_smob_apply (scm_tc16_program, program_apply, 0, 0, 1);
df8cd091
AW
344 scm_smobs[SCM_TC2SMOBNUM (scm_tc16_program)].apply_0 = program_apply_0;
345 scm_smobs[SCM_TC2SMOBNUM (scm_tc16_program)].apply_1 = program_apply_1;
346 scm_smobs[SCM_TC2SMOBNUM (scm_tc16_program)].apply_2 = program_apply_2;
e6fea618 347 scm_set_smob_print (scm_tc16_program, program_print);
60ae5ca2
AW
348 scm_c_register_extension ("libguile", "scm_init_programs",
349 (scm_t_extension_init_func)scm_init_programs, NULL);
07e56b27 350}
17e90c5e 351
07e56b27
AW
352void
353scm_init_programs (void)
354{
355 scm_bootstrap_vm ();
356
17e90c5e 357#ifndef SCM_MAGIC_SNARFER
aeeff258 358#include "libguile/programs.x"
17e90c5e
KN
359#endif
360}
361
362/*
363 Local Variables:
364 c-file-style: "gnu"
365 End:
366*/