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