Liking cljdoc? Tell your friends :D

helins.binf.cabi

Interaction with environments that conforms to a C-like ABI.

This namespace is mainly about defining C structures in order to pass them or to understand them when interacting with native functions. It could be when using JNI on the JVM or when calling WebAssembly functions in Clojurescript, for instance.

This opens the road to interacting with languages like C++ and Rust since they allow for defining such C structures and commonly do so in the context of libraries.

BinF already provides utilities for handling arbitrary data in native memory or in WebAssembly memory. For example, on the JVM, DirectByteBuffer implements view protocols and is commonly used with JNI. Some WebAssembly runtimes such as Wasmer use them to represent the memory of a WebAssembly module. In JS, WebAssembly memories are buffers from which a view can be built.

What is missing is knowing how to use a C-like ABI which relies on following some rules. For instance, the members of a structure are aligned on specific memory addresses for performance reasons. This namespace provides utilities for defining such composite data structures as EDN and computing everything there is to compute for following those ABI rules.

3 definitions are needed for understanding these utilities:

  • An env is a map containing information needed for computing those rules such as the alignment being used. See env for creating one.

  • A description map describes either a primitive type (eg. u32) or a composite data structure (eg. struct).

  • A description function takes an env and produces a description map.

A description map is plain data containing eveything that is needed for handling this type. For instance, a description of a structure contains computed memory offsets of all its data fields.

This namespace contains ready description functions for primitive types (such as f32) as well as functions for creating description functions for composite ones (such as array or struct).

See struct for a small example and a full one in the helins.binf.example.cabi namespace from the repository. Source code also clearly shows what is being outputed. While daunting at first, this namespace is actually quite simple.

Interaction with environments that conforms to a C-like ABI.

This namespace is mainly about defining C structures in order to pass them or to understand
them when interacting with native functions. It could be when using JNI on the JVM or when
calling WebAssembly functions in Clojurescript, for instance.

This opens the road to interacting with languages like C++ and Rust since they allow for
defining such C structures and commonly do so in the context of libraries.

BinF already provides utilities for handling arbitrary data in native memory or in WebAssembly memory.
For example, on the JVM, `DirectByteBuffer` implements view protocols and is commonly used with JNI.
Some WebAssembly runtimes such as `Wasmer` use them to represent the memory of a WebAssembly module. In
JS, WebAssembly memories are buffers from which a view can be built.

What is missing is knowing how to use a C-like ABI which relies on following some rules. For instance,
the members of a structure are aligned on specific memory addresses for performance reasons. This namespace
provides utilities for defining such composite data structures as EDN and computing everything there is to compute
for following those ABI rules.

3 definitions are needed for understanding these utilities:

  - An `env` is a map containing information needed for computing those rules such as the alignment being used.
    See [[env]] for creating one.

  - A description map describes either a primitive type (eg. [[u32]]) or a composite data structure (eg. [[struct]]).

  - A description function takes an `env` and produces a description map.

A description map is plain data containing eveything that is needed for handling this type. For instance,
a description of a structure contains computed memory offsets of all its data fields.

This namespace contains ready description functions for primitive types (such as [[f32]]) as well as functions
for creating description functions for composite ones (such as [[array]] or [[struct]]).

See [[struct]] for a small example and a full one in the `helins.binf.example.cabi` namespace from the repository.
Source code also clearly shows what is being outputed. While daunting at first, this namespace is actually quite simple.
raw docstring

alignedclj/s

(aligned align offset)

Re-align offset given align (an alignment in bytes).

Used by utilities in this namespace.

(aligned 8
         13)

;; 13 is re-aligned to 16, a multiple of 8
Re-align `offset` given `align` (an alignment in bytes).

Used by utilities in this namespace.


```clojure
(aligned 8
         13)

;; 13 is re-aligned to 16, a multiple of 8
```
sourceraw docstring

arrayclj/s

(array description-fn n-element)

Given a description function for a type and a number of elements, returns a description function for an array.

Given a description function for a type and a number of elements, returns a description function
for an array.
sourceraw docstring

boolclj/s

(bool _env)

Given an env, returns a map describing a boolean.

Given an `env`, returns a map describing a boolean.
sourceraw docstring

enumclj/s

(enum type constant+)

Given a type name and a sequence of constants, returns a description function for an enum named as such and composed of those constants.

A constant is either an identifier (string or keyword) or a vector [identifier value]. It looks exactly like defining an enum in C in that regard.

Attention, enums are brittle from an ABI point of view and should be discouraged. For instance, the Google Fuchsia projects even explicitely bans them.

(def make-enum
     (enum :MyEnum
           [:a
            :b
            [:c 42]
            :d]))
Given a type name and a sequence of constants, returns a description function
for an enum named as such and composed of those constants.

A constant is either an identifier (string or keyword) or a vector `[identifier value]`.
It looks exactly like defining an enum in C in that regard.

Attention, enums are brittle from an ABI point of view and should be discouraged. For
instance, the Google Fuchsia projects even explicitely bans them.

```clojure
(def make-enum
     (enum :MyEnum
           [:a
            :b
            [:c 42]
            :d]))
```
sourceraw docstring

envclj/s

(env n-byte-word)

Creates a minimal env map which describes the used alignment and the size of a pointer. Those informations are necessary for computing about any C type.

