]> git.eshelyaron.com Git - emacs.git/commitdiff
Use union for the payload of struct Lisp_Vector.
authorDmitry Antipov <dmantipov@yandex.ru>
Tue, 24 Sep 2013 06:43:20 +0000 (10:43 +0400)
committerDmitry Antipov <dmantipov@yandex.ru>
Tue, 24 Sep 2013 06:43:20 +0000 (10:43 +0400)
This helps to avoid a few glitches dictated by C's aliasing rules.
* lisp.h (struct Lisp_Vector): Use union for next and
contents member.  Adjust comment.  Change related users.
* alloc.c (next_in_free_list, set_next_in_free_list): Remove.
Related users changed.
* buffer.c, bytecode.c, ccl.c, character.h, chartab.c, composite.c:
* composite.h, disptab.h, fns.c, fontset.c, indent.c, keyboard.c:
* lread.c, msdos.c, process.c, w32menu.c, window.c, xdisp.c:
* xfaces.c, xfont.c, xmenu.c: Related users changed.

24 files changed:
src/ChangeLog
src/alloc.c
src/buffer.c
src/bytecode.c
src/ccl.c
src/character.h
src/chartab.c
src/composite.c
src/composite.h
src/disptab.h
src/fns.c
src/fontset.c
src/indent.c
src/keyboard.c
src/lisp.h
src/lread.c
src/msdos.c
src/process.c
src/w32menu.c
src/window.c
src/xdisp.c
src/xfaces.c
src/xfont.c
src/xmenu.c

index 28b4da176aee6d5fd9630d60badf69832057eaa6..a2eb39e7196af2e1addd8b19a7f1b64b2f74b625 100644 (file)
@@ -1,3 +1,16 @@
+2013-09-24  Dmitry Antipov  <dmantipov@yandex.ru>
+
+       Use union for the payload of struct Lisp_Vector.
+       This helps to avoid a few glitches dictated by C's aliasing rules.
+       * lisp.h (struct Lisp_Vector): Use union for next and
+       contents member.  Adjust comment.  Change related users.
+       * alloc.c (next_in_free_list, set_next_in_free_list): Remove.
+       Related users changed.
+       * buffer.c, bytecode.c, ccl.c, character.h, chartab.c, composite.c:
+       * composite.h, disptab.h, fns.c, fontset.c, indent.c, keyboard.c:
+       * lread.c, msdos.c, process.c, w32menu.c, window.c, xdisp.c:
+       * xfaces.c, xfont.c, xmenu.c: Related users changed.
+
 2013-09-24  Dmitry Antipov  <dmantipov@yandex.ru>
 
        Optimize glyph row clearing and copying routines.
index e380d66cb1b135ce695e5115a7e2679091bd6445..ca21ba2469bbf27a12d75a092ca477e130cee03b 100644 (file)
@@ -2647,22 +2647,6 @@ verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS));
 
 #define VINDEX(nbytes) (((nbytes) - VBLOCK_BYTES_MIN) / roundup_size)
 
-/* Get and set the next field in block-allocated vectorlike objects on
-   the free list.  Doing it this way respects C's aliasing rules.
-   We could instead make 'contents' a union, but that would mean
-   changes everywhere that the code uses 'contents'.  */
-static struct Lisp_Vector *
-next_in_free_list (struct Lisp_Vector *v)
-{
-  intptr_t i = XLI (v->contents[0]);
-  return (struct Lisp_Vector *) i;
-}
-static void
-set_next_in_free_list (struct Lisp_Vector *v, struct Lisp_Vector *next)
-{
-  v->contents[0] = XIL ((intptr_t) next);
-}
-
 /* Common shortcut to setup vector on a free list.  */
 
 #define SETUP_ON_FREE_LIST(v, nbytes, tmp)             \
@@ -2672,7 +2656,7 @@ set_next_in_free_list (struct Lisp_Vector *v, struct Lisp_Vector *next)
     eassert ((nbytes) % roundup_size == 0);            \
     (tmp) = VINDEX (nbytes);                           \
     eassert ((tmp) < VECTOR_MAX_FREE_LIST_INDEX);      \
-    set_next_in_free_list (v, vector_free_lists[tmp]); \
+    v->u.next = vector_free_lists[tmp];                        \
     vector_free_lists[tmp] = (v);                      \
     total_free_vector_slots += (nbytes) / word_size;   \
   } while (0)
@@ -2769,7 +2753,7 @@ allocate_vector_from_block (size_t nbytes)
   if (vector_free_lists[index])
     {
       vector = vector_free_lists[index];
-      vector_free_lists[index] = next_in_free_list (vector);
+      vector_free_lists[index] = vector->u.next;
       total_free_vector_slots -= nbytes / word_size;
       return vector;
     }
@@ -2783,7 +2767,7 @@ allocate_vector_from_block (size_t nbytes)
       {
        /* This vector is larger than requested.  */
        vector = vector_free_lists[index];
-       vector_free_lists[index] = next_in_free_list (vector);
+       vector_free_lists[index] = vector->u.next;
        total_free_vector_slots -= nbytes / word_size;
 
        /* Excess bytes are used for the smaller vector,
@@ -2981,7 +2965,7 @@ allocate_vectorlike (ptrdiff_t len)
       else
        {
          struct large_vector *lv
-           = lisp_malloc ((offsetof (struct large_vector, v.contents)
+           = lisp_malloc ((offsetof (struct large_vector, v.u.contents)
                            + len * word_size),
                           MEM_TYPE_VECTORLIKE);
          lv->next.vector = large_vectors;
@@ -3035,7 +3019,7 @@ allocate_pseudovector (int memlen, int lisplen, enum pvec_type tag)
 
   /* Only the first lisplen slots will be traced normally by the GC.  */
   for (i = 0; i < lisplen; ++i)
-    v->contents[i] = Qnil;
+    v->u.contents[i] = Qnil;
 
   XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen);
   return v;
