burn / docs

The Burn VM

Values and the runtime library

Type ids

Every module starts with twelve built-in types. The types it declares are numbered from 12 on.

Id Type Id Type
0 error 6 string
1 void 7 any
2 null 8 [any]
3 int 9 map<string, any>
4 float 10 [string]
5 bool 11 [int]

Runtime functions that have to understand a value take its static type id as an extra argument. For example to_str takes the value and its type, so const 3; rt to_str formats an int and const 11; rt to_str formats an [int] array.

Heap objects

Heap objects start with a 16-byte header: kind (1 byte), cycle collector color, flags, element kind, type id (4 bytes), size in bytes (4 bytes) and reference count (4 bytes). After the header:

Kind Layout
string length at +16, UTF-8 bytes at +24
array length at +16, capacity at +24, pointer to the elements at +32 (8 bytes each, or packed, see below)
record field i at +16 + 8·i
box the boxed value at +16, with the type id of the value in the header
map, future opaque, used through runtime functions

The sized number types (int8, uint8, int16, uint16, int32, uint32, uint64, float32) are written int8 ... float32 in bvm assembly. On the stack they are 64-bit words like every other value: integers are sign- or zero-extended and float32 values are doubles rounded to single precision. Arrays whose element type is one of the packed types (all of them except uint64) store each element in 1, 2 or 4 bytes; the element kind byte in the header says which, and index, setindex and the array runtime functions convert between the packed bytes and 64-bit words.

Values of type any are boxes (or the object itself when it is already on the heap). rt box v tid creates one and unbox reads it. rt is_type, rt cast and rt type_name inspect it.

Reference counting

Objects are reference counted. A new object has a count of 1, owned by whoever created it: the result of rt functions, newarr, new and calls is owned by the code that receives it. rt retain v adds an owner and returns v, rt release v removes one and frees the object when none is left, releasing what it holds. Both ignore null and strings from the module's string pool, which are static.

Containers own their contents: newarr and new take ownership of the values they are built from, and rt functions that store a value (arr_push, arr_set, map_set, box, ...) add their own owner, so the caller still releases its copy. index, getfield and unbox read without adding an owner. Burn generates these instructions itself; another language on bvm must do the same, or its objects are never freed.

Objects that only refer to each other are found by a cycle collector, which runs when enough memory has been allocated (BURN_GC_THRESHOLD, 32 MB by default; BURN_GC_STATS=1 prints a line each time) and never while spawned threads are running. While threads run, counts are updated atomically.

Runtime functions

rt name pops the function's arguments (the first argument is deepest on the stack) and pushes its result. Functions without a meaningful result return 0, so pop it. bvm runtime prints every name with its argument count. The most useful ones:

Written in Burn

The whole runtime is written in Burn, in lib/rt/ of the Burn repository: memory and values, reference counting and the cycle collector, strings, arrays, maps, records, printing and number formatting, files, processes, the network, JSON, time and tasks. It calls the C library through @Extern and works on raw memory in unsafe code (std/memory). Each runtime function is a Burn function with a C name:

@Extern("burn_str_split")
pub unsafe fun strSplit(s: int, sep: int): int {
    ...
}

The same code is compiled into the toolchain, where rt str_split calls burn_str_split directly, and into libburn_runtime.a, which native executables link, so a program behaves the same on bvm and as an executable. A runtime function raises a runtime error that points at loc, the place in the program that called it, as in str_index, arr_get and fail below.

Text and output

Function Arguments Result
print, print_raw, print_err string prints with a newline, without one, or to stderr
to_str value, type id the value formatted as text (arrays, maps and records included)
str_concat a, b a new string a + b
str_eq, str_cmp a, b 1 if equal / -1, 0 or 1
str_len s length in characters
str_index s, i, loc the character at i as a string
str_sub s, start, end substring (character indexes)
str_find, str_contains, str_starts, str_ends s, t index or -1 / bool
str_replace s, from, to replaces every occurrence
str_split s, sep [string]
str_trim, str_upper, str_lower, str_chars s transformed string / [string] of characters
str_repeat s, n s repeated n times
str_code, str_from_code s / n code point of the first character / string from a code point
char_class s, kind 1 if every character is a letter (0), digit (1), letter or digit (2), whitespace (3)
parse_int, parse_float s, loc the parsed number; a runtime error if s isn't one
is_int_str, is_float_str s bool
is_int_radix, parse_int_radix s, radix, loc bool / the int in base radix
int_to_str_radix n, radix, loc n written in base radix
input prompt a line from stdin
read_stdin all of stdin

Arrays and maps

Function Arguments Result
arr_new array type id, length a zero-filled array
arr_push arr, v appends
arr_pop arr, loc removes and returns the last element
arr_insert, arr_remove arr, i, (v,) loc inserts / removes and returns
arr_get, arr_set arr, i, (v,) loc bounds-checked access (the index instruction is faster)
arr_slice arr, start, end a new array
arr_concat, arr_copy, arr_reverse, arr_clear arr (, other) new array / in place
arr_index_of, arr_contains arr, v, element type id index or -1 / bool
arr_join arr, separator, element type id a string
arr_sort arr, element type id sorts in place
map_new map type id an empty map
map_set, map_get, map_get_or map, key, value / loc / default writes / reads
map_has, map_remove, map_len map (, key) bool / removes / count
map_keys, map_values map, array type id an array

Everything else

Function Arguments Result
fmath op, x 0 sqrt, 1 floor, 2 ceil, 3 round, 4 abs, 5 sin, 6 cos, 7 tan, 8 ln, 9 log10, 10 exp, 11 asin, 12 acos, 13 atan
fpow, fatan2, fmod, fmin, fmax a, b float math
ipow, imin, imax, iabs a (, b) integer math
random, random_int, seed / lo, hi / seed float in [0, 1) / int in [lo, hi] / 0
now_ms, now_sec, clock_ns, sleep / ms wall clock and monotonic time
read_file, write_file, append_file, file_exists path (, content or loc) file I/O
env, args name / environment variable / [string] of program arguments
json_parse, json_stringify text, loc / value, type id any / string
http_request method, url, body, [string] headers [status, body, headers]
box, is_type, cast, unwrap, type_name value and type ids dynamic typing helpers
eq, cmp a, b, type id structural equality / ordering
await future the result of a spawn
panic, assert message, loc / cond, message, loc runtime errors
fail message, loc a runtime error with message at loc
exit_now code waits for spawned threads, flushes output and exits
gc_collect forces a collection