Merge remote-tracking branch 'origin/stable-2.0'
[bpt/guile.git] / libguile / struct.c
index 4a2a9d7..12a8842 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996,1997,1998,1999,2000,2001, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+/* Copyright (C) 1996,1997,1998,1999,2000,2001, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012 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
 #include <alloca.h>
 #include <assert.h>
 
+#define SCM_BUILDING_DEPRECATED_CODE
+
 #include "libguile/_scm.h"
 #include "libguile/async.h"
 #include "libguile/chars.h"
 #include "libguile/eval.h"
 #include "libguile/alist.h"
-#include "libguile/weaks.h"
 #include "libguile/hashtab.h"
 #include "libguile/ports.h"
 #include "libguile/strings.h"
@@ -443,16 +444,8 @@ scm_i_alloc_struct (scm_t_bits *vtable_data, int n_words)
 
   /* vtable_data can be null when making a vtable vtable */
   if (vtable_data && vtable_data[scm_vtable_index_instance_finalize])
-    {
-      /* Register a finalizer for the newly created instance.  */
-      GC_finalization_proc prev_finalizer;
-      GC_PTR prev_finalizer_data;
-      GC_REGISTER_FINALIZER_NO_ORDER (SCM2PTR (ret),
-                                     struct_finalizer_trampoline,
-                                     NULL,
-                                     &prev_finalizer,
-                                     &prev_finalizer_data);
-    }
+    /* Register a finalizer for the newly created instance.  */
+    scm_i_set_finalizer (SCM2PTR (ret), struct_finalizer_trampoline, NULL);
 
   return ret;
 }
