comparison src/lisp.h @ 5052:92dc90c0bb40

merge
author Ben Wing <ben@xemacs.org>
date Sat, 20 Feb 2010 23:56:01 -0600
parents 6f2158fa75ed 9410323e4b0d
children d372b17f63ce 2a462149bd6a 8b2f75cecb89
comparison
equal deleted inserted replaced
5051:c3d372419e09 5052:92dc90c0bb40
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
1454 1454
1455 /* 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. */
1456 1456
1457 /* We put typedefs here so that prototype declarations don't choke. 1457 /* We put typedefs here so that prototype declarations don't choke.
1458 Note that we don't actually declare the structures here (except 1458 Note that we don't actually declare the structures here (except
1459 maybe for simple structures like Dynarrs); that keeps them private 1459 maybe for simple structures like dynarrs); that keeps them private
1460 to the routines that actually use them. */ 1460 to the routines that actually use them. */
1461 1461
1462 /* ------------------------------- */ 1462 /* ------------------------------- */
1463 /* Error_Behavior typedefs */ 1463 /* Error_Behavior typedefs */
1464 /* ------------------------------- */ 1464 /* ------------------------------- */
1720 EMACS_UINT p = XUINT (obj); 1720 EMACS_UINT p = XUINT (obj);
1721 return (void *) (p << 1); 1721 return (void *) (p << 1);
1722 } 1722 }
1723 1723
1724 /************************************************************************/ 1724 /************************************************************************/
1725 /** Definitions of dynamic arrays (Dynarrs) and other allocators **/ 1725 /** Definitions of dynamic arrays (dynarrs) and other allocators **/
1726 /************************************************************************/ 1726 /************************************************************************/
1727 1727
1728 BEGIN_C_DECLS 1728 BEGIN_C_DECLS
1729 1729
1730 /************* Dynarr declaration *************/ 1730 /************* Dynarr declaration *************/
1746 #define Dynarr_declare(type) \ 1746 #define Dynarr_declare(type) \
1747 struct lrecord_header header; \ 1747 struct lrecord_header header; \
1748 type *base; \ 1748 type *base; \
1749 DECLARE_DYNARR_LISP_IMP () \ 1749 DECLARE_DYNARR_LISP_IMP () \
1750 DECLARE_DYNARR_LOCKED () \ 1750 DECLARE_DYNARR_LOCKED () \
1751 int elsize; \ 1751 int elsize_; \
1752 int len_; \ 1752 int len_; \
1753 int largest_; \ 1753 int largest_; \
1754 int max_ 1754 int max_
1755 1755
1756 typedef struct dynarr 1756 typedef struct dynarr
1774 { XD_INT_RESET, offsetof (base_type, max_), XD_INDIRECT(1, 0) } 1774 { XD_INT_RESET, offsetof (base_type, max_), XD_INDIRECT(1, 0) }
1775 #endif /* NEW_GC */ 1775 #endif /* NEW_GC */
1776 1776
1777 /************* Dynarr verification *************/ 1777 /************* Dynarr verification *************/
1778 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
1779 #ifdef ERROR_CHECK_DYNARR 1850 #ifdef ERROR_CHECK_DYNARR
1780 DECLARE_INLINE_HEADER ( 1851 DECLARE_INLINE_HEADER (
1781 int 1852 int
1782 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)
1783 ) 1854 )
1784 { 1855 {
1785 Dynarr *dy = (Dynarr *) d; 1856 Dynarr *dy = (Dynarr *) d;
1786 /* We use `largest', not `len', because the redisplay code often 1857 /* We use `largest', not `len', because the redisplay code often
1787 accesses stuff between len and largest. */ 1858 accesses stuff between len and largest. */
1789 return pos; 1860 return pos;
1790 } 1861 }
1791 1862
1792 DECLARE_INLINE_HEADER ( 1863 DECLARE_INLINE_HEADER (
1793 int 1864 int
1794 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)
1795 ) 1866 )
1796 { 1867 {
1797 Dynarr *dy = (Dynarr *) d; 1868 Dynarr *dy = (Dynarr *) d;
1798 /* We use `largest', not `len', because the redisplay code often 1869 /* We use `largest', not `len', because the redisplay code often
1799 accesses stuff between len and largest. */ 1870 accesses stuff between len and largest. */
1829 return pos; 1900 return pos;
1830 } 1901 }
1831 1902
1832 DECLARE_INLINE_HEADER ( 1903 DECLARE_INLINE_HEADER (
1833 int 1904 int
1834 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,
1835 int line) 1906 int line)
1836 ) 1907 )
1837 { 1908 {
1838 Dynarr *dy = (Dynarr *) d; 1909 Dynarr *dy = (Dynarr *) d;
1839 /* We use `largest', not `len', because the redisplay code often 1910 /* We use `largest', not `len', because the redisplay code often
1872 return Dynarr_verify_1 (d, file, line); 1943 return Dynarr_verify_1 (d, file, line);
1873 } 1944 }
1874 1945
1875 #define Dynarr_verify(d) Dynarr_verify_1 (d, __FILE__, __LINE__) 1946 #define Dynarr_verify(d) Dynarr_verify_1 (d, __FILE__, __LINE__)
1876 #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__)
1877 #define Dynarr_lock(d) \ 1948
1878 do { \ 1949 DECLARE_INLINE_HEADER (
1879 Dynarr *dy = Dynarr_verify_mod (d); \ 1950 void
1880 dy->locked = 1; \ 1951 Dynarr_lock (void *d)
1881 } while (0) 1952 )
1882 #define Dynarr_unlock(d) \ 1953 {
1883 do { \ 1954 Dynarr *dy = Dynarr_verify_mod (d);
1884 Dynarr *dy = Dynarr_verify (d); \ 1955 dy->locked = 1;
1885 dy->locked = 0; \ 1956 }
1886 } while (0) 1957
1887 #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
1888 #define Dynarr_verify(d) ((Dynarr *) d) 1970 #define Dynarr_verify(d) ((Dynarr *) d)
1889 #define Dynarr_verify_mod(d) ((Dynarr *) d) 1971 #define Dynarr_verify_mod(d) ((Dynarr *) d)
1890 #define Dynarr_lock(d) DO_NOTHING 1972 #define Dynarr_lock(d) DO_NOTHING
1891 #define Dynarr_unlock(d) DO_NOTHING 1973 #define Dynarr_unlock(d) DO_NOTHING
1974
1892 #endif /* ERROR_CHECK_DYNARR */ 1975 #endif /* ERROR_CHECK_DYNARR */
1893 1976
1894 /************* Dynarr creation *************/ 1977 /************* Dynarr creation *************/
1895 1978
1896 MODULE_API void *Dynarr_newf (int elsize); 1979 MODULE_API void *Dynarr_newf (Bytecount elsize);
1897 MODULE_API void Dynarr_free (void *d); 1980 MODULE_API void Dynarr_free (void *d);
1898 1981
1899 #ifdef NEW_GC 1982 #ifdef NEW_GC
1900 MODULE_API void *Dynarr_lisp_newf (int elsize, 1983 MODULE_API void *Dynarr_lisp_newf (Bytecount elsize,
1901 const struct lrecord_implementation 1984 const struct lrecord_implementation
1902 *dynarr_imp, 1985 *dynarr_imp,
1903 const struct lrecord_implementation *imp); 1986 const struct lrecord_implementation *imp);
1904 1987
1905 #define Dynarr_lisp_new(type, dynarr_imp, imp) \ 1988 #define Dynarr_lisp_new(type, dynarr_imp, imp) \
1932 #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))
1933 2016
1934 2017
1935 /************* Dynarr length/size retrieval and setting *************/ 2018 /************* Dynarr length/size retrieval and setting *************/
1936 2019
1937 /* 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
1938 be used as an lvalue. */ 2021 be used as an lvalue. */
1939 #define Dynarr_length(d) (Dynarr_verify (d)->len_ + 0) 2022 #define Dynarr_length(d) (Dynarr_verify (d)->len_ + 0)
1940 /* 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
1941 ensure that this cannot be used as an lvalue. */ 2024 ensure that this cannot be used as an lvalue. */
1942 #define Dynarr_largest(d) (Dynarr_verify (d)->largest_ + 0) 2025 #define Dynarr_largest(d) (Dynarr_verify (d)->largest_ + 0)
1943 /* Retrieve the number of elements that fit in the currently allocated 2026 /* Retrieve the number of elements that fit in the currently allocated
1944 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. */
1945 #define Dynarr_max(d) (Dynarr_verify (d)->max_ + 0) 2028 #define Dynarr_max(d) (Dynarr_verify (d)->max_ + 0)
1946 /* 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. */
1947 bytes occupied by the elements in the Dynarr, not counting any overhead. */ 2030 #define Dynarr_elsize(d) (Dynarr_verify (d)->elsize_ + 0)
1948 #define Dynarr_sizeof(d) (Dynarr_length (d) * (d)->elsize) 2031 /* Retrieve the advertised memory usage of a dynarr, i.e. the number of
1949 /* 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. */
1950 should not be directly used; use Dynarr_set_length() instead if you need 2033 #define Dynarr_sizeof(d) (Dynarr_length (d) * Dynarr_elsize (d))
1951 to, but be very careful when doing so! */ 2034
1952 #define Dynarr_set_length_1(d, n) \ 2035 /* Actually set the length of a dynarr. This is a low-level routine that
1953 do { \ 2036 should not be directly used; use Dynarr_set_length() or
1954 Elemcount _dsl1_n = (n); \ 2037 Dynarr_set_lengthr() instead. */
1955 dynarr_checking_assert (_dsl1_n >= 0 && _dsl1_n <= Dynarr_max (d)); \ 2038 DECLARE_INLINE_HEADER (
1956 (void) Dynarr_verify_mod (d); \ 2039 void
1957 (d)->len_ = _dsl1_n; \ 2040 Dynarr_set_length_1 (void *d, Elemcount len)
1958 /* Use the raw field references here otherwise we get a crash because \ 2041 )
1959 we've set the length but not yet fixed up the largest value. */ \ 2042 {
1960 if ((d)->len_ > (d)->largest_) \ 2043 Dynarr *dy = Dynarr_verify_mod (d);
1961 (d)->largest_ = (d)->len_; \ 2044 dynarr_checking_assert (len >= 0 && len <= Dynarr_max (dy));
1962 (void) Dynarr_verify_mod (d); \ 2045 /* Use the raw field references here otherwise we get a crash because
1963 } while (0) 2046 we've set the length but not yet fixed up the largest value. */
1964 2047 dy->len_ = len;
1965 /* The following two defines will get you into real trouble if you aren't 2048 if (dy->len_ > dy->largest_)
1966 careful. But they can save a lot of execution time when used wisely. */ 2049 dy->largest_ = dy->len_;
1967 #define Dynarr_set_length(d, n) \ 2050 (void) Dynarr_verify_mod (d);
1968 do { \ 2051 }
1969 Elemcount _dsl_n = (n); \ 2052
1970 dynarr_checking_assert (_dsl_n >= 0 && _dsl_n <= Dynarr_largest (d)); \ 2053 /* "Restricted set-length": Set the length of dynarr D to LEN,
1971 Dynarr_set_length_1 (d, _dsl_n); \ 2054 which must be in the range [0, Dynarr_largest(d)]. */
1972 } while (0) 2055
1973 #define Dynarr_increment(d) \ 2056 DECLARE_INLINE_HEADER (
1974 Dynarr_set_length (d, Dynarr_length (d) + 1) 2057 void
1975 2058 Dynarr_set_lengthr (void *d, Elemcount len)
1976 /* Reset the Dynarr's length to 0. */ 2059 )
1977 #define Dynarr_reset(d) Dynarr_set_length (d, 0) 2060 {
1978 2061 Dynarr *dy = Dynarr_verify_mod (d);
1979 MODULE_API void Dynarr_resize (void *dy, Elemcount size); 2062 dynarr_checking_assert (len >= 0 && len <= Dynarr_largest (dy));
1980 2063 Dynarr_set_length_1 (dy, len);
1981 #define Dynarr_resize_if(d, numels) \ 2064 }
1982 do { \ 2065
1983 Elemcount _dri_numels = (numels); \ 2066 /* "Restricted increment": Increment the length of dynarr D by 1; the resulting
1984 if (Dynarr_length (d) + _dri_numels > Dynarr_max (d)) \ 2067 length must be in the range [0, Dynarr_largest(d)]. */
1985 Dynarr_resize (d, Dynarr_length (d) + _dri_numels); \ 2068
1986 } 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)
1987 2168
1988 #ifdef MEMORY_USAGE_STATS 2169 #ifdef MEMORY_USAGE_STATS
1989 struct overhead_stats; 2170 struct overhead_stats;
1990 Bytecount Dynarr_memory_usage (void *d, struct overhead_stats *stats); 2171 Bytecount Dynarr_memory_usage (void *d, struct overhead_stats *stats);
1991 #endif 2172 #endif
1992 2173
1993 /************* 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. */
1994 2179
1995 #ifdef NEW_GC 2180 #ifdef NEW_GC
1996 #define Dynarr_add(d, el) \ 2181 #define DYNARR_SET_LISP_IMP(d, pos) \
1997 do { \ 2182 do { \
1998 const struct lrecord_implementation *imp = (d)->lisp_imp; \ 2183 if ((d)->lisp_imp) \
1999 (void) Dynarr_verify_mod (d); \
2000 Dynarr_resize_if (d, 1); \
2001 ((d)->base)[Dynarr_length (d)] = (el); \
2002 if (imp) \
2003 set_lheader_implementation \ 2184 set_lheader_implementation \
2004 ((struct lrecord_header *)&(((d)->base)[Dynarr_length (d)]), imp); \ 2185 ((struct lrecord_header *)&(((d)->base)[pos]), (d)->lisp_imp); \
2005 Dynarr_set_length_1 (d, Dynarr_length (d) + 1); \ 2186 } while (0)
2006 (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); \
2007 } while (0) 2200 } while (0)
2008 #else /* not NEW_GC */ 2201
2009 #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) \
2010 do { \ 2208 do { \
2209 Elemcount _ds_pos = (pos); \
2011 (void) Dynarr_verify_mod (d); \ 2210 (void) Dynarr_verify_mod (d); \
2012 Dynarr_resize_if (d, 1); \ 2211 if (Dynarr_length (d) < _ds_pos + 1) \
2013 ((d)->base)[Dynarr_length (d)] = (el); \ 2212 Dynarr_increase_length_and_zero (d, _ds_pos + 1); \
2014 Dynarr_set_length_1 (d, Dynarr_length (d) + 1); \ 2213 ((d)->base)[_ds_pos] = (el); \
2015 (void) Dynarr_verify_mod (d); \ 2214 DYNARR_SET_LISP_IMP (d, _ds_pos); \
2016 } while (0) 2215 } while (0)
2017 #endif /* not NEW_GC */ 2216
2018 2217 /* Add LEN contiguous elements, stored at BASE, to dynarr D. If BASE is
2019 2218 NULL, reserve space but don't store anything. */
2020 MODULE_API void Dynarr_insert_many (void *d, const void *el, int len, 2219
2021 int start); 2220 DECLARE_INLINE_HEADER (
2022 MODULE_API void Dynarr_delete_many (void *d, int start, int len); 2221 void
2023 2222 Dynarr_add_many (void *d, const void *base, Elemcount len)
2024 #define Dynarr_insert_many_at_start(d, el, len) \ 2223 )
2025 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
2026 #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)
2027 #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) \
2028 do { \ 2259 do { \
2029 Lisp_Object dyna_ls_s = (s); \ 2260 Lisp_Object dyna_ls_s = (s); \
2030 Lisp_Object dyna_ls_cs = (codesys); \ 2261 Lisp_Object dyna_ls_cs = (codesys); \
2031 Extbyte *dyna_ls_eb; \ 2262 Extbyte *dyna_ls_eb; \
2032 Bytecount dyna_ls_bc; \ 2263 Bytecount dyna_ls_bc; \
2034 LISP_STRING_TO_SIZED_EXTERNAL (dyna_ls_s, dyna_ls_eb, \ 2265 LISP_STRING_TO_SIZED_EXTERNAL (dyna_ls_s, dyna_ls_eb, \
2035 dyna_ls_bc, dyna_ls_cs); \ 2266 dyna_ls_bc, dyna_ls_cs); \
2036 Dynarr_add_many (d, dyna_ls_eb, dyna_ls_bc); \ 2267 Dynarr_add_many (d, dyna_ls_eb, dyna_ls_bc); \
2037 } while (0) 2268 } while (0)
2038 2269
2039 /* Add LEN contiguous elements to a Dynarr */ 2270 /* Delete LEN elements starting at position POS. */
2040 2271
2041 DECLARE_INLINE_HEADER ( 2272 MODULE_API void Dynarr_delete_many (void *d, Elemcount pos, Elemcount len);
2042 void 2273
2043 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 */
2044 )
2045 {
2046 /* This duplicates Dynarr_insert_many to some extent; but since it is
2047 called so often, it seemed useful to remove the unnecessary stuff
2048 from that function and to make it inline */
2049 Dynarr *dy = Dynarr_verify_mod (d);
2050 Dynarr_resize_if (dy, len);
2051 /* Some functions call us with a value of 0 to mean "reserve space but
2052 don't write into it" */
2053 if (el)
2054 memcpy ((char *) dy->base + Dynarr_sizeof (dy), el, len*dy->elsize);
2055 Dynarr_set_length_1 (dy, Dynarr_length (dy) + len);
2056 (void) Dynarr_verify_mod (dy);
2057 }
2058 2275
2059 #define Dynarr_pop(d) \ 2276 #define Dynarr_pop(d) \
2060 (dynarr_checking_assert (Dynarr_length (d) > 0), \ 2277 (dynarr_checking_assert (Dynarr_length (d) > 0), \
2061 Dynarr_verify_mod (d)->len_--, \ 2278 Dynarr_verify_mod (d)->len_--, \
2062 Dynarr_at (d, Dynarr_length (d))) 2279 Dynarr_at (d, Dynarr_length (d)))
2063 #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. */
2064 #define Dynarr_delete_by_pointer(d, p) \ 2287 #define Dynarr_delete_by_pointer(d, p) \
2065 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. */
2066 2291
2067 #define Dynarr_delete_object(d, el) \ 2292 #define Dynarr_delete_object(d, el) \
2068 do \ 2293 do \
2069 { \ 2294 { \
2070 REGISTER int i; \ 2295 REGISTER int i; \
3199 { 3424 {
3200 assert_at_line (INTP (obj), file, line); 3425 assert_at_line (INTP (obj), file, line);
3201 return XREALINT (obj); 3426 return XREALINT (obj);
3202 } 3427 }
3203 3428
3204 #else /* no error checking */ 3429 #else /* not ERROR_CHECK_TYPES */
3205 3430
3206 #define XINT(obj) XREALINT (obj) 3431 #define XINT(obj) XREALINT (obj)
3207 3432
3208 #endif /* no error checking */ 3433 #endif /* (not) ERROR_CHECK_TYPES */
3209 3434
3210 #define CHECK_INT(x) do { \ 3435 #define CHECK_INT(x) do { \
3211 if (!INTP (x)) \ 3436 if (!INTP (x)) \
3212 dead_wrong_type_argument (Qintegerp, x); \ 3437 dead_wrong_type_argument (Qintegerp, x); \
3213 } while (0) 3438 } while (0)
3214 3439
3215 #define CONCHECK_INT(x) do { \ 3440 #define CONCHECK_INT(x) do { \
3216 if (!INTP (x)) \ 3441 if (!INTP (x)) \
3217 x = wrong_type_argument (Qintegerp, x); \ 3442 x = wrong_type_argument (Qintegerp, x); \
3218 } 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(). */
3219 3448
3220 #define NATNUMP(x) (INTP (x) && XINT (x) >= 0) 3449 #define NATNUMP(x) (INTP (x) && XINT (x) >= 0)
3221 3450
3222 #define CHECK_NATNUM(x) do { \ 3451 #define CHECK_NATNUM(x) do { \
3223 if (!NATNUMP (x)) \ 3452 if (!NATNUMP (x)) \