lilypond-devel
[Top][All Lists]
Advanced

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

Re: Re: %module-public-interface


From: Han-Wen Nienhuys
Subject: Re: Re: %module-public-interface
Date: Mon, 3 May 2010 17:29:36 -0300

On Mon, May 3, 2010 at 3:50 PM, Ian Hulin <address@hidden> wrote:
>
> I believe you originally put together the Lily/Guile module code.  There's an 
> upcoming change such that Guile want to deprecate

yep.

>
> %module-public-interface .  The Guile developers have come up with the 
> proposed fix below, which requires some changes to the Lilypond code.
>
> I'll continue my mail at the bottom  . . .

> >> --8<---------------cut here---------------start------------->8---
> >>        mod = scm_call_0 (maker);
> >>        scm_module_define (mod, ly_symbol2scm ("%module-public-interface"),
> >>                           mod);
> >> --8<---------------cut here---------------end--------------->8---
> >>
> >> Solution: do something like:
> >>
> >> --8<---------------cut here---------------start------------->8---
> >> #ifdef HAVE_SCM_SET_MODULE_PUBLIC_INTERFACE_X
> >>    scm_set_module_public_interface_x (mod, mod);
> >> #else
> >>    scm_module_define (mod, ly_symbol2scm ("%module-public-interface"),
> >>                       mod);
> >> #endif
> >> --8<---------------cut here---------------end--------------->8---
> >>
> >> (We just need to add that function.)
>
> As it appears here that you are trying to export everything from that
> module (in a somewhat incorrect formulation -- I can explain if you
> like), and that seems to be a sort of pattern, I'd suggest that instead
> we offer a module-export-all! function. Here is some code to provide
> such a function for pre-2.0 guile:
>
>     (cond-expand
>       ((not guile-2)
>        (define (module-export-all! mod)
>          (define (fresh-interface!)
>            (let ((iface (make-module)))
>              (set-module-name! iface (module-name mod))
>              ;; for guile 2: (set-module-version! iface (module-version mod))
>              (set-module-kind! iface 'interface)
>              (set-module-public-interface! mod iface)
>              iface))
>          (let ((iface (or (module-public-interface mod)
>                           (fresh-interface!))))
>            (set-module-obarray! iface (module-obarray mod))))))
>
> Use that to export all bindings instead. As it is, there are some shims
> for %module-public-interface hackery to keep on working if deprecated
> code is compiled in, but you should migrate to calling
> module-export-all!, I think.
>
> Then your C code would unconditionally:
>
>    scm_call_1 (scm_variable_ref (module_export_all_var), mod);
>
> Regards,
>
> Andy
> --
> http://wingolog.org/
>
> ______________________________________________
> This email has been scanned by Netintelligence
> http://www.netintelligence.com/email
>
> Hello again.
> Here's the complete c++ function which uses %module-public-interface
> ly_make_anonymous_module (bool safe)
> {
>
>     SCM mod = SCM_EOL;
>   if (!safe)
>     {
>       SCM maker = ly_lily_module_constant ("make-module");
>
>       SCM scm_module = ly_lily_module_constant ("the-scm-module");
>
>       mod = scm_call_0 (maker);
>       scm_module_define (mod, ly_symbol2scm ("%module-public-interface"),
>                        mod);
>       ly_use_module (mod, scm_module);
>       ly_use_module (mod, global_lily_module);
>     }
>   else
>     {
>       SCM proc = ly_lily_module_constant ("make-safe-lilypond-module");
>       mod = scm_call_0 (proc);
>     }
>
> #ifdef MODULE_GC_KLUDGE
>   if (perform_gc_kludge)
>     anonymous_modules = scm_cons (mod, anonymous_modules);
> #endif

While you're at it, you could look at removing this kludge, the code
says it is for GUILE 1.6 which we don't support anyway.

> Firstly, is Andy's interpretation that we are "trying to export everything 
> from that module" correct?

Basically, scopes in the .ly file are modules, and they are nested, ie.

  foo = "bar"
  \header { title = \foo }

here , both toplevel and \header are scopes (ie. guile modules), and
the toplevel scope is visible in the \header scopes.  This is
implemented as \header importing the toplevel scope, and for this to
work all the symbols from toplevel must be visible to the importing
scope.

I forgot what the exact reasoning for the mucking with
%public-interface was, but it must have been related to that.


> If that is the case, would just we be able to do
>
>       ly_reexport(scm_current_module()), or
>
>       SCM old_mod = scm_current_module ();
>       mod = scm_call_0 (maker);
>       ly_module_copy (old_mod, mod);
>
> ?
>
> I've also had a poke at putting the guile code Andy suggested in lily.scm, 
> and tried to use his stub to pick up the
> new module.  I've got it to work with a few tweaks.

good!

> I've seen this reference in the Guile NEWS for 1.9 development saying this:
> "** All modules have names now
>
> Before, you could have anonymous modules: modules without names. Now,
> because of hygiene and macros, all modules have names. If a module was
> created without a name, the first time `module-name' is called on it, a
> fresh name will be lazily generated for it.
> "
>
> So should the Lilypond parser even be calling ly_make_anonymous_module at all?

Yes, but you could change the name of the function.  For safe mode to
work, we have to centralize creation of modules, to make sure none of
them import anything restricted.

> I know you wrote this code a long way back, but I'd appreciate insights you 
> nay have.

My recollections are somewhat dim.  In absence of documentation and an
API in GUILE that did what I want, I just hacked about until it
worked.  Feel to substitute something more sanitized, as long as it
passes the regtest :-)

--
Han-Wen Nienhuys - address@hidden - http://www.xs4all.nl/~hanwen




reply via email to

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