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
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. */
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;
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))
}
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;
{
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 };
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))
/* 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 ();
...
}
- 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:
...
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 */
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];
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)
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. */