1996-10-14 03:26:51 +00:00
|
|
|
|
/* Representation of stack frame debug information
|
2006-04-17 00:05:42 +00:00
|
|
|
|
* Copyright (C) 1996,1997,2000,2001, 2006 Free Software Foundation
|
1996-10-14 03:26:51 +00:00
|
|
|
|
*
|
2003-04-05 19:15:35 +00:00
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
1996-10-14 03:26:51 +00:00
|
|
|
|
*
|
2003-04-05 19:15:35 +00:00
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
1996-10-14 03:26:51 +00:00
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2003-04-05 19:15:35 +00:00
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
|
* Lesser General Public License for more details.
|
1996-10-14 03:26:51 +00:00
|
|
|
|
*
|
2003-04-05 19:15:35 +00:00
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
|
* License along with this library; if not, write to the Free Software
|
2005-05-23 19:57:22 +00:00
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
2003-04-05 19:15:35 +00:00
|
|
|
|
*/
|
1999-12-12 02:36:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
2000-04-21 14:16:44 +00:00
|
|
|
|
#include "libguile/_scm.h"
|
|
|
|
|
|
#include "libguile/eval.h"
|
|
|
|
|
|
#include "libguile/debug.h"
|
|
|
|
|
|
#include "libguile/continuations.h"
|
|
|
|
|
|
#include "libguile/struct.h"
|
|
|
|
|
|
#include "libguile/macros.h"
|
|
|
|
|
|
#include "libguile/procprop.h"
|
|
|
|
|
|
#include "libguile/modules.h"
|
|
|
|
|
|
#include "libguile/root.h"
|
|
|
|
|
|
#include "libguile/strings.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "libguile/validate.h"
|
|
|
|
|
|
#include "libguile/stacks.h"
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* {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
|
2001-06-14 19:50:43 +00:00
|
|
|
|
* array of scm_t_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
|
2001-06-14 19:50:43 +00:00
|
|
|
|
* the scm_t_info_frame struct.
|
1996-10-14 03:26:51 +00:00
|
|
|
|
*
|
|
|
|
|
|
* 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
|
2001-06-14 19:50:43 +00:00
|
|
|
|
example, each scm_t_debug_frame structure contains a pointer to the
|
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
|
|
|
|
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) \
|
2001-06-14 19:50:43 +00:00
|
|
|
|
((scm_t_debug_info *) ((SCM_STACKITEM *) (ptr) + (offset)))
|
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
|
|
|
|
#define RELOC_FRAME(ptr, offset) \
|
2001-06-14 19:50:43 +00:00
|
|
|
|
((scm_t_debug_frame *) ((SCM_STACKITEM *) (ptr) + (offset)))
|
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
|
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
*/
|
2001-06-14 19:50:43 +00:00
|
|
|
|
static scm_t_bits
|
2004-12-23 15:30:29 +00:00
|
|
|
|
stack_depth (scm_t_debug_frame *dframe, scm_t_ptrdiff offset,
|
|
|
|
|
|
SCM *id, int *maxp)
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
2001-05-26 20:51:22 +00:00
|
|
|
|
long n;
|
|
|
|
|
|
long max_depth = SCM_BACKTRACE_MAXDEPTH;
|
1996-10-14 03:26:51 +00:00
|
|
|
|
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))
|
|
|
|
|
|
{
|
2004-12-23 15:30:29 +00:00
|
|
|
|
scm_t_debug_info *info = RELOC_INFO (dframe->info, offset);
|
|
|
|
|
|
scm_t_debug_info *vect = RELOC_INFO (dframe->vect, offset);
|
|
|
|
|
|
n += (info - vect) / 2 + 1;
|
1996-10-14 03:26:51 +00:00
|
|
|
|
/* Data in the apply part of an eval info frame comes from previous
|
2001-06-14 19:50:43 +00:00
|
|
|
|
stack frame if the scm_t_debug_info vector is overflowed. */
|
2004-12-23 15:30:29 +00:00
|
|
|
|
if ((((info - vect) & 1) == 0)
|
1996-10-14 03:26:51 +00:00
|
|
|
|
&& 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))
|
2004-12-23 15:30:29 +00:00
|
|
|
|
*id = RELOC_INFO(dframe->vect, offset)[0].id;
|
1996-10-14 20:27:14 +00:00
|
|
|
|
else if (dframe)
|
1996-10-14 03:26:51 +00:00
|
|
|
|
*maxp = 1;
|
|
|
|
|
|
return n;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Read debug info from DFRAME into IFRAME.
|
|
|
|
|
|
*/
|
|
|
|
|
|
static void
|
2004-12-23 15:30:29 +00:00
|
|
|
|
read_frame (scm_t_debug_frame *dframe, scm_t_ptrdiff offset,
|
|
|
|
|
|
scm_t_info_frame *iframe)
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
2001-06-14 19:50:43 +00:00
|
|
|
|
scm_t_bits flags = SCM_UNPACK (SCM_INUM0); /* UGh. */
|
1996-10-14 03:26:51 +00:00
|
|
|
|
if (SCM_EVALFRAMEP (*dframe))
|
|
|
|
|
|
{
|
2004-12-23 15:30:29 +00:00
|
|
|
|
scm_t_debug_info *info = RELOC_INFO (dframe->info, offset);
|
|
|
|
|
|
scm_t_debug_info *vect = RELOC_INFO (dframe->vect, offset);
|
|
|
|
|
|
if ((info - vect) & 1)
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
|
|
|
|
|
/* Debug.vect ends with apply info. */
|
|
|
|
|
|
--info;
|
2000-04-03 08:47:51 +00:00
|
|
|
|
if (!SCM_UNBNDP (info[1].a.proc))
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
1998-11-10 06:10:33 +00:00
|
|
|
|
iframe->source = scm_make_memoized (info[0].e.exp, info[0].e.env);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2004-12-23 15:30:29 +00:00
|
|
|
|
scm_t_debug_info *vect = RELOC_INFO (dframe->vect, offset);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
flags |= SCM_FRAMEF_PROC;
|
2004-12-23 15:30:29 +00:00
|
|
|
|
iframe->proc = vect[0].a.proc;
|
|
|
|
|
|
iframe->args = vect[0].a.args;
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
iframe->flags = flags;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
1998-11-10 07:57:51 +00:00
|
|
|
|
/* Look up the first body form of the apply closure. We'll use this
|
|
|
|
|
|
below to prevent it from being displayed.
|
|
|
|
|
|
*/
|
|
|
|
|
|
static SCM
|
|
|
|
|
|
get_applybody ()
|
|
|
|
|
|
{
|
2001-05-15 14:57:22 +00:00
|
|
|
|
SCM var = scm_sym2var (scm_sym_apply, SCM_BOOL_F, SCM_BOOL_F);
|
|
|
|
|
|
if (SCM_VARIABLEP (var) && SCM_CLOSUREP (SCM_VARIABLE_REF (var)))
|
2002-01-10 20:52:45 +00:00
|
|
|
|
return SCM_CAR (SCM_CLOSURE_BODY (SCM_VARIABLE_REF (var)));
|
1998-11-10 07:57:51 +00:00
|
|
|
|
else
|
|
|
|
|
|
return SCM_UNDEFINED;
|
|
|
|
|
|
}
|
1996-10-17 23:32:25 +00:00
|
|
|
|
|
|
|
|
|
|
#define NEXT_FRAME(iframe, n, quit) \
|
1999-12-16 03:46:42 +00:00
|
|
|
|
do { \
|
2001-06-25 11:06:33 +00:00
|
|
|
|
if (SCM_MEMOIZEDP (iframe->source) \
|
2004-07-27 15:41:49 +00:00
|
|
|
|
&& scm_is_eq (SCM_MEMOIZED_EXP (iframe->source), applybody)) \
|
1998-11-10 07:57:51 +00:00
|
|
|
|
{ \
|
|
|
|
|
|
iframe->source = SCM_BOOL_F; \
|
2004-07-06 10:59:25 +00:00
|
|
|
|
if (scm_is_false (iframe->proc)) \
|
1998-11-10 07:57:51 +00:00
|
|
|
|
{ \
|
|
|
|
|
|
--iframe; \
|
|
|
|
|
|
++n; \
|
|
|
|
|
|
} \
|
|
|
|
|
|
} \
|
1996-10-17 23:32:25 +00:00
|
|
|
|
++iframe; \
|
|
|
|
|
|
if (--n == 0) \
|
|
|
|
|
|
goto quit; \
|
1999-12-16 03:46:42 +00:00
|
|
|
|
} while (0)
|
1996-10-17 23:32:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
2001-06-14 19:50:43 +00:00
|
|
|
|
/* Fill the scm_t_info_frame vector IFRAME with data from N stack frames
|
1998-11-10 07:57:51 +00:00
|
|
|
|
* starting with the first stack frame represented by debug frame
|
|
|
|
|
|
* DFRAME.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2001-06-14 19:50:43 +00:00
|
|
|
|
static scm_t_bits
|
2004-12-23 15:30:29 +00:00
|
|
|
|
read_frames (scm_t_debug_frame *dframe, scm_t_ptrdiff offset,
|
|
|
|
|
|
long n, scm_t_info_frame *iframes)
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
2001-06-14 19:50:43 +00:00
|
|
|
|
scm_t_info_frame *iframe = iframes;
|
2004-12-23 15:30:29 +00:00
|
|
|
|
scm_t_debug_info *info, *vect;
|
1998-11-10 07:57:51 +00:00
|
|
|
|
static SCM applybody = SCM_UNDEFINED;
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
1998-11-10 07:57:51 +00:00
|
|
|
|
/* The value of applybody has to be setup after r4rs.scm has executed. */
|
|
|
|
|
|
if (SCM_UNBNDP (applybody))
|
|
|
|
|
|
applybody = get_applybody ();
|
1996-10-14 03:26:51 +00:00
|
|
|
|
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))
|
|
|
|
|
|
{
|
1998-11-10 06:10:33 +00:00
|
|
|
|
/* If current frame is a macro during expansion, we should
|
|
|
|
|
|
skip the previously recorded macro transformer
|
|
|
|
|
|
application frame. */
|
|
|
|
|
|
if (SCM_MACROEXPP (*dframe) && iframe > iframes)
|
1998-11-09 16:46:08 +00:00
|
|
|
|
{
|
|
|
|
|
|
*(iframe - 1) = *iframe;
|
|
|
|
|
|
--iframe;
|
|
|
|
|
|
}
|
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);
|
2004-12-23 15:30:29 +00:00
|
|
|
|
vect = RELOC_INFO (dframe->vect, offset);
|
|
|
|
|
|
if ((info - vect) & 1)
|
1996-10-14 03:26:51 +00:00
|
|
|
|
--info;
|
|
|
|
|
|
/* Data in the apply part of an eval info frame comes from
|
2001-06-25 11:06:33 +00:00
|
|
|
|
previous stack frame if the scm_t_debug_info vector is
|
|
|
|
|
|
overflowed. */
|
1996-10-14 03:26:51 +00:00
|
|
|
|
else if (SCM_OVERFLOWP (*dframe)
|
|
|
|
|
|
&& !SCM_UNBNDP (info[1].a.proc))
|
|
|
|
|
|
{
|
1996-10-17 23:32:25 +00:00
|
|
|
|
NEXT_FRAME (iframe, n, quit);
|
2000-03-12 18:30:33 +00:00
|
|
|
|
iframe->flags = SCM_UNPACK(SCM_INUM0) | SCM_FRAMEF_PROC;
|
1996-10-14 03:26:51 +00:00
|
|
|
|
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);
|
2004-12-23 15:30:29 +00:00
|
|
|
|
while (info >= vect)
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
|
|
|
|
|
if (!SCM_UNBNDP (info[1].a.proc))
|
|
|
|
|
|
{
|
2000-03-12 18:30:33 +00:00
|
|
|
|
iframe->flags = SCM_UNPACK(SCM_INUM0) | SCM_FRAMEF_PROC;
|
1996-10-14 03:26:51 +00:00
|
|
|
|
iframe->proc = info[1].a.proc;
|
|
|
|
|
|
iframe->args = info[1].a.args;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
2000-03-12 18:30:33 +00:00
|
|
|
|
iframe->flags = SCM_UNPACK (SCM_INUM0);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
}
|
2004-07-27 15:41:49 +00:00
|
|
|
|
else if (scm_is_eq (iframe->proc, scm_f_gsubr_apply))
|
1998-11-09 16:46:08 +00:00
|
|
|
|
/* Skip gsubr apply frames. */
|
|
|
|
|
|
continue;
|
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;
|
|
|
|
|
|
}
|
1998-11-09 16:46:08 +00:00
|
|
|
|
return iframe - iframes; /* Number of frames actually read */
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
1999-03-12 08:51:08 +00:00
|
|
|
|
/* Narrow STACK by cutting away stackframes (mutatingly).
|
|
|
|
|
|
*
|
|
|
|
|
|
* Inner frames (most recent) are cut by advancing the frames pointer.
|
|
|
|
|
|
* Outer frames are cut by decreasing the recorded length.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Cut maximally INNER inner frames and OUTER outer frames using
|
|
|
|
|
|
* the keys INNER_KEY and OUTER_KEY.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Frames are cut away starting at the end points and moving towards
|
|
|
|
|
|
* the center of the stack. The key is normally compared to the
|
|
|
|
|
|
* operator in application frames. Frames up to and including the key
|
|
|
|
|
|
* are cut.
|
|
|
|
|
|
*
|
|
|
|
|
|
* If INNER_KEY is #t a different scheme is used for inner frames:
|
|
|
|
|
|
*
|
|
|
|
|
|
* Frames up to but excluding the first source frame originating from
|
|
|
|
|
|
* a user module are cut, except for possible application frames
|
|
|
|
|
|
* between the user frame and the last system frame previously
|
|
|
|
|
|
* encountered.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
1996-10-17 23:32:25 +00:00
|
|
|
|
static void
|
2002-07-20 14:08:34 +00:00
|
|
|
|
narrow_stack (SCM stack, long inner, SCM inner_key, long outer, SCM outer_key)
|
1996-10-17 23:32:25 +00:00
|
|
|
|
{
|
2001-06-14 19:50:43 +00:00
|
|
|
|
scm_t_stack *s = SCM_STACK (stack);
|
2001-06-25 11:06:33 +00:00
|
|
|
|
unsigned long int i;
|
2001-05-26 20:51:22 +00:00
|
|
|
|
long n = s->length;
|
1996-10-17 23:32:25 +00:00
|
|
|
|
|
|
|
|
|
|
/* Cut inner part. */
|
2004-07-27 15:41:49 +00:00
|
|
|
|
if (scm_is_eq (inner_key, SCM_BOOL_T))
|
1999-03-12 08:51:08 +00:00
|
|
|
|
{
|
2001-06-25 11:06:33 +00:00
|
|
|
|
/* Cut all frames up to user module code */
|
1999-03-12 08:51:08 +00:00
|
|
|
|
for (i = 0; inner; ++i, --inner)
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM m = s->frames[i].source;
|
2001-06-25 11:06:33 +00:00
|
|
|
|
if (SCM_MEMOIZEDP (m)
|
|
|
|
|
|
&& !SCM_IMP (SCM_MEMOIZED_ENV (m))
|
2004-07-06 10:59:25 +00:00
|
|
|
|
&& scm_is_false (scm_system_module_env_p (SCM_MEMOIZED_ENV (m))))
|
1999-03-12 08:51:08 +00:00
|
|
|
|
{
|
|
|
|
|
|
/* Back up in order to include any non-source frames */
|
2001-06-25 11:06:33 +00:00
|
|
|
|
while (i > 0)
|
1999-03-12 08:51:08 +00:00
|
|
|
|
{
|
2001-06-25 11:06:33 +00:00
|
|
|
|
m = s->frames[i - 1].source;
|
|
|
|
|
|
if (SCM_MEMOIZEDP (m))
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
m = s->frames[i - 1].proc;
|
2004-07-06 10:59:25 +00:00
|
|
|
|
if (scm_is_true (scm_procedure_p (m))
|
|
|
|
|
|
&& scm_is_true (scm_procedure_property
|
2001-06-25 11:06:33 +00:00
|
|
|
|
(m, scm_sym_system_procedure)))
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
1999-03-12 08:51:08 +00:00
|
|
|
|
--i;
|
|
|
|
|
|
++inner;
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
/* Use standard cutting procedure. */
|
|
|
|
|
|
{
|
|
|
|
|
|
for (i = 0; inner; --inner)
|
2004-07-27 15:41:49 +00:00
|
|
|
|
if (scm_is_eq (s->frames[i++].proc, inner_key))
|
1999-03-12 08:51:08 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
1996-10-17 23:32:25 +00:00
|
|
|
|
s->frames = &s->frames[i];
|
|
|
|
|
|
n -= i;
|
|
|
|
|
|
|
|
|
|
|
|
/* Cut outer part. */
|
|
|
|
|
|
for (; n && outer; --outer)
|
2004-07-27 15:41:49 +00:00
|
|
|
|
if (scm_is_eq (s->frames[--n].proc, outer_key))
|
1996-10-17 23:32:25 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
s->length = n;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Stacks
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2001-12-16 21:57:52 +00:00
|
|
|
|
SCM scm_stack_type;
|
1996-10-14 20:27:14 +00:00
|
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
|
SCM_DEFINE (scm_stack_p, "stack?", 1, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
|
(SCM obj),
|
* alist.c, chars.c, debug.c, dynl.c, dynwind.c, error.c, eval.c,
evalext.c, filesys.c, gc.c, hash.c, hashtab.c, ioext.c,
keywords.c, list.c, load.c, macros.c, net_db.c, numbers.c,
objprop.c, ports.c, posix.c, print.c, procprop.c, procs.c,
ramap.c, regex-posix.c, root.c, scmsigs.c, simpos.c, socket.c,
stacks.c, stime.c, strings.c, strop.c, strports.c, struct.c,
symbols.c, throw.c, unif.c, vectors.c, version.c, vports.c,
weaks.c: Converted docstrings to ANSI C format.
2000-01-18 11:24:03 +00:00
|
|
|
|
"Return @code{#t} if @var{obj} is a calling stack.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_stack_p
|
1996-10-14 20:27:14 +00:00
|
|
|
|
{
|
2004-07-06 10:59:25 +00:00
|
|
|
|
return scm_from_bool(SCM_STACKP (obj));
|
1996-10-14 20:27:14 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-10-14 20:27:14 +00:00
|
|
|
|
|
2000-05-18 08:47:52 +00:00
|
|
|
|
SCM_DEFINE (scm_make_stack, "make-stack", 1, 0, 1,
|
|
|
|
|
|
(SCM obj, SCM args),
|
(scm_make_stack, scm_stack_ref, scm_stack_length, scm_frame_p,
scm_last_stack_frame, scm_frame_number, scm_frame_source,
scm_frame_procedure, scm_frame_arguments, scm_frame_previous,
scm_frame_next, scm_frame_real_p, scm_frame_procedure_p,
scm_frame_evaluating_args_p, scm_frame_overflow_p): Added docstrings.
2001-02-16 15:14:10 +00:00
|
|
|
|
"Create a new stack. If @var{obj} is @code{#t}, the current\n"
|
|
|
|
|
|
"evaluation stack is used for creating the stack frames,\n"
|
|
|
|
|
|
"otherwise the frames are taken from @var{obj} (which must be\n"
|
2001-08-02 20:26:21 +00:00
|
|
|
|
"either a debug object or a continuation).\n\n"
|
|
|
|
|
|
"@var{args} should be a list containing any combination of\n"
|
|
|
|
|
|
"integer, procedure and @code{#t} values.\n\n"
|
|
|
|
|
|
"These values specify various ways of cutting away uninteresting\n"
|
|
|
|
|
|
"stack frames from the top and bottom of the stack that\n"
|
|
|
|
|
|
"@code{make-stack} returns. They come in pairs like this:\n"
|
|
|
|
|
|
"@code{(@var{inner_cut_1} @var{outer_cut_1} @var{inner_cut_2}\n"
|
|
|
|
|
|
"@var{outer_cut_2} @dots{})}.\n\n"
|
|
|
|
|
|
"Each @var{inner_cut_N} can be @code{#t}, an integer, or a\n"
|
|
|
|
|
|
"procedure. @code{#t} means to cut away all frames up to but\n"
|
|
|
|
|
|
"excluding the first user module frame. An integer means to cut\n"
|
|
|
|
|
|
"away exactly that number of frames. A procedure means to cut\n"
|
|
|
|
|
|
"away all frames up to but excluding the application frame whose\n"
|
|
|
|
|
|
"procedure matches the specified one.\n\n"
|
|
|
|
|
|
"Each @var{outer_cut_N} can be an integer or a procedure. An\n"
|
|
|
|
|
|
"integer means to cut away that number of frames. A procedure\n"
|
|
|
|
|
|
"means to cut away frames down to but excluding the application\n"
|
|
|
|
|
|
"frame whose procedure matches the specified one.\n\n"
|
|
|
|
|
|
"If the @var{outer_cut_N} of the last pair is missing, it is\n"
|
|
|
|
|
|
"taken as 0.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_make_stack
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
2001-05-26 20:51:22 +00:00
|
|
|
|
long n, size;
|
* validate.h
(SCM_NUM2{SIZE,PTRDIFF,SHORT,USHORT,BITS,UBITS,INT,UINT}[_DEF]):
new macros.
* unif.h: type renaming:
scm_array -> scm_array_t
scm_array_dim -> scm_array_dim_t
the old names are deprecated, all in-Guile uses changed.
* tags.h (scm_ubits_t): new typedef, representing unsigned
scm_bits_t.
* stacks.h: type renaming:
scm_info_frame -> scm_info_frame_t
scm_stack -> scm_stack_t
the old names are deprecated, all in-Guile uses changed.
* srcprop.h: type renaming:
scm_srcprops -> scm_srcprops_t
scm_srcprops_chunk -> scm_srcprops_chunk_t
the old names are deprecated, all in-Guile uses changed.
* gsubr.c, procs.c, print.c, ports.c, read.c, rdelim.c, ramap.c,
rw.c, smob.c, sort.c, srcprop.c, stacks.c, strings.c, strop.c,
strorder.c, strports.c, struct.c, symbols.c, unif.c, values.c,
vectors.c, vports.c, weaks.c:
various int/size_t -> size_t/scm_bits_t changes.
* random.h: type renaming:
scm_rstate -> scm_rstate_t
scm_rng -> scm_rng_t
scm_i_rstate -> scm_i_rstate_t
the old names are deprecated, all in-Guile uses changed.
* procs.h: type renaming:
scm_subr_entry -> scm_subr_entry_t
the old name is deprecated, all in-Guile uses changed.
* options.h (scm_option_t.val): unsigned long -> scm_bits_t.
type renaming:
scm_option -> scm_option_t
the old name is deprecated, all in-Guile uses changed.
* objects.c: various long -> scm_bits_t changes.
(scm_i_make_class_object): flags: unsigned long -> scm_ubits_t
* numbers.h (SCM_FIXNUM_BIT): deprecated, renamed to
SCM_I_FIXNUM_BIT.
* num2integral.i.c: new file, multiply included by numbers.c, used
to "templatize" the various integral <-> num conversion routines.
* numbers.c (scm_mkbig, scm_big2num, scm_adjbig, scm_normbig,
scm_copybig, scm_2ulong2big, scm_dbl2big, scm_big2dbl):
deprecated.
(scm_i_mkbig, scm_i_big2inum, scm_i_adjbig, scm_i_normbig,
scm_i_copybig, scm_i_short2big, scm_i_ushort2big, scm_i_int2big,
scm_i_uint2big, scm_i_long2big, scm_i_ulong2big, scm_i_bits2big,
scm_i_ubits2big, scm_i_size2big, scm_i_ptrdiff2big,
scm_i_long_long2big, scm_i_ulong_long2big, scm_i_dbl2big,
scm_i_big2dbl, scm_short2num, scm_ushort2num, scm_int2num,
scm_uint2num, scm_bits2num, scm_ubits2num, scm_size2num,
scm_ptrdiff2num, scm_num2short, scm_num2ushort, scm_num2int,
scm_num2uint, scm_num2bits, scm_num2ubits, scm_num2ptrdiff,
scm_num2size): new functions.
* modules.c (scm_module_reverse_lookup): i, n: int -> scm_bits_t.x
* load.c: change int -> size_t in various places (where the
variable is used to store a string length).
(search-path): call scm_done_free, not scm_done_malloc.
* list.c (scm_ilength): return a scm_bits_t, not long.
some other {int,long} -> scm_bits_t changes.
* hashtab.c: various [u]int -> scm_bits_t changes.
scm_ihashx_closure -> scm_ihashx_closure_t (and made a typedef).
(scm_ihashx): n: uint -> scm_bits_t
use scm_bits2num instead of scm_ulong2num.
* gsubr.c: various int -> scm_bits_t changes.
* gh_data.c (gh_scm2double): no loss of precision any more.
* gh.h (gh_str2scm): len: int -> size_t
(gh_{get,set}_substr): start: int -> scm_bits_t,
len: int -> size_t
(gh_<num>2scm): n: int -> scm_bits_t
(gh_*vector_length): return scm_[u]size_t, not unsigned long.
(gh_length): return scm_bits_t, not unsigned long.
* fports.h: type renaming:
scm_fport -> scm_fport_t
the old name is deprecated, all in-Guile uses changed.
* fports.c (fport_fill_input): count: int -> scm_bits_t
(fport_flush): init_size, remaining, count: int -> scm_bits_t
* debug.h (scm_lookup_cstr, scm_lookup_soft, scm_evstr): removed
those prototypes, as the functions they prototype don't exist.
* fports.c (default_buffer_size): int -> size_t
(scm_fport_buffer_add): read_size, write_size: int -> scm_bits_t
default_size: int -> size_t
(scm_setvbuf): csize: int -> scm_bits_t
* fluids.c (n_fluids): int -> scm_bits_t
(grow_fluids): old_length, i: int -> scm_bits_t
(next_fluid_num, scm_fluid_ref, scm_fluid_set_x): n: int ->
scm_bits_t
(scm_c_with_fluids): flen, vlen: int -> scm_bits_t
* filesys.c (s_scm_open_fdes): changed calls to SCM_NUM2LONG to
the new and shiny SCM_NUM2INT.
* extensions.c: extension -> extension_t (and made a typedef).
* eval.h (SCM_IFRAME): cast to scm_bits_t, not int. just so
there are no nasty surprises if/when the various deeply magic tag
bits move somewhere else.
* eval.c: changed the locals used to store results of SCM_IFRAME,
scm_ilength and such to be of type scm_bits_t (and not int/long).
(iqq): depth, edepth: int -> scm_bits_t
(scm_eval_stack): int -> scm_bits_t
(SCM_CEVAL): various vars are not scm_bits_t instead of int.
(check_map_args, scm_map, scm_for_each): len: long -> scm_bits_t
i: int -> scm_bits_t
* environments.c: changed the many calls to scm_ulong2num to
scm_ubits2num.
(import_environment_fold): proc_as_ul: ulong -> scm_ubits_t
* dynwind.c (scm_dowinds): delta: long -> scm_bits_t
* debug.h: type renaming:
scm_debug_info -> scm_debug_info_t
scm_debug_frame -> scm_debug_frame_t
the old names are deprecated, all in-Guile uses changed.
(scm_debug_eframe_size): int -> scm_bits_t
* debug.c (scm_init_debug): use scm_c_define instead of the
deprecated scm_define.
* continuations.h: type renaming:
scm_contregs -> scm_contregs_t
the old name is deprecated, all in-Guile uses changed.
(scm_contregs_t.num_stack_items): size_t -> scm_bits_t
(scm_contregs_t.num_stack_items): ulong -> scm_ubits_t
* continuations.c (scm_make_continuation): change the type of
stack_size form long to scm_bits_t.
* ports.h: type renaming:
scm_port_rw_active -> scm_port_rw_active_t (and made a typedef)
scm_port -> scm_port_t
scm_ptob_descriptor -> scm_ptob_descriptor_t
the old names are deprecated, all in-Guile uses changed.
(scm_port_t.entry): int -> scm_bits_t.
(scm_port_t.line_number): int -> long.
(scm_port_t.putback_buf_size): int -> size_t.
* __scm.h (long_long, ulong_long): deprecated (they pollute the
global namespace and have little value besides that).
(SCM_BITS_LENGTH): new, is the bit size of scm_bits_t (i.e. of an
SCM handle).
(ifdef spaghetti): include sys/types.h and sys/stdtypes.h, if they
exist (for size_t & ptrdiff_t)
(scm_sizet): deprecated.
* Makefile.am (noinst_HEADERS): add num2integral.i.c
2001-05-24 00:50:51 +00:00
|
|
|
|
int maxp;
|
2001-06-25 11:06:33 +00:00
|
|
|
|
scm_t_debug_frame *dframe;
|
2001-06-14 19:50:43 +00:00
|
|
|
|
scm_t_info_frame *iframe;
|
2001-05-26 20:51:22 +00:00
|
|
|
|
long offset = 0;
|
1996-10-14 20:27:14 +00:00
|
|
|
|
SCM stack, id;
|
2000-05-18 08:47:52 +00:00
|
|
|
|
SCM inner_cut, outer_cut;
|
1996-11-02 20:54:19 +00:00
|
|
|
|
|
|
|
|
|
|
/* Extract a pointer to the innermost frame of whatever object
|
|
|
|
|
|
scm_make_stack was given. */
|
2004-07-27 15:41:49 +00:00
|
|
|
|
if (scm_is_eq (obj, SCM_BOOL_T))
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
2005-03-02 20:42:01 +00:00
|
|
|
|
dframe = scm_i_last_debug_frame ();
|
2001-06-25 11:06:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
else if (SCM_DEBUGOBJP (obj))
|
|
|
|
|
|
{
|
|
|
|
|
|
dframe = SCM_DEBUGOBJ_FRAME (obj);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (SCM_CONTINUATIONP (obj))
|
|
|
|
|
|
{
|
2004-12-23 15:30:29 +00:00
|
|
|
|
scm_t_contregs *cont = SCM_CONTREGS (obj);
|
|
|
|
|
|
offset = cont->offset;
|
|
|
|
|
|
dframe = RELOC_FRAME (cont->dframe, offset);
|
2001-06-25 11:06:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_WRONG_TYPE_ARG (SCM_ARG1, obj);
|
|
|
|
|
|
/* not reached */
|
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. */
|
2004-07-23 15:43:02 +00:00
|
|
|
|
stack = scm_make_struct (scm_stack_type, scm_from_long (size), SCM_EOL);
|
1996-10-14 20:27:14 +00:00
|
|
|
|
SCM_STACK (stack) -> id = id;
|
1996-10-17 23:32:25 +00:00
|
|
|
|
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. */
|
2004-12-23 15:30:29 +00:00
|
|
|
|
n = read_frames (dframe, offset, n, iframe);
|
1998-11-09 16:46:08 +00:00
|
|
|
|
SCM_STACK (stack) -> length = n;
|
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. */
|
2000-05-18 08:47:52 +00:00
|
|
|
|
SCM_VALIDATE_REST_ARGUMENT (args);
|
2004-09-22 17:41:37 +00:00
|
|
|
|
while (n > 0 && !scm_is_null (args))
|
1996-11-02 20:54:19 +00:00
|
|
|
|
{
|
|
|
|
|
|
inner_cut = SCM_CAR (args);
|
|
|
|
|
|
args = SCM_CDR (args);
|
2004-09-22 17:41:37 +00:00
|
|
|
|
if (scm_is_null (args))
|
2000-05-18 08:47:52 +00:00
|
|
|
|
{
|
2001-06-25 11:06:33 +00:00
|
|
|
|
outer_cut = SCM_INUM0;
|
2000-05-18 08:47:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
else
|
1996-11-02 20:54:19 +00:00
|
|
|
|
{
|
|
|
|
|
|
outer_cut = SCM_CAR (args);
|
|
|
|
|
|
args = SCM_CDR (args);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
narrow_stack (stack,
|
2004-07-23 15:43:02 +00:00
|
|
|
|
scm_is_integer (inner_cut) ? scm_to_int (inner_cut) : n,
|
|
|
|
|
|
scm_is_integer (inner_cut) ? 0 : inner_cut,
|
|
|
|
|
|
scm_is_integer (outer_cut) ? scm_to_int (outer_cut) : n,
|
|
|
|
|
|
scm_is_integer (outer_cut) ? 0 : outer_cut);
|
1996-11-02 20:54:19 +00:00
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
|
SCM_DEFINE (scm_stack_id, "stack-id", 1, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
|
(SCM stack),
|
* alist.c, chars.c, debug.c, dynl.c, dynwind.c, error.c, eval.c,
evalext.c, filesys.c, gc.c, hash.c, hashtab.c, ioext.c,
keywords.c, list.c, load.c, macros.c, net_db.c, numbers.c,
objprop.c, ports.c, posix.c, print.c, procprop.c, procs.c,
ramap.c, regex-posix.c, root.c, scmsigs.c, simpos.c, socket.c,
stacks.c, stime.c, strings.c, strop.c, strports.c, struct.c,
symbols.c, throw.c, unif.c, vectors.c, version.c, vports.c,
weaks.c: Converted docstrings to ANSI C format.
2000-01-18 11:24:03 +00:00
|
|
|
|
"Return the identifier given to @var{stack} by @code{start-stack}.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_stack_id
|
1996-10-14 20:27:14 +00:00
|
|
|
|
{
|
2001-06-14 19:50:43 +00:00
|
|
|
|
scm_t_debug_frame *dframe;
|
2001-05-26 20:51:22 +00:00
|
|
|
|
long offset = 0;
|
2004-07-27 15:41:49 +00:00
|
|
|
|
if (scm_is_eq (stack, SCM_BOOL_T))
|
1996-10-17 23:32:25 +00:00
|
|
|
|
{
|
2005-03-02 20:42:01 +00:00
|
|
|
|
dframe = scm_i_last_debug_frame ();
|
2001-06-25 11:06:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
else if (SCM_DEBUGOBJP (stack))
|
|
|
|
|
|
{
|
|
|
|
|
|
dframe = SCM_DEBUGOBJ_FRAME (stack);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (SCM_CONTINUATIONP (stack))
|
|
|
|
|
|
{
|
2004-12-23 15:30:29 +00:00
|
|
|
|
scm_t_contregs *cont = SCM_CONTREGS (stack);
|
|
|
|
|
|
offset = cont->offset;
|
|
|
|
|
|
dframe = RELOC_FRAME (cont->dframe, offset);
|
2001-06-25 11:06:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
else if (SCM_STACKP (stack))
|
|
|
|
|
|
{
|
|
|
|
|
|
return SCM_STACK (stack) -> id;
|
1996-10-17 23:32:25 +00:00
|
|
|
|
}
|
2001-06-25 11:06:33 +00:00
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_WRONG_TYPE_ARG (1, stack);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
1996-10-17 23:32:25 +00:00
|
|
|
|
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))
|
2004-12-23 15:30:29 +00:00
|
|
|
|
return RELOC_INFO (dframe->vect, offset)[0].id;
|
1996-10-17 23:32:25 +00:00
|
|
|
|
return SCM_BOOL_F;
|
1996-10-14 20:27:14 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-10-14 20:27:14 +00:00
|
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
|
SCM_DEFINE (scm_stack_ref, "stack-ref", 2, 0, 0,
|
2001-06-25 11:06:33 +00:00
|
|
|
|
(SCM stack, SCM index),
|
|
|
|
|
|
"Return the @var{index}'th frame from @var{stack}.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_stack_ref
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
2001-06-25 11:06:33 +00:00
|
|
|
|
unsigned long int c_index;
|
|
|
|
|
|
|
|
|
|
|
|
SCM_VALIDATE_STACK (1, stack);
|
* validate.h, deprecated.h (SCM_VALIDATE_INUM, SCM_VALIDATE_INUM_COPY,
SCM_VALIDATE_BIGINT, SCM_VALIDATE_INUM_MIN,
SCM_VALIDATE_INUM_MIN_COPY,
SCM_VALIDATE_INUM_MIN_DEF_COPY,SCM_VALIDATE_INUM_DEF,
SCM_VALIDATE_INUM_DEF_COPY, SCM_VALIDATE_INUM_RANGE,
SCM_VALIDATE_INUM_RANGE_COPY): Deprecated because they make the
fixnum/bignum distinction visible. Changed all uses to scm_to_size_t
or similar.
2004-07-10 14:35:36 +00:00
|
|
|
|
c_index = scm_to_unsigned_integer (index, 0, SCM_STACK_LENGTH(stack)-1);
|
2001-06-25 11:06:33 +00:00
|
|
|
|
return scm_cons (stack, index);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
2000-01-05 19:25:37 +00:00
|
|
|
|
SCM_DEFINE (scm_stack_length, "stack-length", 1, 0, 0,
|
(scm_make_stack, scm_stack_ref, scm_stack_length, scm_frame_p,
scm_last_stack_frame, scm_frame_number, scm_frame_source,
scm_frame_procedure, scm_frame_arguments, scm_frame_previous,
scm_frame_next, scm_frame_real_p, scm_frame_procedure_p,
scm_frame_evaluating_args_p, scm_frame_overflow_p): Added docstrings.
2001-02-16 15:14:10 +00:00
|
|
|
|
(SCM stack),
|
|
|
|
|
|
"Return the length of @var{stack}.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_stack_length
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
|
SCM_VALIDATE_STACK (1, stack);
|
2004-07-23 15:43:02 +00:00
|
|
|
|
return scm_from_int (SCM_STACK_LENGTH (stack));
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
|
|
|
|
|
/* Frames
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
|
SCM_DEFINE (scm_frame_p, "frame?", 1, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
|
(SCM obj),
|
(scm_make_stack, scm_stack_ref, scm_stack_length, scm_frame_p,
scm_last_stack_frame, scm_frame_number, scm_frame_source,
scm_frame_procedure, scm_frame_arguments, scm_frame_previous,
scm_frame_next, scm_frame_real_p, scm_frame_procedure_p,
scm_frame_evaluating_args_p, scm_frame_overflow_p): Added docstrings.
2001-02-16 15:14:10 +00:00
|
|
|
|
"Return @code{#t} if @var{obj} is a stack frame.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_frame_p
|
1996-10-14 20:27:14 +00:00
|
|
|
|
{
|
2004-07-06 10:59:25 +00:00
|
|
|
|
return scm_from_bool(SCM_FRAMEP (obj));
|
1996-10-14 20:27:14 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-10-14 20:27:14 +00:00
|
|
|
|
|
2000-01-05 19:25:37 +00:00
|
|
|
|
SCM_DEFINE (scm_last_stack_frame, "last-stack-frame", 1, 0, 0,
|
(scm_make_stack, scm_stack_ref, scm_stack_length, scm_frame_p,
scm_last_stack_frame, scm_frame_number, scm_frame_source,
scm_frame_procedure, scm_frame_arguments, scm_frame_previous,
scm_frame_next, scm_frame_real_p, scm_frame_procedure_p,
scm_frame_evaluating_args_p, scm_frame_overflow_p): Added docstrings.
2001-02-16 15:14:10 +00:00
|
|
|
|
(SCM obj),
|
2006-08-11 15:33:41 +00:00
|
|
|
|
"Return the last (innermost) frame of @var{obj}, which must be\n"
|
|
|
|
|
|
"either a debug object or a continuation.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_last_stack_frame
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
2001-06-14 19:50:43 +00:00
|
|
|
|
scm_t_debug_frame *dframe;
|
2001-05-26 20:51:22 +00:00
|
|
|
|
long offset = 0;
|
1996-10-17 23:32:25 +00:00
|
|
|
|
SCM stack;
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
|
|
|
|
|
if (SCM_DEBUGOBJP (obj))
|
2001-06-25 11:06:33 +00:00
|
|
|
|
{
|
|
|
|
|
|
dframe = SCM_DEBUGOBJ_FRAME (obj);
|
|
|
|
|
|
}
|
* use an applicable SMOB to represent continuations, instead of a
custom tc7 type. This will make it easier to support R5RS
multiple value continuations, without the use of a Scheme-level
wrapper.
* continuations.c (scm_tc16_continuation, continuation_mark,
continuation_free, continuation_print, continuation_apply):
new SMOB support.
(scm_make_continuation): new procedure, replaces scm_make_cont
with a different interface.
(copy_stack_and_call, scm_dynthrow, scm_init_continuations): rewritten.
(CHEAP_CONTINUATIONS): removed non-working code completely.
(scm_call_continuation): removed.
* continuations.h (struct scm_contregs): add num_stack_items and
stack fields. previously stack was stored following this struct:
use a tail array instead.
(SCM_CONTINUATIONP): new macro.
(SCM_CONTINUATION_LENGTH, SCM_SET_CONTINUATION_LENGTH):
rewritten.
(SCM_SET_CONTREGS): removed.
* tags.h: removed scm_tc7_contin (was tag 61).
* debug.c, gc.c, hash.c, print.c, procprop.c, procs.c:
removed scm_tc7_contin support.
* eval.c: use scm_make_continuation instead of scm_make_cont.
don't set jump buffers here. remove scm_tc7_contin support.
* init.c, root.c: create SMOB continuation for rootcont instead
of scm_tc7_contin. call scm_init_continuations before
scm_init_root.
* root.c: remove support for static jmpbuf. It's not used by
default and I broke it. create SMOB continuation for rootcont.
* stacks.c: use SCM_CONTINUATIONP.
2000-11-25 16:58:25 +00:00
|
|
|
|
else if (SCM_CONTINUATIONP (obj))
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
2004-12-23 15:30:29 +00:00
|
|
|
|
scm_t_contregs *cont = SCM_CONTREGS (obj);
|
|
|
|
|
|
offset = cont->offset;
|
|
|
|
|
|
dframe = RELOC_FRAME (cont->dframe, 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
|
|
|
|
|
|
{
|
2001-03-04 22:48:13 +00:00
|
|
|
|
SCM_WRONG_TYPE_ARG (1, obj);
|
|
|
|
|
|
/* not reached */
|
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
|
|
|
|
}
|
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;
|
|
|
|
|
|
|
2004-07-23 15:43:02 +00:00
|
|
|
|
stack = scm_make_struct (scm_stack_type, scm_from_int (SCM_FRAME_N_SLOTS),
|
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_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,
|
2001-06-14 19:50:43 +00:00
|
|
|
|
(scm_t_info_frame *) &SCM_STACK (stack) -> frames[0]);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
2001-06-25 11:06:33 +00:00
|
|
|
|
return scm_cons (stack, SCM_INUM0);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
2000-01-05 19:25:37 +00:00
|
|
|
|
SCM_DEFINE (scm_frame_number, "frame-number", 1, 0, 0,
|
(scm_make_stack, scm_stack_ref, scm_stack_length, scm_frame_p,
scm_last_stack_frame, scm_frame_number, scm_frame_source,
scm_frame_procedure, scm_frame_arguments, scm_frame_previous,
scm_frame_next, scm_frame_real_p, scm_frame_procedure_p,
scm_frame_evaluating_args_p, scm_frame_overflow_p): Added docstrings.
2001-02-16 15:14:10 +00:00
|
|
|
|
(SCM frame),
|
|
|
|
|
|
"Return the frame number of @var{frame}.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_frame_number
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
|
SCM_VALIDATE_FRAME (1, frame);
|
2004-07-23 15:43:02 +00:00
|
|
|
|
return scm_from_int (SCM_FRAME_NUMBER (frame));
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
2000-01-05 19:25:37 +00:00
|
|
|
|
SCM_DEFINE (scm_frame_source, "frame-source", 1, 0, 0,
|
(scm_make_stack, scm_stack_ref, scm_stack_length, scm_frame_p,
scm_last_stack_frame, scm_frame_number, scm_frame_source,
scm_frame_procedure, scm_frame_arguments, scm_frame_previous,
scm_frame_next, scm_frame_real_p, scm_frame_procedure_p,
scm_frame_evaluating_args_p, scm_frame_overflow_p): Added docstrings.
2001-02-16 15:14:10 +00:00
|
|
|
|
(SCM frame),
|
|
|
|
|
|
"Return the source of @var{frame}.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_frame_source
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
|
SCM_VALIDATE_FRAME (1, frame);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
return SCM_FRAME_SOURCE (frame);
|
|
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
2000-01-05 19:25:37 +00:00
|
|
|
|
SCM_DEFINE (scm_frame_procedure, "frame-procedure", 1, 0, 0,
|
(scm_make_stack, scm_stack_ref, scm_stack_length, scm_frame_p,
scm_last_stack_frame, scm_frame_number, scm_frame_source,
scm_frame_procedure, scm_frame_arguments, scm_frame_previous,
scm_frame_next, scm_frame_real_p, scm_frame_procedure_p,
scm_frame_evaluating_args_p, scm_frame_overflow_p): Added docstrings.
2001-02-16 15:14:10 +00:00
|
|
|
|
(SCM frame),
|
|
|
|
|
|
"Return the procedure for @var{frame}, or @code{#f} if no\n"
|
|
|
|
|
|
"procedure is associated with @var{frame}.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_frame_procedure
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
|
SCM_VALIDATE_FRAME (1, frame);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
return (SCM_FRAME_PROC_P (frame)
|
1997-12-02 17:34:07 +00:00
|
|
|
|
? SCM_FRAME_PROC (frame)
|
|
|
|
|
|
: SCM_BOOL_F);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
2000-01-05 19:25:37 +00:00
|
|
|
|
SCM_DEFINE (scm_frame_arguments, "frame-arguments", 1, 0, 0,
|
(scm_make_stack, scm_stack_ref, scm_stack_length, scm_frame_p,
scm_last_stack_frame, scm_frame_number, scm_frame_source,
scm_frame_procedure, scm_frame_arguments, scm_frame_previous,
scm_frame_next, scm_frame_real_p, scm_frame_procedure_p,
scm_frame_evaluating_args_p, scm_frame_overflow_p): Added docstrings.
2001-02-16 15:14:10 +00:00
|
|
|
|
(SCM frame),
|
|
|
|
|
|
"Return the arguments of @var{frame}.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_frame_arguments
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
|
SCM_VALIDATE_FRAME (1, frame);
|
1996-10-14 03:26:51 +00:00
|
|
|
|
return SCM_FRAME_ARGS (frame);
|
|
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
2000-01-05 19:25:37 +00:00
|
|
|
|
SCM_DEFINE (scm_frame_previous, "frame-previous", 1, 0, 0,
|
(scm_make_stack, scm_stack_ref, scm_stack_length, scm_frame_p,
scm_last_stack_frame, scm_frame_number, scm_frame_source,
scm_frame_procedure, scm_frame_arguments, scm_frame_previous,
scm_frame_next, scm_frame_real_p, scm_frame_procedure_p,
scm_frame_evaluating_args_p, scm_frame_overflow_p): Added docstrings.
2001-02-16 15:14:10 +00:00
|
|
|
|
(SCM frame),
|
|
|
|
|
|
"Return the previous frame of @var{frame}, or @code{#f} if\n"
|
|
|
|
|
|
"@var{frame} is the first frame in its stack.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_frame_previous
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
2001-06-25 11:06:33 +00:00
|
|
|
|
unsigned long int n;
|
|
|
|
|
|
SCM_VALIDATE_FRAME (1, frame);
|
2004-07-23 15:43:02 +00:00
|
|
|
|
n = scm_to_ulong (SCM_CDR (frame)) + 1;
|
1996-10-14 03:26:51 +00:00
|
|
|
|
if (n >= SCM_STACK_LENGTH (SCM_CAR (frame)))
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
else
|
2004-07-23 15:43:02 +00:00
|
|
|
|
return scm_cons (SCM_CAR (frame), scm_from_ulong (n));
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
2000-01-05 19:25:37 +00:00
|
|
|
|
SCM_DEFINE (scm_frame_next, "frame-next", 1, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
|
(SCM frame),
|
(scm_make_stack, scm_stack_ref, scm_stack_length, scm_frame_p,
scm_last_stack_frame, scm_frame_number, scm_frame_source,
scm_frame_procedure, scm_frame_arguments, scm_frame_previous,
scm_frame_next, scm_frame_real_p, scm_frame_procedure_p,
scm_frame_evaluating_args_p, scm_frame_overflow_p): Added docstrings.
2001-02-16 15:14:10 +00:00
|
|
|
|
"Return the next frame of @var{frame}, or @code{#f} if\n"
|
|
|
|
|
|
"@var{frame} is the last frame in its stack.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_frame_next
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
2001-06-25 11:06:33 +00:00
|
|
|
|
unsigned long int n;
|
|
|
|
|
|
SCM_VALIDATE_FRAME (1, frame);
|
2004-07-23 15:43:02 +00:00
|
|
|
|
n = scm_to_ulong (SCM_CDR (frame));
|
2001-06-25 11:06:33 +00:00
|
|
|
|
if (n == 0)
|
1996-10-14 03:26:51 +00:00
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
else
|
2004-07-23 15:43:02 +00:00
|
|
|
|
return scm_cons (SCM_CAR (frame), scm_from_ulong (n - 1));
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
2000-01-05 19:25:37 +00:00
|
|
|
|
SCM_DEFINE (scm_frame_real_p, "frame-real?", 1, 0, 0,
|
(scm_make_stack, scm_stack_ref, scm_stack_length, scm_frame_p,
scm_last_stack_frame, scm_frame_number, scm_frame_source,
scm_frame_procedure, scm_frame_arguments, scm_frame_previous,
scm_frame_next, scm_frame_real_p, scm_frame_procedure_p,
scm_frame_evaluating_args_p, scm_frame_overflow_p): Added docstrings.
2001-02-16 15:14:10 +00:00
|
|
|
|
(SCM frame),
|
|
|
|
|
|
"Return @code{#t} if @var{frame} is a real frame.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_frame_real_p
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
|
SCM_VALIDATE_FRAME (1, frame);
|
2004-07-06 10:59:25 +00:00
|
|
|
|
return scm_from_bool(SCM_FRAME_REAL_P (frame));
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
2000-01-05 19:25:37 +00:00
|
|
|
|
SCM_DEFINE (scm_frame_procedure_p, "frame-procedure?", 1, 0, 0,
|
(scm_make_stack, scm_stack_ref, scm_stack_length, scm_frame_p,
scm_last_stack_frame, scm_frame_number, scm_frame_source,
scm_frame_procedure, scm_frame_arguments, scm_frame_previous,
scm_frame_next, scm_frame_real_p, scm_frame_procedure_p,
scm_frame_evaluating_args_p, scm_frame_overflow_p): Added docstrings.
2001-02-16 15:14:10 +00:00
|
|
|
|
(SCM frame),
|
|
|
|
|
|
"Return @code{#t} if a procedure is associated with @var{frame}.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_frame_procedure_p
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
|
SCM_VALIDATE_FRAME (1, frame);
|
2004-07-06 10:59:25 +00:00
|
|
|
|
return scm_from_bool(SCM_FRAME_PROC_P (frame));
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
2000-01-05 19:25:37 +00:00
|
|
|
|
SCM_DEFINE (scm_frame_evaluating_args_p, "frame-evaluating-args?", 1, 0, 0,
|
(scm_make_stack, scm_stack_ref, scm_stack_length, scm_frame_p,
scm_last_stack_frame, scm_frame_number, scm_frame_source,
scm_frame_procedure, scm_frame_arguments, scm_frame_previous,
scm_frame_next, scm_frame_real_p, scm_frame_procedure_p,
scm_frame_evaluating_args_p, scm_frame_overflow_p): Added docstrings.
2001-02-16 15:14:10 +00:00
|
|
|
|
(SCM frame),
|
|
|
|
|
|
"Return @code{#t} if @var{frame} contains evaluated arguments.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_frame_evaluating_args_p
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
|
SCM_VALIDATE_FRAME (1, frame);
|
2004-07-06 10:59:25 +00:00
|
|
|
|
return scm_from_bool(SCM_FRAME_EVAL_ARGS_P (frame));
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
2000-01-05 19:25:37 +00:00
|
|
|
|
SCM_DEFINE (scm_frame_overflow_p, "frame-overflow?", 1, 0, 0,
|
(scm_make_stack, scm_stack_ref, scm_stack_length, scm_frame_p,
scm_last_stack_frame, scm_frame_number, scm_frame_source,
scm_frame_procedure, scm_frame_arguments, scm_frame_previous,
scm_frame_next, scm_frame_real_p, scm_frame_procedure_p,
scm_frame_evaluating_args_p, scm_frame_overflow_p): Added docstrings.
2001-02-16 15:14:10 +00:00
|
|
|
|
(SCM frame),
|
|
|
|
|
|
"Return @code{#t} if @var{frame} is an overflow frame.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_frame_overflow_p
|
1996-10-14 03:26:51 +00:00
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
|
SCM_VALIDATE_FRAME (1, frame);
|
2004-07-06 10:59:25 +00:00
|
|
|
|
return scm_from_bool(SCM_FRAME_OVERFLOW_P (frame));
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-10-14 03:26:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
scm_init_stacks ()
|
|
|
|
|
|
{
|
1996-10-14 20:27:14 +00:00
|
|
|
|
SCM vtable;
|
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
|
* strings.h, strings.c: (scm_i_string_chars, scm_i_string_length,
scm_i_string_writable_chars, scm_i_string_stop_writing): New, to
replace SCM_I_STRING_CHARS and SCM_I_STRING_LENGTH. Updated all
uses.
(scm_i_make_string, scm_c_make_string): New, to replace
scm_allocate_string. Updated all uses.
(SCM_STRINGP, SCM_STRING_CHARS, SCM_STRING_UCHARS,
SCM_STRING_LENGTH): Deprecated.
(scm_allocate_string, scm_take_str, scm_take0str, scm_mem2string,
scm_str2string, scm_makfrom0str, scm_makfrom0str_opt):
Discouraged. Replaced all uses with scm_from_locale_string or
similar, as appropriate.
(scm_c_string_length, scm_c_string_ref, scm_c_string_set_x,
scm_c_substring, scm_c_substring_shared, scm_c_substring_copy,
scm_substring_shared, scm_substring_copy): New.
* symbols.c, symbols.h (SCM_SYMBOLP, SCM_SYMBOL_FUNC,
SCM_SET_SYMBOL_FUNC, SCM_SYMBOL_PROPS, SCM_SET_SYMBOL_PROPS,
SCM_SYMBOL_HASH, SCM_SYMBOL_INTERNED_P, scm_mem2symbol,
scm_str2symbol, scm_mem2uninterned_symbol): Discouraged.
(SCM_SYMBOL_LENGTH, SCM_SYMBOL_CHARS, scm_c_symbol2str):
Deprecated.
(SCM_MAKE_SYMBOL_TAG, SCM_SET_SYMBOL_LENGTH, SCM_SET_SYMBOL_CHARS,
SCM_PROP_SLOTS, SCM_SET_PROP_SLOTS): Removed.
(scm_is_symbol, scm_from_locale_symbol, scm_from_locale_symboln):
New, to replace scm_str2symbol and scm_mem2symbol, respectively.
Updated all uses.
(scm_gensym): Generate only the number suffix in the buffer, just
string-append the prefix.
2004-08-19 17:19:44 +00:00
|
|
|
|
= scm_make_struct_layout (scm_from_locale_string (SCM_STACK_LAYOUT));
|
2000-08-27 03:21:03 +00:00
|
|
|
|
vtable = scm_make_vtable_vtable (scm_nullstr, SCM_INUM0, SCM_EOL);
|
2001-12-16 21:57:52 +00:00
|
|
|
|
scm_stack_type
|
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_permanent_object (scm_make_struct (vtable, SCM_INUM0,
|
|
|
|
|
|
scm_cons (stack_layout,
|
|
|
|
|
|
SCM_EOL)));
|
* strings.h, strings.c: (scm_i_string_chars, scm_i_string_length,
scm_i_string_writable_chars, scm_i_string_stop_writing): New, to
replace SCM_I_STRING_CHARS and SCM_I_STRING_LENGTH. Updated all
uses.
(scm_i_make_string, scm_c_make_string): New, to replace
scm_allocate_string. Updated all uses.
(SCM_STRINGP, SCM_STRING_CHARS, SCM_STRING_UCHARS,
SCM_STRING_LENGTH): Deprecated.
(scm_allocate_string, scm_take_str, scm_take0str, scm_mem2string,
scm_str2string, scm_makfrom0str, scm_makfrom0str_opt):
Discouraged. Replaced all uses with scm_from_locale_string or
similar, as appropriate.
(scm_c_string_length, scm_c_string_ref, scm_c_string_set_x,
scm_c_substring, scm_c_substring_shared, scm_c_substring_copy,
scm_substring_shared, scm_substring_copy): New.
* symbols.c, symbols.h (SCM_SYMBOLP, SCM_SYMBOL_FUNC,
SCM_SET_SYMBOL_FUNC, SCM_SYMBOL_PROPS, SCM_SET_SYMBOL_PROPS,
SCM_SYMBOL_HASH, SCM_SYMBOL_INTERNED_P, scm_mem2symbol,
scm_str2symbol, scm_mem2uninterned_symbol): Discouraged.
(SCM_SYMBOL_LENGTH, SCM_SYMBOL_CHARS, scm_c_symbol2str):
Deprecated.
(SCM_MAKE_SYMBOL_TAG, SCM_SET_SYMBOL_LENGTH, SCM_SET_SYMBOL_CHARS,
SCM_PROP_SLOTS, SCM_SET_PROP_SLOTS): Removed.
(scm_is_symbol, scm_from_locale_symbol, scm_from_locale_symboln):
New, to replace scm_str2symbol and scm_mem2symbol, respectively.
Updated all uses.
(scm_gensym): Generate only the number suffix in the buffer, just
string-append the prefix.
2004-08-19 17:19:44 +00:00
|
|
|
|
scm_set_struct_vtable_name_x (scm_stack_type,
|
|
|
|
|
|
scm_from_locale_symbol ("stack"));
|
2000-04-21 14:16:44 +00:00
|
|
|
|
#include "libguile/stacks.x"
|
1996-10-14 03:26:51 +00:00
|
|
|
|
}
|
2000-03-19 19:01:16 +00:00
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
Local Variables:
|
|
|
|
|
|
c-file-style: "gnu"
|
|
|
|
|
|
End:
|
|
|
|
|
|
*/
|