degenerate let forms
[bpt/guile.git] / libguile / frames.h
index bd85b7e..31f8634 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
  * * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -110,27 +110,6 @@ struct scm_vm_frame
 #define SCM_FRAME_NUM_LOCALS(fp, sp)            \
   ((sp) + 1 - &SCM_FRAME_LOCAL (fp, 0))
 
-/* Currently (November 2013) we keep the procedure and arguments in
-   their slots for the duration of the procedure call, regardless of
-   whether the values are live or not.  This allows for backtraces that
-   show the closure and arguments.  We may allow the compiler to relax
-   this restriction in the future, if the user so desires.  This would
-   conserve stack space and make GC more precise.  We would need better
-   debugging information to do that, however.
-
-   Even now there is an exception to the rule that slot 0 holds the
-   procedure, which is in the case of tail calls.  The compiler will
-   emit code that shuffles the new procedure and arguments into position
-   before performing the tail call, so there is a window in which
-   SCM_FRAME_PROGRAM does not correspond to the program being executed.
-
-   The moral of the story is to use the IP in a frame to determine what
-   procedure is being called.  It is only appropriate to use
-   SCM_FRAME_PROGRAM in the prologue of a procedure call, when you know
-   it must be there.  */
-
-#define SCM_FRAME_PROGRAM(fp) (SCM_FRAME_LOCAL (fp, 0))
-
 \f
 /*
  * Heap frames
@@ -140,31 +119,48 @@ struct scm_vm_frame
 
 struct scm_frame 
 {
-  SCM stack_holder;
+  void *stack_holder;
   scm_t_ptrdiff fp_offset;
   scm_t_ptrdiff sp_offset;
   scm_t_uint32 *ip;
 };
 
+enum scm_vm_frame_kind
+  {
+    SCM_VM_FRAME_KIND_VM,
+    SCM_VM_FRAME_KIND_CONT
+  };
+
 #define SCM_VM_FRAME_P(x)      (SCM_HAS_TYP7 (x, scm_tc7_frame))
-#define SCM_VM_FRAME_DATA(x)   ((struct scm_frame*)SCM_CELL_WORD_1 (x))
-#define SCM_VM_FRAME_STACK_HOLDER(f)   SCM_VM_FRAME_DATA(f)->stack_holder
-#define SCM_VM_FRAME_FP(f)     (SCM_VM_FRAME_DATA(f)->fp_offset + scm_i_frame_stack_base(f))
-#define SCM_VM_FRAME_SP(f)     (SCM_VM_FRAME_DATA(f)->sp_offset + scm_i_frame_stack_base(f))
-#define SCM_VM_FRAME_IP(f)     SCM_VM_FRAME_DATA(f)->ip
+#define SCM_VM_FRAME_KIND(x)   ((enum scm_vm_frame_kind) (SCM_CELL_WORD_0 (x) >> 8))
+#define SCM_VM_FRAME_DATA(x)   ((struct scm_frame *)SCM_CELL_WORD_1 (x))
+#define SCM_VM_FRAME_STACK_HOLDER(f)   SCM_VM_FRAME_DATA (f)->stack_holder
+#define SCM_VM_FRAME_FP_OFFSET(f)      SCM_VM_FRAME_DATA (f)->fp_offset
+#define SCM_VM_FRAME_SP_OFFSET(f)      SCM_VM_FRAME_DATA (f)->sp_offset
+#define SCM_VM_FRAME_FP(f)     (SCM_VM_FRAME_FP_OFFSET (f) + scm_i_frame_stack_base (f))
+#define SCM_VM_FRAME_SP(f)     (SCM_VM_FRAME_SP_OFFSET (f) + scm_i_frame_stack_base (f))
+#define SCM_VM_FRAME_IP(f)     SCM_VM_FRAME_DATA (f)->ip
 #define SCM_VM_FRAME_OFFSET(f) scm_i_frame_offset (f)
 #define SCM_VALIDATE_VM_FRAME(p,x)     SCM_MAKE_VALIDATE (p, x, VM_FRAME_P)
 
 SCM_INTERNAL SCM* scm_i_frame_stack_base (SCM frame);
 SCM_INTERNAL scm_t_ptrdiff scm_i_frame_offset (SCM frame);
 
-SCM_INTERNAL SCM scm_c_make_frame (SCM stack_holder, scm_t_ptrdiff fp_offset,
-                                   scm_t_ptrdiff sp_offset, scm_t_uint32 *ip);
+/* See notes in frames.c before using this.  */
+SCM_INTERNAL SCM scm_c_frame_closure (enum scm_vm_frame_kind kind,
+                                      const struct scm_frame *frame);
+
+SCM_INTERNAL SCM scm_c_make_frame (enum scm_vm_frame_kind kind,
+                                   const struct scm_frame *frame);
+
+SCM_INTERNAL int scm_c_frame_previous (enum scm_vm_frame_kind kind,
+                                       struct scm_frame *frame);
 
 #endif
 
 SCM_API SCM scm_frame_p (SCM obj);
 SCM_API SCM scm_frame_procedure (SCM frame);
+SCM_API SCM scm_frame_call_representation (SCM frame);
 SCM_API SCM scm_frame_arguments (SCM frame);
 SCM_API SCM scm_frame_source (SCM frame);
 SCM_API SCM scm_frame_num_locals (SCM frame);