@@ -3123,7 +3107,7 @@ See also the function `vector'.  */)
   p = allocate_vector (XFASTINT (length));
   sizei = XFASTINT (length);
   for (i = 0; i < sizei; i++)
-    p->contents[i] = init;
+    p->u.contents[i] = init;
 
   XSETVECTOR (vector, p);
   return vector;
@@ -3141,21 +3125,21 @@ usage: (vector &rest OBJECTS)  */)
   register struct Lisp_Vector *p = XVECTOR (val);
 
   for (i = 0; i < nargs; i++)
-    p->contents[i] = args[i];
+    p->u.contents[i] = args[i];
   return val;
 }
 
 void
 make_byte_code (struct Lisp_Vector *v)
 {
-  if (v->header.size > 1 && STRINGP (v->contents[1])
-      && STRING_MULTIBYTE (v->contents[1]))
+  if (v->header.size > 1 && STRINGP (v->u.contents[1])
+      && STRING_MULTIBYTE (v->u.contents[1]))
     /* BYTECODE-STRING must have been produced by Emacs 20.2 or the
        earlier because they produced a raw 8-bit string for byte-code
        and now such a byte-code string is loaded as multibyte while
        raw 8-bit characters converted to multibyte form.  Thus, now we
        must convert them back to the original unibyte form.  */
-    v->contents[1] = Fstring_as_unibyte (v->contents[1]);
+    v->u.contents[1] = Fstring_as_unibyte (v->u.contents[1]);
   XSETPVECTYPE (v, PVEC_COMPILED);
 }
 
@@ -3190,7 +3174,7 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT
      to be setcar'd).  */
 
   for (i = 0; i < nargs; i++)
-    p->contents[i] = args[i];
+    p->u.contents[i] = args[i];
   make_byte_code (p);
   XSETCOMPILED (val, p);
   return val;
@@ -5183,7 +5167,7 @@ Does not copy symbols.  Copies strings without text properties.  */)
        size &= PSEUDOVECTOR_SIZE_MASK;
       vec = XVECTOR (make_pure_vector (size));
       for (i = 0; i < size; i++)
-       vec->contents[i] = Fpurecopy (AREF (obj, i));
+       vec->u.contents[i] = Fpurecopy (AREF (obj, i));
       if (COMPILEDP (obj))
        {
          XSETPVECTYPE (vec, PVEC_COMPILED);
@@ -5674,7 +5658,7 @@ mark_vectorlike (struct Lisp_Vector *ptr)
      The distinction is used e.g. by Lisp_Process which places extra
      non-Lisp_Object fields at the end of the structure...  */
   for (i = 0; i < size; i++) /* ...and then mark its elements.  */
-    mark_object (ptr->contents[i]);
+    mark_object (ptr->u.contents[i]);
 }
 
 /* Like mark_vectorlike but optimized for char-tables (and
@@ -5691,7 +5675,7 @@ mark_char_table (struct Lisp_Vector *ptr)
   VECTOR_MARK (ptr);
   for (i = 0; i < size; i++)
     {
-      Lisp_Object val = ptr->contents[i];
+      Lisp_Object val = ptr->u.contents[i];
 
       if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->gcmarkbit))
        continue;
@@ -5896,10 +5880,10 @@ mark_object (Lisp_Object arg)
              VECTOR_MARK (ptr);
              for (i = 0; i < size; i++)
                if (i != COMPILED_CONSTANTS)
-                 mark_object (ptr->contents[i]);
+                 mark_object (ptr->u.contents[i]);
              if (size > COMPILED_CONSTANTS)
                {
-                 obj = ptr->contents[COMPILED_CONSTANTS];
+                 obj = ptr->u.contents[COMPILED_CONSTANTS];
                  goto loop;
                }
            }
index 815f3926c554157810e3f054bf22ac9926981a6d..1570f3831ac63aa968bbc8a86c98813ccf50e493 100644 (file)
@@ -4534,7 +4534,7 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
     Lisp_Object *copy = alloca (size * sizeof *copy);
     ptrdiff_t i;
 
-    memcpy (copy, XVECTOR (last_overlay_modification_hooks)->contents,
+    memcpy (copy, XVECTOR (last_overlay_modification_hooks)->u.contents,
            size * word_size);
     gcpro1.var = copy;
     gcpro1.nvars = size;
index 3ac8b452fbe93f0910179294b35301c0c65c4643..23e5082663381c294fb7632de43494dcaf9aa0dd 100644 (file)
@@ -536,7 +536,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
 #ifdef BYTE_CODE_SAFE
   bytestr_length = SBYTES (bytestr);
 #endif
-  vectorp = XVECTOR (vector)->contents;
+  vectorp = XVECTOR (vector)->u.contents;
 
   stack.byte_string = bytestr;
   stack.pc = stack.byte_string_start = SDATA (bytestr);
index 8fec18296a66f27c68bf43c8c280755ef029da9b..d1783c25718bd4fd4d2df318af757fb247f80526 100644 (file)
--- a/src/ccl.c
+++ b/src/ccl.c
@@ -1094,7 +1094,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
            ccl_prog_stack_struct[stack_idx].ic = ic;
            ccl_prog_stack_struct[stack_idx].eof_ic = eof_ic;
            stack_idx++;
-           ccl_prog = XVECTOR (AREF (slot, 1))->contents;
+           ccl_prog = XVECTOR (AREF (slot, 1))->u.contents;
            ic = CCL_HEADER_MAIN;
            eof_ic = XFASTINT (ccl_prog[CCL_HEADER_EOF]);
          }
@@ -1936,9 +1936,9 @@ setup_ccl_program (struct ccl_program *ccl, Lisp_Object ccl_prog)
        return -1;
       vp = XVECTOR (ccl_prog);
       ccl->size = vp->header.size;
-      ccl->prog = vp->contents;
-      ccl->eof_ic = XINT (vp->contents[CCL_HEADER_EOF]);
-      ccl->buf_magnification = XINT (vp->contents[CCL_HEADER_BUF_MAG]);
+      ccl->prog = vp->u.contents;
+      ccl->eof_ic = XINT (vp->u.contents[CCL_HEADER_EOF]);
+      ccl->buf_magnification = XINT (vp->u.contents[CCL_HEADER_BUF_MAG]);
       if (ccl->idx >= 0)
        {
          Lisp_Object slot;
index cb03cb3994784f54a31f943bab76ab146073ba84..d1b781caa53b693b8fe416ae46053204fc54be6b 100644 (file)
@@ -677,7 +677,7 @@ extern Lisp_Object string_escape_byte8 (Lisp_Object);
 
 /* Return a translation table of id number ID.  */
 #define GET_TRANSLATION_TABLE(id) \
-  (XCDR(XVECTOR(Vtranslation_table_vector)->contents[(id)]))
+  (XCDR (XVECTOR (Vtranslation_table_vector)->u.contents[(id)]))
 
 INLINE_HEADER_END
 
index b7b9590a5382f34bba86b1e3f8b503f3a1dce292..089c4254da63b8c22f5ab51b84542c6488ac1f01 100644 (file)
@@ -1258,7 +1258,7 @@ uniprop_encode_value_character (Lisp_Object table, Lisp_Object value)
 static Lisp_Object
 uniprop_encode_value_run_length (Lisp_Object table, Lisp_Object value)
 {
-  Lisp_Object *value_table = XVECTOR (XCHAR_TABLE (table)->extras[4])->contents;
+  Lisp_Object *value_table = XVECTOR (XCHAR_TABLE (table)->extras[4])->u.contents;
   int i, size = ASIZE (XCHAR_TABLE (table)->extras[4]);
 
   for (i = 0; i < size; i++)
@@ -1276,7 +1276,7 @@ uniprop_encode_value_run_length (Lisp_Object table, Lisp_Object value)
 static Lisp_Object
 uniprop_encode_value_numeric (Lisp_Object table, Lisp_Object value)
 {
-  Lisp_Object *value_table = XVECTOR (XCHAR_TABLE (table)->extras[4])->contents;
+  Lisp_Object *value_table = XVECTOR (XCHAR_TABLE (table)->extras[4])->u.contents;
   int i, size = ASIZE (XCHAR_TABLE (table)->extras[4]);
 
   CHECK_NUMBER (value);
index 47cac7150861216c693a063da1783c8e63eb2f41..4f125522e38fa08d40f9a80be1bc2881b4a81cf8 100644 (file)
@@ -266,7 +266,7 @@ get_composition_id (ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t nchars,
     composition_table = xpalloc (composition_table, &composition_table_size,
                                 1, -1, sizeof *composition_table);
 
-  key_contents = XVECTOR (key)->contents;
+  key_contents = XVECTOR (key)->u.contents;
 
   /* Check if the contents of COMPONENTS are valid if COMPONENTS is a
      vector or a list.  It should be a sequence of:
index 9026d03f7b6d6db2caf3ad176e0fc2f1e67c4ea8..b3ea5cd1ed83d85661004a88f9683d3aaf9ac833 100644 (file)
@@ -88,8 +88,8 @@ composition_registered_p (Lisp_Object prop)
 #define COMPOSITION_GLYPH(cmp, n)                                      \
   XINT (XVECTOR (XVECTOR (XHASH_TABLE (composition_hash_table)         \
                          ->key_and_value)                              \
-                ->contents[cmp->hash_index * 2])                       \
-       ->contents[cmp->method == COMPOSITION_WITH_RULE_ALTCHARS        \
+                ->u.contents[cmp->hash_index * 2])                     \
+       ->u.contents[cmp->method == COMPOSITION_WITH_RULE_ALTCHARS      \
                  ? (n) * 2 : (n)])
 
 /* Return the encoded composition rule to compose the Nth glyph of
@@ -98,8 +98,8 @@ composition_registered_p (Lisp_Object prop)
 #define COMPOSITION_RULE(cmp, n)                               \
   XINT (XVECTOR (XVECTOR (XHASH_TABLE (composition_hash_table) \
                          ->key_and_value)                      \
-                ->contents[cmp->hash_index * 2])               \
-       ->contents[(n) * 2 - 1])
+                ->u.contents[cmp->hash_index * 2])             \
+       ->u.contents[(n) * 2 - 1])
 
 /* Decode encoded composition rule RULE_CODE into GREF (global
    reference point code), NREF (new ref. point code).  Don't check RULE_CODE;
index e02bab04bbc9108a3c5f5c0accb77dedc1663ba9..87dc5a22a68345ff019c8eb234626762c70a59fb 100644 (file)
@@ -59,7 +59,7 @@ extern Lisp_Object Qdisplay_table;
 /* Return the current base (for indexing) of the GLYPH table,
    or 0 if the table isn't currently valid.  */
 #define GLYPH_TABLE_BASE  \
-  ((VECTORP (Vglyph_table)) ? XVECTOR (Vglyph_table)->contents : 0)
+  ((VECTORP (Vglyph_table)) ? XVECTOR (Vglyph_table)->u.contents : 0)
 
 /* Given BASE and LEN returned by the two previous macros,
    return nonzero if the GLYPH code G should be output as a single
index de90fd731fbe86cef6c127603e14fd88addcdbed..e46189196405f506adef8fff03bfc76f0c1f804b 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -1604,7 +1604,7 @@ changing the value of a sequence `foo'.  */)
 
          for (i = n = 0; i < ASIZE (seq); ++i)
            if (NILP (Fequal (AREF (seq, i), elt)))
