fix bug in compilation of `and' and `or'; more robust underflow detection.
[bpt/guile.git] / src / vm.c
CommitLineData
8f5cfc81 1/* Copyright (C) 2001 Free Software Foundation, Inc.
a98cef7e
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>
ac99cb0c
KN
47#include "envs.h"
48#include "frames.h"
17e90c5e 49#include "instructions.h"
8f5cfc81 50#include "objcodes.h"
ac99cb0c 51#include "programs.h"
a98cef7e
KN
52#include "vm.h"
53
a98cef7e
KN
54/* I sometimes use this for debugging. */
55#define vm_puts(OBJ) \
56{ \
22bcbe8c
AW
57 scm_display (OBJ, scm_current_error_port ()); \
58 scm_newline (scm_current_error_port ()); \
a98cef7e
KN
59}
60
61\f
a98cef7e
KN
62/*
63 * VM Continuation
64 */
65
f9e8c09d 66scm_t_bits scm_tc16_vm_cont;
17e90c5e
KN
67
68
69#define SCM_VM_CONT_P(OBJ) SCM_SMOB_PREDICATE (scm_tc16_vm_cont, OBJ)
3d5ee0cd 70#define SCM_VM_CONT_VP(CONT) ((struct scm_vm *) SCM_CELL_WORD_1 (CONT))
a98cef7e
KN
71
72static SCM
3d5ee0cd 73capture_vm_cont (struct scm_vm *vp)
a98cef7e 74{
d8eeb67c 75 struct scm_vm *p = scm_gc_malloc (sizeof (*p), "capture_vm_cont");
3d5ee0cd 76 p->stack_size = vp->stack_limit - vp->sp;
d8eeb67c
LC
77 p->stack_base = scm_gc_malloc (p->stack_size * sizeof (SCM),
78 "capture_vm_cont");
17e90c5e 79 p->stack_limit = p->stack_base + p->stack_size - 2;
3d5ee0cd
KN
80 p->ip = vp->ip;
81 p->sp = (SCM *) (vp->stack_limit - vp->sp);
82 p->fp = (SCM *) (vp->stack_limit - vp->fp);
83 memcpy (p->stack_base, vp->sp + 1, vp->stack_size * sizeof (SCM));
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{
3d5ee0cd
KN
90 struct scm_vm *p = SCM_VM_CONT_VP (cont);
91 if (vp->stack_size < p->stack_size)
a98cef7e 92 {
17e90c5e 93 /* puts ("FIXME: Need to expand"); */
a98cef7e
KN
94 abort ();
95 }
3d5ee0cd
KN
96 vp->ip = p->ip;
97 vp->sp = vp->stack_limit - (int) p->sp;
98 vp->fp = vp->stack_limit - (int) p->fp;
99 memcpy (vp->sp + 1, p->stack_base, p->stack_size * sizeof (SCM));
a98cef7e
KN
100}
101
17d1b4bf
AW
102struct vm_unwind_data
103{
104 struct scm_vm *vp;
105 SCM *sp;
106 SCM *fp;
107 SCM this_frame;
108};
109
110static void
111vm_reset_stack (void *data)
112{
113 struct vm_unwind_data *w = data;
114
115 w->vp->sp = w->sp;
116 w->vp->fp = w->fp;
117 w->vp->this_frame = w->this_frame;
118}
119
a98cef7e 120static SCM
17e90c5e 121vm_cont_mark (SCM obj)
a98cef7e
KN
122{
123 SCM *p;
3d5ee0cd
KN
124 struct scm_vm *vp = SCM_VM_CONT_VP (obj);
125 for (p = vp->stack_base; p <= vp->stack_limit; p++)
a98cef7e
KN
126 if (SCM_NIMP (*p))
127 scm_gc_mark (*p);
128 return SCM_BOOL_F;
129}
130
131static scm_sizet
17e90c5e 132vm_cont_free (SCM obj)
a98cef7e 133{
3d5ee0cd 134 struct scm_vm *p = SCM_VM_CONT_VP (obj);
d8eeb67c
LC
135
136 scm_gc_free (p->stack_base, p->stack_size * sizeof (SCM), "stack-base");
137 scm_gc_free (p, sizeof (struct scm_vm), "vm");
138
139 return 0;
a98cef7e
KN
140}
141
17e90c5e
KN
142\f
143/*
144 * VM Internal functions
145 */
146
41f248a8 147SCM_SYMBOL (sym_vm_run, "vm-run");
17e90c5e
KN
148SCM_SYMBOL (sym_vm_error, "vm-error");
149
150static scm_byte_t *
151vm_fetch_length (scm_byte_t *ip, size_t *lenp)
a98cef7e 152{
4bfb26f5 153 /* NOTE: format defined in system/vm/conv.scm */
17e90c5e
KN
154 *lenp = *ip++;
155 if (*lenp < 254)
156 return ip;
157 else if (*lenp == 254)
46cd9a34
KN
158 {
159 int b1 = *ip++;
160 int b2 = *ip++;
161 *lenp = (b1 << 8) + b2;
162 }
17e90c5e 163 else
46cd9a34
KN
164 {
165 int b1 = *ip++;
166 int b2 = *ip++;
167 int b3 = *ip++;
168 int b4 = *ip++;
169 *lenp = (b1 << 24) + (b2 << 16) + (b3 << 8) + b4;
170 }
17e90c5e 171 return ip;
a98cef7e
KN
172}
173
af988bbf 174static SCM
a6df585a 175vm_heapify_frames_1 (struct scm_vm *vp, SCM *fp, SCM *sp, SCM **destp)
af988bbf 176{
a6df585a 177 SCM frame;
af988bbf 178 SCM *dl = SCM_FRAME_DYNAMIC_LINK (fp);
a6df585a
KN
179 SCM *src = SCM_FRAME_UPPER_ADDRESS (fp);
180 SCM *dest = SCM_FRAME_LOWER_ADDRESS (fp);
af988bbf
KN
181
182 if (!dl)
183 {
184 /* The top frame */
af988bbf
KN
185 frame = scm_c_make_heap_frame (fp);
186 fp = SCM_HEAP_FRAME_POINTER (frame);
187 SCM_FRAME_HEAP_LINK (fp) = SCM_BOOL_T;
188 }
189 else
190 {
a6df585a 191 /* Child frames */
af988bbf
KN
192 SCM link = SCM_FRAME_HEAP_LINK (dl);
193 if (!SCM_FALSEP (link))
a6df585a 194 link = SCM_FRAME_LOWER_ADDRESS (dl)[-1]; /* self link */
af988bbf 195 else
a6df585a 196 link = vm_heapify_frames_1 (vp, dl, dest - 1, &dest);
af988bbf
KN
197 frame = scm_c_make_heap_frame (fp);
198 fp = SCM_HEAP_FRAME_POINTER (frame);
199 SCM_FRAME_HEAP_LINK (fp) = link;
b6368dbb 200 SCM_FRAME_SET_DYNAMIC_LINK (fp, SCM_HEAP_FRAME_POINTER (link));
af988bbf
KN
201 }
202
17d1b4bf
AW
203 /* Apparently the intention here is to be able to have a frame on the heap,
204 but data on the stack, so that you can push as much as you want on the
205 stack; but I think that it's currently causing borkage with nonlocal exits
206 and the unwind handler, which reinstates the sp and fp, but it's no longer
207 pointing at a valid stack frame. So disable for now, we'll get back to
208 this later. */
209#if 0
af988bbf 210 /* Move stack data */
a6df585a
KN
211 for (; src <= sp; src++, dest++)
212 *dest = *src;
213 *destp = dest;
17d1b4bf 214#endif
af988bbf
KN
215
216 return frame;
217}
218
219static SCM
220vm_heapify_frames (SCM vm)
221{
222 struct scm_vm *vp = SCM_VM_DATA (vm);
223 if (SCM_FALSEP (SCM_FRAME_HEAP_LINK (vp->fp)))
224 {
a6df585a
KN
225 SCM *dest;
226 vp->this_frame = vm_heapify_frames_1 (vp, vp->fp, vp->sp, &dest);
af988bbf 227 vp->fp = SCM_HEAP_FRAME_POINTER (vp->this_frame);
a6df585a 228 vp->sp = dest - 1;
af988bbf
KN
229 }
230 return vp->this_frame;
231}
232
a98cef7e
KN
233\f
234/*
235 * VM
236 */
237
c0a25ecc 238#define VM_DEFAULT_STACK_SIZE (16 * 1024)
17e90c5e
KN
239
240#define VM_REGULAR_ENGINE 0
241#define VM_DEBUG_ENGINE 1
242
243#if 0
244#define VM_NAME vm_regular_engine
245#define VM_ENGINE VM_REGULAR_ENGINE
246#include "vm_engine.c"
247#undef VM_NAME
248#undef VM_ENGINE
249#endif
250
251#define VM_NAME vm_debug_engine
252#define VM_ENGINE VM_DEBUG_ENGINE
253#include "vm_engine.c"
254#undef VM_NAME
255#undef VM_ENGINE
256
f9e8c09d 257scm_t_bits scm_tc16_vm;
a98cef7e 258
499a4c07
KN
259static SCM the_vm;
260
a98cef7e 261static SCM
17e90c5e
KN
262make_vm (void)
263#define FUNC_NAME "make_vm"
a98cef7e 264{
17e90c5e 265 int i;
d8eeb67c
LC
266 struct scm_vm *vp = scm_gc_malloc (sizeof (struct scm_vm), "vm");
267
3d5ee0cd 268 vp->stack_size = VM_DEFAULT_STACK_SIZE;
d8eeb67c
LC
269 vp->stack_base = scm_gc_malloc (vp->stack_size * sizeof (SCM),
270 "stack-base");
3616e9e9
KN
271 vp->stack_limit = vp->stack_base + vp->stack_size - 3;
272 vp->ip = NULL;
273 vp->sp = vp->stack_base - 1;
274 vp->fp = NULL;
3d5ee0cd
KN
275 vp->time = 0;
276 vp->clock = 0;
277 vp->options = SCM_EOL;
af988bbf 278 vp->this_frame = SCM_BOOL_F;
ac99cb0c 279 vp->last_frame = SCM_BOOL_F;
d0168f3d 280 vp->last_ip = NULL;
17e90c5e 281 for (i = 0; i < SCM_VM_NUM_HOOKS; i++)
3d5ee0cd
KN
282 vp->hooks[i] = SCM_BOOL_F;
283 SCM_RETURN_NEWSMOB (scm_tc16_vm, vp);
a98cef7e 284}
17e90c5e 285#undef FUNC_NAME
a98cef7e
KN
286
287static SCM
17e90c5e 288vm_mark (SCM obj)
a98cef7e 289{
17e90c5e 290 int i;
3d5ee0cd 291 struct scm_vm *vp = SCM_VM_DATA (obj);
17e90c5e 292
af988bbf
KN
293 /* mark the stack conservatively */
294 scm_mark_locations ((SCM_STACKITEM *) vp->stack_base,
295 sizeof (SCM) * (vp->sp - vp->stack_base + 1));
a98cef7e 296
af988bbf 297 /* mark other objects */
17e90c5e 298 for (i = 0; i < SCM_VM_NUM_HOOKS; i++)
3d5ee0cd 299 scm_gc_mark (vp->hooks[i]);
af988bbf 300 scm_gc_mark (vp->this_frame);
ac99cb0c 301 scm_gc_mark (vp->last_frame);
3d5ee0cd 302 return vp->options;
a98cef7e
KN
303}
304
17e90c5e
KN
305static scm_sizet
306vm_free (SCM obj)
307{
3d5ee0cd 308 struct scm_vm *vp = SCM_VM_DATA (obj);
d8eeb67c
LC
309
310 scm_gc_free (vp->stack_base, vp->stack_size * sizeof (SCM),
311 "stack-base");
312 scm_gc_free (vp, sizeof (struct scm_vm), "vm");
313
314 return 0;
17e90c5e
KN
315}
316
317SCM_SYMBOL (sym_debug, "debug");
318
319SCM
320scm_vm_apply (SCM vm, SCM program, SCM args)
321#define FUNC_NAME "scm_vm_apply"
a98cef7e 322{
17e90c5e 323 SCM_VALIDATE_PROGRAM (1, program);
41f248a8 324 return vm_run (vm, program, args);
a98cef7e 325}
17e90c5e 326#undef FUNC_NAME
a98cef7e
KN
327
328/* Scheme interface */
329
330SCM_DEFINE (scm_vm_version, "vm-version", 0, 0, 0,
17e90c5e
KN
331 (void),
332 "")
a98cef7e
KN
333#define FUNC_NAME s_scm_vm_version
334{
d3518113 335 return scm_from_locale_string (PACKAGE_VERSION);
a98cef7e
KN
336}
337#undef FUNC_NAME
338
499a4c07
KN
339SCM_DEFINE (scm_the_vm, "the-vm", 0, 0, 0,
340 (),
341 "")
342#define FUNC_NAME s_scm_the_vm
343{
344 return the_vm;
345}
346#undef FUNC_NAME
347
348
a98cef7e
KN
349SCM_DEFINE (scm_vm_p, "vm?", 1, 0, 0,
350 (SCM obj),
17e90c5e 351 "")
a98cef7e
KN
352#define FUNC_NAME s_scm_vm_p
353{
354 return SCM_BOOL (SCM_VM_P (obj));
355}
356#undef FUNC_NAME
357
358SCM_DEFINE (scm_make_vm, "make-vm", 0, 0, 0,
17e90c5e
KN
359 (void),
360 "")
361#define FUNC_NAME s_scm_make_vm,
a98cef7e 362{
17e90c5e 363 return make_vm ();
a98cef7e
KN
364}
365#undef FUNC_NAME
366
17e90c5e 367SCM_DEFINE (scm_vm_ip, "vm:ip", 1, 0, 0,
a98cef7e 368 (SCM vm),
17e90c5e
KN
369 "")
370#define FUNC_NAME s_scm_vm_ip
a98cef7e
KN
371{
372 SCM_VALIDATE_VM (1, vm);
f41cb00c 373 return scm_from_ulong ((unsigned long) SCM_VM_DATA (vm)->ip);
a98cef7e
KN
374}
375#undef FUNC_NAME
376
377SCM_DEFINE (scm_vm_sp, "vm:sp", 1, 0, 0,
378 (SCM vm),
17e90c5e 379 "")
a98cef7e
KN
380#define FUNC_NAME s_scm_vm_sp
381{
382 SCM_VALIDATE_VM (1, vm);
f41cb00c 383 return scm_from_ulong ((unsigned long) SCM_VM_DATA (vm)->sp);
a98cef7e
KN
384}
385#undef FUNC_NAME
386
387SCM_DEFINE (scm_vm_fp, "vm:fp", 1, 0, 0,
388 (SCM vm),
17e90c5e 389 "")
a98cef7e
KN
390#define FUNC_NAME s_scm_vm_fp
391{
392 SCM_VALIDATE_VM (1, vm);
f41cb00c 393 return scm_from_ulong ((unsigned long) SCM_VM_DATA (vm)->fp);
a98cef7e
KN
394}
395#undef FUNC_NAME
396
17e90c5e
KN
397#define VM_DEFINE_HOOK(n) \
398{ \
3d5ee0cd 399 struct scm_vm *vp; \
17e90c5e 400 SCM_VALIDATE_VM (1, vm); \
3d5ee0cd
KN
401 vp = SCM_VM_DATA (vm); \
402 if (SCM_FALSEP (vp->hooks[n])) \
238e7a11 403 vp->hooks[n] = scm_make_hook (SCM_I_MAKINUM (1)); \
3d5ee0cd 404 return vp->hooks[n]; \
17e90c5e
KN
405}
406
407SCM_DEFINE (scm_vm_boot_hook, "vm-boot-hook", 1, 0, 0,
a98cef7e 408 (SCM vm),
17e90c5e
KN
409 "")
410#define FUNC_NAME s_scm_vm_boot_hook
a98cef7e 411{
17e90c5e 412 VM_DEFINE_HOOK (SCM_VM_BOOT_HOOK);
a98cef7e
KN
413}
414#undef FUNC_NAME
415
17e90c5e
KN
416SCM_DEFINE (scm_vm_halt_hook, "vm-halt-hook", 1, 0, 0,
417 (SCM vm),
418 "")
419#define FUNC_NAME s_scm_vm_halt_hook
a98cef7e 420{
17e90c5e 421 VM_DEFINE_HOOK (SCM_VM_HALT_HOOK);
a98cef7e
KN
422}
423#undef FUNC_NAME
424
17e90c5e 425SCM_DEFINE (scm_vm_next_hook, "vm-next-hook", 1, 0, 0,
a98cef7e 426 (SCM vm),
17e90c5e
KN
427 "")
428#define FUNC_NAME s_scm_vm_next_hook
a98cef7e 429{
17e90c5e 430 VM_DEFINE_HOOK (SCM_VM_NEXT_HOOK);
a98cef7e
KN
431}
432#undef FUNC_NAME
433
7a0d0cee
KN
434SCM_DEFINE (scm_vm_break_hook, "vm-break-hook", 1, 0, 0,
435 (SCM vm),
436 "")
437#define FUNC_NAME s_scm_vm_break_hook
438{
439 VM_DEFINE_HOOK (SCM_VM_BREAK_HOOK);
440}
441#undef FUNC_NAME
442
17e90c5e
KN
443SCM_DEFINE (scm_vm_enter_hook, "vm-enter-hook", 1, 0, 0,
444 (SCM vm),
445 "")
446#define FUNC_NAME s_scm_vm_enter_hook
a98cef7e 447{
17e90c5e 448 VM_DEFINE_HOOK (SCM_VM_ENTER_HOOK);
a98cef7e
KN
449}
450#undef FUNC_NAME
451
17e90c5e
KN
452SCM_DEFINE (scm_vm_apply_hook, "vm-apply-hook", 1, 0, 0,
453 (SCM vm),
454 "")
455#define FUNC_NAME s_scm_vm_apply_hook
a98cef7e 456{
17e90c5e 457 VM_DEFINE_HOOK (SCM_VM_APPLY_HOOK);
a98cef7e
KN
458}
459#undef FUNC_NAME
460
17e90c5e 461SCM_DEFINE (scm_vm_exit_hook, "vm-exit-hook", 1, 0, 0,
a98cef7e 462 (SCM vm),
17e90c5e
KN
463 "")
464#define FUNC_NAME s_scm_vm_exit_hook
a98cef7e 465{
17e90c5e 466 VM_DEFINE_HOOK (SCM_VM_EXIT_HOOK);
a98cef7e
KN
467}
468#undef FUNC_NAME
469
17e90c5e 470SCM_DEFINE (scm_vm_return_hook, "vm-return-hook", 1, 0, 0,
a98cef7e 471 (SCM vm),
17e90c5e
KN
472 "")
473#define FUNC_NAME s_scm_vm_return_hook
a98cef7e 474{
17e90c5e 475 VM_DEFINE_HOOK (SCM_VM_RETURN_HOOK);
a98cef7e
KN
476}
477#undef FUNC_NAME
478
17e90c5e
KN
479SCM_DEFINE (scm_vm_option, "vm-option", 2, 0, 0,
480 (SCM vm, SCM key),
481 "")
482#define FUNC_NAME s_scm_vm_option
a98cef7e
KN
483{
484 SCM_VALIDATE_VM (1, vm);
17e90c5e 485 return scm_assq_ref (SCM_VM_DATA (vm)->options, key);
a98cef7e
KN
486}
487#undef FUNC_NAME
488
17e90c5e
KN
489SCM_DEFINE (scm_set_vm_option_x, "set-vm-option!", 3, 0, 0,
490 (SCM vm, SCM key, SCM val),
491 "")
492#define FUNC_NAME s_scm_set_vm_option_x
a98cef7e
KN
493{
494 SCM_VALIDATE_VM (1, vm);
17e90c5e
KN
495 SCM_VM_DATA (vm)->options
496 = scm_assq_set_x (SCM_VM_DATA (vm)->options, key, val);
497 return SCM_UNSPECIFIED;
a98cef7e
KN
498}
499#undef FUNC_NAME
500
17e90c5e 501SCM_DEFINE (scm_vm_stats, "vm-stats", 1, 0, 0,
a98cef7e 502 (SCM vm),
17e90c5e
KN
503 "")
504#define FUNC_NAME s_scm_vm_stats
a98cef7e 505{
17e90c5e
KN
506 SCM stats;
507
a98cef7e 508 SCM_VALIDATE_VM (1, vm);
17e90c5e 509
2d80426a
LC
510 stats = scm_make_vector (SCM_I_MAKINUM (2), SCM_UNSPECIFIED);
511 scm_vector_set_x (stats, SCM_I_MAKINUM (0),
f9e8c09d 512 scm_from_ulong (SCM_VM_DATA (vm)->time));
2d80426a 513 scm_vector_set_x (stats, SCM_I_MAKINUM (1),
f9e8c09d 514 scm_from_ulong (SCM_VM_DATA (vm)->clock));
17e90c5e
KN
515
516 return stats;
a98cef7e
KN
517}
518#undef FUNC_NAME
519
17e90c5e
KN
520#define VM_CHECK_RUNNING(vm) \
521 if (!SCM_VM_DATA (vm)->ip) \
522 SCM_MISC_ERROR ("Not running", SCM_LIST1 (vm))
523
af988bbf 524SCM_DEFINE (scm_vm_this_frame, "vm-this-frame", 1, 0, 0,
a98cef7e 525 (SCM vm),
17e90c5e 526 "")
af988bbf 527#define FUNC_NAME s_scm_vm_this_frame
a98cef7e
KN
528{
529 SCM_VALIDATE_VM (1, vm);
af988bbf 530 return SCM_VM_DATA (vm)->this_frame;
ac99cb0c
KN
531}
532#undef FUNC_NAME
533
534SCM_DEFINE (scm_vm_last_frame, "vm-last-frame", 1, 0, 0,
535 (SCM vm),
536 "")
537#define FUNC_NAME s_scm_vm_last_frame
538{
539 SCM_VALIDATE_VM (1, vm);
540 return SCM_VM_DATA (vm)->last_frame;
a98cef7e
KN
541}
542#undef FUNC_NAME
543
d0168f3d
AW
544SCM_DEFINE (scm_vm_last_ip, "vm:last-ip", 1, 0, 0,
545 (SCM vm),
546 "")
547#define FUNC_NAME s_scm_vm_last_ip
548{
549 SCM_VALIDATE_VM (1, vm);
550 return scm_from_ulong ((unsigned long) SCM_VM_DATA (vm)->last_ip);
551}
552#undef FUNC_NAME
553
68a2e18a
AW
554SCM_DEFINE (scm_vm_save_stack, "vm-save-stack", 1, 0, 0,
555 (SCM vm),
556 "")
557#define FUNC_NAME s_scm_vm_save_stack
558{
17d1b4bf
AW
559 struct scm_vm *vp;
560 SCM *dest;
68a2e18a 561 SCM_VALIDATE_VM (1, vm);
17d1b4bf 562 vp = SCM_VM_DATA (vm);
7e4760e4
AW
563
564 if (vp->fp)
565 {
566 vp->last_frame = vm_heapify_frames_1 (vp, vp->fp, vp->sp, &dest);
567 vp->last_ip = vp->ip;
568 }
569 else
570 {
571 vp->last_frame = SCM_BOOL_F;
572 }
573
574
17d1b4bf 575 return vp->last_frame;
68a2e18a
AW
576}
577#undef FUNC_NAME
578
17e90c5e
KN
579SCM_DEFINE (scm_vm_fetch_code, "vm-fetch-code", 1, 0, 0,
580 (SCM vm),
581 "")
582#define FUNC_NAME s_scm_vm_fetch_code
583{
584 int i;
585 SCM list;
586 scm_byte_t *ip;
587 struct scm_instruction *p;
a98cef7e 588
17e90c5e
KN
589 SCM_VALIDATE_VM (1, vm);
590 VM_CHECK_RUNNING (vm);
a98cef7e 591
17e90c5e
KN
592 ip = SCM_VM_DATA (vm)->ip;
593 p = SCM_INSTRUCTION (*ip);
a98cef7e 594
17e90c5e
KN
595 list = SCM_LIST1 (scm_str2symbol (p->name));
596 for (i = 1; i <= p->len; i++)
2d80426a 597 list = scm_cons (SCM_I_MAKINUM (ip[i]), list);
17e90c5e
KN
598 return scm_reverse_x (list, SCM_EOL);
599}
600#undef FUNC_NAME
601
602SCM_DEFINE (scm_vm_fetch_stack, "vm-fetch-stack", 1, 0, 0,
603 (SCM vm),
604 "")
605#define FUNC_NAME s_scm_vm_fetch_stack
a98cef7e 606{
3616e9e9
KN
607 SCM *sp;
608 SCM ls = SCM_EOL;
609 struct scm_vm *vp;
a98cef7e
KN
610
611 SCM_VALIDATE_VM (1, vm);
17e90c5e 612 VM_CHECK_RUNNING (vm);
a98cef7e 613
3616e9e9 614 vp = SCM_VM_DATA (vm);
af988bbf 615 for (sp = vp->stack_base; sp <= vp->sp; sp++)
3616e9e9
KN
616 ls = scm_cons (*sp, ls);
617 return ls;
a98cef7e
KN
618}
619#undef FUNC_NAME
620
621\f
622/*
17e90c5e 623 * Initialize
a98cef7e
KN
624 */
625
07e56b27
AW
626SCM scm_load_compiled_with_vm (SCM file)
627{
628 SCM program = scm_objcode_to_program (scm_load_objcode (file));
629
630 return vm_run (the_vm, program, SCM_EOL);
631}
632
17e90c5e 633void
07e56b27 634scm_bootstrap_vm (void)
17e90c5e 635{
07e56b27
AW
636 static int strappage = 0;
637
638 if (strappage)
639 return;
640
641 scm_bootstrap_frames ();
642 scm_bootstrap_instructions ();
643 scm_bootstrap_objcodes ();
644 scm_bootstrap_programs ();
a98cef7e 645
17e90c5e
KN
646 scm_tc16_vm_cont = scm_make_smob_type ("vm-cont", 0);
647 scm_set_smob_mark (scm_tc16_vm_cont, vm_cont_mark);
648 scm_set_smob_free (scm_tc16_vm_cont, vm_cont_free);
a98cef7e 649
17e90c5e
KN
650 scm_tc16_vm = scm_make_smob_type ("vm", 0);
651 scm_set_smob_mark (scm_tc16_vm, vm_mark);
652 scm_set_smob_free (scm_tc16_vm, vm_free);
653 scm_set_smob_apply (scm_tc16_vm, scm_vm_apply, 1, 0, 1);
a98cef7e 654
499a4c07
KN
655 the_vm = scm_permanent_object (make_vm ());
656
07e56b27
AW
657 /* a bit heavy-handed, this */
658 scm_variable_set_x (scm_c_lookup ("load-compiled"),
659 scm_c_make_gsubr ("load-compiled/vm", 1, 0, 0,
660 scm_load_compiled_with_vm));
661
662 strappage = 1;
663}
664
665void
666scm_init_vm (void)
667{
668 scm_bootstrap_vm ();
669
17e90c5e 670#ifndef SCM_MAGIC_SNARFER
a98cef7e 671#include "vm.x"
17e90c5e 672#endif
a98cef7e 673}
17e90c5e
KN
674
675/*
676 Local Variables:
677 c-file-style: "gnu"
678 End:
679*/