C0 Value and Pointer
This section is not the Type Inference section. This section will not discuss how the actual type of variable is inference during runtime. We only focus on the w32 (value type) and * (pointer type) here.
In C0VM.ts, everything is eventually a segment of ArrayBuffer. We use DataView to wrap up the ArrayBuffer with two benefits:
DataViewprovides an interface that allow us to read and write theArrayBufferDataViewallow us to create alias to a specific segment ofArrayBuffer
C0Pointer *t
*tC0Pointer is a DataView with byte-length of 8 (64-bit). However, different from what C actually do to pointer, we only use the first 6 bytes to store the memory address. The remaining 2 bytes are used to annotate the size of allocated memory block. This allow C0VM.ts to check memory-access out of bound and throw error when dereferencing (or even creating!) such pointer.
0
4
Uint32 - (address) Address of Memory block this pointer is pointing to
4
6
Uint16 - (offset) Offset of the pointer on the pointed memory block
6
8
Uint16 - (size) The size of memory block
NULL Pointer
By C convention, if a pointer is 0x0000000000000000 (64-bit zero), we say this pointer is a NULL Pointer.
Since the definition of NULL pointer is subject to change in the future, it is highly recommended to use the function
export function isNullPtr(ptr: C0Pointer): boolean;to verify whether a pointer is NULL or not.
Read Pointer
A helper function
export function read_ptr(ptr: C0Pointer): [number, number, number];
// usage example
const [addr, offset, size] = read_ptr(ptr);is defined in utility/pointer_ops.ts. Giving the function a C0Pointer (which is, in fact, only an alias of DataView), it will return the address, offset of pointer and size of memory segment.
Function Pointer* (C1 Standard)
The Function Pointer is not supported in C0VM now, it is here for future implementation and compatibility.
Currently, I planned to use pointers with
Address
0x0000_0000
Offset
0x0000 to 0xFFFF
Size
0x0000
to represent the function pointers.
Int, Boolean and Char w32
w32int, boolean and char are all a DataView with length of 4 bytes. That is to say, they are all stored in a segment of ArrayBuffer.
In C0VM Write-up, these 4-bytes values are all annotated as w32 type.
For types of boolean and char, their value will be stored in the last byte of the 4-byte ArrayBuffer (follows little endian byte ordering).
Array t[]
t[]For any type t with size s, we can create an array of it. The array is described by structure like this
0
4
Size of each element of the array
4
4 + n * s
An n-element array
C0Value
Defined in
./src/types/types.d.ts
C0Value is a wrapper for the actual values in C0VM with type information stored to allow us perform run-time type inference.
declare const enum C0TypeClass {
unknown = "<unknown>",
value = "value",
ptr = "ptr",
string = "string"
}
type C0Value<T extends C0TypeClass> = {
type: C0Type<T>;
value: DataView;
};The type here is the inferenced data type that can be used for visualization and debug console. This will be further discussed in the Type Inference section.
In the future, some more options will be added to the C0TypeClass to make it compatible with tagged_pointer and func_pointer (C1 Standard).
Last updated