-             p->contents[n++] = AREF (seq, i);
+             p->u.contents[n++] = AREF (seq, i);
 
          XSETVECTOR (seq, p);
        }
@@ -3450,7 +3450,7 @@ larger_vector (Lisp_Object vec, ptrdiff_t incr_min, ptrdiff_t nitems_max)
 {
   struct Lisp_Vector *v;
   ptrdiff_t i, incr, incr_max, old_size, new_size;
-  ptrdiff_t C_language_max = min (PTRDIFF_MAX, SIZE_MAX) / sizeof *v->contents;
+  ptrdiff_t C_language_max = min (PTRDIFF_MAX, SIZE_MAX) / sizeof *v->u.contents;
   ptrdiff_t n_max = (0 <= nitems_max && nitems_max < C_language_max
                     ? nitems_max : C_language_max);
   eassert (VECTORP (vec));
@@ -3462,9 +3462,9 @@ larger_vector (Lisp_Object vec, ptrdiff_t incr_min, ptrdiff_t nitems_max)
     memory_full (SIZE_MAX);
   new_size = old_size + incr;
   v = allocate_vector (new_size);
-  memcpy (v->contents, XVECTOR (vec)->contents, old_size * sizeof *v->contents);
+  memcpy (v->u.contents, XVECTOR (vec)->u.contents, old_size * sizeof *v->u.contents);
   for (i = old_size; i < new_size; ++i)
-    v->contents[i] = Qnil;
+    v->u.contents[i] = Qnil;
   XSETVECTOR (vec, v);
   return vec;
 }
