emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How does one find out what file a library has been loaded from?


From: Andrea Corallo
Subject: Re: How does one find out what file a library has been loaded from?
Date: Mon, 01 Aug 2022 09:23:05 +0000
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Andrea Corallo <akrl@sdf.org>
>> Cc: acm@muc.de, emacs-devel@gnu.org
>> Date: Sun, 24 Jul 2022 17:46:02 +0000
>> 
>> >> (native-comp-unit-file (subr-native-comp-unit (symbol-function 
>> >> #'find-file)))
>> >
>> > Andrea, does anything similar to subr-native-comp-unit exists for
>> > other types of symbols accepted by symbol-file: defvar and defface?
>> 
>> No it does not exists.
>> 
>> The reason why the compilation unit concept was introduced is to have
>> the GC capable of unloading the eln when possible, this mechanism is
>> only related to functions that are indeed memory mapped from the loaded
>> shared libraries.  Variables etc are just regular variables (tipically
>> defined at eln load time) so they didn't required any new mechanism.
>> 
>> > If not, then the only way to produce the same information for them
>> > would be to generate the base name of the .eln file with
>> > comp-el-to-eln-rel-filename, and then look for that file along
>> > native-comp-eln-load-path, right?
>> 
>> Yes I think so.
>
> Andrea and Alan, please review and test the version of symbol-file
> below that I intend to install soon.  TIA.
>
> (defun locate-eln-file (eln-file)
>   "Locate a natively-compiled ELN-FILE by searching its load path.
> This function looks in directories named by `native-comp-eln-load-path'."
>   (or (locate-file-internal (concat comp-native-version-dir "/" eln-file)
>                  native-comp-eln-load-path)
>       (locate-file-internal
>        ;; Preloaded *.eln files live in the preloaded/ subdirectory of
>        ;; the last entry in `native-comp-eln-load-path'.
>        (concat comp-native-version-dir "/preloaded/" eln-file)
>        (last native-comp-eln-load-path))))
>
> (defun symbol-file (symbol &optional type native-p)
>   "Return the name of the file that defined SYMBOL.
> The value is normally an absolute file name.  It can also be nil,
> if the definition is not associated with any file.  If SYMBOL
> specifies an autoloaded function, the value can be a relative
> file name without extension.
>
> If TYPE is nil, then any kind of definition is acceptable.  If
> TYPE is `defun', `defvar', or `defface', that specifies function
> definition, variable definition, or face definition only.
> Otherwise TYPE is assumed to be a symbol property.
>
> If NATIVE-P is nil, and SYMBOL was loaded from a .eln file, this
> function will return the absolute file name of that .eln file,
> if found.
>
> This function only works for symbols defined in Lisp files.  For
> symbols that are defined in C files, use `help-C-file-name'
> instead."
>   (if (and (or (null type) (eq type 'defun))
>          (symbolp symbol)
>          (autoloadp (symbol-function symbol)))
>       (nth 1 (symbol-function symbol))
>     (if (and native-p (or (null type) (eq type 'defun))
>            (symbolp symbol)
>            (subr-native-elisp-p (symbol-function symbol)))
>       ;; native-comp-unit-file returns unnormalized file names.
>       (expand-file-name (native-comp-unit-file (subr-native-comp-unit
>                                                 (symbol-function symbol))))
>       (let ((elc-file
>            (catch 'found
>              (pcase-dolist (`(,file . ,elems) load-history)
>                (when (if type
>                          (if (eq type 'defvar)
>                              ;; Variables are present just as their
>                              ;; names.
>                              (member symbol elems)
>                            ;; Many other types are represented as
>                            ;; (TYPE . NAME).
>                            (or (member (cons type symbol) elems)
>                                (memq
>                                 symbol
>                                 (alist-get type
>                                            (alist-get 'define-symbol-props
>                                                       elems)))))
>                        ;; We accept all types, so look for variable def
>                        ;; and then for any other kind.
>                        (or (member symbol elems)
>                            (let ((match (rassq symbol elems)))
>                              (and match
>                                   (not (eq 'require (car match)))))))
>                  (throw 'found file))))))
>       ;; If they asked for the .eln file, try to find it.
>       (or (and elc-file
>                native-p
>                (let* ((sans-ext (file-name-sans-extension elc-file))
>                       (el-file
>                        (and (fboundp 'zlib-available-p)
>                             (zlib-available-p)
>                             (concat sans-ext ".el.gz")))
>                       (el-file-backup (concat sans-ext ".el")))
>                  (or (and el-file (file-exists-p el-file))
>                      (and (file-exists-p el-file-backup)
>                           (setq el-file el-file-backup))
>                      (setq el-file nil))
>                  (if (stringp el-file)
>                      (locate-eln-file
>                       (comp-el-to-eln-rel-filename el-file)))))
>           elc-file)))))

Hi Eli,

I think this has some overlap with the code we have in
'maybe_swap_for_eln', but it does not look trivial to decouple it, so
I'm not sure is it worth the pain.

Other than that only note I've is that (in 'maybe_swap_for_eln1') we do
reject the .eln file if it's younger than the corresponding .elc one.  I
think we should mimic this as well here no?

Otherwise LGTM.

Thanks

  Andrea



reply via email to

[Prev in Thread] Current Thread [Next in Thread]