Merge commit '7337d56d5714227865aeca2b40b6bd97cce296d2' into boehm-demers-weiser-gc
authorLudovic Courtès <ludo@gnu.org>
Wed, 10 Sep 2008 20:44:31 +0000 (22:44 +0200)
committerLudovic Courtès <ludo@gnu.org>
Wed, 10 Sep 2008 20:44:31 +0000 (22:44 +0200)
Conflicts:
libguile/struct.c

12 files changed:
1  2 
configure.in
libguile/Makefile.am
libguile/eval.c
libguile/fluids.c
libguile/gdbint.c
libguile/goops.c
libguile/modules.c
libguile/numbers.c
libguile/ports.c
libguile/struct.c
libguile/struct.h
test-suite/Makefile.am

diff --cc configure.in
Simple merge
Simple merge
diff --cc libguile/eval.c
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -385,13 -427,31 +385,33 @@@ SCM_DEFINE (scm_make_struct, "make-stru
    SCM_VALIDATE_VTABLE (1, vtable);
    SCM_VALIDATE_REST_ARGUMENT (init);
  
 -  layout = SCM_PACK (SCM_STRUCT_DATA (vtable) [scm_vtable_index_layout]);
 +  c_vtable = SCM_STRUCT_DATA (vtable);
 +
 +  layout = SCM_PACK (c_vtable [scm_vtable_index_layout]);
    basic_size = scm_i_symbol_length (layout) / 2;
    tail_elts = scm_to_size_t (tail_array_size);
+   /* A tail array is only allowed if the layout fields string ends in "R",
+      "W" or "O". */
+   if (tail_elts != 0)
+     {
+       SCM layout_str, last_char;
+       
+       if (basic_size == 0)
+         {
+         bad_tail: 
+           SCM_MISC_ERROR ("tail array not allowed unless layout ends R, W, or O", SCM_EOL);
+         }
+       layout_str = scm_symbol_to_string (layout);
+       last_char = scm_string_ref (layout_str,
+                                   scm_from_size_t (2 * basic_size - 1));
+       if (! SCM_LAYOUT_TAILP (SCM_CHAR (last_char)))
+         goto bad_tail;
+     }
+     
    SCM_CRITICAL_SECTION_START;
 -  if (SCM_STRUCT_DATA (vtable)[scm_struct_i_flags] & SCM_STRUCTF_ENTITY)
 +  if (c_vtable[scm_struct_i_flags] & SCM_STRUCTF_ENTITY)
      {
        data = scm_alloc_struct (basic_size + tail_elts,
                               scm_struct_entity_n_extra_words,
      data = scm_alloc_struct (basic_size + tail_elts,
                             scm_struct_n_extra_words,
                             "struct");
 -  handle = scm_double_cell ((((scm_t_bits) SCM_STRUCT_DATA (vtable))
 +  handle = scm_double_cell ((((scm_t_bits) c_vtable)
                             + scm_tc3_struct),
                            (scm_t_bits) data, 0, 0);
-   scm_struct_init (handle, layout, data, tail_elts, init);
 +
 +  if (c_vtable[scm_struct_i_free])
 +    {
 +      /* Register a finalizer for the newly created instance.  */
 +      GC_finalization_proc prev_finalizer;
 +      GC_PTR prev_finalizer_data;
 +      scm_t_struct_free free_struct =
 +      (scm_t_struct_free)c_vtable[scm_struct_i_free];
 +
 +      GC_REGISTER_FINALIZER_NO_ORDER (SCM2PTR (handle),
 +                                    struct_finalizer_trampoline,
 +                                    free_struct,
 +                                    &prev_finalizer,
 +                                    &prev_finalizer_data);
 +    }
 +
    SCM_CRITICAL_SECTION_END;
+   /* In guile 1.8.1 and earlier, the SCM_CRITICAL_SECTION_END above covered
+      also the following scm_struct_init.  But that meant if scm_struct_init
+      finds an invalid type for a "u" field then there's an error throw in a
+      critical section, which results in an abort().  Not sure if we need any
+      protection across scm_struct_init.  The data array contains garbage at
+      this point, but until we return it's not visible to anyone except
+      `gc'.  */
+   scm_struct_init (handle, layout, data, tail_elts, init);
    return handle;
  }
  #undef FUNC_NAME
Simple merge
Simple merge