index 797d51ac0a76895544b7e650f7f1eed5e55e977d..15fdf9f41a071771c62336c05003ad306d5cebae 100644 (file)
@@ -453,7 +453,7 @@ reorder_font_vector (Lisp_Object font_group, struct font *font)
     }
 
   if (score_changed)
-    qsort (XVECTOR (vec)->contents, size, word_size,
+    qsort (XVECTOR (vec)->u.contents, size, word_size,
           fontset_compare_rfontdef);
   XSETCAR (font_group, make_number (charset_ordered_list_tick));
 }
index 891b42788ed80ec4c5f6c41348ccd68f590b0574..d956e627ba94323fe7cd98a06a53f93739df1591 100644 (file)
@@ -118,7 +118,7 @@ disptab_matches_widthtab (struct Lisp_Char_Table *disptab, struct Lisp_Vector *w
 
   for (i = 0; i < 256; i++)
     if (character_width (i, disptab)
-        != XFASTINT (widthtab->contents[i]))
+        != XFASTINT (widthtab->u.contents[i]))
       return 0;
 
   return 1;
@@ -138,7 +138,7 @@ recompute_width_table (struct buffer *buf, struct Lisp_Char_Table *disptab)
   eassert (widthtab->header.size == 256);
 
   for (i = 0; i < 256; i++)
-    XSETFASTINT (widthtab->contents[i], character_width (i, disptab));
+    XSETFASTINT (widthtab->u.contents[i], character_width (i, disptab));
 }
 
 /* Allocate or free the width run cache, as requested by the
@@ -1136,7 +1136,7 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos,
   width_run_cache_on_off ();
   if (dp == buffer_display_table ())
     width_table = (VECTORP (BVAR (current_buffer, width_table))
-                   ? XVECTOR (BVAR (current_buffer, width_table))->contents
+                   ? XVECTOR (BVAR (current_buffer, width_table))->u.contents
                    : 0);
   else
     /* If the window has its own display table, we can't use the width
index 201b9ec8f5b5b3a87fc925b706f4de4310b9c76c..05efe7c131291a0fcb2c1592e1c4437e3771d331 100644 (file)
@@ -4341,7 +4341,7 @@ decode_timer (Lisp_Object timer, struct timespec *result)
 
   if (! (VECTORP (timer) && ASIZE (timer) == 9))
     return 0;
-  vector = XVECTOR (timer)->contents;
+  vector = XVECTOR (timer)->u.contents;
   if (! NILP (vector[0]))
     return 0;
 
@@ -7998,7 +7998,7 @@ process_tool_bar_item (Lisp_Object key, Lisp_Object def, Lisp_Object data, void
         discard any previously made item.  */
       for (i = 0; i < ntool_bar_items; i += TOOL_BAR_ITEM_NSLOTS)
        {
-         Lisp_Object *v = XVECTOR (tool_bar_items_vector)->contents + i;
+         Lisp_Object *v = XVECTOR (tool_bar_items_vector)->u.contents + i;
 
          if (EQ (key, v[TOOL_BAR_ITEM_KEY]))
            {
@@ -8322,7 +8322,7 @@ append_tool_bar_item (void)
   /* Append entries from tool_bar_item_properties to the end of
      tool_bar_items_vector.  */
   vcopy (tool_bar_items_vector, ntool_bar_items,
-        XVECTOR (tool_bar_item_properties)->contents, TOOL_BAR_ITEM_NSLOTS);
+        XVECTOR (tool_bar_item_properties)->u.contents, TOOL_BAR_ITEM_NSLOTS);
   ntool_bar_items += TOOL_BAR_ITEM_NSLOTS;
 }
 
