aboutsummaryrefslogtreecommitdiffstats
path: root/src/lread.c
diff options
context:
space:
mode:
authorVibhav Pant2020-08-21 14:04:35 +0530
committerVibhav Pant2020-08-21 14:04:35 +0530
commitf0f8d7b82492e741950c363a03b886965c91b1b0 (patch)
tree19b716830b1ebabc0d7d75949c4e6800c0f104ad /src/lread.c
parent9e64a087c4d167e7ec1c4e22bea3e6af53b563de (diff)
parentc818c29771d3cb51875643b2f6c894073e429dd2 (diff)
downloademacs-feature/native-comp-macos-fixes.tar.gz
emacs-feature/native-comp-macos-fixes.zip
Merge branch 'feature/native-comp' into feature/native-comp-macos-fixesfeature/native-comp-macos-fixes
Diffstat (limited to 'src/lread.c')
-rw-r--r--src/lread.c214
1 files changed, 74 insertions, 140 deletions
diff --git a/src/lread.c b/src/lread.c
index f5a7d44a1e0..521da4e1d81 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1099,7 +1099,7 @@ close_infile_unwind (void *arg)
1099 infile = prev_infile; 1099 infile = prev_infile;
1100} 1100}
1101 1101
1102static Lisp_Object 1102static ATTRIBUTE_UNUSED Lisp_Object
1103parent_directory (Lisp_Object directory) 1103parent_directory (Lisp_Object directory)
1104{ 1104{
1105 return Ffile_name_directory (Fsubstring (directory, 1105 return Ffile_name_directory (Fsubstring (directory,
@@ -1231,8 +1231,7 @@ Return t if the file exists and loads successfully. */)
1231 suffixes = CALLN (Fappend, suffixes, Vload_file_rep_suffixes); 1231 suffixes = CALLN (Fappend, suffixes, Vload_file_rep_suffixes);
1232 } 1232 }
1233 1233
1234 fd = 1234 fd = openp (Vload_path, file, suffixes, &found, Qnil, load_prefer_newer);
1235 openp (Vload_path, file, suffixes, &found, Qnil, load_prefer_newer);
1236 } 1235 }
1237 1236
1238 if (fd == -1) 1237 if (fd == -1)
@@ -1478,9 +1477,8 @@ Return t if the file exists and loads successfully. */)
1478 same folder of their respective sources therfore not to break 1477 same folder of their respective sources therfore not to break
1479 packages we fake `load-file-name' here. The non faked 1478 packages we fake `load-file-name' here. The non faked
1480 version of it is `load-true-file-name'. */ 1479 version of it is `load-true-file-name'. */
1481 specbind (Qload_file_name, 1480 specbind (Qload_file_name, Fgethash (Ffile_name_nondirectory (found),
1482 concat2 (parent_directory (Ffile_name_directory (found)), 1481 Vcomp_eln_to_el_h, Qnil));
1483 Ffile_name_nondirectory (found)));
1484 } 1482 }
1485 else 1483 else
1486 specbind (Qload_file_name, found); 1484 specbind (Qload_file_name, found);
@@ -1608,118 +1606,52 @@ directories, make sure the PREDICATE function returns `dir-ok' for them. */)
1608 return file; 1606 return file;
1609} 1607}
1610 1608
1611/* This function turns a list of suffixes into a list of middle dirs 1609/* Look for a suitable .eln file to be loaded in place of FILENAME.
1612 and suffixes. If the suffix is not NATIVE_ELISP_SUFFIX then its 1610 If found replace the content of FILENAME and FD. */
1613 suffix is nil and it is added to the list as is. Instead, if it
1614 suffix is NATIVE_ELISP_SUFFIX then two elements are added to the
1615 list. The first one has middledir equal to nil and the second uses
1616 comp-native-path-postfix as middledir. This is because we'd like
1617 to search for dir/foo.eln before dir/middledir/foo.eln.
1618
1619For example, it turns this:
1620
1621(".eln" ".elc" ".elc.gz" ".el" ".el.gz")
1622 1611
1623 into this: 1612static void
1624 1613maybe_swap_for_eln (Lisp_Object *filename, int *fd, struct timespec mtime)
1625((nil . ".eln")
1626 (comp-native-path-postfix . ".eln")
1627 (nil . ".elc")
1628 (nil . ".elc.gz")
1629 (nil . ".el")
1630 (nil . ".el.gz"))
1631*/
1632static Lisp_Object
1633openp_add_middle_dir_to_suffixes (Lisp_Object suffixes)
1634{ 1614{
1635 Lisp_Object tail = suffixes;
1636 Lisp_Object extended_suf = Qnil;
1637 FOR_EACH_TAIL_SAFE (tail)
1638 {
1639 /* suffixes may be a stack-based cons pointing to stack-based
1640 strings. We must copy the suffix if we are putting it into
1641 a heap-based cons to avoid a dangling reference. This would
1642 lead to crashes during the GC. */
1643 CHECK_STRING_CAR (tail);
1644 char * suf = SSDATA (XCAR (tail));
1645 Lisp_Object copied_suffix = build_string (suf);
1646#ifdef HAVE_NATIVE_COMP 1615#ifdef HAVE_NATIVE_COMP
1647 if (strcmp (NATIVE_ELISP_SUFFIX, suf) == 0) 1616 struct stat eln_st;
1648 {
1649 CHECK_STRING (Vcomp_native_path_postfix);
1650 /* Here we add them in the opposite order so that nreverse
1651 corrects it. */
1652 extended_suf = Fcons (Fcons (Qnil, copied_suffix), extended_suf);
1653 extended_suf = Fcons (Fcons (Vcomp_native_path_postfix,
1654 copied_suffix),
1655 extended_suf);
1656 }
1657 else
1658#endif
1659 extended_suf = Fcons (Fcons (Qnil, copied_suffix), extended_suf);
1660 }
1661 1617
1662 suffixes = Fnreverse (extended_suf); 1618 if (load_no_native
1663 return suffixes; 1619 || !suffix_p (*filename, ".elc"))
1664} 1620 return;
1665 1621
1666/* This function takes a list of middledirs and suffixes and returns 1622 /* Search eln in the eln-cache directories. */
1667 the maximum buffer space that this part of the filename will 1623 Lisp_Object eln_path_tail = Vcomp_eln_load_path;
1668 need. */ 1624 FOR_EACH_TAIL_SAFE (eln_path_tail)
1669static ptrdiff_t
1670openp_max_middledir_and_suffix_len (Lisp_Object middledir_and_suffixes)
1671{
1672 ptrdiff_t max_extra_len = 0;
1673 Lisp_Object tail = middledir_and_suffixes;
1674 FOR_EACH_TAIL_SAFE (tail)
1675 { 1625 {
1676 Lisp_Object middledir_and_suffix = XCAR (tail); 1626 Lisp_Object el_name =
1677 Lisp_Object middledir = XCAR (middledir_and_suffix); 1627 Fsubstring (*filename, Qnil, make_fixnum (-1));
1678 Lisp_Object suffix = XCDR (middledir_and_suffix); 1628 Lisp_Object eln_name =
1679 ptrdiff_t len = SBYTES (suffix); 1629 Fcomp_el_to_eln_filename (el_name, XCAR (eln_path_tail));
1680 if (!NILP (middledir)) 1630 int eln_fd = emacs_open (SSDATA (ENCODE_FILE (eln_name)), O_RDONLY, 0);
1681 len += 2 + SBYTES (middledir); /* Add two slashes. */
1682 max_extra_len = max (max_extra_len, len);
1683 }
1684 return max_extra_len;
1685}
1686 1631
1687/* This function completes the FN buffer with the middledir, 1632 if (eln_fd > 0)
1688 basenameme, and suffix. It takes the directory length in DIRNAME, 1633 {
1689 but it requires that it has been copied already to the start of 1634 if (fstat (eln_fd, &eln_st) || S_ISDIR (eln_st.st_mode))
1690 the buffer. 1635 emacs_close (eln_fd);
1691 1636 else
1692 After this function the FN buffer will be (depending on middledir) 1637 {
1693 dirname/middledir/basename.suffix 1638 struct timespec eln_mtime = get_stat_mtime (&eln_st);
1694 or 1639 if (timespec_cmp (eln_mtime, mtime) > 0)
1695 dirname/basename.suffix 1640 {
1696*/ 1641 *filename = eln_name;
1697static ptrdiff_t 1642 emacs_close (*fd);
1698openp_fill_filename_buffer (char *fn, ptrdiff_t dirnamelen, 1643 *fd = eln_fd;
1699 Lisp_Object basenamewext, 1644 /* Store the eln -> el relation. */
1700 Lisp_Object middledir_and_suffix) 1645 Fputhash (Ffile_name_nondirectory (eln_name),
1701{ 1646 el_name, Vcomp_eln_to_el_h);
1702 Lisp_Object middledir = XCAR (middledir_and_suffix); 1647 return;
1703 Lisp_Object suffix = XCDR (middledir_and_suffix); 1648 }
1704 ptrdiff_t basenamewext_len = SBYTES (basenamewext); 1649 else
1705 ptrdiff_t fnlen, lsuffix = SBYTES (suffix); 1650 emacs_close (eln_fd);
1706 ptrdiff_t lmiddledir = 0; 1651 }
1707 if (!NILP (middledir)) 1652 }
1708 {
1709 /* Add 1 for the slash. */
1710 lmiddledir = SBYTES (middledir) + 1;
1711 memcpy (fn + dirnamelen, SDATA (middledir),
1712 lmiddledir - 1);
1713 fn[dirnamelen + (lmiddledir - 1)] = '/';
1714 } 1653 }
1715 1654#endif
1716 memcpy (fn + dirnamelen + lmiddledir, SDATA (basenamewext),
1717 basenamewext_len);
1718 /* Make complete filename by appending SUFFIX. */
1719 memcpy (fn + dirnamelen + lmiddledir + basenamewext_len,
1720 SDATA (suffix), lsuffix + 1);
1721 fnlen = dirnamelen + lmiddledir + basenamewext_len + lsuffix;
1722 return fnlen;
1723} 1655}
1724 1656
1725/* Search for a file whose name is STR, looking in directories 1657/* Search for a file whose name is STR, looking in directories
@@ -1759,21 +1691,23 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1759 ptrdiff_t want_length; 1691 ptrdiff_t want_length;
1760 Lisp_Object filename; 1692 Lisp_Object filename;
1761 Lisp_Object string, tail, encoded_fn, save_string; 1693 Lisp_Object string, tail, encoded_fn, save_string;
1762 Lisp_Object middledir_and_suffixes; 1694 ptrdiff_t max_suffix_len = 0;
1763 ptrdiff_t max_extra_len = 0;
1764 int last_errno = ENOENT; 1695 int last_errno = ENOENT;
1765 int save_fd = -1; 1696 int save_fd = -1;
1766 USE_SAFE_ALLOCA; 1697 USE_SAFE_ALLOCA;
1767
1768 /* The last-modified time of the newest matching file found. 1698 /* The last-modified time of the newest matching file found.
1769 Initialize it to something less than all valid timestamps. */ 1699 Initialize it to something less than all valid timestamps. */
1770 struct timespec save_mtime = make_timespec (TYPE_MINIMUM (time_t), -1); 1700 struct timespec save_mtime = make_timespec (TYPE_MINIMUM (time_t), -1);
1771 1701
1772 CHECK_STRING (str); 1702 CHECK_STRING (str);
1773 1703
1774 middledir_and_suffixes = openp_add_middle_dir_to_suffixes (suffixes); 1704 tail = suffixes;
1775 1705 FOR_EACH_TAIL_SAFE (tail)
1776 max_extra_len = openp_max_middledir_and_suffix_len (middledir_and_suffixes); 1706 {
1707 CHECK_STRING_CAR (tail);
1708 max_suffix_len = max (max_suffix_len,
1709 SBYTES (XCAR (tail)));
1710 }
1777 1711
1778 string = filename = encoded_fn = save_string = Qnil; 1712 string = filename = encoded_fn = save_string = Qnil;
1779 1713
@@ -1790,7 +1724,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1790 executable. */ 1724 executable. */
1791 FOR_EACH_TAIL_SAFE (path) 1725 FOR_EACH_TAIL_SAFE (path)
1792 { 1726 {
1793 ptrdiff_t dirnamelen, prefixlen; 1727 ptrdiff_t baselen, prefixlen;
1794 1728
1795 if (EQ (path, just_use_str)) 1729 if (EQ (path, just_use_str))
1796 filename = str; 1730 filename = str;
@@ -1807,40 +1741,35 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1807 continue; 1741 continue;
1808 } 1742 }
1809 1743
1810
1811 /* Calculate maximum length of any filename made from 1744 /* Calculate maximum length of any filename made from
1812 this path element/specified file name and any possible suffix. */ 1745 this path element/specified file name and any possible suffix. */
1813 want_length = max_extra_len + SBYTES (filename); 1746 want_length = max_suffix_len + SBYTES (filename);
1814 if (fn_size <= want_length) 1747 if (fn_size <= want_length)
1815 { 1748 {
1816 fn_size = 100 + want_length; 1749 fn_size = 100 + want_length;
1817 fn = SAFE_ALLOCA (fn_size); 1750 fn = SAFE_ALLOCA (fn_size);
1818 } 1751 }
1819 1752
1820 Lisp_Object dirnamewslash = Ffile_name_directory (filename);
1821 Lisp_Object basenamewext = Ffile_name_nondirectory (filename);
1822
1823 /* Copy FILENAME's data to FN but remove starting /: if any. */ 1753 /* Copy FILENAME's data to FN but remove starting /: if any. */
1824 prefixlen = ((SCHARS (dirnamewslash) > 2 1754 prefixlen = ((SCHARS (filename) > 2
1825 && SREF (dirnamewslash, 0) == '/' 1755 && SREF (filename, 0) == '/'
1826 && SREF (dirnamewslash, 1) == ':') 1756 && SREF (filename, 1) == ':')
1827 ? 2 : 0); 1757 ? 2 : 0);
1828 dirnamelen = SBYTES (dirnamewslash) - prefixlen; 1758 baselen = SBYTES (filename) - prefixlen;
1829 memcpy (fn, SDATA (dirnamewslash) + prefixlen, dirnamelen); 1759 memcpy (fn, SDATA (filename) + prefixlen, baselen);
1830 1760
1831 /* Loop over middledir_and_suffixes. */ 1761 /* Loop over suffixes. */
1832 AUTO_LIST1 (empty_string_only, Fcons (Qnil, empty_unibyte_string)); 1762 AUTO_LIST1 (empty_string_only, empty_unibyte_string);
1833 tail = NILP (middledir_and_suffixes) ? empty_string_only 1763 tail = NILP (suffixes) ? empty_string_only : suffixes;
1834 : middledir_and_suffixes;
1835 FOR_EACH_TAIL_SAFE (tail) 1764 FOR_EACH_TAIL_SAFE (tail)
1836 { 1765 {
1837 Lisp_Object middledir_and_suffix = XCAR (tail); 1766 Lisp_Object suffix = XCAR (tail);
1838 Lisp_Object suffix = XCDR (middledir_and_suffix); 1767 ptrdiff_t fnlen, lsuffix = SBYTES (suffix);
1839 Lisp_Object handler; 1768 Lisp_Object handler;
1840 1769
1841 ptrdiff_t fnlen = openp_fill_filename_buffer (fn, dirnamelen, 1770 /* Make complete filename by appending SUFFIX. */
1842 basenamewext, 1771 memcpy (fn + baselen, SDATA (suffix), lsuffix + 1);
1843 middledir_and_suffix); 1772 fnlen = baselen + lsuffix;
1844 1773
1845 /* Check that the file exists and is not a directory. */ 1774 /* Check that the file exists and is not a directory. */
1846 /* We used to only check for handlers on non-absolute file names: 1775 /* We used to only check for handlers on non-absolute file names:
@@ -1962,9 +1891,11 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1962 } 1891 }
1963 else 1892 else
1964 { 1893 {
1894 maybe_swap_for_eln (&string, &fd, get_stat_mtime (&st));
1965 /* We succeeded; return this descriptor and filename. */ 1895 /* We succeeded; return this descriptor and filename. */
1966 if (storeptr) 1896 if (storeptr)
1967 *storeptr = string; 1897 *storeptr = string;
1898
1968 SAFE_FREE (); 1899 SAFE_FREE ();
1969 return fd; 1900 return fd;
1970 } 1901 }
@@ -1973,6 +1904,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1973 /* No more suffixes. Return the newest. */ 1904 /* No more suffixes. Return the newest. */
1974 if (0 <= save_fd && ! CONSP (XCDR (tail))) 1905 if (0 <= save_fd && ! CONSP (XCDR (tail)))
1975 { 1906 {
1907 maybe_swap_for_eln (&save_string, &save_fd, save_mtime);
1976 if (storeptr) 1908 if (storeptr)
1977 *storeptr = save_string; 1909 *storeptr = save_string;
1978 SAFE_FREE (); 1910 SAFE_FREE ();
@@ -5030,11 +4962,8 @@ to the specified file name if a suffix is allowed or required. */);
5030 Vload_suffixes = 4962 Vload_suffixes =
5031 Fcons (build_pure_c_string (MODULES_SECONDARY_SUFFIX), Vload_suffixes); 4963 Fcons (build_pure_c_string (MODULES_SECONDARY_SUFFIX), Vload_suffixes);
5032#endif 4964#endif
5033#endif
5034#ifdef HAVE_NATIVE_COMP
5035 Vload_suffixes = Fcons (build_pure_c_string (NATIVE_ELISP_SUFFIX), Vload_suffixes);
5036#endif
5037 4965
4966#endif
5038 DEFVAR_LISP ("module-file-suffix", Vmodule_file_suffix, 4967 DEFVAR_LISP ("module-file-suffix", Vmodule_file_suffix,
5039 doc: /* Suffix of loadable module file, or nil if modules are not supported. */); 4968 doc: /* Suffix of loadable module file, or nil if modules are not supported. */);
5040#ifdef HAVE_MODULES 4969#ifdef HAVE_MODULES
@@ -5228,6 +5157,11 @@ Note that if you customize this, obviously it will not affect files
5228that are loaded before your customizations are read! */); 5157that are loaded before your customizations are read! */);
5229 load_prefer_newer = 0; 5158 load_prefer_newer = 0;
5230 5159
5160 DEFVAR_BOOL ("load-no-native", load_no_native,
5161 doc: /* Do not try to load the a .eln file in place of
5162 a .elc one. */);
5163 load_no_native = false;
5164
5231 /* Vsource_directory was initialized in init_lread. */ 5165 /* Vsource_directory was initialized in init_lread. */
5232 5166
5233 DEFSYM (Qcurrent_load_list, "current-load-list"); 5167 DEFSYM (Qcurrent_load_list, "current-load-list");