external_term.c

Include dependency graph for external_term.c:

digraph { graph [bgcolor="#00000000"] node [shape=rectangle style=filled fillcolor="#FFFFFF" font=Helvetica padding=2] edge [color="#1414CE"] "10" [label="atom.h" tooltip="atom.h"] "28" [label="atom_table.h" tooltip="atom_table.h"] "33" [label="bitstring.h" tooltip="bitstring.h"] "26" [label="context.h" tooltip="context.h"] "36" [label="defaultatoms.h" tooltip="defaultatoms.h"] "16" [label="erl_nif.h" tooltip="erl_nif.h"] "29" [label="ets.h" tooltip="ets.h"] "35" [label="exportedfunction.h" tooltip="exportedfunction.h"] "1" [label="/__w/AtomVM/AtomVM/src/libAtomVM/external_term.c" tooltip="/__w/AtomVM/AtomVM/src/libAtomVM/external_term.c" fillcolor="#BFBFBF"] "2" [label="external_term.h" tooltip="external_term.h"] "27" [label="globalcontext.h" tooltip="globalcontext.h"] "11" [label="intn.h" tooltip="intn.h"] "32" [label="jit.h" tooltip="jit.h"] "21" [label="list.h" tooltip="list.h"] "23" [label="mailbox.h" tooltip="mailbox.h"] "15" [label="memory.h" tooltip="memory.h"] "38" [label="module.h" tooltip="module.h"] "20" [label="refc_binary.h" tooltip="refc_binary.h"] "22" [label="resources.h" tooltip="resources.h"] "25" [label="smp.h" tooltip="smp.h"] "24" [label="synclist.h" tooltip="synclist.h"] "3" [label="term.h" tooltip="term.h"] "17" [label="term_typedef.h" tooltip="term_typedef.h"] "30" [label="timer_list.h" tooltip="timer_list.h"] "34" [label="unicode.h" tooltip="unicode.h"] "12" [label="utils.h" tooltip="utils.h"] "31" [label="valueshashtable.h" tooltip="valueshashtable.h"] "18" [label="assert.h" tooltip="assert.h"] "37" [label="defaultatoms.def" tooltip="defaultatoms.def"] "13" [label="inttypes.h" tooltip="inttypes.h"] "19" [label="limits.h" tooltip="limits.h"] "5" [label="stdbool.h" tooltip="stdbool.h"] "14" [label="stddef.h" tooltip="stddef.h"] "6" [label="stdint.h" tooltip="stdint.h"] "7" [label="stdio.h" tooltip="stdio.h"] "8" [label="stdlib.h" tooltip="stdlib.h"] "9" [label="string.h" tooltip="string.h"] "4" [label="sys/types.h" tooltip="sys/types.h"] "10" -> "6" [dir=forward tooltip="include"] "10" -> "8" [dir=forward tooltip="include"] "28" -> "5" [dir=forward tooltip="include"] "28" -> "10" [dir=forward tooltip="include"] "28" -> "12" [dir=forward tooltip="include"] "33" -> "11" [dir=forward tooltip="include"] "33" -> "3" [dir=forward tooltip="include"] "33" -> "34" [dir=forward tooltip="include"] "33" -> "5" [dir=forward tooltip="include"] "33" -> "6" [dir=forward tooltip="include"] "26" -> "27" [dir=forward tooltip="include"] "26" -> "32" [dir=forward tooltip="include"] "26" -> "21" [dir=forward tooltip="include"] "26" -> "23" [dir=forward tooltip="include"] "26" -> "25" [dir=forward tooltip="include"] "26" -> "3" [dir=forward tooltip="include"] "26" -> "30" [dir=forward tooltip="include"] "36" -> "27" [dir=forward tooltip="include"] "36" -> "37" [dir=forward tooltip="include"] "16" -> "17" [dir=forward tooltip="include"] "29" -> "5" [dir=forward tooltip="include"] "29" -> "24" [dir=forward tooltip="include"] "29" -> "3" [dir=forward tooltip="include"] "35" -> "3" [dir=forward tooltip="include"] "1" -> "2" [dir=forward tooltip="include"] "1" -> "26" [dir=forward tooltip="include"] "1" -> "21" [dir=forward tooltip="include"] "1" -> "5" [dir=forward tooltip="include"] "1" -> "6" [dir=forward tooltip="include"] "1" -> "7" [dir=forward tooltip="include"] "1" -> "8" [dir=forward tooltip="include"] "1" -> "33" [dir=forward tooltip="include"] "1" -> "36" [dir=forward tooltip="include"] "1" -> "15" [dir=forward tooltip="include"] "1" -> "38" [dir=forward tooltip="include"] "1" -> "22" [dir=forward tooltip="include"] "1" -> "3" [dir=forward tooltip="include"] "1" -> "34" [dir=forward tooltip="include"] "1" -> "12" [dir=forward tooltip="include"] "2" -> "3" [dir=forward tooltip="include"] "2" -> "12" [dir=forward tooltip="include"] "27" -> "6" [dir=forward tooltip="include"] "27" -> "10" [dir=forward tooltip="include"] "27" -> "28" [dir=forward tooltip="include"] "27" -> "16" [dir=forward tooltip="include"] "27" -> "29" [dir=forward tooltip="include"] "27" -> "21" [dir=forward tooltip="include"] "27" -> "23" [dir=forward tooltip="include"] "27" -> "25" [dir=forward tooltip="include"] "27" -> "24" [dir=forward tooltip="include"] "27" -> "3" [dir=forward tooltip="include"] "27" -> "30" [dir=forward tooltip="include"] "27" -> "31" [dir=forward tooltip="include"] "11" -> "5" [dir=forward tooltip="include"] "11" -> "9" [dir=forward tooltip="include"] "11" -> "12" [dir=forward tooltip="include"] "32" -> "33" [dir=forward tooltip="include"] "32" -> "35" [dir=forward tooltip="include"] "32" -> "3" [dir=forward tooltip="include"] "32" -> "17" [dir=forward tooltip="include"] "32" -> "5" [dir=forward tooltip="include"] "21" -> "5" [dir=forward tooltip="include"] "23" -> "5" [dir=forward tooltip="include"] "23" -> "21" [dir=forward tooltip="include"] "23" -> "17" [dir=forward tooltip="include"] "23" -> "12" [dir=forward tooltip="include"] "15" -> "6" [dir=forward tooltip="include"] "15" -> "8" [dir=forward tooltip="include"] "15" -> "16" [dir=forward tooltip="include"] "15" -> "17" [dir=forward tooltip="include"] "15" -> "12" [dir=forward tooltip="include"] "38" -> "5" [dir=forward tooltip="include"] "38" -> "6" [dir=forward tooltip="include"] "38" -> "10" [dir=forward tooltip="include"] "38" -> "28" [dir=forward tooltip="include"] "38" -> "26" [dir=forward tooltip="include"] "38" -> "35" [dir=forward tooltip="include"] "38" -> "27" [dir=forward tooltip="include"] "38" -> "32" [dir=forward tooltip="include"] "38" -> "3" [dir=forward tooltip="include"] "20" -> "5" [dir=forward tooltip="include"] "20" -> "8" [dir=forward tooltip="include"] "20" -> "21" [dir=forward tooltip="include"] "20" -> "22" [dir=forward tooltip="include"] "22" -> "8" [dir=forward tooltip="include"] "22" -> "16" [dir=forward tooltip="include"] "22" -> "21" [dir=forward tooltip="include"] "22" -> "23" [dir=forward tooltip="include"] "22" -> "15" [dir=forward tooltip="include"] "22" -> "24" [dir=forward tooltip="include"] "25" -> "5" [dir=forward tooltip="include"] "24" -> "7" [dir=forward tooltip="include"] "24" -> "21" [dir=forward tooltip="include"] "24" -> "25" [dir=forward tooltip="include"] "3" -> "4" [dir=forward tooltip="include"] "3" -> "5" [dir=forward tooltip="include"] "3" -> "6" [dir=forward tooltip="include"] "3" -> "7" [dir=forward tooltip="include"] "3" -> "8" [dir=forward tooltip="include"] "3" -> "9" [dir=forward tooltip="include"] "3" -> "10" [dir=forward tooltip="include"] "3" -> "11" [dir=forward tooltip="include"] "3" -> "15" [dir=forward tooltip="include"] "3" -> "20" [dir=forward tooltip="include"] "3" -> "22" [dir=forward tooltip="include"] "3" -> "12" [dir=forward tooltip="include"] "3" -> "17" [dir=forward tooltip="include"] "17" -> "18" [dir=forward tooltip="include"] "17" -> "19" [dir=forward tooltip="include"] "17" -> "13" [dir=forward tooltip="include"] "17" -> "6" [dir=forward tooltip="include"] "30" -> "5" [dir=forward tooltip="include"] "30" -> "6" [dir=forward tooltip="include"] "30" -> "21" [dir=forward tooltip="include"] "34" -> "5" [dir=forward tooltip="include"] "34" -> "14" [dir=forward tooltip="include"] "34" -> "6" [dir=forward tooltip="include"] "12" -> "13" [dir=forward tooltip="include"] "12" -> "5" [dir=forward tooltip="include"] "12" -> "14" [dir=forward tooltip="include"] "12" -> "7" [dir=forward tooltip="include"] "12" -> "8" [dir=forward tooltip="include"] "31" -> "14" [dir=forward tooltip="include"] "31" -> "6" [dir=forward tooltip="include"] }

