Cook Computing

 

«  Component Pascal  »

Thursday 30 May 2002

Component Pascal, described in the interesting Compiling for the .NET Common Language Runtime, does support covariant return types.

I verified this in my first (and last?) CP program:

MODULE HELLO;
IMPORT CPmain, Console;
  
TYPE 
  BaseParser = EXTENSIBLE RECORD END;
  FaultParser = EXTENSIBLE RECORD (BaseParser) END;
  
  BaseRet = EXTENSIBLE RECORD END;
  BaseRetPtr = POINTER TO BaseRet;
	
  FaultRet = RECORD (BaseRet) END;
  FaultRetPtr = POINTER TO FaultRet;
 
VAR
  bp : POINTER TO BaseParser;
  bret : BaseRetPtr;
  fp : POINTER TO FaultParser;
  fret : FaultRetPtr;

PROCEDURE (IN p : BaseParser) Foo() :  BaseRetPtr, NEW , EXTENSIBLE;
VAR tmp : BaseRetPtr;
BEGIN
  NEW(tmp);
  RETURN tmp;
END Foo;

PROCEDURE (IN p : FaultParser) Foo() :  FaultRetPtr;
VAR tmp : FaultRetPtr;
BEGIN
  NEW(tmp);
  RETURN tmp;
END Foo;
  
BEGIN
  NEW(bp);
  bret := bp.Foo();
  NEW(fp);
  fret := fp.Foo();
END HELLO.

Method Foo in FaultParser overrides Foo in the base class and returns a pointer to FaultRet instead of BaseRet. CP handles the covariant return type via a two-pronged approach. First, Foo in the derived class, although defined in the IL method signature to return a type of BaseRet, actually returns a type of FaultRet:

.method assembly final virtual instance class HELLO.BaseRet 
        Foo() cil managed
{
  // Code size       8 (0x8)
  .maxstack  8
  .locals init ([0] class HELLO.FaultRet tmp)
  IL_0000:  newobj     instance void HELLO.FaultRet::.ctor()
  IL_0005:  stloc.0
  IL_0006:  ldloc.0
  IL_0007:  ret
} // end of method FaultParser::Foo

Second, the compiler recognizes that a covariant return is required and automatically downcasts the returned BaseRet to the required FaultRet type:

IL_0015: call       instance class HELLO.BaseRet HELLO.FaultParser::Foo()
IL_001a: castclass  class HELLO.FaultRet
IL_001f: stsfld     class HELLO.FaultRet HELLO.HELLO::fret

I don't how the compiler recognizes that a method supports covariant return when referencing another CP assembly because there doesn't seem to be any metadata to indicate this (even when all the types are marked as exportable)

Posted by at 07:45 AM. Permalink.