or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

callbacks-handles.mdcore-ffi.mddata-conversion.mderror-handling.mdindex.mdmemory-management.mdsource-generation.mdtype-system.md

type-system.mddocs/

0

# Type System

1

2

C type introspection and manipulation operations. The type system provides complete information about C types, sizes, alignment, and structure layouts.

3

4

## Capabilities

5

6

### Type Information

7

8

Gets type information for C declarations and data objects.

9

10

```python { .api }

11

def typeof(self, cdecl):

12

"""

13

Get the C type of a declaration or data object.

14

15

Parameters:

16

- cdecl (str|CData): C type string or existing CData object

17

18

Returns:

19

CType object representing the C type

20

"""

21

```

22

23

**Usage Examples:**

24

25

```python

26

# Get type from string declaration

27

int_type = ffi.typeof("int")

28

ptr_type = ffi.typeof("int *")

29

array_type = ffi.typeof("int[10]")

30

31

# Get type from existing data

32

data = ffi.new("int *", 42)

33

data_type = ffi.typeof(data) # Returns pointer type

34

35

# Function types

36

ffi.cdef("int add(int a, int b);")

37

func_type = ffi.typeof("int(*)(int, int)")

38

39

# Structure types

40

ffi.cdef("struct point { int x, y; };")

41

struct_type = ffi.typeof("struct point")

42

```

43

44

### Size Information

45

46

Gets the size in bytes of C types or data objects.

47

48

```python { .api }

49

def sizeof(self, cdecl):

50

"""

51

Get size in bytes of C type or data object.

52

53

Parameters:

54

- cdecl (str|CData): C type string or CData object

55

56

Returns:

57

int: Size in bytes

58

"""

59

```

60

61

**Usage Examples:**

62

63

```python

64

# Basic type sizes

65

int_size = ffi.sizeof("int") # Usually 4

66

long_size = ffi.sizeof("long") # Platform dependent

67

ptr_size = ffi.sizeof("void *") # Usually 8 on 64-bit

68

69

# Array sizes

70

array_size = ffi.sizeof("int[10]") # 40 bytes (10 * 4)

71

72

# Structure sizes (including padding)

73

ffi.cdef("struct data { char a; int b; };")

74

struct_size = ffi.sizeof("struct data") # Usually 8 (due to alignment)

75

76

# Size of existing data

77

data = ffi.new("char[100]")

78

data_size = ffi.sizeof(data) # 100

79

```

80

81

### Alignment Information

82

83

Gets the natural alignment requirements for C types.

84

85

```python { .api }

86

def alignof(self, cdecl):

87

"""

88

Get natural alignment size in bytes of C type.

89

90

Parameters:

91

- cdecl (str|CType): C type string or CType object

92

93

Returns:

94

int: Alignment requirement in bytes

95

"""

96

```

97

98

**Usage Examples:**

99

100

```python

101

# Basic type alignments

102

char_align = ffi.alignof("char") # 1

103

int_align = ffi.alignof("int") # Usually 4

104

double_align = ffi.alignof("double") # Usually 8

105

ptr_align = ffi.alignof("void *") # Usually 8 on 64-bit

106

107

# Structure alignment

108

ffi.cdef("struct aligned { char a; double b; };")

109

struct_align = ffi.alignof("struct aligned") # Usually 8

110

```

111

112

### Field Offset Information

113

114

Gets the byte offset of fields within structures or arrays.

115

116

```python { .api }

117

def offsetof(self, cdecl, *fields_or_indexes):

118

"""

119

Get byte offset of field within structure or array element.

120

121

Parameters:

122

- cdecl (str): C type string for structure or array

123

- *fields_or_indexes: Field names or array indexes

124

125

Returns:

126

int: Byte offset from start of structure/array

127

"""

128

```

129

130

**Usage Examples:**

131

132

```python

133

# Structure field offsets

134

ffi.cdef("""

135

struct person {

136

char name[32];

137

int age;

138

double salary;

139

};

140

""")

141

142

name_offset = ffi.offsetof("struct person", "name") # 0

143

age_offset = ffi.offsetof("struct person", "age") # 32

144

salary_offset = ffi.offsetof("struct person", "salary") # 36 (or 40 with padding)

145

146

# Array element offsets

147

element_offset = ffi.offsetof("int[10]", 5) # 20 (5 * 4)

148

149

# Nested structure offsets

150

ffi.cdef("""

151

struct inner { int x, y; };

152

struct outer { char flag; struct inner data[3]; };

153

""")

154

155

nested_offset = ffi.offsetof("struct outer", "data", 1, "y")

156

```

157

158

### Type String Generation

159

160

Generates C type strings from type objects with optional formatting.

161

162

```python { .api }

163

def getctype(self, cdecl, replace_with=''):

164

"""

165

Get C type string representation.

166

167

Parameters:

168

- cdecl (str|CType): C type string or CType object

169

- replace_with (str): Text to insert/append (e.g., variable name)

170

171

Returns:

172

str: C type string representation

173

"""

174

```

