psyntax defeats autoload

  • Done
  • quality assurance status badge
Details
2 participants
  • Ludovic Courtès
  • Andy Wingo
Owner
unassigned
Submitted by
Ludovic Courtès
Severity
normal
L
L
Ludovic Courtès wrote on 14 Aug 2012 18:14
(address . bug-guile@gnu.org)
87y5lhmowt.fsf@gnu.org
Hello!

Consider this module:

Toggle snippet (5 lines)
(define-module (foo) #:autoload (does-not-exist) (baz))
(define (chbouib) (baz))
(pk 'hello)

Trying to evaluate it fails this way:

Toggle snippet (18 lines)
$ guile --no-auto-compile t.scm
Backtrace:
In ice-9/boot-9.scm:

[...]

292: 3 [get-global-definition-hook baz (hygiene foo)]
In unknown file:
?: 2 [module-variable #<directory (foo) b3b510> baz]
In ice-9/boot-9.scm:
2732: 1 [b #<autoload (does-not-exist) b3b3f0> baz #f]
In unknown file:
?: 0 [scm-error misc-error #f ...]

ERROR: In procedure scm-error:
ERROR: missing interface for module (does-not-exist)

... which defeats the whole purpose of autoloads.

What about something along these lines (untested)?
Toggle diff (29 lines)
diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm
index 6c264a6..8a30f82 100644
--- a/module/ice-9/psyntax.scm
+++ b/module/ice-9/psyntax.scm
@@ -289,15 +289,20 @@
(lambda (symbol module)
(if (and (not module) (current-module))
(warn "module system is booted, we should have a module" symbol))
- (let ((v (module-variable (if module
+ (let ((m (if module
(resolve-module (cdr module))
- (current-module))
- symbol)))
+ (current-module))))
+ (case (module-kind m)
+ ((autoload)
+ ;; don't try to actually load the module
+ #t)
+ (else
+ (let ((v (module-variable m symbol)))
(and v (variable-bound? v)
(let ((val (variable-ref v)))
(and (macro? val) (macro-type val)
(cons (macro-type val)
- (macro-binding val)))))))))
+ (macro-binding val))))))))))))
(define (decorate-source e s)
Thanks,
Ludo’.
A
A
Andy Wingo wrote on 5 Mar 2013 17:45
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 12202@debbugs.gnu.org)
87wqtlvlr2.fsf@pobox.com
On Tue 14 Aug 2012 18:14, ludo@gnu.org (Ludovic Courtès) writes:

Toggle quote (27 lines)
> (define-module (foo) #:autoload (does-not-exist) (baz))
> (define (chbouib) (baz))
> (pk 'hello)
>
> Trying to evaluate it fails this way:
>
> $ guile --no-auto-compile t.scm
> Backtrace:
> In ice-9/boot-9.scm:
>
> [...]
>
> 292: 3 [get-global-definition-hook baz (hygiene foo)]
> In unknown file:
> ?: 2 [module-variable #<directory (foo) b3b510> baz]
> In ice-9/boot-9.scm:
> 2732: 1 [b #<autoload (does-not-exist) b3b3f0> baz #f]
> In unknown file:
> ?: 0 [scm-error misc-error #f ...]
>
> ERROR: In procedure scm-error:
> ERROR: missing interface for module (does-not-exist)
>
> ... which defeats the whole purpose of autoloads.
>
> What about something along these lines (untested)?

This is a great idea. We should assume that autoloads are not macros.
Not sure we can change it in 2.0 though, because there could be uses of
autoloaded macros.

However your patch won't work:

Toggle quote (28 lines)
> diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm
> index 6c264a6..8a30f82 100644
> --- a/module/ice-9/psyntax.scm
> +++ b/module/ice-9/psyntax.scm
> @@ -289,15 +289,20 @@
> (lambda (symbol module)
> (if (and (not module) (current-module))
> (warn "module system is booted, we should have a module" symbol))
> - (let ((v (module-variable (if module
> + (let ((m (if module
> (resolve-module (cdr module))
> - (current-module))
> - symbol)))
> + (current-module))))
> + (case (module-kind m)
> + ((autoload)
> + ;; don't try to actually load the module
> + #t)
> + (else
> + (let ((v (module-variable m symbol)))
> (and v (variable-bound? v)
> (let ((val (variable-ref v)))
> (and (macro? val) (macro-type val)
> (cons (macro-type val)
> - (macro-binding val)))))))))
> + (macro-binding val))))))))))))
>

because the module-kind of the module will never be `autoload' here. As
you can see in your backtrace, the module-kind is `directory' -- the
autoload only ends up getting loaded while grovelling (foo)'s import
array.

Andy
--
A
A
Andy Wingo wrote on 13 Mar 2013 10:01
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 12202-done@debbugs.gnu.org)
87txofk712.fsf@pobox.com
On Tue 05 Mar 2013 17:45, Andy Wingo <wingo@pobox.com> writes:

Toggle quote (5 lines)
>> ERROR: In procedure scm-error:
>> ERROR: missing interface for module (does-not-exist)
>>
>> ... which defeats the whole purpose of autoloads.

I pushed something that simply wraps the module binder in the autoload
with a false-if-exception (that also prints a warning).

Initially I wrapped the call to resolve-module / module-variable in
psyntax.scm's get-global-definition-hook with the false-if-exception,
but I ran into something interesting. memoize-expression, written in
memoize.c, has the job of turning tree-il into something the evaluator
can deal with. It has to specially recognize some toplevel
applications -- like @apply. It does this... by looking up the
variable! So that was another place autoloads could be defeated.

In the end I would have to wrap scm_module_variable
(scm_current_module(), sym) with a catch, and that's silly -- of course
resolving some other module can fail, but you don't expect
module-variable on a known module to throw an exception. So for that
reason it made sense to me to prevent the autoload module binder from
propagating an exception.

Andy
--
Closed
L
L
Ludovic Courtès wrote on 14 Mar 2013 14:21
(name . Andy Wingo)(address . wingo@pobox.com)(address . 12202-done@debbugs.gnu.org)
87txoet8w0.fsf@gnu.org
Andy Wingo <wingo@pobox.com> skribis:

Toggle quote (10 lines)
> On Tue 05 Mar 2013 17:45, Andy Wingo <wingo@pobox.com> writes:
>
>>> ERROR: In procedure scm-error:
>>> ERROR: missing interface for module (does-not-exist)
>>>
>>> ... which defeats the whole purpose of autoloads.
>
> I pushed something that simply wraps the module binder in the autoload
> with a false-if-exception (that also prints a warning).

Great, thank you!

Ludo’.
Closed
?