[Oberon] [interface changes in] OP2 Vs Wirth's compiler.
andreas_pirklbauer at yahoo.com
Mon Jul 31 21:34:49 CEST 2017
> On Monday, July 31, 2017, 7:37:51 PM GMT+2, Paul Reed <paulreed at paddedcell.com> wrote:
> > The latest RISC5 compiler handles this similar to the original Oberon
> > compiler...the key is simply the sum of all bytes in the symbol file,
> > i.e. really is a checksum.
> So the more fine-grained feature of OP2 can be achieved, at least
> cosmetically, by careful choice of the new identifier names. ;-)
Yes, if you know what you are doing, that's possible. You can even trick the system to *believe* that the symbol file has not changed when in fact it has. However, that is hardly in the spirit of the method used. It is used because it turns out that despite its crudeness and simplicity (calculation of the key is implemented in two (!) lines of code in procedure ORB.Export), it works surprisingly well in practice. Indeed, I have yet to "accidentally" create a symbol file with the same key for different interfaces. But it can happen,
To achieve the more fine-grained feature of OP2, one would need to bring the OP2 to the Oberon on RISC compiler. If you are interested, you can study procedure OPT.OutObj in the OP2 compiler (OPT is the name of OP2's table handler and corresponds to ORB for RISC Oberon). In essence, OP2 manages a stack of so-called "extension layers" (repeated extensions of an interface results in a multi-layered interface, and when you only add layers to existing interfaces, clients are not invalidated). In the symbol file, there are so-called "stoppers", which simply consist of a tag following by a fingerprint of the layer. So a symbol file with 7 layers will have 7 fingerprints. The details are described in the PhD thesis "Separate Compilation and Module Extensions" by R. Crelier.
Even though it is relatively easy to update an existing Oberon compiler on RISC to this "layer model", I would refrain from doing so. It has a number of drawbacks, most of which are outlined in the PhD thesis. In addition, I would add this: Even though it will allow you to extend interfaces *without* invalidating clients, this is a rather narrow use case. What about if you make changes to an *existing* procedure? This is not an extension. So clients *will* be invalidated. Any yet, it should not invalidate clients that do not make use of the modified procedure.
This is why I have played with computing a key (checksum) for *each* object (ORB.Object) and *each* type (ORB.Type) in the symbol file and simply *add up* exactly those that are imported when compiling a client. That way one can exactly pinpoint when an interface change *actually* affects a client. However, the linker is a tick more complex... I have yet to find a compelling enough solution worth publishing.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Oberon