Mercurial > hg > xemacs-beta
comparison src/lisp.h @ 5126:2a462149bd6a ben-lisp-object
merge
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Wed, 24 Feb 2010 19:04:27 -0600 |
parents | b5df3737028a 92dc90c0bb40 |
children | a9c41067dd88 |
comparison
equal
deleted
inserted
replaced
5125:b5df3737028a | 5126:2a462149bd6a |
---|---|
315 these become needed, they can always be defined. */ | 315 these become needed, they can always be defined. */ |
316 | 316 |
317 #ifdef ERROR_CHECK_STRUCTURES | 317 #ifdef ERROR_CHECK_STRUCTURES |
318 /* Check for problems with the catch list and specbind stack */ | 318 /* Check for problems with the catch list and specbind stack */ |
319 #define ERROR_CHECK_CATCH | 319 #define ERROR_CHECK_CATCH |
320 /* Check for incoherent Dynarr structures, attempts to access Dynarr | 320 /* Check for incoherent dynarr structures, attempts to access Dynarr |
321 positions out of range, reentrant use of Dynarrs through Dynarr locking, | 321 positions out of range, reentrant use of dynarrs through dynarr locking, |
322 etc. */ | 322 etc. */ |
323 #define ERROR_CHECK_DYNARR | 323 #define ERROR_CHECK_DYNARR |
324 /* Check for insufficient use of call_trapping_problems(), particularly | 324 /* Check for insufficient use of call_trapping_problems(), particularly |
325 due to glyph-related changes causing eval or QUIT within redisplay */ | 325 due to glyph-related changes causing eval or QUIT within redisplay */ |
326 #define ERROR_CHECK_TRAPPING_PROBLEMS | 326 #define ERROR_CHECK_TRAPPING_PROBLEMS |
1231 MODULE_API void assert_failed (const Ascbyte *, int, const Ascbyte *); | 1231 MODULE_API void assert_failed (const Ascbyte *, int, const Ascbyte *); |
1232 #define ABORT() assert_failed (__FILE__, __LINE__, "ABORT()") | 1232 #define ABORT() assert_failed (__FILE__, __LINE__, "ABORT()") |
1233 #define abort_with_message(msg) assert_failed (__FILE__, __LINE__, msg) | 1233 #define abort_with_message(msg) assert_failed (__FILE__, __LINE__, msg) |
1234 | 1234 |
1235 /* This used to be ((void) (0)) but that triggers lots of unused variable | 1235 /* This used to be ((void) (0)) but that triggers lots of unused variable |
1236 warnings. It's pointless to force all that code to be rewritten, with | 1236 warnings -- furthermore, if `x' has any side effects, e.g. |
1237 added ifdefs. Any reasonable compiler will eliminate an expression with | 1237 assert (++depth <= 20);, we DEFINITELY want to execute the code inside of |
1238 `x'. Any reasonable compiler will eliminate an expression with | |
1238 no effects. We keep this abstracted out like this in case we want to | 1239 no effects. We keep this abstracted out like this in case we want to |
1239 change it in the future. */ | 1240 change it in the future. */ |
1240 #define disabled_assert(x) ((void) (x)) | 1241 #define disabled_assert(x) ((void) (x)) |
1241 #define disabled_assert_with_message(x, msg) ((void) msg, disabled_assert (x)) | 1242 #define disabled_assert_with_message(x, msg) ((void) msg, disabled_assert (x)) |
1242 #define disabled_assert_at_line(x, file, line) \ | 1243 #define disabled_assert_at_line(x, file, line) \ |
1453 | 1454 |
1454 /* Note that the simplest typedefs are near the top of this file. */ | 1455 /* Note that the simplest typedefs are near the top of this file. */ |
1455 | 1456 |
1456 /* We put typedefs here so that prototype declarations don't choke. | 1457 /* We put typedefs here so that prototype declarations don't choke. |
1457 Note that we don't actually declare the structures here (except | 1458 Note that we don't actually declare the structures here (except |
1458 maybe for simple structures like Dynarrs); that keeps them private | 1459 maybe for simple structures like dynarrs); that keeps them private |
1459 to the routines that actually use them. */ | 1460 to the routines that actually use them. */ |
1460 | 1461 |
1461 /* ------------------------------- */ | 1462 /* ------------------------------- */ |
1462 /* Error_Behavior typedefs */ | 1463 /* Error_Behavior typedefs */ |
1463 /* ------------------------------- */ | 1464 /* ------------------------------- */ |
1719 EMACS_UINT p = XUINT (obj); | 1720 EMACS_UINT p = XUINT (obj); |
1720 return (void *) (p << 1); | 1721 return (void *) (p << 1); |
1721 } | 1722 } |
1722 | 1723 |
1723 /************************************************************************/ | 1724 /************************************************************************/ |
1724 /** Definitions of dynamic arrays (Dynarrs) and other allocators **/ | 1725 /** Definitions of dynamic arrays (dynarrs) and other allocators **/ |
1725 /************************************************************************/ | 1726 /************************************************************************/ |
1726 | 1727 |
1727 BEGIN_C_DECLS | 1728 BEGIN_C_DECLS |
1728 | 1729 |
1729 /************* Dynarr declaration *************/ | 1730 /************* Dynarr declaration *************/ |
1745 #define Dynarr_declare(type) \ | 1746 #define Dynarr_declare(type) \ |
1746 struct lrecord_header header; \ | 1747 struct lrecord_header header; \ |
1747 type *base; \ | 1748 type *base; \ |
1748 DECLARE_DYNARR_LISP_IMP () \ | 1749 DECLARE_DYNARR_LISP_IMP () \ |
1749 DECLARE_DYNARR_LOCKED () \ | 1750 DECLARE_DYNARR_LOCKED () \ |
1750 int elsize; \ | 1751 int elsize_; \ |
1751 int len_; \ | 1752 int len_; \ |
1752 int largest_; \ | 1753 int largest_; \ |
1753 int max_ | 1754 int max_ |
1754 | 1755 |
1755 typedef struct dynarr | 1756 typedef struct dynarr |
1773 { XD_INT_RESET, offsetof (base_type, max_), XD_INDIRECT(1, 0) } | 1774 { XD_INT_RESET, offsetof (base_type, max_), XD_INDIRECT(1, 0) } |
1774 #endif /* NEW_GC */ | 1775 #endif /* NEW_GC */ |
1775 | 1776 |
1776 /************* Dynarr verification *************/ | 1777 /************* Dynarr verification *************/ |
1777 | 1778 |
1779 /* Dynarr locking and verification. | |
1780 | |
1781 [I] VERIFICATION | |
1782 | |
1783 Verification routines simply return their basic argument, possibly | |
1784 casted, but in the process perform some verification on it, aborting if | |
1785 the verification fails. The verification routines take FILE and LINE | |
1786 parameters, and use them to output the file and line of the caller | |
1787 when an abort occurs, rather than the file and line of the inline | |
1788 function, which is less than useful. | |
1789 | |
1790 There are three basic types of verification routines: | |
1791 | |
1792 (1) Verify the dynarr itself. This verifies the basic invariant | |
1793 involving the length/size values: | |
1794 | |
1795 0 <= Dynarr_length(d) <= Dynarr_largest(d) <= Dynarr_max(d) | |
1796 | |
1797 (2) Verify the dynarr itself prior to modifying it. This performs | |
1798 the same verification as previously, but also checks that the | |
1799 dynarr is not locked (see below). | |
1800 | |
1801 (3) Verify a dynarr position. Unfortunately we have to have | |
1802 different verification routines depending on which kind of operation | |
1803 is being performed: | |
1804 | |
1805 (a) For Dynarr_at(), we check that the POS is bounded by Dynarr_largest(), | |
1806 i.e. 0 <= POS < Dynarr_largest(). | |
1807 (b) For Dynarr_atp_allow_end(), we also have to allow | |
1808 POS == Dynarr_largest(). | |
1809 (c) For Dynarr_atp(), we behave largely like Dynarr_at() but make a | |
1810 special exception when POS == 0 and Dynarr_largest() == 0 -- see | |
1811 comment below. | |
1812 (d) Some other routines contain the POS verification within their code, | |
1813 and make the check 0 <= POS < Dynarr_length() or | |
1814 0 <= POS <= Dynarr_length(). | |
1815 | |
1816 #### It is not well worked-out whether and in what circumstances it's | |
1817 allowed to use a position that is between Dynarr_length() and | |
1818 Dynarr_largest(). The ideal solution is to never allow this, and require | |
1819 instead that code first change the length before accessing higher | |
1820 positions. That would require looking through all the code that accesses | |
1821 dynarrs and fixing it appropriately (especially redisplay code, and | |
1822 especially redisplay code in the vicinity of a reference to | |
1823 Dynarr_largest(), since such code usually checks explicitly to see whether | |
1824 there is extra stuff between Dynarr_length() and Dynarr_largest().) | |
1825 | |
1826 [II] LOCKING | |
1827 | |
1828 The idea behind dynarr locking is simple: Locking a dynarr prevents | |
1829 any modification from occurring, or rather, leads to an abort upon | |
1830 any attempt to modify a dynarr. | |
1831 | |
1832 Dynarr locking was originally added to catch some sporadic and hard-to- | |
1833 debug crashes in the redisplay code where dynarrs appeared to be getting | |
1834 corrupted in an unexpected fashion. The solution was to lock the | |
1835 dynarrs that were getting corrupted (in this case, the display-line | |
1836 dynarrs) around calls to routines that weren't supposed to be changing | |
1837 these dynarrs but might somehow be calling code that modified them. | |
1838 This eventually revealed that there was a reentrancy problem with | |
1839 redisplay that involved the QUIT mechanism and the processing done in | |
1840 order to determine whether C-g had been pressed -- this processing | |
1841 involves retrieving, processing and queueing pending events to see | |
1842 whether any of them result in a C-g keypress. However, at least under | |
1843 MS Windows this can result in redisplay being called reentrantly. | |
1844 For more info:-- | |
1845 | |
1846 (Info-goto-node "(internals)Critical Redisplay Sections") | |
1847 | |
1848 */ | |
1849 | |
1778 #ifdef ERROR_CHECK_DYNARR | 1850 #ifdef ERROR_CHECK_DYNARR |
1779 DECLARE_INLINE_HEADER ( | 1851 DECLARE_INLINE_HEADER ( |
1780 int | 1852 int |
1781 Dynarr_verify_pos_at (void *d, int pos, const Ascbyte *file, int line) | 1853 Dynarr_verify_pos_at (void *d, Elemcount pos, const Ascbyte *file, int line) |
1782 ) | 1854 ) |
1783 { | 1855 { |
1784 Dynarr *dy = (Dynarr *) d; | 1856 Dynarr *dy = (Dynarr *) d; |
1785 /* We use `largest', not `len', because the redisplay code often | 1857 /* We use `largest', not `len', because the redisplay code often |
1786 accesses stuff between len and largest. */ | 1858 accesses stuff between len and largest. */ |
1788 return pos; | 1860 return pos; |
1789 } | 1861 } |
1790 | 1862 |
1791 DECLARE_INLINE_HEADER ( | 1863 DECLARE_INLINE_HEADER ( |
1792 int | 1864 int |
1793 Dynarr_verify_pos_atp (void *d, int pos, const Ascbyte *file, int line) | 1865 Dynarr_verify_pos_atp (void *d, Elemcount pos, const Ascbyte *file, int line) |
1794 ) | 1866 ) |
1795 { | 1867 { |
1796 Dynarr *dy = (Dynarr *) d; | 1868 Dynarr *dy = (Dynarr *) d; |
1797 /* We use `largest', not `len', because the redisplay code often | 1869 /* We use `largest', not `len', because the redisplay code often |
1798 accesses stuff between len and largest. */ | 1870 accesses stuff between len and largest. */ |
1828 return pos; | 1900 return pos; |
1829 } | 1901 } |
1830 | 1902 |
1831 DECLARE_INLINE_HEADER ( | 1903 DECLARE_INLINE_HEADER ( |
1832 int | 1904 int |
1833 Dynarr_verify_pos_atp_allow_end (void *d, int pos, const Ascbyte *file, | 1905 Dynarr_verify_pos_atp_allow_end (void *d, Elemcount pos, const Ascbyte *file, |
1834 int line) | 1906 int line) |
1835 ) | 1907 ) |
1836 { | 1908 { |
1837 Dynarr *dy = (Dynarr *) d; | 1909 Dynarr *dy = (Dynarr *) d; |
1838 /* We use `largest', not `len', because the redisplay code often | 1910 /* We use `largest', not `len', because the redisplay code often |
1871 return Dynarr_verify_1 (d, file, line); | 1943 return Dynarr_verify_1 (d, file, line); |
1872 } | 1944 } |
1873 | 1945 |
1874 #define Dynarr_verify(d) Dynarr_verify_1 (d, __FILE__, __LINE__) | 1946 #define Dynarr_verify(d) Dynarr_verify_1 (d, __FILE__, __LINE__) |
1875 #define Dynarr_verify_mod(d) Dynarr_verify_mod_1 (d, __FILE__, __LINE__) | 1947 #define Dynarr_verify_mod(d) Dynarr_verify_mod_1 (d, __FILE__, __LINE__) |
1876 #define Dynarr_lock(d) \ | 1948 |
1877 do { \ | 1949 DECLARE_INLINE_HEADER ( |
1878 Dynarr *dy = Dynarr_verify_mod (d); \ | 1950 void |
1879 dy->locked = 1; \ | 1951 Dynarr_lock (void *d) |
1880 } while (0) | 1952 ) |
1881 #define Dynarr_unlock(d) \ | 1953 { |
1882 do { \ | 1954 Dynarr *dy = Dynarr_verify_mod (d); |
1883 Dynarr *dy = Dynarr_verify (d); \ | 1955 dy->locked = 1; |
1884 dy->locked = 0; \ | 1956 } |
1885 } while (0) | 1957 |
1886 #else | 1958 DECLARE_INLINE_HEADER ( |
1959 void | |
1960 Dynarr_unlock (void *d) | |
1961 ) | |
1962 { | |
1963 Dynarr *dy = Dynarr_verify (d); | |
1964 assert (dy->locked); | |
1965 dy->locked = 0; | |
1966 } | |
1967 | |
1968 #else /* not ERROR_CHECK_DYNARR */ | |
1969 | |
1887 #define Dynarr_verify(d) ((Dynarr *) d) | 1970 #define Dynarr_verify(d) ((Dynarr *) d) |
1888 #define Dynarr_verify_mod(d) ((Dynarr *) d) | 1971 #define Dynarr_verify_mod(d) ((Dynarr *) d) |
1889 #define Dynarr_lock(d) DO_NOTHING | 1972 #define Dynarr_lock(d) DO_NOTHING |
1890 #define Dynarr_unlock(d) DO_NOTHING | 1973 #define Dynarr_unlock(d) DO_NOTHING |
1974 | |
1891 #endif /* ERROR_CHECK_DYNARR */ | 1975 #endif /* ERROR_CHECK_DYNARR */ |
1892 | 1976 |
1893 /************* Dynarr creation *************/ | 1977 /************* Dynarr creation *************/ |
1894 | 1978 |
1895 MODULE_API void *Dynarr_newf (Bytecount elsize); | 1979 MODULE_API void *Dynarr_newf (Bytecount elsize); |
1931 #define Dynarr_past_lastp(d) Dynarr_atp_allow_end (d, Dynarr_length (d)) | 2015 #define Dynarr_past_lastp(d) Dynarr_atp_allow_end (d, Dynarr_length (d)) |
1932 | 2016 |
1933 | 2017 |
1934 /************* Dynarr length/size retrieval and setting *************/ | 2018 /************* Dynarr length/size retrieval and setting *************/ |
1935 | 2019 |
1936 /* Retrieve the length of a Dynarr. The `+ 0' is to ensure that this cannot | 2020 /* Retrieve the length of a dynarr. The `+ 0' is to ensure that this cannot |
1937 be used as an lvalue. */ | 2021 be used as an lvalue. */ |
1938 #define Dynarr_length(d) (Dynarr_verify (d)->len_ + 0) | 2022 #define Dynarr_length(d) (Dynarr_verify (d)->len_ + 0) |
1939 /* Retrieve the largest ever length seen of a Dynarr. The `+ 0' is to | 2023 /* Retrieve the largest ever length seen of a dynarr. The `+ 0' is to |
1940 ensure that this cannot be used as an lvalue. */ | 2024 ensure that this cannot be used as an lvalue. */ |
1941 #define Dynarr_largest(d) (Dynarr_verify (d)->largest_ + 0) | 2025 #define Dynarr_largest(d) (Dynarr_verify (d)->largest_ + 0) |
1942 /* Retrieve the number of elements that fit in the currently allocated | 2026 /* Retrieve the number of elements that fit in the currently allocated |
1943 space. The `+ 0' is to ensure that this cannot be used as an lvalue. */ | 2027 space. The `+ 0' is to ensure that this cannot be used as an lvalue. */ |
1944 #define Dynarr_max(d) (Dynarr_verify (d)->max_ + 0) | 2028 #define Dynarr_max(d) (Dynarr_verify (d)->max_ + 0) |
1945 /* Retrieve the advertised memory usage of a Dynarr, i.e. the number of | 2029 /* Return the size in bytes of an element in a dynarr. */ |
1946 bytes occupied by the elements in the Dynarr, not counting any overhead. */ | 2030 #define Dynarr_elsize(d) (Dynarr_verify (d)->elsize_ + 0) |
1947 #define Dynarr_sizeof(d) (Dynarr_length (d) * (d)->elsize) | 2031 /* Retrieve the advertised memory usage of a dynarr, i.e. the number of |
1948 /* Actually set the length of a Dynarr. This is a low-level routine that | 2032 bytes occupied by the elements in the dynarr, not counting any overhead. */ |
1949 should not be directly used; use Dynarr_set_length() instead if you need | 2033 #define Dynarr_sizeof(d) (Dynarr_length (d) * Dynarr_elsize (d)) |
1950 to, but be very careful when doing so! */ | 2034 |
1951 #define Dynarr_set_length_1(d, n) \ | 2035 /* Actually set the length of a dynarr. This is a low-level routine that |
1952 do { \ | 2036 should not be directly used; use Dynarr_set_length() or |
1953 Elemcount _dsl1_n = (n); \ | 2037 Dynarr_set_lengthr() instead. */ |
1954 dynarr_checking_assert (_dsl1_n >= 0 && _dsl1_n <= Dynarr_max (d)); \ | 2038 DECLARE_INLINE_HEADER ( |
1955 (void) Dynarr_verify_mod (d); \ | 2039 void |
1956 (d)->len_ = _dsl1_n; \ | 2040 Dynarr_set_length_1 (void *d, Elemcount len) |
1957 /* Use the raw field references here otherwise we get a crash because \ | 2041 ) |
1958 we've set the length but not yet fixed up the largest value. */ \ | 2042 { |
1959 if ((d)->len_ > (d)->largest_) \ | 2043 Dynarr *dy = Dynarr_verify_mod (d); |
1960 (d)->largest_ = (d)->len_; \ | 2044 dynarr_checking_assert (len >= 0 && len <= Dynarr_max (dy)); |
1961 (void) Dynarr_verify_mod (d); \ | 2045 /* Use the raw field references here otherwise we get a crash because |
1962 } while (0) | 2046 we've set the length but not yet fixed up the largest value. */ |
1963 | 2047 dy->len_ = len; |
1964 /* The following two defines will get you into real trouble if you aren't | 2048 if (dy->len_ > dy->largest_) |
1965 careful. But they can save a lot of execution time when used wisely. */ | 2049 dy->largest_ = dy->len_; |
1966 #define Dynarr_set_length(d, n) \ | 2050 (void) Dynarr_verify_mod (d); |
1967 do { \ | 2051 } |
1968 Elemcount _dsl_n = (n); \ | 2052 |
1969 dynarr_checking_assert (_dsl_n >= 0 && _dsl_n <= Dynarr_largest (d)); \ | 2053 /* "Restricted set-length": Set the length of dynarr D to LEN, |
1970 Dynarr_set_length_1 (d, _dsl_n); \ | 2054 which must be in the range [0, Dynarr_largest(d)]. */ |
1971 } while (0) | 2055 |
1972 #define Dynarr_increment(d) \ | 2056 DECLARE_INLINE_HEADER ( |
1973 Dynarr_set_length (d, Dynarr_length (d) + 1) | 2057 void |
1974 | 2058 Dynarr_set_lengthr (void *d, Elemcount len) |
1975 /* Reset the Dynarr's length to 0. */ | 2059 ) |
1976 #define Dynarr_reset(d) Dynarr_set_length (d, 0) | 2060 { |
1977 | 2061 Dynarr *dy = Dynarr_verify_mod (d); |
1978 MODULE_API void Dynarr_resize (void *dy, Elemcount size); | 2062 dynarr_checking_assert (len >= 0 && len <= Dynarr_largest (dy)); |
1979 | 2063 Dynarr_set_length_1 (dy, len); |
1980 #define Dynarr_resize_if(d, numels) \ | 2064 } |
1981 do { \ | 2065 |
1982 Elemcount _dri_numels = (numels); \ | 2066 /* "Restricted increment": Increment the length of dynarr D by 1; the resulting |
1983 if (Dynarr_length (d) + _dri_numels > Dynarr_max (d)) \ | 2067 length must be in the range [0, Dynarr_largest(d)]. */ |
1984 Dynarr_resize (d, Dynarr_length (d) + _dri_numels); \ | 2068 |
1985 } while (0) | 2069 #define Dynarr_incrementr(d) Dynarr_set_lengthr (d, Dynarr_length (d) + 1) |
2070 | |
2071 | |
2072 MODULE_API void Dynarr_resize (void *d, Elemcount size); | |
2073 | |
2074 DECLARE_INLINE_HEADER ( | |
2075 void | |
2076 Dynarr_resize_to_fit (void *d, Elemcount size) | |
2077 ) | |
2078 { | |
2079 Dynarr *dy = Dynarr_verify_mod (d); | |
2080 if (size > Dynarr_max (dy)) | |
2081 Dynarr_resize (dy, size); | |
2082 } | |
2083 | |
2084 #define Dynarr_resize_to_add(d, numels) \ | |
2085 Dynarr_resize_to_fit (d, Dynarr_length (d) + numels) | |
2086 | |
2087 /* This is an optimization. This is like Dynarr_set_length() but the length | |
2088 is guaranteed to be at least as big as the existing length. */ | |
2089 | |
2090 DECLARE_INLINE_HEADER ( | |
2091 void | |
2092 Dynarr_increase_length (void *d, Elemcount len) | |
2093 ) | |
2094 { | |
2095 Dynarr *dy = Dynarr_verify_mod (d); | |
2096 dynarr_checking_assert (len >= Dynarr_length (dy)); | |
2097 Dynarr_resize_to_fit (dy, len); | |
2098 Dynarr_set_length_1 (dy, len); | |
2099 } | |
2100 | |
2101 /* Set the length of dynarr D to LEN. If the length increases, resize as | |
2102 necessary to fit. (NOTE: This will leave uninitialized memory. If you | |
2103 aren't planning on immediately overwriting the memory, use | |
2104 Dynarr_set_length_and_zero() to zero out all the memory that would | |
2105 otherwise be uninitialized.) */ | |
2106 | |
2107 DECLARE_INLINE_HEADER ( | |
2108 void | |
2109 Dynarr_set_length (void *d, Elemcount len) | |
2110 ) | |
2111 { | |
2112 Dynarr *dy = Dynarr_verify_mod (d); | |
2113 Elemcount old_len = Dynarr_length (dy); | |
2114 if (old_len >= len) | |
2115 Dynarr_set_lengthr (dy, len); | |
2116 else | |
2117 Dynarr_increase_length (d, len); | |
2118 } | |
2119 | |
2120 #define Dynarr_increment(d) Dynarr_increase_length (d, Dynarr_length (d) + 1) | |
2121 | |
2122 /* Zero LEN contiguous elements starting at POS. */ | |
2123 | |
2124 DECLARE_INLINE_HEADER ( | |
2125 void | |
2126 Dynarr_zero_many (void *d, Elemcount pos, Elemcount len) | |
2127 ) | |
2128 { | |
2129 Dynarr *dy = Dynarr_verify_mod (d); | |
2130 memset ((Rawbyte *) dy->base + pos*Dynarr_elsize (dy), 0, | |
2131 len*Dynarr_elsize (dy)); | |
2132 } | |
2133 | |
2134 /* This is an optimization. This is like Dynarr_set_length_and_zero() but | |
2135 the length is guaranteed to be at least as big as the existing | |
2136 length. */ | |
2137 | |
2138 DECLARE_INLINE_HEADER ( | |
2139 void | |
2140 Dynarr_increase_length_and_zero (void *d, Elemcount len) | |
2141 ) | |
2142 { | |
2143 Dynarr *dy = Dynarr_verify_mod (d); | |
2144 Elemcount old_len = Dynarr_length (dy); | |
2145 Dynarr_increase_length (dy, len); | |
2146 Dynarr_zero_many (dy, old_len, len - old_len); | |
2147 } | |
2148 | |
2149 /* Set the length of dynarr D to LEN. If the length increases, resize as | |
2150 necessary to fit and zero out all the elements between the old and new | |
2151 lengths. */ | |
2152 | |
2153 DECLARE_INLINE_HEADER ( | |
2154 void | |
2155 Dynarr_set_length_and_zero (void *d, Elemcount len) | |
2156 ) | |
2157 { | |
2158 Dynarr *dy = Dynarr_verify_mod (d); | |
2159 Elemcount old_len = Dynarr_length (dy); | |
2160 if (old_len >= len) | |
2161 Dynarr_set_lengthr (dy, len); | |
2162 else | |
2163 Dynarr_increase_length_and_zero (d, len); | |
2164 } | |
2165 | |
2166 /* Reset the dynarr's length to 0. */ | |
2167 #define Dynarr_reset(d) Dynarr_set_lengthr (d, 0) | |
1986 | 2168 |
1987 #ifdef MEMORY_USAGE_STATS | 2169 #ifdef MEMORY_USAGE_STATS |
1988 struct overhead_stats; | 2170 struct overhead_stats; |
1989 Bytecount Dynarr_memory_usage (void *d, struct overhead_stats *stats); | 2171 Bytecount Dynarr_memory_usage (void *d, struct overhead_stats *stats); |
1990 #endif | 2172 #endif |
1991 | 2173 |
1992 /************* Adding/deleting elements to/from a Dynarr *************/ | 2174 /************* Adding/deleting elements to/from a dynarr *************/ |
2175 | |
2176 /* Set the Lisp implementation of the element at POS in dynarr D. Only | |
2177 does this if the dynarr holds Lisp objects of a particular type (the | |
2178 objects themselves, not pointers to them), and only under NEW_GC. */ | |
1993 | 2179 |
1994 #ifdef NEW_GC | 2180 #ifdef NEW_GC |
1995 #define Dynarr_add(d, el) \ | 2181 #define DYNARR_SET_LISP_IMP(d, pos) \ |
1996 do { \ | 2182 do { \ |
1997 const struct lrecord_implementation *imp = (d)->lisp_imp; \ | 2183 if ((d)->lisp_imp) \ |
1998 (void) Dynarr_verify_mod (d); \ | |
1999 Dynarr_resize_if (d, 1); \ | |
2000 ((d)->base)[Dynarr_length (d)] = (el); \ | |
2001 if (imp) \ | |
2002 set_lheader_implementation \ | 2184 set_lheader_implementation \ |
2003 ((struct lrecord_header *)&(((d)->base)[Dynarr_length (d)]), imp); \ | 2185 ((struct lrecord_header *)&(((d)->base)[pos]), (d)->lisp_imp); \ |
2004 Dynarr_set_length_1 (d, Dynarr_length (d) + 1); \ | 2186 } while (0) |
2005 (void) Dynarr_verify_mod (d); \ | 2187 #else |
2188 #define DYNARR_SET_LISP_IMP(d, pos) DO_NOTHING | |
2189 #endif /* (not) NEW_GC */ | |
2190 | |
2191 /* Add Element EL to the end of dynarr D. */ | |
2192 | |
2193 #define Dynarr_add(d, el) \ | |
2194 do { \ | |
2195 Elemcount _da_pos = Dynarr_length (d); \ | |
2196 (void) Dynarr_verify_mod (d); \ | |
2197 Dynarr_increment (d); \ | |
2198 ((d)->base)[_da_pos] = (el); \ | |
2199 DYNARR_SET_LISP_IMP (d, _da_pos); \ | |
2006 } while (0) | 2200 } while (0) |
2007 #else /* not NEW_GC */ | 2201 |
2008 #define Dynarr_add(d, el) \ | 2202 /* Set EL as the element at position POS in dynarr D. |
2203 Expand the dynarr as necessary so that its length is enough to include | |
2204 position POS within it, and zero out any new elements created as a | |
2205 result of expansion, other than the one at POS. */ | |
2206 | |
2207 #define Dynarr_set(d, pos, el) \ | |
2009 do { \ | 2208 do { \ |
2209 Elemcount _ds_pos = (pos); \ | |
2010 (void) Dynarr_verify_mod (d); \ | 2210 (void) Dynarr_verify_mod (d); \ |
2011 Dynarr_resize_if (d, 1); \ | 2211 if (Dynarr_length (d) < _ds_pos + 1) \ |
2012 ((d)->base)[Dynarr_length (d)] = (el); \ | 2212 Dynarr_increase_length_and_zero (d, _ds_pos + 1); \ |
2013 Dynarr_set_length_1 (d, Dynarr_length (d) + 1); \ | 2213 ((d)->base)[_ds_pos] = (el); \ |
2014 (void) Dynarr_verify_mod (d); \ | 2214 DYNARR_SET_LISP_IMP (d, _ds_pos); \ |
2015 } while (0) | 2215 } while (0) |
2016 #endif /* not NEW_GC */ | 2216 |
2017 | 2217 /* Add LEN contiguous elements, stored at BASE, to dynarr D. If BASE is |
2018 | 2218 NULL, reserve space but don't store anything. */ |
2019 MODULE_API void Dynarr_insert_many (void *d, const void *el, int len, | 2219 |
2020 int start); | 2220 DECLARE_INLINE_HEADER ( |
2021 MODULE_API void Dynarr_delete_many (void *d, int start, int len); | 2221 void |
2022 | 2222 Dynarr_add_many (void *d, const void *base, Elemcount len) |
2023 #define Dynarr_insert_many_at_start(d, el, len) \ | 2223 ) |
2024 Dynarr_insert_many (d, el, len, 0) | 2224 { |
2225 /* This duplicates Dynarr_insert_many to some extent; but since it is | |
2226 called so often, it seemed useful to remove the unnecessary stuff | |
2227 from that function and to make it inline */ | |
2228 Dynarr *dy = Dynarr_verify_mod (d); | |
2229 Elemcount pos = Dynarr_length (dy); | |
2230 Dynarr_increase_length (dy, Dynarr_length (dy) + len); | |
2231 if (base) | |
2232 memcpy ((Rawbyte *) dy->base + pos*Dynarr_elsize (dy), base, | |
2233 len*Dynarr_elsize (dy)); | |
2234 } | |
2235 | |
2236 /* Insert LEN elements, currently pointed to by BASE, into dynarr D | |
2237 starting at position POS. */ | |
2238 | |
2239 MODULE_API void Dynarr_insert_many (void *d, const void *base, Elemcount len, | |
2240 Elemcount pos); | |
2241 | |
2242 /* Prepend LEN elements, currently pointed to by BASE, to the beginning. */ | |
2243 | |
2244 #define Dynarr_prepend_many(d, base, len) Dynarr_insert_many (d, base, len, 0) | |
2245 | |
2246 /* Add literal string S to dynarr D, which should hold chars or unsigned | |
2247 chars. The final zero byte is not stored. */ | |
2248 | |
2025 #define Dynarr_add_literal_string(d, s) Dynarr_add_many (d, s, sizeof (s) - 1) | 2249 #define Dynarr_add_literal_string(d, s) Dynarr_add_many (d, s, sizeof (s) - 1) |
2026 #define Dynarr_add_lisp_string(d, s, codesys) \ | 2250 |
2251 /* Convert Lisp string S to an external encoding according to CODESYS and | |
2252 add to dynarr D, which should hold chars or unsigned chars. No final | |
2253 zero byte is appended. */ | |
2254 | |
2255 /* #### This should be an inline function but LISP_STRING_TO_SIZED_EXTERNAL | |
2256 isn't declared yet. */ | |
2257 | |
2258 #define Dynarr_add_ext_lisp_string(d, s, codesys) \ | |
2027 do { \ | 2259 do { \ |
2028 Lisp_Object dyna_ls_s = (s); \ | 2260 Lisp_Object dyna_ls_s = (s); \ |
2029 Lisp_Object dyna_ls_cs = (codesys); \ | 2261 Lisp_Object dyna_ls_cs = (codesys); \ |
2030 Extbyte *dyna_ls_eb; \ | 2262 Extbyte *dyna_ls_eb; \ |
2031 Bytecount dyna_ls_bc; \ | 2263 Bytecount dyna_ls_bc; \ |
2033 LISP_STRING_TO_SIZED_EXTERNAL (dyna_ls_s, dyna_ls_eb, \ | 2265 LISP_STRING_TO_SIZED_EXTERNAL (dyna_ls_s, dyna_ls_eb, \ |
2034 dyna_ls_bc, dyna_ls_cs); \ | 2266 dyna_ls_bc, dyna_ls_cs); \ |
2035 Dynarr_add_many (d, dyna_ls_eb, dyna_ls_bc); \ | 2267 Dynarr_add_many (d, dyna_ls_eb, dyna_ls_bc); \ |
2036 } while (0) | 2268 } while (0) |
2037 | 2269 |
2038 /* Add LEN contiguous elements to a Dynarr */ | 2270 /* Delete LEN elements starting at position POS. */ |
2039 | 2271 |
2040 DECLARE_INLINE_HEADER ( | 2272 MODULE_API void Dynarr_delete_many (void *d, Elemcount pos, Elemcount len); |
2041 void | 2273 |
2042 Dynarr_add_many (void *d, const void *el, int len) | 2274 /* Pop off (i.e. delete) the last element from the dynarr and return it */ |
2043 ) | |
2044 { | |
2045 /* This duplicates Dynarr_insert_many to some extent; but since it is | |
2046 called so often, it seemed useful to remove the unnecessary stuff | |
2047 from that function and to make it inline */ | |
2048 Dynarr *dy = Dynarr_verify_mod (d); | |
2049 Dynarr_resize_if (dy, len); | |
2050 /* Some functions call us with a value of 0 to mean "reserve space but | |
2051 don't write into it" */ | |
2052 if (el) | |
2053 memcpy ((char *) dy->base + Dynarr_sizeof (dy), el, len*dy->elsize); | |
2054 Dynarr_set_length_1 (dy, Dynarr_length (dy) + len); | |
2055 (void) Dynarr_verify_mod (dy); | |
2056 } | |
2057 | 2275 |
2058 #define Dynarr_pop(d) \ | 2276 #define Dynarr_pop(d) \ |
2059 (dynarr_checking_assert (Dynarr_length (d) > 0), \ | 2277 (dynarr_checking_assert (Dynarr_length (d) > 0), \ |
2060 Dynarr_verify_mod (d)->len_--, \ | 2278 Dynarr_verify_mod (d)->len_--, \ |
2061 Dynarr_at (d, Dynarr_length (d))) | 2279 Dynarr_at (d, Dynarr_length (d))) |
2062 #define Dynarr_delete(d, i) Dynarr_delete_many (d, i, 1) | 2280 |
2281 /* Delete the item at POS */ | |
2282 | |
2283 #define Dynarr_delete(d, pos) Dynarr_delete_many (d, pos, 1) | |
2284 | |
2285 /* Delete the item located at memory address P, which must be a `type *' | |
2286 pointer, where `type' is the type of the elements of the dynarr. */ | |
2063 #define Dynarr_delete_by_pointer(d, p) \ | 2287 #define Dynarr_delete_by_pointer(d, p) \ |
2064 Dynarr_delete_many (d, (p) - ((d)->base), 1) | 2288 Dynarr_delete_many (d, (p) - ((d)->base), 1) |
2289 | |
2290 /* Delete all elements that are numerically equal to EL. */ | |
2065 | 2291 |
2066 #define Dynarr_delete_object(d, el) \ | 2292 #define Dynarr_delete_object(d, el) \ |
2067 do \ | 2293 do \ |
2068 { \ | 2294 { \ |
2069 REGISTER int i; \ | 2295 REGISTER int i; \ |
3176 #define MARKERP(x) RECORDP (x, marker) | 3402 #define MARKERP(x) RECORDP (x, marker) |
3177 #define CHECK_MARKER(x) CHECK_RECORD (x, marker) | 3403 #define CHECK_MARKER(x) CHECK_RECORD (x, marker) |
3178 #define CONCHECK_MARKER(x) CONCHECK_RECORD (x, marker) | 3404 #define CONCHECK_MARKER(x) CONCHECK_RECORD (x, marker) |
3179 | 3405 |
3180 /* The second check was looking for GCed markers still in use */ | 3406 /* The second check was looking for GCed markers still in use */ |
3181 /* if (INTP (XMARKER (x)->lheader.next.v)) ABORT (); */ | 3407 /* assert (!INTP (XMARKER (x)->lheader.next.v)); */ |
3182 | 3408 |
3183 #define marker_next(m) ((m)->next) | 3409 #define marker_next(m) ((m)->next) |
3184 #define marker_prev(m) ((m)->prev) | 3410 #define marker_prev(m) ((m)->prev) |
3185 | 3411 |
3186 /*-------------------basic int (no connection to char)------------------*/ | 3412 /*-------------------basic int (no connection to char)------------------*/ |
3198 { | 3424 { |
3199 assert_at_line (INTP (obj), file, line); | 3425 assert_at_line (INTP (obj), file, line); |
3200 return XREALINT (obj); | 3426 return XREALINT (obj); |
3201 } | 3427 } |
3202 | 3428 |
3203 #else /* no error checking */ | 3429 #else /* not ERROR_CHECK_TYPES */ |
3204 | 3430 |
3205 #define XINT(obj) XREALINT (obj) | 3431 #define XINT(obj) XREALINT (obj) |
3206 | 3432 |
3207 #endif /* no error checking */ | 3433 #endif /* (not) ERROR_CHECK_TYPES */ |
3208 | 3434 |
3209 #define CHECK_INT(x) do { \ | 3435 #define CHECK_INT(x) do { \ |
3210 if (!INTP (x)) \ | 3436 if (!INTP (x)) \ |
3211 dead_wrong_type_argument (Qintegerp, x); \ | 3437 dead_wrong_type_argument (Qintegerp, x); \ |
3212 } while (0) | 3438 } while (0) |
3213 | 3439 |
3214 #define CONCHECK_INT(x) do { \ | 3440 #define CONCHECK_INT(x) do { \ |
3215 if (!INTP (x)) \ | 3441 if (!INTP (x)) \ |
3216 x = wrong_type_argument (Qintegerp, x); \ | 3442 x = wrong_type_argument (Qintegerp, x); \ |
3217 } while (0) | 3443 } while (0) |
3444 | |
3445 /* NOTE NOTE NOTE! This definition of "natural number" is mathematically | |
3446 wrong. Mathematically, a natural number is a positive integer; 0 | |
3447 isn't included. This would be better called NONNEGINT(). */ | |
3218 | 3448 |
3219 #define NATNUMP(x) (INTP (x) && XINT (x) >= 0) | 3449 #define NATNUMP(x) (INTP (x) && XINT (x) >= 0) |
3220 | 3450 |
3221 #define CHECK_NATNUM(x) do { \ | 3451 #define CHECK_NATNUM(x) do { \ |
3222 if (!NATNUMP (x)) \ | 3452 if (!NATNUMP (x)) \ |