* ports.c (scm_char_ready_p): bug fix: in SCM_PROC char-ready's
[bpt/guile.git] / libguile / stacks.c
CommitLineData
782d171c
MD
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"
66f45472 51#include "struct.h"
782d171c
MD
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 *
7115d1e4
MD
84 * The stack is represented as a struct with an id slot and a tail
85 * array of scm_info_frame structs.
782d171c
MD
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
7115d1e4
MD
94 * Selectors
95 * stack-id
782d171c
MD
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?
7115d1e4 114 * frame-overflow? */
782d171c
MD
115
116\f
117
118/* Some auxiliary functions for reading debug frames off the stack.
119 */
120
c0ab1b8d
JB
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
782d171c
MD
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 */
66f45472 145static int stack_depth SCM_P ((scm_debug_frame *dframe, long offset, SCM *id, int *maxp));
782d171c 146static int
66f45472 147stack_depth (dframe, offset, id, maxp)
782d171c
MD
148 scm_debug_frame *dframe;
149 long offset;
66f45472 150 SCM *id;
782d171c
MD
151 int *maxp;
152{
153 int n, size;
154 int max_depth = SCM_BACKTRACE_MAXDEPTH;
155 scm_debug_info *info;
156 for (n = 0;
66f45472 157 dframe && !SCM_VOIDFRAMEP (*dframe) && n < max_depth;
c0ab1b8d 158 dframe = RELOC_FRAME (dframe->prev, offset))
782d171c
MD
159 {
160 if (SCM_EVALFRAMEP (*dframe))
161 {
162 size = dframe->status & SCM_MAX_FRAME_SIZE;
c0ab1b8d 163 info = RELOC_INFO (dframe->info, offset);
782d171c
MD
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 }
66f45472
MD
175 if (dframe && SCM_VOIDFRAMEP (*dframe))
176 *id = dframe->vect[0].id;
177 else if (dframe)
782d171c
MD
178 *maxp = 1;
179 return n;
180}
181
182/* Read debug info from DFRAME into IFRAME.
183 */
184static void read_frame SCM_P ((scm_debug_frame *dframe, long offset, scm_info_frame *iframe));
185static void
186read_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;
c0ab1b8d 197 info = RELOC_INFO (dframe->info, offset);
782d171c
MD
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 */
7115d1e4
MD
226
227#define NEXT_FRAME(iframe, n, quit) \
228{ \
229 ++iframe; \
230 if (--n == 0) \
231 goto quit; \
232} \
233
234
235static void read_frames SCM_P ((scm_debug_frame *dframe, long offset, int nframes, scm_info_frame *iframes));
782d171c 236static void
7115d1e4 237read_frames (dframe, offset, n, iframes)
782d171c
MD
238 scm_debug_frame *dframe;
239 long offset;
782d171c
MD
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 (;
66f45472 248 dframe && !SCM_VOIDFRAMEP (*dframe) && n > 0;
c0ab1b8d 249 dframe = RELOC_FRAME (dframe->prev, offset))
782d171c
MD
250 {
251 read_frame (dframe, offset, iframe);
252 if (SCM_EVALFRAMEP (*dframe))
253 {
254 size = dframe->status & SCM_MAX_FRAME_SIZE;
c0ab1b8d 255 info = RELOC_INFO (dframe->info, offset);
782d171c
MD
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 {
7115d1e4 263 NEXT_FRAME (iframe, n, quit);
782d171c
MD
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;
7115d1e4 271 NEXT_FRAME (iframe, n, quit);
782d171c
MD
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;
7115d1e4 285 NEXT_FRAME (iframe, n, quit);
782d171c
MD
286 }
287 }
288 else
289 {
7115d1e4 290 NEXT_FRAME (iframe, n, quit);
782d171c
MD
291 }
292 quit:
293 if (iframe > iframes)
294 (iframe - 1) -> flags |= SCM_FRAMEF_REAL;
295 }
296}
297
7115d1e4
MD
298static void narrow_stack SCM_P ((SCM stack, int inner, SCM inner_key, int outer, SCM outer_key));
299
300static void
301narrow_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
782d171c
MD
327\f
328
329/* Stacks
330 */
331
66f45472
MD
332SCM scm_stack_type;
333
334SCM_PROC (s_stack_p, "stack?", 1, 0, 0, scm_stack_p);
335SCM
336scm_stack_p (obj)
337 SCM obj;
338{
339 return SCM_NIMP (obj) && SCM_STACKP (obj) ? SCM_BOOL_T : SCM_BOOL_F;
340}
341
f6f88e0d 342SCM_PROC (s_make_stack, "make-stack", 0, 0, 1, scm_make_stack);
782d171c 343SCM
f6f88e0d
MD
344scm_make_stack (args)
345 SCM args;
782d171c 346{
7115d1e4 347 int n, maxp, size;
782d171c
MD
348 scm_debug_frame *dframe;
349 scm_info_frame *iframe;
350 long offset = 0;
66f45472 351 SCM stack, id;
f6f88e0d 352 SCM obj, inner_cut, outer_cut;
782d171c 353
f6f88e0d
MD
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. */
7115d1e4 360 if (obj == SCM_BOOL_T)
782d171c
MD
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
c0ab1b8d 374 dframe = RELOC_FRAME (SCM_DFRAME (obj), offset);
782d171c 375 }
3323ad08
JB
376 else
377 {
378 scm_wta (obj, (char *) SCM_ARG1, s_make_stack);
379 abort ();
380 }
782d171c
MD
381 }
382
f6f88e0d
MD
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). */
66f45472
MD
386 id = SCM_BOOL_F;
387 maxp = 0;
7115d1e4 388 n = stack_depth (dframe, offset, &id, &maxp);
782d171c
MD
389 size = n * SCM_FRAME_N_SLOTS;
390
f6f88e0d 391 /* Make the stack object. */
66f45472
MD
392 stack = scm_make_struct (scm_stack_type, SCM_MAKINUM (size), SCM_EOL);
393 SCM_STACK (stack) -> id = id;
7115d1e4
MD
394 SCM_STACK (stack) -> length = n;
395 iframe = &SCM_STACK (stack) -> tail[0];
396 SCM_STACK (stack) -> frames = iframe;
7115d1e4 397
f6f88e0d 398 /* Translate the current chain of stack frames into debugging information. */
c0ab1b8d 399 read_frames (RELOC_FRAME (dframe, offset), offset, n, iframe);
7115d1e4 400
f6f88e0d
MD
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
7115d1e4 423 if (n > 0)
f6f88e0d
MD
424 {
425 if (maxp)
426 iframe[n - 1].flags |= SCM_FRAMEF_OVERFLOW;
427 return stack;
428 }
7115d1e4
MD
429 else
430 return SCM_BOOL_F;
782d171c
MD
431}
432
66f45472
MD
433SCM_PROC (s_stack_id, "stack-id", 1, 0, 0, scm_stack_id);
434SCM
435scm_stack_id (stack)
436 SCM stack;
437{
7115d1e4
MD
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
c0ab1b8d 454 dframe = RELOC_FRAME (SCM_DFRAME (stack), offset);
7115d1e4
MD
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))
c0ab1b8d 461 dframe = RELOC_FRAME (dframe->prev, offset);
7115d1e4
MD
462 if (dframe && SCM_VOIDFRAMEP (*dframe))
463 return dframe->vect[0].id;
464 return SCM_BOOL_F;
66f45472
MD
465}
466
467SCM_PROC (s_stack_ref, "stack-ref", 2, 0, 0, scm_stack_ref);
782d171c
MD
468SCM
469scm_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
487SCM_PROC(s_stack_length, "stack-length", 1, 0, 0, scm_stack_length);
488SCM
489scm_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
66f45472
MD
503SCM_PROC (s_frame_p, "frame?", 1, 0, 0, scm_frame_p);
504SCM
505scm_frame_p (obj)
506 SCM obj;
507{
508 return SCM_NIMP (obj) && SCM_FRAMEP (obj);
509}
510
782d171c
MD
511SCM_PROC(s_last_stack_frame, "last-stack-frame", 1, 0, 0, scm_last_stack_frame);
512SCM
513scm_last_stack_frame (obj)
514 SCM obj;
515{
516 scm_debug_frame *dframe;
517 long offset = 0;
7115d1e4 518 SCM stack;
782d171c
MD
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
c0ab1b8d 530 dframe = RELOC_FRAME (SCM_DFRAME (obj), offset);
782d171c 531 }
3323ad08
JB
532 else
533 {
534 scm_wta (obj, (char *) SCM_ARG1, s_last_stack_frame);
535 abort ();
536 }
782d171c 537
66f45472 538 if (!dframe || SCM_VOIDFRAMEP (*dframe))
782d171c
MD
539 return SCM_BOOL_F;
540
c0ab1b8d
JB
541 stack = scm_make_struct (scm_stack_type, SCM_MAKINUM (SCM_FRAME_N_SLOTS),
542 SCM_EOL);
7115d1e4
MD
543 SCM_STACK (stack) -> length = 1;
544 SCM_STACK (stack) -> frames = &SCM_STACK (stack) -> tail[0];
c0ab1b8d
JB
545 read_frame (dframe, offset,
546 (scm_info_frame *) &SCM_STACK (stack) -> frames[0]);
782d171c 547
7115d1e4 548 return scm_cons (stack, SCM_INUM0);;
782d171c
MD
549}
550
551SCM_PROC(s_frame_number, "frame-number", 1, 0, 0, scm_frame_number);
552SCM
553scm_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
563SCM_PROC(s_frame_source, "frame-source", 1, 0, 0, scm_frame_source);
564SCM
565scm_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
575SCM_PROC(s_frame_procedure, "frame-procedure", 1, 0, 0, scm_frame_procedure);
576SCM
577scm_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
589SCM_PROC(s_frame_arguments, "frame-arguments", 1, 0, 0, scm_frame_arguments);
590SCM
591scm_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
601SCM_PROC(s_frame_previous, "frame-previous", 1, 0, 0, scm_frame_previous);
602SCM
603scm_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
618SCM_PROC(s_frame_next, "frame-next", 1, 0, 0, scm_frame_next);
619SCM
620scm_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
635SCM_PROC(s_frame_real_p, "frame-real?", 1, 0, 0, scm_frame_real_p);
636SCM
637scm_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
647SCM_PROC(s_frame_procedure_p, "frame-procedure?", 1, 0, 0, scm_frame_procedure_p);
648SCM
649scm_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
659SCM_PROC(s_frame_evaluating_args_p, "frame-evaluating-args?", 1, 0, 0, scm_frame_evaluating_args_p);
660SCM
661scm_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
671SCM_PROC(s_frame_overflow_p, "frame-overflow?", 1, 0, 0, scm_frame_overflow_p);
672SCM
673scm_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
685void
686scm_init_stacks ()
687{
66f45472
MD
688 SCM vtable;
689 SCM vtable_layout = scm_make_struct_layout (scm_nullstr);
c0ab1b8d
JB
690 SCM stack_layout
691 = scm_make_struct_layout (scm_makfrom0str (SCM_STACK_LAYOUT));
66f45472 692 vtable = scm_make_vtable_vtable (vtable_layout, SCM_INUM0, SCM_EOL);
c0ab1b8d
JB
693 scm_stack_type
694 = scm_permanent_object (scm_make_struct (vtable, SCM_INUM0,
695 scm_cons (stack_layout,
696 SCM_EOL)));
782d171c
MD
697#include "stacks.x"
698}