Click here
for
that pesky preface, and here
for a sample chapter.
Click here
for Prentice-Hall’s home page for the book,
then search for gough.
Click cover for
larger view
This page last
updated on December 4, 2001
The idea for the book arose
out of work that was done in Microsoft’s Project 7.
In that project a number of
compiler teams created new language compilers for the Common Language Runtime.
John Gough and Paul Roe
wrote a compiler for Component Pascal.
As it turns out, this is an interesting language to implement on the
CLR, since it poses a number of interesting problems. Finding solutions to these problems helps to clarify the
capabilities of the runtime.
The book is the first in a
series that Prentice-Hall will publish.
The series editor is Bertrand Meyer.
Although the book was not
primarily intended as a text, it may be of some interest to those universities
and colleges that take a practical approach to the compiler subject. Wayne Kelly has pioneered the use of the CLR
as a target for an introductory compiler construction course. This site will add some material in the
resources section (below) that may be of interest to others wishing to go down
that path.
This section has
links to material on a chapter-by-chapter basis.
For each chapter
there is a commentary, including any errata or late breaking news. There is
also a link to download the example programs for that particular chapter. These resources should all appear by mid
December 2001.
![]()
People using the RTM
version of the framework should be aware of a small number of issues that have
arisen since completion of the book.
Installation of the framework may not set up
your path so as to be able to find ildasm or peverify. You may check for this by opening a command
window and trying “ilasm”, and then “ildasm”. If the command line processor can
find one but not the other, edit your PATH variable so as to include the extra
directory. On my machine it was
C:\Program Files\Microsoft Visual Studio .NET\FrameworkSDK\Bin
The verifier is
now insisting that methods with one or more local variables must set the “init”
flag. gpcp version 1.1.2 has
been fixed to account for this. Local
declarations now appear like –
.locals
init (int32 foo)
with the declaration “init” being new.
The complete
listings for the test program ValCls.cp and ValCls.il shown in
outline on page 127 are linked here. You will note that RecTyp is implemented as a value class, and
PtrTyp is implemented as the reference class Boxed_RecTyp. Beware of the
typographical error on the following page (listed below).
In general errors fall
into three categories: regular typographical errors, things that were correct
when they were written but are now incorrect, and stuff that is just plain
wrong.
On page 57 it is stated
that value types cannot have virtual methods defined on them.
This is just plain wrong.
Value types may
have both instance and virtual methods defined on them. In both cases it is a boxed instance of the
value type that is passed as the “this” reference, but the “this” inside the
method is a managed pointer to the value.
The use of virtual
methods on value types is rather limited.
Such types are necessarily sealed, so any new virtual method cannot be
overridden. In such cases an ordinary instance method would do as well, and
possibly be more efficient. The main
use of such methods is to override virtual methods defined on the base types
System.ValueType or System.Object.
Page 73 mentions
“transient pointers”. Transient
pointers have been struck from final version the CLR. Instead addresses on the evaluation stack are always managed
pointers. This change does not affect
any of the described semantics (which is a good reason to delete the concept.)
On page 128 the
first of the two call statements has a typographical error. The class name part of the method
designator is wrong.
The two lines
should read
call instance void ValCls.RecTyp::’Foo’()
call instance void ValCls.Boxed_RecTyp::’Bar’()
See the resources section above for complete listings of the
example program.
One of the topics
in this chapter, is handling overloading in languages that don’t.
Since release 1.1
gpcp has taken this chapter’s advice, and directly implements name overloading
of method names in foreign (imported) libraries. As suggested in the chapter, when there is not an unambiguous
binding of the name, it is an error.
This forces programmers to avoid implicit type-coercions in argument
lists to overloaded methods.
Eiffel for .NET
takes a rather different approach. In
the case of that language for every foreign library an explicit mapping of
names must be created. Because of the
confusion that would result if every Eiffel programmer defined their own
name-mapping ISE is hosting a repository of agreed maps. This is an elegant solution to the problem
for those languages that have a close-knit user community where such a
repository can work well.
(Warning: this
section will make no sense until the relevant section of the book has been read
and understood. Sorry.) The final section on Accessing Non-local Variables has
been simplified for purposes of exposition.
The gpcp compiler actually implements one significant optimization
compared to the design described in this section of the book. The new idea is that only activation records
that actually contain uplevel data have XHR records. The static link references still chain the XHR records
together, but skip over activation records that have no such data. In this optimized design, if a method at
level N needs to access data a level M, then instead of following
the chain of links (N-M) times the link must be followed d times
where d is the number of methods statically nested between level M
and N that have non-empty uplevel addressed local variable sets. This number is statically known at compile
time. In typical code, where the use of non-local data is sparse, this optimization
not only saves on runtime code but also reduces the number of costly object creation
steps. Check both the source of gpcp,
and run some examples to see how it works in practice.
Because of the new
requirements for verification mentioned above (use of the “init” marker), it is
now less critical to perform initialization analysis. Nevertheless, in unverified contexts this is still an efficiency
gain. In any case, the arguments in
favor of detecting additional erroneous programs at compile time still hold.