Fix bogus computation of `vm->stack_limit'.
[bpt/guile.git] / libguile / vm.c
CommitLineData
20d47c39 1/* Copyright (C) 2001, 2009 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>
560b9c25 26#include "_scm.h"
83495480 27#include "vm-bootstrap.h"
ac99cb0c 28#include "frames.h"
17e90c5e 29#include "instructions.h"
8f5cfc81 30#include "objcodes.h"
ac99cb0c 31#include "programs.h"
fb10a008 32#include "lang.h" /* NULL_OR_NIL_P */
a98cef7e
KN
33#include "vm.h"
34
a98cef7e
KN
35/* I sometimes use this for debugging. */
36#define vm_puts(OBJ) \
37{ \
22bcbe8c
AW
38 scm_display (OBJ, scm_current_error_port ()); \
39 scm_newline (scm_current_error_port ()); \
a98cef7e
KN
40}
41
11ea1aba
AW
42/* The VM has a number of internal assertions that shouldn't normally be
43 necessary, but might be if you think you found a bug in the VM. */
44#define VM_ENABLE_ASSERTIONS
45
46/* We can add a mode that ensures that all stack items above the stack pointer
47 are NULL. This is useful for checking the internal consistency of the VM's
48 assumptions and its operators, but isn't necessary for normal operation. It
616167fc 49 will ensure that assertions are enabled. Slows down the VM by about 30%. */
747a1635 50/* NB! If you enable this, search for NULLING in throw.c */
616167fc 51/* #define VM_ENABLE_STACK_NULLING */
11ea1aba 52
53e28ed9
AW
53/* #define VM_ENABLE_PARANOID_ASSERTIONS */
54
11ea1aba
AW
55#if defined (VM_ENABLE_STACK_NULLING) && !defined (VM_ENABLE_ASSERTIONS)
56#define VM_ENABLE_ASSERTIONS
57#endif
58
a98cef7e 59\f
a98cef7e
KN
60/*
61 * VM Continuation
62 */
63
f9e8c09d 64scm_t_bits scm_tc16_vm_cont;
17e90c5e 65
a98cef7e 66static SCM
3d5ee0cd 67capture_vm_cont (struct scm_vm *vp)
a98cef7e 68{
bfffd258
AW
69 struct scm_vm_cont *p = scm_gc_malloc (sizeof (*p), "capture_vm_cont");
70 p->stack_size = vp->sp - vp->stack_base + 1;
d8eeb67c
LC
71 p->stack_base = scm_gc_malloc (p->stack_size * sizeof (SCM),
72 "capture_vm_cont");
11ea1aba 73#ifdef VM_ENABLE_STACK_NULLING
66db076a
AW
74 if (vp->sp >= vp->stack_base)
75 if (!vp->sp[0] || vp->sp[1])
76 abort ();
11ea1aba
AW
77 memset (p->stack_base, 0, p->stack_size * sizeof (SCM));
78#endif
3d5ee0cd 79 p->ip = vp->ip;
7aa6f86b
AW
80 p->sp = vp->sp;
81 p->fp = vp->fp;
bfffd258 82 memcpy (p->stack_base, vp->stack_base, p->stack_size * sizeof (SCM));
11ea1aba 83 p->reloc = p->stack_base - vp->stack_base;
17e90c5e 84 SCM_RETURN_NEWSMOB (scm_tc16_vm_cont, p);
a98cef7e
KN
85}
86
87static void
3d5ee0cd 88reinstate_vm_cont (struct scm_vm *vp, SCM cont)
a98cef7e 89{
bfffd258 90 struct scm_vm_cont *p = SCM_VM_CONT_DATA (cont);
3d5ee0cd 91 if (vp->stack_size < p->stack_size)
a98cef7e 92 {
17e90c5e 93 /* puts ("FIXME: Need to expand"); */
a98cef7e
KN
94 abort ();
95 }
11ea1aba
AW
96#ifdef VM_ENABLE_STACK_NULLING
97 {
7aa6f86b 98 scm_t_ptrdiff nzero = (vp->sp - p->sp);
11ea1aba 99 if (nzero > 0)
66db076a
AW
100 memset (vp->stack_base + p->stack_size, 0, nzero * sizeof (SCM));
101 /* actually nzero should always be negative, because vm_reset_stack will
102 unwind the stack to some point *below* this continuation */
11ea1aba
AW
103 }
104#endif
3d5ee0cd 105 vp->ip = p->ip;
7aa6f86b
AW
106 vp->sp = p->sp;
107 vp->fp = p->fp;
bfffd258
AW
108 memcpy (vp->stack_base, p->stack_base, p->stack_size * sizeof (SCM));
109}
110
111/* In theory, a number of vm instances can be active in the call trace, and we
112 only want to reify the continuations of those in the current continuation
113 root. I don't see a nice way to do this -- ideally it would involve dynwinds,
114 and previous values of the *the-vm* fluid within the current continuation
115 root. But we don't have access to continuation roots in the dynwind stack.
116 So, just punt for now -- take the current value of *the-vm*.
117
118 While I'm on the topic, ideally we could avoid copying the C stack if the
119 continuation root is inside VM code, and call/cc was invoked within that same
120 call to vm_run; but that's currently not implemented.
121 */
122SCM
123scm_vm_capture_continuations (void)
124{
125 SCM vm = scm_the_vm ();
126 return scm_acons (vm, capture_vm_cont (SCM_VM_DATA (vm)), SCM_EOL);
127}
128
129void
130scm_vm_reinstate_continuations (SCM conts)
131{
132 for (; conts != SCM_EOL; conts = SCM_CDR (conts))
133 reinstate_vm_cont (SCM_VM_DATA (SCM_CAAR (conts)), SCM_CDAR (conts));
a98cef7e
KN
134}
135
b1b942b7
AW
136static void enfalsen_frame (void *p)
137{
138 struct scm_vm *vp = p;
139 vp->trace_frame = SCM_BOOL_F;
140}
141
142static void
6d14383e 143vm_dispatch_hook (struct scm_vm *vp, SCM hook, SCM hook_args)
b1b942b7 144{
b1b942b7
AW
145 if (!SCM_FALSEP (vp->trace_frame))
146 return;
147
148 scm_dynwind_begin (0);
6d14383e
AW
149 // FIXME, stack holder should be the vm
150 vp->trace_frame = scm_c_make_vm_frame (SCM_BOOL_F, vp->fp, vp->sp, vp->ip, 0);
b1b942b7
AW
151 scm_dynwind_unwind_handler (enfalsen_frame, vp, SCM_F_WIND_EXPLICITLY);
152
153 scm_c_run_hook (hook, hook_args);
154
155 scm_dynwind_end ();
156}
157
17e90c5e
KN
158\f
159/*
160 * VM Internal functions
161 */
162
90b0be20
AW
163static SCM sym_vm_run;
164static SCM sym_vm_error;
165static SCM sym_debug;
17e90c5e 166
2fda0242 167static SCM
d2d7acd5 168really_make_boot_program (long nargs)
2fda0242 169{
5bd047ce 170 SCM u8vec;
28b119ee
AW
171 /* Make sure "bytes" is 64-bit aligned. */
172 scm_t_uint8 text[] = { scm_op_mv_call, 0, 0, 1,
e5dc27b8 173 scm_op_make_int8_1, scm_op_nop, scm_op_nop, scm_op_nop,
28b119ee
AW
174 scm_op_halt };
175 struct scm_objcode *bp;
3b9e095b 176 SCM ret;
5bd047ce 177
53e28ed9 178 if (SCM_UNLIKELY (nargs > 255 || nargs < 0))
2fda0242 179 abort ();
28b119ee
AW
180 text[1] = (scm_t_uint8)nargs;
181
182 bp = scm_gc_malloc (sizeof (struct scm_objcode) + sizeof (text),
183 "make-u8vector");
184 memcpy (bp->base, text, sizeof (text));
185 bp->nargs = 0;
186 bp->nrest = 0;
187 bp->nlocs = 0;
188 bp->len = sizeof(text);
189 bp->metalen = 0;
190 bp->unused = 0;
191
192 u8vec = scm_take_u8vector ((scm_t_uint8*)bp,
193 sizeof (struct scm_objcode) + sizeof (text));
5bd047ce 194 ret = scm_make_program (scm_bytecode_to_objcode (u8vec),
20d47c39 195 SCM_BOOL_F, SCM_BOOL_F);
3b9e095b 196 SCM_SET_SMOB_FLAGS (ret, SCM_F_PROGRAM_IS_BOOT);
5bd047ce 197
3b9e095b 198 return ret;
2fda0242 199}
d2d7acd5
AW
200#define NUM_BOOT_PROGS 8
201static SCM
202vm_make_boot_program (long nargs)
203{
204 static SCM programs[NUM_BOOT_PROGS] = { 0, };
205
206 if (SCM_UNLIKELY (!programs[0]))
207 {
208 int i;
209 for (i = 0; i < NUM_BOOT_PROGS; i++)
210 programs[i] = scm_permanent_object (really_make_boot_program (i));
211 }
212
213 if (SCM_LIKELY (nargs < NUM_BOOT_PROGS))
214 return programs[nargs];
215 else
216 return really_make_boot_program (nargs);
217}
2fda0242 218
a98cef7e
KN
219\f
220/*
221 * VM
222 */
223
b7393ea1
AW
224static SCM
225resolve_variable (SCM what, SCM program_module)
226{
227 if (SCM_LIKELY (SCM_SYMBOLP (what)))
228 {
229 if (SCM_LIKELY (scm_module_system_booted_p
230 && scm_is_true (program_module)))
231 /* might longjmp */
232 return scm_module_lookup (program_module, what);
233 else
234 {
235 SCM v = scm_sym2var (what, SCM_BOOL_F, SCM_BOOL_F);
236 if (scm_is_false (v))
237 scm_misc_error (NULL, "unbound variable: ~S", scm_list_1 (what));
238 else
239 return v;
240 }
241 }
242 else
243 {
244 SCM mod;
245 /* compilation of @ or @@
246 `what' is a three-element list: (MODNAME SYM INTERFACE?)
247 INTERFACE? is #t if we compiled @ or #f if we compiled @@
248 */
249 mod = scm_resolve_module (SCM_CAR (what));
250 if (scm_is_true (SCM_CADDR (what)))
251 mod = scm_module_public_interface (mod);
252 if (SCM_FALSEP (mod))
253 scm_misc_error (NULL, "no such module: ~S",
254 scm_list_1 (SCM_CAR (what)));
255 /* might longjmp */
256 return scm_module_lookup (mod, SCM_CADR (what));
257 }
258}
259
260
51e9ba2f 261#define VM_DEFAULT_STACK_SIZE (64 * 1024)
17e90c5e 262
17e90c5e 263#define VM_NAME vm_regular_engine
6d14383e
AW
264#define FUNC_NAME "vm-regular-engine"
265#define VM_ENGINE SCM_VM_REGULAR_ENGINE
83495480 266#include "vm-engine.c"
17e90c5e 267#undef VM_NAME
6d14383e 268#undef FUNC_NAME
17e90c5e 269#undef VM_ENGINE
17e90c5e
KN
270
271#define VM_NAME vm_debug_engine
6d14383e
AW
272#define FUNC_NAME "vm-debug-engine"
273#define VM_ENGINE SCM_VM_DEBUG_ENGINE
83495480 274#include "vm-engine.c"
17e90c5e 275#undef VM_NAME
6d14383e 276#undef FUNC_NAME
17e90c5e
KN
277#undef VM_ENGINE
278
6d14383e
AW
279static const scm_t_vm_engine vm_engines[] =
280 { vm_regular_engine, vm_debug_engine };
281
f9e8c09d 282scm_t_bits scm_tc16_vm;
a98cef7e
KN
283
284static SCM
17e90c5e
KN
285make_vm (void)
286#define FUNC_NAME "make_vm"
a98cef7e 287{
17e90c5e 288 int i;
747a1635
AW
289
290 if (!scm_tc16_vm)
291 return SCM_BOOL_F; /* not booted yet */
292
d8eeb67c
LC
293 struct scm_vm *vp = scm_gc_malloc (sizeof (struct scm_vm), "vm");
294
3d5ee0cd 295 vp->stack_size = VM_DEFAULT_STACK_SIZE;
d8eeb67c
LC
296 vp->stack_base = scm_gc_malloc (vp->stack_size * sizeof (SCM),
297 "stack-base");
2bbe1533
AW
298#ifdef VM_ENABLE_STACK_NULLING
299 memset (vp->stack_base, 0, vp->stack_size * sizeof (SCM));
300#endif
75d315e1 301 vp->stack_limit = vp->stack_base + vp->stack_size;
3616e9e9
KN
302 vp->ip = NULL;
303 vp->sp = vp->stack_base - 1;
304 vp->fp = NULL;
6d14383e 305 vp->engine = SCM_VM_DEBUG_ENGINE;
3d5ee0cd
KN
306 vp->time = 0;
307 vp->clock = 0;
308 vp->options = SCM_EOL;
17e90c5e 309 for (i = 0; i < SCM_VM_NUM_HOOKS; i++)
3d5ee0cd 310 vp->hooks[i] = SCM_BOOL_F;
b1b942b7 311 vp->trace_frame = SCM_BOOL_F;
3d5ee0cd 312 SCM_RETURN_NEWSMOB (scm_tc16_vm, vp);
a98cef7e 313}
17e90c5e 314#undef FUNC_NAME
a98cef7e 315
6d14383e 316SCM
4abef68f 317scm_c_vm_run (SCM vm, SCM program, SCM *argv, int nargs)
6d14383e 318{
4abef68f 319 struct scm_vm *vp = SCM_VM_DATA (vm);
6d14383e
AW
320 return vm_engines[vp->engine](vp, program, argv, nargs);
321}
322
17e90c5e
KN
323SCM
324scm_vm_apply (SCM vm, SCM program, SCM args)
325#define FUNC_NAME "scm_vm_apply"
a98cef7e 326{
6d14383e
AW
327 SCM *argv;
328 int i, nargs;
329
330 SCM_VALIDATE_VM (1, vm);
331 SCM_VALIDATE_PROGRAM (2, program);
332
333 nargs = scm_ilength (args);
334 if (SCM_UNLIKELY (nargs < 0))
335 scm_wrong_type_arg_msg (FUNC_NAME, 3, args, "list");
336
337 argv = alloca(nargs * sizeof(SCM));
338 for (i = 0; i < nargs; i++)
339 {
340 argv[i] = SCM_CAR (args);
341 args = SCM_CDR (args);
342 }
343
4abef68f 344 return scm_c_vm_run (vm, program, argv, nargs);
a98cef7e 345}
17e90c5e 346#undef FUNC_NAME
a98cef7e
KN
347
348/* Scheme interface */
349
350SCM_DEFINE (scm_vm_version, "vm-version", 0, 0, 0,
17e90c5e
KN
351 (void),
352 "")
a98cef7e
KN
353#define FUNC_NAME s_scm_vm_version
354{
d3518113 355 return scm_from_locale_string (PACKAGE_VERSION);
a98cef7e
KN
356}
357#undef FUNC_NAME
358
499a4c07 359SCM_DEFINE (scm_the_vm, "the-vm", 0, 0, 0,
fcd4901b 360 (void),
499a4c07
KN
361 "")
362#define FUNC_NAME s_scm_the_vm
363{
2bbe1533 364 scm_i_thread *t = SCM_I_CURRENT_THREAD;
f63ea2ce 365
2bbe1533
AW
366 if (SCM_UNLIKELY (SCM_FALSEP ((t->vm))))
367 t->vm = make_vm ();
f63ea2ce 368
2bbe1533 369 return t->vm;
499a4c07
KN
370}
371#undef FUNC_NAME
372
373
a98cef7e
KN
374SCM_DEFINE (scm_vm_p, "vm?", 1, 0, 0,
375 (SCM obj),
17e90c5e 376 "")
a98cef7e
KN
377#define FUNC_NAME s_scm_vm_p
378{
379 return SCM_BOOL (SCM_VM_P (obj));
380}
381#undef FUNC_NAME
382
383SCM_DEFINE (scm_make_vm, "make-vm", 0, 0, 0,
17e90c5e
KN
384 (void),
385 "")
386#define FUNC_NAME s_scm_make_vm,
a98cef7e 387{
17e90c5e 388 return make_vm ();
a98cef7e
KN
389}
390#undef FUNC_NAME
391
17e90c5e 392SCM_DEFINE (scm_vm_ip, "vm:ip", 1, 0, 0,
a98cef7e 393 (SCM vm),
17e90c5e
KN
394 "")
395#define FUNC_NAME s_scm_vm_ip
a98cef7e
KN
396{
397 SCM_VALIDATE_VM (1, vm);
f41cb00c 398 return scm_from_ulong ((unsigned long) SCM_VM_DATA (vm)->ip);
a98cef7e
KN
399}
400#undef FUNC_NAME
401
402SCM_DEFINE (scm_vm_sp, "vm:sp", 1, 0, 0,
403 (SCM vm),
17e90c5e 404 "")
a98cef7e
KN
405#define FUNC_NAME s_scm_vm_sp
406{
407 SCM_VALIDATE_VM (1, vm);
f41cb00c 408 return scm_from_ulong ((unsigned long) SCM_VM_DATA (vm)->sp);
a98cef7e
KN
409}
410#undef FUNC_NAME
411
412SCM_DEFINE (scm_vm_fp, "vm:fp", 1, 0, 0,
413 (SCM vm),
17e90c5e 414 "")
a98cef7e
KN
415#define FUNC_NAME s_scm_vm_fp
416{
417 SCM_VALIDATE_VM (1, vm);
f41cb00c 418 return scm_from_ulong ((unsigned long) SCM_VM_DATA (vm)->fp);
a98cef7e
KN
419}
420#undef FUNC_NAME
421
17e90c5e
KN
422#define VM_DEFINE_HOOK(n) \
423{ \
3d5ee0cd 424 struct scm_vm *vp; \
17e90c5e 425 SCM_VALIDATE_VM (1, vm); \
3d5ee0cd
KN
426 vp = SCM_VM_DATA (vm); \
427 if (SCM_FALSEP (vp->hooks[n])) \
238e7a11 428 vp->hooks[n] = scm_make_hook (SCM_I_MAKINUM (1)); \
3d5ee0cd 429 return vp->hooks[n]; \
17e90c5e
KN
430}
431
432SCM_DEFINE (scm_vm_boot_hook, "vm-boot-hook", 1, 0, 0,
a98cef7e 433 (SCM vm),
17e90c5e
KN
434 "")
435#define FUNC_NAME s_scm_vm_boot_hook
a98cef7e 436{
17e90c5e 437 VM_DEFINE_HOOK (SCM_VM_BOOT_HOOK);
a98cef7e
KN
438}
439#undef FUNC_NAME
440
17e90c5e
KN
441SCM_DEFINE (scm_vm_halt_hook, "vm-halt-hook", 1, 0, 0,
442 (SCM vm),
443 "")
444#define FUNC_NAME s_scm_vm_halt_hook
a98cef7e 445{
17e90c5e 446 VM_DEFINE_HOOK (SCM_VM_HALT_HOOK);
a98cef7e
KN
447}
448#undef FUNC_NAME
449
17e90c5e 450SCM_DEFINE (scm_vm_next_hook, "vm-next-hook", 1, 0, 0,
a98cef7e 451 (SCM vm),
17e90c5e
KN
452 "")
453#define FUNC_NAME s_scm_vm_next_hook
a98cef7e 454{
17e90c5e 455 VM_DEFINE_HOOK (SCM_VM_NEXT_HOOK);
a98cef7e
KN
456}
457#undef FUNC_NAME
458
7a0d0cee
KN
459SCM_DEFINE (scm_vm_break_hook, "vm-break-hook", 1, 0, 0,
460 (SCM vm),
461 "")
462#define FUNC_NAME s_scm_vm_break_hook
463{
464 VM_DEFINE_HOOK (SCM_VM_BREAK_HOOK);
465}
466#undef FUNC_NAME
467
17e90c5e
KN
468SCM_DEFINE (scm_vm_enter_hook, "vm-enter-hook", 1, 0, 0,
469 (SCM vm),
470 "")
471#define FUNC_NAME s_scm_vm_enter_hook
a98cef7e 472{
17e90c5e 473 VM_DEFINE_HOOK (SCM_VM_ENTER_HOOK);
a98cef7e
KN
474}
475#undef FUNC_NAME
476
17e90c5e
KN
477SCM_DEFINE (scm_vm_apply_hook, "vm-apply-hook", 1, 0, 0,
478 (SCM vm),
479 "")
480#define FUNC_NAME s_scm_vm_apply_hook
a98cef7e 481{
17e90c5e 482 VM_DEFINE_HOOK (SCM_VM_APPLY_HOOK);
a98cef7e
KN
483}
484#undef FUNC_NAME
485
17e90c5e 486SCM_DEFINE (scm_vm_exit_hook, "vm-exit-hook", 1, 0, 0,
a98cef7e 487 (SCM vm),
17e90c5e
KN
488 "")
489#define FUNC_NAME s_scm_vm_exit_hook
a98cef7e 490{
17e90c5e 491 VM_DEFINE_HOOK (SCM_VM_EXIT_HOOK);
a98cef7e
KN
492}
493#undef FUNC_NAME
494
17e90c5e 495SCM_DEFINE (scm_vm_return_hook, "vm-return-hook", 1, 0, 0,
a98cef7e 496 (SCM vm),
17e90c5e
KN
497 "")
498#define FUNC_NAME s_scm_vm_return_hook
a98cef7e 499{
17e90c5e 500 VM_DEFINE_HOOK (SCM_VM_RETURN_HOOK);
a98cef7e
KN
501}
502#undef FUNC_NAME
503
17e90c5e
KN
504SCM_DEFINE (scm_vm_option, "vm-option", 2, 0, 0,
505 (SCM vm, SCM key),
506 "")
507#define FUNC_NAME s_scm_vm_option
a98cef7e
KN
508{
509 SCM_VALIDATE_VM (1, vm);
17e90c5e 510 return scm_assq_ref (SCM_VM_DATA (vm)->options, key);
a98cef7e
KN
511}
512#undef FUNC_NAME
513
17e90c5e
KN
514SCM_DEFINE (scm_set_vm_option_x, "set-vm-option!", 3, 0, 0,
515 (SCM vm, SCM key, SCM val),
516 "")
517#define FUNC_NAME s_scm_set_vm_option_x
a98cef7e
KN
518{
519 SCM_VALIDATE_VM (1, vm);
17e90c5e
KN
520 SCM_VM_DATA (vm)->options
521 = scm_assq_set_x (SCM_VM_DATA (vm)->options, key, val);
522 return SCM_UNSPECIFIED;
a98cef7e
KN
523}
524#undef FUNC_NAME
525
17e90c5e 526SCM_DEFINE (scm_vm_stats, "vm-stats", 1, 0, 0,
a98cef7e 527 (SCM vm),
17e90c5e
KN
528 "")
529#define FUNC_NAME s_scm_vm_stats
a98cef7e 530{
17e90c5e
KN
531 SCM stats;
532
a98cef7e 533 SCM_VALIDATE_VM (1, vm);
17e90c5e 534
2d80426a
LC
535 stats = scm_make_vector (SCM_I_MAKINUM (2), SCM_UNSPECIFIED);
536 scm_vector_set_x (stats, SCM_I_MAKINUM (0),
f9e8c09d 537 scm_from_ulong (SCM_VM_DATA (vm)->time));
2d80426a 538 scm_vector_set_x (stats, SCM_I_MAKINUM (1),
f9e8c09d 539 scm_from_ulong (SCM_VM_DATA (vm)->clock));
17e90c5e
KN
540
541 return stats;
a98cef7e
KN
542}
543#undef FUNC_NAME
544
b1b942b7 545SCM_DEFINE (scm_vm_trace_frame, "vm-trace-frame", 1, 0, 0,
17e90c5e
KN
546 (SCM vm),
547 "")
b1b942b7 548#define FUNC_NAME s_scm_vm_trace_frame
a98cef7e 549{
a98cef7e 550 SCM_VALIDATE_VM (1, vm);
b1b942b7 551 return SCM_VM_DATA (vm)->trace_frame;
a98cef7e
KN
552}
553#undef FUNC_NAME
554
555\f
556/*
17e90c5e 557 * Initialize
a98cef7e
KN
558 */
559
07e56b27
AW
560SCM scm_load_compiled_with_vm (SCM file)
561{
53e28ed9 562 SCM program = scm_make_program (scm_load_objcode (file),
20d47c39 563 SCM_BOOL_F, SCM_BOOL_F);
07e56b27 564
4abef68f 565 return scm_c_vm_run (scm_the_vm (), program, NULL, 0);
07e56b27
AW
566}
567
17e90c5e 568void
07e56b27 569scm_bootstrap_vm (void)
17e90c5e 570{
07e56b27
AW
571 static int strappage = 0;
572
573 if (strappage)
574 return;
575
576 scm_bootstrap_frames ();
577 scm_bootstrap_instructions ();
578 scm_bootstrap_objcodes ();
579 scm_bootstrap_programs ();
a98cef7e 580
17e90c5e 581 scm_tc16_vm_cont = scm_make_smob_type ("vm-cont", 0);
a98cef7e 582
17e90c5e 583 scm_tc16_vm = scm_make_smob_type ("vm", 0);
17e90c5e 584 scm_set_smob_apply (scm_tc16_vm, scm_vm_apply, 1, 0, 1);
a98cef7e 585
83495480
AW
586 scm_c_define ("load-compiled",
587 scm_c_make_gsubr ("load-compiled/vm", 1, 0, 0,
588 scm_load_compiled_with_vm));
07e56b27 589
90b0be20
AW
590 sym_vm_run = scm_permanent_object (scm_from_locale_symbol ("vm-run"));
591 sym_vm_error = scm_permanent_object (scm_from_locale_symbol ("vm-error"));
592 sym_debug = scm_permanent_object (scm_from_locale_symbol ("debug"));
593
60ae5ca2
AW
594 scm_c_register_extension ("libguile", "scm_init_vm",
595 (scm_t_extension_init_func)scm_init_vm, NULL);
596
07e56b27
AW
597 strappage = 1;
598}
599
600void
601scm_init_vm (void)
602{
603 scm_bootstrap_vm ();
604
17e90c5e 605#ifndef SCM_MAGIC_SNARFER
aeeff258 606#include "libguile/vm.x"
17e90c5e 607#endif
a98cef7e 608}
17e90c5e
KN
609
610/*
611 Local Variables:
612 c-file-style: "gnu"
613 End:
614*/