summaryrefslogtreecommitdiff
path: root/libguile/frames.h
diff options
context:
space:
mode:
Diffstat (limited to 'libguile/frames.h')
-rw-r--r--libguile/frames.h76
1 files changed, 36 insertions, 40 deletions
diff --git a/libguile/frames.h b/libguile/frames.h
index 31f86345f..c2f1e57db 100644
--- a/libguile/frames.h
+++ b/libguile/frames.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2009, 2010, 2011, 2012, 2013, 2014, 2015 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
@@ -38,24 +38,29 @@
Stack frame layout
------------------
- /------------------\
- | Local N-1 | <- sp
| ... |
- | Local 1 |
- | Local 0 | <- fp = SCM_FRAME_LOCALS_ADDRESS (fp)
- +==================+
+ +==================+ <- fp + 2 = SCM_FRAME_PREVIOUS_SP (fp)
+ | Dynamic link |
+ +------------------+
| Return address |
- | Dynamic link | <- fp - 2 = SCM_FRAME_LOWER_ADDRESS (fp)
- +==================+
- | | <- fp - 3 = SCM_FRAME_PREVIOUS_SP (fp)
+ +==================+ <- fp
+ | Local 0 |
+ +------------------+
+ | Local 1 |
+ +------------------+
+ | ... |
+ +------------------+
+ | Local N-1 |
+ \------------------/ <- sp
+
+ The stack grows down.
The calling convention is that a caller prepares a stack frame
consisting of the saved FP and the return address, followed by the
procedure and then the arguments to the call, in order. Thus in the
beginning of a call, the procedure being called is in slot 0, the
first argument is in slot 1, and the SP points to the last argument.
- The number of arguments, including the procedure, is thus SP - FP +
- 1.
+ The number of arguments, including the procedure, is thus FP - SP.
After ensuring that the correct number of arguments have been passed,
a function will set the stack pointer to point to the last local
@@ -80,35 +85,26 @@
-/* This structure maps to the contents of a VM stack frame. It can
- alias a frame directly. */
-struct scm_vm_frame
+/* Each element on the stack occupies the same amount of space. */
+union scm_vm_stack_element
{
- SCM *dynamic_link;
- scm_t_uint32 *return_address;
- SCM locals[1]; /* Variable-length */
-};
-
-#define SCM_FRAME_LOWER_ADDRESS(fp) (((SCM *) (fp)) - 2)
-#define SCM_FRAME_STRUCT(fp) \
- ((struct scm_vm_frame *) SCM_FRAME_LOWER_ADDRESS (fp))
-#define SCM_FRAME_LOCALS_ADDRESS(fp) (SCM_FRAME_STRUCT (fp)->locals)
-
-#define SCM_FRAME_PREVIOUS_SP(fp) (((SCM *) (fp)) - 3)
+ union scm_vm_stack_element *fp;
+ scm_t_uint32 *ip;
+ SCM scm;
-#define SCM_FRAME_RETURN_ADDRESS(fp) \
- (SCM_FRAME_STRUCT (fp)->return_address)
-#define SCM_FRAME_SET_RETURN_ADDRESS(fp, ra) \
- SCM_FRAME_STRUCT (fp)->return_address = (ra)
-#define SCM_FRAME_DYNAMIC_LINK(fp) \
- (SCM_FRAME_STRUCT (fp)->dynamic_link)
-#define SCM_FRAME_SET_DYNAMIC_LINK(fp, dl) \
- SCM_FRAME_DYNAMIC_LINK (fp) = (dl)
-#define SCM_FRAME_LOCAL(fp,i) \
- (SCM_FRAME_STRUCT (fp)->locals[i])
+ /* For GC purposes. */
+ void *ptr;
+ scm_t_bits bits;
+};
-#define SCM_FRAME_NUM_LOCALS(fp, sp) \
- ((sp) + 1 - &SCM_FRAME_LOCAL (fp, 0))
+#define SCM_FRAME_PREVIOUS_SP(fp_) ((fp_) + 2)
+#define SCM_FRAME_RETURN_ADDRESS(fp_) ((fp_)[0].ip)
+#define SCM_FRAME_SET_RETURN_ADDRESS(fp_, ra) ((fp_)[0].ip = (ra))
+#define SCM_FRAME_DYNAMIC_LINK(fp_) ((fp_)[1].fp)
+#define SCM_FRAME_SET_DYNAMIC_LINK(fp_, dl) ((fp_)[1].fp = (dl))
+#define SCM_FRAME_SLOT(fp_,i) ((fp_) - (i) - 1)
+#define SCM_FRAME_LOCAL(fp_,i) (SCM_FRAME_SLOT (fp_, i)->scm)
+#define SCM_FRAME_NUM_LOCALS(fp_, sp) ((fp_) - (sp))
/*
@@ -137,13 +133,13 @@ enum scm_vm_frame_kind
#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_FP(f) (scm_i_frame_stack_top (f) - SCM_VM_FRAME_FP_OFFSET (f))
+#define SCM_VM_FRAME_SP(f) (scm_i_frame_stack_top (f) - SCM_VM_FRAME_SP_OFFSET (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 union scm_vm_stack_element* scm_i_frame_stack_top (SCM frame);
SCM_INTERNAL scm_t_ptrdiff scm_i_frame_offset (SCM frame);
/* See notes in frames.c before using this. */