kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

cg_type_test.c (51040B)


      1 #include <kit/cg.h>
      2 #include <kit/compile.h>
      3 #include <kit/core.h>
      4 #include <kit/frontend.h>
      5 #include <kit/object.h>
      6 #include <stdarg.h>
      7 #include <stdio.h>
      8 #include <stdlib.h>
      9 #include <string.h>
     10 
     11 #include "lib/kit_unit.h"
     12 
     13 /* One shared test context replaces the per-file heap/diag/counter globals.
     14  * EXPECT is aliased to CU_EXPECT so the call sites below are unchanged; the
     15  * expected-panic helper uses g_u.suppress_fatal + g_u.last_diag. */
     16 static KitUnit g_u;
     17 #define EXPECT(cond, ...) CU_EXPECT(&g_u, cond, __VA_ARGS__)
     18 
     19 static KitObjBuilder* new_obj(KitCompiler* c) {
     20   KitObjBuilder* ob = NULL;
     21   if (kit_obj_builder_new(c, &ob) != KIT_OK) return NULL;
     22   return ob;
     23 }
     24 
     25 static int open_emitted_obj(KitCompiler* c, KitObjBuilder* ob,
     26                             KitWriter** writer_out, KitObjFile** file_out) {
     27   KitWriter* w = NULL;
     28   KitObjFile* f = NULL;
     29   KitSlice bytes;
     30   size_t len = 0;
     31   const KitContext* ctx;
     32 
     33   if (!writer_out || !file_out) return 0;
     34   *writer_out = NULL;
     35   *file_out = NULL;
     36   if (kit_writer_mem(&g_u.heap, &w) != KIT_OK || !w) return 0;
     37   if (kit_obj_builder_emit(ob, w) != KIT_OK) {
     38     kit_writer_close(w);
     39     return 0;
     40   }
     41   bytes.data = kit_writer_mem_bytes(w, &len);
     42   bytes.len = len;
     43   ctx = kit_compiler_context(c);
     44   if (kit_obj_open(ctx, KIT_SLICE_LIT("<cg-api-test>"), &bytes, &f) != KIT_OK) {
     45     kit_writer_close(w);
     46     return 0;
     47   }
     48   *writer_out = w;
     49   *file_out = f;
     50   return 1;
     51 }
     52 
     53 static void finish_cg(KitCg* cg, const char* tag) {
     54   EXPECT(kit_cg_finish(cg, NULL) == KIT_OK, "%s cg finish failed", tag);
     55   EXPECT(kit_cg_detach(cg) == KIT_OK, "%s cg detach failed", tag);
     56 }
     57 
     58 typedef struct PanicRunCtx {
     59   void (*fn)(void*);
     60   void* arg;
     61 } PanicRunCtx;
     62 
     63 static KitStatus run_expected_panic(KitCompiler* c, void* arg) {
     64   PanicRunCtx* ctx = (PanicRunCtx*)arg;
     65   (void)c;
     66   ctx->fn(ctx->arg);
     67   return KIT_OK;
     68 }
     69 
     70 static int expect_panic_contains(KitCompiler* c, void (*fn)(void*), void* arg,
     71                                  const char* expected) {
     72   PanicRunCtx ctx;
     73   KitStatus st;
     74   ctx.fn = fn;
     75   ctx.arg = arg;
     76   g_u.last_diag[0] = '\0';
     77   g_u.suppress_fatal++;
     78   st = kit_frontend_run(c, run_expected_panic, &ctx);
     79   g_u.suppress_fatal--;
     80   return st == KIT_ERR && strstr(g_u.last_diag, expected) != NULL;
     81 }
     82 
     83 static void exercise_cg_handles(KitCompiler* c, KitCgTypeId i32_ty,
     84                                 int opt_level) {
     85   char name_buf[32];
     86   KitCodeOptions opts;
     87   KitObjBuilder* ob;
     88   KitCg* cg;
     89   KitCgFuncParam param_desc;
     90   KitCgFuncSig sig;
     91   KitCgDecl decl;
     92   KitCgSym sym;
     93   KitCgLocalAttrs attrs;
     94   KitCgLocal local;
     95   KitCgLocal param;
     96   KitCgMemAccess mem;
     97 
     98   memset(&opts, 0, sizeof(opts));
     99   opts.opt_level = opt_level;
    100   ob = new_obj(c);
    101   EXPECT(ob != NULL, "obj builder allocation failed");
    102   if (!ob) return;
    103   cg = NULL;
    104   (void)kit_cg_new(c, &cg);
    105   if (cg) (void)kit_cg_begin(cg, ob, &opts);
    106   EXPECT(cg != NULL, "cg allocation failed");
    107   if (!cg) {
    108     kit_obj_builder_free(ob);
    109     return;
    110   }
    111 
    112   memset(&param_desc, 0, sizeof(param_desc));
    113   param_desc.type = i32_ty;
    114   memset(&sig, 0, sizeof(sig));
    115   KitCgFuncResult sig_result;
    116   memset(&sig_result, 0, sizeof sig_result);
    117   sig_result.type = i32_ty;
    118   sig.result = sig_result;
    119   sig.params = &param_desc;
    120   sig.nparams = 1;
    121   sig.call_conv = KIT_CG_CC_TARGET_C;
    122 
    123   snprintf(name_buf, sizeof(name_buf), "cg_handles_o%d", opt_level);
    124   memset(&decl, 0, sizeof(decl));
    125   decl.kind = KIT_CG_DECL_FUNC;
    126   decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name_buf));
    127   decl.display_name = decl.linkage_name;
    128   decl.type = kit_cg_type_func(c, sig);
    129   decl.sym.bind = KIT_SB_GLOBAL;
    130   decl.sym.visibility = KIT_CG_VIS_DEFAULT;
    131   sym = kit_cg_decl(cg, decl);
    132   EXPECT(sym != KIT_CG_SYM_NONE, "function decl failed");
    133 
    134   kit_cg_func_begin(cg, sym);
    135   memset(&attrs, 0, sizeof(attrs));
    136   attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("p"));
    137   param = kit_cg_param(cg, 0, i32_ty, attrs);
    138   attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("x"));
    139   local = kit_cg_local(cg, i32_ty, attrs);
    140   EXPECT(local != KIT_CG_LOCAL_NONE, "local handle is none");
    141   EXPECT(param != KIT_CG_LOCAL_NONE, "param handle is none");
    142   EXPECT((uint32_t)param == 1u, "first local id should be param");
    143   EXPECT((uint32_t)local == 2u, "local id should follow param");
    144   EXPECT((uint32_t)local != (uint32_t)param, "local and param handles collide");
    145 
    146   memset(&mem, 0, sizeof(mem));
    147   mem.type = i32_ty;
    148   mem.align = kit_cg_type_align(c, i32_ty);
    149 
    150   kit_cg_push_local(cg, local);
    151   kit_cg_push_local_addr(cg, param);
    152   kit_cg_deref(cg, 0); /* pointer VALUE -> PLACE for the load */
    153   kit_cg_load(cg, mem);
    154   kit_cg_store(cg, mem);
    155 
    156   kit_cg_push_local_addr(cg, local);
    157   kit_cg_deref(cg, 0); /* pointer VALUE -> PLACE for the load */
    158   kit_cg_load(cg, mem);
    159   kit_cg_ret(cg);
    160   kit_cg_func_end(cg);
    161 
    162   kit_cg_free(cg);
    163   kit_obj_builder_free(ob);
    164 }
    165 
    166 static void exercise_cg_scalar_local(KitCompiler* c, KitCgTypeId i32_ty,
    167                                      int opt_level) {
    168   char name_buf[40];
    169   KitCodeOptions opts;
    170   KitObjBuilder* ob;
    171   KitCg* cg;
    172   KitCgFuncSig sig;
    173   KitCgDecl decl;
    174   KitCgSym sym;
    175   KitCgLocalAttrs attrs;
    176   KitCgLocal local;
    177   KitCgMemAccess mem;
    178 
    179   memset(&opts, 0, sizeof opts);
    180   opts.opt_level = opt_level;
    181   ob = new_obj(c);
    182   EXPECT(ob != NULL, "obj builder allocation failed");
    183   if (!ob) return;
    184   cg = NULL;
    185   (void)kit_cg_new(c, &cg);
    186   if (cg) (void)kit_cg_begin(cg, ob, &opts);
    187   EXPECT(cg != NULL, "cg allocation failed");
    188   if (!cg) {
    189     kit_obj_builder_free(ob);
    190     return;
    191   }
    192 
    193   memset(&sig, 0, sizeof sig);
    194   KitCgFuncResult sig_result;
    195   memset(&sig_result, 0, sizeof sig_result);
    196   sig_result.type = i32_ty;
    197   sig.result = sig_result;
    198   sig.call_conv = KIT_CG_CC_TARGET_C;
    199 
    200   snprintf(name_buf, sizeof name_buf, "cg_scalar_local_o%d", opt_level);
    201   memset(&decl, 0, sizeof decl);
    202   decl.kind = KIT_CG_DECL_FUNC;
    203   decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name_buf));
    204   decl.display_name = decl.linkage_name;
    205   decl.type = kit_cg_type_func(c, sig);
    206   decl.sym.bind = KIT_SB_GLOBAL;
    207   decl.sym.visibility = KIT_CG_VIS_DEFAULT;
    208   sym = kit_cg_decl(cg, decl);
    209   EXPECT(sym != KIT_CG_SYM_NONE, "scalar local decl failed");
    210 
    211   kit_cg_func_begin(cg, sym);
    212   memset(&attrs, 0, sizeof attrs);
    213   attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("x"));
    214   local = kit_cg_local(cg, i32_ty, attrs);
    215   EXPECT(local != KIT_CG_LOCAL_NONE, "scalar local handle is none");
    216 
    217   memset(&mem, 0, sizeof mem);
    218   mem.type = i32_ty;
    219   mem.align = kit_cg_type_align(c, i32_ty);
    220 
    221   kit_cg_push_local(cg, local);
    222   kit_cg_push_int(cg, 40, i32_ty);
    223   kit_cg_store(cg, mem);
    224   kit_cg_push_local(cg, local);
    225   kit_cg_load(cg, mem);
    226   kit_cg_push_int(cg, 2, i32_ty);
    227   kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0);
    228   kit_cg_ret(cg);
    229   kit_cg_func_end(cg);
    230 
    231   kit_cg_free(cg);
    232   kit_obj_builder_free(ob);
    233 }
    234 
    235 static void exercise_cg_late_local_addr(KitCompiler* c, KitCgTypeId i32_ty,
    236                                         int opt_level) {
    237   char name_buf[40];
    238   KitCodeOptions opts;
    239   KitObjBuilder* ob;
    240   KitCg* cg;
    241   KitCgFuncSig sig;
    242   KitCgDecl decl;
    243   KitCgSym sym;
    244   KitCgLocalAttrs attrs;
    245   KitCgLocal local;
    246   KitCgMemAccess mem;
    247 
    248   memset(&opts, 0, sizeof opts);
    249   opts.opt_level = opt_level;
    250   ob = new_obj(c);
    251   EXPECT(ob != NULL, "obj builder allocation failed");
    252   if (!ob) return;
    253   cg = NULL;
    254   (void)kit_cg_new(c, &cg);
    255   if (cg) (void)kit_cg_begin(cg, ob, &opts);
    256   EXPECT(cg != NULL, "cg allocation failed");
    257   if (!cg) {
    258     kit_obj_builder_free(ob);
    259     return;
    260   }
    261 
    262   memset(&sig, 0, sizeof sig);
    263   KitCgFuncResult sig_result;
    264   memset(&sig_result, 0, sizeof sig_result);
    265   sig_result.type = i32_ty;
    266   sig.result = sig_result;
    267   sig.call_conv = KIT_CG_CC_TARGET_C;
    268 
    269   snprintf(name_buf, sizeof name_buf, "cg_late_local_addr_o%d", opt_level);
    270   memset(&decl, 0, sizeof decl);
    271   decl.kind = KIT_CG_DECL_FUNC;
    272   decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name_buf));
    273   decl.display_name = decl.linkage_name;
    274   decl.type = kit_cg_type_func(c, sig);
    275   decl.sym.bind = KIT_SB_GLOBAL;
    276   decl.sym.visibility = KIT_CG_VIS_DEFAULT;
    277   sym = kit_cg_decl(cg, decl);
    278   EXPECT(sym != KIT_CG_SYM_NONE, "late local addr decl failed");
    279 
    280   kit_cg_func_begin(cg, sym);
    281   memset(&attrs, 0, sizeof attrs);
    282   attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("x"));
    283   local = kit_cg_local(cg, i32_ty, attrs);
    284   EXPECT(local != KIT_CG_LOCAL_NONE, "late addr local handle is none");
    285 
    286   memset(&mem, 0, sizeof mem);
    287   mem.type = i32_ty;
    288   mem.align = kit_cg_type_align(c, i32_ty);
    289 
    290   kit_cg_push_local(cg, local);
    291   kit_cg_push_int(cg, 41, i32_ty);
    292   kit_cg_store(cg, mem);
    293   kit_cg_push_local_addr(cg, local);
    294   kit_cg_deref(cg, 0); /* pointer VALUE -> PLACE for the load */
    295   kit_cg_load(cg, mem);
    296   kit_cg_push_int(cg, 1, i32_ty);
    297   kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0);
    298   kit_cg_ret(cg);
    299   kit_cg_func_end(cg);
    300 
    301   kit_cg_free(cg);
    302   kit_obj_builder_free(ob);
    303 }
    304 
    305 static uint32_t text_size(KitCompiler* c, KitObjBuilder* ob) {
    306   uint32_t total = 0;
    307   KitWriter* w = NULL;
    308   KitObjFile* f = NULL;
    309   uint32_t n;
    310   if (!open_emitted_obj(c, ob, &w, &f)) {
    311     EXPECT(0, "failed to inspect emitted object");
    312     return 0;
    313   }
    314   n = kit_obj_nsections(f);
    315   for (uint32_t i = 0; i < n; ++i) {
    316     KitObjSecInfo sec;
    317     if (kit_obj_section(f, i, &sec) != KIT_OK) continue;
    318     if (sec.kind == KIT_SEC_TEXT) total += (uint32_t)sec.size;
    319   }
    320   kit_obj_free(f);
    321   kit_writer_close(w);
    322   return total;
    323 }
    324 
    325 static void exercise_cg_data_entsize(KitCompiler* c, KitCgTypeId i8_ty) {
    326   static const uint8_t bytes[] = {'t', 'o', 'y', '\0'};
    327   KitCodeOptions opts;
    328   KitObjBuilder* ob;
    329   KitCg* cg;
    330   KitCgDecl decl;
    331   KitCgSym sym;
    332   KitCgDataDefAttrs data_attrs;
    333   KitCgTypeId array_ty;
    334   int found = 0;
    335 
    336   memset(&opts, 0, sizeof opts);
    337   ob = new_obj(c);
    338   EXPECT(ob != NULL, "entsize obj builder allocation failed");
    339   if (!ob) return;
    340   cg = NULL;
    341   (void)kit_cg_new(c, &cg);
    342   if (cg) (void)kit_cg_begin(cg, ob, &opts);
    343   EXPECT(cg != NULL, "entsize cg allocation failed");
    344   if (!cg) {
    345     kit_obj_builder_free(ob);
    346     return;
    347   }
    348 
    349   array_ty = kit_cg_type_array(c, i8_ty, sizeof bytes);
    350   EXPECT(array_ty != KIT_CG_TYPE_NONE, "entsize array type failed");
    351 
    352   memset(&decl, 0, sizeof decl);
    353   decl.kind = KIT_CG_DECL_OBJECT;
    354   decl.linkage_name = kit_sym_intern(c, KIT_SLICE_LIT("cg_entsize_string"));
    355   decl.display_name = decl.linkage_name;
    356   decl.type = array_ty;
    357   decl.sym.bind = KIT_SB_GLOBAL;
    358   decl.sym.visibility = KIT_CG_VIS_DEFAULT;
    359   decl.as.object.flags = KIT_CG_OBJ_READONLY;
    360   decl.as.object.align = 1;
    361   sym = kit_cg_decl(cg, decl);
    362   EXPECT(sym != KIT_CG_SYM_NONE, "entsize object decl failed");
    363 
    364   memset(&data_attrs, 0, sizeof data_attrs);
    365   data_attrs.section = kit_sym_intern(c, KIT_SLICE_LIT(".rodata.kit.merge"));
    366   data_attrs.align = 1;
    367   data_attrs.entsize = 1;
    368   data_attrs.flags =
    369       KIT_CG_DATADEF_READONLY | KIT_CG_DATADEF_MERGE | KIT_CG_DATADEF_STRINGS;
    370   kit_cg_data_begin(cg, sym, data_attrs);
    371   kit_cg_data_bytes(cg, bytes, sizeof bytes);
    372   kit_cg_data_end(cg);
    373   finish_cg(cg, "entsize");
    374   kit_cg_free(cg);
    375 
    376   {
    377     KitWriter* w = NULL;
    378     KitObjFile* f = NULL;
    379     uint32_t n;
    380     if (!open_emitted_obj(c, ob, &w, &f)) {
    381       EXPECT(0, "failed to inspect entsize object");
    382       kit_obj_builder_free(ob);
    383       return;
    384     }
    385     n = kit_obj_nsections(f);
    386     for (uint32_t i = 0; i < n; ++i) {
    387       KitObjSecInfo sec;
    388       if (kit_obj_section(f, i, &sec) != KIT_OK) continue;
    389       if ((sec.flags & (KIT_SF_MERGE | KIT_SF_STRINGS)) ==
    390           (KIT_SF_MERGE | KIT_SF_STRINGS)) {
    391         found = 1;
    392         EXPECT(sec.entsize == 1,
    393                "merge string section entsize should be 1, got %u", sec.entsize);
    394       }
    395     }
    396     kit_obj_free(f);
    397     kit_writer_close(w);
    398   }
    399   EXPECT(found, "expected merge string data section");
    400 
    401   kit_obj_builder_free(ob);
    402 }
    403 
    404 static KitCgSym begin_i32_func(KitCompiler* c, KitCg* cg, KitCgTypeId i32_ty,
    405                                const char* name) {
    406   KitCgFuncSig sig;
    407   KitCgDecl decl;
    408   memset(&sig, 0, sizeof sig);
    409   KitCgFuncResult sig_result;
    410   memset(&sig_result, 0, sizeof sig_result);
    411   sig_result.type = i32_ty;
    412   sig.result = sig_result;
    413   sig.call_conv = KIT_CG_CC_TARGET_C;
    414 
    415   memset(&decl, 0, sizeof decl);
    416   decl.kind = KIT_CG_DECL_FUNC;
    417   decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name));
    418   decl.display_name = decl.linkage_name;
    419   decl.type = kit_cg_type_func(c, sig);
    420   decl.sym.bind = KIT_SB_GLOBAL;
    421   decl.sym.visibility = KIT_CG_VIS_DEFAULT;
    422   return kit_cg_decl(cg, decl);
    423 }
    424 
    425 static void exercise_cg_literal_folds(KitCompiler* c, KitCgTypeId i32_ty) {
    426   static const char* names[] = {
    427       "cg_fold_add_o1",
    428       "cg_fold_shift_or_o1",
    429       "cg_fold_cmp_o1",
    430       "cg_fold_unop_o1",
    431   };
    432   KitCodeOptions opts;
    433   KitObjBuilder* ob;
    434   KitCg* cg;
    435 
    436   memset(&opts, 0, sizeof opts);
    437   opts.opt_level = 1;
    438   ob = new_obj(c);
    439   EXPECT(ob != NULL, "literal fold obj builder allocation failed");
    440   if (!ob) return;
    441   cg = NULL;
    442   (void)kit_cg_new(c, &cg);
    443   if (cg) (void)kit_cg_begin(cg, ob, &opts);
    444   EXPECT(cg != NULL, "literal fold cg allocation failed");
    445   if (!cg) {
    446     kit_obj_builder_free(ob);
    447     return;
    448   }
    449 
    450   for (uint32_t i = 0; i < 4; ++i) {
    451     KitCgSym sym = begin_i32_func(c, cg, i32_ty, names[i]);
    452     EXPECT(sym != KIT_CG_SYM_NONE, "literal fold decl failed");
    453     kit_cg_func_begin(cg, sym);
    454     switch (i) {
    455       case 0:
    456         kit_cg_push_int(cg, 40, i32_ty);
    457         kit_cg_push_int(cg, 2, i32_ty);
    458         kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0);
    459         break;
    460       case 1:
    461         kit_cg_push_int(cg, 5, i32_ty);
    462         kit_cg_push_int(cg, 3, i32_ty);
    463         kit_cg_int_binop(cg, KIT_CG_INT_SHL, 0);
    464         kit_cg_push_int(cg, 2, i32_ty);
    465         kit_cg_int_binop(cg, KIT_CG_INT_OR, 0);
    466         break;
    467       case 2:
    468         kit_cg_push_int(cg, 40, i32_ty);
    469         kit_cg_push_int(cg, 2, i32_ty);
    470         kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0);
    471         kit_cg_push_int(cg, 42, i32_ty);
    472         kit_cg_int_cmp(cg, KIT_CG_INT_EQ);
    473         break;
    474       case 3:
    475         kit_cg_push_int(cg, 41, i32_ty);
    476         kit_cg_int_unop(cg, KIT_CG_INT_BNOT, 0);
    477         kit_cg_int_unop(cg, KIT_CG_INT_BNOT, 0);
    478         kit_cg_push_int(cg, 1, i32_ty);
    479         kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0);
    480         break;
    481     }
    482     kit_cg_ret(cg);
    483     kit_cg_func_end(cg);
    484   }
    485 
    486   finish_cg(cg, "literal fold");
    487   kit_cg_free(cg);
    488   EXPECT(text_size(c, ob) <= 128,
    489          "literal folds should avoid arithmetic materialization, text size=%u",
    490          text_size(c, ob));
    491   kit_obj_builder_free(ob);
    492 }
    493 
    494 static uint32_t cg_emit_delayed_chain(KitCompiler* c, KitCgTypeId i32_ty,
    495                                       const char* name) {
    496   KitCodeOptions opts;
    497   KitObjBuilder* ob;
    498   KitCg* cg;
    499   KitCgFuncParam param_desc;
    500   KitCgFuncSig sig;
    501   KitCgDecl decl;
    502   KitCgSym sym;
    503   KitCgLocalAttrs attrs;
    504   KitCgLocal param;
    505   KitCgMemAccess mem;
    506   uint32_t size;
    507 
    508   memset(&opts, 0, sizeof opts);
    509   opts.opt_level = 1;
    510   ob = new_obj(c);
    511   EXPECT(ob != NULL, "delayed chain obj builder allocation failed");
    512   if (!ob) return 0;
    513   cg = NULL;
    514   (void)kit_cg_new(c, &cg);
    515   if (cg) (void)kit_cg_begin(cg, ob, &opts);
    516   EXPECT(cg != NULL, "delayed chain cg allocation failed");
    517   if (!cg) {
    518     kit_obj_builder_free(ob);
    519     return 0;
    520   }
    521 
    522   memset(&param_desc, 0, sizeof param_desc);
    523   param_desc.type = i32_ty;
    524   memset(&sig, 0, sizeof sig);
    525   KitCgFuncResult sig_result;
    526   memset(&sig_result, 0, sizeof sig_result);
    527   sig_result.type = i32_ty;
    528   sig.result = sig_result;
    529   sig.params = &param_desc;
    530   sig.nparams = 1;
    531   sig.call_conv = KIT_CG_CC_TARGET_C;
    532 
    533   memset(&decl, 0, sizeof decl);
    534   decl.kind = KIT_CG_DECL_FUNC;
    535   decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name));
    536   decl.display_name = decl.linkage_name;
    537   decl.type = kit_cg_type_func(c, sig);
    538   decl.sym.bind = KIT_SB_GLOBAL;
    539   decl.sym.visibility = KIT_CG_VIS_DEFAULT;
    540   sym = kit_cg_decl(cg, decl);
    541   EXPECT(sym != KIT_CG_SYM_NONE, "delayed chain decl failed");
    542 
    543   kit_cg_func_begin(cg, sym);
    544   memset(&attrs, 0, sizeof attrs);
    545   attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("p"));
    546   param = kit_cg_param(cg, 0, i32_ty, attrs);
    547   EXPECT(param != KIT_CG_LOCAL_NONE, "delayed chain param failed");
    548   memset(&mem, 0, sizeof mem);
    549   mem.type = i32_ty;
    550   mem.align = kit_cg_type_align(c, i32_ty);
    551   kit_cg_push_local(cg, param);
    552   kit_cg_load(cg, mem);
    553   kit_cg_push_int(cg, 40, i32_ty);
    554   kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0);
    555   kit_cg_push_int(cg, 2, i32_ty);
    556   kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0);
    557   kit_cg_ret(cg);
    558   kit_cg_func_end(cg);
    559 
    560   finish_cg(cg, "delayed chain");
    561   kit_cg_free(cg);
    562   size = text_size(c, ob);
    563   kit_obj_builder_free(ob);
    564   return size;
    565 }
    566 
    567 static uint32_t cg_emit_unary_chain(KitCompiler* c, KitCgTypeId i32_ty,
    568                                     const char* name) {
    569   KitCodeOptions opts;
    570   KitObjBuilder* ob;
    571   KitCg* cg;
    572   KitCgFuncParam param_desc;
    573   KitCgFuncSig sig;
    574   KitCgDecl decl;
    575   KitCgSym sym;
    576   KitCgLocalAttrs attrs;
    577   KitCgLocal param;
    578   KitCgMemAccess mem;
    579   uint32_t size;
    580 
    581   memset(&opts, 0, sizeof opts);
    582   opts.opt_level = 1;
    583   ob = new_obj(c);
    584   EXPECT(ob != NULL, "unary chain obj builder allocation failed");
    585   if (!ob) return 0;
    586   cg = NULL;
    587   (void)kit_cg_new(c, &cg);
    588   if (cg) (void)kit_cg_begin(cg, ob, &opts);
    589   EXPECT(cg != NULL, "unary chain cg allocation failed");
    590   if (!cg) {
    591     kit_obj_builder_free(ob);
    592     return 0;
    593   }
    594 
    595   memset(&param_desc, 0, sizeof param_desc);
    596   param_desc.type = i32_ty;
    597   memset(&sig, 0, sizeof sig);
    598   KitCgFuncResult sig_result;
    599   memset(&sig_result, 0, sizeof sig_result);
    600   sig_result.type = i32_ty;
    601   sig.result = sig_result;
    602   sig.params = &param_desc;
    603   sig.nparams = 1;
    604   sig.call_conv = KIT_CG_CC_TARGET_C;
    605 
    606   memset(&decl, 0, sizeof decl);
    607   decl.kind = KIT_CG_DECL_FUNC;
    608   decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name));
    609   decl.display_name = decl.linkage_name;
    610   decl.type = kit_cg_type_func(c, sig);
    611   decl.sym.bind = KIT_SB_GLOBAL;
    612   decl.sym.visibility = KIT_CG_VIS_DEFAULT;
    613   sym = kit_cg_decl(cg, decl);
    614   EXPECT(sym != KIT_CG_SYM_NONE, "unary chain decl failed");
    615 
    616   kit_cg_func_begin(cg, sym);
    617   memset(&attrs, 0, sizeof attrs);
    618   attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("p"));
    619   param = kit_cg_param(cg, 0, i32_ty, attrs);
    620   EXPECT(param != KIT_CG_LOCAL_NONE, "unary chain param failed");
    621   memset(&mem, 0, sizeof mem);
    622   mem.type = i32_ty;
    623   mem.align = kit_cg_type_align(c, i32_ty);
    624   kit_cg_push_local(cg, param);
    625   kit_cg_load(cg, mem);
    626   kit_cg_int_unop(cg, KIT_CG_INT_BNOT, 0);
    627   kit_cg_int_unop(cg, KIT_CG_INT_BNOT, 0);
    628   kit_cg_ret(cg);
    629   kit_cg_func_end(cg);
    630 
    631   finish_cg(cg, "unary chain");
    632   kit_cg_free(cg);
    633   size = text_size(c, ob);
    634   kit_obj_builder_free(ob);
    635   return size;
    636 }
    637 
    638 static uint32_t cg_emit_local_shadow(KitCompiler* c, KitCgTypeId i32_ty,
    639                                      const char* name) {
    640   KitCodeOptions opts;
    641   KitObjBuilder* ob;
    642   KitCg* cg;
    643   KitCgFuncSig sig;
    644   KitCgDecl decl;
    645   KitCgSym sym;
    646   KitCgLocalAttrs attrs;
    647   KitCgLocal local;
    648   KitCgMemAccess mem;
    649   uint32_t size;
    650 
    651   memset(&opts, 0, sizeof opts);
    652   opts.opt_level = 1;
    653   ob = new_obj(c);
    654   EXPECT(ob != NULL, "local shadow obj builder allocation failed");
    655   if (!ob) return 0;
    656   cg = NULL;
    657   (void)kit_cg_new(c, &cg);
    658   if (cg) (void)kit_cg_begin(cg, ob, &opts);
    659   EXPECT(cg != NULL, "local shadow cg allocation failed");
    660   if (!cg) {
    661     kit_obj_builder_free(ob);
    662     return 0;
    663   }
    664 
    665   memset(&sig, 0, sizeof sig);
    666   KitCgFuncResult sig_result;
    667   memset(&sig_result, 0, sizeof sig_result);
    668   sig_result.type = i32_ty;
    669   sig.result = sig_result;
    670   sig.call_conv = KIT_CG_CC_TARGET_C;
    671 
    672   memset(&decl, 0, sizeof decl);
    673   decl.kind = KIT_CG_DECL_FUNC;
    674   decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name));
    675   decl.display_name = decl.linkage_name;
    676   decl.type = kit_cg_type_func(c, sig);
    677   decl.sym.bind = KIT_SB_GLOBAL;
    678   decl.sym.visibility = KIT_CG_VIS_DEFAULT;
    679   sym = kit_cg_decl(cg, decl);
    680   EXPECT(sym != KIT_CG_SYM_NONE, "local shadow decl failed");
    681 
    682   kit_cg_func_begin(cg, sym);
    683   memset(&attrs, 0, sizeof attrs);
    684   attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("x"));
    685   local = kit_cg_local(cg, i32_ty, attrs);
    686   EXPECT(local != KIT_CG_LOCAL_NONE, "local shadow local failed");
    687   memset(&mem, 0, sizeof mem);
    688   mem.type = i32_ty;
    689   mem.align = kit_cg_type_align(c, i32_ty);
    690   kit_cg_push_local(cg, local);
    691   kit_cg_push_int(cg, 40, i32_ty);
    692   kit_cg_store(cg, mem);
    693   kit_cg_push_local(cg, local);
    694   kit_cg_load(cg, mem);
    695   kit_cg_push_int(cg, 2, i32_ty);
    696   kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0);
    697   kit_cg_ret(cg);
    698   kit_cg_func_end(cg);
    699 
    700   finish_cg(cg, "local shadow");
    701   kit_cg_free(cg);
    702   size = text_size(c, ob);
    703   kit_obj_builder_free(ob);
    704   return size;
    705 }
    706 
    707 static uint32_t cg_emit_delayed_cmp(KitCompiler* c, KitCgTypeId i32_ty,
    708                                     const char* name) {
    709   KitCodeOptions opts;
    710   KitObjBuilder* ob;
    711   KitCg* cg;
    712   KitCgFuncParam param_desc;
    713   KitCgFuncSig sig;
    714   KitCgDecl decl;
    715   KitCgSym sym;
    716   KitCgLocalAttrs attrs;
    717   KitCgLocal param;
    718   KitCgMemAccess mem;
    719   uint32_t size;
    720 
    721   memset(&opts, 0, sizeof opts);
    722   opts.opt_level = 1;
    723   ob = new_obj(c);
    724   EXPECT(ob != NULL, "delayed cmp obj builder allocation failed");
    725   if (!ob) return 0;
    726   cg = NULL;
    727   (void)kit_cg_new(c, &cg);
    728   if (cg) (void)kit_cg_begin(cg, ob, &opts);
    729   EXPECT(cg != NULL, "delayed cmp cg allocation failed");
    730   if (!cg) {
    731     kit_obj_builder_free(ob);
    732     return 0;
    733   }
    734 
    735   memset(&param_desc, 0, sizeof param_desc);
    736   param_desc.type = i32_ty;
    737   memset(&sig, 0, sizeof sig);
    738   KitCgFuncResult sig_result;
    739   memset(&sig_result, 0, sizeof sig_result);
    740   sig_result.type = i32_ty;
    741   sig.result = sig_result;
    742   sig.params = &param_desc;
    743   sig.nparams = 1;
    744   sig.call_conv = KIT_CG_CC_TARGET_C;
    745 
    746   memset(&decl, 0, sizeof decl);
    747   decl.kind = KIT_CG_DECL_FUNC;
    748   decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name));
    749   decl.display_name = decl.linkage_name;
    750   decl.type = kit_cg_type_func(c, sig);
    751   decl.sym.bind = KIT_SB_GLOBAL;
    752   decl.sym.visibility = KIT_CG_VIS_DEFAULT;
    753   sym = kit_cg_decl(cg, decl);
    754   EXPECT(sym != KIT_CG_SYM_NONE, "delayed cmp decl failed");
    755 
    756   kit_cg_func_begin(cg, sym);
    757   memset(&attrs, 0, sizeof attrs);
    758   attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("p"));
    759   param = kit_cg_param(cg, 0, i32_ty, attrs);
    760   EXPECT(param != KIT_CG_LOCAL_NONE, "delayed cmp param failed");
    761   memset(&mem, 0, sizeof mem);
    762   mem.type = i32_ty;
    763   mem.align = kit_cg_type_align(c, i32_ty);
    764   kit_cg_push_local(cg, param);
    765   kit_cg_load(cg, mem);
    766   kit_cg_push_int(cg, 40, i32_ty);
    767   kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0);
    768   kit_cg_push_int(cg, 2, i32_ty);
    769   kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0);
    770   kit_cg_push_int(cg, 42, i32_ty);
    771   kit_cg_int_cmp(cg, KIT_CG_INT_EQ);
    772   kit_cg_ret(cg);
    773   kit_cg_func_end(cg);
    774 
    775   finish_cg(cg, "delayed cmp");
    776   kit_cg_free(cg);
    777   size = text_size(c, ob);
    778   kit_obj_builder_free(ob);
    779   return size;
    780 }
    781 
    782 static uint32_t cg_emit_delayed_store(KitCompiler* c, KitCgTypeId i32_ty,
    783                                       const char* name) {
    784   KitCodeOptions opts;
    785   KitObjBuilder* ob;
    786   KitCg* cg;
    787   KitCgFuncParam param_desc;
    788   KitCgFuncSig sig;
    789   KitCgDecl decl;
    790   KitCgSym sym;
    791   KitCgLocalAttrs attrs;
    792   KitCgLocal param;
    793   KitCgLocal local;
    794   KitCgMemAccess mem;
    795   uint32_t size;
    796 
    797   memset(&opts, 0, sizeof opts);
    798   opts.opt_level = 1;
    799   ob = new_obj(c);
    800   EXPECT(ob != NULL, "delayed store obj builder allocation failed");
    801   if (!ob) return 0;
    802   cg = NULL;
    803   (void)kit_cg_new(c, &cg);
    804   if (cg) (void)kit_cg_begin(cg, ob, &opts);
    805   EXPECT(cg != NULL, "delayed store cg allocation failed");
    806   if (!cg) {
    807     kit_obj_builder_free(ob);
    808     return 0;
    809   }
    810 
    811   memset(&param_desc, 0, sizeof param_desc);
    812   param_desc.type = i32_ty;
    813   memset(&sig, 0, sizeof sig);
    814   KitCgFuncResult sig_result;
    815   memset(&sig_result, 0, sizeof sig_result);
    816   sig_result.type = i32_ty;
    817   sig.result = sig_result;
    818   sig.params = &param_desc;
    819   sig.nparams = 1;
    820   sig.call_conv = KIT_CG_CC_TARGET_C;
    821 
    822   memset(&decl, 0, sizeof decl);
    823   decl.kind = KIT_CG_DECL_FUNC;
    824   decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name));
    825   decl.display_name = decl.linkage_name;
    826   decl.type = kit_cg_type_func(c, sig);
    827   decl.sym.bind = KIT_SB_GLOBAL;
    828   decl.sym.visibility = KIT_CG_VIS_DEFAULT;
    829   sym = kit_cg_decl(cg, decl);
    830   EXPECT(sym != KIT_CG_SYM_NONE, "delayed store decl failed");
    831 
    832   kit_cg_func_begin(cg, sym);
    833   memset(&attrs, 0, sizeof attrs);
    834   attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("p"));
    835   param = kit_cg_param(cg, 0, i32_ty, attrs);
    836   attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("x"));
    837   local = kit_cg_local(cg, i32_ty, attrs);
    838   EXPECT(param != KIT_CG_LOCAL_NONE, "delayed store param failed");
    839   EXPECT(local != KIT_CG_LOCAL_NONE, "delayed store local failed");
    840   memset(&mem, 0, sizeof mem);
    841   mem.type = i32_ty;
    842   mem.align = kit_cg_type_align(c, i32_ty);
    843   kit_cg_push_local(cg, local);
    844   kit_cg_push_local(cg, param);
    845   kit_cg_load(cg, mem);
    846   kit_cg_push_int(cg, 40, i32_ty);
    847   kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0);
    848   kit_cg_push_int(cg, 2, i32_ty);
    849   kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0);
    850   kit_cg_store(cg, mem);
    851   kit_cg_push_local(cg, local);
    852   kit_cg_load(cg, mem);
    853   kit_cg_ret(cg);
    854   kit_cg_func_end(cg);
    855 
    856   finish_cg(cg, "delayed store");
    857   kit_cg_free(cg);
    858   size = text_size(c, ob);
    859   kit_obj_builder_free(ob);
    860   return size;
    861 }
    862 
    863 static uint32_t cg_emit_delayed_pressure(KitCompiler* c, KitCgTypeId i32_ty,
    864                                          const char* name) {
    865   enum { NPARAMS = 13 };
    866   KitCodeOptions opts;
    867   KitObjBuilder* ob;
    868   KitCg* cg;
    869   KitCgFuncParam param_desc[NPARAMS];
    870   KitCgFuncSig sig;
    871   KitCgDecl decl;
    872   KitCgSym sym;
    873   KitCgLocalAttrs attrs;
    874   KitCgLocal params[NPARAMS];
    875   KitCgMemAccess mem;
    876   uint32_t size;
    877 
    878   memset(&opts, 0, sizeof opts);
    879   opts.opt_level = 1;
    880   ob = new_obj(c);
    881   EXPECT(ob != NULL, "delayed pressure obj builder allocation failed");
    882   if (!ob) return 0;
    883   cg = NULL;
    884   (void)kit_cg_new(c, &cg);
    885   if (cg) (void)kit_cg_begin(cg, ob, &opts);
    886   EXPECT(cg != NULL, "delayed pressure cg allocation failed");
    887   if (!cg) {
    888     kit_obj_builder_free(ob);
    889     return 0;
    890   }
    891 
    892   memset(param_desc, 0, sizeof param_desc);
    893   for (uint32_t i = 0; i < NPARAMS; ++i) param_desc[i].type = i32_ty;
    894   memset(&sig, 0, sizeof sig);
    895   KitCgFuncResult sig_result;
    896   memset(&sig_result, 0, sizeof sig_result);
    897   sig_result.type = i32_ty;
    898   sig.result = sig_result;
    899   sig.params = param_desc;
    900   sig.nparams = NPARAMS;
    901   sig.call_conv = KIT_CG_CC_TARGET_C;
    902 
    903   memset(&decl, 0, sizeof decl);
    904   decl.kind = KIT_CG_DECL_FUNC;
    905   decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name));
    906   decl.display_name = decl.linkage_name;
    907   decl.type = kit_cg_type_func(c, sig);
    908   decl.sym.bind = KIT_SB_GLOBAL;
    909   decl.sym.visibility = KIT_CG_VIS_DEFAULT;
    910   sym = kit_cg_decl(cg, decl);
    911   EXPECT(sym != KIT_CG_SYM_NONE, "delayed pressure decl failed");
    912 
    913   kit_cg_func_begin(cg, sym);
    914   memset(&attrs, 0, sizeof attrs);
    915   memset(&mem, 0, sizeof mem);
    916   mem.type = i32_ty;
    917   mem.align = kit_cg_type_align(c, i32_ty);
    918   for (uint32_t i = 0; i < NPARAMS; ++i) {
    919     char pname[8];
    920     snprintf(pname, sizeof pname, "p%u", (unsigned)i);
    921     attrs.name = kit_sym_intern(c, kit_slice_cstr(pname));
    922     params[i] = kit_cg_param(cg, i, i32_ty, attrs);
    923     EXPECT(params[i] != KIT_CG_LOCAL_NONE, "delayed pressure param failed");
    924   }
    925 
    926   for (uint32_t i = 0; i + 1 < NPARAMS; ++i) {
    927     kit_cg_push_local(cg, params[i]);
    928     kit_cg_load(cg, mem);
    929     kit_cg_push_int(cg, 1, i32_ty);
    930     kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0);
    931   }
    932   kit_cg_push_local(cg, params[NPARAMS - 1]);
    933   kit_cg_load(cg, mem);
    934   kit_cg_drop(cg);
    935   for (uint32_t i = 0; i + 1 < NPARAMS; ++i) kit_cg_drop(cg);
    936   kit_cg_push_int(cg, 0, i32_ty);
    937   kit_cg_ret(cg);
    938   kit_cg_func_end(cg);
    939 
    940   finish_cg(cg, "delayed pressure");
    941   kit_cg_free(cg);
    942   size = text_size(c, ob);
    943   kit_obj_builder_free(ob);
    944   return size;
    945 }
    946 
    947 typedef enum CgShadowBoundary {
    948   CG_SHADOW_LABEL,
    949   CG_SHADOW_BRANCH,
    950   CG_SHADOW_ADDR,
    951   CG_SHADOW_VOLATILE,
    952   CG_SHADOW_INDIRECT_STORE,
    953 } CgShadowBoundary;
    954 
    955 static uint32_t cg_emit_local_shadow_boundary(KitCompiler* c,
    956                                               KitCgTypeId i32_ty,
    957                                               const char* name,
    958                                               CgShadowBoundary boundary) {
    959   KitCodeOptions opts;
    960   KitObjBuilder* ob;
    961   KitCg* cg;
    962   KitCgFuncSig sig;
    963   KitCgDecl decl;
    964   KitCgSym sym;
    965   KitCgLocalAttrs attrs;
    966   KitCgLocal local;
    967   KitCgMemAccess mem;
    968   uint32_t size;
    969 
    970   memset(&opts, 0, sizeof opts);
    971   opts.opt_level = 1;
    972   ob = new_obj(c);
    973   EXPECT(ob != NULL, "local shadow boundary obj builder allocation failed");
    974   if (!ob) return 0;
    975   cg = NULL;
    976   (void)kit_cg_new(c, &cg);
    977   if (cg) (void)kit_cg_begin(cg, ob, &opts);
    978   EXPECT(cg != NULL, "local shadow boundary cg allocation failed");
    979   if (!cg) {
    980     kit_obj_builder_free(ob);
    981     return 0;
    982   }
    983 
    984   memset(&sig, 0, sizeof sig);
    985   KitCgFuncResult sig_result;
    986   memset(&sig_result, 0, sizeof sig_result);
    987   sig_result.type = i32_ty;
    988   sig.result = sig_result;
    989   sig.call_conv = KIT_CG_CC_TARGET_C;
    990 
    991   memset(&decl, 0, sizeof decl);
    992   decl.kind = KIT_CG_DECL_FUNC;
    993   decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name));
    994   decl.display_name = decl.linkage_name;
    995   decl.type = kit_cg_type_func(c, sig);
    996   decl.sym.bind = KIT_SB_GLOBAL;
    997   decl.sym.visibility = KIT_CG_VIS_DEFAULT;
    998   sym = kit_cg_decl(cg, decl);
    999   EXPECT(sym != KIT_CG_SYM_NONE, "local shadow boundary decl failed");
   1000 
   1001   kit_cg_func_begin(cg, sym);
   1002   memset(&attrs, 0, sizeof attrs);
   1003   attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("x"));
   1004   local = kit_cg_local(cg, i32_ty, attrs);
   1005   EXPECT(local != KIT_CG_LOCAL_NONE, "local shadow boundary local failed");
   1006   memset(&mem, 0, sizeof mem);
   1007   mem.type = i32_ty;
   1008   mem.align = kit_cg_type_align(c, i32_ty);
   1009 
   1010   kit_cg_push_local(cg, local);
   1011   kit_cg_push_int(cg, 40, i32_ty);
   1012   kit_cg_store(cg, mem);
   1013 
   1014   switch (boundary) {
   1015     case CG_SHADOW_LABEL: {
   1016       KitCgLabel label = kit_cg_label_new(cg);
   1017       kit_cg_label_place(cg, label);
   1018       break;
   1019     }
   1020     case CG_SHADOW_BRANCH: {
   1021       KitCgLabel label = kit_cg_label_new(cg);
   1022       kit_cg_push_int(cg, 0, i32_ty);
   1023       kit_cg_branch_true(cg, label);
   1024       kit_cg_label_place(cg, label);
   1025       break;
   1026     }
   1027     case CG_SHADOW_ADDR:
   1028       kit_cg_push_local_addr(cg, local);
   1029       kit_cg_drop(cg);
   1030       break;
   1031     case CG_SHADOW_VOLATILE:
   1032       mem.flags = KIT_CG_MEM_VOLATILE;
   1033       kit_cg_push_local(cg, local);
   1034       kit_cg_load(cg, mem);
   1035       kit_cg_drop(cg);
   1036       mem.flags = 0;
   1037       break;
   1038     case CG_SHADOW_INDIRECT_STORE:
   1039       kit_cg_push_local_addr(cg, local);
   1040       kit_cg_deref(cg, 0); /* pointer VALUE -> PLACE for the store */
   1041       kit_cg_push_int(cg, 41, i32_ty);
   1042       kit_cg_store(cg, mem);
   1043       break;
   1044   }
   1045 
   1046   kit_cg_push_local(cg, local);
   1047   kit_cg_load(cg, mem);
   1048   kit_cg_push_int(cg, 2, i32_ty);
   1049   kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0);
   1050   kit_cg_ret(cg);
   1051   kit_cg_func_end(cg);
   1052 
   1053   finish_cg(cg, "local shadow boundary");
   1054   kit_cg_free(cg);
   1055   size = text_size(c, ob);
   1056   kit_obj_builder_free(ob);
   1057   return size;
   1058 }
   1059 
   1060 static uint32_t cg_emit_local_shadow_partial_store(KitCompiler* c,
   1061                                                    KitCgTypeId i32_ty,
   1062                                                    KitCgTypeId i8_ty,
   1063                                                    const char* name) {
   1064   KitCodeOptions opts;
   1065   KitObjBuilder* ob;
   1066   KitCg* cg;
   1067   KitCgFuncSig sig;
   1068   KitCgDecl decl;
   1069   KitCgSym sym;
   1070   KitCgLocalAttrs attrs;
   1071   KitCgLocal local;
   1072   KitCgMemAccess mem_i32;
   1073   KitCgMemAccess mem_i8;
   1074   uint32_t size;
   1075 
   1076   memset(&opts, 0, sizeof opts);
   1077   opts.opt_level = 1;
   1078   ob = new_obj(c);
   1079   EXPECT(ob != NULL, "partial shadow obj builder allocation failed");
   1080   if (!ob) return 0;
   1081   cg = NULL;
   1082   (void)kit_cg_new(c, &cg);
   1083   if (cg) (void)kit_cg_begin(cg, ob, &opts);
   1084   EXPECT(cg != NULL, "partial shadow cg allocation failed");
   1085   if (!cg) {
   1086     kit_obj_builder_free(ob);
   1087     return 0;
   1088   }
   1089 
   1090   memset(&sig, 0, sizeof sig);
   1091   KitCgFuncResult sig_result;
   1092   memset(&sig_result, 0, sizeof sig_result);
   1093   sig_result.type = i32_ty;
   1094   sig.result = sig_result;
   1095   sig.call_conv = KIT_CG_CC_TARGET_C;
   1096 
   1097   memset(&decl, 0, sizeof decl);
   1098   decl.kind = KIT_CG_DECL_FUNC;
   1099   decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name));
   1100   decl.display_name = decl.linkage_name;
   1101   decl.type = kit_cg_type_func(c, sig);
   1102   decl.sym.bind = KIT_SB_GLOBAL;
   1103   decl.sym.visibility = KIT_CG_VIS_DEFAULT;
   1104   sym = kit_cg_decl(cg, decl);
   1105   EXPECT(sym != KIT_CG_SYM_NONE, "partial shadow decl failed");
   1106 
   1107   kit_cg_func_begin(cg, sym);
   1108   memset(&attrs, 0, sizeof attrs);
   1109   attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("x"));
   1110   local = kit_cg_local(cg, i32_ty, attrs);
   1111   EXPECT(local != KIT_CG_LOCAL_NONE, "partial shadow local failed");
   1112   memset(&mem_i32, 0, sizeof mem_i32);
   1113   mem_i32.type = i32_ty;
   1114   mem_i32.align = kit_cg_type_align(c, i32_ty);
   1115   memset(&mem_i8, 0, sizeof mem_i8);
   1116   mem_i8.type = i8_ty;
   1117   mem_i8.align = kit_cg_type_align(c, i8_ty);
   1118 
   1119   kit_cg_push_local(cg, local);
   1120   kit_cg_push_int(cg, 40, i32_ty);
   1121   kit_cg_store(cg, mem_i32);
   1122   kit_cg_push_local(cg, local);
   1123   kit_cg_push_int(cg, 7, i8_ty);
   1124   kit_cg_store(cg, mem_i8);
   1125   kit_cg_push_local(cg, local);
   1126   kit_cg_load(cg, mem_i32);
   1127   kit_cg_push_int(cg, 2, i32_ty);
   1128   kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0);
   1129   kit_cg_ret(cg);
   1130   kit_cg_func_end(cg);
   1131 
   1132   finish_cg(cg, "partial shadow");
   1133   kit_cg_free(cg);
   1134   size = text_size(c, ob);
   1135   kit_obj_builder_free(ob);
   1136   return size;
   1137 }
   1138 
   1139 static void exercise_cg_constfold_phases(KitCompiler* c, KitCgTypeId i32_ty,
   1140                                          KitCgTypeId i8_ty) {
   1141   uint32_t delayed_size =
   1142       cg_emit_delayed_chain(c, i32_ty, "cg_delayed_chain_o1");
   1143   uint32_t unary_size = cg_emit_unary_chain(c, i32_ty, "cg_unary_chain_o1");
   1144   uint32_t local_size = cg_emit_local_shadow(c, i32_ty, "cg_local_shadow_o1");
   1145   uint32_t delayed_cmp_size =
   1146       cg_emit_delayed_cmp(c, i32_ty, "cg_delayed_cmp_o1");
   1147   uint32_t delayed_store_size =
   1148       cg_emit_delayed_store(c, i32_ty, "cg_delayed_store_o1");
   1149   uint32_t pressure_size =
   1150       cg_emit_delayed_pressure(c, i32_ty, "cg_delayed_pressure_o1");
   1151   uint32_t label_size = cg_emit_local_shadow_boundary(
   1152       c, i32_ty, "cg_shadow_label_o1", CG_SHADOW_LABEL);
   1153   uint32_t branch_size = cg_emit_local_shadow_boundary(
   1154       c, i32_ty, "cg_shadow_branch_o1", CG_SHADOW_BRANCH);
   1155   uint32_t addr_size = cg_emit_local_shadow_boundary(
   1156       c, i32_ty, "cg_shadow_addr_o1", CG_SHADOW_ADDR);
   1157   uint32_t volatile_size = cg_emit_local_shadow_boundary(
   1158       c, i32_ty, "cg_shadow_volatile_o1", CG_SHADOW_VOLATILE);
   1159   uint32_t indirect_size = cg_emit_local_shadow_boundary(
   1160       c, i32_ty, "cg_shadow_indirect_o1", CG_SHADOW_INDIRECT_STORE);
   1161   uint32_t partial_size = cg_emit_local_shadow_partial_store(
   1162       c, i32_ty, i8_ty, "cg_shadow_partial_o1");
   1163 
   1164   EXPECT(delayed_size <= 56,
   1165          "delayed arithmetic chain should materialize as one add, text "
   1166          "size=%u",
   1167          delayed_size);
   1168   EXPECT(unary_size <= 48,
   1169          "delayed unary chain should collapse before return, text size=%u",
   1170          unary_size);
   1171   EXPECT(local_size <= 32,
   1172          "local constant shadow should fold x=40; return x+2, text size=%u",
   1173          local_size);
   1174   EXPECT(delayed_cmp_size <= 64,
   1175          "delayed arithmetic consumed by compare should stay compact, text "
   1176          "size=%u",
   1177          delayed_cmp_size);
   1178   EXPECT(delayed_store_size <= 64,
   1179          "delayed arithmetic forced by store should stay compact, text size=%u",
   1180          delayed_store_size);
   1181   EXPECT(pressure_size > 0,
   1182          "delayed arithmetic pressure materialization should emit code");
   1183   EXPECT(label_size > local_size,
   1184          "label should clear local shadow, label=%u folded=%u", label_size,
   1185          local_size);
   1186   EXPECT(branch_size > local_size,
   1187          "branch should clear local shadow, branch=%u folded=%u", branch_size,
   1188          local_size);
   1189   EXPECT(addr_size > local_size,
   1190          "address-taking should clear local shadow, addr=%u folded=%u",
   1191          addr_size, local_size);
   1192   EXPECT(volatile_size > local_size,
   1193          "volatile access should clear local shadow, volatile=%u folded=%u",
   1194          volatile_size, local_size);
   1195   EXPECT(indirect_size > local_size,
   1196          "indirect store should clear local shadow, indirect=%u folded=%u",
   1197          indirect_size, local_size);
   1198   EXPECT(partial_size > local_size,
   1199          "partial-width store should clear local shadow, partial=%u folded=%u",
   1200          partial_size, local_size);
   1201 }
   1202 
   1203 typedef struct BadStoreCtx {
   1204   KitCompiler* c;
   1205   KitCgTypeId i32_ty;
   1206   KitCgTypeId i64_ty;
   1207   KitCgTypeId rec_ty;
   1208 } BadStoreCtx;
   1209 
   1210 static KitCg* cg_begin_bad_store_func(KitCompiler* c, const char* name) {
   1211   KitCodeOptions opts;
   1212   KitObjBuilder* ob;
   1213   KitCg* cg;
   1214   KitCgFuncSig sig;
   1215   KitCgDecl decl;
   1216   KitCgSym sym;
   1217 
   1218   memset(&opts, 0, sizeof opts);
   1219   ob = new_obj(c);
   1220   EXPECT(ob != NULL, "bad-store obj builder allocation failed");
   1221   if (!ob) return NULL;
   1222   cg = NULL;
   1223   (void)kit_cg_new(c, &cg);
   1224   if (cg) (void)kit_cg_begin(cg, ob, &opts);
   1225   EXPECT(cg != NULL, "bad-store cg allocation failed");
   1226   if (!cg) {
   1227     kit_obj_builder_free(ob);
   1228     return NULL;
   1229   }
   1230 
   1231   memset(&sig, 0, sizeof sig);
   1232   sig.call_conv = KIT_CG_CC_TARGET_C;
   1233   memset(&decl, 0, sizeof decl);
   1234   decl.kind = KIT_CG_DECL_FUNC;
   1235   decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name));
   1236   decl.display_name = decl.linkage_name;
   1237   decl.type = kit_cg_type_func(c, sig);
   1238   decl.sym.bind = KIT_SB_LOCAL;
   1239   decl.sym.visibility = KIT_CG_VIS_DEFAULT;
   1240   sym = kit_cg_decl(cg, decl);
   1241   EXPECT(sym != KIT_CG_SYM_NONE, "bad-store function decl failed");
   1242   kit_cg_func_begin(cg, sym);
   1243   return cg;
   1244 }
   1245 
   1246 static void run_bad_scalar_access_to_aggregate(void* arg) {
   1247   BadStoreCtx* ctx = (BadStoreCtx*)arg;
   1248   KitCgLocal local;
   1249   KitCgLocalAttrs attrs;
   1250   KitCgMemAccess mem;
   1251   KitCg* cg =
   1252       cg_begin_bad_store_func(ctx->c, "cg_bad_scalar_access_to_aggregate");
   1253   if (!cg) return;
   1254 
   1255   memset(&attrs, 0, sizeof attrs);
   1256   local = kit_cg_local(cg, ctx->rec_ty, attrs);
   1257   memset(&mem, 0, sizeof mem);
   1258   mem.type = ctx->i32_ty;
   1259   mem.align = kit_cg_type_align(ctx->c, ctx->i32_ty);
   1260   kit_cg_push_local(cg, local);
   1261   kit_cg_push_int(cg, 42, ctx->i32_ty);
   1262   kit_cg_store(cg, mem);
   1263 }
   1264 
   1265 static void run_bad_store_value_size(void* arg) {
   1266   BadStoreCtx* ctx = (BadStoreCtx*)arg;
   1267   KitCgLocal local;
   1268   KitCgLocalAttrs attrs;
   1269   KitCgMemAccess mem;
   1270   KitCg* cg = cg_begin_bad_store_func(ctx->c, "cg_bad_store_value_size");
   1271   if (!cg) return;
   1272 
   1273   memset(&attrs, 0, sizeof attrs);
   1274   local = kit_cg_local(cg, ctx->i64_ty, attrs);
   1275   memset(&mem, 0, sizeof mem);
   1276   mem.type = ctx->i64_ty;
   1277   mem.align = kit_cg_type_align(ctx->c, ctx->i64_ty);
   1278   kit_cg_push_local(cg, local);
   1279   kit_cg_push_int(cg, 42, ctx->i32_ty);
   1280   kit_cg_store(cg, mem);
   1281 }
   1282 
   1283 static void exercise_cg_memory_mismatch_diags(KitCompiler* c,
   1284                                               KitCgTypeId i32_ty,
   1285                                               KitCgTypeId i64_ty,
   1286                                               KitCgTypeId rec_ty) {
   1287   BadStoreCtx ctx;
   1288   ctx.c = c;
   1289   ctx.i32_ty = i32_ty;
   1290   ctx.i64_ty = i64_ty;
   1291   ctx.rec_ty = rec_ty;
   1292 
   1293   /* Scalar store at offset 0 into an aggregate lvalue is now a field-store
   1294    * under the EA model (see doc/INDIRECT.md), so no diagnostic fires. */
   1295   (void)run_bad_scalar_access_to_aggregate;
   1296   EXPECT(expect_panic_contains(c, run_bad_store_value_size, &ctx,
   1297                                "store value type/size mismatch"),
   1298          "store size mismatch should diagnose clearly, got '%s'",
   1299          g_u.last_diag);
   1300 }
   1301 
   1302 static void exercise_compile_session_two_deltas(KitCompiler* c) {
   1303   KitCompileSessionOptions sopts;
   1304   KitCompileSession* s = NULL;
   1305   KitAsmCompileOptions aopts;
   1306   KitSourceInput in;
   1307   KitObjBuilder* ob1 = NULL;
   1308   KitObjBuilder* ob2 = NULL;
   1309   static const uint8_t empty[] = "";
   1310 
   1311   memset(&sopts, 0, sizeof(sopts));
   1312   memset(&aopts, 0, sizeof(aopts));
   1313   sopts.lang = KIT_LANG_ASM;
   1314   sopts.compile.language_options = &aopts;
   1315   memset(&in, 0, sizeof(in));
   1316   in.name = KIT_SLICE_LIT("<api-session-asm>");
   1317   in.bytes.data = empty;
   1318   in.bytes.len = 0;
   1319   in.lang = KIT_LANG_ASM;
   1320 
   1321   EXPECT(kit_compile_session_new(c, &sopts, &s) == KIT_OK && s,
   1322          "compile session new failed");
   1323   if (!s) return;
   1324   EXPECT(kit_compile_session_compile(s, &in, &ob1) == KIT_OK && ob1,
   1325          "compile session first delta failed");
   1326   EXPECT(kit_compile_session_compile(s, &in, &ob2) == KIT_OK && ob2,
   1327          "compile session second delta failed");
   1328   kit_obj_builder_free(ob1);
   1329   kit_obj_builder_free(ob2);
   1330   kit_compile_session_free(s);
   1331 }
   1332 
   1333 static void exercise_cg_begin_end_two_objects(KitCompiler* c) {
   1334   KitCg* cg = NULL;
   1335   KitObjBuilder* ob1 = NULL;
   1336   KitObjBuilder* ob2 = NULL;
   1337   KitCodeOptions opts;
   1338 
   1339   memset(&opts, 0, sizeof(opts));
   1340   ob1 = new_obj(c);
   1341   ob2 = new_obj(c);
   1342   EXPECT(ob1 && ob2, "obj builder allocation failed for cg begin/end session");
   1343   EXPECT(kit_cg_new(c, &cg) == KIT_OK && cg, "cg session new failed");
   1344   if (cg && ob1) {
   1345     EXPECT(kit_cg_begin(cg, ob1, &opts) == KIT_OK,
   1346            "cg begin first object failed");
   1347     EXPECT(kit_cg_finish(cg, NULL) == KIT_OK, "cg finish first object failed");
   1348     EXPECT(kit_cg_detach(cg) == KIT_OK, "cg detach first object failed");
   1349   }
   1350   if (cg && ob2) {
   1351     EXPECT(kit_cg_begin(cg, ob2, &opts) == KIT_OK,
   1352            "cg begin second object failed");
   1353     EXPECT(kit_cg_finish(cg, NULL) == KIT_OK,
   1354            "cg finish second object failed");
   1355     EXPECT(kit_cg_detach(cg) == KIT_OK, "cg detach second object failed");
   1356   }
   1357   kit_cg_free(cg);
   1358   kit_obj_builder_free(ob1);
   1359   kit_obj_builder_free(ob2);
   1360 }
   1361 
   1362 static void exercise_cg_free_does_not_finish(KitCompiler* c,
   1363                                              KitCgTypeId i32_ty) {
   1364   KitCodeOptions opts;
   1365   KitCgUnitOptions unit_opts;
   1366   KitObjBuilder* ob = NULL;
   1367   KitCg* cg = NULL;
   1368   KitCgFuncSig sig;
   1369   KitCgDecl decl;
   1370   KitCgSym sym;
   1371 
   1372   memset(&opts, 0, sizeof opts);
   1373   opts.opt_level = 1;
   1374   ob = new_obj(c);
   1375   EXPECT(ob != NULL, "no-finish obj builder allocation failed");
   1376   if (!ob) return;
   1377   EXPECT(kit_cg_new(c, &cg) == KIT_OK && cg, "no-finish cg new failed");
   1378   if (!cg) {
   1379     kit_obj_builder_free(ob);
   1380     return;
   1381   }
   1382   EXPECT(kit_cg_begin(cg, ob, &opts) == KIT_OK, "no-finish cg begin failed");
   1383   memset(&unit_opts, 0, sizeof unit_opts);
   1384   unit_opts.source_name = KIT_SLICE_LIT("cg_free_does_not_finish.c");
   1385   EXPECT(kit_cg_begin_unit(cg, &unit_opts) == KIT_OK,
   1386          "no-finish begin unit failed");
   1387 
   1388   memset(&sig, 0, sizeof sig);
   1389   {
   1390     KitCgFuncResult result;
   1391     memset(&result, 0, sizeof result);
   1392     result.type = i32_ty;
   1393     sig.result = result;
   1394     sig.call_conv = KIT_CG_CC_TARGET_C;
   1395 
   1396     memset(&decl, 0, sizeof decl);
   1397     decl.kind = KIT_CG_DECL_FUNC;
   1398     decl.linkage_name =
   1399         kit_sym_intern(c, KIT_SLICE_LIT("cg_free_does_not_finish"));
   1400     decl.display_name = decl.linkage_name;
   1401     decl.type = kit_cg_type_func(c, sig);
   1402     decl.sym.bind = KIT_SB_GLOBAL;
   1403     decl.sym.visibility = KIT_CG_VIS_DEFAULT;
   1404     sym = kit_cg_decl(cg, decl);
   1405   }
   1406   EXPECT(sym != KIT_CG_SYM_NONE, "no-finish decl failed");
   1407   kit_cg_func_begin(cg, sym);
   1408   kit_cg_push_int(cg, 42, i32_ty);
   1409   kit_cg_ret(cg);
   1410   kit_cg_func_end(cg);
   1411   EXPECT(kit_cg_end_unit(cg) == KIT_OK, "no-finish end unit failed");
   1412 
   1413   kit_cg_free(cg);
   1414   EXPECT(kit_obj_builder_finalize(ob) == KIT_OK,
   1415          "no-finish explicit object finalize failed");
   1416   EXPECT(text_size(c, ob) == 0,
   1417          "kit_cg_free must not lower optimized IR into the object");
   1418   kit_obj_builder_free(ob);
   1419 }
   1420 
   1421 int main(void) {
   1422   KitTargetSpec target;
   1423   KitCompiler* c;
   1424   KitCgBuiltinTypes bi;
   1425   KitCgTypeId void_ty;
   1426   KitCgTypeId i8_ty;
   1427   KitCgTypeId i32_ty;
   1428   KitCgTypeId i64_ty;
   1429   KitCgTypeId f64_ty;
   1430   KitCgTypeId va_list_ty;
   1431   KitCgTypeId ptr_i32;
   1432   KitCgTypeId array_i32;
   1433   KitCgFuncParam params[2];
   1434   KitCgFuncSig sig;
   1435   KitCgTypeId fn;
   1436   KitCgTypeId alias;
   1437   KitCgTypeId rec;
   1438   KitCgTypeId rec_ex;
   1439   KitCgTypeId enm;
   1440   KitCgRecordDesc rdesc;
   1441   KitCgField fields[2];
   1442   KitCgField field_out;
   1443   KitCgEnumValue vals[2];
   1444   uint64_t field_off;
   1445 
   1446   kit_unit_init(&g_u);
   1447   target = kit_unit_target(KIT_ARCH_ARM_64, KIT_OS_LINUX, KIT_OBJ_ELF);
   1448 
   1449   c = NULL;
   1450   if (kit_unit_compiler_new(&g_u, target, &c) != KIT_OK || !c) {
   1451     fprintf(stderr, "compiler_new failed\n");
   1452     return 2;
   1453   }
   1454 
   1455   bi = kit_cg_builtin_types(c);
   1456   void_ty = bi.id[KIT_CG_BUILTIN_VOID];
   1457   i8_ty = bi.id[KIT_CG_BUILTIN_I8];
   1458   i32_ty = bi.id[KIT_CG_BUILTIN_I32];
   1459   i64_ty = bi.id[KIT_CG_BUILTIN_I64];
   1460   f64_ty = bi.id[KIT_CG_BUILTIN_F64];
   1461   va_list_ty = bi.id[KIT_CG_BUILTIN_VARARG_STATE];
   1462   EXPECT(void_ty != KIT_CG_TYPE_NONE, "void builtin id is none");
   1463   EXPECT(i8_ty != KIT_CG_TYPE_NONE, "i8 builtin id is none");
   1464   EXPECT(i32_ty != KIT_CG_TYPE_NONE, "i32 builtin id is none");
   1465   EXPECT(f64_ty != KIT_CG_TYPE_NONE, "f64 builtin id is none");
   1466   EXPECT(va_list_ty != KIT_CG_TYPE_NONE, "va_list builtin id is none");
   1467   EXPECT(void_ty != i32_ty && i32_ty != f64_ty, "builtin ids collide");
   1468 
   1469   ptr_i32 = kit_cg_type_ptr(c, i32_ty, 0);
   1470   array_i32 = kit_cg_type_array(c, i32_ty, 4);
   1471   EXPECT(ptr_i32 != KIT_CG_TYPE_NONE, "ptr type failed");
   1472   EXPECT(array_i32 != KIT_CG_TYPE_NONE, "array type failed");
   1473   EXPECT(kit_cg_type_ptr(c, i32_ty, 0) == ptr_i32,
   1474          "ptr type id should be interned");
   1475   EXPECT(kit_cg_type_array(c, i32_ty, 4) == array_i32,
   1476          "array type id should be interned");
   1477   EXPECT(kit_cg_type_ptr(c, KIT_CG_TYPE_NONE, 0) == KIT_CG_TYPE_NONE,
   1478          "invalid pointer pointee should fail");
   1479   EXPECT(kit_cg_type_size(c, ptr_i32) == 8, "ptr size mismatch");
   1480   EXPECT(kit_cg_type_align(c, ptr_i32) == 8, "ptr align mismatch");
   1481   EXPECT(kit_cg_type_ptr_pointee(c, ptr_i32) == i32_ty, "ptr pointee mismatch");
   1482   EXPECT(kit_cg_type_array_elem(c, array_i32) == i32_ty, "array elem mismatch");
   1483   EXPECT(kit_cg_type_array_count(c, array_i32) == 4, "array count mismatch");
   1484 
   1485   alias = kit_cg_type_alias(c, kit_sym_intern(c, KIT_SLICE_LIT("I")), i32_ty);
   1486   EXPECT(alias != KIT_CG_TYPE_NONE && alias != i32_ty,
   1487          "alias id should be fresh");
   1488   EXPECT(kit_cg_type_kind(c, alias) == KIT_CG_TYPE_ALIAS,
   1489          "alias kind mismatch");
   1490   EXPECT(kit_cg_type_size(c, alias) == kit_cg_type_size(c, i32_ty),
   1491          "alias size mismatch");
   1492 
   1493   memset(fields, 0, sizeof fields);
   1494   fields[0].name = kit_sym_intern(c, KIT_SLICE_LIT("a"));
   1495   fields[0].type = i32_ty;
   1496   fields[0].align_override = 0;
   1497   fields[1].name = kit_sym_intern(c, KIT_SLICE_LIT("b"));
   1498   fields[1].type = ptr_i32;
   1499   fields[1].align_override = 1;
   1500   rec = kit_cg_type_record(c, kit_sym_intern(c, KIT_SLICE_LIT("R")), fields, 2);
   1501   EXPECT(rec != KIT_CG_TYPE_NONE, "record type failed");
   1502   EXPECT(kit_cg_type_record(c, kit_sym_intern(c, KIT_SLICE_LIT("Bad")), fields,
   1503                             0) != KIT_CG_TYPE_NONE,
   1504          "empty record type failed");
   1505   EXPECT(kit_cg_type_kind(c, rec) == KIT_CG_TYPE_RECORD,
   1506          "record kind mismatch");
   1507   EXPECT(kit_cg_type_record_nfields(c, rec) == 2,
   1508          "record field count mismatch");
   1509   EXPECT(kit_cg_type_record_field(c, rec, 1, &field_out, &field_off) == 0,
   1510          "record field query failed");
   1511   EXPECT(field_out.name == fields[1].name && field_out.type == ptr_i32,
   1512          "record field data mismatch");
   1513   EXPECT(field_off == 4, "record field offset mismatch");
   1514 
   1515   memset(fields, 0, sizeof fields);
   1516   fields[0].name = kit_sym_intern(c, KIT_SLICE_LIT("lo"));
   1517   fields[0].type = i32_ty;
   1518   fields[0].flags = KIT_CG_FIELD_BITFIELD;
   1519   fields[0].bit_width = 5;
   1520   fields[1].name = kit_sym_intern(c, KIT_SLICE_LIT("hi"));
   1521   fields[1].type = i32_ty;
   1522   fields[1].flags = KIT_CG_FIELD_BITFIELD;
   1523   fields[1].bit_width = 3;
   1524   rec_ex =
   1525       kit_cg_type_record(c, kit_sym_intern(c, KIT_SLICE_LIT("BF")), fields, 2);
   1526   EXPECT(rec_ex != KIT_CG_TYPE_NONE, "bit-field record type failed");
   1527   EXPECT(kit_cg_type_size(c, rec_ex) == 4, "bit-field record size mismatch");
   1528   EXPECT(kit_cg_type_record_field(c, rec_ex, 1, &field_out, &field_off) == 0,
   1529          "bit-field record query failed");
   1530   EXPECT(field_off == 0 && field_out.bit_offset == 5 &&
   1531              field_out.bit_width == 3 && field_out.bit_storage_size == 4,
   1532          "bit-field metadata mismatch");
   1533 
   1534   memset(fields, 0, sizeof fields);
   1535   fields[0].name = kit_sym_intern(c, KIT_SLICE_LIT("a"));
   1536   fields[0].type = i32_ty;
   1537   fields[1].name = kit_sym_intern(c, KIT_SLICE_LIT("b"));
   1538   fields[1].type = ptr_i32;
   1539   fields[1].align_override = 1;
   1540   memset(&rdesc, 0, sizeof rdesc);
   1541   rdesc.tag = kit_sym_intern(c, KIT_SLICE_LIT("U"));
   1542   rdesc.fields = fields;
   1543   rdesc.nfields = 2;
   1544   rdesc.is_union = 1;
   1545   rdesc.align_override = 16;
   1546   rec_ex = kit_cg_type_record_ex(c, &rdesc);
   1547   EXPECT(rec_ex != KIT_CG_TYPE_NONE, "record desc type failed");
   1548   EXPECT(kit_cg_type_size(c, rec_ex) == 16, "record desc size mismatch");
   1549   EXPECT(kit_cg_type_align(c, rec_ex) == 16, "record desc align mismatch");
   1550   EXPECT(kit_cg_type_record_field(c, rec_ex, 1, &field_out, &field_off) == 0,
   1551          "record desc field query failed");
   1552   EXPECT(field_off == 0, "union field offset mismatch");
   1553 
   1554   vals[0].name = kit_sym_intern(c, KIT_SLICE_LIT("A"));
   1555   vals[0].value = 1;
   1556   vals[1].name = kit_sym_intern(c, KIT_SLICE_LIT("B"));
   1557   vals[1].value = 2;
   1558   enm = kit_cg_type_enum(c, kit_sym_intern(c, KIT_SLICE_LIT("E")),
   1559                          KIT_CG_TYPE_NONE, vals, 2);
   1560   EXPECT(enm != KIT_CG_TYPE_NONE, "enum type failed");
   1561 
   1562   memset(params, 0, sizeof(params));
   1563   params[0].type = i32_ty;
   1564   params[1].type = ptr_i32;
   1565   memset(&sig, 0, sizeof(sig));
   1566   KitCgFuncResult sig_result;
   1567   memset(&sig_result, 0, sizeof sig_result);
   1568   sig_result.type = i64_ty;
   1569   sig.result = sig_result;
   1570   sig.params = params;
   1571   sig.nparams = 2;
   1572   sig.abi_variadic = 1;
   1573   sig.call_conv = KIT_CG_CC_TARGET_C;
   1574   fn = kit_cg_type_func(c, sig);
   1575   EXPECT(fn != KIT_CG_TYPE_NONE, "function type failed");
   1576   EXPECT(kit_cg_type_func(c, sig) == fn, "function type id should be interned");
   1577   EXPECT(kit_cg_type_func_result(c, fn).type == i64_ty,
   1578          "function return mismatch");
   1579   EXPECT(kit_cg_type_func_nparams(c, fn) == 2, "function param count mismatch");
   1580   EXPECT(kit_cg_type_func_param(c, fn, 1).type == ptr_i32,
   1581          "function param mismatch");
   1582   sig.nparams = 70000;
   1583   EXPECT(kit_cg_type_func(c, sig) == KIT_CG_TYPE_NONE,
   1584          "oversized function param list should fail");
   1585 
   1586   exercise_cg_handles(c, i32_ty, 0);
   1587   exercise_cg_handles(c, i32_ty, 1);
   1588   exercise_cg_scalar_local(c, i32_ty, 0);
   1589   exercise_cg_scalar_local(c, i32_ty, 1);
   1590   exercise_cg_late_local_addr(c, i32_ty, 0);
   1591   exercise_cg_late_local_addr(c, i32_ty, 1);
   1592   exercise_cg_data_entsize(c, i8_ty);
   1593   exercise_cg_literal_folds(c, i32_ty);
   1594   exercise_cg_constfold_phases(c, i32_ty, i8_ty);
   1595   exercise_cg_memory_mismatch_diags(c, i32_ty, i64_ty, rec);
   1596   exercise_compile_session_two_deltas(c);
   1597   exercise_cg_begin_end_two_objects(c);
   1598   exercise_cg_free_does_not_finish(c, i32_ty);
   1599 
   1600   kit_compiler_free(c);
   1601   kit_unit_summary(&g_u, "cg_api_test");
   1602   return kit_unit_status(&g_u);
   1603 }