* ports.c (scm_char_ready_p): bug fix: in SCM_PROC char-ready's
[bpt/guile.git] / libguile / stacks.c
1 /* Representation of stack frame debug information
2 * Copyright (C) 1996 Mikael Djurfeldt
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this software; see the file COPYING. If not, write to
16 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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 *
42 * The author can be reached at djurfeldt@nada.kth.se
43 * Mikael Djurfeldt, SANS/NADA KTH, 10044 STOCKHOLM, SWEDEN
44 */
45 \f
46
47 #include <stdio.h>
48 #include "_scm.h"
49 #include "debug.h"
50 #include "continuations.h"
51 #include "struct.h"
52
53 #include "stacks.h"
54
55 \f
56 /* {Frames and stacks}
57 *
58 * The debugging evaluator creates debug frames on the stack. These
59 * are linked from the innermost frame and outwards. The last frame
60 * created can always be accessed as SCM_LAST_DEBUG_FRAME.
61 * Continuations contain a pointer to the innermost debug frame on the
62 * continuation stack.
63 *
64 * Each debug frame contains a set of flags and information about one
65 * or more stack frames. The case of multiple frames occurs due to
66 * tail recursion. The maximal number of stack frames which can be
67 * recorded in one debug frame can be set dynamically with the debug
68 * option FRAMES.
69 *
70 * Stack frame information is of two types: eval information (the
71 * expression being evaluated and its environment) and apply
72 * information (the procedure being applied and its arguments). A
73 * stack frame normally corresponds to an eval/apply pair, but macros
74 * and special forms (which are implemented as macros in Guile) only
75 * have eval information and apply calls leads to apply only frames.
76 *
77 * Since we want to record the total stack information and later
78 * manipulate this data at the scheme level in the debugger, we need
79 * to transform it into a new representation. In the following code
80 * section you'll find the functions implementing this data type.
81 *
82 * Representation:
83 *
84 * The stack is represented as a struct with an id slot and a tail
85 * array of scm_info_frame structs.
86 *
87 * A frame is represented as a pair where the car contains a stack and
88 * the cdr an inum. The inum is an index to the first SCM value of
89 * the scm_info_frame struct.
90 *
91 * Stacks
92 * Constructor
93 * make-stack
94 * Selectors
95 * stack-id
96 * stack-ref
97 * Inspector
98 * stack-length
99 *
100 * Frames
101 * Constructor
102 * last-stack-frame
103 * Selectors
104 * frame-number
105 * frame-source
106 * frame-procedure
107 * frame-arguments
108 * frame-previous
109 * frame-next
110 * Predicates
111 * frame-real?
112 * frame-procedure?
113 * frame-evaluating-args?
114 * frame-overflow? */
115
116 \f
117
118 /* Some auxiliary functions for reading debug frames off the stack.
119 */
120
121 /* Stacks often contain pointers to other items on the stack; for
122 example, each scm_debug_frame structure contains a pointer to the
123 next frame out. When we capture a continuation, we copy the stack
124 into the heap, and just leave all the pointers unchanged. This
125 makes it simple to restore the continuation --- just copy the stack
126 back! However, if we retrieve a pointer from the heap copy to
127 another item that was originally on the stack, we have to add an
128 offset to the pointer to discover the new referent.
129
130 If PTR is a pointer retrieved from a continuation, whose original
131 target was on the stack, and OFFSET is the appropriate offset from
132 the original stack to the continuation, then RELOC_MUMBLE (PTR,
133 OFFSET) is a pointer to the copy in the continuation of the
134 original referent, cast to an scm_debug_MUMBLE *. */
135 #define RELOC_INFO(ptr, offset) \
136 ((scm_debug_info *) ((SCM_STACKITEM *) (ptr) + (offset)))
137 #define RELOC_FRAME(ptr, offset) \
138 ((scm_debug_frame *) ((SCM_STACKITEM *) (ptr) + (offset)))
139
140
141 /* Count number of debug info frames on a stack, beginning with
142 * DFRAME. OFFSET is used for relocation of pointers when the stack
143 * is read from a continuation.
144 */
145 static int stack_depth SCM_P ((scm_debug_frame *dframe, long offset, SCM *id, int *maxp));
146 static int
147 stack_depth (dframe, offset, id, maxp)
148 scm_debug_frame *dframe;
149 long offset;
150 SCM *id;
151 int *maxp;
152 {
153 int n, size;
154 int max_depth = SCM_BACKTRACE_MAXDEPTH;
155 scm_debug_info *info;
156 for (n = 0;
157 dframe && !SCM_VOIDFRAMEP (*dframe) && n < max_depth;
158 dframe = RELOC_FRAME (dframe->prev, offset))
159 {
160 if (SCM_EVALFRAMEP (*dframe))
161 {
162 size = dframe->status & SCM_MAX_FRAME_SIZE;
163 info = RELOC_INFO (dframe->info, offset);
164 n += (info - dframe->vect) / 2 + 1;
165 /* Data in the apply part of an eval info frame comes from previous
166 stack frame if the scm_debug_info vector is overflowed. */
167 if ((((info - dframe->vect) & 1) == 0)
168 && SCM_OVERFLOWP (*dframe)
169 && !SCM_UNBNDP (info[1].a.proc))
170 ++n;
171 }
172 else
173 ++n;
174 }
175 if (dframe && SCM_VOIDFRAMEP (*dframe))
176 *id = dframe->vect[0].id;
177 else if (dframe)
178 *maxp = 1;
179 return n;
180 }
181
182 /* Read debug info from DFRAME into IFRAME.
183 */
184 static void read_frame SCM_P ((scm_debug_frame *dframe, long offset, scm_info_frame *iframe));
185 static void
186 read_frame (dframe, offset, iframe)
187 scm_debug_frame *dframe;
188 long offset;
189 scm_info_frame *iframe;
190 {
191 SCM flags = SCM_INUM0;
192 int size;
193 scm_debug_info *info;
194 if (SCM_EVALFRAMEP (*dframe))
195 {
196 size = dframe->status & SCM_MAX_FRAME_SIZE;
197 info = RELOC_INFO (dframe->info, offset);
198 if ((info - dframe->vect) & 1)
199 {
200 /* Debug.vect ends with apply info. */
201 --info;
202 if (info[1].a.proc != SCM_UNDEFINED)
203 {
204 flags |= SCM_FRAMEF_PROC;
205 iframe->proc = info[1].a.proc;
206 iframe->args = info[1].a.args;
207 if (!SCM_ARGS_READY_P (*dframe))
208 flags |= SCM_FRAMEF_EVAL_ARGS;
209 }
210 }
211 iframe->source = scm_make_memoized (info[0].e.exp, info[0].e.env);
212 }
213 else
214 {
215 flags |= SCM_FRAMEF_PROC;
216 iframe->proc = dframe->vect[0].a.proc;
217 iframe->args = dframe->vect[0].a.args;
218 }
219 iframe->flags = flags;
220 }
221
222 /* Fill the scm_info_frame vector IFRAME with data from N stack frames
223 * starting with the first stack frame represented by debug frame
224 * DFRAME.
225 */
226
227 #define NEXT_FRAME(iframe, n, quit) \
228 { \
229 ++iframe; \
230 if (--n == 0) \
231 goto quit; \
232 } \
233
234
235 static void read_frames SCM_P ((scm_debug_frame *dframe, long offset, int nframes, scm_info_frame *iframes));
236 static void
237 read_frames (dframe, offset, n, iframes)
238 scm_debug_frame *dframe;
239 long offset;
240 int n;
241 scm_info_frame *iframes;
242 {
243 int size;
244 scm_info_frame *iframe = iframes;
245 scm_debug_info *info;
246
247 for (;
248 dframe && !SCM_VOIDFRAMEP (*dframe) && n > 0;
249 dframe = RELOC_FRAME (dframe->prev, offset))
250 {
251 read_frame (dframe, offset, iframe);
252 if (SCM_EVALFRAMEP (*dframe))
253 {
254 size = dframe->status & SCM_MAX_FRAME_SIZE;
255 info = RELOC_INFO (dframe->info, offset);
256 if ((info - dframe->vect) & 1)
257 --info;
258 /* Data in the apply part of an eval info frame comes from
259 previous stack frame if the scm_debug_info vector is overflowed. */
260 else if (SCM_OVERFLOWP (*dframe)
261 && !SCM_UNBNDP (info[1].a.proc))
262 {
263 NEXT_FRAME (iframe, n, quit);
264 iframe->flags = SCM_INUM0 | SCM_FRAMEF_PROC;
265 iframe->proc = info[1].a.proc;
266 iframe->args = info[1].a.args;
267 }
268 if (SCM_OVERFLOWP (*dframe))
269 iframe->flags |= SCM_FRAMEF_OVERFLOW;
270 info -= 2;
271 NEXT_FRAME (iframe, n, quit);
272 while (info >= dframe->vect)
273 {
274 if (!SCM_UNBNDP (info[1].a.proc))
275 {
276 iframe->flags = SCM_INUM0 | SCM_FRAMEF_PROC;
277 iframe->proc = info[1].a.proc;
278 iframe->args = info[1].a.args;
279 }
280 else
281 iframe->flags = SCM_INUM0;
282 iframe->source = scm_make_memoized (info[0].e.exp,
283 info[0].e.env);
284 info -= 2;
285 NEXT_FRAME (iframe, n, quit);
286 }
287 }
288 else
289 {
290 NEXT_FRAME (iframe, n, quit);
291 }
292 quit:
293 if (iframe > iframes)
294 (iframe - 1) -> flags |= SCM_FRAMEF_REAL;
295 }
296 }
297
298 static void narrow_stack SCM_P ((SCM stack, int inner, SCM inner_key, int outer, SCM outer_key));
299
300 static void
301 narrow_stack (stack, inner, inner_key, outer, outer_key)
302 SCM stack;
303 int inner;
304 SCM inner_key;
305 int outer;
306 SCM outer_key;
307 {
308 scm_stack *s = SCM_STACK (stack);
309 int i;
310 int n = s->length;
311
312 /* Cut inner part. */
313 for (i = 0; inner; --inner)
314 if (s->frames[i++].proc == inner_key)
315 break;
316 s->frames = &s->frames[i];
317 n -= i;
318
319 /* Cut outer part. */
320 for (; n && outer; --outer)
321 if (s->frames[--n].proc == outer_key)
322 break;
323
324 s->length = n;
325 }
326
327 \f
328
329 /* Stacks
330 */
331
332 SCM scm_stack_type;
333
334 SCM_PROC (s_stack_p, "stack?", 1, 0, 0, scm_stack_p);
335 SCM
336 scm_stack_p (obj)
337 SCM obj;
338 {
339 return SCM_NIMP (obj) && SCM_STACKP (obj) ? SCM_BOOL_T : SCM_BOOL_F;
340 }
341
342 SCM_PROC (s_make_stack, "make-stack", 0, 0, 1, scm_make_stack);
343 SCM
344 scm_make_stack (args)
345 SCM args;
346 {
347 int n, maxp, size;
348 scm_debug_frame *dframe;
349 scm_info_frame *iframe;
350 long offset = 0;
351 SCM stack, id;
352 SCM obj, inner_cut, outer_cut;
353
354 SCM_ASSERT (SCM_NIMP (args) && SCM_CONSP (args), SCM_WNA, args, s_make_stack);
355 obj = SCM_CAR (args);
356 args = SCM_CDR (args);
357
358 /* Extract a pointer to the innermost frame of whatever object
359 scm_make_stack was given. */
360 if (obj == SCM_BOOL_T)
361 dframe = scm_last_debug_frame;
362 else
363 {
364 SCM_ASSERT (SCM_NIMP (obj), obj, SCM_ARG1, s_make_stack);
365 if (SCM_DEBUGOBJP (obj))
366 dframe = (scm_debug_frame *) SCM_DEBUGOBJ_FRAME (obj);
367 else if (scm_tc7_contin == SCM_TYP7 (obj))
368 {
369 offset = ((SCM_STACKITEM *) (SCM_CHARS (obj) + sizeof (scm_contregs))
370 - SCM_BASE (obj));
371 #ifndef STACK_GROWS_UP
372 offset += SCM_LENGTH (obj);
373 #endif
374 dframe = RELOC_FRAME (SCM_DFRAME (obj), offset);
375 }
376 else
377 {
378 scm_wta (obj, (char *) SCM_ARG1, s_make_stack);
379 abort ();
380 }
381 }
382
383 /* Count number of frames. Also get stack id tag and check whether
384 there are more stackframes than we want to record
385 (SCM_BACKTRACE_MAXDEPTH). */
386 id = SCM_BOOL_F;
387 maxp = 0;
388 n = stack_depth (dframe, offset, &id, &maxp);
389 size = n * SCM_FRAME_N_SLOTS;
390
391 /* Make the stack object. */
392 stack = scm_make_struct (scm_stack_type, SCM_MAKINUM (size), SCM_EOL);
393 SCM_STACK (stack) -> id = id;
394 SCM_STACK (stack) -> length = n;
395 iframe = &SCM_STACK (stack) -> tail[0];
396 SCM_STACK (stack) -> frames = iframe;
397
398 /* Translate the current chain of stack frames into debugging information. */
399 read_frames (RELOC_FRAME (dframe, offset), offset, n, iframe);
400
401 /* Narrow the stack according to the arguments given to scm_make_stack. */
402 while (n > 0 && SCM_NIMP (args) && SCM_CONSP (args))
403 {
404 inner_cut = SCM_CAR (args);
405 args = SCM_CDR (args);
406 if (SCM_NIMP (args) && SCM_CONSP (args))
407 {
408 outer_cut = SCM_CAR (args);
409 args = SCM_CDR (args);
410 }
411 else
412 outer_cut = SCM_INUM0;
413
414 narrow_stack (stack,
415 SCM_INUMP (inner_cut) ? SCM_INUM (inner_cut) : n,
416 SCM_INUMP (inner_cut) ? 0 : inner_cut,
417 SCM_INUMP (outer_cut) ? SCM_INUM (outer_cut) : n,
418 SCM_INUMP (outer_cut) ? 0 : outer_cut);
419
420 n = SCM_STACK (stack) -> length;
421 }
422
423 if (n > 0)
424 {
425 if (maxp)
426 iframe[n - 1].flags |= SCM_FRAMEF_OVERFLOW;
427 return stack;
428 }
429 else
430 return SCM_BOOL_F;
431 }
432
433 SCM_PROC (s_stack_id, "stack-id", 1, 0, 0, scm_stack_id);
434 SCM
435 scm_stack_id (stack)
436 SCM stack;
437 {
438 scm_debug_frame *dframe;
439 long offset = 0;
440 if (stack == SCM_BOOL_T)
441 dframe = scm_last_debug_frame;
442 else
443 {
444 SCM_ASSERT (SCM_NIMP (stack), stack, SCM_ARG1, s_make_stack);
445 if (SCM_DEBUGOBJP (stack))
446 dframe = (scm_debug_frame *) SCM_DEBUGOBJ_FRAME (stack);
447 else if (scm_tc7_contin == SCM_TYP7 (stack))
448 {
449 offset = ((SCM_STACKITEM *) (SCM_CHARS (stack) + sizeof (scm_contregs))
450 - SCM_BASE (stack));
451 #ifndef STACK_GROWS_UP
452 offset += SCM_LENGTH (stack);
453 #endif
454 dframe = RELOC_FRAME (SCM_DFRAME (stack), offset);
455 }
456 else if (SCM_STACKP (stack))
457 return SCM_STACK (stack) -> id;
458 else scm_wrong_type_arg (s_stack_id, SCM_ARG1, stack);
459 }
460 while (dframe && !SCM_VOIDFRAMEP (*dframe))
461 dframe = RELOC_FRAME (dframe->prev, offset);
462 if (dframe && SCM_VOIDFRAMEP (*dframe))
463 return dframe->vect[0].id;
464 return SCM_BOOL_F;
465 }
466
467 SCM_PROC (s_stack_ref, "stack-ref", 2, 0, 0, scm_stack_ref);
468 SCM
469 scm_stack_ref (stack, i)
470 SCM stack;
471 SCM i;
472 {
473 SCM_ASSERT (SCM_NIMP (stack)
474 && SCM_STACKP (stack),
475 stack,
476 SCM_ARG1,
477 s_stack_ref);
478 SCM_ASSERT (SCM_INUMP (i), i, SCM_ARG2, s_stack_ref);
479 SCM_ASSERT (SCM_INUM (i) >= 0
480 && SCM_INUM (i) < SCM_STACK_LENGTH (stack),
481 i,
482 SCM_OUTOFRANGE,
483 s_stack_ref);
484 return scm_cons (stack, i);
485 }
486
487 SCM_PROC(s_stack_length, "stack-length", 1, 0, 0, scm_stack_length);
488 SCM
489 scm_stack_length (stack)
490 SCM stack;
491 {
492 SCM_ASSERT (SCM_NIMP (stack)
493 && SCM_STACKP (stack),
494 stack,
495 SCM_ARG1,
496 s_stack_length);
497 return SCM_MAKINUM (SCM_STACK_LENGTH (stack));
498 }
499
500 /* Frames
501 */
502
503 SCM_PROC (s_frame_p, "frame?", 1, 0, 0, scm_frame_p);
504 SCM
505 scm_frame_p (obj)
506 SCM obj;
507 {
508 return SCM_NIMP (obj) && SCM_FRAMEP (obj);
509 }
510
511 SCM_PROC(s_last_stack_frame, "last-stack-frame", 1, 0, 0, scm_last_stack_frame);
512 SCM
513 scm_last_stack_frame (obj)
514 SCM obj;
515 {
516 scm_debug_frame *dframe;
517 long offset = 0;
518 SCM stack;
519
520 SCM_ASSERT (SCM_NIMP (obj), obj, SCM_ARG1, s_last_stack_frame);
521 if (SCM_DEBUGOBJP (obj))
522 dframe = (scm_debug_frame *) SCM_DEBUGOBJ_FRAME (obj);
523 else if (scm_tc7_contin == SCM_TYP7 (obj))
524 {
525 offset = ((SCM_STACKITEM *) (SCM_CHARS (obj) + sizeof (scm_contregs))
526 - SCM_BASE (obj));
527 #ifndef STACK_GROWS_UP
528 offset += SCM_LENGTH (obj);
529 #endif
530 dframe = RELOC_FRAME (SCM_DFRAME (obj), offset);
531 }
532 else
533 {
534 scm_wta (obj, (char *) SCM_ARG1, s_last_stack_frame);
535 abort ();
536 }
537
538 if (!dframe || SCM_VOIDFRAMEP (*dframe))
539 return SCM_BOOL_F;
540
541 stack = scm_make_struct (scm_stack_type, SCM_MAKINUM (SCM_FRAME_N_SLOTS),
542 SCM_EOL);
543 SCM_STACK (stack) -> length = 1;
544 SCM_STACK (stack) -> frames = &SCM_STACK (stack) -> tail[0];
545 read_frame (dframe, offset,
546 (scm_info_frame *) &SCM_STACK (stack) -> frames[0]);
547
548 return scm_cons (stack, SCM_INUM0);;
549 }
550
551 SCM_PROC(s_frame_number, "frame-number", 1, 0, 0, scm_frame_number);
552 SCM
553 scm_frame_number (frame)
554 SCM frame;
555 {
556 SCM_ASSERT (SCM_NIMP (frame) && SCM_FRAMEP (frame),
557 frame,
558 SCM_ARG1,
559 s_frame_number);
560 return SCM_MAKINUM (SCM_FRAME_NUMBER (frame));
561 }
562
563 SCM_PROC(s_frame_source, "frame-source", 1, 0, 0, scm_frame_source);
564 SCM
565 scm_frame_source (frame)
566 SCM frame;
567 {
568 SCM_ASSERT (SCM_NIMP (frame) && SCM_FRAMEP (frame),
569 frame,
570 SCM_ARG1,
571 s_frame_source);
572 return SCM_FRAME_SOURCE (frame);
573 }
574
575 SCM_PROC(s_frame_procedure, "frame-procedure", 1, 0, 0, scm_frame_procedure);
576 SCM
577 scm_frame_procedure (frame)
578 SCM frame;
579 {
580 SCM_ASSERT (SCM_NIMP (frame) && SCM_FRAMEP (frame),
581 frame,
582 SCM_ARG1,
583 s_frame_procedure);
584 return (SCM_FRAME_PROC_P (frame)
585 ? SCM_BOOL_F
586 : SCM_FRAME_PROC (frame));
587 }
588
589 SCM_PROC(s_frame_arguments, "frame-arguments", 1, 0, 0, scm_frame_arguments);
590 SCM
591 scm_frame_arguments (frame)
592 SCM frame;
593 {
594 SCM_ASSERT (SCM_NIMP (frame) && SCM_FRAMEP (frame),
595 frame,
596 SCM_ARG1,
597 s_frame_arguments);
598 return SCM_FRAME_ARGS (frame);
599 }
600
601 SCM_PROC(s_frame_previous, "frame-previous", 1, 0, 0, scm_frame_previous);
602 SCM
603 scm_frame_previous (frame)
604 SCM frame;
605 {
606 int n;
607 SCM_ASSERT (SCM_NIMP (frame) && SCM_FRAMEP (frame),
608 frame,
609 SCM_ARG1,
610 s_frame_previous);
611 n = SCM_INUM (SCM_CDR (frame)) + 1;
612 if (n >= SCM_STACK_LENGTH (SCM_CAR (frame)))
613 return SCM_BOOL_F;
614 else
615 return scm_cons (SCM_CAR (frame), SCM_MAKINUM (n));
616 }
617
618 SCM_PROC(s_frame_next, "frame-next", 1, 0, 0, scm_frame_next);
619 SCM
620 scm_frame_next (frame)
621 SCM frame;
622 {
623 int n;
624 SCM_ASSERT (SCM_NIMP (frame) && SCM_FRAMEP (frame),
625 frame,
626 SCM_ARG1,
627 s_frame_next);
628 n = SCM_INUM (SCM_CDR (frame)) - 1;
629 if (n < 0)
630 return SCM_BOOL_F;
631 else
632 return scm_cons (SCM_CAR (frame), SCM_MAKINUM (n));
633 }
634
635 SCM_PROC(s_frame_real_p, "frame-real?", 1, 0, 0, scm_frame_real_p);
636 SCM
637 scm_frame_real_p (frame)
638 SCM frame;
639 {
640 SCM_ASSERT (SCM_NIMP (frame) && SCM_FRAMEP (frame),
641 frame,
642 SCM_ARG1,
643 s_frame_real_p);
644 return SCM_FRAME_REAL_P (frame) ? SCM_BOOL_T : SCM_BOOL_F;
645 }
646
647 SCM_PROC(s_frame_procedure_p, "frame-procedure?", 1, 0, 0, scm_frame_procedure_p);
648 SCM
649 scm_frame_procedure_p (frame)
650 SCM frame;
651 {
652 SCM_ASSERT (SCM_NIMP (frame) && SCM_FRAMEP (frame),
653 frame,
654 SCM_ARG1,
655 s_frame_procedure_p);
656 return SCM_FRAME_PROC_P (frame) ? SCM_BOOL_T : SCM_BOOL_F;
657 }
658
659 SCM_PROC(s_frame_evaluating_args_p, "frame-evaluating-args?", 1, 0, 0, scm_frame_evaluating_args_p);
660 SCM
661 scm_frame_evaluating_args_p (frame)
662 SCM frame;
663 {
664 SCM_ASSERT (SCM_NIMP (frame) && SCM_FRAMEP (frame),
665 frame,
666 SCM_ARG1,
667 s_frame_evaluating_args_p);
668 return SCM_FRAME_EVAL_ARGS_P (frame) ? SCM_BOOL_T : SCM_BOOL_F;
669 }
670
671 SCM_PROC(s_frame_overflow_p, "frame-overflow?", 1, 0, 0, scm_frame_overflow_p);
672 SCM
673 scm_frame_overflow_p (frame)
674 SCM frame;
675 {
676 SCM_ASSERT (SCM_NIMP (frame) && SCM_FRAMEP (frame),
677 frame,
678 SCM_ARG1,
679 s_frame_overflow_p);
680 return SCM_FRAME_OVERFLOW_P (frame) ? SCM_BOOL_T : SCM_BOOL_F;
681 }
682
683 \f
684
685 void
686 scm_init_stacks ()
687 {
688 SCM vtable;
689 SCM vtable_layout = scm_make_struct_layout (scm_nullstr);
690 SCM stack_layout
691 = scm_make_struct_layout (scm_makfrom0str (SCM_STACK_LAYOUT));
692 vtable = scm_make_vtable_vtable (vtable_layout, SCM_INUM0, SCM_EOL);
693 scm_stack_type
694 = scm_permanent_object (scm_make_struct (vtable, SCM_INUM0,
695 scm_cons (stack_layout,
696 SCM_EOL)));
697 #include "stacks.x"
698 }