emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master e6b5cd0: Avoid SAFE_ALLOCA in Fstring, Funibyte_string


From: Paul Eggert
Subject: master e6b5cd0: Avoid SAFE_ALLOCA in Fstring, Funibyte_string
Date: Sat, 4 Apr 2020 21:27:16 -0400 (EDT)

branch: master
commit e6b5cd0edacb5663859f6a6f93d82a0a4d486e83
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    Avoid SAFE_ALLOCA in Fstring, Funibyte_string
    
    * src/character.c (Fstring, Funibyte_string):
    Redo to avoid the need for a temporary array allocation
    and then a copying from that array to the destination.
---
 src/character.c | 39 +++++++++++++++------------------------
 1 file changed, 15 insertions(+), 24 deletions(-)

diff --git a/src/character.c b/src/character.c
index d71cb3f..a566cac 100644
--- a/src/character.c
+++ b/src/character.c
@@ -849,24 +849,22 @@ Concatenate all the argument characters and make the 
result a string.
 usage: (string &rest CHARACTERS)  */)
   (ptrdiff_t n, Lisp_Object *args)
 {
-  ptrdiff_t i;
-  int c;
-  unsigned char *buf, *p;
-  Lisp_Object str;
-  USE_SAFE_ALLOCA;
-
-  SAFE_NALLOCA (buf, MAX_MULTIBYTE_LENGTH, n);
-  p = buf;
-
-  for (i = 0; i < n; i++)
+  ptrdiff_t nbytes = 0;
+  for (ptrdiff_t i = 0; i < n; i++)
     {
       CHECK_CHARACTER (args[i]);
-      c = XFIXNUM (args[i]);
+      nbytes += CHAR_BYTES (XFIXNUM (args[i]));
+    }
+  if (nbytes == n)
+    return Funibyte_string (n, args);
+  Lisp_Object str = make_uninit_multibyte_string (n, nbytes);
+  unsigned char *p = SDATA (str);
+  for (ptrdiff_t i = 0; i < n; i++)
+    {
+      eassume (CHARACTERP (args[i]));
+      int c = XFIXNUM (args[i]);
       p += CHAR_STRING (c, p);
     }
-
-  str = make_string_from_bytes ((char *) buf, n, p - buf);
-  SAFE_FREE ();
   return str;
 }
 
@@ -875,20 +873,13 @@ DEFUN ("unibyte-string", Funibyte_string, 
Sunibyte_string, 0, MANY, 0,
 usage: (unibyte-string &rest BYTES)  */)
   (ptrdiff_t n, Lisp_Object *args)
 {
-  ptrdiff_t i;
-  Lisp_Object str;
-  USE_SAFE_ALLOCA;
-  unsigned char *buf = SAFE_ALLOCA (n);
-  unsigned char *p = buf;
-
-  for (i = 0; i < n; i++)
+  Lisp_Object str = make_uninit_string (n);
+  unsigned char *p = SDATA (str);
+  for (ptrdiff_t i = 0; i < n; i++)
     {
       CHECK_RANGED_INTEGER (args[i], 0, 255);
       *p++ = XFIXNUM (args[i]);
     }
-
-  str = make_string_from_bytes ((char *) buf, n, p - buf);
-  SAFE_FREE ();
   return str;
 }
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]