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