infix
A JIT-Powered FFI Library for C
Loading...
Searching...
No Matches
types.c File Reference

Implements the public API for creating and managing type descriptions. More...

#include "common/infix_internals.h"
#include "common/utility.h"
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Include dependency graph for types.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  recalc_visited_node_t
 
struct  memo_node_t
 
struct  estimate_visited_node_t
 

Macros

#define INFIX_TYPE_INIT(id, T)
 

Typedefs

typedef struct recalc_visited_node_t recalc_visited_node_t
 
typedef struct memo_node_t memo_node_t
 
typedef struct estimate_visited_node_t estimate_visited_node_t
 

Functions

c23_nodiscard infix_typeinfix_type_create_primitive (infix_primitive_type_id id)
 Creates a static descriptor for a primitive C type.
 
c23_nodiscard infix_typeinfix_type_create_pointer (void)
 Creates a static descriptor for a generic pointer (void*).
 
c23_nodiscard infix_typeinfix_type_create_void (void)
 Creates a static descriptor for the void type.
 
infix_struct_member infix_type_create_member (const char *name, infix_type *type, size_t offset)
 A factory function to create an infix_struct_member.
 
static infix_status _create_aggregate_setup (infix_arena_t *arena, infix_type **out_type, infix_struct_member **out_arena_members, infix_struct_member *members, size_t num_members)
 
c23_nodiscard infix_status infix_type_create_pointer_to (infix_arena_t *arena, infix_type **out_type, infix_type *pointee_type)
 Creates a new pointer type that points to a specific type.
 
c23_nodiscard infix_status infix_type_create_array (infix_arena_t *arena, infix_type **out_type, infix_type *element_type, size_t num_elements)
 Creates a new fixed-size array type.
 
c23_nodiscard infix_status infix_type_create_enum (infix_arena_t *arena, infix_type **out_type, infix_type *underlying_type)
 Creates a new enum type with a specified underlying integer type.
 
c23_nodiscard infix_status infix_type_create_complex (infix_arena_t *arena, infix_type **out_type, infix_type *base_type)
 Creates a new _Complex number type.
 
c23_nodiscard infix_status infix_type_create_vector (infix_arena_t *arena, infix_type **out_type, infix_type *element_type, size_t num_elements)
 Creates a new SIMD vector type.
 
c23_nodiscard infix_status infix_type_create_union (infix_arena_t *arena, infix_type **out_type, infix_struct_member *members, size_t num_members)
 Creates a new union type from an array of members.
 
c23_nodiscard infix_status infix_type_create_struct (infix_arena_t *arena, infix_type **out_type, infix_struct_member *members, size_t num_members)
 Creates a new struct type from an array of members, calculating layout automatically.
 
c23_nodiscard infix_status infix_type_create_packed_struct (infix_arena_t *arena, infix_type **out_type, size_t total_size, size_t alignment, infix_struct_member *members, size_t num_members)
 Creates a new packed struct type with a user-specified layout.
 
c23_nodiscard infix_status infix_type_create_named_reference (infix_arena_t *arena, infix_type **out_type, const char *name, infix_aggregate_category_t agg_cat)
 Creates a placeholder for a named type that will be resolved later by a type registry.
 
static void _infix_type_recalculate_layout_recursive (infix_arena_t *temp_arena, infix_type *type, recalc_visited_node_t **visited_head)
 
void _infix_type_recalculate_layout (infix_type *type)
 Recalculates the layout of a fully resolved type graph.
 
static infix_type_copy_type_graph_to_arena_recursive (infix_arena_t *dest_arena, const infix_type *src_type, memo_node_t **memo_head)
 
infix_type_copy_type_graph_to_arena (infix_arena_t *dest_arena, const infix_type *src_type)
 Performs a deep copy of a type graph into a destination arena.
 
static size_t _estimate_graph_size_recursive (infix_arena_t *temp_arena, const infix_type *type, estimate_visited_node_t **visited_head)
 
size_t _infix_estimate_graph_size (infix_arena_t *temp_arena, const infix_type *type)
 Estimates the total memory required to deep-copy a complete type graph.
 
