Semantic Challenges


Almost all of the features of Component Pascal were mapped to the CLR without difficulty and provide the exact semantics expected for the source language. Once the necessity for reference surrogates is accepted, the rest follows in a natural way.

There are a small number of language constructs that pose design issues for the implementation. A few of these are discussed here. None of these turns out to be a show-stopper, but all create challenges of different levels of seriousness.

Nonlocal Addressing

In Pascal-family languages, nested procedures are able to access the local variables and parameters of their enclosing procedures. Such access is called nonlocal addressing. Curiously, C-family languages do not have nested procedures but may have nested blocks with local data. The implementation problems in the C-language case are trivial, as all data within a function lie within the same activation frame.

The issue with nonlocal addressing in the CLR is that there is no native mechanism to support it. Indeed, there is no legal way to refer to the local data of any method other than the currently active one. There are a small number of possible approaches to solve the problem, and the Component Pascal compiler uses the author's favorite one. Procedures that declare data that are accessed nonlocally define a heap-allocated data structure to hold the variables in question. An object of the type is allocated on entry to the procedure. A reference to this object is passed as an additional, hidden parameter to all nested procedures. In deeply nested cases, these explicit heap-allocated records ( XHR ) form a linked list. Because the compiler knows the relative nesting depths of each piece of code, it is able to generate object code to traverse the chain to access the data of any enclosing procedure.

There is some minor runtime overhead caused by the excess object creation in this approach, and it works exactly in almost every case. The pesky exception is the mercifully rare case where a nested procedure wants to access a reference parameter of an enclosing procedure, and the parameter type is an unboxed value type (that is, the type is not a reference surrogate). The dilemma is how to place the incoming parameter in the XHR. If the incoming reference is copied into the XHR, it must be declared as an unmanaged pointer type, and the program will not be verifiable . Alternatively, if the value pointed to by the reference is copied into the XHR and copied back out when the nested call returns, the code will be verifiable, but the semantics will be inexact . Truly an exquisite dilemma!

Structural Compatibility of Delegates

Delegates are the CTS versions of type-safe function pointers. Although delegates are most often used to implement the event-handling model used by GUI programs on .NET, they are also well suited to implement the procedure variable types of Component Pascal. However, there is a slight semantic constraint. We would like delegates to be assignment compatible if they represent methods with the same signature. Instead, they are compatible only if the two types have the same type name . It is always possible to program around this constraint, but it nevertheless represents a slight semantic inaccuracy in the language implementation. Future versions of the runtime system will support the required structural compatability, so the problem will eventually go away.

Covariant Function Types

Methods in Component Pascal may be declared with covariant return types. That is, an overriding method may return a type that is a narrowed version of the return type of the method that it overrides . This language feature is not supported by the runtime environment.

It is possible to overcome this constraint by using a limited form of type erasure. In summary, the compiler produces code that promises to return the non-covariant type, so as to keep the verifier happy. However, the Component Pascal compiler knows that the real return type is narrower, and it casts the return values as necessary. This trick has a low overhead and precise semantics. The only problem is that in a mixed-language environment a compiler for a different language might try to subclass the type and override the covariant method. If the compiler for the other language did not understand the covariance metadata, it might allow the overriding method to return an incorrect type. This could cause an unexpected class cast exception in the Component Pascal component.



Programming in the .NET Environment
Programming in the .NET Environment
ISBN: 0201770180
EAN: 2147483647
Year: 2002
Pages: 146

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net