prompt handlers are always inline
[bpt/guile.git] / libguile / vm.c
CommitLineData
a6029b97 1/* Copyright (C) 2001, 2009, 2010 Free Software Foundation, Inc.
a98cef7e 2 *
560b9c25 3 * This library is free software; you can redistribute it and/or
53befeb7
NJ
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.
a98cef7e 7 *
53befeb7
NJ
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
560b9c25
AW
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
a98cef7e 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
53befeb7
NJ
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 * 02110-1301 USA
560b9c25 17 */
a98cef7e 18
13c47753
AW
19#if HAVE_CONFIG_H
20# include <config.h>
21#endif
22
da8b4747 23#include <stdlib.h>
6d14383e 24#include <alloca.h>
17e90c5e 25#include <string.h>
e3eb628d 26
1c44468d 27#include "libguile/bdw-gc.h"
e3eb628d
LC
28#include <gc/gc_mark.h>
29
560b9c25 30#include "_scm.h"
adaf86ec 31#include "control.h"
ac99cb0c 32#include "frames.h"
17e90c5e 33#include "instructions.h"
8f5cfc81 34#include "objcodes.h"
ac99cb0c 35#include "programs.h"
fb10a008 36#include "lang.h" /* NULL_OR_NIL_P */
a98cef7e
KN
37#include "vm.h"
38
a98cef7e
KN
39/* I sometimes use this for debugging. */
40#define vm_puts(OBJ) \
41{ \
22bcbe8c
AW
42 scm_display (OBJ, scm_current_error_port ()); \
43 scm_newline (scm_current_error_port ()); \
a98cef7e
KN
44}
45
11ea1aba
AW
46/* The VM has a number of internal assertions that shouldn't normally be
47 necessary, but might be if you think you found a bug in the VM. */
48#define VM_ENABLE_ASSERTIONS
49
50/* We can add a mode that ensures that all stack items above the stack pointer
51 are NULL. This is useful for checking the internal consistency of the VM's
52 assumptions and its operators, but isn't necessary for normal operation. It
616167fc 53 will ensure that assertions are enabled. Slows down the VM by about 30%. */
747a1635 54/* NB! If you enable this, search for NULLING in throw.c */
616167fc 55/* #define VM_ENABLE_STACK_NULLING */
11ea1aba 56
53e28ed9
AW
57/* #define VM_ENABLE_PARANOID_ASSERTIONS */
58
11ea1aba
AW
59#if defined (VM_ENABLE_STACK_NULLING) && !defined (VM_ENABLE_ASSERTIONS)
60#define VM_ENABLE_ASSERTIONS
61#endif
62
e3eb628d
LC
63/* When defined, arrange so that the GC doesn't scan the VM stack beyond its
64 current SP. This should help avoid excess data retention. See
65 http://thread.gmane.org/gmane.comp.programming.garbage-collection.boehmgc/3001
66 for a discussion. */
67#define VM_ENABLE_PRECISE_STACK_GC_SCAN
68
69
a98cef7e 70\f
a98cef7e
KN
71/*
72 * VM Continuation
73 */
74
6f3b0cc2
AW
75void
76scm_i_vm_cont_print (SCM x, SCM port, scm_print_state *pstate)
77{
78 scm_puts ("#<vm-continuation ", port);
79 scm_uintprint (SCM_UNPACK (x), 16, port);
80 scm_puts (">", port);
81}
17e90c5e 82
d8873dfe
AW
83/* In theory, a number of vm instances can be active in the call trace, and we
84 only want to reify the continuations of those in the current continuation
85 root. I don't see a nice way to do this -- ideally it would involve dynwinds,
86 and previous values of the *the-vm* fluid within the current continuation
87 root. But we don't have access to continuation roots in the dynwind stack.
88 So, just punt for now, we just capture the continuation for the current VM.
89
90 While I'm on the topic, ideally we could avoid copying the C stack if the
91 continuation root is inside VM code, and call/cc was invoked within that same
92 call to vm_run; but that's currently not implemented.
93 */
a98cef7e 94static SCM
d8873dfe
AW
95vm_capture_continuation (SCM *stack_base,
96 SCM *fp, SCM *sp, scm_t_uint8 *ra, scm_t_uint8 *mvra)
a98cef7e 97{
d8873dfe
AW
98 struct scm_vm_cont *p;
99
100 p = scm_gc_malloc (sizeof (*p), "capture_vm_cont");
101 p->stack_size = sp - stack_base + 1;
d8eeb67c
LC
102 p->stack_base = scm_gc_malloc (p->stack_size * sizeof (SCM),
103 "capture_vm_cont");
d8873dfe
AW
104#if defined(VM_ENABLE_STACK_NULLING) && 0
105 /* Tail continuations leave their frame on the stack for subsequent
106 application, but don't capture the frame -- so there are some elements on
107 the stack then, and this check doesn't work, so disable it for now. */
108 if (sp >= vp->stack_base)
66db076a
AW
109 if (!vp->sp[0] || vp->sp[1])
110 abort ();
11ea1aba
AW
111 memset (p->stack_base, 0, p->stack_size * sizeof (SCM));
112#endif
d8873dfe
AW
113 p->ra = ra;
114 p->mvra = mvra;
115 p->sp = sp;
116 p->fp = fp;
117 memcpy (p->stack_base, stack_base, (sp + 1 - stack_base) * sizeof (SCM));
118 p->reloc = p->stack_base - stack_base;
6f3b0cc2 119 return scm_cell (scm_tc7_vm_cont, (scm_t_bits)p);
a98cef7e
KN
120}
121
122static void
d8873dfe 123vm_return_to_continuation (SCM vm, SCM cont, size_t n, SCM *argv)
a98cef7e 124{
d8873dfe
AW
125 struct scm_vm *vp;
126 struct scm_vm_cont *cp;
127 SCM *argv_copy;
128
129 argv_copy = alloca (n * sizeof(SCM));
130 memcpy (argv_copy, argv, n * sizeof(SCM));
131
132 vp = SCM_VM_DATA (vm);
133 cp = SCM_VM_CONT_DATA (cont);
134
135 if (n == 0 && !cp->mvra)
136 scm_misc_error (NULL, "Too few values returned to continuation",
137 SCM_EOL);
138
139 if (vp->stack_size < cp->stack_size + n + 1)
a98cef7e 140 {
17e90c5e 141 /* puts ("FIXME: Need to expand"); */
a98cef7e
KN
142 abort ();
143 }
11ea1aba
AW
144#ifdef VM_ENABLE_STACK_NULLING
145 {
d8873dfe 146 scm_t_ptrdiff nzero = (vp->sp - cp->sp);
11ea1aba 147 if (nzero > 0)
d8873dfe 148 memset (vp->stack_base + cp->stack_size, 0, nzero * sizeof (SCM));
66db076a
AW
149 /* actually nzero should always be negative, because vm_reset_stack will
150 unwind the stack to some point *below* this continuation */
11ea1aba
AW
151 }
152#endif
d8873dfe
AW
153 vp->sp = cp->sp;
154 vp->fp = cp->fp;
155 memcpy (vp->stack_base, cp->stack_base, cp->stack_size * sizeof (SCM));
bfffd258 156
d8873dfe
AW
157 if (n == 1 || !cp->mvra)
158 {
159 vp->ip = cp->ra;
160 vp->sp++;
161 *vp->sp = argv_copy[0];
162 }
163 else
164 {
165 size_t i;
166 for (i = 0; i < n; i++)
167 {
168 vp->sp++;
169 *vp->sp = argv_copy[i];
170 }
171 vp->sp++;
172 *vp->sp = scm_from_size_t (n);
173 vp->ip = cp->mvra;
174 }
175}
bfffd258 176
bfffd258 177SCM
269479e3 178scm_i_vm_capture_continuation (SCM vm)
bfffd258 179{
d8873dfe
AW
180 struct scm_vm *vp = SCM_VM_DATA (vm);
181 return vm_capture_continuation (vp->stack_base, vp->fp, vp->sp, vp->ip, NULL);
a98cef7e
KN
182}
183
b1b942b7 184static void
7656f194 185vm_dispatch_hook (SCM vm, int hook_num)
b1b942b7 186{
7656f194
AW
187 struct scm_vm *vp;
188 SCM hook;
189 SCM frame;
b1b942b7 190
7656f194
AW
191 vp = SCM_VM_DATA (vm);
192 hook = vp->hooks[hook_num];
b1b942b7 193
7656f194
AW
194 if (SCM_LIKELY (scm_is_false (hook))
195 || scm_is_null (SCM_HOOK_PROCEDURES (hook)))
196 return;
197
198 vp->trace_level--;
199 frame = scm_c_make_frame (vm, vp->fp, vp->sp, vp->ip, 0);
200 scm_c_run_hookn (hook, &frame, 1);
201 vp->trace_level++;
b1b942b7
AW
202}
203
17e90c5e 204\f
4f66bcde
AW
205/*
206 * The dynamic stack
207 */
4f66bcde
AW
208#define VM_SETJMP(jmpbuf) 0
209
6e84cb95 210static void vm_abort (SCM vm, SCM tag, SCM args) SCM_NORETURN;
4f66bcde 211static void
6e84cb95 212vm_abort (SCM vm, SCM tag, SCM args)
4f66bcde
AW
213{
214 abort ();
215}
216
217\f
17e90c5e
KN
218/*
219 * VM Internal functions
220 */
221
f6a8e791
AW
222SCM_SYMBOL (sym_vm_run, "vm-run");
223SCM_SYMBOL (sym_vm_error, "vm-error");
224SCM_SYMBOL (sym_keyword_argument_error, "keyword-argument-error");
225SCM_SYMBOL (sym_debug, "debug");
17e90c5e 226
6f3b0cc2
AW
227void
228scm_i_vm_print (SCM x, SCM port, scm_print_state *pstate)
229{
230 scm_puts ("#<vm ", port);
231 scm_uintprint (SCM_UNPACK (x), 16, port);
232 scm_puts (">", port);
233}
234
2fda0242 235static SCM
d2d7acd5 236really_make_boot_program (long nargs)
2fda0242 237{
5bd047ce 238 SCM u8vec;
97fcf583
AW
239 scm_t_uint8 text[] = { scm_op_mv_call, 0, 0, 0, 1,
240 scm_op_make_int8_1, scm_op_halt };
28b119ee 241 struct scm_objcode *bp;
3b9e095b 242 SCM ret;
5bd047ce 243
53e28ed9 244 if (SCM_UNLIKELY (nargs > 255 || nargs < 0))
2fda0242 245 abort ();
28b119ee
AW
246 text[1] = (scm_t_uint8)nargs;
247
d7e7a02a 248 bp = scm_malloc (sizeof (struct scm_objcode) + sizeof (text));
3dbbe28d 249 memcpy (SCM_C_OBJCODE_BASE (bp), text, sizeof (text));
28b119ee
AW
250 bp->len = sizeof(text);
251 bp->metalen = 0;
28b119ee 252
7055591c
AW
253 u8vec = scm_c_take_bytevector ((scm_t_int8*)bp,
254 sizeof (struct scm_objcode) + sizeof (text));
5bd047ce 255 ret = scm_make_program (scm_bytecode_to_objcode (u8vec),
20d47c39 256 SCM_BOOL_F, SCM_BOOL_F);
ba20f78a 257 SCM_SET_CELL_WORD_0 (ret, SCM_CELL_WORD_0 (ret) | SCM_F_PROGRAM_IS_BOOT);
5bd047ce 258
3b9e095b 259 return ret;
2fda0242 260}
d2d7acd5
AW
261#define NUM_BOOT_PROGS 8
262static SCM
263vm_make_boot_program (long nargs)
264{
265 static SCM programs[NUM_BOOT_PROGS] = { 0, };
266
267 if (SCM_UNLIKELY (!programs[0]))
268 {
269 int i;
270 for (i = 0; i < NUM_BOOT_PROGS; i++)
f39448c5 271 programs[i] = really_make_boot_program (i);
d2d7acd5
AW
272 }
273
274 if (SCM_LIKELY (nargs < NUM_BOOT_PROGS))
275 return programs[nargs];
276 else
277 return really_make_boot_program (nargs);
278}
2fda0242 279
a98cef7e
KN
280\f
281/*
282 * VM
283 */
284
b7393ea1
AW
285static SCM
286resolve_variable (SCM what, SCM program_module)
287{
9bd48cb1 288 if (SCM_LIKELY (scm_is_symbol (what)))
b7393ea1
AW
289 {
290 if (SCM_LIKELY (scm_module_system_booted_p
291 && scm_is_true (program_module)))
292 /* might longjmp */
293 return scm_module_lookup (program_module, what);
294 else
295 {
296 SCM v = scm_sym2var (what, SCM_BOOL_F, SCM_BOOL_F);
297 if (scm_is_false (v))
298 scm_misc_error (NULL, "unbound variable: ~S", scm_list_1 (what));
299 else
300 return v;
301 }
302 }
303 else
304 {
305 SCM mod;
306 /* compilation of @ or @@
307 `what' is a three-element list: (MODNAME SYM INTERFACE?)
308 INTERFACE? is #t if we compiled @ or #f if we compiled @@
309 */
310 mod = scm_resolve_module (SCM_CAR (what));
311 if (scm_is_true (SCM_CADDR (what)))
312 mod = scm_module_public_interface (mod);
5c8cefe5 313 if (scm_is_false (mod))
b7393ea1
AW
314 scm_misc_error (NULL, "no such module: ~S",
315 scm_list_1 (SCM_CAR (what)));
316 /* might longjmp */
317 return scm_module_lookup (mod, SCM_CADR (what));
318 }
319}
320
51e9ba2f 321#define VM_DEFAULT_STACK_SIZE (64 * 1024)
17e90c5e 322
17e90c5e 323#define VM_NAME vm_regular_engine
6d14383e
AW
324#define FUNC_NAME "vm-regular-engine"
325#define VM_ENGINE SCM_VM_REGULAR_ENGINE
83495480 326#include "vm-engine.c"
17e90c5e 327#undef VM_NAME
6d14383e 328#undef FUNC_NAME
17e90c5e 329#undef VM_ENGINE
17e90c5e
KN
330
331#define VM_NAME vm_debug_engine
6d14383e
AW
332#define FUNC_NAME "vm-debug-engine"
333#define VM_ENGINE SCM_VM_DEBUG_ENGINE
83495480 334#include "vm-engine.c"
17e90c5e 335#undef VM_NAME
6d14383e 336#undef FUNC_NAME
17e90c5e
KN
337#undef VM_ENGINE
338
6d14383e
AW
339static const scm_t_vm_engine vm_engines[] =
340 { vm_regular_engine, vm_debug_engine };
341
e3eb628d
LC
342#ifdef VM_ENABLE_PRECISE_STACK_GC_SCAN
343
344/* The GC "kind" for the VM stack. */
345static int vm_stack_gc_kind;
346
347#endif
348
a98cef7e 349static SCM
17e90c5e
KN
350make_vm (void)
351#define FUNC_NAME "make_vm"
a98cef7e 352{
17e90c5e 353 int i;
7f991c7d 354 struct scm_vm *vp;
747a1635 355
7f991c7d 356 vp = scm_gc_malloc (sizeof (struct scm_vm), "vm");
d8eeb67c 357
3d5ee0cd 358 vp->stack_size = VM_DEFAULT_STACK_SIZE;
e3eb628d
LC
359
360#ifdef VM_ENABLE_PRECISE_STACK_GC_SCAN
4168aa46
TTN
361 vp->stack_base = (SCM *)
362 GC_generic_malloc (vp->stack_size * sizeof (SCM), vm_stack_gc_kind);
e3eb628d
LC
363
364 /* Keep a pointer to VP so that `vm_stack_mark ()' can know what the stack
365 top is. */
366 *vp->stack_base = PTR2SCM (vp);
367 vp->stack_base++;
368 vp->stack_size--;
369#else
d8eeb67c
LC
370 vp->stack_base = scm_gc_malloc (vp->stack_size * sizeof (SCM),
371 "stack-base");
e3eb628d
LC
372#endif
373
2bbe1533
AW
374#ifdef VM_ENABLE_STACK_NULLING
375 memset (vp->stack_base, 0, vp->stack_size * sizeof (SCM));
376#endif
75d315e1 377 vp->stack_limit = vp->stack_base + vp->stack_size;
3616e9e9
KN
378 vp->ip = NULL;
379 vp->sp = vp->stack_base - 1;
380 vp->fp = NULL;
6d14383e 381 vp->engine = SCM_VM_DEBUG_ENGINE;
3d5ee0cd 382 vp->options = SCM_EOL;
7656f194 383 vp->trace_level = 0;
17e90c5e 384 for (i = 0; i < SCM_VM_NUM_HOOKS; i++)
3d5ee0cd 385 vp->hooks[i] = SCM_BOOL_F;
6f3b0cc2 386 return scm_cell (scm_tc7_vm, (scm_t_bits)vp);
a98cef7e 387}
17e90c5e 388#undef FUNC_NAME
a98cef7e 389
e3eb628d
LC
390#ifdef VM_ENABLE_PRECISE_STACK_GC_SCAN
391
392/* Mark the VM stack region between its base and its current top. */
393static struct GC_ms_entry *
394vm_stack_mark (GC_word *addr, struct GC_ms_entry *mark_stack_ptr,
395 struct GC_ms_entry *mark_stack_limit, GC_word env)
396{
397 GC_word *word;
398 const struct scm_vm *vm;
399
400 /* The first word of the VM stack should contain a pointer to the
401 corresponding VM. */
402 vm = * ((struct scm_vm **) addr);
403
8071c490
LC
404 if (vm == NULL
405 || (SCM *) addr != vm->stack_base - 1
78747ac6 406 || vm->stack_limit - vm->stack_base != vm->stack_size)
e3eb628d
LC
407 /* ADDR must be a pointer to a free-list element, which we must ignore
408 (see warning in <gc/gc_mark.h>). */
409 return mark_stack_ptr;
410
e3eb628d
LC
411 for (word = (GC_word *) vm->stack_base; word <= (GC_word *) vm->sp; word++)
412 mark_stack_ptr = GC_MARK_AND_PUSH ((* (GC_word **) word),
413 mark_stack_ptr, mark_stack_limit,
414 NULL);
415
416 return mark_stack_ptr;
417}
418
419#endif /* VM_ENABLE_PRECISE_STACK_GC_SCAN */
420
421
6d14383e 422SCM
4abef68f 423scm_c_vm_run (SCM vm, SCM program, SCM *argv, int nargs)
6d14383e 424{
4abef68f 425 struct scm_vm *vp = SCM_VM_DATA (vm);
7656f194 426 return vm_engines[vp->engine](vm, program, argv, nargs);
6d14383e
AW
427}
428
6f3b0cc2
AW
429SCM_DEFINE (scm_vm_apply, "vm-apply", 3, 0, 0,
430 (SCM vm, SCM program, SCM args),
431 "")
432#define FUNC_NAME s_scm_vm_apply
a98cef7e 433{
6d14383e
AW
434 SCM *argv;
435 int i, nargs;
436
437 SCM_VALIDATE_VM (1, vm);
67e2d80a 438 SCM_VALIDATE_PROC (2, program);
6d14383e
AW
439
440 nargs = scm_ilength (args);
441 if (SCM_UNLIKELY (nargs < 0))
442 scm_wrong_type_arg_msg (FUNC_NAME, 3, args, "list");
443
444 argv = alloca(nargs * sizeof(SCM));
445 for (i = 0; i < nargs; i++)
446 {
447 argv[i] = SCM_CAR (args);
448 args = SCM_CDR (args);
449 }
450
4abef68f 451 return scm_c_vm_run (vm, program, argv, nargs);
a98cef7e 452}
17e90c5e 453#undef FUNC_NAME
a98cef7e 454
14aa25e4
AW
455SCM
456scm_vm_call_with_new_stack (SCM vm, SCM thunk, SCM id)
457{
458 return scm_c_vm_run (vm, thunk, NULL, 0);
459}
460
a98cef7e
KN
461/* Scheme interface */
462
463SCM_DEFINE (scm_vm_version, "vm-version", 0, 0, 0,
17e90c5e
KN
464 (void),
465 "")
a98cef7e
KN
466#define FUNC_NAME s_scm_vm_version
467{
d3518113 468 return scm_from_locale_string (PACKAGE_VERSION);
a98cef7e
KN
469}
470#undef FUNC_NAME
471
499a4c07 472SCM_DEFINE (scm_the_vm, "the-vm", 0, 0, 0,
fcd4901b 473 (void),
499a4c07
KN
474 "")
475#define FUNC_NAME s_scm_the_vm
476{
2bbe1533 477 scm_i_thread *t = SCM_I_CURRENT_THREAD;
f63ea2ce 478
8b22ed7a 479 if (SCM_UNLIKELY (scm_is_false ((t->vm))))
2bbe1533 480 t->vm = make_vm ();
f63ea2ce 481
2bbe1533 482 return t->vm;
499a4c07
KN
483}
484#undef FUNC_NAME
485
486
a98cef7e
KN
487SCM_DEFINE (scm_vm_p, "vm?", 1, 0, 0,
488 (SCM obj),
17e90c5e 489 "")
a98cef7e
KN
490#define FUNC_NAME s_scm_vm_p
491{
9bd48cb1 492 return scm_from_bool (SCM_VM_P (obj));
a98cef7e
KN
493}
494#undef FUNC_NAME
495
496SCM_DEFINE (scm_make_vm, "make-vm", 0, 0, 0,
17e90c5e
KN
497 (void),
498 "")
499#define FUNC_NAME s_scm_make_vm,
a98cef7e 500{
17e90c5e 501 return make_vm ();
a98cef7e
KN
502}
503#undef FUNC_NAME
504
17e90c5e 505SCM_DEFINE (scm_vm_ip, "vm:ip", 1, 0, 0,
a98cef7e 506 (SCM vm),
17e90c5e
KN
507 "")
508#define FUNC_NAME s_scm_vm_ip
a98cef7e
KN
509{
510 SCM_VALIDATE_VM (1, vm);
f41cb00c 511 return scm_from_ulong ((unsigned long) SCM_VM_DATA (vm)->ip);
a98cef7e
KN
512}
513#undef FUNC_NAME
514
515SCM_DEFINE (scm_vm_sp, "vm:sp", 1, 0, 0,
516 (SCM vm),
17e90c5e 517 "")
a98cef7e
KN
518#define FUNC_NAME s_scm_vm_sp
519{
520 SCM_VALIDATE_VM (1, vm);
f41cb00c 521 return scm_from_ulong ((unsigned long) SCM_VM_DATA (vm)->sp);
a98cef7e
KN
522}
523#undef FUNC_NAME
524
525SCM_DEFINE (scm_vm_fp, "vm:fp", 1, 0, 0,
526 (SCM vm),
17e90c5e 527 "")
a98cef7e
KN
528#define FUNC_NAME s_scm_vm_fp
529{
530 SCM_VALIDATE_VM (1, vm);
f41cb00c 531 return scm_from_ulong ((unsigned long) SCM_VM_DATA (vm)->fp);
a98cef7e
KN
532}
533#undef FUNC_NAME
534
17e90c5e
KN
535#define VM_DEFINE_HOOK(n) \
536{ \
3d5ee0cd 537 struct scm_vm *vp; \
17e90c5e 538 SCM_VALIDATE_VM (1, vm); \
3d5ee0cd 539 vp = SCM_VM_DATA (vm); \
8b22ed7a 540 if (scm_is_false (vp->hooks[n])) \
238e7a11 541 vp->hooks[n] = scm_make_hook (SCM_I_MAKINUM (1)); \
3d5ee0cd 542 return vp->hooks[n]; \
17e90c5e
KN
543}
544
545SCM_DEFINE (scm_vm_boot_hook, "vm-boot-hook", 1, 0, 0,
a98cef7e 546 (SCM vm),
17e90c5e
KN
547 "")
548#define FUNC_NAME s_scm_vm_boot_hook
a98cef7e 549{
17e90c5e 550 VM_DEFINE_HOOK (SCM_VM_BOOT_HOOK);
a98cef7e
KN
551}
552#undef FUNC_NAME
553
17e90c5e
KN
554SCM_DEFINE (scm_vm_halt_hook, "vm-halt-hook", 1, 0, 0,
555 (SCM vm),
556 "")
557#define FUNC_NAME s_scm_vm_halt_hook
a98cef7e 558{
17e90c5e 559 VM_DEFINE_HOOK (SCM_VM_HALT_HOOK);
a98cef7e
KN
560}
561#undef FUNC_NAME
562
17e90c5e 563SCM_DEFINE (scm_vm_next_hook, "vm-next-hook", 1, 0, 0,
a98cef7e 564 (SCM vm),
17e90c5e
KN
565 "")
566#define FUNC_NAME s_scm_vm_next_hook
a98cef7e 567{
17e90c5e 568 VM_DEFINE_HOOK (SCM_VM_NEXT_HOOK);
a98cef7e
KN
569}
570#undef FUNC_NAME
571
7a0d0cee
KN
572SCM_DEFINE (scm_vm_break_hook, "vm-break-hook", 1, 0, 0,
573 (SCM vm),
574 "")
575#define FUNC_NAME s_scm_vm_break_hook
576{
577 VM_DEFINE_HOOK (SCM_VM_BREAK_HOOK);
578}
579#undef FUNC_NAME
580
17e90c5e
KN
581SCM_DEFINE (scm_vm_enter_hook, "vm-enter-hook", 1, 0, 0,
582 (SCM vm),
583 "")
584#define FUNC_NAME s_scm_vm_enter_hook
a98cef7e 585{
17e90c5e 586 VM_DEFINE_HOOK (SCM_VM_ENTER_HOOK);
a98cef7e
KN
587}
588#undef FUNC_NAME
589
17e90c5e
KN
590SCM_DEFINE (scm_vm_apply_hook, "vm-apply-hook", 1, 0, 0,
591 (SCM vm),
592 "")
593#define FUNC_NAME s_scm_vm_apply_hook
a98cef7e 594{
17e90c5e 595 VM_DEFINE_HOOK (SCM_VM_APPLY_HOOK);
a98cef7e
KN
596}
597#undef FUNC_NAME
598
17e90c5e 599SCM_DEFINE (scm_vm_exit_hook, "vm-exit-hook", 1, 0, 0,
a98cef7e 600 (SCM vm),
17e90c5e
KN
601 "")
602#define FUNC_NAME s_scm_vm_exit_hook
a98cef7e 603{
17e90c5e 604 VM_DEFINE_HOOK (SCM_VM_EXIT_HOOK);
a98cef7e
KN
605}
606#undef FUNC_NAME
607
17e90c5e 608SCM_DEFINE (scm_vm_return_hook, "vm-return-hook", 1, 0, 0,
a98cef7e 609 (SCM vm),
17e90c5e
KN
610 "")
611#define FUNC_NAME s_scm_vm_return_hook
a98cef7e 612{
17e90c5e 613 VM_DEFINE_HOOK (SCM_VM_RETURN_HOOK);
a98cef7e
KN
614}
615#undef FUNC_NAME
616
17e90c5e
KN
617SCM_DEFINE (scm_vm_option, "vm-option", 2, 0, 0,
618 (SCM vm, SCM key),
619 "")
620#define FUNC_NAME s_scm_vm_option
a98cef7e
KN
621{
622 SCM_VALIDATE_VM (1, vm);
17e90c5e 623 return scm_assq_ref (SCM_VM_DATA (vm)->options, key);
a98cef7e
KN
624}
625#undef FUNC_NAME
626
17e90c5e
KN
627SCM_DEFINE (scm_set_vm_option_x, "set-vm-option!", 3, 0, 0,
628 (SCM vm, SCM key, SCM val),
629 "")
630#define FUNC_NAME s_scm_set_vm_option_x
a98cef7e
KN
631{
632 SCM_VALIDATE_VM (1, vm);
17e90c5e
KN
633 SCM_VM_DATA (vm)->options
634 = scm_assq_set_x (SCM_VM_DATA (vm)->options, key, val);
635 return SCM_UNSPECIFIED;
a98cef7e
KN
636}
637#undef FUNC_NAME
638
7656f194 639SCM_DEFINE (scm_vm_trace_level, "vm-trace-level", 1, 0, 0,
17e90c5e
KN
640 (SCM vm),
641 "")
7656f194 642#define FUNC_NAME s_scm_vm_trace_level
a98cef7e 643{
a98cef7e 644 SCM_VALIDATE_VM (1, vm);
7656f194
AW
645 return scm_from_int (SCM_VM_DATA (vm)->trace_level);
646}
647#undef FUNC_NAME
648
649SCM_DEFINE (scm_set_vm_trace_level_x, "set-vm-trace-level!", 2, 0, 0,
650 (SCM vm, SCM level),
651 "")
652#define FUNC_NAME s_scm_set_vm_trace_level_x
653{
654 SCM_VALIDATE_VM (1, vm);
655 SCM_VM_DATA (vm)->trace_level = scm_to_int (level);
656 return SCM_UNSPECIFIED;
a98cef7e
KN
657}
658#undef FUNC_NAME
659
660\f
661/*
17e90c5e 662 * Initialize
a98cef7e
KN
663 */
664
07e56b27
AW
665SCM scm_load_compiled_with_vm (SCM file)
666{
53e28ed9 667 SCM program = scm_make_program (scm_load_objcode (file),
20d47c39 668 SCM_BOOL_F, SCM_BOOL_F);
07e56b27 669
4abef68f 670 return scm_c_vm_run (scm_the_vm (), program, NULL, 0);
07e56b27
AW
671}
672
17e90c5e 673void
07e56b27 674scm_bootstrap_vm (void)
17e90c5e 675{
60ae5ca2
AW
676 scm_c_register_extension ("libguile", "scm_init_vm",
677 (scm_t_extension_init_func)scm_init_vm, NULL);
678
e3eb628d
LC
679#ifdef VM_ENABLE_PRECISE_STACK_GC_SCAN
680 vm_stack_gc_kind =
681 GC_new_kind (GC_new_free_list (),
682 GC_MAKE_PROC (GC_new_proc (vm_stack_mark), 0),
683 0, 1);
684
685#endif
07e56b27
AW
686}
687
688void
689scm_init_vm (void)
690{
17e90c5e 691#ifndef SCM_MAGIC_SNARFER
aeeff258 692#include "libguile/vm.x"
17e90c5e 693#endif
a98cef7e 694}
17e90c5e
KN
695
696/*
697 Local Variables:
698 c-file-style: "gnu"
699 End:
700*/