c23_nodiscard const char * infix_type_get_name (const infix_type *type)
 Gets the semantic alias of a type, if one exists.
 
c23_nodiscard infix_type_category infix_type_get_category (const infix_type *type)
 Gets the fundamental category of a type.
 
c23_nodiscard size_t infix_type_get_size (const infix_type *type)
 Gets the size of a type in bytes.
 
c23_nodiscard size_t infix_type_get_alignment (const infix_type *type)
 Gets the alignment requirement of a type in bytes.
 
c23_nodiscard size_t infix_type_get_member_count (const infix_type *type)
 Gets the number of members in a struct or union type.
 
c23_nodiscard const infix_struct_memberinfix_type_get_member (const infix_type *type, size_t index)
 Gets a specific member from a struct or union type.
 
c23_nodiscard const char * infix_type_get_arg_name (const infix_type *func_type, size_t index)
 Gets the name of a specific argument from a function type.
 
c23_nodiscard const infix_typeinfix_type_get_arg_type (const infix_type *func_type, size_t index)
 Gets the type of a specific argument from a function type.
 
c23_nodiscard size_t infix_forward_get_num_args (const infix_forward_t *trampoline)
 Gets the total number of arguments for a forward trampoline.
 
c23_nodiscard size_t infix_forward_get_num_fixed_args (const infix_forward_t *trampoline)
 Gets the number of fixed (non-variadic) arguments for a forward trampoline.
 
c23_nodiscard const infix_typeinfix_forward_get_return_type (const infix_forward_t *trampoline)
 Gets the return type for a forward trampoline.
 
c23_nodiscard const infix_typeinfix_forward_get_arg_type (const infix_forward_t *trampoline, size_t index)
 Gets the type of a specific argument for a forward trampoline.
 
c23_nodiscard size_t infix_reverse_get_num_args (const infix_reverse_t *trampoline)
 Gets the total number of arguments for a reverse trampoline.
 
c23_nodiscard size_t infix_reverse_get_num_fixed_args (const infix_reverse_t *trampoline)
 Gets the number of fixed (non-variadic) arguments for a reverse trampoline.
 
c23_nodiscard const infix_typeinfix_reverse_get_return_type (const infix_reverse_t *trampoline)
 Gets the return type for a reverse trampoline.
 
c23_nodiscard const infix_typeinfix_reverse_get_arg_type (const infix_reverse_t *trampoline, size_t index)
 Gets the type of a specific argument for a reverse trampoline.
 

Variables

static infix_type _infix_type_void
 
static infix_type _infix_type_pointer
 
static infix_type _infix_type_bool = INFIX_TYPE_INIT(INFIX_PRIMITIVE_BOOL, bool)
 
static infix_type _infix_type_uint8 = INFIX_TYPE_INIT(INFIX_PRIMITIVE_UINT8, uint8_t)
 
static infix_type _infix_type_sint8 = INFIX_TYPE_INIT(INFIX_PRIMITIVE_SINT8, int8_t)
 
static infix_type _infix_type_uint16 = INFIX_TYPE_INIT(INFIX_PRIMITIVE_UINT16, uint16_t)
 
static infix_type _infix_type_sint16 = INFIX_TYPE_INIT(INFIX_PRIMITIVE_SINT16, int16_t)
 
static infix_type _infix_type_uint32 = INFIX_TYPE_INIT(INFIX_PRIMITIVE_UINT32, uint32_t)
 
static infix_type _infix_type_sint32 = INFIX_TYPE_INIT(INFIX_PRIMITIVE_SINT32, int32_t)
 
static infix_type _infix_type_uint64 = INFIX_TYPE_INIT(INFIX_PRIMITIVE_UINT64, uint64_t)
 
static infix_type _infix_type_sint64 = INFIX_TYPE_INIT(INFIX_PRIMITIVE_SINT64, int64_t)
 
static infix_type _infix_type_uint128 = INFIX_TYPE_INIT(INFIX_PRIMITIVE_UINT128, __uint128_t)
 
static infix_type _infix_type_sint128 = INFIX_TYPE_INIT(INFIX_PRIMITIVE_SINT128, __int128_t)
 