@@ -9919,7 +9919,7 @@ DEFUN ("recent-keys", Frecent_keys, Srecent_keys, 0, 0, 0,
        doc: /* Return vector of last 300 events, not counting those from keyboard macros.  */)
   (void)
 {
-  Lisp_Object *keys = XVECTOR (recent_keys)->contents;
+  Lisp_Object *keys = XVECTOR (recent_keys)->u.contents;
   Lisp_Object val;
 
   if (total_keys < NUM_RECENT_KEYS)
@@ -9945,7 +9945,7 @@ See also `this-command-keys-vector'.  */)
   (void)
 {
   return make_event_array (this_command_key_count,
-                          XVECTOR (this_command_keys)->contents);
+                          XVECTOR (this_command_keys)->u.contents);
 }
 
 DEFUN ("this-command-keys-vector", Fthis_command_keys_vector, Sthis_command_keys_vector, 0, 0, 0,
@@ -9957,7 +9957,7 @@ See also `this-command-keys'.  */)
   (void)
 {
   return Fvector (this_command_key_count,
-                 XVECTOR (this_command_keys)->contents);
+                 XVECTOR (this_command_keys)->u.contents);
 }
 
 DEFUN ("this-single-command-keys", Fthis_single_command_keys,
@@ -9972,7 +9972,7 @@ The value is always a vector.  */)
 {
   return Fvector (this_command_key_count
                  - this_single_command_key_start,
-                 (XVECTOR (this_command_keys)->contents
+                 (XVECTOR (this_command_keys)->u.contents
                   + this_single_command_key_start));
 }
 
@@ -9986,8 +9986,7 @@ shows the events before all translations (except for input methods).
 The value is always a vector.  */)
   (void)
 {
-  return Fvector (raw_keybuf_count,
-                 (XVECTOR (raw_keybuf)->contents));
+  return Fvector (raw_keybuf_count, XVECTOR (raw_keybuf)->u.contents);
 }
 
 DEFUN ("reset-this-command-lengths", Freset_this_command_lengths,
index f49a2042b1b9a149f2a3eef98b4e170d1e2a393d..63597e86be69767f134a38472b2f06092ff413de 100644 (file)
@@ -1136,12 +1136,19 @@ struct vectorlike_header
     ptrdiff_t size;
   };
 
-/* Regular vector is just a header plus array of Lisp_Objects.  */
+/* Regular vector is just a header plus array of Lisp_Objects...  */
 
 struct Lisp_Vector
   {
     struct vectorlike_header header;
-    Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER];
+    union {
+      /* ...but sometimes there is also a pointer internally used in
+        vector allocation code.  Usually you don't want to touch this.  */
+      struct Lisp_Vector *next;
+      
+      /* We can't use FLEXIBLE_ARRAY_MEMBER here.  */
+      Lisp_Object contents[1]; 
+    } u;
   };
 
 /* A boolvector is a kind of vectorlike, with contents are like a string.  */
@@ -1162,7 +1169,7 @@ struct Lisp_Bool_Vector
 
 enum
   {
-    header_size = offsetof (struct Lisp_Vector, contents),
+    header_size = offsetof (struct Lisp_Vector, u.contents),
     bool_header_size = offsetof (struct Lisp_Bool_Vector, data),
     word_size = sizeof (Lisp_Object)
   };
@@ -1172,13 +1179,13 @@ enum
 INLINE Lisp_Object
 AREF (Lisp_Object array, ptrdiff_t idx)
 {
-  return XVECTOR (array)->contents[idx];
+  return XVECTOR (array)->u.contents[idx];
 }
 
 INLINE Lisp_Object *
 aref_addr (Lisp_Object array, ptrdiff_t idx)
 {
-  return & XVECTOR (array)->contents[idx];
+  return & XVECTOR (array)->u.contents[idx];
 }
 
 INLINE ptrdiff_t
@@ -1191,7 +1198,7 @@ INLINE void
 ASET (Lisp_Object array, ptrdiff_t idx, Lisp_Object val)
 {
   eassert (0 <= idx && idx < ASIZE (array));
-  XVECTOR (array)->contents[idx] = val;
+  XVECTOR (array)->u.contents[idx] = val;
 }
 
 INLINE void
@@ -1200,7 +1207,7 @@ gc_aset (Lisp_Object array, ptrdiff_t idx, Lisp_Object val)
   /* Like ASET, but also can be used in the garbage collector:
      sweep_weak_table calls set_hash_key etc. while the table is marked.  */
   eassert (0 <= idx && idx < (ASIZE (array) & ~ARRAY_MARK_FLAG));
