LEGACY DOCS · 12.1Stable is 13.2. This page stays because it still owns historical or unchanged contracts.CURRENT 13.2 →
RELEASE LINE13.2 HISTORICAL13.1 PREDECESSOR13.0 PREVIOUS12.4 NATIVE MIRARCHIVE

V12.1 RUNTIME FOUNDATION

PAGE ROLE · NORMATIVE CONTRACT

RUNTIME · DROP

Normative release contract summary from docs/RUNTIME.md in the supplied v12.1.0 package.

import "alloc.dby" as alloc
import "array.dby" as array
import "string.dby" as string

static mut STORAGE: array[u8, 4096]
static mut ARENA: alloc.ArenaAllocator

pub fn kernel_main() -> int:
    let allocator = alloc.arena_initialize(&ARENA, &STORAGE as usize as ptr[u8], 4096 as usize)
    let values = array.with_allocator[u32](allocator)
    let first = array.push[u32](borrow mut values, 40 as u32)
    match first:
        case Result.Ok(value):
            let accepted: u32 = 0 as u32
        case Result.Err(error):
            return 1
    let second = array.push[u32](borrow mut values, 2 as u32)
    match second:
        case Result.Ok(value):
            let accepted: u32 = 0 as u32
        case Result.Err(error):
            return 1
    let result = array.pop[u32](borrow mut values)
    match result:
        case Option.Some(value):
            if value != (2 as u32):
                return 1
        case Option.None():
            return 1
    let made = string.from_view("runtime", allocator)
    match made:
        case Result.Ok(text):
            if string.length(borrow text) != (7 as usize):
                return 1
        case Result.Err(error):
            return 1
    return 0
DBY · 1.2 KiBSHA-256 98ada86aca557c533455b3f80e366489ef03a7d18bf190c4700a996b3410d864
import "alloc.dby" as alloc
import "array.dby" as arrays
import "string.dby" as string
import "serial.dby" as serial

static mut ARENA_MEMORY: array[u32, 2048]
static mut FIXED_MEMORY: array[u32, 1024]
static mut ARENA: alloc.ArenaAllocator
static mut FIXED: alloc.FixedAllocator
static mut KERNEL: alloc.KernelAllocator
static mut KERNEL_BACKING: alloc.AllocatorRef

fn line(text: str, length: usize) -> unit:
    serial.write(text, length)
    serial.newline()
    return unit

fn fail() -> int:
    return 1

fn push_byte(values: borrow mut arrays.Array[u8], value: u8) -> bool:
    let result = arrays.push[u8](values, value)
    match result:
        case Result.Ok(accepted):
            return true
        case Result.Err(error):
            return false

fn mutate_first(values: borrow mut arrays.Array[u8]) -> bool:
    let view = arrays.as_mut_slice[u8](values)
    if len(view) == (0 as usize):
        return false
    view[0 as usize] = 68 as u8
    return view[0 as usize] == (68 as u8)

fn first_u32(values: borrow arrays.Array[u32]) -> u32:
    let view = arrays.as_slice[u32](values)
    return view[0 as usize]

fn second_u32(values: borrow arrays.Array[u32]) -> u32:
    let view = arrays.as_slice[u32](values)
    return view[1 as usize]

fn first_byte(text: borrow string.String) -> u8:
    let view = string.as_view(text)
    return view[0 as usize]

fn kernel_allocate(context: ptr[u8], size: usize, alignment: usize) -> Result[ptr[u8], alloc.AllocError]:
    let backing: ptr[alloc.AllocatorRef] = context as usize as ptr[alloc.AllocatorRef]
    let allocator = alloc.AllocatorRef(context = (*backing).context, vtable = (*backing).vtable)
    return alloc.allocate(allocator, size, alignment)

fn kernel_resize(context: ptr[u8], pointer: ptr[u8], old_size: usize, new_size: usize, alignment: usize) -> Result[ptr[u8], alloc.AllocError]:
    let backing: ptr[alloc.AllocatorRef] = context as usize as ptr[alloc.AllocatorRef]
    let allocator = alloc.AllocatorRef(context = (*backing).context, vtable = (*backing).vtable)
    return alloc.resize(allocator, pointer, old_size, new_size, alignment)

fn kernel_free(context: ptr[u8], pointer: ptr[u8], size: usize, alignment: usize) -> unit:
    let backing: ptr[alloc.AllocatorRef] = context as usize as ptr[alloc.AllocatorRef]
    let allocator = alloc.AllocatorRef(context = (*backing).context, vtable = (*backing).vtable)
    alloc.release(allocator, pointer, size, alignment)
    return unit

