Describe the memory layout of a named boundary type (pure). A field list goes in, a layout descriptor comes out, or a diagnostic is thrown.
The descriptor carries the fields in declaration order with their normalized types and C-ABI byte offsets, plus the whole struct's size and alignment:
(describe 'Point '[x :f64 y :f64])
=> {:name Point
:fields [{:name x :type {:kind :scalar :name :f64} :offset 0}
{:name y :type {:kind :scalar :name :f64} :offset 8}]
:size 16 :align 8}
A field may be a carrier scalar, an enum's i32 backing, or a buffer
field (:string, [:bytes [:slice :u8]], or a bare, owned, or
borrowed slice of a carrier scalar). A buffer field has no single C
type: it expands in the wire struct to two usize words, a pointer
and a length, so the descriptor records both offsets and the
marshalled Clojure target for each. The descriptor renders the
extern struct the generated Zig uses and drives the field
marshalling FFM performs; the layout matches Zig's extern struct
(C ABI).
Describe the memory layout of a named boundary type (pure). A field
list goes in, a layout descriptor comes out, or a diagnostic is thrown.
The descriptor carries the fields in declaration order with their
normalized types and C-ABI byte offsets, plus the whole struct's size
and alignment:
(describe 'Point '[x :f64 y :f64])
=> {:name Point
:fields [{:name x :type {:kind :scalar :name :f64} :offset 0}
{:name y :type {:kind :scalar :name :f64} :offset 8}]
:size 16 :align 8}
A field may be a carrier scalar, an enum's i32 backing, or a buffer
field (`:string`, `[:bytes [:slice :u8]]`, or a bare, owned, or
borrowed slice of a carrier scalar). A buffer field has no single C
type: it expands in the wire struct to two `usize` words, a pointer
and a length, so the descriptor records both offsets and the
marshalled Clojure target for each. The descriptor renders the
`extern struct` the generated Zig uses and drives the field
marshalling FFM performs; the layout matches Zig's `extern struct`
(C ABI).(describe type-name fields)(describe type-name fields types)(describe type-name fields types opts)Build the layout descriptor for a named type from its fields, a
vector of name type pairs. A carrier scalar or an enum keeps its
carrier size and alignment (an enum crosses as its i32 backing); a
buffer field (:string, [:bytes [:slice :u8]], or a slice) expands
to two usize words aligned to the word width, and the field records
the pointer offset as :offset, the length offset as :len-offset,
and the marshalled target. Throws a diagnostic for an odd field list
or a field the wire struct cannot carry. The optional types map
resolves named enum fields against the registry of named types already
declared in the namespace. The optional opts map may carry :packed true to produce a Zig packed struct with no alignment padding;
packed structs support scalar and enum fields only.
Build the layout descriptor for a named type from its `fields`, a vector of `name type` pairs. A carrier scalar or an enum keeps its carrier size and alignment (an enum crosses as its `i32` backing); a buffer field (`:string`, `[:bytes [:slice :u8]]`, or a slice) expands to two `usize` words aligned to the word width, and the field records the pointer offset as `:offset`, the length offset as `:len-offset`, and the marshalled target. Throws a diagnostic for an odd field list or a field the wire struct cannot carry. The optional `types` map resolves named enum fields against the registry of named types already declared in the namespace. The optional `opts` map may carry `:packed true` to produce a Zig `packed struct` with no alignment padding; packed structs support scalar and enum fields only.
(describe-enum type-name members)(describe-enum type-name members opts)The descriptor for a defenumz type: an enum whose members cross as
keywords, backed by an integer scalar (default :i32). The optional
opts map may carry :backing to widen or narrow the tag (:u8,
:u32, ...). Throws for an odd member list, a non-integer member, a
non-integer or carrierless backing, or a member value that does not fit
the backing's range.
The descriptor for a `defenumz` type: an enum whose members cross as keywords, backed by an integer scalar (default `:i32`). The optional `opts` map may carry `:backing` to widen or narrow the tag (`:u8`, `:u32`, ...). Throws for an odd member list, a non-integer member, a non-integer or carrierless backing, or a member value that does not fit the backing's range.
(describe-record type-name fields record-ns)(describe-record type-name fields record-ns types)The layout descriptor for a defrecordz type: the struct layout of
describe, plus the qualified map-factory symbol the boundary resolves
to rebuild the record from its fields on a return.
The layout descriptor for a `defrecordz` type: the struct layout of `describe`, plus the qualified map-factory symbol the boundary resolves to rebuild the record from its fields on a return.
(enum? descriptor)True when a layout descriptor describes a defenumz enum rather than a
struct or record.
True when a layout descriptor describes a `defenumz` enum rather than a struct or record.
(scalar-only-layout? layout)True when a struct layout's fields are all carrier scalars, directly or through a further nested struct whose own inner layout is scalar- only. A buffer field, an enum field, or any non-scalar field disqualifies. Used to gate which named types may nest inside another struct and which may serve as a slice or array element: a struct crossed by value (a nested field) or carried in bulk (a slice element) composes cleanly only with a scalar interior.
True when a struct layout's fields are all carrier scalars, directly or through a further nested struct whose own inner layout is scalar- only. A buffer field, an enum field, or any non-scalar field disqualifies. Used to gate which named types may nest inside another struct and which may serve as a slice or array element: a struct crossed by value (a nested field) or carried in bulk (a slice element) composes cleanly only with a scalar interior.
(slice-element-layout? layout)True when a struct layout can serve as a slice or array element that
carries its own buffer fields: every field is a carrier scalar (not a
128-bit integer), an enum, a nested struct that is itself slice-element-
capable (recursively, so a nested buffer-carrying struct is accepted),
or a buffer field (string, bytes, or a slice of a carrier scalar).
Broader than scalar-only-layout?: the wrapper transforms the body's
nice-record slice into a wire (extern) slab the marshaller reads, and
the free shim walks each element freeing its buffers (recursing into
nested buffer-carrying structs).
True when a struct layout can serve as a slice or array element that carries its own buffer fields: every field is a carrier scalar (not a 128-bit integer), an enum, a nested struct that is itself slice-element- capable (recursively, so a nested buffer-carrying struct is accepted), or a buffer field (string, bytes, or a slice of a carrier scalar). Broader than `scalar-only-layout?`: the wrapper transforms the body's nice-record slice into a wire (extern) slab the marshaller reads, and the free shim walks each element freeing its buffers (recursing into nested buffer-carrying structs).
(zig-decl descriptor)The declaration node for a named type: an enum for a defenumz, a
regular struct (the nice record the body constructs) for a
buffer-carrying deftypez/defrecordz, and an extern struct (the
wire layout, which is also the nice layout) for a scalar-only struct.
The declaration node for a named type: an `enum` for a `defenumz`, a regular `struct` (the nice record the body constructs) for a buffer-carrying `deftypez`/`defrecordz`, and an `extern struct` (the wire layout, which is also the nice layout) for a scalar-only struct.
(zig-enum {type-name :name :keys [backing values]})The enum(<backing>) declaration node for an enum layout. The backing
width defaults to i32 when a legacy descriptor carries none.
The `enum(<backing>)` declaration node for an enum layout. The backing width defaults to `i32` when a legacy descriptor carries none.
(zig-nice-struct {type-name :name :keys [fields]})The nice record struct declaration node: a regular struct (not
extern) whose buffer fields are real Zig slices, not the usize
ptr/len words of the wire struct. Emitted for a buffer-carrying record
so the body can build the nice type the wrapper then decomposes field
by field into the wire extern struct. A scalar-only record keeps its
extern struct (the nice and wire layouts coincide).
The nice record struct declaration node: a regular `struct` (not `extern`) whose buffer fields are real Zig slices, not the `usize` ptr/len words of the wire struct. Emitted for a buffer-carrying record so the body can build the nice type the wrapper then decomposes field by field into the wire `extern struct`. A scalar-only record keeps its `extern struct` (the nice and wire layouts coincide).
(zig-struct {type-name :name :keys [fields packed]})The extern struct (or packed struct) declaration node for a
layout. Each scalar field is declared by its carrier; each buffer
field expands to a usize pointer and length pair, the wire form a
slice parameter already takes.
The `extern struct` (or `packed struct`) declaration node for a layout. Each scalar field is declared by its carrier; each buffer field expands to a `usize` pointer and length pair, the wire form a slice parameter already takes.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |