Merge commit 'e20d7001c3f7150400169fecb0bf0eefdf122fe2' into vm-check
[bpt/guile.git] / libguile / stacks.c
index 5765a22..5b2eea9 100644 (file)
@@ -1,50 +1,26 @@
 /* Representation of stack frame debug information
- * Copyright (C) 1996,1997,2000,2001 Free Software Foundation
+ * Copyright (C) 1996,1997,2000,2001, 2006, 2007, 2008, 2009 Free Software Foundation
  *
- * 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 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.
  *
- * This program is distributed in the hope that it will be useful,
+ * This library 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser 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
- * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307 USA
- *
- * 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
- * Mikael Djurfeldt, SANS/NADA KTH, 10044 STOCKHOLM, SWEDEN */
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
 
 
 \f
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
 
 #include "libguile/_scm.h"
 #include "libguile/eval.h"
 #include "libguile/modules.h"
 #include "libguile/root.h"
 #include "libguile/strings.h"
+#include "libguile/vm.h" /* to capture vm stacks */
+#include "libguile/frames.h" /* vm frames */
+#include "libguile/instructions.h" /* scm_op_halt */
 
 #include "libguile/validate.h"
 #include "libguile/stacks.h"
+#include "libguile/private-options.h"
+
 
 \f
 /* {Frames and stacks}
 #define RELOC_FRAME(ptr, offset) \
   ((scm_t_debug_frame *) ((SCM_STACKITEM *) (ptr) + (offset)))
 
-
 /* 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.
  */
