diff options
| author | Paul Eggert | 2013-07-01 20:41:16 -0700 |
|---|---|---|
| committer | Paul Eggert | 2013-07-01 20:41:16 -0700 |
| commit | 52a9bcae40a1c8536cf70cc4622a6877024e4b36 (patch) | |
| tree | 90f239c0a7f16286c3938b1e1f4c8b72ce56b1e9 /src | |
| parent | bb70a65f1de65b5abf87c0b43d03e55ed6e579f6 (diff) | |
| download | emacs-52a9bcae40a1c8536cf70cc4622a6877024e4b36.tar.gz emacs-52a9bcae40a1c8536cf70cc4622a6877024e4b36.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 15 | ||||
| -rw-r--r-- | src/alloc.c | 8 | ||||
| -rw-r--r-- | src/keymap.c | 6 | ||||
| -rw-r--r-- | src/lisp.h | 32 | ||||
| -rw-r--r-- | src/print.c | 9 |
5 files changed, 55 insertions, 15 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 2dc1af6d02b..13a9162caab 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,20 @@ | |||
| 1 | 2013-07-02 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2013-07-02 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 2 | ||
| 3 | Don't convert function pointers to void * and back. | ||
| 4 | It isn't portable C, and it's easy enough to avoid. | ||
| 5 | * alloc.c: Verify SAVE_FUNCPOINTER bits, too. | ||
| 6 | (make_save_value): Add support for SAVE_FUNCPOINTER. | ||
| 7 | * keymap.c (map_keymap_char_table_item, map_keymap_internal): | ||
| 8 | * print.c (print_object): | ||
| 9 | Distinguish function from object pointers. | ||
| 10 | * lisp.h (SAVE_FUNCPOINTER): New constant. | ||
| 11 | (SAVE_SLOT_BITS): Adjust to it. | ||
| 12 | (SAVE_TYPE_FUNCPTR_PTR_OBJ): New constant, replacing | ||
| 13 | SAVE_TYPE_PTR_PTR_OBJ. Change the only use. | ||
| 14 | (voidfuncptr): New typedef. | ||
| 15 | (struct Lisp_Save_Value): New member data[0].funcpointer. | ||
| 16 | (XSAVE_FUNCPOINTER): New function. | ||
| 17 | |||
| 3 | Simplify buildobj processing. | 18 | Simplify buildobj processing. |
| 4 | * Makefile.in (buildobj.h): Make it a sequence of strings each | 19 | * Makefile.in (buildobj.h): Make it a sequence of strings each |
| 5 | followed by comma, rather than a single string. Put it into a | 20 | 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) | |||
| 3352 | that are assumed here and elsewhere. */ | 3352 | that are assumed here and elsewhere. */ |
| 3353 | 3353 | ||
| 3354 | verify (SAVE_UNUSED == 0); | 3354 | verify (SAVE_UNUSED == 0); |
| 3355 | verify ((SAVE_INTEGER | SAVE_POINTER | SAVE_OBJECT) >> SAVE_SLOT_BITS == 0); | 3355 | verify (((SAVE_INTEGER | SAVE_POINTER | SAVE_FUNCPOINTER | SAVE_OBJECT) |
| 3356 | >> SAVE_SLOT_BITS) | ||
| 3357 | == 0); | ||
| 3356 | 3358 | ||
| 3357 | /* Return a Lisp_Save_Value object with the data saved according to | 3359 | /* Return a Lisp_Save_Value object with the data saved according to |
| 3358 | DATA_TYPE. DATA_TYPE should be one of SAVE_TYPE_INT_INT, etc. */ | 3360 | 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, ...) | |||
| 3379 | p->data[i].pointer = va_arg (ap, void *); | 3381 | p->data[i].pointer = va_arg (ap, void *); |
| 3380 | break; | 3382 | break; |
| 3381 | 3383 | ||
| 3384 | case SAVE_FUNCPOINTER: | ||
| 3385 | p->data[i].funcpointer = va_arg (ap, voidfuncptr); | ||
| 3386 | break; | ||
| 3387 | |||
| 3382 | case SAVE_INTEGER: | 3388 | case SAVE_INTEGER: |
| 3383 | p->data[i].integer = va_arg (ap, ptrdiff_t); | 3389 | p->data[i].integer = va_arg (ap, ptrdiff_t); |
| 3384 | break; | 3390 | 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) | |||
| 572 | if (!NILP (val)) | 572 | if (!NILP (val)) |
| 573 | { | 573 | { |
| 574 | map_keymap_function_t fun | 574 | map_keymap_function_t fun |
| 575 | = (map_keymap_function_t) XSAVE_POINTER (args, 0); | 575 | = (map_keymap_function_t) XSAVE_FUNCPOINTER (args, 0); |
| 576 | /* If the key is a range, make a copy since map_char_table modifies | 576 | /* If the key is a range, make a copy since map_char_table modifies |
| 577 | it in place. */ | 577 | it in place. */ |
| 578 | if (CONSP (key)) | 578 | if (CONSP (key)) |
| @@ -617,8 +617,8 @@ map_keymap_internal (Lisp_Object map, | |||
| 617 | } | 617 | } |
| 618 | else if (CHAR_TABLE_P (binding)) | 618 | else if (CHAR_TABLE_P (binding)) |
| 619 | map_char_table (map_keymap_char_table_item, Qnil, binding, | 619 | map_char_table (map_keymap_char_table_item, Qnil, binding, |
| 620 | make_save_value (SAVE_TYPE_PTR_PTR_OBJ, | 620 | make_save_value (SAVE_TYPE_FUNCPTR_PTR_OBJ, |
| 621 | fun, data, args)); | 621 | (voidfuncptr) fun, data, args)); |
| 622 | } | 622 | } |
| 623 | UNGCPRO; | 623 | UNGCPRO; |
| 624 | return tail; | 624 | 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 | |||
| 1777 | { | 1777 | { |
| 1778 | SAVE_UNUSED, | 1778 | SAVE_UNUSED, |
| 1779 | SAVE_INTEGER, | 1779 | SAVE_INTEGER, |
| 1780 | SAVE_FUNCPOINTER, | ||
| 1780 | SAVE_POINTER, | 1781 | SAVE_POINTER, |
| 1781 | SAVE_OBJECT | 1782 | SAVE_OBJECT |
| 1782 | }; | 1783 | }; |
| 1783 | 1784 | ||
| 1784 | /* Number of bits needed to store one of the above values. */ | 1785 | /* Number of bits needed to store one of the above values. */ |
| 1785 | enum { SAVE_SLOT_BITS = 2 }; | 1786 | enum { SAVE_SLOT_BITS = 3 }; |
| 1786 | 1787 | ||
| 1787 | /* Number of slots in a save value where save_type is nonzero. */ | 1788 | /* Number of slots in a save value where save_type is nonzero. */ |
| 1788 | enum { SAVE_VALUE_SLOTS = 4 }; | 1789 | enum { SAVE_VALUE_SLOTS = 4 }; |
| @@ -1803,8 +1804,8 @@ enum Lisp_Save_Type | |||
| 1803 | SAVE_TYPE_PTR_INT = SAVE_POINTER + (SAVE_INTEGER << SAVE_SLOT_BITS), | 1804 | SAVE_TYPE_PTR_INT = SAVE_POINTER + (SAVE_INTEGER << SAVE_SLOT_BITS), |
| 1804 | SAVE_TYPE_PTR_OBJ = SAVE_POINTER + (SAVE_OBJECT << SAVE_SLOT_BITS), | 1805 | SAVE_TYPE_PTR_OBJ = SAVE_POINTER + (SAVE_OBJECT << SAVE_SLOT_BITS), |
| 1805 | SAVE_TYPE_PTR_PTR = SAVE_POINTER + (SAVE_POINTER << SAVE_SLOT_BITS), | 1806 | SAVE_TYPE_PTR_PTR = SAVE_POINTER + (SAVE_POINTER << SAVE_SLOT_BITS), |
| 1806 | SAVE_TYPE_PTR_PTR_OBJ | 1807 | SAVE_TYPE_FUNCPTR_PTR_OBJ |
| 1807 | = SAVE_POINTER + (SAVE_TYPE_PTR_OBJ << SAVE_SLOT_BITS), | 1808 | = SAVE_FUNCPOINTER + (SAVE_TYPE_PTR_OBJ << SAVE_SLOT_BITS), |
| 1808 | 1809 | ||
| 1809 | /* This has an extra bit indicating it's raw memory. */ | 1810 | /* This has an extra bit indicating it's raw memory. */ |
| 1810 | SAVE_TYPE_MEMORY = SAVE_TYPE_PTR_INT + (1 << (SAVE_TYPE_BITS - 1)) | 1811 | SAVE_TYPE_MEMORY = SAVE_TYPE_PTR_INT + (1 << (SAVE_TYPE_BITS - 1)) |
| @@ -1813,9 +1814,9 @@ enum Lisp_Save_Type | |||
| 1813 | /* Special object used to hold a different values for later use. | 1814 | /* Special object used to hold a different values for later use. |
| 1814 | 1815 | ||
| 1815 | This is mostly used to package C integers and pointers to call | 1816 | This is mostly used to package C integers and pointers to call |
| 1816 | record_unwind_protect. Typical task is to pass just one C pointer | 1817 | record_unwind_protect. A typical task is to pass just one C object |
| 1817 | to unwind function. You should pack pointer with make_save_pointer | 1818 | pointer to the unwind function. You should pack an object pointer with |
| 1818 | and then get it back with XSAVE_POINTER, e.g.: | 1819 | make_save_pointer and then get it back with XSAVE_POINTER, e.g.: |
| 1819 | 1820 | ||
| 1820 | ... | 1821 | ... |
| 1821 | struct my_data *md = get_my_data (); | 1822 | struct my_data *md = get_my_data (); |
| @@ -1828,10 +1829,10 @@ enum Lisp_Save_Type | |||
| 1828 | ... | 1829 | ... |
| 1829 | } | 1830 | } |
| 1830 | 1831 | ||
| 1831 | If yon need to pass more than just one C pointer, you should | 1832 | If you need to pass something else you can use make_save_value, |
| 1832 | use make_save_value. This function allows you to pack up to | 1833 | which allows you to pack up to SAVE_VALUE_SLOTS integers, pointers, |
| 1833 | SAVE_VALUE_SLOTS integers, pointers or Lisp_Objects and | 1834 | function pointers or Lisp_Objects and conveniently get them back |
| 1834 | conveniently get them back with XSAVE_POINTER, XSAVE_INTEGER and | 1835 | with XSAVE_INTEGER, XSAVE_POINTER, XSAVE_FUNCPOINTER, and |
| 1835 | XSAVE_OBJECT macros: | 1836 | XSAVE_OBJECT macros: |
| 1836 | 1837 | ||
| 1837 | ... | 1838 | ... |
| @@ -1854,6 +1855,8 @@ enum Lisp_Save_Type | |||
| 1854 | or XSAVE_OBJECT (arg, 0) are wrong because nothing was saved in slot 2 and | 1855 | or XSAVE_OBJECT (arg, 0) are wrong because nothing was saved in slot 2 and |
| 1855 | Lisp_Object was saved in slot 1 of ARG. */ | 1856 | Lisp_Object was saved in slot 1 of ARG. */ |
| 1856 | 1857 | ||
| 1858 | typedef void (*voidfuncptr) (void); | ||
| 1859 | |||
| 1857 | struct Lisp_Save_Value | 1860 | struct Lisp_Save_Value |
| 1858 | { | 1861 | { |
| 1859 | ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Save_Value */ | 1862 | ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Save_Value */ |
| @@ -1869,6 +1872,7 @@ struct Lisp_Save_Value | |||
| 1869 | ENUM_BF (Lisp_Save_Type) save_type : SAVE_TYPE_BITS; | 1872 | ENUM_BF (Lisp_Save_Type) save_type : SAVE_TYPE_BITS; |
| 1870 | union { | 1873 | union { |
| 1871 | void *pointer; | 1874 | void *pointer; |
| 1875 | voidfuncptr funcpointer; | ||
| 1872 | ptrdiff_t integer; | 1876 | ptrdiff_t integer; |
| 1873 | Lisp_Object object; | 1877 | Lisp_Object object; |
| 1874 | } data[SAVE_VALUE_SLOTS]; | 1878 | } data[SAVE_VALUE_SLOTS]; |
| @@ -1888,7 +1892,7 @@ LISP_INLINE void * | |||
| 1888 | XSAVE_POINTER (Lisp_Object obj, int n) | 1892 | XSAVE_POINTER (Lisp_Object obj, int n) |
| 1889 | { | 1893 | { |
| 1890 | eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_POINTER); | 1894 | eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_POINTER); |
| 1891 | return XSAVE_VALUE (obj)->data[n].pointer;; | 1895 | return XSAVE_VALUE (obj)->data[n].pointer; |
| 1892 | } | 1896 | } |
| 1893 | LISP_INLINE void | 1897 | LISP_INLINE void |
| 1894 | set_save_pointer (Lisp_Object obj, int n, void *val) | 1898 | set_save_pointer (Lisp_Object obj, int n, void *val) |
| @@ -1896,6 +1900,12 @@ set_save_pointer (Lisp_Object obj, int n, void *val) | |||
| 1896 | eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_POINTER); | 1900 | eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_POINTER); |
| 1897 | XSAVE_VALUE (obj)->data[n].pointer = val; | 1901 | XSAVE_VALUE (obj)->data[n].pointer = val; |
| 1898 | } | 1902 | } |
| 1903 | LISP_INLINE voidfuncptr | ||
| 1904 | XSAVE_FUNCPOINTER (Lisp_Object obj, int n) | ||
| 1905 | { | ||
| 1906 | eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_FUNCPOINTER); | ||
| 1907 | return XSAVE_VALUE (obj)->data[n].funcpointer; | ||
| 1908 | } | ||
| 1899 | 1909 | ||
| 1900 | /* Likewise for the saved integer. */ | 1910 | /* Likewise for the saved integer. */ |
| 1901 | 1911 | ||
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) | |||
| 2103 | v->data[index].pointer); | 2103 | v->data[index].pointer); |
| 2104 | break; | 2104 | break; |
| 2105 | 2105 | ||
| 2106 | case SAVE_FUNCPOINTER: | ||
| 2107 | i = sprintf (buf, "<funcpointer %p>", | ||
| 2108 | ((void *) (intptr_t) | ||
| 2109 | v->data[index].funcpointer)); | ||
| 2110 | break; | ||
| 2111 | |||
| 2106 | case SAVE_INTEGER: | 2112 | case SAVE_INTEGER: |
| 2107 | i = sprintf (buf, "<integer %"pD"d>", | 2113 | i = sprintf (buf, "<integer %"pD"d>", |
| 2108 | v->data[index].integer); | 2114 | v->data[index].integer); |
| @@ -2112,6 +2118,9 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) | |||
| 2112 | print_object (v->data[index].object, printcharfun, | 2118 | print_object (v->data[index].object, printcharfun, |
| 2113 | escapeflag); | 2119 | escapeflag); |
| 2114 | continue; | 2120 | continue; |
| 2121 | |||
| 2122 | default: | ||
| 2123 | emacs_abort (); | ||
| 2115 | } | 2124 | } |
| 2116 | 2125 | ||
| 2117 | strout (buf, i, i, printcharfun); | 2126 | strout (buf, i, i, printcharfun); |