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.
This commit is contained in:
parent
ec7bc82f9c
commit
d6d9cbc15c
24 changed files with 116 additions and 113 deletions
|
@ -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.
|
||||
|
|
48
src/alloc.c
48
src/alloc.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
23
src/lisp.h
23
src/lisp.h
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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. */)
|
||||
|
|
10
src/xdisp.c
10
src/xdisp.c
|
@ -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;
|
||||
|
|
30
src/xfaces.c
30
src/xfaces.c
|
@ -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
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Add table
Reference in a new issue