Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Undocumented intrinsic routines

Delphi has this list: Delphi Intrinsic Routines
But that list is incomplete.

What are the 7 undocumented intrinsic functions, since when and what is their purpose?

like image 993
Johan Avatar asked May 23 '15 20:05

Johan


1 Answers

I know of the following undocumented intrinsic functions.

Delphi 2007: here and Hallvard's blog:

Default

function Default(T: Typeidentifier): value of T;     

Returns the zero representation of type identifier T.

The following intrinsics introduced in XE7 are explained in the XE7 beta blog and by Stefan Glienke

IsManagedType

function IsManagedType(T: TypeIdentifier): Boolean;   

True if T is a interface, string or dynamic array, or a record containing such. A class containing a managed type will return false.

In XE6 and older you have to use System.Rtti.IsManaged(TypeInfo(T)).

HasWeakRef

function HasWeakRef(T: TypeIdentifier): Boolean;    

True if T has been annotated as [weak]. The compiler keeps a list of [weak] references. You cannot use move and other tricks with these types, because that will prevent the weak-list from getting updated.

In XE6 and older you have to use System.TypInfo.HasWeakRef(TypeInfo(T)).

GetTypeKind

function GetTypeKind(T: TypeIdentifier): TTypeKind;   

Does the same thing as PTypeInfo(System.TypeInfo(T))^.Kind;, however because it is a compiler intrinsic the function is resolved at compiletime and conditional code that evaluates to false will be stripped by the compiler.

IsConstValue

function IsConstValue(const Value): Boolean;          

True if Value is a constant, false if not.
This helps the compiler to eliminate dead code because the function is evaluated at compile time.
This is only useful in inline functions, where it allows for shorter generated code.

TypeInfo

function TypeInfo(T: typeindentifier): PTypeInfo;

This function is not undocumented as such, but what is undocumented is that it is an intrinsic function since XE7.
That means that the snippet if TypeInfo(T) = TypeInfo(byte) then ... does not generate any code if T is not a byte and the test will be resolved at compiletime.
However the compile-time resolution only works inside generic routines and only when doing a if (TypeInfo(T) = TypeInfo(sometype) test.
The test if TypeInfo(byte) = TypeInfo(smallint) then does not get eliminated even though it always evaluates to false.
Nor does other use of TypeInfo(T).

ReturnAddress

The following are used with the raise exception at returnaddress construct.

function ReturnAddress(Expression): pointer;          //Delphi ?
function AddressOfReturnAddress(Expression): pointer; //Delphi ?

And as far as I know you can't call them directly from user code.

Example of IsConstValue

type
   TFlavor = (Tasty, Nasty);
   TIntegerHelper = record helper for integer
     function GetSomething(Flavor: TFlavor): TPoint; inline;
   private
     function GetTastyPoint: TPoint;
     function GetNastyPoint: TPoint;
   end;
 
 function TIntegerHelper.GetSomething(Flavor: TFlavor): TPoint;
 begin
   if IsConstValue(Flavor) then begin
     if Flavor = Tasty then Result:= Self.GetTastyPoint
     else Result:= Self.GetNastyPoint;
   end else begin
     Assert(1=0, 'This function can only be called with constant parameters');
   end;
 end; 

procedure Test;
var
  pt: TPoint;
begin
  pt:= 100000.GetSomething(Tasty); 
This call will get translated to GetTastyPoint and the if/then sequence will be eliminated by the linker.
like image 53
Johan Avatar answered Nov 14 '22 18:11

Johan