Merge branch 'master' into boehm-demers-weiser-gc
[bpt/guile.git] / libguile / strings.c
index 03fb4b4..8aa1e66 100644 (file)
@@ -34,7 +34,6 @@
 #include "libguile/strings.h"
 #include "libguile/deprecation.h"
 #include "libguile/validate.h"
-#include "libguile/dynwind.h"
 
 \f
 
@@ -136,7 +135,7 @@ make_stringbuf (size_t len)
     }
   else
     {
-      char *mem = scm_gc_malloc (len+1, "string");
+      char *mem = scm_gc_malloc_pointerless (len + 1, "string");
       mem[len] = '\0';
       return scm_double_cell (STRINGBUF_TAG, (scm_t_bits) mem,
                              (scm_t_bits) len, (scm_t_bits) 0);
@@ -173,28 +172,6 @@ scm_i_take_stringbufn (char *str, size_t len)
                          (scm_t_bits) len, (scm_t_bits) 0);
 }
 
-SCM
-scm_i_stringbuf_mark (SCM buf)
-{
-  return SCM_BOOL_F;
-}
-
-void
-scm_i_stringbuf_free (SCM buf)
-{
-  if (!STRINGBUF_INLINE (buf))
-    {
-      if (!STRINGBUF_WIDE (buf))
-        scm_gc_free (STRINGBUF_OUTLINE_CHARS (buf),
-                     STRINGBUF_OUTLINE_LENGTH (buf) + 1, "string");
-      else
-        scm_gc_free (STRINGBUF_OUTLINE_CHARS (buf),
-                     sizeof (scm_t_wchar) * (STRINGBUF_OUTLINE_LENGTH (buf) 
-                                             + 1), "string");
-    }
-
-}
-
 /* Convert a stringbuf containing 8-bit Latin-1-encoded characters to
    one containing 32-bit UCS-4-encoded characters.  */
 static void
@@ -425,20 +402,7 @@ scm_c_substring_shared (SCM str, size_t start, size_t end)
   return scm_i_substring_shared (str, start, end);
 }
 
-SCM
-scm_i_string_mark (SCM str)
-{
-  if (IS_SH_STRING (str))
-    return SH_STRING_STRING (str);
-  else
-    return STRING_STRINGBUF (str);
-}
-
-void
-scm_i_string_free (SCM str)
-{
-}
-
+\f
 /* Internal accessors
  */
 
@@ -528,11 +492,18 @@ scm_i_string_start_writing (SCM orig_str)
                    (scm_t_uint32 *) (STRINGBUF_WIDE_CHARS (buf) 
                                      + STRING_START (str)), len);
         }
-      scm_i_thread_put_to_sleep ();
+
       SET_STRING_STRINGBUF (str, new_buf);
       start -= STRING_START (str);
+
+      /* FIXME: The following operations are not atomic, so other threads
+        looking at STR may see an inconsistent state.  Nevertheless it can't
+        hurt much since (i) accessing STR while it is being mutated can't
+        yield a crash, and (ii) concurrent accesses to STR should be
+        protected by a mutex at the application level.  The latter may not
+        apply when STR != ORIG_STR, though.  */
       SET_STRING_START (str, 0);
-      scm_i_thread_wake_up ();
+      SET_STRING_STRINGBUF (str, new_buf);
 
       buf = new_buf;
 
@@ -670,8 +641,8 @@ scm_i_c_make_symbol (const char *name, size_t len,
   SCM buf = make_stringbuf (len);
   memcpy (STRINGBUF_CHARS (buf), name, len);
 
-  return scm_double_cell (scm_tc7_symbol | flags, SCM_UNPACK (buf),
-                         (scm_t_bits) hash, SCM_UNPACK (props));
+  return scm_immutable_double_cell (scm_tc7_symbol | flags, SCM_UNPACK (buf),
+                                   (scm_t_bits) hash, SCM_UNPACK (props));
 }
 
 /* Return a new symbol that uses the LEN bytes pointed to by NAME as its
@@ -745,18 +716,6 @@ scm_i_symbol_wide_chars (SCM sym)
                     scm_list_1 (sym));
 }
 
-SCM
-scm_i_symbol_mark (SCM sym)
-{
-  scm_gc_mark (SYMBOL_STRINGBUF (sym));
-  return SCM_CELL_OBJECT_3 (sym);
-}
-
-void
-scm_i_symbol_free (SCM sym)
-{
-}
-
 SCM
 scm_i_symbol_substring (SCM sym, size_t start, size_t end)
 {
@@ -1592,6 +1551,7 @@ scm_makfromstrs (int argc, char **argv)
 
 char **
 scm_i_allocate_string_pointers (SCM list)
+#define FUNC_NAME "scm_i_allocate_string_pointers"
 {
   char **result;
   int len = scm_ilength (list);
@@ -1600,34 +1560,31 @@ scm_i_allocate_string_pointers (SCM list)
   if (len < 0)
     scm_wrong_type_arg_msg (NULL, 0, list, "proper list");
 
-  scm_dynwind_begin (0);
-
-  result = (char **) scm_malloc ((len + 1) * sizeof (char *));
+  result = scm_gc_malloc ((len + 1) * sizeof (char *),
+                         "string pointers");
   result[len] = NULL;
-  scm_dynwind_unwind_handler (free, result, 0);
 
   /* The list might be have been modified in another thread, so
      we check LIST before each access.
    */
   for (i = 0; i < len && scm_is_pair (list); i++)
     {
-      result[i] = scm_to_locale_string (SCM_CAR (list));
+      SCM str;
+      size_t len;
+
+      str = SCM_CAR (list);
+      len = scm_c_string_length (str);
+
+      result[i] = scm_gc_malloc_pointerless (len + 1, "string pointers");
+      memcpy (result[i], scm_i_string_chars (str), len);
+      result[i][len] = '\0';
+
       list = SCM_CDR (list);
     }
 
-  scm_dynwind_end ();
   return result;
 }
-
-void
-scm_i_free_string_pointers (char **pointers)
-{
-  int i;
-  
-  for (i = 0; pointers[i]; i++)
-    free (pointers[i]);
-  free (pointers);
-}
+#undef FUNC_NAME
 
 void
 scm_i_get_substring_spec (size_t len,