[Oberon] [interface changes in] OP2 Vs Wirth's compiler.
andreas_pirklbauer at yahoo.com
Mon Jul 31 21:53:30 CEST 2017
I forgot to add that there is also a version of OP2 that uses *one fingerprint PER object* rather than one per layer - which can be seen as a kind of refinement of the layer model. However, I am not familiar with the details of the specific approach chosen in its implementation. It felt rather complex when I read about it the first time .. back in the 90s .. so I decided not to make use of it. I only adopted (stole?) the idea, and tried to build a simplified version of it in Experimental Oberon .. without however succeeding at arriving at a satisfactory solution... perhaps the complexity in OP2 is needed after all? I am not convinced yet..
On Monday, July 31, 2017, 9:39:04 PM GMT+2, Andreas Pirklbauer <andreas_pirklbauer at yahoo.com> wrote:
> 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