RFC: Plan to implement FINAL (with polymorphism)
Daniel Kraft
d@domob.eu
Mon Sep 13 11:55:00 GMT 2010
Hi,
I would like to restart on FINAL support; I'm not sure if I will be able
to finish this before stage 3, but anyways here are some ideas and
questions about my plan and I would like to get input on those --
especially with respect to the polymorphism issues (which are also "new"
in the sense that this had not yet to be considered with my last FINAL
attempt).
For polymorphic entities, we basically have to dispatch the finalization
dynamically (just like tbp calls). Another complication is that there
may be multiple finalizers with different ranks (and/or a ELEMENTAL one
as fall-back) and the correct one of those has to be called -- thus we
have to dispatch both by dynamic type and rank (but the rank is known at
compile-time, of course). After calling the FINAL subroutine itself,
other steps have to be performed as well (finalizing components and
calling the parent-type finalizer where applicable).
While my previous patch did generate all the necessary finalization code
at the places where it was needed, I think because of the amount of code
required in certain cases and the possibility of dynamic dispatch, that
we should now switch to generating a destructor function that calls the
finalizer itself and does then all the other stuff. I think we should
generate one for each type *and* rank; or does this seem to expensive?
(If so, what would be a better approach?)
Then, I suggest to create for each type a static array indexed by rank
and pointing to the corresponding destructor routines for each rank;
from the vtable, we finally need a pointer to this table for the current
dynamic type -- with all this in place, we should be able to do the
correct clean-up.
Some questions I have:
* This destructor table will be similar to the vtable structures, I
guess; thus, I think we will generate a definition in the
compilation-unit where the type is defined. This is probably what the
vtable does, too?
* I have the impression that we need to generate destructor functions
for each possible rank, not only those that are actually used -- because
we do not know in advance all places where a type currently compiled may
be used. Or can we avoid this?
* Is it possible to create only a single destructor function that can
handle all ranks alike? (I want to create it in the back-end.) In C
terms, we could pass it a void* and the rank as well as other stuff
necessary and have the code perform casting as required to distinguish
between an array descriptor or direct pointer and so on. Does this
sound like a good approach or should we rather create individual
functions for each case? This seems cleaner but also a lot more
expensive to me.
* As an alternative approach: Instead of using the vtable, maybe we
could try a dispatch based on the dynamic type ID (as SELECT TYPE would
do, basically) -- does this seem to be advantageous for some reasons?
I welcome any opinions and suggestions, especially since I'm not an
expert in gfortran's OOP / polymorphism implementation!
BTW, with respect to development plan / schedule: I do not think that I
can build a full FINAL implementation before stage 3 starts. One
possibility would be to do one half first, like trying to get the
finalization process itself working but only finalize entities when they
go out of scope; and leave all other places open for a second go and
possibly a later gfortran version -- but this seems not really useful to
the users to me. Or else we could do the development on the fortran-dev
branch first when stage 1 really closes before I'm done.
Yours,
Daniel
--
http://www.pro-vegan.info/
--
Done: Arc-Bar-Cav-Kni-Ran-Rog-Sam-Tou-Val-Wiz
To go: Hea-Mon-Pri
More information about the Fortran
mailing list