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