summaryrefslogtreecommitdiff
path: root/src/lread.c
diff options
context:
space:
mode:
authorVibhav Pant <vibhavp@gmail.com>2020-08-21 14:04:35 +0530
committerVibhav Pant <vibhavp@gmail.com>2020-08-21 14:04:35 +0530
commitf0f8d7b82492e741950c363a03b886965c91b1b0 (patch)
tree19b716830b1ebabc0d7d75949c4e6800c0f104ad /src/lread.c
parent9e64a087c4d167e7ec1c4e22bea3e6af53b563de (diff)
parentc818c29771d3cb51875643b2f6c894073e429dd2 (diff)
downloademacs-feature/native-comp-macos-fixes.tar.gz
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)
infile = prev_infile;
}
-static Lisp_Object
+static ATTRIBUTE_UNUSED Lisp_Object
parent_directory (Lisp_Object directory)
{
return Ffile_name_directory (Fsubstring (directory,
@@ -1231,8 +1231,7 @@ Return t if the file exists and loads successfully. */)
suffixes = CALLN (Fappend, suffixes, Vload_file_rep_suffixes);
}
- fd =
- openp (Vload_path, file, suffixes, &found, Qnil, load_prefer_newer);
+ fd = openp (Vload_path, file, suffixes, &found, Qnil, load_prefer_newer);
}
if (fd == -1)
@@ -1478,9 +1477,8 @@ Return t if the file exists and loads successfully. */)
same folder of their respective sources therfore not to break
packages we fake `load-file-name' here. The non faked
version of it is `load-true-file-name'. */
- specbind (Qload_file_name,
- concat2 (parent_directory (Ffile_name_directory (found)),
- Ffile_name_nondirectory (found)));
+ specbind (Qload_file_name, Fgethash (Ffile_name_nondirectory (found),
+ Vcomp_eln_to_el_h, Qnil));
}
else
specbind (Qload_file_name, found);
@@ -1608,118 +1606,52 @@ directories, make sure the PREDICATE function returns `dir-ok' for them. */)
return file;
}
-/* This function turns a list of suffixes into a list of middle dirs
- and suffixes. If the suffix is not NATIVE_ELISP_SUFFIX then its
- suffix is nil and it is added to the list as is. Instead, if it
- suffix is NATIVE_ELISP_SUFFIX then two elements are added to the
- list. The first one has middledir equal to nil and the second uses
- comp-native-path-postfix as middledir. This is because we'd like
- to search for dir/foo.eln before dir/middledir/foo.eln.
-
-For example, it turns this:
-
-(".eln" ".elc" ".elc.gz" ".el" ".el.gz")
+/* Look for a suitable .eln file to be loaded in place of FILENAME.
+ If found replace the content of FILENAME and FD. */
- into this:
-
-((nil . ".eln")
- (comp-native-path-postfix . ".eln")
- (nil . ".elc")
- (nil . ".elc.gz")
- (nil . ".el")
- (nil . ".el.gz"))
-*/
-static Lisp_Object
-openp_add_middle_dir_to_suffixes (Lisp_Object suffixes)
+static void
+maybe_swap_for_eln (Lisp_Object *filename, int *fd, struct timespec mtime)
{
- Lisp_Object tail = suffixes;
- Lisp_Object extended_suf = Qnil;
- FOR_EACH_TAIL_SAFE (tail)
- {
- /* suffixes may be a stack-based cons pointing to stack-based
- strings. We must copy the suffix if we are putting it into
- a heap-based cons to avoid a dangling reference. This would
- lead to crashes during the GC. */
- CHECK_STRING_CAR (tail);
- char * suf = SSDATA (XCAR (tail));
- Lisp_Object copied_suffix = build_string (suf);
#ifdef HAVE_NATIVE_COMP
- if (strcmp (NATIVE_ELISP_SUFFIX, suf) == 0)
- {
- CHECK_STRING (Vcomp_native_path_postfix);
- /* Here we add them in the opposite order so that nreverse
- corrects it. */
- extended_suf = Fcons (Fcons (Qnil, copied_suffix), extended_suf);
- extended_suf = Fcons (Fcons (Vcomp_native_path_postfix,
- copied_suffix),
- extended_suf);
- }
- else
-#endif
- extended_suf = Fcons (Fcons (Qnil, copied_suffix), extended_suf);
- }
+ struct stat eln_st;
- suffixes = Fnreverse (extended_suf);
- return suffixes;
-}
+ if (load_no_native
+ || !suffix_p (*filename, ".elc"))
+ return;
-/* This function takes a list of middledirs and suffixes and returns
- the maximum buffer space that this part of the filename will
- need. */
-static ptrdiff_t
-openp_max_middledir_and_suffix_len (Lisp_Object middledir_and_suffixes)
-{
- ptrdiff_t max_extra_len = 0;
- Lisp_Object tail = middledir_and_suffixes;
- FOR_EACH_TAIL_SAFE (tail)
+ /* Search eln in the eln-cache directories. */
+ Lisp_Object eln_path_tail = Vcomp_eln_load_path;
+ FOR_EACH_TAIL_SAFE (eln_path_tail)
{
- Lisp_Object middledir_and_suffix = XCAR (tail);
- Lisp_Object middledir = XCAR (middledir_and_suffix);
- Lisp_Object suffix = XCDR (middledir_and_suffix);
- ptrdiff_t len = SBYTES (suffix);
- if (!NILP (middledir))
- len += 2 + SBYTES (middledir); /* Add two slashes. */
- max_extra_len = max (max_extra_len, len);
- }
- return max_extra_len;
-}
+ Lisp_Object el_name =
+ Fsubstring (*filename, Qnil, make_fixnum (-1));
+ Lisp_Object eln_name =
+ Fcomp_el_to_eln_filename (el_name, XCAR (eln_path_tail));
+ int eln_fd = emacs_open (SSDATA (ENCODE_FILE (eln_name)), O_RDONLY, 0);
-/* This function completes the FN buffer with the middledir,
- basenameme, and suffix. It takes the directory length in DIRNAME,
- but it requires that it has been copied already to the start of
- the buffer.
-
- After this function the FN buffer will be (depending on middledir)
- dirname/middledir/basename.suffix
- or
- dirname/basename.suffix
-*/
-static ptrdiff_t
-openp_fill_filename_buffer (char *fn, ptrdiff_t dirnamelen,
- Lisp_Object basenamewext,
- Lisp_Object middledir_and_suffix)
-{
- Lisp_Object middledir = XCAR (middledir_and_suffix);
- Lisp_Object suffix = XCDR (middledir_and_suffix);
- ptrdiff_t basenamewext_len = SBYTES (basenamewext);
- ptrdiff_t fnlen, lsuffix = SBYTES (suffix);
- ptrdiff_t lmiddledir = 0;
- if (!NILP (middledir))
- {
- /* Add 1 for the slash. */
- lmiddledir = SBYTES (middledir) + 1;
- memcpy (fn + dirnamelen, SDATA (middledir),
- lmiddledir - 1);
- fn[dirnamelen + (lmiddledir - 1)] = '/';
+ if (eln_fd > 0)
+ {
+ if (fstat (eln_fd, &eln_st) || S_ISDIR (eln_st.st_mode))
+ emacs_close (eln_fd);
+ else
+ {
+ struct timespec eln_mtime = get_stat_mtime (&eln_st);
+ if (timespec_cmp (eln_mtime, mtime) > 0)
+ {
+ *filename = eln_name;
+ emacs_close (*fd);
+ *fd = eln_fd;
+ /* Store the eln -> el relation. */
+ Fputhash (Ffile_name_nondirectory (eln_name),
+ el_name, Vcomp_eln_to_el_h);
+ return;
+ }
+ else
+ emacs_close (eln_fd);
+ }
+ }
}
-
- memcpy (fn + dirnamelen + lmiddledir, SDATA (basenamewext),
- basenamewext_len);
- /* Make complete filename by appending SUFFIX. */
- memcpy (fn + dirnamelen + lmiddledir + basenamewext_len,
- SDATA (suffix), lsuffix + 1);
- fnlen = dirnamelen + lmiddledir + basenamewext_len + lsuffix;
- return fnlen;
+#endif
}
/* 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,
ptrdiff_t want_length;
Lisp_Object filename;
Lisp_Object string, tail, encoded_fn, save_string;
- Lisp_Object middledir_and_suffixes;
- ptrdiff_t max_extra_len = 0;
+ ptrdiff_t max_suffix_len = 0;
int last_errno = ENOENT;
int save_fd = -1;
USE_SAFE_ALLOCA;
-
/* The last-modified time of the newest matching file found.
Initialize it to something less than all valid timestamps. */
struct timespec save_mtime = make_timespec (TYPE_MINIMUM (time_t), -1);
CHECK_STRING (str);
- middledir_and_suffixes = openp_add_middle_dir_to_suffixes (suffixes);
-
- max_extra_len = openp_max_middledir_and_suffix_len (middledir_and_suffixes);
+ tail = suffixes;
+ FOR_EACH_TAIL_SAFE (tail)
+ {
+ CHECK_STRING_CAR (tail);
+ max_suffix_len = max (max_suffix_len,
+ SBYTES (XCAR (tail)));
+ }
string = filename = encoded_fn = save_string = Qnil;
@@ -1790,7 +1724,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
executable. */
FOR_EACH_TAIL_SAFE (path)
{
- ptrdiff_t dirnamelen, prefixlen;
+ ptrdiff_t baselen, prefixlen;
if (EQ (path, just_use_str))
filename = str;
@@ -1807,40 +1741,35 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
continue;
}
-
/* Calculate maximum length of any filename made from
this path element/specified file name and any possible suffix. */
- want_length = max_extra_len + SBYTES (filename);
+ want_length = max_suffix_len + SBYTES (filename);
if (fn_size <= want_length)
{
fn_size = 100 + want_length;
fn = SAFE_ALLOCA (fn_size);
}
- Lisp_Object dirnamewslash = Ffile_name_directory (filename);
- Lisp_Object basenamewext = Ffile_name_nondirectory (filename);
-
/* Copy FILENAME's data to FN but remove starting /: if any. */
- prefixlen = ((SCHARS (dirnamewslash) > 2
- && SREF (dirnamewslash, 0) == '/'
- && SREF (dirnamewslash, 1) == ':')
+ prefixlen = ((SCHARS (filename) > 2
+ && SREF (filename, 0) == '/'
+ && SREF (filename, 1) == ':')
? 2 : 0);
- dirnamelen = SBYTES (dirnamewslash) - prefixlen;
- memcpy (fn, SDATA (dirnamewslash) + prefixlen, dirnamelen);
+ baselen = SBYTES (filename) - prefixlen;
+ memcpy (fn, SDATA (filename) + prefixlen, baselen);
- /* Loop over middledir_and_suffixes. */
- AUTO_LIST1 (empty_string_only, Fcons (Qnil, empty_unibyte_string));
- tail = NILP (middledir_and_suffixes) ? empty_string_only
- : middledir_and_suffixes;
+ /* Loop over suffixes. */
+ AUTO_LIST1 (empty_string_only, empty_unibyte_string);
+ tail = NILP (suffixes) ? empty_string_only : suffixes;
FOR_EACH_TAIL_SAFE (tail)
{
- Lisp_Object middledir_and_suffix = XCAR (tail);
- Lisp_Object suffix = XCDR (middledir_and_suffix);
+ Lisp_Object suffix = XCAR (tail);
+ ptrdiff_t fnlen, lsuffix = SBYTES (suffix);
Lisp_Object handler;
- ptrdiff_t fnlen = openp_fill_filename_buffer (fn, dirnamelen,
- basenamewext,
- middledir_and_suffix);
+ /* Make complete filename by appending SUFFIX. */
+ memcpy (fn + baselen, SDATA (suffix), lsuffix + 1);
+ fnlen = baselen + lsuffix;
/* Check that the file exists and is not a directory. */
/* 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,
}
else
{
+ maybe_swap_for_eln (&string, &fd, get_stat_mtime (&st));
/* We succeeded; return this descriptor and filename. */
if (storeptr)
*storeptr = string;
+
SAFE_FREE ();
return fd;
}
@@ -1973,6 +1904,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
/* No more suffixes. Return the newest. */
if (0 <= save_fd && ! CONSP (XCDR (tail)))
{
+ maybe_swap_for_eln (&save_string, &save_fd, save_mtime);
if (storeptr)
*storeptr = save_string;
SAFE_FREE ();
@@ -5030,11 +4962,8 @@ to the specified file name if a suffix is allowed or required. */);
Vload_suffixes =
Fcons (build_pure_c_string (MODULES_SECONDARY_SUFFIX), Vload_suffixes);
#endif
-#endif
-#ifdef HAVE_NATIVE_COMP
- Vload_suffixes = Fcons (build_pure_c_string (NATIVE_ELISP_SUFFIX), Vload_suffixes);
-#endif
+#endif
DEFVAR_LISP ("module-file-suffix", Vmodule_file_suffix,
doc: /* Suffix of loadable module file, or nil if modules are not supported. */);
#ifdef HAVE_MODULES
@@ -5228,6 +5157,11 @@ Note that if you customize this, obviously it will not affect files
that are loaded before your customizations are read! */);
load_prefer_newer = 0;
+ DEFVAR_BOOL ("load-no-native", load_no_native,
+ doc: /* Do not try to load the a .eln file in place of
+ a .elc one. */);
+ load_no_native = false;
+
/* Vsource_directory was initialized in init_lread. */
DEFSYM (Qcurrent_load_list, "current-load-list");