@@ -527,9 +520,9 @@ scm_c_make_struct (SCM vtable, size_t n_tail, size_t n_init, scm_t_bits init, ..
 SCM_DEFINE (scm_make_struct, "make-struct", 2, 0, 1, 
             (SCM vtable, SCM tail_array_size, SCM init),
            "Create a new structure.\n\n"
-           "@var{type} must be a vtable structure (@pxref{Vtables}).\n\n"
-           "@var{tail-elts} must be a non-negative integer.  If the layout\n"
-           "specification indicated by @var{type} includes a tail-array,\n"
+           "@var{vtable} must be a vtable structure (@pxref{Vtables}).\n\n"
+           "@var{tail_array_size} must be a non-negative integer.  If the layout\n"
+           "specification indicated by @var{vtable} includes a tail-array,\n"
            "this is the number of elements allocated to that array.\n\n"
            "The @var{init1}, @dots{} are optional arguments describing how\n"
            "successive fields of the structure should be initialized.  Only fields\n"
@@ -570,13 +563,14 @@ SCM_DEFINE (scm_make_struct, "make-struct", 2, 0, 1,
 
 
 
+#if SCM_ENABLE_DEPRECATED == 1
 SCM_DEFINE (scm_make_vtable_vtable, "make-vtable-vtable", 2, 0, 1,
             (SCM user_fields, SCM tail_array_size, SCM init),
            "Return a new, self-describing vtable structure.\n\n"
            "@var{user-fields} is a string describing user defined fields of the\n"
            "vtable beginning at index @code{vtable-offset-user}\n"
            "(see @code{make-struct-layout}).\n\n"
-           "@var{tail-size} specifies the size of the tail-array (if any) of\n"
+           "@var{tail_array_size} specifies the size of the tail-array (if any) of\n"
            "this vtable.\n\n"
            "@var{init1}, @dots{} are the optional initializers for the fields of\n"
            "the vtable.\n\n"
@@ -664,7 +658,38 @@ SCM_DEFINE (scm_make_vtable_vtable, "make-vtable-vtable", 2, 0, 1,
   return obj;
 }
 #undef FUNC_NAME
+#endif
+
+SCM
+scm_i_make_vtable_vtable (SCM user_fields)
+#define FUNC_NAME s_scm_make_vtable_vtable
+{
+  SCM fields, layout, obj;
+  size_t basic_size;
+  scm_t_bits v;
 
+  SCM_VALIDATE_STRING (1, user_fields);
+
+  fields = scm_string_append (scm_list_2 (required_vtable_fields,
+                                         user_fields));
+  layout = scm_make_struct_layout (fields);
+  if (!scm_is_valid_vtable_layout (layout))
+    SCM_MISC_ERROR ("invalid user fields", scm_list_1 (user_fields));
+
+  basic_size = scm_i_symbol_length (layout) / 2;
+
+  obj = scm_i_alloc_struct (NULL, basic_size);
+  /* Make it so that the vtable of OBJ is itself.  */
+  SCM_SET_CELL_WORD_0 (obj, (scm_t_bits) SCM_STRUCT_DATA (obj) | scm_tc3_struct);
+
+  v = SCM_UNPACK (layout);
+  scm_struct_init (obj, layout, 0, 1, &v);
+  SCM_SET_VTABLE_FLAGS (obj,
+                        SCM_VTABLE_FLAG_VTABLE | SCM_VTABLE_FLAG_VALIDATED);
+
+  return obj;
+}
+#undef FUNC_NAME
 
 SCM_DEFINE (scm_make_vtable, "make-vtable", 1, 1, 0,
             (SCM fields, SCM printer),
@@ -738,10 +763,15 @@ scm_i_struct_equalp (SCM s1, SCM s2)
 
 SCM_DEFINE (scm_struct_ref, "struct-ref", 2, 0, 0,
             (SCM handle, SCM pos),
-           "Access the @var{n}th field of @var{struct}.\n\n"
-           "If the field is of type 'p', then it can be set to an arbitrary value.\n\n"
-           "If the field is of type 'u', then it can only be set to a non-negative\n"
-           "integer value small enough to fit in one machine word.")
+           "Access the @var{pos}th field of struct associated with\n"
+           "@var{handle}.\n"
+           "\n"
+           "If the field is of type 'p', then it can be set to an arbitrary\n"
+           "value.\n"
+           "\n"
+           "If the field is of type 'u', then it can only be set to a\n"
+           "non-negative integer value small enough to fit in one machine\n"
+           "word.")
 #define FUNC_NAME s_scm_struct_ref
 {
   SCM vtable, answer = SCM_UNDEFINED;
@@ -910,7 +940,8 @@ SCM_DEFINE (scm_struct_set_x, "struct-set!", 3, 0, 0,
 
 SCM_DEFINE (scm_struct_vtable, "struct-vtable", 1, 0, 0, 
             (SCM handle),
-           "Return the vtable structure that describes the type of @var{struct}.")
+           "Return the vtable structure that describes the type of struct\n"
+           "associated with @var{handle}.")
 #define FUNC_NAME s_scm_struct_vtable
 {
   SCM_VALIDATE_STRUCT (1, handle);
@@ -982,22 +1013,22 @@ scm_print_struct (SCM exp, SCM port, scm_print_state *pstate)
     {
       SCM vtable = SCM_STRUCT_VTABLE (exp);
       SCM name = scm_struct_vtable_name (vtable);
-      scm_puts ("#<", port);
+      scm_puts_unlocked ("#<", port);
       if (scm_is_true (name))
        {
           scm_display (name, port);
-          scm_putc (' ', port);
+          scm_putc_unlocked (' ', port);
         }
       else
        {
           if (SCM_VTABLE_FLAG_IS_SET (vtable, SCM_VTABLE_FLAG_VTABLE))
-            scm_puts ("vtable:", port);
+            scm_puts_unlocked ("vtable:", port);
           else
-            scm_puts ("struct:", port);
+            scm_puts_unlocked ("struct:", port);
           scm_uintprint (SCM_UNPACK (vtable), 16, port);
-          scm_putc (' ', port);
+          scm_putc_unlocked (' ', port);
           scm_write (SCM_VTABLE_LAYOUT (vtable), port);
-          scm_putc (' ', port);
+          scm_putc_unlocked (' ', port);
         }
       scm_uintprint (SCM_UNPACK (exp), 16, port);
       /* hackety hack */
@@ -1005,19 +1036,19 @@ scm_print_struct (SCM exp, SCM port, scm_print_state *pstate)
         {
           if (scm_is_true (SCM_STRUCT_PROCEDURE (exp)))
             {
-              scm_puts (" proc: ", port);
+              scm_puts_unlocked (" proc: ", port);
               if (scm_is_true (scm_procedure_p (SCM_STRUCT_PROCEDURE (exp))))
                 scm_write (SCM_STRUCT_PROCEDURE (exp), port);
               else
-                scm_puts ("(not a procedure?)", port);
+                scm_puts_unlocked ("(not a procedure?)", port);
             }
           if (SCM_STRUCT_SETTER_P (exp))
             {
-              scm_puts (" setter: ", port);
+              scm_puts_unlocked (" setter: ", port);
               scm_write (SCM_STRUCT_SETTER (exp), port);
             }
         }
-      scm_putc ('>', port);
+      scm_putc_unlocked ('>', port);
     }
 }
 
@@ -1035,11 +1066,12 @@ scm_init_struct ()
   GC_REGISTER_DISPLACEMENT (2 * sizeof (scm_t_bits));
 
   required_vtable_fields = scm_from_locale_string (SCM_VTABLE_BASE_LAYOUT);
+  scm_c_define ("standard-vtable-fields", required_vtable_fields);
   required_applicable_fields = scm_from_locale_string (SCM_APPLICABLE_BASE_LAYOUT);
   required_applicable_with_setter_fields = scm_from_locale_string (SCM_APPLICABLE_WITH_SETTER_BASE_LAYOUT);
 
-  scm_standard_vtable_vtable =
-    scm_make_vtable_vtable (scm_nullstr, SCM_INUM0, SCM_EOL);
+  scm_standard_vtable_vtable = scm_i_make_vtable_vtable (scm_nullstr);
+  scm_c_define ("<standard-vtable>", scm_standard_vtable_vtable);
 
   scm_applicable_struct_vtable_vtable =
     scm_make_struct (scm_standard_vtable_vtable, SCM_INUM0,