Skip to content

Record Layout and Runtime Implementation

Michael Wang edited this page Jul 15, 2022 · 3 revisions

NOTE: This content is out of date. This precedes the addition of RTTI and type guards. NOTE: The content here regards the implementation details of cish, and therefore may not be up to date. There is no guarantee the following content is completely accurate.

Runtime Implementation with Heap Allocations

cish records, very much like C-style records are merely compile-time abstractions - they ultimately boil down into an abstraction over a cish heap-allocation, which is defined as the following:

typedef struct machine_heap_alloc {
	machine_reg_t* registers;
	int* init_stat, *trace_stat;
	uint16_t limit;

	int gc_flag, reg_with_table, pre_freed;
	gc_trace_mode_t trace_mode;
} heap_alloc_t;

Here is what each property represents:

  • The record's properties are stored in machine_reg_t* registers(read more about them here).
  • init_stat is an array of flags that signify whether a property has been initialized or not.
  • trace_stat signifies whether a property is a reference type(this is a run-time determined value because of generics) and therefore should be traced during garbage collection.
    • This may not be allocated depending on the heap allocation's garbage collector tracing configuration (gc_trace_mode).
  • int gc_flag represents whether a heap_allocation has been traced(and therefore should be kept).
  • int reg_with_table is a flag that signifies whether a heap_allocation is currently registered within SuperForth's garbage collection stack. It is used when heap allocation headers(the struct defined above) are recycled. The headers have to be allocated because of the swapping that goes one when allocations are traced, and kept.
  • int pre_freed Signifies whether a heap allocation's header has been freed beforehand, and should therefore not be freed again.
  • gc_trace_mode_t trace_mode determines the heap allocation's garbage collection trace configuration. Note: You can disregard the last 3 mentioned properties(gc_flag, reg_with table, and pre_freed).

Record Layout

This section talks about the layout of machine_reg_t* registers. Generally speaking, properties are mapped to indices after compilation. Those indices are used to access/set elements from heap allocations.

As a rule of thumb, properties are assigned indices in the order that they are defined. Take the following example:

record person {
	array<char> name = "Michael"; //mapped to index 0
	int age = 16; //mapped to index 1
        person parent; //mapped to index 2
}

When inheritance comes into play, the object is still composed of one heap allocation, unlike many dynamic languages(looking at python).

record student extends person {
	name = "Stanley"; //this is a default property value initializer, it's not mapped to an index
	float gpa = 0f; //mapped to index 3
        person least_favorite_teacher; //mapped to index 4
}
Clone this wiki locally