175

176

**Usage Examples:**

177

178

```python

179

# Basic type strings

180

int_str = ffi.getctype("int") # "int"

181

ptr_str = ffi.getctype("int *") # "int *"

182

183

# With variable names

184

var_decl = ffi.getctype("int", "my_var") # "int my_var"

185

ptr_decl = ffi.getctype("int *", "my_ptr") # "int * my_ptr"

186

187

# Array declarations

188

array_decl = ffi.getctype("int", "[10]") # "int[10]"

189

190

# Function pointer declarations

191

func_decl = ffi.getctype("int(*)(int, int)", "add_func") # "int(*add_func)(int, int)"

192

```

193

194

### Type Enumeration

195

196

Lists all user-defined types known to the FFI instance.

197

198

```python { .api }

199

def list_types(self):

200

"""

201

Get all user-defined type names.

202

203

Returns:

204

tuple: (typedef_names, struct_names, union_names)

205

"""

206

```

207

208

**Usage Example:**

209

210

```python

211

ffi.cdef("""

212

typedef int my_int_t;

213

typedef char* string_t;

214

215

struct point { int x, y; };

216

struct rect { struct point top_left, bottom_right; };

217

218

union value { int i; float f; char c; };

219

""")

220

221

typedefs, structs, unions = ffi.list_types()

222

print("Typedefs:", typedefs) # ['my_int_t', 'string_t']

223

print("Structs:", structs) # ['point', 'rect']

224

print("Unions:", unions) # ['value']

225

```

226

227

## Type Introspection Patterns

228

229

### Runtime Type Checking

230

231

```python

232

def process_data(data):

233

data_type = ffi.typeof(data)

234

235

if data_type.kind == "pointer":

236

print(f"Pointer to {data_type.item}")

237

if data_type.item.cname == "int":

238

print("Integer pointer")

239

elif data_type.kind == "array":

240

print(f"Array of {data_type.item} with length {data_type.length}")

241

```

242

243

### Structure Layout Analysis

244

245

```python

246

def analyze_struct(struct_name):

247

struct_type = ffi.typeof(struct_name)

248

struct_size = ffi.sizeof(struct_type)

249

250

print(f"Structure: {struct_name}")

251

print(f"Total size: {struct_size} bytes")

252

253

# Analyze fields (requires accessing internal structure)

254

for field_name in struct_type.fields:

255

offset = ffi.offsetof(struct_name, field_name)

256

field_type = ffi.typeof(f"{struct_name}.{field_name}")

257

field_size = ffi.sizeof(field_type)

258

259

print(f" {field_name}: offset {offset}, size {field_size}")

260

```

261

262

### Memory Layout Calculation

263

264

```python

265

def calculate_padding(struct_name):

266

struct_size = ffi.sizeof(struct_name)

267

268

# Calculate sum of field sizes

269

field_total = 0

270

for field_name in ["field1", "field2", "field3"]: # Known fields

271

try:

272

field_size = ffi.sizeof(ffi.typeof(f"{struct_name}.{field_name}"))

273

field_total += field_size

274

except:

275

break

276

277

padding = struct_size - field_total

278

print(f"Total padding: {padding} bytes")

279

```

280

281

### Type Compatibility Checking

282

283

```python

284

def are_compatible(type1, type2):

285

"""Check if two types are assignment compatible"""

286

t1 = ffi.typeof(type1)

287

t2 = ffi.typeof(type2)

288

289

# Same type

290

if t1 == t2:

291

return True

292

293

# Pointer compatibility

294

if t1.kind == "pointer" and t2.kind == "pointer":

295

return t1.item == t2.item or t1.item.cname == "char" or t2.item.cname == "char"

296

297

# Integer type compatibility

298

if t1.kind == "primitive" and t2.kind == "primitive":

299

return t1.cname in ["int", "long", "short"] and t2.cname in ["int", "long", "short"]

300

301

return False

302

```

303

304

## Platform-Specific Considerations

305

306

### Size Variations

307

308

```python

309

# Check platform-specific sizes

310

import platform

311

312

print(f"Platform: {platform.machine()}")

313

print(f"Pointer size: {ffi.sizeof('void *')} bytes")

314

print(f"Long size: {ffi.sizeof('long')} bytes")

315

print(f"Size_t size: {ffi.sizeof('size_t')} bytes")

316

317

# Adjust algorithms based on sizes

318

if ffi.sizeof("void *") == 8:

319

print("64-bit platform")

320

else:

321

print("32-bit platform")

322

```

323

324

### Alignment Considerations

325

326

```python

327

def check_alignment(type_name):

328

size = ffi.sizeof(type_name)

329

alignment = ffi.alignof(type_name)

330

331

print(f"{type_name}: size={size}, alignment={alignment}")

332

333

if size % alignment != 0:

334

print(f"Warning: {type_name} size not aligned!")

335

```