-  XVECTOR (array)->contents[idx] = val;
+  XVECTOR (array)->u.contents[idx] = val;
 }
 
 /* If a struct is made to look like a vector, this macro returns the length
@@ -3028,7 +3035,7 @@ INLINE void
 vcopy (Lisp_Object v, ptrdiff_t offset, Lisp_Object *args, ptrdiff_t count)
 {
   eassert (0 <= offset && 0 <= count && offset + count <= ASIZE (v));
-  memcpy (XVECTOR (v)->contents + offset, args, count * sizeof *args);
+  memcpy (XVECTOR (v)->u.contents + offset, args, count * sizeof *args);
 }
 
 /* Functions to modify hash tables.  */
index 9518631ba6dd309583c80a29baf2afcf338df7ca..017dfcb11a54b3c43670c2e8173e18a1f39f118d 100644 (file)
@@ -3459,7 +3459,7 @@ read_vector (Lisp_Object readcharfun, bool bytecodeflag)
   vector = Fmake_vector (len, Qnil);
 
   size = ASIZE (vector);
-  ptr = XVECTOR (vector)->contents;
+  ptr = XVECTOR (vector)->u.contents;
   for (i = 0; i < size; i++)
     {
       item = Fcar (tem);
index 09aedf837d8361ba1b6f3917dead2823382a33c9..aef75120293a20e72ff0a1fc34cab15159c2d655 100644 (file)
@@ -2394,7 +2394,7 @@ Each input key receives two values in this vector: first the ASCII code,
 and then the scan code.  */)
   (void)
 {
-  Lisp_Object val, *keys = XVECTOR (recent_doskeys)->contents;
+  Lisp_Object val, *keys = XVECTOR (recent_doskeys)->u.contents;
 
   if (total_doskeys < NUM_RECENT_DOSKEYS)
     return Fvector (total_doskeys, keys);
index 94f59942a610553b18a44b86f67cd99b68ed5cbf..fcaa78947792c241047c2fbf2eabf21aac90eb0d 100644 (file)
@@ -1333,15 +1333,15 @@ Returns nil if format of ADDRESS is invalid.  */)
 
       for (i = 0; i < nargs; i++)
        {
-         if (! RANGED_INTEGERP (0, p->contents[i], 65535))
+         if (! RANGED_INTEGERP (0, p->u.contents[i], 65535))
            return Qnil;
 
          if (nargs <= 5         /* IPv4 */
              && i < 4           /* host, not port */
-             && XINT (p->contents[i]) > 255)
+             && XINT (p->u.contents[i]) > 255)
            return Qnil;
 
-         args[i+1] = p->contents[i];
+         args[i+1] = p->u.contents[i];
        }
 
       return Fformat (nargs+1, args);
@@ -1980,7 +1980,7 @@ conv_sockaddr_to_lisp (struct sockaddr *sa, int len)
        len = sizeof (sin->sin_addr) + 1;
        address = Fmake_vector (make_number (len), Qnil);
        p = XVECTOR (address);
-       p->contents[--len] = make_number (ntohs (sin->sin_port));
+       p->u.contents[--len] = make_number (ntohs (sin->sin_port));
        cp = (unsigned char *) &sin->sin_addr;
        break;
       }
@@ -1992,9 +1992,9 @@ conv_sockaddr_to_lisp (struct sockaddr *sa, int len)
        len = sizeof (sin6->sin6_addr)/2 + 1;
        address = Fmake_vector (make_number (len), Qnil);
        p = XVECTOR (address);
-       p->contents[--len] = make_number (ntohs (sin6->sin6_port));
+       p->u.contents[--len] = make_number (ntohs (sin6->sin6_port));
        for (i = 0; i < len; i++)
-         p->contents[i] = make_number (ntohs (ip6[i]));
+         p->u.contents[i] = make_number (ntohs (ip6[i]));
        return address;
       }
 #endif
@@ -2019,7 +2019,7 @@ conv_sockaddr_to_lisp (struct sockaddr *sa, int len)
 
   i = 0;
   while (i < len)
-    p->contents[i++] = make_number (*cp++);
+    p->u.contents[i++] = make_number (*cp++);
 
   return address;
 }
@@ -2090,7 +2090,7 @@ conv_lisp_to_sockaddr (int family, Lisp_Object address, struct sockaddr *sa, int
        {
          struct sockaddr_in *sin = (struct sockaddr_in *) sa;
          len = sizeof (sin->sin_addr) + 1;
-         hostport = XINT (p->contents[--len]);
+         hostport = XINT (p->u.contents[--len]);
          sin->sin_port = htons (hostport);
          cp = (unsigned char *)&sin->sin_addr;
          sa->sa_family = family;
@@ -2101,12 +2101,12 @@ conv_lisp_to_sockaddr (int family, Lisp_Object address, struct sockaddr *sa, int
          struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
          uint16_t *ip6 = (uint16_t *)&sin6->sin6_addr;
          len = sizeof (sin6->sin6_addr) + 1;
-         hostport = XINT (p->contents[--len]);
+         hostport = XINT (p->u.contents[--len]);
          sin6->sin6_port = htons (hostport);
          for (i = 0; i < len; i++)
-           if (INTEGERP (p->contents[i]))
+           if (INTEGERP (p->u.contents[i]))
              {
-               int j = XFASTINT (p->contents[i]) & 0xffff;
+               int j = XFASTINT (p->u.contents[i]) & 0xffff;
                ip6[i] = ntohs (j);
              }
          sa->sa_family = family;
@@ -2137,8 +2137,8 @@ conv_lisp_to_sockaddr (int family, Lisp_Object address, struct sockaddr *sa, int
     }
 
   for (i = 0; i < len; i++)
-    if (INTEGERP (p->contents[i]))
-      *cp++ = XFASTINT (p->contents[i]) & 0xff;
+    if (INTEGERP (p->u.contents[i]))
+      *cp++ = XFASTINT (p->u.contents[i]) & 0xff;
 }
 
 #ifdef DATAGRAM_SOCKETS
@@ -3729,7 +3729,7 @@ FLAGS is the current flags of the interface.  */)
 
       any = 1;
       for (n = 0; n < 6; n++)
-       p->contents[n] = make_number (((unsigned char *)&rq.ifr_hwaddr.sa_data[0])[n]);
+       p->u.contents[n] = make_number (((unsigned char *)&rq.ifr_hwaddr.sa_data[0])[n]);
       elt = Fcons (make_number (rq.ifr_hwaddr.sa_family), hwaddr);
     }
 #elif defined (HAVE_GETIFADDRS) && defined (LLADDR)
