diff options
| author | Vibhav Pant | 2020-08-21 14:04:35 +0530 |
|---|---|---|
| committer | Vibhav Pant | 2020-08-21 14:04:35 +0530 |
| commit | f0f8d7b82492e741950c363a03b886965c91b1b0 (patch) | |
| tree | 19b716830b1ebabc0d7d75949c4e6800c0f104ad /src/lread.c | |
| parent | 9e64a087c4d167e7ec1c4e22bea3e6af53b563de (diff) | |
| parent | c818c29771d3cb51875643b2f6c894073e429dd2 (diff) | |
| download | emacs-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.c | 214 |
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 | ||
| 1102 | static Lisp_Object | 1102 | static ATTRIBUTE_UNUSED Lisp_Object |
| 1103 | parent_directory (Lisp_Object directory) | 1103 | parent_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 | |||
| 1619 | For example, it turns this: | ||
| 1620 | |||
| 1621 | (".eln" ".elc" ".elc.gz" ".el" ".el.gz") | ||
| 1622 | 1611 | ||
| 1623 | into this: | 1612 | static void |
| 1624 | 1613 | maybe_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 | */ | ||
| 1632 | static Lisp_Object | ||
| 1633 | openp_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) |
| 1669 | static ptrdiff_t | ||
| 1670 | openp_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; |
| 1697 | static ptrdiff_t | 1642 | emacs_close (*fd); |
| 1698 | openp_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 | |||
| 5228 | that are loaded before your customizations are read! */); | 5157 | that 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"); |