1996-10-14 03:26:51 +00:00
|
|
|
|
/* Representation of stack frame debug information
|
* backtrace.c, backtrace.h, debug.c, debug.h, eq.c,
gdb_interface.h, gdbint.c, gdbint.h, gh_data.c, gh_init.c,
gh_io.c, gh_list.c, gh_predicates.c, gh_test_c.c, gh_test_repl.c,
init.c, net_db.c, options.c, options.h, ports.c, print.c, read.c,
script.h, snarf.h, srcprop.c, srcprop.h, stacks.c, stacks.h,
throw.c: Update copyright years; these files have been worked on
significantly in 1997, but only had copyright years for 1996.
Also, change name of copyright holder on some from Mikael
Djurfeldt to Free Software Foundation; he has signed papers
assigning the changes to the FSF.
1997-05-16 09:14:28 +00:00
|
|
|
|
* Copyright (C) 1996 Free Software Foundation
|
1996-10-14 03:26:51 +00:00
|
|
|
|
*
|
|
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
|
|
|
|
* any later version.
|
|
|
|
|
|
*
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
|
*
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
|
* along with this software; see the file COPYING. If not, write to
|
1997-05-26 22:34:48 +00:00
|
|
|
|
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|
|
|
|
|
* Boston, MA 02111-1307 USA
|
1996-10-14 03:26:51 +00:00
|
|
|
|
*
|
|
|
|
|
|
* As a special exception, the Free Software Foundation gives permission
|
|
|
|
|
|
* for additional uses of the text contained in its release of GUILE.
|
|
|
|
|
|
*
|
|
|
|
|
|
* The exception is that, if you link the GUILE library with other files
|
|
|
|
|
|
* to produce an executable, this does not by itself cause the
|
|
|
|
|
|
* resulting executable to be covered by the GNU General Public License.
|
|
|
|
|
|
* Your use of that executable is in no way restricted on account of
|
|
|
|
|
|
* linking the GUILE library code into it.
|
|
|
|
|
|
*
|
|
|
|
|
|
* This exception does not however invalidate any other reasons why
|
|
|
|
|
|
* the executable file might be covered by the GNU General Public License.
|
|
|
|
|
|
*
|
|
|
|
|
|
* This exception applies only to the code released by the
|
|
|
|
|
|
* Free Software Foundation under the name GUILE. If you copy
|
|
|
|
|
|
* code from other Free Software Foundation releases into a copy of
|
|
|
|
|
|
* GUILE, as the General Public License permits, the exception does
|
|
|
|
|
|
* not apply to the code that you add in this way. To avoid misleading
|
|
|
|
|
|
* anyone as to the status of such modified files, you must delete
|
|
|
|
|
|
* this exception notice from them.
|
|
|
|
|
|
*
|
|
|
|
|
|
* If you write modifications of your own for GUILE, it is your choice
|
|
|
|
|
|
* whether to permit this exception to apply to your modifications.
|
|
|
|
|
|
* If you do not wish that, delete this exception notice.
|
|
|
|
|
|
*
|
|
|
|
|
|
* The author can be reached at djurfeldt@nada.kth.se
|
1997-05-26 22:34:48 +00:00
|
|
|
|
* Mikael Djurfeldt, SANS/NADA KTH, 10044 STOCKHOLM, SWEDEN */
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
#include "_scm.h"
|
|
|
|
|
|
#include "debug.h"
|
|
|
|
|
|
#include "continuations.h"
|
1996-10-14 20:27:14 +00:00
|
|
|
|
#include "struct.h"
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
|
|
|
|
|
#include "stacks.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* {Frames and stacks}
|
|
|
|
|
|
*
|
|
|
|
|
|
* The debugging evaluator creates debug frames on the stack. These
|
|
|
|
|
|
* are linked from the innermost frame and outwards. The last frame
|
|
|
|
|
|
* created can always be accessed as SCM_LAST_DEBUG_FRAME.
|
|
|
|
|
|
* Continuations contain a pointer to the innermost debug frame on the
|
|
|
|
|
|
* continuation stack.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Each debug frame contains a set of flags and information about one
|
|
|
|
|
|
* or more stack frames. The case of multiple frames occurs due to
|
|
|
|
|
|
* tail recursion. The maximal number of stack frames which can be
|
|
|
|
|
|
* recorded in one debug frame can be set dynamically with the debug
|
|
|
|
|
|
* option FRAMES.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Stack frame information is of two types: eval information (the
|
|
|
|
|
|
* expression being evaluated and its environment) and apply
|
|
|
|
|
|
* information (the procedure being applied and its arguments). A
|
|
|
|
|
|
* stack frame normally corresponds to an eval/apply pair, but macros
|
|
|
|
|
|
* and special forms (which are implemented as macros in Guile) only
|
|
|
|
|
|
* have eval information and apply calls leads to apply only frames.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Since we want to record the total stack information and later
|
|
|
|
|
|
* manipulate this data at the scheme level in the debugger, we need
|
|
|
|
|
|
* to transform it into a new representation. In the following code
|
|
|
|
|
|
* section you'll find the functions implementing this data type.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Representation:
|
|
|
|
|
|
*
|
1996-10-17 23:32:25 +00:00
|
|
|
|
* The stack is represented as a struct with an id slot and a tail
|
|
|
|
|
|
* array of scm_info_frame structs.
|
1996-10-14 03:26:51 +00:00
|
|
|
|
*
|
|
|
|
|
|
* A frame is represented as a pair where the car contains a stack and
|
|
|
|
|
|
* the cdr an inum. The inum is an index to the first SCM value of
|
|
|
|
|
|
* the scm_info_frame struct.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Stacks
|
|
|
|
|
|
* Constructor
|
|
|
|
|
|
* make-stack
|
1996-10-17 23:32:25 +00:00
|
|
|
|
* Selectors
|
|
|
|
|
|
* stack-id
|
1996-10-14 03:26:51 +00:00
|
|
|
|
* stack-ref
|
|
|
|
|
|
* Inspector
|
|
|
|
|
|
* stack-length
|
|
|
|
|
|
*
|
|
|
|
|
|
* Frames
|
|
|
|
|
|
* Constructor
|
|
|
|
|
|
* last-stack-frame
|
|
|
|
|
|
* Selectors
|
|
|
|
|
|
* frame-number
|
|
|
|
|
|
* frame-source
|
|
|
|
|
|
* frame-procedure
|
|
|
|
|
|
* frame-arguments
|
|
|
|
|
|
* frame-previous
|
|
|
|
|
|
* frame-next
|
|
|
|
|
|
* Predicates
|
|
|
|
|
|
* frame-real?
|
|
|
|
|
|
* frame-procedure?
|
|
|
|
|
|
* frame-evaluating-args?
|
1996-10-17 23:32:25 +00:00
|
|
|
|
* frame-overflow? */
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Some auxiliary functions for reading debug frames off the stack.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
Don't use GCC extensions to allocate space for debugging frames.
(Here he goes again! Why do we put up with this?!)
* debug.h (scm_debug_frame): Make the 'vect' member a pointer to
an scm_debug_info structure, not an in-line array of them. Add
'info' member, to say how many vect elements we've used, for eval
frames.
* eval.c (SCM_CEVAL): Use alloca to allocate space for vect. Use
a new variable debug_info_end to mark the end of vect, instead of
the address of the 'info' pointer itself.
[DEVAL] (ENTER_APPLY, SCM_CEVAL, SCM_APPLY): Remove casts of
&debug to scm_debug_frame *; debug is a real scm_debug_frame now.
(SCM_APPLY): Explicitly allocate space for debug.vect.
* debug.c (scm_m_start_stack): Same, for vframe.vect.
* stacks.c: Adjusted for new debug frame structure.
(RELOC_INFO, RELOC_FRAME): New macros.
(stack_depth, read_frames): Use them, and new scm_debug_frame
element 'info', instead of magically knowing that eval frames have
an info pointer sitting after vect.
(scm_make_stack, scm_stack_id, scm_last_stack_frame): Use
RELOC_FRAME.
(scm_init_stacks): Formatting tweaks.
1996-12-19 07:55:42 +00:00
|
|
|
|
/* Stacks often contain pointers to other items on the stack; for
|
|
|
|
|
|
example, each scm_debug_frame structure contains a pointer to the
|
|
|
|
|
|
next frame out. When we capture a continuation, we copy the stack
|
|
|
|
|
|
into the heap, and just leave all the pointers unchanged. This
|
|
|
|
|
|
makes it simple to restore the continuation --- just copy the stack
|
|
|
|
|
|
back! However, if we retrieve a pointer from the heap copy to
|
|
|
|
|
|
another item that was originally on the stack, we have to add an
|
|
|
|
|
|
offset to the pointer to discover the new referent.
|
|
|
|
|
|
|
|
|
|
|
|
If PTR is a pointer retrieved from a continuation, whose original
|
|
|
|
|
|
target was on the stack, and OFFSET is the appropriate offset from
|
|
|
|
|
|
the original stack to the continuation, then RELOC_MUMBLE (PTR,
|
|
|
|
|
|
OFFSET) is a pointer to the copy in the continuation of the
|
|
|
|
|
|
original referent, cast to an scm_debug_MUMBLE *. */
|
|
|
|
|
|
#define RELOC_INFO(ptr, offset) \
|
|
|
|
|
|
((scm_debug_info *) ((SCM_STACKITEM *) (ptr) + (offset)))
|
|
|
|
|
|
#define RELOC_FRAME(ptr, offset) \
|
|
|
|
|
|
((scm_debug_frame *) ((SCM_STACKITEM *) (ptr) + (offset)))
|
|
|
|
|
|
|
|
|
|
|
|
|
1996-10-14 03:26:51 +00:00
|
|
|
|
/* Count number of debug info frames on a stack, beginning with
|
|
|
|
|
|
* DFRAME. OFFSET is used for relocation of pointers when the stack
|
|
|
|
|
|
* is read from a continuation.
|
|
|
|
|
|
*/
|
1996-10-14 20:27:14 +00:00
|
|
|
|
static int stack_depth SCM_P ((scm_debug_frame *dframe, long offset, SCM *id, int *maxp));
|
1996-10-14 03:26:51 +00:00
|
|
|
|
static int
|
1996-10-14 20:27:14 +00:00
|
|
|
|
stack_depth (dframe, offset, id, maxp)
|
1996-10-14 03:26:51 +00:00
|
|
|
|
scm_debug_frame *dframe;
|
|
|
|
|
|
long offset;
|
1996-10-14 20:27:14 +00:00
|
|
|
|
SCM *id;
|
1996-10-14 03:26:51 +00:00
|
|
|
|
int *maxp;
|
|
|
|
|
|
{
|
|
|
|
|
|
int n, size;
|
|
|
|
|
|
int max_depth = SCM_BACKTRACE_MAXDEPTH;
|
|
|
|
|
|
scm_debug_info *info;
|
|
|
|
|
|
for (n = 0;
|
1996-10-14 20:27:14 +00:00
|
|
|
|
dframe && !SCM_VOIDFRAMEP (*dframe) && n < max_depth;
|
Don't use GCC extensions to allocate space for debugging frames.
(Here he goes again! Why do we put up with this?!)
* debug.h (scm_debug_frame): Make the 'vect' member a pointer to
an scm_debug_info structure, not an in-line array of them. Add
'info' member, to say how many vect elements we've used, for eval
frames.
* eval.c (SCM_CEVAL): Use alloca to allocate space for vect. Use
a new variable debug_info_end to mark the end of vect, instead of
the address of the 'info' pointer itself.
[DEVAL] (ENTER_APPLY, SCM_CEVAL, SCM_APPLY): Remove casts of
&debug to scm_debug_frame *; debug is a real scm_debug_frame now.
(SCM_APPLY): Explicitly allocate space for debug.vect.
* debug.c (scm_m_start_stack): Same, for vframe.vect.
* stacks.c: Adjusted for new debug frame structure.
(RELOC_INFO, RELOC_FRAME): New macros.
(stack_depth, read_frames): Use them, and new scm_debug_frame
element 'info', instead of magically knowing that eval frames have
an info pointer sitting after vect.
(scm_make_stack, scm_stack_id, scm_last_stack_frame): Use
RELOC_FRAME.
(scm_init_stacks): Formatting tweaks.
1996-12-19 07:55:42 +00:00
|
|
|
|
dframe = RELOC_FRAME (dframe->prev, offset))
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
|
|
|
|
|
if (SCM_EVALFRAMEP (*dframe))
|
|
|
|
|
|
{
|
|
|
|
|
|
size = dframe->status & SCM_MAX_FRAME_SIZE;
|
Don't use GCC extensions to allocate space for debugging frames.
(Here he goes again! Why do we put up with this?!)
* debug.h (scm_debug_frame): Make the 'vect' member a pointer to
an scm_debug_info structure, not an in-line array of them. Add
'info' member, to say how many vect elements we've used, for eval
frames.
* eval.c (SCM_CEVAL): Use alloca to allocate space for vect. Use
a new variable debug_info_end to mark the end of vect, instead of
the address of the 'info' pointer itself.
[DEVAL] (ENTER_APPLY, SCM_CEVAL, SCM_APPLY): Remove casts of
&debug to scm_debug_frame *; debug is a real scm_debug_frame now.
(SCM_APPLY): Explicitly allocate space for debug.vect.
* debug.c (scm_m_start_stack): Same, for vframe.vect.
* stacks.c: Adjusted for new debug frame structure.
(RELOC_INFO, RELOC_FRAME): New macros.
(stack_depth, read_frames): Use them, and new scm_debug_frame
element 'info', instead of magically knowing that eval frames have
an info pointer sitting after vect.
(scm_make_stack, scm_stack_id, scm_last_stack_frame): Use
RELOC_FRAME.
(scm_init_stacks): Formatting tweaks.
1996-12-19 07:55:42 +00:00
|
|
|
|
info = RELOC_INFO (dframe->info, offset);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
n += (info - dframe->vect) / 2 + 1;
|
|
|
|
|
|
/* Data in the apply part of an eval info frame comes from previous
|
|
|
|
|
|
stack frame if the scm_debug_info vector is overflowed. */
|
|
|
|
|
|
if ((((info - dframe->vect) & 1) == 0)
|
|
|
|
|
|
&& SCM_OVERFLOWP (*dframe)
|
|
|
|
|
|
&& !SCM_UNBNDP (info[1].a.proc))
|
|
|
|
|
|
++n;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
++n;
|
|
|
|
|
|
}
|
1996-10-14 20:27:14 +00:00
|
|
|
|
if (dframe && SCM_VOIDFRAMEP (*dframe))
|
|
|
|
|
|
*id = dframe->vect[0].id;
|
|
|
|
|
|
else if (dframe)
|
1996-10-14 03:26:51 +00:00
|
|
|
|
*maxp = 1;
|
|
|
|
|
|
return n;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Read debug info from DFRAME into IFRAME.
|
|
|
|
|
|
*/
|
|
|
|
|
|
static void read_frame SCM_P ((scm_debug_frame *dframe, long offset, scm_info_frame *iframe));
|
|
|
|
|
|
static void
|
|
|
|
|
|
read_frame (dframe, offset, iframe)
|
|
|
|
|
|
scm_debug_frame *dframe;
|
|
|
|
|
|
long offset;
|
|
|
|
|
|
scm_info_frame *iframe;
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM flags = SCM_INUM0;
|
|
|
|
|
|
int size;
|
|
|
|
|
|
scm_debug_info *info;
|
|
|
|
|
|
if (SCM_EVALFRAMEP (*dframe))
|
|
|
|
|
|
{
|
|
|
|
|
|
size = dframe->status & SCM_MAX_FRAME_SIZE;
|
Don't use GCC extensions to allocate space for debugging frames.
(Here he goes again! Why do we put up with this?!)
* debug.h (scm_debug_frame): Make the 'vect' member a pointer to
an scm_debug_info structure, not an in-line array of them. Add
'info' member, to say how many vect elements we've used, for eval
frames.
* eval.c (SCM_CEVAL): Use alloca to allocate space for vect. Use
a new variable debug_info_end to mark the end of vect, instead of
the address of the 'info' pointer itself.
[DEVAL] (ENTER_APPLY, SCM_CEVAL, SCM_APPLY): Remove casts of
&debug to scm_debug_frame *; debug is a real scm_debug_frame now.
(SCM_APPLY): Explicitly allocate space for debug.vect.
* debug.c (scm_m_start_stack): Same, for vframe.vect.
* stacks.c: Adjusted for new debug frame structure.
(RELOC_INFO, RELOC_FRAME): New macros.
(stack_depth, read_frames): Use them, and new scm_debug_frame
element 'info', instead of magically knowing that eval frames have
an info pointer sitting after vect.
(scm_make_stack, scm_stack_id, scm_last_stack_frame): Use
RELOC_FRAME.
(scm_init_stacks): Formatting tweaks.
1996-12-19 07:55:42 +00:00
|
|
|
|
info = RELOC_INFO (dframe->info, offset);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
if ((info - dframe->vect) & 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
/* Debug.vect ends with apply info. */
|
|
|
|
|
|
--info;
|
|
|
|
|
|
if (info[1].a.proc != SCM_UNDEFINED)
|
|
|
|
|
|
{
|
|
|
|
|
|
flags |= SCM_FRAMEF_PROC;
|
|
|
|
|
|
iframe->proc = info[1].a.proc;
|
|
|
|
|
|
iframe->args = info[1].a.args;
|
|
|
|
|
|
if (!SCM_ARGS_READY_P (*dframe))
|
|
|
|
|
|
flags |= SCM_FRAMEF_EVAL_ARGS;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
iframe->source = scm_make_memoized (info[0].e.exp, info[0].e.env);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
flags |= SCM_FRAMEF_PROC;
|
|
|
|
|
|
iframe->proc = dframe->vect[0].a.proc;
|
|
|
|
|
|
iframe->args = dframe->vect[0].a.args;
|
|
|
|
|
|
}
|
|
|
|
|
|
iframe->flags = flags;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Fill the scm_info_frame vector IFRAME with data from N stack frames
|
|
|
|
|
|
* starting with the first stack frame represented by debug frame
|
|
|
|
|
|
* DFRAME.
|
|
|
|
|
|
*/
|
1996-10-17 23:32:25 +00:00
|
|
|
|
|
|
|
|
|
|
#define NEXT_FRAME(iframe, n, quit) \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
++iframe; \
|
|
|
|
|
|
if (--n == 0) \
|
|
|
|
|
|
goto quit; \
|
|
|
|
|
|
} \
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void read_frames SCM_P ((scm_debug_frame *dframe, long offset, int nframes, scm_info_frame *iframes));
|
1996-10-14 03:26:51 +00:00
|
|
|
|
static void
|
1996-10-17 23:32:25 +00:00
|
|
|
|
read_frames (dframe, offset, n, iframes)
|
1996-10-14 03:26:51 +00:00
|
|
|
|
scm_debug_frame *dframe;
|
|
|
|
|
|
long offset;
|
|
|
|
|
|
int n;
|
|
|
|
|
|
scm_info_frame *iframes;
|
|
|
|
|
|
{
|
|
|
|
|
|
int size;
|
|
|
|
|
|
scm_info_frame *iframe = iframes;
|
|
|
|
|
|
scm_debug_info *info;
|
|
|
|
|
|
|
|
|
|
|
|
for (;
|
1996-10-14 20:27:14 +00:00
|
|
|
|
dframe && !SCM_VOIDFRAMEP (*dframe) && n > 0;
|
Don't use GCC extensions to allocate space for debugging frames.
(Here he goes again! Why do we put up with this?!)
* debug.h (scm_debug_frame): Make the 'vect' member a pointer to
an scm_debug_info structure, not an in-line array of them. Add
'info' member, to say how many vect elements we've used, for eval
frames.
* eval.c (SCM_CEVAL): Use alloca to allocate space for vect. Use
a new variable debug_info_end to mark the end of vect, instead of
the address of the 'info' pointer itself.
[DEVAL] (ENTER_APPLY, SCM_CEVAL, SCM_APPLY): Remove casts of
&debug to scm_debug_frame *; debug is a real scm_debug_frame now.
(SCM_APPLY): Explicitly allocate space for debug.vect.
* debug.c (scm_m_start_stack): Same, for vframe.vect.
* stacks.c: Adjusted for new debug frame structure.
(RELOC_INFO, RELOC_FRAME): New macros.
(stack_depth, read_frames): Use them, and new scm_debug_frame
element 'info', instead of magically knowing that eval frames have
an info pointer sitting after vect.
(scm_make_stack, scm_stack_id, scm_last_stack_frame): Use
RELOC_FRAME.
(scm_init_stacks): Formatting tweaks.
1996-12-19 07:55:42 +00:00
|
|
|
|
dframe = RELOC_FRAME (dframe->prev, offset))
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
|
|
|
|
|
read_frame (dframe, offset, iframe);
|
|
|
|
|
|
if (SCM_EVALFRAMEP (*dframe))
|
|
|
|
|
|
{
|
|
|
|
|
|
size = dframe->status & SCM_MAX_FRAME_SIZE;
|
Don't use GCC extensions to allocate space for debugging frames.
(Here he goes again! Why do we put up with this?!)
* debug.h (scm_debug_frame): Make the 'vect' member a pointer to
an scm_debug_info structure, not an in-line array of them. Add
'info' member, to say how many vect elements we've used, for eval
frames.
* eval.c (SCM_CEVAL): Use alloca to allocate space for vect. Use
a new variable debug_info_end to mark the end of vect, instead of
the address of the 'info' pointer itself.
[DEVAL] (ENTER_APPLY, SCM_CEVAL, SCM_APPLY): Remove casts of
&debug to scm_debug_frame *; debug is a real scm_debug_frame now.
(SCM_APPLY): Explicitly allocate space for debug.vect.
* debug.c (scm_m_start_stack): Same, for vframe.vect.
* stacks.c: Adjusted for new debug frame structure.
(RELOC_INFO, RELOC_FRAME): New macros.
(stack_depth, read_frames): Use them, and new scm_debug_frame
element 'info', instead of magically knowing that eval frames have
an info pointer sitting after vect.
(scm_make_stack, scm_stack_id, scm_last_stack_frame): Use
RELOC_FRAME.
(scm_init_stacks): Formatting tweaks.
1996-12-19 07:55:42 +00:00
|
|
|
|
info = RELOC_INFO (dframe->info, offset);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
if ((info - dframe->vect) & 1)
|
|
|
|
|
|
--info;
|
|
|
|
|
|
/* Data in the apply part of an eval info frame comes from
|
|
|
|
|
|
previous stack frame if the scm_debug_info vector is overflowed. */
|
|
|
|
|
|
else if (SCM_OVERFLOWP (*dframe)
|
|
|
|
|
|
&& !SCM_UNBNDP (info[1].a.proc))
|
|
|
|
|
|
{
|
1996-10-17 23:32:25 +00:00
|
|
|
|
NEXT_FRAME (iframe, n, quit);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
iframe->flags = SCM_INUM0 | SCM_FRAMEF_PROC;
|
|
|
|
|
|
iframe->proc = info[1].a.proc;
|
|
|
|
|
|
iframe->args = info[1].a.args;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (SCM_OVERFLOWP (*dframe))
|
|
|
|
|
|
iframe->flags |= SCM_FRAMEF_OVERFLOW;
|
|
|
|
|
|
info -= 2;
|
1996-10-17 23:32:25 +00:00
|
|
|
|
NEXT_FRAME (iframe, n, quit);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
while (info >= dframe->vect)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!SCM_UNBNDP (info[1].a.proc))
|
|
|
|
|
|
{
|
|
|
|
|
|
iframe->flags = SCM_INUM0 | SCM_FRAMEF_PROC;
|
|
|
|
|
|
iframe->proc = info[1].a.proc;
|
|
|
|
|
|
iframe->args = info[1].a.args;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
iframe->flags = SCM_INUM0;
|
|
|
|
|
|
iframe->source = scm_make_memoized (info[0].e.exp,
|
|
|
|
|
|
info[0].e.env);
|
|
|
|
|
|
info -= 2;
|
1996-10-17 23:32:25 +00:00
|
|
|
|
NEXT_FRAME (iframe, n, quit);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
1996-10-17 23:32:25 +00:00
|
|
|
|
NEXT_FRAME (iframe, n, quit);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
quit:
|
|
|
|
|
|
if (iframe > iframes)
|
|
|
|
|
|
(iframe - 1) -> flags |= SCM_FRAMEF_REAL;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
1996-10-17 23:32:25 +00:00
|
|
|
|
static void narrow_stack SCM_P ((SCM stack, int inner, SCM inner_key, int outer, SCM outer_key));
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
narrow_stack (stack, inner, inner_key, outer, outer_key)
|
|
|
|
|
|
SCM stack;
|
|
|
|
|
|
int inner;
|
|
|
|
|
|
SCM inner_key;
|
|
|
|
|
|
int outer;
|
|
|
|
|
|
SCM outer_key;
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_stack *s = SCM_STACK (stack);
|
|
|
|
|
|
int i;
|
|
|
|
|
|
int n = s->length;
|
|
|
|
|
|
|
|
|
|
|
|
/* Cut inner part. */
|
|
|
|
|
|
for (i = 0; inner; --inner)
|
|
|
|
|
|
if (s->frames[i++].proc == inner_key)
|
|
|
|
|
|
break;
|
|
|
|
|
|
s->frames = &s->frames[i];
|
|
|
|
|
|
n -= i;
|
|
|
|
|
|
|
|
|
|
|
|
/* Cut outer part. */
|
|
|
|
|
|
for (; n && outer; --outer)
|
|
|
|
|
|
if (s->frames[--n].proc == outer_key)
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
s->length = n;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Stacks
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
1996-10-14 20:27:14 +00:00
|
|
|
|
SCM scm_stack_type;
|
|
|
|
|
|
|
|
|
|
|
|
SCM_PROC (s_stack_p, "stack?", 1, 0, 0, scm_stack_p);
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_stack_p (obj)
|
|
|
|
|
|
SCM obj;
|
|
|
|
|
|
{
|
|
|
|
|
|
return SCM_NIMP (obj) && SCM_STACKP (obj) ? SCM_BOOL_T : SCM_BOOL_F;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
1996-11-02 20:54:19 +00:00
|
|
|
|
SCM_PROC (s_make_stack, "make-stack", 0, 0, 1, scm_make_stack);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
SCM
|
1996-11-02 20:54:19 +00:00
|
|
|
|
scm_make_stack (args)
|
|
|
|
|
|
SCM args;
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
1996-10-17 23:32:25 +00:00
|
|
|
|
int n, maxp, size;
|
1996-10-14 03:26:51 +00:00
|
|
|
|
scm_debug_frame *dframe;
|
|
|
|
|
|
scm_info_frame *iframe;
|
|
|
|
|
|
long offset = 0;
|
1996-10-14 20:27:14 +00:00
|
|
|
|
SCM stack, id;
|
1996-11-02 20:54:19 +00:00
|
|
|
|
SCM obj, inner_cut, outer_cut;
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
1996-11-02 20:54:19 +00:00
|
|
|
|
SCM_ASSERT (SCM_NIMP (args) && SCM_CONSP (args), SCM_WNA, args, s_make_stack);
|
|
|
|
|
|
obj = SCM_CAR (args);
|
|
|
|
|
|
args = SCM_CDR (args);
|
|
|
|
|
|
|
|
|
|
|
|
/* Extract a pointer to the innermost frame of whatever object
|
|
|
|
|
|
scm_make_stack was given. */
|
1996-10-17 23:32:25 +00:00
|
|
|
|
if (obj == SCM_BOOL_T)
|
1996-10-14 03:26:51 +00:00
|
|
|
|
dframe = scm_last_debug_frame;
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_ASSERT (SCM_NIMP (obj), obj, SCM_ARG1, s_make_stack);
|
|
|
|
|
|
if (SCM_DEBUGOBJP (obj))
|
|
|
|
|
|
dframe = (scm_debug_frame *) SCM_DEBUGOBJ_FRAME (obj);
|
|
|
|
|
|
else if (scm_tc7_contin == SCM_TYP7 (obj))
|
|
|
|
|
|
{
|
|
|
|
|
|
offset = ((SCM_STACKITEM *) (SCM_CHARS (obj) + sizeof (scm_contregs))
|
|
|
|
|
|
- SCM_BASE (obj));
|
|
|
|
|
|
#ifndef STACK_GROWS_UP
|
|
|
|
|
|
offset += SCM_LENGTH (obj);
|
|
|
|
|
|
#endif
|
Don't use GCC extensions to allocate space for debugging frames.
(Here he goes again! Why do we put up with this?!)
* debug.h (scm_debug_frame): Make the 'vect' member a pointer to
an scm_debug_info structure, not an in-line array of them. Add
'info' member, to say how many vect elements we've used, for eval
frames.
* eval.c (SCM_CEVAL): Use alloca to allocate space for vect. Use
a new variable debug_info_end to mark the end of vect, instead of
the address of the 'info' pointer itself.
[DEVAL] (ENTER_APPLY, SCM_CEVAL, SCM_APPLY): Remove casts of
&debug to scm_debug_frame *; debug is a real scm_debug_frame now.
(SCM_APPLY): Explicitly allocate space for debug.vect.
* debug.c (scm_m_start_stack): Same, for vframe.vect.
* stacks.c: Adjusted for new debug frame structure.
(RELOC_INFO, RELOC_FRAME): New macros.
(stack_depth, read_frames): Use them, and new scm_debug_frame
element 'info', instead of magically knowing that eval frames have
an info pointer sitting after vect.
(scm_make_stack, scm_stack_id, scm_last_stack_frame): Use
RELOC_FRAME.
(scm_init_stacks): Formatting tweaks.
1996-12-19 07:55:42 +00:00
|
|
|
|
dframe = RELOC_FRAME (SCM_DFRAME (obj), offset);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
Give GCC more control flow information, so it can be sure that
variables aren't used uninitialized.
* error.h (scm_error, scm_syserror, scm_syserror_msg,
scm_sysmissing, scm_num_overflow, scm_out_of_range,
scm_wrong_num_args, scm_wrong_type_arg, scm_memory_error,
scm_misc_error): Tell GCC that these functions never return.
* struct.c (scm_struct_ref, scm_struct_set_x): If we can't figure
out the field type, call abort if SCM_ASSERT returns, to placate
the optimizer.
* stacks.c (scm_make_stack, scm_last_stack_frame): abort if
scm_wta ever returns. We can't handle this case anyway, and this
gives the optimizer more information.
* unif.c (scm_uniform_vector_ref, scm_array_set_x): Abort if
scm_wta ever returns.
1996-12-18 21:39:44 +00:00
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_wta (obj, (char *) SCM_ARG1, s_make_stack);
|
|
|
|
|
|
abort ();
|
|
|
|
|
|
}
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
1996-11-02 20:54:19 +00:00
|
|
|
|
/* Count number of frames. Also get stack id tag and check whether
|
|
|
|
|
|
there are more stackframes than we want to record
|
|
|
|
|
|
(SCM_BACKTRACE_MAXDEPTH). */
|
1996-10-14 20:27:14 +00:00
|
|
|
|
id = SCM_BOOL_F;
|
|
|
|
|
|
maxp = 0;
|
1996-10-17 23:32:25 +00:00
|
|
|
|
n = stack_depth (dframe, offset, &id, &maxp);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
size = n * SCM_FRAME_N_SLOTS;
|
|
|
|
|
|
|
1996-11-02 20:54:19 +00:00
|
|
|
|
/* Make the stack object. */
|
1996-10-14 20:27:14 +00:00
|
|
|
|
stack = scm_make_struct (scm_stack_type, SCM_MAKINUM (size), SCM_EOL);
|
|
|
|
|
|
SCM_STACK (stack) -> id = id;
|
1996-10-17 23:32:25 +00:00
|
|
|
|
SCM_STACK (stack) -> length = n;
|
|
|
|
|
|
iframe = &SCM_STACK (stack) -> tail[0];
|
|
|
|
|
|
SCM_STACK (stack) -> frames = iframe;
|
|
|
|
|
|
|
1996-11-02 20:54:19 +00:00
|
|
|
|
/* Translate the current chain of stack frames into debugging information. */
|
Don't use GCC extensions to allocate space for debugging frames.
(Here he goes again! Why do we put up with this?!)
* debug.h (scm_debug_frame): Make the 'vect' member a pointer to
an scm_debug_info structure, not an in-line array of them. Add
'info' member, to say how many vect elements we've used, for eval
frames.
* eval.c (SCM_CEVAL): Use alloca to allocate space for vect. Use
a new variable debug_info_end to mark the end of vect, instead of
the address of the 'info' pointer itself.
[DEVAL] (ENTER_APPLY, SCM_CEVAL, SCM_APPLY): Remove casts of
&debug to scm_debug_frame *; debug is a real scm_debug_frame now.
(SCM_APPLY): Explicitly allocate space for debug.vect.
* debug.c (scm_m_start_stack): Same, for vframe.vect.
* stacks.c: Adjusted for new debug frame structure.
(RELOC_INFO, RELOC_FRAME): New macros.
(stack_depth, read_frames): Use them, and new scm_debug_frame
element 'info', instead of magically knowing that eval frames have
an info pointer sitting after vect.
(scm_make_stack, scm_stack_id, scm_last_stack_frame): Use
RELOC_FRAME.
(scm_init_stacks): Formatting tweaks.
1996-12-19 07:55:42 +00:00
|
|
|
|
read_frames (RELOC_FRAME (dframe, offset), offset, n, iframe);
|
1996-10-17 23:32:25 +00:00
|
|
|
|
|
1996-11-02 20:54:19 +00:00
|
|
|
|
/* Narrow the stack according to the arguments given to scm_make_stack. */
|
|
|
|
|
|
while (n > 0 && SCM_NIMP (args) && SCM_CONSP (args))
|
|
|
|
|
|
{
|
|
|
|
|
|
inner_cut = SCM_CAR (args);
|
|
|
|
|
|
args = SCM_CDR (args);
|
|
|
|
|
|
if (SCM_NIMP (args) && SCM_CONSP (args))
|
|
|
|
|
|
{
|
|
|
|
|
|
outer_cut = SCM_CAR (args);
|
|
|
|
|
|
args = SCM_CDR (args);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
outer_cut = SCM_INUM0;
|
|
|
|
|
|
|
|
|
|
|
|
narrow_stack (stack,
|
|
|
|
|
|
SCM_INUMP (inner_cut) ? SCM_INUM (inner_cut) : n,
|
|
|
|
|
|
SCM_INUMP (inner_cut) ? 0 : inner_cut,
|
|
|
|
|
|
SCM_INUMP (outer_cut) ? SCM_INUM (outer_cut) : n,
|
|
|
|
|
|
SCM_INUMP (outer_cut) ? 0 : outer_cut);
|
|
|
|
|
|
|
|
|
|
|
|
n = SCM_STACK (stack) -> length;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
1996-10-17 23:32:25 +00:00
|
|
|
|
if (n > 0)
|
1996-11-02 20:54:19 +00:00
|
|
|
|
{
|
|
|
|
|
|
if (maxp)
|
|
|
|
|
|
iframe[n - 1].flags |= SCM_FRAMEF_OVERFLOW;
|
|
|
|
|
|
return stack;
|
|
|
|
|
|
}
|
1996-10-17 23:32:25 +00:00
|
|
|
|
else
|
|
|
|
|
|
return SCM_BOOL_F;
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
1996-10-14 20:27:14 +00:00
|
|
|
|
SCM_PROC (s_stack_id, "stack-id", 1, 0, 0, scm_stack_id);
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_stack_id (stack)
|
|
|
|
|
|
SCM stack;
|
|
|
|
|
|
{
|
1996-10-17 23:32:25 +00:00
|
|
|
|
scm_debug_frame *dframe;
|
|
|
|
|
|
long offset = 0;
|
|
|
|
|
|
if (stack == SCM_BOOL_T)
|
|
|
|
|
|
dframe = scm_last_debug_frame;
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_ASSERT (SCM_NIMP (stack), stack, SCM_ARG1, s_make_stack);
|
|
|
|
|
|
if (SCM_DEBUGOBJP (stack))
|
|
|
|
|
|
dframe = (scm_debug_frame *) SCM_DEBUGOBJ_FRAME (stack);
|
|
|
|
|
|
else if (scm_tc7_contin == SCM_TYP7 (stack))
|
|
|
|
|
|
{
|
|
|
|
|
|
offset = ((SCM_STACKITEM *) (SCM_CHARS (stack) + sizeof (scm_contregs))
|
|
|
|
|
|
- SCM_BASE (stack));
|
|
|
|
|
|
#ifndef STACK_GROWS_UP
|
|
|
|
|
|
offset += SCM_LENGTH (stack);
|
|
|
|
|
|
#endif
|
Don't use GCC extensions to allocate space for debugging frames.
(Here he goes again! Why do we put up with this?!)
* debug.h (scm_debug_frame): Make the 'vect' member a pointer to
an scm_debug_info structure, not an in-line array of them. Add
'info' member, to say how many vect elements we've used, for eval
frames.
* eval.c (SCM_CEVAL): Use alloca to allocate space for vect. Use
a new variable debug_info_end to mark the end of vect, instead of
the address of the 'info' pointer itself.
[DEVAL] (ENTER_APPLY, SCM_CEVAL, SCM_APPLY): Remove casts of
&debug to scm_debug_frame *; debug is a real scm_debug_frame now.
(SCM_APPLY): Explicitly allocate space for debug.vect.
* debug.c (scm_m_start_stack): Same, for vframe.vect.
* stacks.c: Adjusted for new debug frame structure.
(RELOC_INFO, RELOC_FRAME): New macros.
(stack_depth, read_frames): Use them, and new scm_debug_frame
element 'info', instead of magically knowing that eval frames have
an info pointer sitting after vect.
(scm_make_stack, scm_stack_id, scm_last_stack_frame): Use
RELOC_FRAME.
(scm_init_stacks): Formatting tweaks.
1996-12-19 07:55:42 +00:00
|
|
|
|
dframe = RELOC_FRAME (SCM_DFRAME (stack), offset);
|
1996-10-17 23:32:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
else if (SCM_STACKP (stack))
|
|
|
|
|
|
return SCM_STACK (stack) -> id;
|
|
|
|
|
|
else scm_wrong_type_arg (s_stack_id, SCM_ARG1, stack);
|
|
|
|
|
|
}
|
|
|
|
|
|
while (dframe && !SCM_VOIDFRAMEP (*dframe))
|
Don't use GCC extensions to allocate space for debugging frames.
(Here he goes again! Why do we put up with this?!)
* debug.h (scm_debug_frame): Make the 'vect' member a pointer to
an scm_debug_info structure, not an in-line array of them. Add
'info' member, to say how many vect elements we've used, for eval
frames.
* eval.c (SCM_CEVAL): Use alloca to allocate space for vect. Use
a new variable debug_info_end to mark the end of vect, instead of
the address of the 'info' pointer itself.
[DEVAL] (ENTER_APPLY, SCM_CEVAL, SCM_APPLY): Remove casts of
&debug to scm_debug_frame *; debug is a real scm_debug_frame now.
(SCM_APPLY): Explicitly allocate space for debug.vect.
* debug.c (scm_m_start_stack): Same, for vframe.vect.
* stacks.c: Adjusted for new debug frame structure.
(RELOC_INFO, RELOC_FRAME): New macros.
(stack_depth, read_frames): Use them, and new scm_debug_frame
element 'info', instead of magically knowing that eval frames have
an info pointer sitting after vect.
(scm_make_stack, scm_stack_id, scm_last_stack_frame): Use
RELOC_FRAME.
(scm_init_stacks): Formatting tweaks.
1996-12-19 07:55:42 +00:00
|
|
|
|
dframe = RELOC_FRAME (dframe->prev, offset);
|
1996-10-17 23:32:25 +00:00
|
|
|
|
if (dframe && SCM_VOIDFRAMEP (*dframe))
|
|
|
|
|
|
return dframe->vect[0].id;
|
|
|
|
|
|
return SCM_BOOL_F;
|
1996-10-14 20:27:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM_PROC (s_stack_ref, "stack-ref", 2, 0, 0, scm_stack_ref);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
SCM
|
|
|
|
|
|
scm_stack_ref (stack, i)
|
|
|
|
|
|
SCM stack;
|
|
|
|
|
|
SCM i;
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_ASSERT (SCM_NIMP (stack)
|
|
|
|
|
|
&& SCM_STACKP (stack),
|
|
|
|
|
|
stack,
|
|
|
|
|
|
SCM_ARG1,
|
|
|
|
|
|
s_stack_ref);
|
|
|
|
|
|
SCM_ASSERT (SCM_INUMP (i), i, SCM_ARG2, s_stack_ref);
|
|
|
|
|
|
SCM_ASSERT (SCM_INUM (i) >= 0
|
|
|
|
|
|
&& SCM_INUM (i) < SCM_STACK_LENGTH (stack),
|
|
|
|
|
|
i,
|
|
|
|
|
|
SCM_OUTOFRANGE,
|
|
|
|
|
|
s_stack_ref);
|
|
|
|
|
|
return scm_cons (stack, i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM_PROC(s_stack_length, "stack-length", 1, 0, 0, scm_stack_length);
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_stack_length (stack)
|
|
|
|
|
|
SCM stack;
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_ASSERT (SCM_NIMP (stack)
|
|
|
|
|
|
&& SCM_STACKP (stack),
|
|
|
|
|
|
stack,
|
|
|
|
|
|
SCM_ARG1,
|
|
|
|
|
|
s_stack_length);
|
|
|
|
|
|
return SCM_MAKINUM (SCM_STACK_LENGTH (stack));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Frames
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
1996-10-14 20:27:14 +00:00
|
|
|
|
SCM_PROC (s_frame_p, "frame?", 1, 0, 0, scm_frame_p);
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_frame_p (obj)
|
|
|
|
|
|
SCM obj;
|
|
|
|
|
|
{
|
|
|
|
|
|
return SCM_NIMP (obj) && SCM_FRAMEP (obj);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
1996-10-14 03:26:51 +00:00
|
|
|
|
SCM_PROC(s_last_stack_frame, "last-stack-frame", 1, 0, 0, scm_last_stack_frame);
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_last_stack_frame (obj)
|
|
|
|
|
|
SCM obj;
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_debug_frame *dframe;
|
|
|
|
|
|
long offset = 0;
|
1996-10-17 23:32:25 +00:00
|
|
|
|
SCM stack;
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
|
|
|
|
|
SCM_ASSERT (SCM_NIMP (obj), obj, SCM_ARG1, s_last_stack_frame);
|
|
|
|
|
|
if (SCM_DEBUGOBJP (obj))
|
|
|
|
|
|
dframe = (scm_debug_frame *) SCM_DEBUGOBJ_FRAME (obj);
|
|
|
|
|
|
else if (scm_tc7_contin == SCM_TYP7 (obj))
|
|
|
|
|
|
{
|
|
|
|
|
|
offset = ((SCM_STACKITEM *) (SCM_CHARS (obj) + sizeof (scm_contregs))
|
|
|
|
|
|
- SCM_BASE (obj));
|
|
|
|
|
|
#ifndef STACK_GROWS_UP
|
|
|
|
|
|
offset += SCM_LENGTH (obj);
|
|
|
|
|
|
#endif
|
Don't use GCC extensions to allocate space for debugging frames.
(Here he goes again! Why do we put up with this?!)
* debug.h (scm_debug_frame): Make the 'vect' member a pointer to
an scm_debug_info structure, not an in-line array of them. Add
'info' member, to say how many vect elements we've used, for eval
frames.
* eval.c (SCM_CEVAL): Use alloca to allocate space for vect. Use
a new variable debug_info_end to mark the end of vect, instead of
the address of the 'info' pointer itself.
[DEVAL] (ENTER_APPLY, SCM_CEVAL, SCM_APPLY): Remove casts of
&debug to scm_debug_frame *; debug is a real scm_debug_frame now.
(SCM_APPLY): Explicitly allocate space for debug.vect.
* debug.c (scm_m_start_stack): Same, for vframe.vect.
* stacks.c: Adjusted for new debug frame structure.
(RELOC_INFO, RELOC_FRAME): New macros.
(stack_depth, read_frames): Use them, and new scm_debug_frame
element 'info', instead of magically knowing that eval frames have
an info pointer sitting after vect.
(scm_make_stack, scm_stack_id, scm_last_stack_frame): Use
RELOC_FRAME.
(scm_init_stacks): Formatting tweaks.
1996-12-19 07:55:42 +00:00
|
|
|
|
dframe = RELOC_FRAME (SCM_DFRAME (obj), offset);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
Give GCC more control flow information, so it can be sure that
variables aren't used uninitialized.
* error.h (scm_error, scm_syserror, scm_syserror_msg,
scm_sysmissing, scm_num_overflow, scm_out_of_range,
scm_wrong_num_args, scm_wrong_type_arg, scm_memory_error,
scm_misc_error): Tell GCC that these functions never return.
* struct.c (scm_struct_ref, scm_struct_set_x): If we can't figure
out the field type, call abort if SCM_ASSERT returns, to placate
the optimizer.
* stacks.c (scm_make_stack, scm_last_stack_frame): abort if
scm_wta ever returns. We can't handle this case anyway, and this
gives the optimizer more information.
* unif.c (scm_uniform_vector_ref, scm_array_set_x): Abort if
scm_wta ever returns.
1996-12-18 21:39:44 +00:00
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_wta (obj, (char *) SCM_ARG1, s_last_stack_frame);
|
|
|
|
|
|
abort ();
|
|
|
|
|
|
}
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
1996-10-14 20:27:14 +00:00
|
|
|
|
if (!dframe || SCM_VOIDFRAMEP (*dframe))
|
1996-10-14 03:26:51 +00:00
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
|
Don't use GCC extensions to allocate space for debugging frames.
(Here he goes again! Why do we put up with this?!)
* debug.h (scm_debug_frame): Make the 'vect' member a pointer to
an scm_debug_info structure, not an in-line array of them. Add
'info' member, to say how many vect elements we've used, for eval
frames.
* eval.c (SCM_CEVAL): Use alloca to allocate space for vect. Use
a new variable debug_info_end to mark the end of vect, instead of
the address of the 'info' pointer itself.
[DEVAL] (ENTER_APPLY, SCM_CEVAL, SCM_APPLY): Remove casts of
&debug to scm_debug_frame *; debug is a real scm_debug_frame now.
(SCM_APPLY): Explicitly allocate space for debug.vect.
* debug.c (scm_m_start_stack): Same, for vframe.vect.
* stacks.c: Adjusted for new debug frame structure.
(RELOC_INFO, RELOC_FRAME): New macros.
(stack_depth, read_frames): Use them, and new scm_debug_frame
element 'info', instead of magically knowing that eval frames have
an info pointer sitting after vect.
(scm_make_stack, scm_stack_id, scm_last_stack_frame): Use
RELOC_FRAME.
(scm_init_stacks): Formatting tweaks.
1996-12-19 07:55:42 +00:00
|
|
|
|
stack = scm_make_struct (scm_stack_type, SCM_MAKINUM (SCM_FRAME_N_SLOTS),
|
|
|
|
|
|
SCM_EOL);
|
1996-10-17 23:32:25 +00:00
|
|
|
|
SCM_STACK (stack) -> length = 1;
|
|
|
|
|
|
SCM_STACK (stack) -> frames = &SCM_STACK (stack) -> tail[0];
|
Don't use GCC extensions to allocate space for debugging frames.
(Here he goes again! Why do we put up with this?!)
* debug.h (scm_debug_frame): Make the 'vect' member a pointer to
an scm_debug_info structure, not an in-line array of them. Add
'info' member, to say how many vect elements we've used, for eval
frames.
* eval.c (SCM_CEVAL): Use alloca to allocate space for vect. Use
a new variable debug_info_end to mark the end of vect, instead of
the address of the 'info' pointer itself.
[DEVAL] (ENTER_APPLY, SCM_CEVAL, SCM_APPLY): Remove casts of
&debug to scm_debug_frame *; debug is a real scm_debug_frame now.
(SCM_APPLY): Explicitly allocate space for debug.vect.
* debug.c (scm_m_start_stack): Same, for vframe.vect.
* stacks.c: Adjusted for new debug frame structure.
(RELOC_INFO, RELOC_FRAME): New macros.
(stack_depth, read_frames): Use them, and new scm_debug_frame
element 'info', instead of magically knowing that eval frames have
an info pointer sitting after vect.
(scm_make_stack, scm_stack_id, scm_last_stack_frame): Use
RELOC_FRAME.
(scm_init_stacks): Formatting tweaks.
1996-12-19 07:55:42 +00:00
|
|
|
|
read_frame (dframe, offset,
|
|
|
|
|
|
(scm_info_frame *) &SCM_STACK (stack) -> frames[0]);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
1996-10-17 23:32:25 +00:00
|
|
|
|
return scm_cons (stack, SCM_INUM0);;
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM_PROC(s_frame_number, "frame-number", 1, 0, 0, scm_frame_number);
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_frame_number (frame)
|
|
|
|
|
|
SCM frame;
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_ASSERT (SCM_NIMP (frame) && SCM_FRAMEP (frame),
|
|
|
|
|
|
frame,
|
|
|
|
|
|
SCM_ARG1,
|
|
|
|
|
|
s_frame_number);
|
|
|
|
|
|
return SCM_MAKINUM (SCM_FRAME_NUMBER (frame));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM_PROC(s_frame_source, "frame-source", 1, 0, 0, scm_frame_source);
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_frame_source (frame)
|
|
|
|
|
|
SCM frame;
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_ASSERT (SCM_NIMP (frame) && SCM_FRAMEP (frame),
|
|
|
|
|
|
frame,
|
|
|
|
|
|
SCM_ARG1,
|
|
|
|
|
|
s_frame_source);
|
|
|
|
|
|
return SCM_FRAME_SOURCE (frame);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM_PROC(s_frame_procedure, "frame-procedure", 1, 0, 0, scm_frame_procedure);
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_frame_procedure (frame)
|
|
|
|
|
|
SCM frame;
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_ASSERT (SCM_NIMP (frame) && SCM_FRAMEP (frame),
|
|
|
|
|
|
frame,
|
|
|
|
|
|
SCM_ARG1,
|
|
|
|
|
|
s_frame_procedure);
|
|
|
|
|
|
return (SCM_FRAME_PROC_P (frame)
|
|
|
|
|
|
? SCM_BOOL_F
|
|
|
|
|
|
: SCM_FRAME_PROC (frame));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM_PROC(s_frame_arguments, "frame-arguments", 1, 0, 0, scm_frame_arguments);
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_frame_arguments (frame)
|
|
|
|
|
|
SCM frame;
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_ASSERT (SCM_NIMP (frame) && SCM_FRAMEP (frame),
|
|
|
|
|
|
frame,
|
|
|
|
|
|
SCM_ARG1,
|
|
|
|
|
|
s_frame_arguments);
|
|
|
|
|
|
return SCM_FRAME_ARGS (frame);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM_PROC(s_frame_previous, "frame-previous", 1, 0, 0, scm_frame_previous);
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_frame_previous (frame)
|
|
|
|
|
|
SCM frame;
|
|
|
|
|
|
{
|
|
|
|
|
|
int n;
|
|
|
|
|
|
SCM_ASSERT (SCM_NIMP (frame) && SCM_FRAMEP (frame),
|
|
|
|
|
|
frame,
|
|
|
|
|
|
SCM_ARG1,
|
|
|
|
|
|
s_frame_previous);
|
|
|
|
|
|
n = SCM_INUM (SCM_CDR (frame)) + 1;
|
|
|
|
|
|
if (n >= SCM_STACK_LENGTH (SCM_CAR (frame)))
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
else
|
|
|
|
|
|
return scm_cons (SCM_CAR (frame), SCM_MAKINUM (n));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM_PROC(s_frame_next, "frame-next", 1, 0, 0, scm_frame_next);
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_frame_next (frame)
|
|
|
|
|
|
SCM frame;
|
|
|
|
|
|
{
|
|
|
|
|
|
int n;
|
|
|
|
|
|
SCM_ASSERT (SCM_NIMP (frame) && SCM_FRAMEP (frame),
|
|
|
|
|
|
frame,
|
|
|
|
|
|
SCM_ARG1,
|
|
|
|
|
|
s_frame_next);
|
|
|
|
|
|
n = SCM_INUM (SCM_CDR (frame)) - 1;
|
|
|
|
|
|
if (n < 0)
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
else
|
|
|
|
|
|
return scm_cons (SCM_CAR (frame), SCM_MAKINUM (n));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM_PROC(s_frame_real_p, "frame-real?", 1, 0, 0, scm_frame_real_p);
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_frame_real_p (frame)
|
|
|
|
|
|
SCM frame;
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_ASSERT (SCM_NIMP (frame) && SCM_FRAMEP (frame),
|
|
|
|
|
|
frame,
|
|
|
|
|
|
SCM_ARG1,
|
|
|
|
|
|
s_frame_real_p);
|
|
|
|
|
|
return SCM_FRAME_REAL_P (frame) ? SCM_BOOL_T : SCM_BOOL_F;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM_PROC(s_frame_procedure_p, "frame-procedure?", 1, 0, 0, scm_frame_procedure_p);
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_frame_procedure_p (frame)
|
|
|
|
|
|
SCM frame;
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_ASSERT (SCM_NIMP (frame) && SCM_FRAMEP (frame),
|
|
|
|
|
|
frame,
|
|
|
|
|
|
SCM_ARG1,
|
|
|
|
|
|
s_frame_procedure_p);
|
|
|
|
|
|
return SCM_FRAME_PROC_P (frame) ? SCM_BOOL_T : SCM_BOOL_F;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM_PROC(s_frame_evaluating_args_p, "frame-evaluating-args?", 1, 0, 0, scm_frame_evaluating_args_p);
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_frame_evaluating_args_p (frame)
|
|
|
|
|
|
SCM frame;
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_ASSERT (SCM_NIMP (frame) && SCM_FRAMEP (frame),
|
|
|
|
|
|
frame,
|
|
|
|
|
|
SCM_ARG1,
|
|
|
|
|
|
s_frame_evaluating_args_p);
|
|
|
|
|
|
return SCM_FRAME_EVAL_ARGS_P (frame) ? SCM_BOOL_T : SCM_BOOL_F;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM_PROC(s_frame_overflow_p, "frame-overflow?", 1, 0, 0, scm_frame_overflow_p);
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_frame_overflow_p (frame)
|
|
|
|
|
|
SCM frame;
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_ASSERT (SCM_NIMP (frame) && SCM_FRAMEP (frame),
|
|
|
|
|
|
frame,
|
|
|
|
|
|
SCM_ARG1,
|
|
|
|
|
|
s_frame_overflow_p);
|
|
|
|
|
|
return SCM_FRAME_OVERFLOW_P (frame) ? SCM_BOOL_T : SCM_BOOL_F;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
scm_init_stacks ()
|
|
|
|
|
|
{
|
1996-10-14 20:27:14 +00:00
|
|
|
|
SCM vtable;
|
|
|
|
|
|
SCM vtable_layout = scm_make_struct_layout (scm_nullstr);
|
Don't use GCC extensions to allocate space for debugging frames.
(Here he goes again! Why do we put up with this?!)
* debug.h (scm_debug_frame): Make the 'vect' member a pointer to
an scm_debug_info structure, not an in-line array of them. Add
'info' member, to say how many vect elements we've used, for eval
frames.
* eval.c (SCM_CEVAL): Use alloca to allocate space for vect. Use
a new variable debug_info_end to mark the end of vect, instead of
the address of the 'info' pointer itself.
[DEVAL] (ENTER_APPLY, SCM_CEVAL, SCM_APPLY): Remove casts of
&debug to scm_debug_frame *; debug is a real scm_debug_frame now.
(SCM_APPLY): Explicitly allocate space for debug.vect.
* debug.c (scm_m_start_stack): Same, for vframe.vect.
* stacks.c: Adjusted for new debug frame structure.
(RELOC_INFO, RELOC_FRAME): New macros.
(stack_depth, read_frames): Use them, and new scm_debug_frame
element 'info', instead of magically knowing that eval frames have
an info pointer sitting after vect.
(scm_make_stack, scm_stack_id, scm_last_stack_frame): Use
RELOC_FRAME.
(scm_init_stacks): Formatting tweaks.
1996-12-19 07:55:42 +00:00
|
|
|
|
SCM stack_layout
|
|
|
|
|
|
= scm_make_struct_layout (scm_makfrom0str (SCM_STACK_LAYOUT));
|
1996-10-14 20:27:14 +00:00
|
|
|
|
vtable = scm_make_vtable_vtable (vtable_layout, SCM_INUM0, SCM_EOL);
|
Don't use GCC extensions to allocate space for debugging frames.
(Here he goes again! Why do we put up with this?!)
* debug.h (scm_debug_frame): Make the 'vect' member a pointer to
an scm_debug_info structure, not an in-line array of them. Add
'info' member, to say how many vect elements we've used, for eval
frames.
* eval.c (SCM_CEVAL): Use alloca to allocate space for vect. Use
a new variable debug_info_end to mark the end of vect, instead of
the address of the 'info' pointer itself.
[DEVAL] (ENTER_APPLY, SCM_CEVAL, SCM_APPLY): Remove casts of
&debug to scm_debug_frame *; debug is a real scm_debug_frame now.
(SCM_APPLY): Explicitly allocate space for debug.vect.
* debug.c (scm_m_start_stack): Same, for vframe.vect.
* stacks.c: Adjusted for new debug frame structure.
(RELOC_INFO, RELOC_FRAME): New macros.
(stack_depth, read_frames): Use them, and new scm_debug_frame
element 'info', instead of magically knowing that eval frames have
an info pointer sitting after vect.
(scm_make_stack, scm_stack_id, scm_last_stack_frame): Use
RELOC_FRAME.
(scm_init_stacks): Formatting tweaks.
1996-12-19 07:55:42 +00:00
|
|
|
|
scm_stack_type
|
|
|
|
|
|
= scm_permanent_object (scm_make_struct (vtable, SCM_INUM0,
|
|
|
|
|
|
scm_cons (stack_layout,
|
|
|
|
|
|
SCM_EOL)));
|
1996-10-14 03:26:51 +00:00
|
|
|
|
#include "stacks.x"
|
|
|
|
|
|
}
|