NEW, IS and SYSTEM.TYP

As of December 2021, these features have been implemented: stadard procedure NEW applied to record parameters; relational operator IS applied to record types; and function procedure SYSTEM.TYP applied to pointer variables and record/record pointer types:

TYPE T = POINTER TO EXTENSIBLE RECORD END; Ext = POINTER TO RECORD (T) END; VAR p: T; x: LONGINT; BEGIN NEW(p); IF p IS Ext THEN x := SYSTEM.TYP(Ext) ELSE x := SYSTEM.TYP(T) END; x := SYSTEM.TYP(p); END

Of course, NEW is not implemented by the compiler, but rather by the run-time environment mandated by the Language Report. What the compiler does is transform NEW(p) into calls to a procedure of the following quasi-signature:

NEW = PROCEDURE (tag: ADDRESS): T;

where *tag *is the address of the type descriptor of the formal type of p, i.e. T. Thus, the compiler performs the following transformation:

NEW(p) => p := @Kernel.NewRec(SYSTEM.TYP(T))

The peculiarity is that subject module containing NEW(p) does not have to import Kernel explicitly, and cannot import Kernel implicitly: in a particular system, the procedure implementing NEW(p) may be defined in an arbitrary module. The linking is done at module load time by the loader. So, the compiler has to provide data for the linking loader to be able to perform the linking. The format of this data has changed in the updated OCF format, as has the format of all data defining imports and import fixups in the machine code and module metadata.

The other novelty is that imported types’s descriptor addresses have to be entered at link time into the PROXY table. Thus the PROXY table now holds addresses of imported procedures and imported types’ descriptors. Unlike imported procedures, imported types may be referenced not only from machine code (which is done as a RIP-relative addressing into PROXY), but also from the module’s metadata. This means that the linker has to not only place the imported type’s descriptor address into the PROXY table, but also fixup all references to this type descriptor from the metadata. And the compiler has to chain all references to each imported type.

The testing environment in A2 was made capable of linking against ‘platform interface modules’, much like module WinApi allows to use WinApi calls in BlackBox modules. A module ProtoKernel (compiled by Herschel) imports a platform module and calls a primitive memory allocation procedure in order to provide the NewRec procedure. Thus a module M (compiled also by Herschel) may use NEW, IS and SYSTEM.TYP. The linking loader in the testing environment performs all the work for M to be loaded and executed. This testing environment might in the future become a prototype for BlackBox running on top of A2.

Appropriate tests have been added to the project.

The A2 tester allowing to allocate dynamic variables makes way to further development of Herschel and implementation of other features related to dynamic memory and type extension.