This function leverages the fact that in modern architectures, alignment matches the size of pointers (eg. on 64-bit machine, alignment is 8 bytes and a pointer is 8 bytes as well).

Creates a minimal `env` map which describes the used alignment and the size of a pointer. Those
informations are necessary for computing about any C type.

This function leverages the fact that in modern architectures, alignment matches the size of pointers
(eg. on 64-bit machine, alignment is 8 bytes and a pointer is 8 bytes as well).
sourceraw docstring

f32clj/s

(f32 env)

Given an env, returns a map describing a 32-bit floating value.

Given an `env`, returns a map describing a 32-bit floating value.
sourceraw docstring

f64clj/s

(f64 env)

Given an env, returns a map describing a 64-bit floating value.

Given an `env`, returns a map describing a 64-bit floating value.
sourceraw docstring

force-alignclj/s

(force-align f align)

Sometimes, different alignments are used at the same time. For instance, an inner structure might have a different alignment than its outer structure. This function alters a description function in order to force a particular alignment.

;; Forcing 4 byte alignment on the inner struct

(struct :OuterStruct
        [:a f32]
        [:b (force-align (struct :InnerStruct
                                 [:inner-a i64])
                         4)])
Sometimes, different alignments are used at the same time. For instance, an inner structure might have
a different alignment than its outer structure. This function alters a description function in order to
force a particular alignment.

```clojure
;; Forcing 4 byte alignment on the inner struct

(struct :OuterStruct
        [:a f32]
        [:b (force-align (struct :InnerStruct
                                 [:inner-a i64])
                         4)])
```
sourceraw docstring

force-envclj/s

(force-env f env)

Akin to force-align but forces the given env over the one being used rather than merely the alignment.

Akin to [[force-align]] but forces the given `env` over the one being used rather than merely the alignment.
sourceraw docstring

i16clj/s

(i16 env)

Given an env, returns a map describing a signed 16-bit integer.

Given an `env`, returns a map describing a signed 16-bit integer.
sourceraw docstring

i32clj/s

(i32 env)

Given an env, returns a map describing a signed 32-bit integer.

Given an `env`, returns a map describing a signed 32-bit integer.
sourceraw docstring

i64clj/s

(i64 env)

Given an env, returns a map describing a signed 64-bit integer.

Given an `env`, returns a map describing a signed 64-bit integer.
sourceraw docstring

i8clj/s

(i8 _env)

Given an env, returns a map describing a signed 8-bit integer.

Given an `env`, returns a map describing a signed 8-bit integer.
sourceraw docstring

name-getclj/s

(name-get description-map)

Given a description map, returns its name.

As such, only members of a struct or a union have a name.

Given a description map, returns its name.

As such, only members of a [[struct]] or a [[union]] have a name.
sourceraw docstring

name-setclj/s

(name-set member name)

Assoc'es a new name to a description map.

See name-get.

Assoc'es a new name to a description map.

See [[name-get]].
sourceraw docstring

ptrclj/s

(ptr type)

Given a description function for a type, returns a function taking an env and returning a map describing a pointer for that type.

Given a description function for a type, returns a function taking an `env` and returning
a map describing a pointer for that type.
sourceraw docstring

structclj/s

(struct type member+)

Given a type name and a sequence of members, returns a description function for a structure named as such and composed of those members.

A member is a vector [member-name description-function].

The following example creates a structure containing a byte and an array of doubles. The resulting description function is then being passed an environment map were words are 8 bytes (ie. 64-bit machine).

That description is plain data and contains computed offsets of all members.

(def make-struct
     (struct :MyStruct
             [[:a u8]
              [:b (array f64
                         10)]]))

(def my-struct-map
     (make-struct (env 8)))
Given a type name and a sequence of members, returns a description function for a structure
named as such and composed of those members.

A member is a vector `[member-name description-function]`.

The following example creates a structure containing a byte and an array of doubles. The resulting
description function is then being passed an environment map were words are 8 bytes (ie. 64-bit machine).

That description is plain data and contains computed offsets of all members.

```clojure
(def make-struct
     (struct :MyStruct
             [[:a u8]
              [:b (array f64
                         10)]]))

(def my-struct-map
     (make-struct (env 8)))
```
sourceraw docstring

u16clj/s

(u16 env)

Given an env, returns a map describing an unsigned 16-bit integer.

Given an `env`, returns a map describing an unsigned 16-bit integer.
sourceraw docstring

u32clj/s

(u32 env)

Given an env, returns a map describing an unsigned 32-bit integer.

Given an `env`, returns a map describing an unsigned 32-bit integer.
sourceraw docstring

u64clj/s

(u64 env)

Given an env, returns a map describing an unsigned 64-bit integer.

Given an `env`, returns a map describing an unsigned 64-bit integer.
sourceraw docstring

u8clj/s

(u8 _env)

Given an env, returns a map describing an unsigned 8-bit integer.

Given an `env`, returns a map describing an unsigned 8-bit integer.
sourceraw docstring

unionclj/s

(union type member+)

Given a type name and a sequence of members, returns a description function for a union named as such and composed of those members.

A member is a vector [member-name description-function].

Behaves similarly to struct.

Given a type name and a sequence of members, returns a description function for
a union named as such and composed of those members.

A member is a vector `[member-name description-function]`.

Behaves similarly to [[struct]].
sourceraw docstring

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close