emacs-devel
[Top][All Lists]
Advanced

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

Re: [PATCH] Make purecopy create hash tables properly


From: Stefan Monnier
Subject: Re: [PATCH] Make purecopy create hash tables properly
Date: Fri, 27 Jan 2017 18:10:24 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.0.50 (gnu/linux)

> -  else if (COMPILEDP (obj) || VECTORP (obj) || HASH_TABLE_P (obj))
> +  else if (HASH_TABLE_P (obj)) {
> +    struct Lisp_Hash_Table *h = make_pure_hash_table(XHASH_TABLE(obj));
> +    XSET_HASH_TABLE(obj, h);
> +  }
> +  else if (COMPILEDP (obj) || VECTORP (obj))
>      {
>        struct Lisp_Vector *objp = XVECTOR (obj);
>        ptrdiff_t nbytes = vector_nbytes (objp);

Oh, indeed, I see what was the problem:
We relied on the generic vector-copy code for the hash-tables, whereas
those do not only contain Lisp_Object fields (and they also contain some
Lisp_Object fields which are beyond the part copied by the generic
code).

So another way to fix the code would something like the patch below
(100% untested).

Whichever option you take, please pay attention to `next_weak` because
in your patch, you'll end up purecopying some of the other weak
hash-tables but you won't register this one as a weak hash table, so it
will lead to serious problems.


        Stefan


diff --git a/src/alloc.c b/src/alloc.c
index 1a6d4e2d56..c15bbf3a2f 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -5519,6 +5519,18 @@ purecopy (Lisp_Object obj)
       memcpy (vec, objp, nbytes);
       for (i = 0; i < size; i++)
        vec->contents[i] = purecopy (vec->contents[i]);
+      if (HASH_TABLE_P (obj))
+        {
+          struct Lisp_Hash_Table *old = (struct Lisp_Hash_Table *) objp;
+          struct Lisp_Hash_Table *new = (struct Lisp_Hash_Table *) vec;
+          new->count = new->count;
+          new->key_and_value = purecopy (old->key_and_value);
+          new->test = old->test;
+          new->next_weak = old->next_weak
+          if (!NILP (old->weak))
+            /* Insert ourselves in the list of weak hash tables.  */
+            old->next_weak = new;
+        }
       XSETVECTOR (obj, vec);
     }
   else if (SYMBOLP (obj))




reply via email to

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