1 /* Copyright (C) 2001 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
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
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.
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
24 #include "vm-bootstrap.h"
25 #include "instructions.h"
28 #include "procprop.h" // scm_sym_name
29 #include "srcprop.h" // scm_sym_filename
33 scm_t_bits scm_tc16_program
;
35 static SCM write_program
= SCM_BOOL_F
;
37 SCM_DEFINE (scm_make_program
, "make-program", 1, 2, 0,
38 (SCM objcode
, SCM objtable
, SCM external
),
40 #define FUNC_NAME s_scm_make_program
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
)))
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. */
56 SCM_VALIDATE_LIST (3, external
);
58 SCM_RETURN_NEWSMOB3 (scm_tc16_program
, objcode
, objtable
, external
);
63 program_mark (SCM obj
)
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
);
73 program_apply (SCM program
, SCM args
)
75 return scm_vm_apply (scm_the_vm (), program
, args
);
79 program_apply_0 (SCM program
)
81 return scm_c_vm_run (scm_the_vm (), program
, NULL
, 0);
85 program_apply_1 (SCM program
, SCM a
)
87 return scm_c_vm_run (scm_the_vm (), program
, &a
, 1);
91 program_apply_2 (SCM program
, SCM a
, SCM b
)
96 return scm_c_vm_run (scm_the_vm (), program
, args
, 2);
100 program_print (SCM program
, SCM port
, scm_print_state
*pstate
)
102 static int print_error
= 0;
104 if (SCM_FALSEP (write_program
) && scm_module_system_booted_p
)
105 write_program
= scm_module_local_variable
106 (scm_c_resolve_module ("system vm program"),
107 scm_from_locale_symbol ("write-program"));
109 if (SCM_FALSEP (write_program
) || print_error
)
110 return scm_smob_print (program
, port
, pstate
);
113 scm_call_2 (SCM_VARIABLE_REF (write_program
), program
, port
);
123 SCM_DEFINE (scm_program_p
, "program?", 1, 0, 0,
126 #define FUNC_NAME s_scm_program_p
128 return SCM_BOOL (SCM_PROGRAM_P (obj
));
132 SCM_DEFINE (scm_program_base
, "program-base", 1, 0, 0,
135 #define FUNC_NAME s_scm_program_base
137 SCM_VALIDATE_PROGRAM (1, program
);
139 return scm_from_ulong ((unsigned long) SCM_PROGRAM_DATA (program
)->base
);
143 SCM_DEFINE (scm_program_arity
, "program-arity", 1, 0, 0,
146 #define FUNC_NAME s_scm_program_arity
148 struct scm_objcode
*p
;
150 SCM_VALIDATE_PROGRAM (1, program
);
152 p
= SCM_PROGRAM_DATA (program
);
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
));
160 SCM_DEFINE (scm_program_objects
, "program-objects", 1, 0, 0,
163 #define FUNC_NAME s_scm_program_objects
165 SCM_VALIDATE_PROGRAM (1, program
);
166 return SCM_PROGRAM_OBJTABLE (program
);
170 SCM_DEFINE (scm_program_module
, "program-module", 1, 0, 0,
173 #define FUNC_NAME s_scm_program_module
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
;
182 SCM_DEFINE (scm_program_meta
, "program-meta", 1, 0, 0,
185 #define FUNC_NAME s_scm_program_meta
189 SCM_VALIDATE_PROGRAM (1, program
);
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
);
199 SCM_DEFINE (scm_program_bindings
, "program-bindings", 1, 0, 0,
202 #define FUNC_NAME s_scm_program_bindings
206 SCM_VALIDATE_PROGRAM (1, program
);
208 meta
= scm_program_meta (program
);
209 if (scm_is_false (meta
))
212 return scm_car (scm_call_0 (meta
));
216 SCM_DEFINE (scm_program_sources
, "program-sources", 1, 0, 0,
219 #define FUNC_NAME s_scm_program_sources
221 SCM meta
, sources
, ret
, filename
;
223 SCM_VALIDATE_PROGRAM (1, program
);
225 meta
= scm_program_meta (program
);
226 if (scm_is_false (meta
))
229 filename
= SCM_BOOL_F
;
231 for (sources
= scm_cadr (scm_call_0 (meta
)); !scm_is_null (sources
);
232 sources
= scm_cdr (sources
))
234 SCM x
= scm_car (sources
);
237 if (scm_is_number (scm_car (x
)))
239 SCM addr
= scm_car (x
);
240 ret
= scm_acons (addr
, scm_cons (filename
, scm_cdr (x
)),
243 else if (scm_is_eq (scm_car (x
), scm_sym_filename
))
244 filename
= scm_cdr (x
);
247 return scm_reverse_x (ret
, SCM_UNDEFINED
);
251 SCM_DEFINE (scm_program_properties
, "program-properties", 1, 0, 0,
254 #define FUNC_NAME s_scm_program_properties
258 SCM_VALIDATE_PROGRAM (1, program
);
260 meta
= scm_program_meta (program
);
261 if (scm_is_false (meta
))
264 return scm_cddr (scm_call_0 (meta
));
268 SCM_DEFINE (scm_program_name
, "program-name", 1, 0, 0,
271 #define FUNC_NAME s_scm_program_name
273 SCM_VALIDATE_PROGRAM (1, program
);
274 return scm_assq_ref (scm_program_properties (program
), scm_sym_name
);
278 SCM_DEFINE (scm_program_source
, "program-source", 2, 0, 0,
279 (SCM program
, SCM ip
),
281 #define FUNC_NAME s_scm_program_source
283 SCM_VALIDATE_PROGRAM (1, program
);
284 return scm_c_program_source (program
, scm_to_size_t (ip
));
289 scm_c_program_source (SCM program
, size_t ip
)
291 SCM sources
, source
= SCM_BOOL_F
;
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
);
299 return source
; /* (addr . (filename . (line . column))) */
302 SCM_DEFINE (scm_program_external
, "program-external", 1, 0, 0,
305 #define FUNC_NAME s_scm_program_external
307 SCM_VALIDATE_PROGRAM (1, program
);
308 return SCM_PROGRAM_EXTERNALS (program
);
312 SCM_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
318 SCM_VALIDATE_PROGRAM (1, program
);
319 SCM_VALIDATE_LIST (2, external
);
320 SCM_PROGRAM_EXTERNALS (program
) = external
;
321 return SCM_UNSPECIFIED
;
325 SCM_DEFINE (scm_program_objcode
, "program-objcode", 1, 0, 0,
327 "Return a @var{program}'s object code.")
328 #define FUNC_NAME s_scm_program_objcode
330 SCM_VALIDATE_PROGRAM (1, program
);
332 return SCM_PROGRAM_OBJCODE (program
);
339 scm_bootstrap_programs (void)
341 scm_tc16_program
= scm_make_smob_type ("program", 0);
342 scm_set_smob_mark (scm_tc16_program
, program_mark
);
343 scm_set_smob_apply (scm_tc16_program
, program_apply
, 0, 0, 1);
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
;
347 scm_set_smob_print (scm_tc16_program
, program_print
);
348 scm_c_register_extension ("libguile", "scm_init_programs",
349 (scm_t_extension_init_func
)scm_init_programs
, NULL
);
353 scm_init_programs (void)
357 #ifndef SCM_MAGIC_SNARFER
358 #include "libguile/programs.x"