From: Paul Eggert Date: Tue, 2 Jul 2013 03:41:16 +0000 (-0700) Subject: Don't convert function pointers to void * and back. X-Git-Tag: emacs-24.3.90~173^2^2~42^2~45^2~387^2~1956 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=52a9bcae40a1c8536cf70cc4622a6877024e4b36;p=emacs.git Don't convert function pointers to void * and back. It isn't portable C, and it's easy enough to avoid. * alloc.c: Verify SAVE_FUNCPOINTER bits, too. (make_save_value): Add support for SAVE_FUNCPOINTER. * keymap.c (map_keymap_char_table_item, map_keymap_internal): * print.c (print_object): Distinguish function from object pointers. * lisp.h (SAVE_FUNCPOINTER): New constant. (SAVE_SLOT_BITS): Adjust to it. (SAVE_TYPE_FUNCPTR_PTR_OBJ): New constant, replacing SAVE_TYPE_PTR_PTR_OBJ. Change the only use. (voidfuncptr): New typedef. (struct Lisp_Save_Value): New member data[0].funcpointer. (XSAVE_FUNCPOINTER): New function. --- diff --git a/src/ChangeLog b/src/ChangeLog index 2dc1af6d02b..13a9162caab 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,20 @@ 2013-07-02 Paul Eggert + Don't convert function pointers to void * and back. + It isn't portable C, and it's easy enough to avoid. + * alloc.c: Verify SAVE_FUNCPOINTER bits, too. + (make_save_value): Add support for SAVE_FUNCPOINTER. + * keymap.c (map_keymap_char_table_item, map_keymap_internal): + * print.c (print_object): + Distinguish function from object pointers. + * lisp.h (SAVE_FUNCPOINTER): New constant. + (SAVE_SLOT_BITS): Adjust to it. + (SAVE_TYPE_FUNCPTR_PTR_OBJ): New constant, replacing + SAVE_TYPE_PTR_PTR_OBJ. Change the only use. + (voidfuncptr): New typedef. + (struct Lisp_Save_Value): New member data[0].funcpointer. + (XSAVE_FUNCPOINTER): New function. + Simplify buildobj processing. * Makefile.in (buildobj.h): Make it a sequence of strings each followed by comma, rather than a single string. Put it into a diff --git a/src/alloc.c b/src/alloc.c index eaef0d4b797..b625e1f27e0 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -3352,7 +3352,9 @@ free_misc (Lisp_Object misc) that are assumed here and elsewhere. */ verify (SAVE_UNUSED == 0); -verify ((SAVE_INTEGER | SAVE_POINTER | SAVE_OBJECT) >> SAVE_SLOT_BITS == 0); +verify (((SAVE_INTEGER | SAVE_POINTER | SAVE_FUNCPOINTER | SAVE_OBJECT) + >> SAVE_SLOT_BITS) + == 0); /* Return a Lisp_Save_Value object with the data saved according to DATA_TYPE. DATA_TYPE should be one of SAVE_TYPE_INT_INT, etc. */ @@ -3379,6 +3381,10 @@ make_save_value (enum Lisp_Save_Type save_type, ...) p->data[i].pointer = va_arg (ap, void *); break; + case SAVE_FUNCPOINTER: + p->data[i].funcpointer = va_arg (ap, voidfuncptr); + break; + case SAVE_INTEGER: p->data[i].integer = va_arg (ap, ptrdiff_t); break; diff --git a/src/keymap.c b/src/keymap.c index 4e3eff332cc..d29d5636e1c 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -572,7 +572,7 @@ map_keymap_char_table_item (Lisp_Object args, Lisp_Object key, Lisp_Object val) if (!NILP (val)) { map_keymap_function_t fun - = (map_keymap_function_t) XSAVE_POINTER (args, 0); + = (map_keymap_function_t) XSAVE_FUNCPOINTER (args, 0); /* If the key is a range, make a copy since map_char_table modifies it in place. */ if (CONSP (key)) @@ -617,8 +617,8 @@ map_keymap_internal (Lisp_Object map, } else if (CHAR_TABLE_P (binding)) map_char_table (map_keymap_char_table_item, Qnil, binding, - make_save_value (SAVE_TYPE_PTR_PTR_OBJ, - fun, data, args)); + make_save_value (SAVE_TYPE_FUNCPTR_PTR_OBJ, + (voidfuncptr) fun, data, args)); } UNGCPRO; return tail; diff --git a/src/lisp.h b/src/lisp.h index f4356cd140d..74f52b318f5 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -1777,12 +1777,13 @@ enum { SAVE_UNUSED, SAVE_INTEGER, + SAVE_FUNCPOINTER, SAVE_POINTER, SAVE_OBJECT }; /* Number of bits needed to store one of the above values. */ -enum { SAVE_SLOT_BITS = 2 }; +enum { SAVE_SLOT_BITS = 3 }; /* Number of slots in a save value where save_type is nonzero. */ enum { SAVE_VALUE_SLOTS = 4 }; @@ -1803,8 +1804,8 @@ enum Lisp_Save_Type SAVE_TYPE_PTR_INT = SAVE_POINTER + (SAVE_INTEGER << SAVE_SLOT_BITS), SAVE_TYPE_PTR_OBJ = SAVE_POINTER + (SAVE_OBJECT << SAVE_SLOT_BITS), SAVE_TYPE_PTR_PTR = SAVE_POINTER + (SAVE_POINTER << SAVE_SLOT_BITS), - SAVE_TYPE_PTR_PTR_OBJ - = SAVE_POINTER + (SAVE_TYPE_PTR_OBJ << SAVE_SLOT_BITS), + SAVE_TYPE_FUNCPTR_PTR_OBJ + = SAVE_FUNCPOINTER + (SAVE_TYPE_PTR_OBJ << SAVE_SLOT_BITS), /* This has an extra bit indicating it's raw memory. */ SAVE_TYPE_MEMORY = SAVE_TYPE_PTR_INT + (1 << (SAVE_TYPE_BITS - 1)) @@ -1813,9 +1814,9 @@ enum Lisp_Save_Type /* Special object used to hold a different values for later use. This is mostly used to package C integers and pointers to call - record_unwind_protect. Typical task is to pass just one C pointer - to unwind function. You should pack pointer with make_save_pointer - and then get it back with XSAVE_POINTER, e.g.: + record_unwind_protect. A typical task is to pass just one C object + pointer to the unwind function. You should pack an object pointer with + make_save_pointer and then get it back with XSAVE_POINTER, e.g.: ... struct my_data *md = get_my_data (); @@ -1828,10 +1829,10 @@ enum Lisp_Save_Type ... } - If yon need to pass more than just one C pointer, you should - use make_save_value. This function allows you to pack up to - SAVE_VALUE_SLOTS integers, pointers or Lisp_Objects and - conveniently get them back with XSAVE_POINTER, XSAVE_INTEGER and + If you need to pass something else you can use make_save_value, + which allows you to pack up to SAVE_VALUE_SLOTS integers, pointers, + function pointers or Lisp_Objects and conveniently get them back + with XSAVE_INTEGER, XSAVE_POINTER, XSAVE_FUNCPOINTER, and XSAVE_OBJECT macros: ... @@ -1854,6 +1855,8 @@ enum Lisp_Save_Type or XSAVE_OBJECT (arg, 0) are wrong because nothing was saved in slot 2 and Lisp_Object was saved in slot 1 of ARG. */ +typedef void (*voidfuncptr) (void); + struct Lisp_Save_Value { ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Save_Value */ @@ -1869,6 +1872,7 @@ struct Lisp_Save_Value ENUM_BF (Lisp_Save_Type) save_type : SAVE_TYPE_BITS; union { void *pointer; + voidfuncptr funcpointer; ptrdiff_t integer; Lisp_Object object; } data[SAVE_VALUE_SLOTS]; @@ -1888,7 +1892,7 @@ LISP_INLINE void * XSAVE_POINTER (Lisp_Object obj, int n) { eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_POINTER); - return XSAVE_VALUE (obj)->data[n].pointer;; + return XSAVE_VALUE (obj)->data[n].pointer; } LISP_INLINE void set_save_pointer (Lisp_Object obj, int n, void *val) @@ -1896,6 +1900,12 @@ set_save_pointer (Lisp_Object obj, int n, void *val) eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_POINTER); XSAVE_VALUE (obj)->data[n].pointer = val; } +LISP_INLINE voidfuncptr +XSAVE_FUNCPOINTER (Lisp_Object obj, int n) +{ + eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_FUNCPOINTER); + return XSAVE_VALUE (obj)->data[n].funcpointer; +} /* Likewise for the saved integer. */ diff --git a/src/print.c b/src/print.c index 811ab5011ce..b1eec4c48d4 100644 --- a/src/print.c +++ b/src/print.c @@ -2103,6 +2103,12 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) v->data[index].pointer); break; + case SAVE_FUNCPOINTER: + i = sprintf (buf, "", + ((void *) (intptr_t) + v->data[index].funcpointer)); + break; + case SAVE_INTEGER: i = sprintf (buf, "", v->data[index].integer); @@ -2112,6 +2118,9 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) print_object (v->data[index].object, printcharfun, escapeflag); continue; + + default: + emacs_abort (); } strout (buf, i, i, printcharfun);