static infix_type _infix_type_float = INFIX_TYPE_INIT(INFIX_PRIMITIVE_FLOAT, float)
 
static infix_type _infix_type_double = INFIX_TYPE_INIT(INFIX_PRIMITIVE_DOUBLE, double)
 
static infix_type _infix_type_long_double = INFIX_TYPE_INIT(INFIX_PRIMITIVE_LONG_DOUBLE, long double)
 

Detailed Description

Implements the public API for creating and managing type descriptions.

Copyright (c) 2025 Sanko Robinson

This source code is dual-licensed under the Artistic License 2.0 or the MIT License. You may choose to use this code under the terms of either license.

SPDX-License-Identifier: (Artistic-2.0 OR MIT)

The documentation blocks within this file are licensed under the Creative Commons Attribution 4.0 International License (CC BY 4.0).

SPDX-License-Identifier: CC-BY-4.0

This module serves two primary functions:

  1. It provides the public functions for programmatically constructing infix_type objects (the "Manual API"). These functions are the building blocks for users who need to create type information dynamically without parsing strings.
  2. It contains the crucial internal logic for two core stages of the data pipeline:
    • **Copying (_copy_type_graph_to_arena):** Deep-copies a type graph to a new memory arena, which is fundamental to creating self-contained trampoline objects and ensuring memory safety.
    • **Layout (_infix_type_recalculate_layout):** Traverses a fully resolved type graph to compute the final memory layout (size, alignment, and offsets) of all structures and unions.

The creation functions (infix_type_create_*) perform an initial, preliminary layout calculation. This layout is considered unresolved until a final pass with _infix_type_recalculate_layout is performed after all named types have been resolved by the type registry.

Macro Definition Documentation

◆ INFIX_TYPE_INIT

#define INFIX_TYPE_INIT (   id,
 
)
Value:
{.name = nullptr, \
.category = INFIX_TYPE_PRIMITIVE, \
.size = sizeof(T), \
.alignment = _Alignof(T), \
.is_arena_allocated = false, \
.arena = nullptr, \
.meta.primitive_id = id}
@ INFIX_TYPE_PRIMITIVE
Definition infix.h:163

Typedef Documentation

◆ estimate_visited_node_t

◆ memo_node_t

typedef struct memo_node_t memo_node_t

◆ recalc_visited_node_t

Function Documentation

◆ _copy_type_graph_to_arena()

infix_type * _copy_type_graph_to_arena ( infix_arena_t dest_arena,
const infix_type src_type 
)

Performs a deep copy of a type graph into a destination arena.

Located in src/core/types.c. This is the "Copy" stage of the data pipeline, crucial for creating self-contained trampoline objects and ensuring memory safety. It uses memoization to correctly handle cycles and shared type objects.

Parameters
[in]dest_arenaThe destination arena for the new type graph.
[in]src_typeThe source type graph to copy.
Returns
A pointer to the newly created copy in dest_arena, or nullptr on failure.

◆ _copy_type_graph_to_arena_recursive()

static infix_type * _copy_type_graph_to_arena_recursive ( infix_arena_t dest_arena,
const infix_type src_type,
memo_node_t **  memo_head 
)
static

◆ _create_aggregate_setup()

static infix_status _create_aggregate_setup ( infix_arena_t arena,
infix_type **  out_type,
infix_struct_member **  out_arena_members,
infix_struct_member members,
size_t  num_members 
)
static

◆ _estimate_graph_size_recursive()

static size_t _estimate_graph_size_recursive ( infix_arena_t temp_arena,
const infix_type type,
estimate_visited_node_t **  visited_head 
)
static

◆ _infix_estimate_graph_size()

size_t _infix_estimate_graph_size ( infix_arena_t temp_arena,
const infix_type type 
)

Estimates the total memory required to deep-copy a complete type graph.

Located in src/core/types.c. This function recursively walks the entire type graph, including all nested aggregates and function arguments, to calculate the exact size needed for an arena that will hold a deep copy.