index 7435a09b6270234cb341625e8f323a5a0cfe4971..b52aae554990d1e092af8b04b39d0d3af8f32a50 100644 (file)
@@ -421,7 +421,7 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
 
       /* Save the frame's previous menu bar contents data.  */
       if (previous_menu_items_used)
-       memcpy (previous_items, XVECTOR (f->menu_bar_vector)->contents,
+       memcpy (previous_items, XVECTOR (f->menu_bar_vector)->u.contents,
                previous_menu_items_used * word_size);
 
       /* Fill in menu_items with the current menu bar contents.
index 7081df7de89d3e0f00b40541a4dbcdd326df4279..cca15122522c3c3a64ae241ba8513cad5f16dc31 100644 (file)
@@ -5401,7 +5401,7 @@ struct saved_window
 };
 
 #define SAVED_WINDOW_N(swv,n) \
-  ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
+  ((struct saved_window *) (XVECTOR ((swv)->u.contents[(n)])))
 
 DEFUN ("window-configuration-p", Fwindow_configuration_p, Swindow_configuration_p, 1, 1, 0,
        doc: /* Return t if OBJECT is a window-configuration object.  */)
index 6d19531aab6a73f625848e539525dc3a7d97c84d..0dc34dfbab09c94fa1fb14770a533b196fce5b17 100644 (file)
@@ -4473,8 +4473,8 @@ setup_for_ellipsis (struct it *it, int len)
   if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
     {
       struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
-      it->dpvec = v->contents;
-      it->dpend = v->contents + v->header.size;
+      it->dpvec = v->u.contents;
+      it->dpend = v->u.contents + v->header.size;
     }
   else
     {
@@ -6778,8 +6778,8 @@ get_next_display_element (struct it *it)
              if (v->header.size)
                {
                  it->dpvec_char_len = it->len;
-                 it->dpvec = v->contents;
-                 it->dpend = v->contents + v->header.size;
+                 it->dpvec = v->u.contents;
+                 it->dpend = v->u.contents + v->header.size;
                  it->current.dpvec_index = 0;
                  it->dpvec_face_id = -1;
                  it->saved_face_id = it->face_id;
@@ -27555,7 +27555,7 @@ on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
       if (VECTORP (XCDR (hot_spot)))
        {
          struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
-         Lisp_Object *poly = v->contents;
+         Lisp_Object *poly = v->u.contents;
          ptrdiff_t n = v->header.size;
          ptrdiff_t i;
          int inside = 0;
index 335018dfee21af8109668be031d71143c83775fe..8d78a28eab10b923587519b2864c1a415f1e1b4f 100644 (file)
@@ -1565,7 +1565,7 @@ the face font sort order.  */)
   vec = Fvconcat (ndrivers, drivers);
   nfonts = ASIZE (vec);
 
-  qsort (XVECTOR (vec)->contents, nfonts, word_size,
+  qsort (XVECTOR (vec)->u.contents, nfonts, word_size,
         compare_fonts_by_sort_order);
 
   result = Qnil;
@@ -1830,7 +1830,7 @@ check_lface (Lisp_Object lface)
   if (!NILP (lface))
     {
       eassert (LFACEP (lface));
-      check_lface_attrs (XVECTOR (lface)->contents);
+      check_lface_attrs (XVECTOR (lface)->u.contents);
     }
 }
 
@@ -2007,7 +2007,7 @@ get_lface_attributes_no_remap (struct frame *f, Lisp_Object face_name,
   lface = lface_from_face_name_no_resolve (f, face_name, signal_p);
 
   if (! NILP (lface))
-    memcpy (attrs, XVECTOR (lface)->contents,
+    memcpy (attrs, XVECTOR (lface)->u.contents,
            LFACE_VECTOR_SIZE * sizeof *attrs);
 
   return !NILP (lface);
@@ -2690,7 +2690,7 @@ The value is TO.  */)
       copy = Finternal_make_lisp_face (to, new_frame);
     }
 
-  vcopy (copy, 0, XVECTOR (lface)->contents, LFACE_VECTOR_SIZE);
+  vcopy (copy, 0, XVECTOR (lface)->u.contents, LFACE_VECTOR_SIZE);
 
   /* Changing a named face means that all realized faces depending on
      that face are invalid.  Since we cannot tell which realized faces
@@ -3093,7 +3093,7 @@ FRAME 0 means change the face on all frames, and change the default
                f = XFRAME (frame);
              if (! FONT_OBJECT_P (value))
                {
-                 Lisp_Object *attrs = XVECTOR (lface)->contents;
+                 Lisp_Object *attrs = XVECTOR (lface)->u.contents;
                  Lisp_Object font_object;
 
                  font_object = font_load_for_lface (f, attrs, value);
@@ -3161,7 +3161,7 @@ FRAME 0 means change the face on all frames, and change the default
         the font to nil so that the font selector doesn't think that
         the attribute is mandatory.  Also, clear the average
         width.  */
-      font_clear_prop (XVECTOR (lface)->contents, prop_index);
+      font_clear_prop (XVECTOR (lface)->u.contents, prop_index);
     }
 
   /* Changing a named face means that all realized faces depending on
@@ -3191,7 +3191,7 @@ FRAME 0 means change the face on all frames, and change the default
             reflected in changed `font' frame parameters. */
          if (FRAMEP (frame)
              && (prop_index || EQ (attr, QCfont))
-             && lface_fully_specified_p (XVECTOR (lface)->contents))
+             && lface_fully_specified_p (XVECTOR (lface)->u.contents))
            set_font_frame_param (frame, lface);
          else
 #endif /* HAVE_WINDOW_SYSTEM */