-static scm_t_bits
-stack_depth (scm_t_debug_frame *dframe, long offset, SCM *id, int *maxp)
+static long
+stack_depth (scm_t_debug_frame *dframe, scm_t_ptrdiff offset, SCM vmframe,
+            SCM *id)
 {
   long n;
-  long max_depth = SCM_BACKTRACE_MAXDEPTH;
   for (n = 0;
-       dframe && !SCM_VOIDFRAMEP (*dframe) && n < max_depth;
+       dframe && !SCM_VOIDFRAMEP (*dframe);
        dframe = RELOC_FRAME (dframe->prev, offset))
     {
       if (SCM_EVALFRAMEP (*dframe))
        {
-         scm_t_debug_info * info = RELOC_INFO (dframe->info, offset);
-         n += (info - dframe->vect) / 2 + 1;
+         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;
          /* Data in the apply part of an eval info frame comes from previous
             stack frame if the scm_t_debug_info vector is overflowed. */
-         if ((((info - dframe->vect) & 1) == 0)
+         if ((((info - vect) & 1) == 0)
              && SCM_OVERFLOWP (*dframe)
              && !SCM_UNBNDP (info[1].a.proc))
-           ++n;
+            ++n;
        }
+      else if (SCM_APPLYFRAMEP (*dframe))
+        {
+          scm_t_debug_info *vect = RELOC_INFO (dframe->vect, offset);
+          if (SCM_PROGRAM_P (vect[0].a.proc))
+            {
+              if (!SCM_PROGRAM_IS_BOOT (vect[0].a.proc))
+                /* Programs can end up in the debug stack via deval; but we just
+                   ignore those, because we know that the debugging VM engine
+                   pushes one dframe per invocation, with the boot program as
+                   the proc, so we only count those. */
+                continue;
+              /* count vmframe back to previous boot frame */
+              for (; scm_is_true (vmframe); vmframe = scm_c_vm_frame_prev (vmframe))
+                {
+                  if (!SCM_PROGRAM_IS_BOOT (scm_vm_frame_program (vmframe)))
+                    ++n;
+                  else
+                    { /* skip boot frame, cut out of the vm backtrace */
+                      vmframe = scm_c_vm_frame_prev (vmframe);
+                      break;
+                    }
+                }
+            }
+          else
+            ++n; /* increment for non-program apply frame */
+        }
       else
        ++n;
     }
   if (dframe && SCM_VOIDFRAMEP (*dframe))
-    *id = dframe->vect[0].id;
-  else if (dframe)
-    *maxp = 1;
+    *id = RELOC_INFO(dframe->vect, offset)[0].id;
   return n;
 }
 
 /* Read debug info from DFRAME into IFRAME.
  */
 static void
-read_frame (scm_t_debug_frame *dframe, long offset, scm_t_info_frame *iframe)
+read_frame (scm_t_debug_frame *dframe, scm_t_ptrdiff offset,
+           scm_t_info_frame *iframe)
 {
   scm_t_bits flags = SCM_UNPACK (SCM_INUM0); /* UGh. */
   if (SCM_EVALFRAMEP (*dframe))
     {
-      scm_t_debug_info * info = RELOC_INFO (dframe->info, offset);
-      if ((info - dframe->vect) & 1)
+      scm_t_debug_info *info = RELOC_INFO (dframe->info, offset);
+      scm_t_debug_info *vect = RELOC_INFO (dframe->vect, offset);
+      if ((info - vect) & 1)
        {
          /* Debug.vect ends with apply info. */
          --info;
@@ -206,9 +213,10 @@ read_frame (scm_t_debug_frame *dframe, long offset, scm_t_info_frame *iframe)
     }
   else
     {
+      scm_t_debug_info *vect = RELOC_INFO (dframe->vect, offset);
       flags |= SCM_FRAMEF_PROC;
-      iframe->proc = dframe->vect[0].a.proc;
-      iframe->args = dframe->vect[0].a.args;
+      iframe->proc = vect[0].a.proc;
+      iframe->args = vect[0].a.args;
     }
   iframe->flags = flags;
 }
@@ -229,10 +237,10 @@ get_applybody ()
 #define NEXT_FRAME(iframe, n, quit) \
 do { \
   if (SCM_MEMOIZEDP (iframe->source) \
-      && SCM_EQ_P (SCM_MEMOIZED_EXP (iframe->source), applybody)) \
+      && scm_is_eq (SCM_MEMOIZED_EXP (iframe->source), applybody)) \
     { \
       iframe->source = SCM_BOOL_F; \
-      if (SCM_FALSEP (iframe->proc)) \
+      if (scm_is_false (iframe->proc)) \
        { \
          --iframe; \
          ++n; \
@@ -250,10 +258,11 @@ do { \
  */
 
 static scm_t_bits
-read_frames (scm_t_debug_frame *dframe, long offset, long n, scm_t_info_frame *iframes)
+read_frames (scm_t_debug_frame *dframe, scm_t_ptrdiff offset,
+            SCM vmframe, long n, scm_t_info_frame *iframes)
 {
   scm_t_info_frame *iframe = iframes;
-  scm_t_debug_info *info;
+  scm_t_debug_info *info, *vect;
   static SCM applybody = SCM_UNDEFINED;
   
   /* The value of applybody has to be setup after r4rs.scm has executed. */
@@ -275,7 +284,8 @@ read_frames (scm_t_debug_frame *dframe, long offset, long n, scm_t_info_frame *i
              --iframe;
            }
          info =  RELOC_INFO (dframe->info, offset);
-         if ((info - dframe->vect) & 1)
+         vect =  RELOC_INFO (dframe->vect, offset);
+         if ((info - vect) & 1)
            --info;
          /* Data in the apply part of an eval info frame comes from
             previous stack frame if the scm_t_debug_info vector is
@@ -292,7 +302,7 @@ read_frames (scm_t_debug_frame *dframe, long offset, long n, scm_t_info_frame *i
            iframe->flags |= SCM_FRAMEF_OVERFLOW;
          info -= 2;
          NEXT_FRAME (iframe, n, quit);
-         while (info >= dframe->vect)
+         while (info >= vect)
            {
              if (!SCM_UNBNDP (info[1].a.proc))
                {
@@ -308,13 +318,39 @@ read_frames (scm_t_debug_frame *dframe, long offset, long n, scm_t_info_frame *i
              NEXT_FRAME (iframe, n, quit);
            }
        }
-      else if (SCM_EQ_P (iframe->proc, scm_f_gsubr_apply))
-       /* Skip gsubr apply frames. */
-       continue;
+      else if (SCM_PROGRAM_P (iframe->proc))
+        {
+          if (!SCM_PROGRAM_IS_BOOT (iframe->proc))
+            /* Programs can end up in the debug stack via deval; but we just
+               ignore those, because we know that the debugging VM engine
+               pushes one dframe per invocation, with the boot program as
+               the proc, so we only count those. */
+            continue;
+          for (; scm_is_true (vmframe);
+               vmframe = scm_c_vm_frame_prev (vmframe))
+            {
+              if (SCM_PROGRAM_IS_BOOT (scm_vm_frame_program (vmframe)))
+                { /* skip boot frame, back to interpreted frames */
+                  vmframe = scm_c_vm_frame_prev (vmframe);
+                  break;
+                }
+              else 
+                {
+                  /* Oh dear, oh dear, oh dear. */
+                  iframe->flags = SCM_UNPACK (SCM_INUM0) | SCM_FRAMEF_PROC;
+                  iframe->source = scm_vm_frame_source (vmframe);
+                  iframe->proc = scm_vm_frame_program (vmframe);
+                  iframe->args = scm_vm_frame_arguments (vmframe);
+                  ++iframe;
+                  if (--n == 0)
+                    goto quit;
+                }
+            }
+        }
       else
-       {
-         NEXT_FRAME (iframe, n, quit);
-       }
+        {
+          NEXT_FRAME (iframe, n, quit);
+        }
     quit:
       if (iframe > iframes)
        (iframe - 1) -> flags |= SCM_FRAMEF_REAL;
@@ -351,7 +387,7 @@ narrow_stack (SCM stack, long inner, SCM inner_key, long outer, SCM outer_key)
   long n = s->length;
   
   /* Cut inner part. */
-  if (SCM_EQ_P (inner_key, SCM_BOOL_T))
+  if (scm_is_eq (inner_key, SCM_BOOL_T))
     {
       /* Cut all frames up to user module code */
       for (i = 0; inner; ++i, --inner)
@@ -359,7 +395,7 @@ narrow_stack (SCM stack, long inner, SCM inner_key, long outer, SCM outer_key)
          SCM m = s->frames[i].source;
          if (SCM_MEMOIZEDP (m)
              && !SCM_IMP (SCM_MEMOIZED_ENV (m))
-             && SCM_FALSEP (scm_system_module_env_p (SCM_MEMOIZED_ENV (m))))
+             && scm_is_false (scm_system_module_env_p (SCM_MEMOIZED_ENV (m))))
            {
              /* Back up in order to include any non-source frames */
              while (i > 0)
@@ -369,8 +405,8 @@ narrow_stack (SCM stack, long inner, SCM inner_key, long outer, SCM outer_key)
                    break;
 
                  m = s->frames[i - 1].proc;
-                 if (!SCM_FALSEP (scm_procedure_p (m))
-                     && !SCM_FALSEP (scm_procedure_property
+                 if (scm_is_true (scm_procedure_p (m))
+                     && scm_is_true (scm_procedure_property
                                      (m, scm_sym_system_procedure)))
                    break;
 
@@ -385,7 +421,7 @@ narrow_stack (SCM stack, long inner, SCM inner_key, long outer, SCM outer_key)
     /* Use standard cutting procedure. */
     {
       for (i = 0; inner; --inner)
-       if (SCM_EQ_P (s->frames[i++].proc, inner_key))
+       if (scm_is_eq (s->frames[i++].proc, inner_key))
          break;
     }
   s->frames = &s->frames[i];
@@ -393,7 +429,7 @@ narrow_stack (SCM stack, long inner, SCM inner_key, long outer, SCM outer_key)
 
   /* Cut outer part. */
   for (; n && outer; --outer)
-    if (SCM_EQ_P (s->frames[--n].proc, outer_key))
+    if (scm_is_eq (s->frames[--n].proc, outer_key))
       break;
 
   s->length = n;
@@ -411,7 +447,7 @@ SCM_DEFINE (scm_stack_p, "stack?", 1, 0, 0,
            "Return @code{#t} if @var{obj} is a calling stack.")
 #define FUNC_NAME s_scm_stack_p
 {
-  return SCM_BOOL(SCM_STACKP (obj));
+  return scm_from_bool(SCM_STACKP (obj));
 }
 #undef FUNC_NAME
 
@@ -446,28 +482,46 @@ SCM_DEFINE (scm_make_stack, "make-stack", 1, 0, 1,
   int maxp;
   scm_t_debug_frame *dframe;
   scm_t_info_frame *iframe;
+  SCM vmframe;
   long offset = 0;
   SCM stack, id;
   SCM inner_cut, outer_cut;
 
   /* Extract a pointer to the innermost frame of whatever object
      scm_make_stack was given.  */
-  if (SCM_EQ_P (obj, SCM_BOOL_T))
+  if (scm_is_eq (obj, SCM_BOOL_T))
     {
-      dframe = scm_last_debug_frame;
+      struct scm_vm *vp = SCM_VM_DATA (scm_the_vm ());
+      dframe = scm_i_last_debug_frame ();
+      vmframe = scm_c_make_vm_frame (scm_the_vm (), vp->fp, vp->sp, vp->ip, 0);
     }
   else if (SCM_DEBUGOBJP (obj))
     {
       dframe = SCM_DEBUGOBJ_FRAME (obj);
+      vmframe = SCM_BOOL_F;
+    }
+  else if (SCM_VM_FRAME_P (obj))
+    {
+      dframe = NULL;
+      vmframe = obj;
     }
   else if (SCM_CONTINUATIONP (obj))
     {
-      offset = ((SCM_STACKITEM *) ((char *) SCM_CONTREGS (obj) + sizeof (scm_t_contregs))
-               - SCM_BASE (obj));
-#ifndef STACK_GROWS_UP
-      offset += SCM_CONTINUATION_LENGTH (obj);
-#endif
-      dframe = RELOC_FRAME (SCM_DFRAME (obj), offset);
+      scm_t_contregs *cont = SCM_CONTREGS (obj);
+      offset = cont->offset;
+      dframe = RELOC_FRAME (cont->dframe, offset);
+      if (!scm_is_null (cont->vm_conts))
+        { SCM vm_cont;
+          struct scm_vm_cont *data;
+          vm_cont = scm_cdr (scm_car (cont->vm_conts));
+          data = SCM_VM_CONT_DATA (vm_cont);
+          vmframe = scm_c_make_vm_frame (vm_cont,
+                                         data->fp + data->reloc,
+                                         data->sp + data->reloc,
+                                         data->ip,
+                                         data->reloc);
+        } else 
+          vmframe = SCM_BOOL_F;
     }
   else
     {
@@ -480,26 +534,32 @@ SCM_DEFINE (scm_make_stack, "make-stack", 1, 0, 1,
      (SCM_BACKTRACE_MAXDEPTH). */
   id = SCM_BOOL_F;
   maxp = 0;
-  n = stack_depth (dframe, offset, &id, &maxp);
+  n = stack_depth (dframe, offset, vmframe, &id);
+  /* FIXME: redo maxp? */
   size = n * SCM_FRAME_N_SLOTS;
 
   /* Make the stack object. */
-  stack = scm_make_struct (scm_stack_type, SCM_MAKINUM (size), SCM_EOL);
+  stack = scm_make_struct (scm_stack_type, scm_from_long (size), SCM_EOL);
   SCM_STACK (stack) -> id = id;
   iframe = &SCM_STACK (stack) -> tail[0];
   SCM_STACK (stack) -> frames = iframe;
+  SCM_STACK (stack) -> length = n;
 
   /* Translate the current chain of stack frames into debugging information. */
-  n = read_frames (RELOC_FRAME (dframe, offset), offset, n, iframe);
-  SCM_STACK (stack) -> length = n;
+  n = read_frames (dframe, offset, vmframe, n, iframe);
+  if (n != SCM_STACK (stack)->length)
+    {
+      scm_puts ("warning: stack count incorrect!\n", scm_current_error_port ());
+      SCM_STACK (stack)->length = n;
+    }
 
   /* Narrow the stack according to the arguments given to scm_make_stack. */
   SCM_VALIDATE_REST_ARGUMENT (args);
-  while (n > 0 && !SCM_NULLP (args))
+  while (n > 0 && !scm_is_null (args))
     {
       inner_cut = SCM_CAR (args);
       args = SCM_CDR (args);
-      if (SCM_NULLP (args)) 
+      if (scm_is_null (args)) 
        {
          outer_cut = SCM_INUM0;
        } 
@@ -510,20 +570,19 @@ SCM_DEFINE (scm_make_stack, "make-stack", 1, 0, 1,
        }
       
       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);
+                   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);
 
       n = SCM_STACK (stack) -> length;
     }
   
+  if (n > 0 && maxp)
+    iframe[n - 1].flags |= SCM_FRAMEF_OVERFLOW;
+
   if (n > 0)
-    {
-      if (maxp)
-       iframe[n - 1].flags |= SCM_FRAMEF_OVERFLOW;
-      return stack;
-    }
+    return stack;
   else
     return SCM_BOOL_F;
 }
@@ -536,9 +595,9 @@ SCM_DEFINE (scm_stack_id, "stack-id", 1, 0, 0,
 {
   scm_t_debug_frame *dframe;
   long offset = 0;
-  if (SCM_EQ_P (stack, SCM_BOOL_T))
+  if (scm_is_eq (stack, SCM_BOOL_T))
     {
-      dframe = scm_last_debug_frame;
+      dframe = scm_i_last_debug_frame ();
     }
   else if (SCM_DEBUGOBJP (stack))
     {
@@ -546,12 +605,9 @@ SCM_DEFINE (scm_stack_id, "stack-id", 1, 0, 0,
     }
   else if (SCM_CONTINUATIONP (stack))
     {
-      offset = ((SCM_STACKITEM *) ((char *) SCM_CONTREGS (stack) + sizeof (scm_t_contregs))
-               - SCM_BASE (stack));
-#ifndef STACK_GROWS_UP
-      offset += SCM_CONTINUATION_LENGTH (stack);
-#endif
-      dframe = RELOC_FRAME (SCM_DFRAME (stack), offset);
+      scm_t_contregs *cont = SCM_CONTREGS (stack);
+      offset = cont->offset;
+      dframe = RELOC_FRAME (cont->dframe, offset);
     }
   else if (SCM_STACKP (stack))
     {
@@ -565,7 +621,7 @@ SCM_DEFINE (scm_stack_id, "stack-id", 1, 0, 0,
   while (dframe && !SCM_VOIDFRAMEP (*dframe))
     dframe = RELOC_FRAME (dframe->prev, offset);
   if (dframe && SCM_VOIDFRAMEP (*dframe))
-    return dframe->vect[0].id;
+    return RELOC_INFO (dframe->vect, offset)[0].id;
   return SCM_BOOL_F;
 }
 #undef FUNC_NAME
@@ -578,10 +634,7 @@ SCM_DEFINE (scm_stack_ref, "stack-ref", 2, 0, 0,
   unsigned long int c_index;
 
   SCM_VALIDATE_STACK (1, stack);
-  SCM_VALIDATE_INUM (2, index);
-  SCM_ASSERT_RANGE (1, index, SCM_INUM (index) >= 0);
-  c_index = SCM_INUM (index);
-  SCM_ASSERT_RANGE (1, index, c_index < SCM_STACK_LENGTH (stack));
+  c_index = scm_to_unsigned_integer (index, 0, SCM_STACK_LENGTH(stack)-1);
   return scm_cons (stack, index);
 }
 #undef FUNC_NAME
@@ -592,7 +645,7 @@ SCM_DEFINE (scm_stack_length, "stack-length", 1, 0, 0,
 #define FUNC_NAME s_scm_stack_length
 {
   SCM_VALIDATE_STACK (1, stack);
-  return SCM_MAKINUM (SCM_STACK_LENGTH (stack));
+  return scm_from_int (SCM_STACK_LENGTH (stack));
 }
 #undef FUNC_NAME
 
@@ -604,15 +657,14 @@ SCM_DEFINE (scm_frame_p, "frame?", 1, 0, 0,
            "Return @code{#t} if @var{obj} is a stack frame.")
 #define FUNC_NAME s_scm_frame_p
 {
-  return SCM_BOOL(SCM_FRAMEP (obj));
+  return scm_from_bool(SCM_FRAMEP (obj));
 }
 #undef FUNC_NAME
 
 SCM_DEFINE (scm_last_stack_frame, "last-stack-frame", 1, 0, 0, 
            (SCM obj),
-           "Return a stack which consists of a single frame, which is the\n"
-           "last stack frame for @var{obj}. @var{obj} must be either a\n"
-           "debug object or a continuation.")
+           "Return the last (innermost) frame of @var{obj}, which must be\n"
+           "either a debug object or a continuation.")
 #define FUNC_NAME s_scm_last_stack_frame
 {
   scm_t_debug_frame *dframe;
@@ -625,12 +677,9 @@ SCM_DEFINE (scm_last_stack_frame, "last-stack-frame", 1, 0, 0,
     }
   else if (SCM_CONTINUATIONP (obj))
     {
-      offset = ((SCM_STACKITEM *) ((char *) SCM_CONTREGS (obj) + sizeof (scm_t_contregs))
-               - SCM_BASE (obj));
-#ifndef STACK_GROWS_UP
-      offset += SCM_CONTINUATION_LENGTH (obj);
-#endif
-      dframe = RELOC_FRAME (SCM_DFRAME (obj), offset);
+      scm_t_contregs *cont = SCM_CONTREGS (obj);
+      offset = cont->offset;
+      dframe = RELOC_FRAME (cont->dframe, offset);
     }
   else
     {
@@ -641,7 +690,7 @@ SCM_DEFINE (scm_last_stack_frame, "last-stack-frame", 1, 0, 0,
   if (!dframe || SCM_VOIDFRAMEP (*dframe))
     return SCM_BOOL_F;
 
-  stack = scm_make_struct (scm_stack_type, SCM_MAKINUM (SCM_FRAME_N_SLOTS),
+  stack = scm_make_struct (scm_stack_type, scm_from_int (SCM_FRAME_N_SLOTS),
                           SCM_EOL);
   SCM_STACK (stack) -> length = 1;
   SCM_STACK (stack) -> frames = &SCM_STACK (stack) -> tail[0];
@@ -658,7 +707,7 @@ SCM_DEFINE (scm_frame_number, "frame-number", 1, 0, 0,
 #define FUNC_NAME s_scm_frame_number
 {
   SCM_VALIDATE_FRAME (1, frame);
-  return SCM_MAKINUM (SCM_FRAME_NUMBER (frame));
+  return scm_from_int (SCM_FRAME_NUMBER (frame));
 }
 #undef FUNC_NAME
 
@@ -703,11 +752,11 @@ SCM_DEFINE (scm_frame_previous, "frame-previous", 1, 0, 0,
 {
   unsigned long int n;
   SCM_VALIDATE_FRAME (1, frame);
-  n = SCM_INUM (SCM_CDR (frame)) + 1;
+  n = scm_to_ulong (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));
+    return scm_cons (SCM_CAR (frame), scm_from_ulong (n));
 }
 #undef FUNC_NAME
 
@@ -719,11 +768,11 @@ SCM_DEFINE (scm_frame_next, "frame-next", 1, 0, 0,
 {
   unsigned long int n;
   SCM_VALIDATE_FRAME (1, frame);
-  n = SCM_INUM (SCM_CDR (frame));
+  n = scm_to_ulong (SCM_CDR (frame));
   if (n == 0)
     return SCM_BOOL_F;
   else
-    return scm_cons (SCM_CAR (frame), SCM_MAKINUM (n - 1));
+    return scm_cons (SCM_CAR (frame), scm_from_ulong (n - 1));
 }
 #undef FUNC_NAME
 
@@ -733,7 +782,7 @@ SCM_DEFINE (scm_frame_real_p, "frame-real?", 1, 0, 0,
 #define FUNC_NAME s_scm_frame_real_p
 {
   SCM_VALIDATE_FRAME (1, frame);
-  return SCM_BOOL(SCM_FRAME_REAL_P (frame));
+  return scm_from_bool(SCM_FRAME_REAL_P (frame));
 }
 #undef FUNC_NAME
 
@@ -743,7 +792,7 @@ SCM_DEFINE (scm_frame_procedure_p, "frame-procedure?", 1, 0, 0,
 #define FUNC_NAME s_scm_frame_procedure_p
 {
   SCM_VALIDATE_FRAME (1, frame);
-  return SCM_BOOL(SCM_FRAME_PROC_P (frame));
+  return scm_from_bool(SCM_FRAME_PROC_P (frame));
 }
 #undef FUNC_NAME
 
@@ -753,7 +802,7 @@ SCM_DEFINE (scm_frame_evaluating_args_p, "frame-evaluating-args?", 1, 0, 0,
 #define FUNC_NAME s_scm_frame_evaluating_args_p
 {
   SCM_VALIDATE_FRAME (1, frame);
-  return SCM_BOOL(SCM_FRAME_EVAL_ARGS_P (frame));
+  return scm_from_bool(SCM_FRAME_EVAL_ARGS_P (frame));
 }
 #undef FUNC_NAME
 
@@ -763,7 +812,7 @@ SCM_DEFINE (scm_frame_overflow_p, "frame-overflow?", 1, 0, 0,
 #define FUNC_NAME s_scm_frame_overflow_p
 {
   SCM_VALIDATE_FRAME (1, frame);
-  return SCM_BOOL(SCM_FRAME_OVERFLOW_P (frame));
+  return scm_from_bool(SCM_FRAME_OVERFLOW_P (frame));
 }
 #undef FUNC_NAME
 
@@ -772,15 +821,12 @@ SCM_DEFINE (scm_frame_overflow_p, "frame-overflow?", 1, 0, 0,
 void
 scm_init_stacks ()
 {
-  SCM vtable;
-  SCM stack_layout
-    = scm_make_struct_layout (scm_makfrom0str (SCM_STACK_LAYOUT));
-  vtable = scm_make_vtable_vtable (scm_nullstr, SCM_INUM0, SCM_EOL);
-  scm_stack_type
-    = scm_permanent_object (scm_make_struct (vtable, SCM_INUM0,
-                                            scm_cons (stack_layout,
-                                                      SCM_EOL)));
-  scm_set_struct_vtable_name_x (scm_stack_type, scm_str2symbol ("stack"));
+  scm_stack_type =
+    scm_permanent_object
+    (scm_make_vtable (scm_from_locale_string (SCM_STACK_LAYOUT),
+                      SCM_UNDEFINED));
+  scm_set_struct_vtable_name_x (scm_stack_type,
+                               scm_from_locale_symbol ("stack"));
 #include "libguile/stacks.x"
 }