Skip to content

Latest commit

 

History

History
107 lines (82 loc) · 4.8 KB

File metadata and controls

107 lines (82 loc) · 4.8 KB

Ion runtime ABI notes

This document describes the runtime data shapes that Ion-generated C and the standard library agree on. It is intentionally a beta-facing contract, not a promise that every internal helper symbol is stable before 1.0.

General rules

  • Generated C is the compiler/runtime ABI boundary.
  • Ion values are owned by exactly one binding unless borrowed through &T or &mut T.
  • Owned values with runtime resources are dropped exactly once by generated scope-exit code.
  • References are stack-only views and must not be stored in runtime containers or sent across threads.

String

String is an owned runtime allocation for byte strings. Its C layout uses a uint8_t* data pointer plus length and capacity fields. String iteration in the beta subset is byte iteration (u8), not Unicode scalar-value or grapheme iteration.

Stable beta expectations:

  • String::new, String::from, String::len, String::push_str, and String::push_byte preserve ownership of the String receiver unless a function explicitly consumes it.
  • String::push_str appends string literals or owned String values (the latter reads .data/.len from the source heap buffer).
  • Dropping a String releases its backing allocation once.
  • String == String and String != String compare byte contents.

Vec<T>

Vec<T> is an owned dynamic array with pointer, length, and capacity. The C backend monomorphizes element-specific helpers where needed.

Stable beta expectations:

  • Vec::new, Vec::push, Vec::pop, Vec::get, Vec::get_ref, Vec::set, Vec::len, and Vec::capacity remain available through the stdlib/builtin surface.
  • Dropping Vec<T> drops owned elements when T needs destruction.
  • Bounds-sensitive operations either return Option<T> where documented or trigger the runtime panic path for checked indexing.
  • Vec::get / Vec::pop return heap Option blobs from the runtime; generated C unpacks them with ion_option_from_raw into monomorphized Option_T stack values (tag plus payload at data.variant_0.arg0). match on Vec::get / Vec::pop resolves Option<T> from the call's return type or the vector argument's element type (not the first Vec in the program).
  • Vec::get_ref returns a stack-local Option<&T>: codegen fills tag and a pointer into the vector buffer (or None when out of bounds). No runtime heap Option and no ion_option_from_raw. Monomorphized names use the ref_ prefix (for example Option_ref_int, Option_ref_Product). Match arms on Option::Some(x) bind drop-owning T as T*; copy types bind by value from *arg0. Scope cleanup must not drop nested owned fields through the binding.
  • Monomorphized container typedefs use Ion type names (Vec_String, Option_Customer), not C runtime typedefs (ion_string_t, etc.).
  • &mut Vec<T> parameters codegen as Vec_T**; builtins dereference once when passing the receiver to ion_vec_push, ion_vec_get, and related helpers. Vec::get_ref uses the same ion_vec_t* receiver but does not call ion_vec_get; it bounds-checks and takes the address of the slot in generated C.

Box<T>

Box<T> owns one heap-allocated T.

Stable beta expectations:

  • Box::new allocates and owns a value.
  • Box::unwrap consumes the box and returns the owned payload.
  • Dropping a Box<T> drops the payload and releases the allocation once.

Arrays and slices

Fixed arrays [T; N] are inline values. Slices []T are fat views carrying a data pointer and length. Safe indexing emits runtime bounds checks; indexing inside unsafe blocks may omit those checks.

Enums and structs

Struct layout is C-oriented and field-order preserving in generated C. Enum layout is compiler-generated and should be treated as stable only for C emitted by the same Ion compiler/runtime version unless a beta release explicitly documents a layout guarantee. Enum literals (Enum::Variant(...)) lower to C compound initializers ((Enum_T){ .tag = N, .data = { ... } }); the compiler does not emit per-variant _new helper functions.

Channels and spawn

Channels are typed ownership-transfer queues backed by the C runtime. Sending a value moves ownership into the channel; receiving moves ownership out. spawn creates an OS thread and transfers only structurally Send values into the thread context.

Stable beta expectations:

  • References do not cross channel or thread boundaries.
  • Channel handles are runtime resources and are released by generated drops.
  • Runtime failures such as allocation or thread creation failures call the Ion panic path.

Drops and panics

Generated code is responsible for normal-scope destruction. Runtime panics abort the process; they are not currently exception-style unwinds. Code that relies on drop execution after a runtime panic is outside the beta contract.