[Top][All Lists]

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

[Chicken-hackers] [PATCH] Rework library loading to support conditional

From: Evan Hanson
Subject: [Chicken-hackers] [PATCH] Rework library loading to support conditional unit entry
Date: Tue, 29 May 2018 18:42:33 +1200

Hello fellow hackers,

Here is a big, gnarly patch that finishes the work I started in Bergen,
which was to change the way we handle library dependencies so that units
can be loaded conditionally. This was inspired by Peter's changes to
make import expressions lexically-scoped, so that you can write a
program like the following and have it work like you'd expect:

  (if (some-condition)
      (let () (import (foo)) ...)
      (let () (import (bar)) ...))

With Peter's changes, those imports will only affect the syntactic
environments of their respective branches. However, when the libraries
"foo" and "bar" are compiled in (for example when "-static" is used),
they'll both be loaded unconditionally. This patch changes things so
that those libraries will only be loaded when program execution reaches
the corresponding import expression.

I'm sorry about the size of the diff, but I needed to rework quite a bit
of bookkeeping for this to work. I also took the opportunity to clean up
some related bits of code and rip out some provisional things that were
left over from my last round of library loading changes. The commit
message is exhaustive, and probably exhausting too.

Note that I've taken care to preserve the current behaviour of the
"-uses" flag and "(uses ...)" declaration, which "hoist" the named units
to the top level and call them at the start of the program. This makes
the code slightly more complex than it would otherwise be, but I wanted
to preserve the idea that declarations have unit-global effect. The
correct way to link a program with a unit that may *or may not* be
loaded during program execution is to use the "-link" flag.

Another complicating factor was static libraries containing modules that
export syntax, which contain those now-infamous "(eval '(import-syntax
...))" forms. Previously, such `eval' expressions would never cause an
[unsuccessful] attempt to load a dynamic library into a static program
because the imported module's implementing library would have already
been loaded (at the start of the program, thanks to the aforementioned
unit hoisting), indicating that the module is already provided. Now,
however, that library's top level is only entered when the "culpable"
import expression is reached, but the `eval' form will always precede
that point in the program. Luckily, the compiler knows exactly what
libraries need to be loaded before the `eval' expression to avoid this
situation, because it can consult the module's import forms. So, we now
inject the necessary library entrypoints into the program just before
the `eval' (this is the `compiled-module-dependencies' bit of the patch
that does this, in modules.scm). This is only done when necessary, i.e.
for statically compiled modules that export syntax.

I've tested this pretty extensively, but I also know that it's nasty in
terms of sheer size (15 files changed, 266 insertions, 309 deletions),
so please just let me know if you have any questions and I'll do my best
to help clarify what's going on.



Attachment: 0001-Rework-library-loading-to-support-conditional-unit-e.patch
Description: Text Data

reply via email to

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