1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-27 07:37:33 +00:00

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.
This commit is contained in:
Paul Eggert 2013-07-01 20:41:16 -07:00
parent bb70a65f1d
commit 52a9bcae40
5 changed files with 55 additions and 15 deletions

View File

@ -1,5 +1,20 @@
2013-07-02 Paul Eggert <eggert@cs.ucla.edu>
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

View File

@ -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;

View File

@ -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;

View File

@ -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. */

View File

@ -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, "<funcpointer %p>",
((void *) (intptr_t)
v->data[index].funcpointer));
break;
case SAVE_INTEGER:
i = sprintf (buf, "<integer %"pD"d>",
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);