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:
parent
bb70a65f1d
commit
52a9bcae40
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
32
src/lisp.h
32
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. */
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user