From: Dmitry Antipov Date: Tue, 21 Aug 2012 10:21:04 +0000 (+0400) Subject: Avoid direct writes to contents member of struct Lisp_Vector. X-Git-Tag: emacs-24.2.90~566 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=086ca913a8495b1d4f0d7eae58aea75f2f5e44ae;p=emacs.git Avoid direct writes to contents member of struct Lisp_Vector. * lisp.h (vcopy): New function to copy data into vector. * dispnew.c (Fframe_or_buffer_changed_p): Use AREF and ASET. * fns.c (Ffillarray): Use ASET. * keyboard.c (timer_check_2): Use AREF and ASET. (append_tool_bar_item, Frecent_keys): Use vcopy. * lread.c (read_vector): Use ASET. * msdos.c (Frecent_doskeys): Use vcopy. * xface.c (Finternal_copy_lisp_face): Use vcopy. (Finternal_merge_in_global_face): Use ASET and vcopy. * xfont.c (xfont_list_pattern): Likewise. --- diff --git a/src/ChangeLog b/src/ChangeLog index 15eac722f8e..75853f3d354 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,17 @@ +2012-08-21 Dmitry Antipov + + Avoid direct writes to contents member of struct Lisp_Vector. + * lisp.h (vcopy): New function to copy data into vector. + * dispnew.c (Fframe_or_buffer_changed_p): Use AREF and ASET. + * fns.c (Ffillarray): Use ASET. + * keyboard.c (timer_check_2): Use AREF and ASET. + (append_tool_bar_item, Frecent_keys): Use vcopy. + * lread.c (read_vector): Use ASET. + * msdos.c (Frecent_doskeys): Use vcopy. + * xface.c (Finternal_copy_lisp_face): Use vcopy. + (Finternal_merge_in_global_face): Use ASET and vcopy. + * xfont.c (xfont_list_pattern): Likewise. + 2012-08-21 Martin Rudalics * window.c (Fwindow_point): For the selected window always return diff --git a/src/dispnew.c b/src/dispnew.c index 8db4f93dc70..ce7c4ebcb4c 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -6044,8 +6044,7 @@ pass nil for VARIABLE. */) (Lisp_Object variable) { Lisp_Object state, tail, frame, buf; - Lisp_Object *vecp, *end; - ptrdiff_t n; + ptrdiff_t n, idx; if (! NILP (variable)) { @@ -6057,18 +6056,16 @@ pass nil for VARIABLE. */) else state = frame_and_buffer_state; - vecp = XVECTOR (state)->contents; - end = vecp + ASIZE (state); - + idx = 0; FOR_EACH_FRAME (tail, frame) { - if (vecp == end) + if (idx == ASIZE (state)) goto changed; - if (!EQ (*vecp++, frame)) + if (!EQ (AREF (state, idx++), frame)) goto changed; - if (vecp == end) + if (idx == ASIZE (state)) goto changed; - if (!EQ (*vecp++, XFRAME (frame)->name)) + if (!EQ (AREF (state, idx++), XFRAME (frame)->name)) goto changed; } /* Check that the buffer info matches. */ @@ -6078,23 +6075,23 @@ pass nil for VARIABLE. */) /* Ignore buffers that aren't included in buffer lists. */ if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ') continue; - if (vecp == end) + if (idx == ASIZE (state)) goto changed; - if (!EQ (*vecp++, buf)) + if (!EQ (AREF (state, idx++), buf)) goto changed; - if (vecp == end) + if (idx == ASIZE (state)) goto changed; - if (!EQ (*vecp++, BVAR (XBUFFER (buf), read_only))) + if (!EQ (AREF (state, idx++), BVAR (XBUFFER (buf), read_only))) goto changed; - if (vecp == end) + if (idx == ASIZE (state)) goto changed; - if (!EQ (*vecp++, Fbuffer_modified_p (buf))) + if (!EQ (AREF (state, idx++), Fbuffer_modified_p (buf))) goto changed; } - if (vecp == end) + if (idx == ASIZE (state)) goto changed; /* Detect deletion of a buffer at the end of the list. */ - if (EQ (*vecp, Qlambda)) + if (EQ (AREF (state, idx), Qlambda)) return Qnil; /* Come here if we decide the data has changed. */ @@ -6121,11 +6118,13 @@ pass nil for VARIABLE. */) } /* Record the new data in the (possibly reallocated) vector. */ - vecp = XVECTOR (state)->contents; + idx = 0; FOR_EACH_FRAME (tail, frame) { - *vecp++ = frame; - *vecp++ = XFRAME (frame)->name; + ASET (state, idx, frame); + idx++; + ASET (state, idx, XFRAME (frame)->name); + idx++; } for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) { @@ -6133,19 +6132,23 @@ pass nil for VARIABLE. */) /* Ignore buffers that aren't included in buffer lists. */ if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ') continue; - *vecp++ = buf; - *vecp++ = BVAR (XBUFFER (buf), read_only); - *vecp++ = Fbuffer_modified_p (buf); + ASET (state, idx, buf); + idx++; + ASET (state, idx, BVAR (XBUFFER (buf), read_only)); + idx++; + ASET (state, idx, Fbuffer_modified_p (buf)); + idx++; } /* Fill up the vector with lambdas (always at least one). */ - *vecp++ = Qlambda; - while (vecp - XVECTOR (state)->contents - < ASIZE (state)) - *vecp++ = Qlambda; + ASET (state, idx, Qlambda); + idx++; + while (idx < ASIZE (state)) + { + ASET (state, idx, Qlambda); + idx++; + } /* Make sure we didn't overflow the vector. */ - if (vecp - XVECTOR (state)->contents - > ASIZE (state)) - abort (); + eassert (idx <= ASIZE (state)); return Qt; } diff --git a/src/fns.c b/src/fns.c index 79f8e233fb5..34238e4cd6a 100644 --- a/src/fns.c +++ b/src/fns.c @@ -2139,12 +2139,8 @@ ARRAY is a vector, string, char-table, or bool-vector. */) register ptrdiff_t size, idx; if (VECTORP (array)) - { - register Lisp_Object *p = XVECTOR (array)->contents; - size = ASIZE (array); - for (idx = 0; idx < size; idx++) - p[idx] = item; - } + for (idx = 0, size = ASIZE (array); idx < size; idx++) + ASET (array, idx, item); else if (CHAR_TABLE_P (array)) { int i; diff --git a/src/keyboard.c b/src/keyboard.c index 868d0c8d2c1..3d4061accfc 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -4419,7 +4419,6 @@ timer_check_2 (void) while (CONSP (timers) || CONSP (idle_timers)) { - Lisp_Object *vector; Lisp_Object timer = Qnil, idle_timer = Qnil; EMACS_TIME timer_time, idle_timer_time; EMACS_TIME difference; @@ -4495,15 +4494,14 @@ timer_check_2 (void) /* If timer is ripe, run it if it hasn't been run. */ if (ripe) { - vector = XVECTOR (chosen_timer)->contents; - if (NILP (vector[0])) + if (NILP (AREF (chosen_timer, 0))) { ptrdiff_t count = SPECPDL_INDEX (); Lisp_Object old_deactivate_mark = Vdeactivate_mark; /* Mark the timer as triggered to prevent problems if the lisp code fails to reschedule it right. */ - vector[0] = Qt; + ASET (chosen_timer, 0, Qt); specbind (Qinhibit_quit, Qt); @@ -8447,7 +8445,6 @@ init_tool_bar_items (Lisp_Object reuse) static void append_tool_bar_item (void) { - Lisp_Object *to, *from; ptrdiff_t incr = (ntool_bar_items - (ASIZE (tool_bar_items_vector) - TOOL_BAR_ITEM_NSLOTS)); @@ -8459,9 +8456,8 @@ append_tool_bar_item (void) /* Append entries from tool_bar_item_properties to the end of tool_bar_items_vector. */ - to = XVECTOR (tool_bar_items_vector)->contents + ntool_bar_items; - from = XVECTOR (tool_bar_item_properties)->contents; - memcpy (to, from, TOOL_BAR_ITEM_NSLOTS * sizeof *to); + vcopy (tool_bar_items_vector, ntool_bar_items, + XVECTOR (tool_bar_item_properties)->contents, TOOL_BAR_ITEM_NSLOTS); ntool_bar_items += TOOL_BAR_ITEM_NSLOTS; } @@ -10490,10 +10486,10 @@ DEFUN ("recent-keys", Frecent_keys, Srecent_keys, 0, 0, 0, else { val = Fvector (NUM_RECENT_KEYS, keys); - memcpy (XVECTOR (val)->contents, keys + recent_keys_index, - (NUM_RECENT_KEYS - recent_keys_index) * word_size); - memcpy (XVECTOR (val)->contents + NUM_RECENT_KEYS - recent_keys_index, - keys, recent_keys_index * word_size); + vcopy (val, 0, keys + recent_keys_index, + NUM_RECENT_KEYS - recent_keys_index); + vcopy (val, NUM_RECENT_KEYS - recent_keys_index, + keys, recent_keys_index); return val; } } diff --git a/src/lisp.h b/src/lisp.h index 3a6eb72d020..587e584b091 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2344,6 +2344,20 @@ gc_aset (Lisp_Object array, ptrdiff_t idx, Lisp_Object val) XVECTOR (array)->contents[idx] = val; } +/* Copy COUNT Lisp_Objects from ARGS to contents of V starting from OFFSET. */ + +LISP_INLINE void +vcopy (Lisp_Object v, ptrdiff_t offset, Lisp_Object *args, ptrdiff_t count) +{ + ptrdiff_t i; + + eassert (offset + count <= ASIZE (v)); + for (i = 0; i < count; i++) + ASET (v, offset + i, args[i]); +} + +/* Functions to modify hash tables. */ + LISP_INLINE void set_hash_key_and_value (struct Lisp_Hash_Table *h, Lisp_Object key_and_value) { diff --git a/src/lread.c b/src/lread.c index e2ad03b349f..f3ab1610d2c 100644 --- a/src/lread.c +++ b/src/lread.c @@ -3406,7 +3406,7 @@ read_vector (Lisp_Object readcharfun, int bytecodeflag) /* Delay handling the bytecode slot until we know whether it is lazily-loaded (we can tell by whether the constants slot is nil). */ - ptr[COMPILED_CONSTANTS] = item; + ASET (vector, COMPILED_CONSTANTS, item); item = Qnil; } else if (i == COMPILED_CONSTANTS) @@ -3432,7 +3432,7 @@ read_vector (Lisp_Object readcharfun, int bytecodeflag) } /* Now handle the bytecode slot. */ - ptr[COMPILED_BYTECODE] = bytestr; + ASET (vector, COMPILED_BYTECODE, bytestr); } else if (i == COMPILED_DOC_STRING && STRINGP (item) @@ -3444,7 +3444,7 @@ read_vector (Lisp_Object readcharfun, int bytecodeflag) item = Fstring_as_multibyte (item); } } - ptr[i] = item; + ASET (vector, i, item); otem = XCONS (tem); tem = Fcdr (tem); free_cons (otem); diff --git a/src/msdos.c b/src/msdos.c index 30435820d9e..a214456d104 100644 --- a/src/msdos.c +++ b/src/msdos.c @@ -2434,10 +2434,10 @@ and then the scan code. */) else { val = Fvector (NUM_RECENT_DOSKEYS, keys); - memcpy (XVECTOR (val)->contents, keys + recent_doskeys_index, - (NUM_RECENT_DOSKEYS - recent_doskeys_index) * word_size); - memcpy (XVECTOR (val)->contents + NUM_RECENT_DOSKEYS - recent_doskeys_index, - keys, recent_doskeys_index * word_size); + vcopy (val, 0, keys + recent_doskeys_index, + NUM_RECENT_DOSKEYS - recent_doskeys_index); + vcopy (val, NUM_RECENT_DOSKEYS - recent_doskeys_index, + keys, recent_doskeys_index); return val; } } diff --git a/src/xfaces.c b/src/xfaces.c index 46121d66606..820d764d0a8 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -2781,8 +2781,7 @@ The value is TO. */) copy = Finternal_make_lisp_face (to, new_frame); } - memcpy (XVECTOR (copy)->contents, XVECTOR (lface)->contents, - LFACE_VECTOR_SIZE * word_size); + vcopy (copy, 0, XVECTOR (lface)->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 @@ -3831,9 +3830,9 @@ Default face attributes override any local face attributes. */) gvec = XVECTOR (global_lface)->contents; for (i = 1; i < LFACE_VECTOR_SIZE; ++i) if (IGNORE_DEFFACE_P (gvec[i])) - lvec[i] = Qunspecified; + ASET (local_lface, i, Qunspecified); else if (! UNSPECIFIEDP (gvec[i])) - lvec[i] = gvec[i]; + ASET (local_lface, i, AREF (global_lface, i)); /* If the default face was changed, update the face cache and the `font' frame parameter. */ @@ -3850,7 +3849,7 @@ Default face attributes override any local face attributes. */) the previously-cached vector. */ memcpy (attrs, oldface->lface, sizeof attrs); merge_face_vectors (f, lvec, attrs, 0); - memcpy (lvec, attrs, sizeof attrs); + vcopy (local_lface, 0, attrs, LFACE_VECTOR_SIZE); newface = realize_face (c, lvec, DEFAULT_FACE_ID); if ((! UNSPECIFIEDP (gvec[LFACE_FAMILY_INDEX]) diff --git a/src/xfont.c b/src/xfont.c index 072bce7bb0a..cbb24622ae9 100644 --- a/src/xfont.c +++ b/src/xfont.c @@ -390,7 +390,7 @@ xfont_list_pattern (Display *display, const char *pattern, Lisp_Object scripts = Qnil; for (i = 0; i < ASIZE (xfont_scratch_props); i++) - props[i] = Qnil; + ASET (xfont_scratch_props, i, Qnil); for (i = 0; i < num_fonts; i++) indices[i] = names[i]; qsort (indices, num_fonts, sizeof (char *), compare_font_names); @@ -467,9 +467,9 @@ xfont_list_pattern (Display *display, const char *pattern, word_size * 7) || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7])) { - memcpy (props, aref_addr (entity, FONT_FOUNDRY_INDEX), - word_size * 7); - props[7] = AREF (entity, FONT_SPACING_INDEX); + vcopy (xfont_scratch_props, 0, + aref_addr (entity, FONT_FOUNDRY_INDEX), 7); + ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX)); scripts = xfont_supported_scripts (display, indices[i], xfont_scratch_props, encoding); }