pub fn kernel_main() -> int:
    serial.init()
    line("DBYTE RUNTIME FOUNDATION", 24 as usize)
    let arena = alloc.arena_initialize(&ARENA, &ARENA_MEMORY as usize as ptr[u8], 8192 as usize)
    let fixed = alloc.fixed_initialize(&FIXED, &FIXED_MEMORY as usize as ptr[u8], 4096 as usize)
    KERNEL_BACKING = fixed
    let kernel = alloc.kernel_initialize(&KERNEL, &KERNEL_BACKING as usize as ptr[u8], kernel_allocate, kernel_resize, kernel_free)

    let kernel_block = alloc.allocate(kernel, 32 as usize, 16 as usize)
    match kernel_block:
        case Result.Ok(pointer):
            alloc.release(kernel, pointer, 32 as usize, 16 as usize)
        case Result.Err(error):
            return fail()
    if alloc.kernel_allocation_calls(&KERNEL) != (1 as u32):
        return fail()
    if alloc.kernel_free_calls(&KERNEL) != (1 as u32):
        return fail()

    let empty = alloc.allocate(arena, 0 as usize, 16 as usize)
    match empty:
        case Result.Ok(pointer):
            if alloc.arena_allocation_calls(&ARENA) != (0 as u32):
                return fail()
        case Result.Err(error):
            return fail()

    let first = alloc.allocate(fixed, 64 as usize, 16 as usize)
    match first:
        case Result.Ok(pointer):
            alloc.release(fixed, pointer, 64 as usize, 16 as usize)
            let reused = alloc.allocate(fixed, 64 as usize, 16 as usize)
            match reused:
                case Result.Ok(second):
                    if second != pointer:
                        return fail()
                    alloc.release(fixed, second, 64 as usize, 16 as usize)
                case Result.Err(error):
                    return fail()
        case Result.Err(error):
            return fail()

    let split_a = alloc.allocate(fixed, 64 as usize, 16 as usize)
    let split_b = alloc.allocate(fixed, 64 as usize, 16 as usize)
    let split_c = alloc.allocate(fixed, 64 as usize, 16 as usize)
    match split_a:
        case Result.Ok(pointer_a):
            match split_b:
                case Result.Ok(pointer_b):
                    match split_c:
                        case Result.Ok(pointer_c):
                            alloc.release(fixed, pointer_b, 64 as usize, 16 as usize)
                            alloc.release(fixed, pointer_a, 64 as usize, 16 as usize)
                            let merged = alloc.allocate(fixed, 96 as usize, 16 as usize)
                            match merged:
                                case Result.Ok(merged_pointer):
                                    if merged_pointer != pointer_a:
                                        return fail()
                                    alloc.release(fixed, merged_pointer, 96 as usize, 16 as usize)
                                    alloc.release(fixed, pointer_c, 64 as usize, 16 as usize)
                                case Result.Err(error):
                                    return fail()
                        case Result.Err(error):
                            return fail()
                case Result.Err(error):
                    return fail()
        case Result.Err(error):
            return fail()

    let values = arrays.with_allocator[u32](arena)
    let pushed = arrays.push[u32](borrow mut values, 40 as u32)
    match pushed:
        case Result.Ok(value):
            let accepted: u32 = 0 as u32
        case Result.Err(error):
            return fail()
    let pushed_again = arrays.push[u32](borrow mut values, 2 as u32)
    match pushed_again:
        case Result.Ok(value):
            let accepted: u32 = 0 as u32
        case Result.Err(error):
            return fail()
    if arrays.length[u32](borrow values) != (2 as usize):
        return fail()
    let old_capacity: usize = arrays.capacity[u32](borrow values)
    let impossible = arrays.reserve[u32](borrow mut values, 0xffffffff as u32 as usize)
    match impossible:
        case Result.Ok(value):
            return fail()
        case Result.Err(error):
            if arrays.capacity[u32](borrow values) != old_capacity:
                return fail()
    let values_view = arrays.as_slice[u32](borrow values)
    if len(values_view) != (2 as usize):
        return fail()
    if values_view[0 as usize] != (40 as u32):
        return fail()
    let cloned_values = arrays.clone[u32](borrow values)
    match cloned_values:
        case Result.Ok(copy):
            if arrays.length[u32](borrow copy) != (2 as usize):
                return fail()
            if second_u32(borrow copy) != (2 as u32):
                return fail()
            drop(copy)
        case Result.Err(error):
            return fail()
    let moved_allocator_values = arrays.clone_in[u32](borrow values, fixed)
    match moved_allocator_values:
        case Result.Ok(copy):
            if first_u32(borrow copy) != (40 as u32):
                return fail()
            drop(copy)
        case Result.Err(error):
            return fail()

    let utf8_bytes = arrays.with_allocator[u8](arena)
    if push_byte(borrow mut utf8_bytes, 0 as u8) == false:
        return fail()
    if push_byte(borrow mut utf8_bytes, 0xc3 as u8) == false:
        return fail()
    if push_byte(borrow mut utf8_bytes, 0xa9 as u8) == false:
        return fail()
    if mutate_first(borrow mut utf8_bytes) == false:
        return fail()
    let utf8_view = arrays.as_slice[u8](borrow utf8_bytes)
    let decoded = string.from_utf8(utf8_view, arena)
    match decoded:
        case Result.Ok(text):
            if string.length(borrow text) != (3 as usize):
                return fail()
            let decoded_view = string.as_view(borrow text)
            if decoded_view[0 as usize] != (68 as u8):
                return fail()
            if decoded_view[1 as usize] != (0xc3 as u8):
                return fail()
            if decoded_view[2 as usize] != (0xa9 as u8):
                return fail()
        case Result.Err(error):
            return fail()

    let invalid_bytes = arrays.with_allocator[u8](arena)
    if push_byte(borrow mut invalid_bytes, 0xc0 as u8) == false:
        return fail()
    if push_byte(borrow mut invalid_bytes, 0xaf as u8) == false:
        return fail()
    let invalid_view = arrays.as_slice[u8](borrow invalid_bytes)
    let rejected = string.from_utf8(invalid_view, arena)
    match rejected:
        case Result.Ok(text):
            return fail()
        case Result.Err(error):
            match error:
                case string.StringError.InvalidUtf8:
                    let accepted: u32 = 0 as u32
                case string.StringError.Allocation(allocation_error):
                    return fail()

    let made = string.from_view("DByte UTF-8", arena)
    match made:
        case Result.Ok(text):
            if string.length(borrow text) != (11 as usize):
                return fail()
            let text_view = string.as_view(borrow text)
            if len(text_view) != (11 as usize):
                return fail()
            if text_view[0 as usize] != (68 as u8):
                return fail()
            let cloned_text = string.clone(borrow text)
            match cloned_text:
                case Result.Ok(copy):
                    if string.length(borrow copy) != (11 as usize):
                        return fail()
                    drop(copy)
                case Result.Err(error):
                    return fail()
            let fixed_text = string.clone_in(borrow text, fixed)
            match fixed_text:
                case Result.Ok(copy):
                    if first_byte(borrow copy) != (68 as u8):
                        return fail()
                    drop(copy)
                case Result.Err(error):
                    return fail()
        case Result.Err(error):
            return fail()
    let free_before: u32 = alloc.arena_free_calls(&ARENA)
    let words = arrays.with_allocator[string.String](arena)
    let nested = string.from_view("nested", arena)
    match nested:
        case Result.Ok(text):
            let nested_push = arrays.push[string.String](borrow mut words, text)
            match nested_push:
                case Result.Ok(value):
                    let accepted: u32 = 0 as u32
                case Result.Err(error):
                    return fail()
        case Result.Err(error):
            return fail()
    drop(words)
    if alloc.arena_free_calls(&ARENA) != free_before + (2 as u32):
        return fail()
    line("DROP ONLINE", 11 as usize)
    line("ALLOCATOR ABI ONLINE", 20 as usize)
    line("ARRAY ONLINE", 12 as usize)
    line("STRING ONLINE", 13 as usize)
    line("MOVE OWNERSHIP OK", 17 as usize)
    line("OOM TRANSACTION OK", 18 as usize)
    line("RUNTIME CHECK OK", 16 as usize)
    return 0
