libparrot exports over 16,000 symbols. Half of those are the vtable functions in our PMCs.
For now, they get exported because of the way we build the vtables when we initialize PMCs. Look in src/pmc/class.c in a built Parrot source tree for now. Parrot_Class_class_init() creates the Class PMC's vtable as an array of mostly function pointers. Because Class inherits some behavior from the Default PMC, its vtable array contains pointers to functions declared in Default. That doesn't imply anything about the visibility of those symbols... until you consider that dynpmcs have the same strategy. That is, every dynpmc either reimplements its own functions, or its initialization code has to refer to symbols explicitly exported from libparrot to get at the function pointers directly from the Default PMC, or whichever core PMC is its parent. Instead, we should *clone* the parent's vtable, then override only the function pointers that the current PMC provides directly. This requires two pieces of information. First, we need a way to map the appropriate slot in the vtable array for each overridden entry. That's easy. Second, we need a way to know the proper initialization order of PMC vtables such that we handle all parents before all children. Making this work for core PMCs is fairly easy. Making it work for dynpmcs is a little more difficult, but still doable. I've attached a small program which should get generalized into a module somewhere and somehow, and integrated into our build system. It reads the .dump files produced when we parse the .pmc files. Then it builds up a tree of dependencies, starting with the default PMC, and produces a list of PMCs in root-most dependency order. We'll need to move the generation of src/core_pmcs.c from configuration time to compilation time, but that's simple. The important function in that file is Parrot_initialize_core_pmcs(). Look at the branch where pass = 0. All we need to do is reorder that list of initializations. The same technique will likely work with dynpmcs. However, generating the PMC group files is a bit more complex. I hope to work on this over the next week or so, but if anyone wants to look at the dynpmc group configuration process and see how to make it easier to generate the initialization code there, please feel free. I recommend looking in languages/tcl/ for starters, as its src/pmc/ directory is clean and clear and the example is sufficiently complex that if we can handle it correctly, we can handle everything correctly. -- c
vtable_order.pl
Description: Perl program