RUNTIME · DROP
Normative release contract summary from docs/RUNTIME.md in the supplied v12.1.0 package.
[ SUPPLEMENTAL SMOKE SOURCE ] [ SUPPLEMENTAL KERNEL SOURCE ]
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
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
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 ORDER10 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 ?.
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.