type.c (52900B)
1 #include "arch/arch.h" 2 #include "cg/internal.h" 3 #include "core/hashmap.h" 4 #include "obj/obj.h" 5 6 typedef struct CgApiType { 7 /* Public identity view (kit/cg.h). Kept as the FIRST member so a pointer to 8 * the entry is a valid `const KitCgTypeInfo*` and kit_cg_type_view can hand 9 * it back without a copy. Identity (id/storage_id/kind/flags) is filled once, 10 * lazily, by kit_cg_type_view; layout and the COMPLETE/SIZED flags are not 11 * maintained here (see the view's contract) — kit_cg_type_info computes 12 * those. info.id == 0 marks the entry as not yet filled (a valid id is 13 * never 0, and segvec slots are zero-initialized). */ 14 KitCgTypeInfo info; 15 CgType cg; 16 /* Lazily-filled packed API_TYPE_CLASS_* memo (0 == not yet computed; the 17 * VALID bit distinguishes a computed all-zero class from unfilled). */ 18 u8 cached_class; 19 /* Lazily-filled abi_cg_type_info memo (see api_type_layout_ref/put): `abi` 20 * holds the cached size/align/scalar profile, valid iff abi_cached. */ 21 u8 abi_cached; 22 /* Lazily-filled flat predicate descriptor. Extends the cached_class 23 * mechanism: pred_bits is a bitset of API_PRED_* computed on the exact 24 * operational type, and pred_valid distinguishes a computed all-zero set from 25 * unfilled. */ 26 u8 pred_bits; 27 u8 pred_valid; 28 ABITypeInfo abi; 29 /* This entry's own type id (set by type_alloc). Lets a structural hashset of 30 * CgApiType* recover the id without maintaining a reverse index. */ 31 KitCgTypeId self_id; 32 } CgApiType; 33 34 /* The flat per-id predicate bitset (API_PRED_*) and api_type_pred_bits live in 35 * cg/type.h so multi-predicate-on-same-id call sites can decode an id once. */ 36 37 /* High bit of CgApiType.cached_class: set once the class has been computed, so 38 * a genuine {WK_NARROW, non-aggregate} (packed 0) is told apart from unfilled. 39 */ 40 #define API_TYPE_CLASS_CACHED 0x80u 41 42 enum { CG_API_TYPES_SEG_SHIFT = 6 }; 43 44 SEGVEC_DEFINE(CgApiTypes, CgApiType, CG_API_TYPES_SEG_SHIFT); 45 46 /* Structural dedup of derived ptr/array types, O(1) instead of a linear scan of 47 * the whole type table on every derivation (which made each derived-type use 48 * O(#types) — the dominant frontend hotspot on type-heavy input like sqlite). 49 * Pointer keys fit in a u64: ptr = (pointee<<32)|addr_sp. Arrays use the 50 * structural hashset below so their full uint64_t count participates in 51 * identity. */ 52 static inline u64 cg_ptr_key(KitCgTypeId pointee, u32 address_space) { 53 return ((u64)pointee << 32) | (u64)address_space; 54 } 55 KIT_HASHMAP_DEFINE(CgPtrMap, u64, KitCgTypeId, hash_u64); 56 57 /* Array and function types have structural keys that a scalar hashmap cannot 58 * express (array counts are full uint64_t; function keys include attrs), so 59 * dedup them through structural hashsets of the stored CgApiType* (SEGVEC 60 * entries have stable addresses). The callbacks are defined further down. */ 61 static u32 cg_array_hash(CgApiType* const e); 62 static int cg_array_eq(CgApiType* const a, CgApiType* const b); 63 static u32 cg_func_hash(CgApiType* const e); 64 static int cg_func_eq(CgApiType* const a, CgApiType* const b); 65 KIT_HASHSET_DEFINE(CgArraySet, CgApiType*, cg_array_hash, cg_array_eq); 66 KIT_HASHSET_DEFINE(CgFuncSet, CgApiType*, cg_func_hash, cg_func_eq); 67 68 typedef struct CgApiState { 69 Heap* heap; 70 CgApiTypes types; 71 /* Structural dedup indexes for derived ptr/array/func types (see above). */ 72 CgPtrMap ptr_index; 73 CgArraySet array_index; 74 CgFuncSet func_index; 75 CgType builtins[KIT_CG_BUILTIN_COUNT]; 76 /* Per-builtin identity view returned by kit_cg_type_view: builtins are stored 77 * as bare CgType (no CgApiType entry to point at), so their stable 78 * KitCgTypeInfo backing lives here, precomputed at init. */ 79 KitCgTypeInfo builtin_info[KIT_CG_BUILTIN_COUNT]; 80 /* Packed API_TYPE_CLASS_* per builtin, precomputed at init so the hottest 81 * operand types (i32/i64/f64/ptr/...) classify with a single indexed load. */ 82 u8 builtin_class[KIT_CG_BUILTIN_COUNT]; 83 /* Packed API_PRED_* bitset per builtin, precomputed at init so the (very hot) 84 * cg_type_is_* predicate queries on the most-frequent operand types resolve 85 * with a single indexed load instead of a cg_type_get + per-kind re-classify 86 * on every call. Builtins are never aliases, so the bitset is exact. */ 87 u8 builtin_pred[KIT_CG_BUILTIN_COUNT]; 88 /* Per-builtin ABI layout, precomputed at init so abi_cg_type_info can hit the 89 * same memo path for builtin scalars as it does for user types. */ 90 ABITypeInfo builtin_layout[KIT_CG_BUILTIN_COUNT]; 91 u8 builtins_init; 92 u8 pad[3]; 93 } CgApiState; 94 95 KitCgTypeId builtin_id(KitCgBuiltinType t) { 96 if ((u32)t >= KIT_CG_BUILTIN_COUNT) return KIT_CG_TYPE_NONE; 97 return (KitCgTypeId)((u32)t + 1u); 98 } 99 100 static int decode_user_id(KitCgTypeId id, u32* index_out) { 101 if (!index_out) return 0; 102 if (id <= KIT_CG_BUILTIN_COUNT) return 0; 103 *index_out = id - (KitCgTypeId)KIT_CG_BUILTIN_COUNT - 1u; 104 return 1; 105 } 106 107 static KitCgTypeId user_id_from_index(u32 index) { 108 if (index > UINT32_MAX - (u32)KIT_CG_BUILTIN_COUNT - 1u) 109 return KIT_CG_TYPE_NONE; 110 return (KitCgTypeId)((u32)KIT_CG_BUILTIN_COUNT + 1u + index); 111 } 112 113 static u64 cg_align_to(u64 n, u32 align) { 114 u64 a = align ? (u64)align : 1u; 115 return ((n + a - 1u) / a) * a; 116 } 117 118 static void builtin_cg_type_init(Compiler* c, CgType* out, KitCgBuiltinType t) { 119 memset(out, 0, sizeof(*out)); 120 switch (t) { 121 case KIT_CG_BUILTIN_VOID: 122 out->kind = KIT_CG_TYPE_VOID; 123 out->align = 1; 124 break; 125 case KIT_CG_BUILTIN_BOOL: 126 out->kind = KIT_CG_TYPE_BOOL; 127 out->size = 1; 128 out->align = 1; 129 out->integer.width = 8; 130 break; 131 case KIT_CG_BUILTIN_I8: 132 out->kind = KIT_CG_TYPE_INT; 133 out->size = 1; 134 out->align = 1; 135 out->integer.width = 8; 136 break; 137 case KIT_CG_BUILTIN_I16: 138 out->kind = KIT_CG_TYPE_INT; 139 out->size = 2; 140 out->align = 2; 141 out->integer.width = 16; 142 break; 143 case KIT_CG_BUILTIN_I32: 144 out->kind = KIT_CG_TYPE_INT; 145 out->size = 4; 146 out->align = 4; 147 out->integer.width = 32; 148 break; 149 case KIT_CG_BUILTIN_I64: 150 out->kind = KIT_CG_TYPE_INT; 151 out->size = 8; 152 out->align = 8; 153 out->integer.width = 64; 154 break; 155 case KIT_CG_BUILTIN_I128: 156 out->kind = KIT_CG_TYPE_INT; 157 out->size = 16; 158 out->align = 16; 159 out->integer.width = 128; 160 break; 161 case KIT_CG_BUILTIN_F32: 162 out->kind = KIT_CG_TYPE_FLOAT; 163 out->size = 4; 164 out->align = 4; 165 out->fp.width = 32; 166 break; 167 case KIT_CG_BUILTIN_F64: 168 out->kind = KIT_CG_TYPE_FLOAT; 169 out->size = 8; 170 out->align = 8; 171 out->fp.width = 64; 172 break; 173 case KIT_CG_BUILTIN_F128: 174 out->kind = KIT_CG_TYPE_FLOAT; 175 out->size = 16; 176 out->align = 16; 177 out->fp.width = 128; 178 break; 179 case KIT_CG_BUILTIN_VARARG_STATE: { 180 ABITypeInfo info = abi_va_list_info(c->abi); 181 out->kind = KIT_CG_TYPE_VARARG_STATE; 182 out->size = info.size; 183 out->align = info.align ? info.align : 1; 184 break; 185 } 186 case KIT_CG_BUILTIN_COUNT: 187 break; 188 } 189 } 190 191 static CgApiState* cg_api_get(Compiler* c); 192 static CgApiType* api_type_from_id(Compiler* c, KitCgTypeId id); 193 static u8 api_pred_bits_for_kind(const CgType* ty); 194 195 static ABITypeInfo api_builtin_layout_info(Compiler* c, const CgType* t) { 196 ABITypeInfo r = {0, 0, ABI_SC_VOID, 0, 0, 0}; 197 if (!t) return r; 198 switch (t->kind) { 199 case KIT_CG_TYPE_PTR: 200 r.size = c->target.ptr_size ? c->target.ptr_size : 8; 201 r.align = c->target.ptr_align ? c->target.ptr_align : 8; 202 r.scalar_kind = ABI_SC_PTR; 203 return r; 204 case KIT_CG_TYPE_VOID: 205 r.align = 1; 206 r.scalar_kind = ABI_SC_VOID; 207 return r; 208 case KIT_CG_TYPE_BOOL: 209 r.size = t->size; 210 r.align = t->align; 211 r.scalar_kind = ABI_SC_BOOL; 212 return r; 213 case KIT_CG_TYPE_INT: 214 r.size = t->size; 215 r.align = t->align; 216 r.scalar_kind = ABI_SC_INT; 217 return r; 218 case KIT_CG_TYPE_FLOAT: 219 r.size = t->size; 220 r.align = t->align; 221 r.scalar_kind = ABI_SC_FLOAT; 222 return r; 223 case KIT_CG_TYPE_VARARG_STATE: 224 r.size = t->size; 225 r.align = t->align; 226 return r; 227 default: 228 return r; 229 } 230 } 231 232 /* ---- codegen scalar type-property predicates ---- 233 * Thin queries over the resolved CgType / target ABI; pure functions of 234 * (type, target). The wide-class predicates below feed api_wide_kind_for, which 235 * feeds the memoized api_type_class. */ 236 237 int api_type_is_float(Compiler* c, KitCgTypeId ty) { 238 const CgType* cg; 239 cg = cg_type_get(c, ty); 240 return cg && cg->kind == KIT_CG_TYPE_FLOAT; 241 } 242 243 int api_is_f128_type(Compiler* c, KitCgTypeId ty) { 244 const CgType* cg; 245 cg = cg_type_get(c, ty); 246 return cg && cg->kind == KIT_CG_TYPE_FLOAT && cg->fp.width == 128; 247 } 248 249 int api_is_i128_type(Compiler* c, KitCgTypeId ty) { 250 const CgType* cg; 251 cg = cg_type_get(c, ty); 252 return cg && cg->kind == KIT_CG_TYPE_INT && cg->integer.width == 128; 253 } 254 255 int api_is_wide16_scalar_type(Compiler* c, KitCgTypeId ty) { 256 return api_is_f128_type(c, ty) || api_is_i128_type(c, ty); 257 } 258 259 /* 8-byte scalar split into two 4-byte lanes by the selected ABI. This covers 260 * 32-bit native ABIs whose generic CG path cannot keep the value in a single 261 * scalar register/value. Such values are forced memory-resident so operations 262 * can be legalized as lane sequences or runtime calls. */ 263 int api_is_wide8_scalar_type(Compiler* c, KitCgTypeId ty) { 264 ABITypeInfo ti; 265 if (!c || !c->abi || !ty) return 0; 266 if (abi_cg_scalar_split_lane_size(c->abi, ty) != 4u) return 0; 267 ti = abi_cg_type_info(c->abi, ty); 268 return ti.size == 8u && 269 (ti.scalar_kind == ABI_SC_INT || ti.scalar_kind == ABI_SC_FLOAT); 270 } 271 272 /* Classify a scalar into its mutually-exclusive wide / soft-float dispatch 273 * class. Reproduces the predicates exactly: WK_I128/WK_F128 are the 128-bit 274 * scalars; WK_WIDE8 is an int-width-bearing split-lane scalar (excluding i128, 275 * handled above; a split-lane *float* bears int width 0 and falls through to a 276 * soft class); WK_SOFT_DOUBLE/WK_SOFT_SINGLE are f64/f32 with no hardware FP of 277 * that width. Only api_compute_type_class calls this. */ 278 static u8 api_wide_kind_for(Compiler* c, KitCgTypeId ty) { 279 u8 fa; 280 if (!c || !ty) return WK_NARROW; 281 if (api_is_i128_type(c, ty)) return WK_I128; 282 if (api_is_f128_type(c, ty)) return WK_F128; 283 if (kit_cg_type_int_width((KitCompiler*)c, ty) != 0 && 284 api_is_wide8_scalar_type(c, ty)) { 285 return WK_WIDE8; 286 } 287 fa = c->target.float_abi; 288 if ((fa == KIT_FLOAT_ABI_SOFT || fa == KIT_FLOAT_ABI_SINGLE) && 289 kit_cg_type_float_width((KitCompiler*)c, ty) == 64) { 290 return WK_SOFT_DOUBLE; 291 } 292 if (fa == KIT_FLOAT_ABI_SOFT && 293 kit_cg_type_float_width((KitCompiler*)c, ty) == 32) { 294 return WK_SOFT_SINGLE; 295 } 296 return WK_NARROW; 297 } 298 299 /* Compute the packed API_TYPE_CLASS_* byte for `ty` from scratch: the wide / 300 * soft-float dispatch class plus the aggregate-place bit. Both are pure 301 * functions of (type, target), so callers memoize the result (per builtin at 302 * init, per user type lazily) rather than re-run this on every value push. */ 303 static u8 api_compute_type_class(Compiler* c, KitCgTypeId ty) { 304 u8 cls = api_wide_kind_for(c, ty) & API_TYPE_CLASS_WIDE_MASK; 305 if (cg_type_is_aggregate(c, ty)) cls |= API_TYPE_CLASS_AGGREGATE; 306 return cls; 307 } 308 309 static void cg_api_init_builtins(Compiler* c, CgApiState* s) { 310 if (s->builtins_init) return; 311 for (u32 i = 0; i < KIT_CG_BUILTIN_COUNT; ++i) { 312 builtin_cg_type_init(c, &s->builtins[i], (KitCgBuiltinType)i); 313 } 314 for (u32 i = 0; i < KIT_CG_BUILTIN_COUNT; ++i) { 315 s->builtin_layout[i] = api_builtin_layout_info(c, &s->builtins[i]); 316 } 317 /* Publish the filled table so abi_cg_type_info can index it inline (one load, 318 * no cross-TU call) for the common builtin case. NULLed in cg_api_fini. */ 319 c->cg_builtin_layout = s->builtin_layout; 320 /* Precompute each builtin's class now that the builtin table and the ABI are 321 * both live (builtin_cg_type_init already consults c->abi for the va_list 322 * builtin, so it is ready). */ 323 for (u32 i = 0; i < KIT_CG_BUILTIN_COUNT; ++i) { 324 s->builtin_class[i] = 325 api_compute_type_class(c, builtin_id((KitCgBuiltinType)i)); 326 /* Builtins are never aliases, so the kind-derived predicate bitset is the 327 * exact, final value — classify the node once here, then every predicate 328 * query is one indexed load (see api_type_pred). */ 329 s->builtin_pred[i] = api_pred_bits_for_kind(&s->builtins[i]); 330 /* Stable identity view for kit_cg_type_view. storage_id == id; 331 * layout/complete/sized are left to kit_cg_type_info. */ 332 s->builtin_info[i].id = builtin_id((KitCgBuiltinType)i); 333 s->builtin_info[i].storage_id = s->builtin_info[i].id; 334 s->builtin_info[i].kind = s->builtins[i].kind; 335 s->builtin_info[i].flags = KIT_CG_TYPEF_BUILTIN; 336 } 337 s->builtins_init = 1; 338 } 339 340 u8 api_type_class(Compiler* c, KitCgTypeId ty) { 341 CgApiState* s; 342 CgApiType* e; 343 if (ty == KIT_CG_TYPE_NONE) return 0; 344 s = c->cg_api ? (CgApiState*)c->cg_api : cg_api_get(c); 345 if (!s) return api_compute_type_class(c, ty); 346 if (ty <= KIT_CG_BUILTIN_COUNT) { 347 u32 off = ty - 1u; 348 if (off < KIT_CG_BUILTIN_COUNT) return s->builtin_class[off]; 349 return api_compute_type_class(c, ty); 350 } 351 e = api_type_from_id(c, ty); 352 if (!e) return api_compute_type_class(c, ty); 353 if (!(e->cached_class & API_TYPE_CLASS_CACHED)) 354 e->cached_class = API_TYPE_CLASS_CACHED | api_compute_type_class(c, ty); 355 return (u8)(e->cached_class & ~API_TYPE_CLASS_CACHED); 356 } 357 358 const ABITypeInfo* api_type_layout_ref(Compiler* c, KitCgTypeId ty) { 359 CgApiState* s; 360 CgApiType* e; 361 if (!c || ty == KIT_CG_TYPE_NONE) return NULL; 362 if (ty <= KIT_CG_BUILTIN_COUNT) { 363 s = c->cg_api ? (CgApiState*)c->cg_api : cg_api_get(c); 364 return s ? &s->builtin_layout[ty - 1u] : NULL; 365 } 366 e = api_type_from_id(c, ty); 367 return (e && e->abi_cached) ? &e->abi : NULL; 368 } 369 370 void api_type_layout_put(Compiler* c, KitCgTypeId ty, ABITypeInfo info) { 371 CgApiType* e; 372 if (!c || ty == KIT_CG_TYPE_NONE) return; 373 if (ty <= KIT_CG_BUILTIN_COUNT) return; 374 if (!info.align && info.scalar_kind == ABI_SC_VOID) return; 375 e = api_type_from_id(c, ty); 376 if (!e) return; 377 e->abi = info; 378 e->abi_cached = 1; 379 } 380 381 static CgApiState* cg_api_get(Compiler* c) { 382 Heap* h; 383 CgApiState* s; 384 if (!c) return NULL; 385 if (c->cg_api) return (CgApiState*)c->cg_api; 386 h = (Heap*)c->ctx->heap; 387 s = (CgApiState*)h->alloc(h, sizeof(*s), _Alignof(CgApiState)); 388 if (!s) return NULL; 389 memset(s, 0, sizeof(*s)); 390 s->heap = h; 391 CgApiTypes_init(&s->types, h); 392 CgPtrMap_init(&s->ptr_index, h); 393 CgArraySet_init(&s->array_index, h); 394 CgFuncSet_init(&s->func_index, h); 395 c->cg_api = s; 396 c->cg_api_free = cg_api_fini; 397 cg_api_init_builtins(c, s); 398 return s; 399 } 400 401 const CgType* cg_type_get(Compiler* c, KitCgTypeId id) { 402 u32 off; 403 CgApiState* s; 404 CgApiType* e; 405 if (!c || id == KIT_CG_TYPE_NONE) return NULL; 406 if (id <= KIT_CG_BUILTIN_COUNT) { 407 off = id - 1u; 408 /* Fast path: the per-compiler state (with its builtin table) is created 409 * on first use and then stays put, so inline the already-initialized case 410 * -- the hot per-op type query becomes a load + index instead of a call 411 * into cg_api_get. cg_api_get still handles lazy first-time creation. */ 412 s = c->cg_api ? (CgApiState*)c->cg_api : cg_api_get(c); 413 if (!s) return NULL; 414 return &s->builtins[off]; 415 } 416 e = api_type_from_id(c, id); 417 return e ? &e->cg : NULL; 418 } 419 420 uint64_t cg_type_size(Compiler* c, KitCgTypeId id) { 421 return c && c->abi ? abi_cg_sizeof(c->abi, id) : 0; 422 } 423 424 uint32_t cg_type_align(Compiler* c, KitCgTypeId id) { 425 return c && c->abi ? abi_cg_alignof(c->abi, id) : 0; 426 } 427 428 /* Predicate bitset of a single (already-unaliased) CgType node. The kind->bit 429 * mapping reproduces the legacy cg_type_is_* predicates exactly. */ 430 static u8 api_pred_bits_for_kind(const CgType* ty) { 431 if (!ty) return 0; 432 switch (ty->kind) { 433 case KIT_CG_TYPE_INT: 434 case KIT_CG_TYPE_BOOL: 435 case KIT_CG_TYPE_ENUM: 436 return API_PRED_INT; 437 case KIT_CG_TYPE_FLOAT: 438 return API_PRED_FLOAT; 439 case KIT_CG_TYPE_PTR: 440 return API_PRED_PTR; 441 case KIT_CG_TYPE_VOID: 442 return API_PRED_VOID; 443 case KIT_CG_TYPE_RECORD: 444 return API_PRED_RECORD | API_PRED_AGGREGATE; 445 default: 446 return 0; 447 } 448 } 449 450 /* Full API_PRED_* bitset for `id` via exactly one decode: builtin fast path (no 451 * aliasing, no entry) or a descriptor load off the user-type entry, filled 452 * lazily on first miss. Multi-predicate-on-the-same-id call sites read this 453 * once and then test the masks locally instead of decoding `id` per predicate. 454 */ 455 u8 api_type_pred_bits(Compiler* c, KitCgTypeId id) { 456 CgApiType* e; 457 if (id == KIT_CG_TYPE_NONE) return 0; 458 if (id <= KIT_CG_BUILTIN_COUNT) { 459 /* Builtin predicate bitsets are precomputed at init, so this is one indexed 460 * load (no cg_type_get + re-classify). */ 461 u32 off = id - 1u; 462 CgApiState* s = c->cg_api ? (CgApiState*)c->cg_api : cg_api_get(c); 463 if (s && off < KIT_CG_BUILTIN_COUNT) return s->builtin_pred[off]; 464 return api_pred_bits_for_kind(cg_type_get(c, id)); 465 } 466 e = api_type_from_id(c, id); 467 if (!e) return 0; 468 if (!e->pred_valid) { 469 e->pred_bits = api_pred_bits_for_kind(cg_type_get(c, id)); 470 e->pred_valid = 1; 471 } 472 return e->pred_bits; 473 } 474 475 /* One predicate query for `id`: returns (bits & mask) != 0 off the 476 * single-decode bitset. Mirrors api_type_class's CACHED-bit memo. */ 477 static int api_type_pred(Compiler* c, KitCgTypeId id, u8 mask) { 478 return (api_type_pred_bits(c, id) & mask) != 0; 479 } 480 481 int cg_type_is_int(Compiler* c, KitCgTypeId id) { 482 return api_type_pred(c, id, API_PRED_INT); 483 } 484 485 int cg_type_is_float(Compiler* c, KitCgTypeId id) { 486 return api_type_pred(c, id, API_PRED_FLOAT); 487 } 488 489 int cg_type_is_ptr(Compiler* c, KitCgTypeId id) { 490 return api_type_pred(c, id, API_PRED_PTR); 491 } 492 493 int cg_type_is_record(Compiler* c, KitCgTypeId id) { 494 return api_type_pred(c, id, API_PRED_RECORD); 495 } 496 497 int cg_type_is_void(Compiler* c, KitCgTypeId id) { 498 return api_type_pred(c, id, API_PRED_VOID); 499 } 500 501 int cg_type_is_aggregate(Compiler* c, KitCgTypeId id) { 502 return api_type_pred(c, id, API_PRED_AGGREGATE); 503 } 504 505 KitCgTypeId cg_type_ptr_to(Compiler* c, KitCgTypeId pointee) { 506 return kit_cg_type_ptr(c, pointee, 0); 507 } 508 509 KitCgTypeId cg_type_pointee(Compiler* c, KitCgTypeId id) { 510 const CgType* ty = cg_type_get(c, id); 511 return ty && ty->kind == KIT_CG_TYPE_PTR ? ty->ptr.pointee : KIT_CG_TYPE_NONE; 512 } 513 514 KitCgTypeId cg_type_func_ret_id(Compiler* c, KitCgTypeId id) { 515 const CgType* ty = cg_type_get(c, id); 516 if (!ty || ty->kind != KIT_CG_TYPE_FUNC) return KIT_CG_TYPE_NONE; 517 return ty->func.result.type; 518 } 519 520 KitCgTypeId cg_func_ret_type(const CgType* fnty) { 521 return fnty->func.result.type; 522 } 523 524 KitCgTypeId cg_type_func_result_id(Compiler* c, KitCgTypeId id) { 525 const CgType* ty = cg_type_get(c, id); 526 if (!ty || ty->kind != KIT_CG_TYPE_FUNC) return KIT_CG_TYPE_NONE; 527 return ty->func.result.type; 528 } 529 530 KitCgTypeId cg_type_func_param_id(Compiler* c, KitCgTypeId id, u32 index) { 531 const CgType* ty = cg_type_get(c, id); 532 if (!ty || ty->kind != KIT_CG_TYPE_FUNC || index >= ty->func.nparams) 533 return KIT_CG_TYPE_NONE; 534 return ty->func.params[index].type; 535 } 536 537 static CgApiType* type_alloc(Compiler* c, KitCgTypeId* id_out) { 538 CgApiState* s = cg_api_get(c); 539 CgApiType* e; 540 u32 index; 541 if (!s) return NULL; 542 e = CgApiTypes_push(&s->types, &index); 543 if (!e) return NULL; 544 *id_out = user_id_from_index(index); 545 if (*id_out == KIT_CG_TYPE_NONE) return NULL; 546 e->self_id = *id_out; 547 return e; 548 } 549 550 static KitCgTypeId find_ptr_type_id(Compiler* c, KitCgTypeId pointee, 551 u32 address_space) { 552 CgApiState* s; 553 const KitCgTypeId* hit; 554 if (!c || !c->cg_api) return KIT_CG_TYPE_NONE; 555 s = (CgApiState*)c->cg_api; 556 hit = CgPtrMap_get(&s->ptr_index, cg_ptr_key(pointee, address_space)); 557 return hit ? *hit : KIT_CG_TYPE_NONE; 558 } 559 560 static KitCgTypeId find_array_type_id(Compiler* c, KitCgTypeId elem, 561 u64 count) { 562 CgApiState* s; 563 CgApiType probe; 564 CgApiType* hit; 565 if (!c || !c->cg_api) return KIT_CG_TYPE_NONE; 566 s = (CgApiState*)c->cg_api; 567 memset(&probe, 0, sizeof probe); 568 probe.cg.kind = KIT_CG_TYPE_ARRAY; 569 probe.cg.array.elem = elem; 570 probe.cg.array.count = count; 571 hit = CgArraySet_find(&s->array_index, &probe); 572 return hit ? hit->self_id : KIT_CG_TYPE_NONE; 573 } 574 575 static int cg_params_eq(const KitCgFuncParam* a, const KitCgFuncParam* b, 576 u32 n) { 577 for (u32 i = 0; i < n; ++i) 578 if (a[i].type != b[i].type || 579 memcmp(&a[i].attrs, &b[i].attrs, sizeof(a[i].attrs)) != 0) { 580 return 0; 581 } 582 return 1; 583 } 584 585 static int cg_result_eq(const KitCgFuncResult* a, const KitCgFuncResult* b) { 586 return a->type == b->type && 587 memcmp(&a->attrs, &b->attrs, sizeof(a->attrs)) == 0; 588 } 589 590 static u32 cg_array_hash(CgApiType* const e) { 591 u32 h = hash_u32((u32)e->cg.array.elem); 592 h ^= hash_u64(e->cg.array.count) + 0x9e3779b9u + (h << 6) + (h >> 2); 593 return h; 594 } 595 596 static int cg_array_eq(CgApiType* const a, CgApiType* const b) { 597 return a->cg.array.elem == b->cg.array.elem && 598 a->cg.array.count == b->cg.array.count; 599 } 600 601 /* Structural hash/eq over a function type's identity — the same fields the old 602 * linear scan compared. Only function types enter this set, so neither callback 603 * needs to re-check kind. The result/param attrs are compared (not hashed): 604 * fewer hash inputs just means eq resolves the (rare) collision. */ 605 static u32 cg_func_hash(CgApiType* const e) { 606 u32 h = 2166136261u; 607 h = (h ^ (u32)e->cg.func.nparams) * 16777619u; 608 h = (h ^ (u32)e->cg.func.abi_variadic) * 16777619u; 609 h = (h ^ (u32)e->cg.func.call_conv) * 16777619u; 610 h = (h ^ (u32)e->cg.func.result.type) * 16777619u; 611 for (u32 i = 0; i < e->cg.func.nparams; ++i) 612 h = (h ^ (u32)e->cg.func.params[i].type) * 16777619u; 613 return h; 614 } 615 616 static int cg_func_eq(CgApiType* const a, CgApiType* const b) { 617 if (a->cg.func.nparams != b->cg.func.nparams) return 0; 618 if (a->cg.func.abi_variadic != b->cg.func.abi_variadic) return 0; 619 if (a->cg.func.call_conv != b->cg.func.call_conv) return 0; 620 if (!cg_result_eq(&a->cg.func.result, &b->cg.func.result)) return 0; 621 if (a->cg.func.nparams && 622 !cg_params_eq(a->cg.func.params, b->cg.func.params, a->cg.func.nparams)) { 623 return 0; 624 } 625 return 1; 626 } 627 628 static KitCgTypeId find_func_type_id(Compiler* c, KitCgFuncSig sig) { 629 CgApiState* s; 630 CgApiType probe; 631 CgApiType* hit; 632 if (!c || !c->cg_api) return KIT_CG_TYPE_NONE; 633 s = (CgApiState*)c->cg_api; 634 memset(&probe, 0, sizeof probe); 635 probe.cg.kind = KIT_CG_TYPE_FUNC; 636 probe.cg.func.nparams = sig.nparams; 637 probe.cg.func.abi_variadic = sig.abi_variadic != 0; 638 probe.cg.func.call_conv = sig.call_conv; 639 probe.cg.func.result = sig.result; 640 probe.cg.func.params = sig.params; 641 hit = CgFuncSet_find(&s->func_index, &probe); 642 return hit ? hit->self_id : KIT_CG_TYPE_NONE; 643 } 644 645 static CgApiType* api_type_from_id(Compiler* c, KitCgTypeId id) { 646 u32 index; 647 CgApiState* s; 648 CgApiType* e; 649 if (!c || id == KIT_CG_TYPE_NONE) return NULL; 650 if (!decode_user_id(id, &index)) return NULL; 651 s = (CgApiState*)c->cg_api; 652 if (!s) return NULL; 653 e = CgApiTypes_at(&s->types, index); 654 return e; 655 } 656 657 KitCgTypeId resolve_type(Compiler* c, KitCgTypeId id) { 658 if (!c || id == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 659 if (id <= KIT_CG_BUILTIN_COUNT) return id; 660 return api_type_from_id(c, id) ? id : KIT_CG_TYPE_NONE; 661 } 662 663 /* Fill an entry's identity prefix (the kit/cg.h KitCgTypeInfo) once. Identity 664 * is immutable after creation, so this runs at most once per entry 665 * (info.id != 0 thereafter). */ 666 static void api_type_info_fill(Compiler* c, CgApiType* e, KitCgTypeId id) { 667 (void)c; 668 e->info.id = id; 669 e->info.kind = e->cg.kind; 670 if (e->cg.kind == KIT_CG_TYPE_RECORD || e->cg.kind == KIT_CG_TYPE_ENUM) 671 e->info.flags = KIT_CG_TYPEF_NOMINAL; 672 e->info.storage_id = id; 673 } 674 675 /* The CgApiType for a user id with its identity prefix filled, or NULL. */ 676 static CgApiType* api_type_entry_filled(Compiler* c, KitCgTypeId id) { 677 CgApiType* e = api_type_from_id(c, id); 678 if (!e) return NULL; 679 if (e->info.id == 0) api_type_info_fill(c, e, id); 680 return e; 681 } 682 683 static KitCgFuncParam* copy_cg_params(Compiler* c, const KitCgFuncParam* src, 684 u32 n) { 685 KitCgFuncParam* dst; 686 if (!n) return NULL; 687 if (!src) return NULL; 688 dst = arena_array(&c->global->arena, KitCgFuncParam, n); 689 if (!dst) return NULL; 690 memcpy(dst, src, sizeof(*dst) * n); 691 return dst; 692 } 693 694 static CgTypeField* copy_cg_fields(Compiler* c, const KitCgFieldDesc* src, 695 u32 n) { 696 CgTypeField* dst; 697 if (!n) return NULL; 698 if (!src) return NULL; 699 dst = arena_array(&c->global->arena, CgTypeField, n); 700 if (!dst) return NULL; 701 memset(dst, 0, sizeof(*dst) * n); 702 for (u32 i = 0; i < n; ++i) { 703 dst[i].name = src[i].name; 704 dst[i].type = src[i].type; 705 dst[i].align_override = src[i].align_override; 706 dst[i].max_align = src[i].max_align; 707 dst[i].flags = src[i].flags; 708 dst[i].bit_width = src[i].bit_width; 709 dst[i].bit_signed = src[i].bit_signed != 0; 710 } 711 return dst; 712 } 713 714 static int cg_type_record_complete(const CgType* ty) { 715 return ty && ty->kind == KIT_CG_TYPE_RECORD && 716 (ty->record.flags & CG_TYPE_RECORD_COMPLETE) != 0; 717 } 718 719 static int cg_type_complete_id(Compiler* c, KitCgTypeId id) { 720 const CgType* ty = cg_type_get(c, id); 721 if (!ty) return 0; 722 switch (ty->kind) { 723 case KIT_CG_TYPE_ARRAY: 724 return cg_type_complete_id(c, ty->array.elem); 725 case KIT_CG_TYPE_RECORD: 726 return cg_type_record_complete(ty); 727 default: 728 return 1; 729 } 730 } 731 732 static int cg_type_sized_id(Compiler* c, KitCgTypeId id) { 733 ABITypeInfo ti; 734 const CgType* ty; 735 ty = cg_type_get(c, id); 736 if (!ty) return 0; 737 switch (ty->kind) { 738 case KIT_CG_TYPE_VOID: 739 return 0; 740 case KIT_CG_TYPE_FUNC: 741 return 0; 742 case KIT_CG_TYPE_RECORD: 743 if (!cg_type_record_complete(ty)) return 0; 744 break; 745 case KIT_CG_TYPE_ARRAY: 746 if (!cg_type_sized_id(c, ty->array.elem)) return 0; 747 break; 748 default: 749 break; 750 } 751 ti = abi_cg_type_info(c->abi, id); 752 return ti.align != 0; 753 } 754 755 static int cg_type_valid_by_value(Compiler* c, KitCgTypeId id) { 756 const CgType* ty = cg_type_get(c, id); 757 if (!ty) return 0; 758 if (ty->kind == KIT_CG_TYPE_VOID || ty->kind == KIT_CG_TYPE_FUNC) return 0; 759 return cg_type_sized_id(c, id); 760 } 761 762 static int cg_type_contains_by_value(Compiler* c, KitCgTypeId id, 763 KitCgTypeId needle) { 764 const CgType* ty; 765 if (!id) return 0; 766 if (id == needle) return 1; 767 ty = cg_type_get(c, id); 768 if (!ty) return 0; 769 switch (ty->kind) { 770 case KIT_CG_TYPE_ARRAY: 771 return cg_type_contains_by_value(c, ty->array.elem, needle); 772 case KIT_CG_TYPE_RECORD: 773 if (!cg_type_record_complete(ty)) return 0; 774 for (u32 i = 0; i < ty->record.nfields; ++i) { 775 if (cg_type_contains_by_value(c, ty->record.fields[i].type, needle)) 776 return 1; 777 } 778 return 0; 779 default: 780 return 0; 781 } 782 } 783 784 static int cg_type_layout_record(Compiler* c, CgType* cg) { 785 u32 max_align = 1; 786 u64 size = 0; 787 if (!c || !cg || cg->kind != KIT_CG_TYPE_RECORD) return 0; 788 if (cg->record.nfields && !cg->record.fields) return 0; 789 if (cg->record.is_union) { 790 for (u32 i = 0; i < cg->record.nfields; ++i) { 791 CgTypeField* f = &cg->record.fields[i]; 792 u64 fsize = cg_type_size(c, f->type); 793 u32 falign = cg_type_align(c, f->type); 794 if (!falign) return 0; 795 if (f->max_align && falign > f->max_align) falign = f->max_align; 796 if (f->align_override == 1u) { 797 falign = 1; 798 } else if (f->align_override > falign) { 799 falign = f->align_override; 800 } 801 if (falign > max_align) max_align = falign; 802 if ((f->flags & KIT_CG_FIELD_BITFIELD) != 0) { 803 f->offset = 0; 804 f->bit_offset = 0; 805 f->bit_storage_size = (u32)fsize; 806 if (f->bit_width == 0) continue; 807 } 808 if (fsize > size) size = fsize; 809 f->offset = 0; 810 } 811 } else { 812 u64 off = 0; 813 int active_bitfield_unit = 0; 814 u64 unit_off = 0; 815 u32 unit_bits = 0; 816 u32 unit_size = 0; 817 u32 next_bit = 0; 818 for (u32 i = 0; i < cg->record.nfields; ++i) { 819 CgTypeField* f = &cg->record.fields[i]; 820 u64 fsize = cg_type_size(c, f->type); 821 u32 falign = cg_type_align(c, f->type); 822 if (!falign) return 0; 823 if (f->max_align && falign > f->max_align) falign = f->max_align; 824 if (f->align_override == 1u) { 825 falign = 1; 826 } else if (f->align_override > falign) { 827 falign = f->align_override; 828 } 829 if (falign > max_align) max_align = falign; 830 if ((f->flags & KIT_CG_FIELD_BITFIELD) != 0) { 831 if (fsize > UINT32_MAX / 8u) return 0; 832 if (f->bit_width == 0) { 833 if (active_bitfield_unit) off = unit_off + unit_size; 834 off = cg_align_to(off, falign); 835 f->offset = off; 836 f->bit_offset = 0; 837 f->bit_storage_size = (u32)fsize; 838 active_bitfield_unit = 0; 839 next_bit = 0; 840 continue; 841 } 842 if (f->bit_width > fsize * 8u) return 0; 843 if (!active_bitfield_unit || unit_size != (u32)fsize || 844 next_bit + f->bit_width > unit_bits) { 845 if (active_bitfield_unit) off = unit_off + unit_size; 846 off = cg_align_to(off, falign); 847 unit_off = off; 848 unit_size = (u32)fsize; 849 unit_bits = unit_size * 8u; 850 next_bit = 0; 851 active_bitfield_unit = 1; 852 } 853 f->offset = unit_off; 854 f->bit_offset = (u16)next_bit; 855 f->bit_storage_size = unit_size; 856 next_bit += f->bit_width; 857 off = unit_off + unit_size; 858 continue; 859 } 860 active_bitfield_unit = 0; 861 off = cg_align_to(off, falign); 862 f->offset = off; 863 off += fsize; 864 } 865 size = off; 866 } 867 if (cg->record.align_override > max_align) { 868 max_align = cg->record.align_override; 869 } 870 cg->align = max_align; 871 cg->size = cg_align_to(size, max_align); 872 return 1; 873 } 874 875 static int cg_type_set_ptr(Compiler* c, CgApiType* e, KitCgTypeId pointee, 876 u32 address_space) { 877 u32 ptr_size; 878 u32 ptr_align; 879 if (!cg_type_get(c, pointee)) return 0; 880 memset(&e->cg, 0, sizeof(e->cg)); 881 ptr_size = c->target.ptr_size ? c->target.ptr_size : 8; 882 ptr_align = c->target.ptr_align ? c->target.ptr_align : ptr_size; 883 e->cg.kind = KIT_CG_TYPE_PTR; 884 e->cg.size = ptr_size; 885 e->cg.align = ptr_align; 886 e->cg.ptr.pointee = pointee; 887 e->cg.ptr.address_space = address_space; 888 return 1; 889 } 890 891 static int cg_type_set_array(Compiler* c, CgApiType* e, KitCgTypeId elem, 892 u64 count) { 893 ABITypeInfo ety; 894 if (!cg_type_sized_id(c, elem)) return 0; 895 ety = abi_cg_type_info(c->abi, elem); 896 if (ety.size && count > UINT32_MAX / ety.size) return 0; 897 memset(&e->cg, 0, sizeof(e->cg)); 898 e->cg.kind = KIT_CG_TYPE_ARRAY; 899 e->cg.size = (u64)ety.size * count; 900 e->cg.align = ety.align; 901 e->cg.array.elem = elem; 902 e->cg.array.count = count; 903 return 1; 904 } 905 906 static int cg_type_set_record(Compiler* c, CgApiType* e, KitSym tag, 907 const KitCgFieldDesc* fields, u32 nfields, 908 int is_union, u32 align_override, u32 flags) { 909 CgTypeField* copied = copy_cg_fields(c, fields, nfields); 910 if (nfields && !copied) return 0; 911 memset(&e->cg, 0, sizeof(e->cg)); 912 e->cg.kind = KIT_CG_TYPE_RECORD; 913 e->cg.record.tag = tag; 914 e->cg.record.fields = copied; 915 e->cg.record.nfields = nfields; 916 e->cg.record.is_union = is_union != 0; 917 e->cg.record.align_override = align_override; 918 e->cg.record.flags = flags; 919 return cg_type_layout_record(c, &e->cg); 920 } 921 922 static int cg_type_set_enum(Compiler* c, CgApiType* e, KitSym tag, 923 KitCgTypeId base, KitCgEnumValue* values, 924 u32 nvalues) { 925 const CgType* sty; 926 ABITypeInfo ti; 927 if (base == KIT_CG_TYPE_NONE) base = builtin_id(KIT_CG_BUILTIN_I32); 928 sty = cg_type_get(c, base); 929 if (!sty || 930 !(sty->kind == KIT_CG_TYPE_INT || sty->kind == KIT_CG_TYPE_BOOL)) { 931 return 0; 932 } 933 ti = abi_cg_type_info(c->abi, base); 934 memset(&e->cg, 0, sizeof(e->cg)); 935 e->cg.kind = KIT_CG_TYPE_ENUM; 936 e->cg.size = ti.size; 937 e->cg.align = ti.align; 938 e->cg.enum_.tag = tag; 939 e->cg.enum_.base = base; 940 e->cg.enum_.values = values; 941 e->cg.enum_.nvalues = nvalues; 942 return 1; 943 } 944 945 static int cg_type_set_func(Compiler* c, CgApiType* e, KitCgFuncSig sig, 946 KitCgFuncParam* params) { 947 KitCgTypeId void_ty = builtin_id(KIT_CG_BUILTIN_VOID); 948 if (!sig.result.type || !cg_type_get(c, sig.result.type)) return 0; 949 if (sig.result.type != void_ty && !cg_type_valid_by_value(c, sig.result.type)) 950 return 0; 951 for (u32 i = 0; i < sig.nparams; ++i) { 952 if (!cg_type_valid_by_value(c, sig.params[i].type)) return 0; 953 } 954 memset(&e->cg, 0, sizeof(e->cg)); 955 e->cg.kind = KIT_CG_TYPE_FUNC; 956 e->cg.size = 1; 957 e->cg.align = 1; 958 e->cg.func.result = sig.result; 959 e->cg.func.params = params; 960 e->cg.func.nparams = sig.nparams; 961 e->cg.func.call_conv = sig.call_conv; 962 e->cg.func.abi_variadic = sig.abi_variadic != 0; 963 return 1; 964 } 965 966 KitCgTypeId kit_cg_type_builtin(KitCompiler* c, KitCgBuiltinType which) { 967 (void)c; 968 if ((u32)which >= KIT_CG_BUILTIN_COUNT) return KIT_CG_TYPE_NONE; 969 return builtin_id(which); 970 } 971 972 KitCgTypeId kit_cg_type_ptr(KitCompiler* c, KitCgTypeId pointee, 973 uint32_t address_space) { 974 KitCgTypeId id; 975 CgApiType* e; 976 if (!cg_type_get(c, pointee)) return KIT_CG_TYPE_NONE; 977 id = find_ptr_type_id(c, pointee, address_space); 978 if (id != KIT_CG_TYPE_NONE) return id; 979 e = type_alloc(c, &id); 980 if (!e) return KIT_CG_TYPE_NONE; 981 if (!cg_type_set_ptr(c, e, pointee, address_space)) { 982 return KIT_CG_TYPE_NONE; 983 } 984 CgPtrMap_set(&((CgApiState*)c->cg_api)->ptr_index, 985 cg_ptr_key(pointee, address_space), id); 986 return id; 987 } 988 989 KitCgTypeId kit_cg_type_array(KitCompiler* c, KitCgTypeId elem, 990 uint64_t count) { 991 KitCgTypeId id; 992 CgApiType* e; 993 if (!cg_type_sized_id(c, elem)) return KIT_CG_TYPE_NONE; 994 id = find_array_type_id(c, elem, count); 995 if (id != KIT_CG_TYPE_NONE) return id; 996 e = type_alloc(c, &id); 997 if (!e) return KIT_CG_TYPE_NONE; 998 if (!cg_type_set_array(c, e, elem, count)) { 999 return KIT_CG_TYPE_NONE; 1000 } 1001 CgArraySet_add(&((CgApiState*)c->cg_api)->array_index, e); 1002 return id; 1003 } 1004 1005 KitCgTypeId kit_cg_type_record_decl(KitCompiler* c, KitSym tag, int is_union) { 1006 KitCgTypeId id; 1007 CgApiType* e; 1008 if (!c) return KIT_CG_TYPE_NONE; 1009 e = type_alloc(c, &id); 1010 if (!e) return KIT_CG_TYPE_NONE; 1011 memset(&e->cg, 0, sizeof(e->cg)); 1012 e->cg.kind = KIT_CG_TYPE_RECORD; 1013 e->cg.record.tag = tag; 1014 e->cg.record.is_union = is_union != 0; 1015 return id; 1016 } 1017 1018 KitStatus kit_cg_type_record_complete(KitCompiler* c, KitCgTypeId record, 1019 const KitCgRecordDesc* desc) { 1020 CgApiType* e; 1021 KitSym tag; 1022 if (!c || !desc || (desc->nfields && !desc->fields) || 1023 desc->nfields > UINT16_MAX) { 1024 return KIT_INVALID; 1025 } 1026 e = api_type_from_id(c, record); 1027 if (!e || e->cg.kind != KIT_CG_TYPE_RECORD) return KIT_INVALID; 1028 if (e->cg.record.flags & CG_TYPE_RECORD_COMPLETE) return KIT_INVALID; 1029 if (e->cg.record.is_union != (desc->is_union != 0)) return KIT_INVALID; 1030 1031 for (u32 i = 0; i < desc->nfields; ++i) { 1032 KitCgTypeId fty = desc->fields[i].type; 1033 if (!cg_type_valid_by_value(c, fty)) return KIT_INVALID; 1034 if (cg_type_contains_by_value(c, fty, record)) return KIT_INVALID; 1035 } 1036 1037 tag = desc->tag ? desc->tag : e->cg.record.tag; 1038 if (!cg_type_set_record(c, e, tag, desc->fields, desc->nfields, 1039 desc->is_union, desc->align_override, 1040 CG_TYPE_RECORD_COMPLETE)) { 1041 return KIT_INVALID; 1042 } 1043 return KIT_OK; 1044 } 1045 1046 KitCgTypeId kit_cg_type_enum(KitCompiler* c, KitSym tag, KitCgTypeId base, 1047 const KitCgEnumValue* values, uint32_t nvalues) { 1048 KitCgEnumValue* copied = NULL; 1049 KitCgTypeId id; 1050 CgApiType* e; 1051 if (!c || (nvalues && !values)) return KIT_CG_TYPE_NONE; 1052 if (base == KIT_CG_TYPE_NONE) base = builtin_id(KIT_CG_BUILTIN_I32); 1053 if (!cg_type_is_int(c, base)) return KIT_CG_TYPE_NONE; 1054 if (nvalues) { 1055 copied = arena_array(&c->global->arena, KitCgEnumValue, nvalues); 1056 if (!copied) return KIT_CG_TYPE_NONE; 1057 memcpy(copied, values, sizeof(*copied) * nvalues); 1058 } 1059 e = type_alloc(c, &id); 1060 if (!e) return KIT_CG_TYPE_NONE; 1061 if (!cg_type_set_enum(c, e, tag, base, copied, nvalues)) { 1062 return KIT_CG_TYPE_NONE; 1063 } 1064 return id; 1065 } 1066 1067 KitCgTypeId kit_cg_type_func(KitCompiler* c, KitCgFuncSig sig) { 1068 KitCgFuncParam* copied = NULL; 1069 KitCgTypeId id; 1070 CgApiType* e; 1071 if (!c || (sig.nparams && !sig.params) || sig.nparams > UINT16_MAX) { 1072 return KIT_CG_TYPE_NONE; 1073 } 1074 if (!sig.result.type || !cg_type_get(c, sig.result.type)) 1075 return KIT_CG_TYPE_NONE; 1076 if (sig.result.type != builtin_id(KIT_CG_BUILTIN_VOID) && 1077 !cg_type_valid_by_value(c, sig.result.type)) 1078 return KIT_CG_TYPE_NONE; 1079 for (u32 i = 0; i < sig.nparams; ++i) { 1080 if (!cg_type_valid_by_value(c, sig.params[i].type)) return KIT_CG_TYPE_NONE; 1081 } 1082 id = find_func_type_id(c, sig); 1083 if (id != KIT_CG_TYPE_NONE) return id; 1084 if (sig.nparams) { 1085 copied = copy_cg_params(c, sig.params, sig.nparams); 1086 if (!copied) return KIT_CG_TYPE_NONE; 1087 } 1088 e = type_alloc(c, &id); 1089 if (!e) return KIT_CG_TYPE_NONE; 1090 if (!cg_type_set_func(c, e, sig, copied)) { 1091 return KIT_CG_TYPE_NONE; 1092 } 1093 CgFuncSet_add(&((CgApiState*)c->cg_api)->func_index, e); 1094 return id; 1095 } 1096 1097 uint64_t kit_cg_type_size(KitCompiler* c, KitCgTypeId id) { 1098 return cg_type_size(c, id); 1099 } 1100 1101 uint32_t kit_cg_type_align(KitCompiler* c, KitCgTypeId id) { 1102 return cg_type_align(c, id); 1103 } 1104 1105 /* Identity view backing the inline kit_cg_type_{kind,resolve_alias,is_void} and 1106 * kit_cg_func_result_has_value queries in kit/cg.h. Builtins read the 1107 * precomputed table; user entries fill their identity prefix once (immutable 1108 * thereafter: kind and storage identity are stable, NOMINAL is fixed at 1109 * creation), then hand back the entry's first member. Layout and the 1110 * COMPLETE/SIZED flags are deliberately left to kit_cg_type_info. */ 1111 const KitCgTypeInfo* kit_cg_type_view(KitCompiler* kc, KitCgTypeId id) { 1112 Compiler* c = (Compiler*)kc; 1113 CgApiState* s; 1114 CgApiType* e; 1115 if (!c || id == KIT_CG_TYPE_NONE) return NULL; 1116 s = c->cg_api ? (CgApiState*)c->cg_api : cg_api_get(c); 1117 if (!s) return NULL; 1118 if (id <= KIT_CG_BUILTIN_COUNT) return &s->builtin_info[id - 1u]; 1119 e = api_type_entry_filled(c, id); 1120 return e ? &e->info : NULL; 1121 } 1122 1123 int kit_cg_type_is_complete(KitCompiler* c, KitCgTypeId id) { 1124 return cg_type_complete_id(c, id); 1125 } 1126 1127 int kit_cg_type_is_sized(KitCompiler* c, KitCgTypeId id) { 1128 return cg_type_sized_id(c, id); 1129 } 1130 1131 static KitCgStorageKind cg_storage_kind_from_abi(const CgType* ty, 1132 ABITypeInfo ti) { 1133 switch ((ABIScalarKind)ti.scalar_kind) { 1134 case ABI_SC_VOID: 1135 if (ty && 1136 (ty->kind == KIT_CG_TYPE_ARRAY || ty->kind == KIT_CG_TYPE_RECORD)) 1137 return KIT_CG_STORAGE_AGGREGATE; 1138 return KIT_CG_STORAGE_VOID; 1139 case ABI_SC_BOOL: 1140 return KIT_CG_STORAGE_BOOL; 1141 case ABI_SC_INT: 1142 return KIT_CG_STORAGE_INT; 1143 case ABI_SC_FLOAT: 1144 return KIT_CG_STORAGE_FLOAT; 1145 case ABI_SC_PTR: 1146 return KIT_CG_STORAGE_PTR; 1147 } 1148 return KIT_CG_STORAGE_VOID; 1149 } 1150 1151 static uint16_t cg_type_scalar_width(Compiler* c, const CgType* ty) { 1152 if (!ty) return 0; 1153 switch (ty->kind) { 1154 case KIT_CG_TYPE_BOOL: 1155 case KIT_CG_TYPE_INT: 1156 return (uint16_t)ty->integer.width; 1157 case KIT_CG_TYPE_FLOAT: 1158 return (uint16_t)ty->fp.width; 1159 case KIT_CG_TYPE_ENUM: 1160 return (uint16_t)kit_cg_type_int_width((KitCompiler*)c, ty->enum_.base); 1161 default: 1162 return 0; 1163 } 1164 } 1165 1166 KitStatus kit_cg_type_info(KitCompiler* kc, KitCgTypeId id, 1167 KitCgTypeInfo* out) { 1168 Compiler* c = (Compiler*)kc; 1169 const KitCgTypeInfo* v; 1170 const CgType* storage; 1171 ABITypeInfo ti; 1172 if (!out) return KIT_INVALID; 1173 v = kit_cg_type_view(kc, id); 1174 if (!v) { 1175 memset(out, 0, sizeof(*out)); 1176 return KIT_INVALID; 1177 } 1178 storage = cg_type_get(c, v->storage_id); 1179 if (!storage) { 1180 memset(out, 0, sizeof(*out)); 1181 return KIT_INVALID; 1182 } 1183 1184 /* Identity (id/storage_id/kind and the BUILTIN/NOMINAL flags) comes straight 1185 * from the view's interned prefix; only the completion/sizing flags and the 1186 * ABI layout are computed per call (they are not maintained on the view). */ 1187 *out = *v; 1188 if (cg_type_complete_id(c, id)) out->flags |= KIT_CG_TYPEF_COMPLETE; 1189 if (cg_type_sized_id(c, id)) out->flags |= KIT_CG_TYPEF_SIZED; 1190 1191 ti = abi_cg_type_info(c->abi, v->storage_id); 1192 if (ti.align || storage->kind == KIT_CG_TYPE_VOID) { 1193 out->layout.size = ti.size; 1194 out->layout.align = ti.align; 1195 out->layout.scalar_width = cg_type_scalar_width(c, storage); 1196 out->layout.storage_kind = (uint8_t)cg_storage_kind_from_abi(storage, ti); 1197 out->layout.valid = 1; 1198 } 1199 return KIT_OK; 1200 } 1201 1202 static int cg_type_same_storage_rec(Compiler* c, KitCgTypeId a, KitCgTypeId b) { 1203 const CgType* ta; 1204 const CgType* tb; 1205 if (!a || !b) return 0; 1206 if (a == b) return 1; 1207 ta = cg_type_get(c, a); 1208 tb = cg_type_get(c, b); 1209 if (!ta || !tb) return 0; 1210 if (ta->kind == KIT_CG_TYPE_ENUM) 1211 return cg_type_same_storage_rec(c, ta->enum_.base, b); 1212 if (tb->kind == KIT_CG_TYPE_ENUM) 1213 return cg_type_same_storage_rec(c, a, tb->enum_.base); 1214 if (ta->kind != tb->kind) return 0; 1215 switch (ta->kind) { 1216 case KIT_CG_TYPE_VOID: 1217 case KIT_CG_TYPE_BOOL: 1218 case KIT_CG_TYPE_INT: 1219 case KIT_CG_TYPE_FLOAT: { 1220 ABITypeInfo ai = abi_cg_type_info(c->abi, a); 1221 ABITypeInfo bi = abi_cg_type_info(c->abi, b); 1222 return ai.scalar_kind == bi.scalar_kind && ai.size == bi.size && 1223 ai.align == bi.align; 1224 } 1225 case KIT_CG_TYPE_PTR: 1226 return ta->ptr.address_space == tb->ptr.address_space && 1227 cg_type_same_storage_rec(c, ta->ptr.pointee, tb->ptr.pointee); 1228 case KIT_CG_TYPE_ARRAY: 1229 return ta->array.count == tb->array.count && 1230 cg_type_same_storage_rec(c, ta->array.elem, tb->array.elem); 1231 case KIT_CG_TYPE_FUNC: 1232 if (ta->func.nparams != tb->func.nparams || 1233 ta->func.call_conv != tb->func.call_conv || 1234 ta->func.abi_variadic != tb->func.abi_variadic || 1235 memcmp(&ta->func.result.attrs, &tb->func.result.attrs, 1236 sizeof(ta->func.result.attrs)) != 0) 1237 return 0; 1238 if (!cg_type_same_storage_rec(c, ta->func.result.type, 1239 tb->func.result.type)) 1240 return 0; 1241 for (u32 i = 0; i < ta->func.nparams; ++i) { 1242 if (memcmp(&ta->func.params[i].attrs, &tb->func.params[i].attrs, 1243 sizeof(ta->func.params[i].attrs)) != 0) 1244 return 0; 1245 if (!cg_type_same_storage_rec(c, ta->func.params[i].type, 1246 tb->func.params[i].type)) 1247 return 0; 1248 } 1249 return 1; 1250 case KIT_CG_TYPE_RECORD: 1251 return 0; 1252 case KIT_CG_TYPE_ENUM: 1253 return 0; 1254 case KIT_CG_TYPE_VARARG_STATE: { 1255 ABITypeInfo ai = abi_cg_type_info(c->abi, a); 1256 ABITypeInfo bi = abi_cg_type_info(c->abi, b); 1257 return ai.size == bi.size && ai.align == bi.align; 1258 } 1259 } 1260 return 0; 1261 } 1262 1263 int kit_cg_type_same_storage(KitCompiler* c, KitCgTypeId a, KitCgTypeId b) { 1264 return cg_type_same_storage_rec((Compiler*)c, a, b); 1265 } 1266 1267 uint32_t kit_cg_type_int_width(KitCompiler* c, KitCgTypeId id) { 1268 const CgType* ty = cg_type_get(c, id); 1269 if (!ty) return 0; 1270 if (ty->kind == KIT_CG_TYPE_INT || ty->kind == KIT_CG_TYPE_BOOL) { 1271 return ty->integer.width; 1272 } 1273 if (ty->kind == KIT_CG_TYPE_ENUM) { 1274 return kit_cg_type_int_width(c, ty->enum_.base); 1275 } 1276 return 0; 1277 } 1278 1279 uint32_t kit_cg_type_float_width(KitCompiler* c, KitCgTypeId id) { 1280 const CgType* ty = cg_type_get(c, id); 1281 if (!ty) return 0; 1282 if (ty->kind == KIT_CG_TYPE_FLOAT) return ty->fp.width; 1283 return 0; 1284 } 1285 1286 KitCgTypeId kit_cg_type_ptr_pointee(KitCompiler* c, KitCgTypeId id) { 1287 const CgType* ty = cg_type_get(c, id); 1288 return (ty && ty->kind == KIT_CG_TYPE_PTR) ? ty->ptr.pointee 1289 : KIT_CG_TYPE_NONE; 1290 } 1291 1292 KitCgTypeId kit_cg_type_array_elem(KitCompiler* c, KitCgTypeId id) { 1293 const CgType* ty = cg_type_get(c, id); 1294 return (ty && ty->kind == KIT_CG_TYPE_ARRAY) ? ty->array.elem 1295 : KIT_CG_TYPE_NONE; 1296 } 1297 1298 uint32_t kit_cg_type_ptr_address_space(KitCompiler* c, KitCgTypeId id) { 1299 const CgType* ty = cg_type_get(c, id); 1300 return (ty && ty->kind == KIT_CG_TYPE_PTR) ? ty->ptr.address_space : 0u; 1301 } 1302 1303 uint64_t kit_cg_type_array_count(KitCompiler* c, KitCgTypeId id) { 1304 const CgType* ty = cg_type_get(c, id); 1305 return (ty && ty->kind == KIT_CG_TYPE_ARRAY) ? ty->array.count : 0u; 1306 } 1307 1308 KitCgFuncResult kit_cg_type_func_result(KitCompiler* c, KitCgTypeId id) { 1309 const CgType* ty = cg_type_get(c, id); 1310 KitCgFuncResult empty; 1311 memset(&empty, 0, sizeof(empty)); 1312 if (!ty || ty->kind != KIT_CG_TYPE_FUNC) return empty; 1313 return ty->func.result; 1314 } 1315 1316 uint32_t kit_cg_type_func_nparams(KitCompiler* c, KitCgTypeId id) { 1317 const CgType* ty = cg_type_get(c, id); 1318 return (ty && ty->kind == KIT_CG_TYPE_FUNC) ? ty->func.nparams : 0; 1319 } 1320 1321 KitCgFuncParam kit_cg_type_func_param(KitCompiler* c, KitCgTypeId id, 1322 uint32_t index) { 1323 const CgType* ty = cg_type_get(c, id); 1324 KitCgFuncParam empty; 1325 memset(&empty, 0, sizeof(empty)); 1326 if (!ty || ty->kind != KIT_CG_TYPE_FUNC || index >= ty->func.nparams) { 1327 return empty; 1328 } 1329 return ty->func.params[index]; 1330 } 1331 1332 KitCgCallConv kit_cg_type_func_call_conv(KitCompiler* c, KitCgTypeId id) { 1333 const CgType* ty = cg_type_get(c, id); 1334 return (ty && ty->kind == KIT_CG_TYPE_FUNC) ? ty->func.call_conv 1335 : KIT_CG_CC_TARGET_C; 1336 } 1337 1338 int kit_cg_type_func_is_variadic(KitCompiler* c, KitCgTypeId id) { 1339 const CgType* ty = cg_type_get(c, id); 1340 return ty && ty->kind == KIT_CG_TYPE_FUNC && ty->func.abi_variadic; 1341 } 1342 1343 KitSym kit_cg_type_record_tag(KitCompiler* c, KitCgTypeId id) { 1344 const CgType* ty = cg_type_get(c, id); 1345 return (ty && ty->kind == KIT_CG_TYPE_RECORD) ? ty->record.tag : 0; 1346 } 1347 1348 int kit_cg_type_record_is_union(KitCompiler* c, KitCgTypeId id) { 1349 const CgType* ty = cg_type_get(c, id); 1350 return ty && ty->kind == KIT_CG_TYPE_RECORD && ty->record.is_union; 1351 } 1352 1353 uint32_t kit_cg_type_record_nfields(KitCompiler* c, KitCgTypeId id) { 1354 const CgType* ty = cg_type_get(c, id); 1355 return (ty && ty->kind == KIT_CG_TYPE_RECORD && cg_type_record_complete(ty)) 1356 ? ty->record.nfields 1357 : 0; 1358 } 1359 1360 const KitCgRecordLayout* kit_cg_type_record_layout(KitCompiler* c, 1361 KitCgTypeId id) { 1362 CgApiType* e; 1363 CgType* ty; 1364 KitCgRecordLayout* view; 1365 KitCgFieldLayout* fields; 1366 u32 n; 1367 e = api_type_from_id(c, id); 1368 if (!e || e->cg.kind != KIT_CG_TYPE_RECORD) return NULL; 1369 ty = &e->cg; 1370 if (!cg_type_record_complete(ty)) return NULL; 1371 /* Force/confirm sizing through the same path size/align queries use; an 1372 * unsized record (e.g. a field that never sized) has no borrowable layout. */ 1373 if (!cg_type_sized_id(c, id)) return NULL; 1374 if (ty->record.layout_view) return ty->record.layout_view; 1375 1376 n = ty->record.nfields; 1377 view = arena_new(&c->global->arena, KitCgRecordLayout); 1378 if (!view) return NULL; 1379 fields = n ? arena_array(&c->global->arena, KitCgFieldLayout, n) : NULL; 1380 if (n && !fields) return NULL; 1381 for (u32 i = 0; i < n; ++i) { 1382 const CgTypeField* f = &ty->record.fields[i]; 1383 fields[i].name = f->name; 1384 fields[i].type = f->type; 1385 fields[i].offset = f->offset; 1386 fields[i].flags = f->flags; 1387 fields[i].bit_storage_size = f->bit_storage_size; 1388 fields[i].bit_offset = f->bit_offset; 1389 fields[i].bit_width = f->bit_width; 1390 fields[i].bit_signed = f->bit_signed; 1391 } 1392 view->size = ty->size; 1393 view->align = ty->align; 1394 view->nfields = n; 1395 view->fields = fields; 1396 ty->record.layout_view = view; 1397 return view; 1398 } 1399 1400 KitSym kit_cg_type_enum_tag(KitCompiler* c, KitCgTypeId id) { 1401 const CgType* ty = cg_type_get(c, id); 1402 return (ty && ty->kind == KIT_CG_TYPE_ENUM) ? ty->enum_.tag : 0; 1403 } 1404 1405 KitCgTypeId kit_cg_type_enum_base(KitCompiler* c, KitCgTypeId id) { 1406 const CgType* ty = cg_type_get(c, id); 1407 return (ty && ty->kind == KIT_CG_TYPE_ENUM) ? ty->enum_.base 1408 : KIT_CG_TYPE_NONE; 1409 } 1410 1411 uint32_t kit_cg_type_enum_nvalues(KitCompiler* c, KitCgTypeId id) { 1412 const CgType* ty = cg_type_get(c, id); 1413 return (ty && ty->kind == KIT_CG_TYPE_ENUM) ? ty->enum_.nvalues : 0; 1414 } 1415 1416 KitStatus kit_cg_type_enum_value(KitCompiler* c, KitCgTypeId id, uint32_t index, 1417 KitCgEnumValue* out) { 1418 const CgType* ty = cg_type_get(c, id); 1419 if (!ty || ty->kind != KIT_CG_TYPE_ENUM || index >= ty->enum_.nvalues) 1420 return KIT_NOT_FOUND; 1421 if (out) *out = ty->enum_.values[index]; 1422 return KIT_OK; 1423 } 1424 1425 int kit_cg_target_supports_call_conv(KitCompiler* c, KitCgCallConv cc) { 1426 const ArchImpl* a; 1427 if (!c) return 0; 1428 /* TARGET_C is always available, including for arches with no codegen backend 1429 * (x86_32/arm_32, where arch_for_compiler is NULL). */ 1430 if (cc == KIT_CG_CC_TARGET_C) return 1; 1431 a = arch_for_compiler(c); 1432 if (!a || !a->supports_call_conv) return 0; 1433 return a->supports_call_conv(c, cc); 1434 } 1435 1436 int kit_cg_target_supports_symbol_feature(KitCompiler* c, 1437 KitCgSymbolFeature feat) { 1438 if (!c) return 0; 1439 switch (feat) { 1440 case KIT_CG_SYMFEAT_WEAK: 1441 case KIT_CG_SYMFEAT_PROTECTED_VISIBILITY: 1442 case KIT_CG_SYMFEAT_COMDAT: 1443 case KIT_CG_SYMFEAT_COMMON: 1444 return 1; 1445 case KIT_CG_SYMFEAT_TLS_LOCAL_EXEC: 1446 /* Local-exec is the only TLS model kit emits. Whether it is actually 1447 * available still depends on the object format being able to represent a 1448 * TLS access at all (ELF/Mach-O yes; COFF/Wasm no). */ 1449 return obj_format_supports_symbol_feature(c, (int)feat); 1450 case KIT_CG_SYMFEAT_TLS_INITIAL_EXEC: 1451 case KIT_CG_SYMFEAT_TLS_LOCAL_DYNAMIC: 1452 case KIT_CG_SYMFEAT_TLS_GENERAL_DYNAMIC: 1453 /* kit has no initial-exec / local-dynamic / general-dynamic codegen and 1454 * no dynamic-TLS runtime (__tls_get_addr), so it never emits these even 1455 * where the object format could represent them. Report the truth so a 1456 * caller can't request a dynamic model and silently get local-exec; the 1457 * linker enforces the same contract (see link_require_local_tls). */ 1458 return 0; 1459 case KIT_CG_SYMFEAT_DLLIMPORT: 1460 case KIT_CG_SYMFEAT_DLLEXPORT: 1461 case KIT_CG_SYMFEAT_MERGE_SECTIONS: 1462 case KIT_CG_SYMFEAT_CONSTRUCTOR_PRIORITY: 1463 return 0; 1464 } 1465 return 0; 1466 } 1467 1468 KitCgVaListKind kit_cg_target_va_list_kind(const KitCompiler* c) { 1469 ABIVaListInfo va; 1470 if (!c) return KIT_CG_VALIST_OPAQUE; 1471 va = abi_va_list_layout(c->abi); 1472 switch ((ABIVaListKind)va.kind) { 1473 case ABI_VA_LIST_OPAQUE: 1474 return KIT_CG_VALIST_OPAQUE; 1475 case ABI_VA_LIST_POINTER: 1476 return KIT_CG_VALIST_POINTER; 1477 case ABI_VA_LIST_AAPCS64: 1478 return KIT_CG_VALIST_AAPCS64; 1479 case ABI_VA_LIST_SYSV_X64: 1480 return KIT_CG_VALIST_SYSV_X64; 1481 } 1482 return KIT_CG_VALIST_OPAQUE; 1483 } 1484 1485 const char* kit_cg_target_c_label_prefix(const KitCompiler* c) { 1486 return obj_format_c_label_prefix(c); 1487 } 1488 1489 int kit_cg_target_supports_intrinsic(KitCompiler* c, KitCgIntrinsic intrin) { 1490 const ArchImpl* a; 1491 if (!c) return 0; 1492 a = arch_for_compiler(c); 1493 if (!a || !a->supports_intrinsic) return 0; 1494 return a->supports_intrinsic(c, intrin); 1495 } 1496 1497 uint64_t kit_cg_target_backend_features(KitCompiler* c) { 1498 const ArchImpl* a; 1499 if (!c) return 0; 1500 a = arch_for_compiler(c); 1501 /* Arches with no registered codegen backend (x86_32) fall back to the 1502 * conservative strict-alignment baseline. */ 1503 if (!a) return KIT_CG_BACKEND_STRICT_ALIGNMENT; 1504 return a->backend_features; 1505 } 1506 1507 void cg_api_fini(Compiler* c) { 1508 CgApiState* s; 1509 if (!c || !c->cg_api) return; 1510 s = (CgApiState*)c->cg_api; 1511 CgApiTypes_fini(&s->types); 1512 CgPtrMap_fini(&s->ptr_index); 1513 CgArraySet_fini(&s->array_index); 1514 CgFuncSet_fini(&s->func_index); 1515 s->heap->free(s->heap, s, sizeof(*s)); 1516 c->cg_api = NULL; 1517 c->cg_api_free = NULL; 1518 c->cg_builtin_layout = NULL; 1519 } 1520 1521 /* ============================================================ 1522 * KitCg: public codegen API implementation 1523 * 1524 * Drives CgTarget directly with its own value stack. 1525 * ============================================================ */