Defines

NEW_FLOAT_EXT 70
NEW_PID_EXT 88
NEWER_REFERENCE_EXT 90
SMALL_INTEGER_EXT 97
INTEGER_EXT 98
ATOM_EXT 100
PID_EXT 103
SMALL_TUPLE_EXT 104
LARGE_TUPLE_EXT 105
NIL_EXT 106
STRING_EXT 107
LIST_EXT 108
BINARY_EXT 109
SMALL_BIG_EXT 110
NEW_FUN_EXT 112
EXPORT_EXT 113
MAP_EXT 116
ATOM_UTF8_EXT 118
SMALL_ATOM_UTF8_EXT 119
V4_PORT_EXT 120
INVALID_TERM_SIZE -1
NEW_FLOAT_EXT_SIZE 9
SMALL_INTEGER_EXT_SIZE 2
INTEGER_EXT_SIZE 5
SMALL_BIG_EXT_BASE_SIZE 3
ATOM_EXT_BASE_SIZE 3
STRING_EXT_BASE_SIZE 3
LIST_EXT_BASE_SIZE 5
BINARY_EXT_BASE_SIZE 5
MAP_EXT_BASE_SIZE 5
SMALL_ATOM_EXT_BASE_SIZE 2

Functions

static term parse_external_terms(const uint8_t *external_term_buf, size_t *eterm_size, bool copy, Heap *heap, GlobalContext *glb)
static int calculate_heap_usage(const uint8_t *external_term_buf, size_t remaining, size_t *eterm_size, bool copy)
static size_t compute_external_size(term t, GlobalContext *glb)
static int external_term_from_term(uint8_t **buf, size_t *len, term t, GlobalContext *glb)
static int serialize_term(uint8_t *buf, term t, GlobalContext *glb)
external_term_read_result_t external_term_validate_buf_raw(const void *buf, size_t buf_size, external_term_read_opts_t opts, size_t *required_heap, size_t *bytes_read, GlobalContext *glb)

