C0 Value and Pointer

In C0VM.ts, everything is eventually a segment of ArrayBuffer. We use DataView to wrap up the ArrayBuffer with two benefits:

  • DataView provides an interface that allow us to read and write the ArrayBuffer

  • DataView allow us to create alias to a specific segment of ArrayBuffer

C0Pointer *t

C0Pointer 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.

Start Index (include)
End Index (exclude)
Representation

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

A pointer points at allocated memory segment [address, address + size) with precise address as address + offset will be represented as

[address, offset, size]

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)

Currently, I planned to use pointers with

Field
Value

Address

0x0000_0000

Offset

0x0000 to 0xFFFF

Size

0x0000

to represent the function pointers.

Int, Boolean and Char w32

int, 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[]

For any type t with size s, we can create an array of it. The array is described by structure like this

Starting Index (Include)
Ending Byte Index (Exclude)
Meaning

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.

Last updated