@@ -3371,7 +3371,7 @@ set_font_frame_param (Lisp_Object frame, Lisp_Object lface)
     {
       if (FONT_SPEC_P (font))
        {
-         font = font_load_for_lface (f, XVECTOR (lface)->contents, font);
+         font = font_load_for_lface (f, XVECTOR (lface)->u.contents, font);
          if (NILP (font))
            return;
          ASET (lface, LFACE_FONT_INDEX, font);
@@ -3728,8 +3728,8 @@ Default face attributes override any local face attributes.  */)
      the local frame is defined from default specs in `face-defface-spec'
      and those should be overridden by global settings.  Hence the strange
      "global before local" priority.  */
-  lvec = XVECTOR (local_lface)->contents;
-  gvec = XVECTOR (global_lface)->contents;
+  lvec = XVECTOR (local_lface)->u.contents;
+  gvec = XVECTOR (global_lface)->u.contents;
   for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
     if (IGNORE_DEFFACE_P (gvec[i]))
       ASET (local_lface, i, Qunspecified);
@@ -3913,8 +3913,8 @@ If FRAME is omitted or nil, use the selected frame.  */)
 
   lface1 = lface_from_face_name (f, face1, 1);
   lface2 = lface_from_face_name (f, face2, 1);
-  equal_p = lface_equal_p (XVECTOR (lface1)->contents,
-                          XVECTOR (lface2)->contents);
+  equal_p = lface_equal_p (XVECTOR (lface1)->u.contents,
+                          XVECTOR (lface2)->u.contents);
   return equal_p ? Qt : Qnil;
 }
 
@@ -4651,7 +4651,7 @@ DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector,
   Lisp_Object lface;
   lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
                        Qunspecified);
-  merge_face_ref (XFRAME (selected_frame), plist, XVECTOR (lface)->contents,
+  merge_face_ref (XFRAME (selected_frame), plist, XVECTOR (lface)->u.contents,
                  1, 0);
   return lface;
 }
@@ -5331,9 +5331,9 @@ realize_default_face (struct frame *f)
     ASET (lface, LFACE_STIPPLE_INDEX, Qnil);
 
   /* Realize the face; it must be fully-specified now.  */
-  eassert (lface_fully_specified_p (XVECTOR (lface)->contents));
+  eassert (lface_fully_specified_p (XVECTOR (lface)->u.contents));
   check_lface (lface);
-  memcpy (attrs, XVECTOR (lface)->contents, sizeof attrs);
+  memcpy (attrs, XVECTOR (lface)->u.contents, sizeof attrs);
   face = realize_face (c, attrs, DEFAULT_FACE_ID);
 
 #ifdef HAVE_WINDOW_SYSTEM
index 6a675482ed95bf89881be57e94002b1359e29b73..c5b8db3830ccf88f46cfe0cf8a02e0ed79c23f47 100644 (file)
@@ -384,7 +384,7 @@ xfont_list_pattern (Display *display, const char *pattern,
   if (num_fonts > 0)
     {
       char **indices = alloca (sizeof (char *) * num_fonts);
-      Lisp_Object *props = XVECTOR (xfont_scratch_props)->contents;
+      Lisp_Object *props = XVECTOR (xfont_scratch_props)->u.contents;
       Lisp_Object scripts = Qnil;
 
       for (i = 0; i < ASIZE (xfont_scratch_props); i++)
index 1535b00a47fe543f6a633122abb737441e5c18b8..ad8380a3c3ed66d34903150b6f7e90b15187a461 100644 (file)
@@ -990,7 +990,7 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
 
       /* Save the frame's previous menu bar contents data.  */
       if (previous_menu_items_used)
-       memcpy (previous_items, XVECTOR (f->menu_bar_vector)->contents,
+       memcpy (previous_items, XVECTOR (f->menu_bar_vector)->u.contents,
                previous_menu_items_used * word_size);
 
       /* Fill in menu_items with the current menu bar contents.
@@ -2187,7 +2187,7 @@ menu_help_callback (char const *help_string, int pane, int item)
   Lisp_Object pane_name;
   Lisp_Object menu_object;
 
-  first_item = XVECTOR (menu_items)->contents;
+  first_item = XVECTOR (menu_items)->u.contents;
   if (EQ (first_item[0], Qt))
     pane_name = first_item[MENU_ITEMS_PANE_NAME];
   else if (EQ (first_item[0], Qquote))