Validate a raw external term buffer (tag byte excluded).

Like external_term_validate_buf() but expects a buffer without the leading EXTERNAL_TERM_TAG byte. bytes_read does not account for the tag byte.

See also

external_term_validate_buf() for the standard tag-included variant.

external_term_read_result_t external_term_deserialize_buf_raw(const void *buf, size_t buf_size, external_term_read_opts_t opts, Heap *heap, term *out_term, GlobalContext *glb)

Deserialize a raw external term buffer (tag byte excluded) into a term.

Like external_term_deserialize_buf() but expects a buffer without the leading EXTERNAL_TERM_TAG byte.

See also

external_term_deserialize_buf() for the standard tag-included variant.

Warning

external_term_validate_buf_raw() MUST be called successfully on the same buffer before calling this function, and the heap must have been grown to accommodate at least the number of words reported by that call. Skipping validation or providing insufficient heap space results in undefined behavior.

term external_term_from_binary_with_roots(Context *ctx, size_t binary_ix, size_t offset, size_t *bytes_read, size_t num_roots, term *roots)

Create a term from a binary.

Deserialize a binary term that stores term data in Erlang external term format, and instantiate the serialized terms. The heap from the context will be used to allocate the instantiated terms. This function is the complement of external_term_to_binary. WARNING: This function may call the GC, which may render the input binary invalid.

Parameters:
  • ctx – the context that owns the memory that will be allocated.

  • binary_ix – offset of the binary in roots

  • offset – offset in the binary

  • bytes_read – the number of bytes read from the input binary.

  • num_roots – number of roots to preserve in case of GC

  • roots – roots to preserve in case of GC

Returns:

the term deserialized from the input term, or an invalid term, if deserialization fails.

term external_term_from_const_literal(const void *external_term, size_t size, Context *ctx)

Gets a term from a const literal (module in flash).

Deserialize an external term from external format and returns a term. Use a heap fragment to store the generated terms. The heap fragment is appended to the context heap. Atoms and binaries are not copied.

Parameters:
  • external_term – the const literal buffer that will be deserialized

  • size – to allocate for term.

  • ctx – the context that owns the memory that will be allocated.

Returns:

a term.

term external_term_to_binary(Context *ctx, term t)

Create a binary from a term.

Serialize a term in Erlang external term format, and store the result in a binary term. The heap from the context will be used to allocate the hydrated terms. WARNING: This function may call the GC, which may render the input binary invalid.

Parameters:
  • ctx – the context that owns the memory that will be allocated.

  • t – the term to return as binary.

Returns:

the term deserialized from the input term, or an invalid term, if deserialization fails.

static uint8_t get_num_bytes(avm_uint64_t val)
static void write_bytes(uint8_t *buf, avm_uint64_t val)
static avm_uint64_t read_bytes(const uint8_t *buf, uint8_t num_bytes)
external_term_write_result_t external_term_compute_external_size_raw(term t, size_t *size, GlobalContext *glb)

Computes the size required for a external term (tag excluded)

This function should be called in order to calculate the required buffer size to store a serialized term in external term format. This function doesn’t prepend the external term 1 byte tag.

Parameters:
  • t – the term for which size is calculated

  • size – the required buffer size (tag excluded)

  • glb – the global context

Returns:

ExternalTermWriteOk in case of success

external_term_write_result_t external_term_serialize_term_raw(term t, void *buf, GlobalContext *glb)

Serialize a term (tag excluded)

This function serializes in external term format given term, and writes it to the given buffer. This function doesn’t prepend the external term 1 byte tag.

Parameters:
  • t – the term that will be serialized

  • buf – the buffer where the external term is written

  • glb – the global context

Returns:

ExternalTermWriteOk in case of success