Native Types

XXML provides access to low-level types and memory operations for systems programming, enabling direct hardware-level access when needed.

NativeType

xxml
// Property declarations
Property <ptr> Types NativeType<"void*">^;
Property <count> Types NativeType<"int64">^;
Property <flags> Types NativeType<"uint32">^;
Property <byte> Types NativeType<"uint8">^;

// Local variables
Instantiate NativeType<"int64">% As <size> = 1024;
Instantiate NativeType<"void*">% As <buffer> = Syscall::malloc(size);
TypeDescriptionSize
NativeType<"int8">Signed 8-bit integer1 byte
NativeType<"uint8">Unsigned 8-bit (byte)1 byte
NativeType<"int32">Signed 32-bit integer4 bytes
NativeType<"int64">Signed 64-bit integer8 bytes
NativeType<"void*">Pointer8 bytes (64-bit)
NativeType<"float">32-bit floating point4 bytes
NativeType<"double">64-bit floating point8 bytes

NativeStructure

Define C-compatible structures for FFI:

xxml
[ NativeStructure <Point>
    [ Public <>
        Property <x> Types NativeType<"int32">%;
        Property <y> Types NativeType<"int32">%;
    ]
]

[ NativeStructure <Rectangle>
    [ Public <>
        Property <left> Types NativeType<"int32">%;
        Property <top> Types NativeType<"int32">%;
        Property <right> Types NativeType<"int32">%;
        Property <bottom> Types NativeType<"int32">%;
    ]
]

// Usage
Instantiate Point% As <p>;
Set p.x = 10;
Set p.y = 20;
Run nativeDrawPoint(&p);

Syscall Interface

Memory Management

xxml
// Allocate memory
Instantiate NativeType<"void*">% As <ptr> = Syscall::malloc(size);

// Free memory
Run Syscall::free(ptr);

// Copy memory
Run Syscall::memcpy(dest, src, numBytes);

// Set memory
Run Syscall::memset(ptr, value, numBytes);

Pointer Operations

xxml
// Read value from pointer
Instantiate MyType^ As <value> = Syscall::ptr_read(pointer);

// Write value to pointer
Run Syscall::ptr_write(pointer, value);

// Read single byte
Instantiate NativeType<"uint8">% As <byte> = Syscall::read_byte(pointer);

// Write single byte
Run Syscall::write_byte(pointer, byteValue);

Pointer Arithmetic

xxml
// Calculate offset
Instantiate NativeType<"void*">% As <base> = Syscall::malloc(100);
Instantiate NativeType<"int64">% As <offset> = 10;
Instantiate NativeType<"void*">% As <ptr> = base + offset;

// Pointer subtraction
Instantiate NativeType<"int64">% As <diff> = ptr2 - ptr1;

Complete Example: Buffer Class

buffer.xxml
[ Class <Buffer> Final Extends None
    [ Private <>
        Property <data> Types NativeType<"void*">^;
        Property <size> Types NativeType<"int64">^;
    ]

    [ Public <>
        Constructor Parameters (
            Parameter <bufferSize> Types NativeType<"int64">%
        ) -> {
            Set data = Syscall::malloc(bufferSize);
            Set size = bufferSize;
            Run Syscall::memset(data, 0, bufferSize);
        }

        Destructor Parameters () -> {
            Run Syscall::free(data);
        }

        Method <write> Returns None Parameters (
            Parameter <offset> Types NativeType<"int64">%,
            Parameter <value> Types NativeType<"uint8">%
        ) Do {
            Instantiate NativeType<"void*">% As <ptr> = data + offset;
            Run Syscall::write_byte(ptr, value);
        }

        Method <read> Returns NativeType<"uint8">% Parameters (
            Parameter <offset> Types NativeType<"int64">%
        ) Do {
            Instantiate NativeType<"void*">% As <ptr> = data + offset;
            Return Syscall::read_byte(ptr);
        }

        Method <getSize> Returns NativeType<"int64">% Parameters () Do {
            Return size;
        }
    ]
]

Warning

Native memory operations bypass XXML's safety guarantees. Always pair malloc with free, check for null pointers, and validate buffer bounds.

Best Practices

Memory Safety

  • Always free allocated memory - Match every malloc with free
  • Check for null - Verify allocation succeeded before use
  • Avoid buffer overflows - Validate indices before access
  • Use RAII - Wrap native resources in classes with destructors

Performance

  • Minimize allocations - Reuse buffers when possible
  • Align data - Use natural alignment for better cache performance
  • Batch operations - Use memcpy for bulk transfers

Next Steps

Learn about FFI for calling native libraries, or explore Destructors for RAII-style cleanup.