lucy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Nathan Kurz <>
Subject Re: [lucy-dev] OFFSET globals
Date Tue, 24 Apr 2012 21:21:00 GMT
On Tue, Apr 24, 2012 at 4:32 AM, Marvin Humphrey <> wrote:
> On Mon, Apr 23, 2012 at 10:20 PM, Nathan Kurz <> wrote:
>> 2) We don't want to allow "monkey-patching" of classes at runtime,
>> such that an extension can make changes to parent classes that
>> propagate back to the child classes.
> I think you can stop at "make changes to parent classes [period]".  As far as
> Clownfish is concerned, once a class has been registered, it is immutable.

OK, slightly more stringent but also true.  Children load after their
parents, and are allowed presume that their parents are immutable.
This follows from the requirement that registration happens from the
top down and that all classes are immutable once registered.

>> 4) In all other cases (removal or signature change of an inherited
>> method) we just want to detect the incompatibility at start time and
>> die with an appropriate error message rather than randomly crashing or
>> doing the wrong thing.
> +0.  Nice if possible, but from the perspective of an existing compiled
> extension, it's hard to detect when upstream has broken an ABI.

Difficult, but I think as necessary as the other requirements.  If we
don't do this, we have no way of knowing whether the system is stable,
or just hasn't yet encountered a broken pathway.  The main library
needs increment something every time an internal ABI changes, and this
needs to be checked by the extension.   This is one of the places I
hope we can use DSO symbol versioning, so this check would happen
automatically at runtime linkage.

>> Are these correct?  Are the requirements I'm missing?
> I would add this:
> 6) It should be possible to remove methods from upstream which are not marked
> as "public.

What would be the desired behaviour when a compiled extension
references a removed method?

> Then, after we finish dealing with methods, the next step is to give upstream
> the ability to add, remove or rearrange member variables. :)

Can this wait for the second round, or should this be solved now as well?


For reference, here's a followup from Ian Wienand.  I don't yet
comprehend his suggestion regarding libbfd.

Ian Wienand replies:
> Nathan Kurz writes:
>    Unfortunately, the externally compiled Boxer_vtable has a fixed layout,
>    and it puts Boxer_drool in the slot where the core expects to find eat().
>    When the core tries to call eat() on a Boxer object, chaos will ensue.

Yeah; aren't you also relying on the compiler laying out the
structures the same, independent of you adding a function?

> Our goal is to figure out a way to leverage the runtime linker to do
> the lifting work so we don't have to do our own bootstrapping.  Likely
> this will be by specifying the VTable lengths (offsets) as a variable
> within the .so rather than as hardcoded.  But fully understand that
> this *might* not be the best use of your time today.  Thanks for the
> response!

I don't think the dynamic linker is going to help you much with this
... it seems you really need to version "Dog" and have "Boxer" tell
the core what version of "Dog" it implements.  Something you could
consider is stamping this info into a separate section of the .so with
something like

#define DOG_VERSION(version)
 const char __dog_version __attribute__((section(""))) =
"dog_version =" #version

in your "boxer" plugin, and then use libbfd to read and parse that
section at load time, and hence know what members to call.

View raw message