Parameters
[in]temp_arenaA temporary arena used for the estimator's own bookkeeping (e.g., cycle detection).
[in]typeThe root of the type graph to estimate.
Returns
The estimated size in bytes required for a deep copy.

◆ _infix_type_recalculate_layout()

void _infix_type_recalculate_layout ( infix_type type)

Recalculates the layout of a fully resolved type graph.

Located in src/core/types.c. This is the "Layout" stage of the data pipeline. It recursively walks a type graph and computes the final size, alignment, and member offset fields for all aggregate types. It must only be called on a fully resolved graph.

Parameters
[in,out]typeThe root of the type graph to recalculate. The graph is modified in-place.

◆ _infix_type_recalculate_layout_recursive()

static void _infix_type_recalculate_layout_recursive ( infix_arena_t temp_arena,
infix_type type,
recalc_visited_node_t **  visited_head 
)
static

Variable Documentation

◆ _infix_type_bool

infix_type _infix_type_bool = INFIX_TYPE_INIT(INFIX_PRIMITIVE_BOOL, bool)
static

◆ _infix_type_double

infix_type _infix_type_double = INFIX_TYPE_INIT(INFIX_PRIMITIVE_DOUBLE, double)
static

◆ _infix_type_float

infix_type _infix_type_float = INFIX_TYPE_INIT(INFIX_PRIMITIVE_FLOAT, float)
static

◆ _infix_type_long_double

infix_type _infix_type_long_double = INFIX_TYPE_INIT(INFIX_PRIMITIVE_LONG_DOUBLE, long double)
static

◆ _infix_type_pointer

infix_type _infix_type_pointer
static
Initial value:
= {.name = nullptr,
.category = INFIX_TYPE_POINTER,
.size = sizeof(void *),
.alignment = _Alignof(void *),
.is_arena_allocated = false,
.arena = nullptr,
.meta.pointer_info = {.pointee_type = &_infix_type_void}}
@ INFIX_TYPE_POINTER
Definition infix.h:164
static infix_type _infix_type_void
Definition types.c:74

◆ _infix_type_sint128

infix_type _infix_type_sint128 = INFIX_TYPE_INIT(INFIX_PRIMITIVE_SINT128, __int128_t)
static

◆ _infix_type_sint16

infix_type _infix_type_sint16 = INFIX_TYPE_INIT(INFIX_PRIMITIVE_SINT16, int16_t)
static

◆ _infix_type_sint32

infix_type _infix_type_sint32 = INFIX_TYPE_INIT(INFIX_PRIMITIVE_SINT32, int32_t)
static

◆ _infix_type_sint64

infix_type _infix_type_sint64 = INFIX_TYPE_INIT(INFIX_PRIMITIVE_SINT64, int64_t)
static

◆ _infix_type_sint8

infix_type _infix_type_sint8 = INFIX_TYPE_INIT(INFIX_PRIMITIVE_SINT8, int8_t)
static

◆ _infix_type_uint128

infix_type _infix_type_uint128 = INFIX_TYPE_INIT(INFIX_PRIMITIVE_UINT128, __uint128_t)
static

◆ _infix_type_uint16

infix_type _infix_type_uint16 = INFIX_TYPE_INIT(INFIX_PRIMITIVE_UINT16, uint16_t)
static

◆ _infix_type_uint32

infix_type _infix_type_uint32 = INFIX_TYPE_INIT(INFIX_PRIMITIVE_UINT32, uint32_t)
static

◆ _infix_type_uint64

infix_type _infix_type_uint64 = INFIX_TYPE_INIT(INFIX_PRIMITIVE_UINT64, uint64_t)
static

◆ _infix_type_uint8

infix_type _infix_type_uint8 = INFIX_TYPE_INIT(INFIX_PRIMITIVE_UINT8, uint8_t)
static

◆ _infix_type_void

infix_type _infix_type_void
static
Initial value:
= {.name = nullptr,
.category = INFIX_TYPE_VOID,
.size = 0,
.alignment = 0,
.is_arena_allocated = false,
.arena = nullptr,
.meta = {0}}
@ INFIX_TYPE_VOID
Definition infix.h:173