DBY · 11.0 KiBSHA-256 00eed9640653fa814525faad45cabf7c545ab614be3c6eb30484e185ab43cb52

SOURCE SHA-256 1225888fc77de837846ca7fcc74336011e8aadc91240251a80e199c612da19cd · RAW CONTRACT MIRROR

00 destruction§

drop fn is a nominal language item with one borrow mut T parameter and unit result. T must be a struct or enum owned by the same module. Source cannot call the destructor directly; drop(value) consumes the owner and invokes compiler-resolved glue.

CUSTOM DESTRUCTOR
        |
        v
ACTIVE PAYLOAD + OWNED FIELDS
        |
        v
REVERSE DECLARATION ORDER

10 ownership + cleanup edges§

Moved sources lose their cleanup obligation; destinations acquire exactly one. Locals register cleanup only after successful initialization. Return storage is populated before local cleanup.

Drop and defer share one reverse-activation cleanup graph for fallthrough, return, break, continue and ?.

BOUNDARY: v12.1 has no dynamic drop flags. Partial moves and maybe-live · maybe-moved control-flow joins are rejected. Architectural faults, aborts and process termination do not unwind.

20 metadata§

Public nominal drop contracts are carried in non-loadable .dbyte.drop metadata. Object parsing and linking validate canonical records and remove the section from final executables.

30 runtime modules§

The normative document defines allocator, Array and String behavior through DByte runtime modules and allocator vtables. The i686 owned collection layout is five words: data, length, capacity, allocator context and allocator vtable.

NEXT: Read allocator capability contract.