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