kit

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

api_frontend.c (4800B)


      1 #include <kit/cg.h>
      2 #include <kit/link.h>
      3 #include <kit/target.h>
      4 
      5 typedef struct AuditArena {
      6   unsigned char* data;
      7   size_t capacity;
      8   size_t used;
      9 } AuditArena;
     10 
     11 static void* audit_alloc(KitHeap* heap, size_t size, size_t align) {
     12   AuditArena* arena = heap->user;
     13   size_t mask = align - 1;
     14   size_t start = (arena->used + mask) & ~mask;
     15   if (size > arena->capacity - start) return NULL;
     16   arena->used = start + size;
     17   return arena->data + start;
     18 }
     19 
     20 static void* audit_realloc(KitHeap* heap, void* ptr, size_t old_size,
     21                            size_t new_size, size_t align) {
     22   unsigned char* out = audit_alloc(heap, new_size, align);
     23   const unsigned char* old = ptr;
     24   size_t copy_size = old_size < new_size ? old_size : new_size;
     25   size_t i;
     26   if (!out) return NULL;
     27   for (i = 0; old && i < copy_size; ++i) out[i] = old[i];
     28   return out;
     29 }
     30 
     31 static void audit_free(KitHeap* heap, void* ptr, size_t size) {
     32   (void)heap;
     33   (void)ptr;
     34   (void)size;
     35 }
     36 
     37 static void audit_diag(KitDiagSink* sink, KitDiagKind kind, KitSrcLoc loc,
     38                        const char* fmt, va_list ap) {
     39   (void)sink;
     40   (void)kind;
     41   (void)loc;
     42   (void)fmt;
     43   (void)ap;
     44 }
     45 
     46 static int emit_object(KitCompiler* compiler, KitHeap* heap) {
     47   KitObjBuilder* object = NULL;
     48   KitCg* cg = NULL;
     49   KitWriter* writer = NULL;
     50   KitWriter* link_writer = NULL;
     51   KitLinkSession* link = NULL;
     52   KitCodeOptions code = {0};
     53   KitCgUnitOptions unit = {0};
     54   KitCgFinishOptions finish = {0};
     55   KitCgFuncSig signature = {0};
     56   KitCgDecl declaration = {0};
     57   KitLinkSessionOptions link_options = {0};
     58   KitCgTypeId i32_type;
     59   KitCgTypeId function_type;
     60   KitCgSym function;
     61   size_t object_size = 0;
     62   size_t linked_size = 0;
     63   int result = 20;
     64 
     65   if (kit_obj_builder_new(compiler, &object) != KIT_OK) goto done;
     66   if (kit_cg_new(compiler, &cg) != KIT_OK) goto done;
     67   if (kit_cg_begin(cg, object, &code) != KIT_OK) goto done;
     68   unit.source_name = KIT_SLICE_LIT("audit-language");
     69   if (kit_cg_begin_unit(cg, &unit) != KIT_OK) goto done;
     70 
     71   i32_type = kit_cg_type_builtin(compiler, KIT_CG_BUILTIN_I32);
     72   signature.result.type = i32_type;
     73   signature.call_conv = KIT_CG_CC_TARGET_C;
     74   function_type = kit_cg_type_func(compiler, signature);
     75   if (function_type == KIT_CG_TYPE_NONE) goto done;
     76 
     77   declaration.kind = KIT_CG_DECL_FUNC;
     78   declaration.linkage_name = kit_cg_c_linkage_name(
     79       compiler, kit_sym_intern(compiler, KIT_SLICE_LIT("answer")));
     80   declaration.display_name = declaration.linkage_name;
     81   declaration.type = function_type;
     82   declaration.sym.bind = KIT_SB_GLOBAL;
     83   function = kit_cg_decl(cg, declaration);
     84   if (function == KIT_CG_SYM_NONE) goto done;
     85 
     86   kit_cg_func_begin(cg, function);
     87   kit_cg_push_int(cg, 42, i32_type);
     88   kit_cg_ret(cg);
     89   kit_cg_func_end(cg);
     90 
     91   if (kit_cg_end_unit(cg) != KIT_OK) goto done;
     92   finish.output_kind = KIT_CG_OUTPUT_RELOCATABLE;
     93   if (kit_cg_finish(cg, &finish) != KIT_OK) goto done;
     94   if (kit_cg_detach(cg) != KIT_OK) goto done;
     95   if (kit_writer_mem(heap, &writer) != KIT_OK) goto done;
     96   if (kit_obj_builder_emit(object, writer) != KIT_OK) goto done;
     97   (void)kit_writer_mem_bytes(writer, &object_size);
     98   if (!object_size) {
     99     result = 21;
    100     goto done;
    101   }
    102 
    103   link_options.output_kind = KIT_LINK_OUTPUT_EXE;
    104   link_options.entry = KIT_SLICE_LIT("answer");
    105   link_options.freestanding_strict = true;
    106   if (kit_link_session_new(compiler, &link_options, &link) != KIT_OK) goto done;
    107   if (kit_link_session_add_obj(link, object) != KIT_OK) goto done;
    108   if (kit_link_session_resolve(link) != KIT_OK) goto done;
    109   if (kit_writer_mem(heap, &link_writer) != KIT_OK) goto done;
    110   if (kit_link_session_emit(link, link_writer) != KIT_OK) goto done;
    111   (void)kit_writer_mem_bytes(link_writer, &linked_size);
    112   result = linked_size ? 0 : 22;
    113 
    114 done:
    115   if (link_writer) kit_writer_close(link_writer);
    116   if (link) kit_link_session_free(link);
    117   if (writer) kit_writer_close(writer);
    118   if (cg) kit_cg_free(cg);
    119   if (object) kit_obj_builder_free(object);
    120   return result;
    121 }
    122 
    123 int main(void) {
    124   unsigned char storage[4u * 1024u * 1024u];
    125   AuditArena arena = {storage, sizeof(storage), 0};
    126   KitHeap heap = {audit_alloc, audit_realloc, audit_free, &arena};
    127   KitDiagSink diag = {audit_diag, NULL, 0, 0};
    128   KitContext context = {&heap, NULL, &diag, NULL, -1};
    129   KitTargetSpec spec;
    130   KitTargetOptions options = {0};
    131   KitTarget* target = NULL;
    132   KitCompiler* compiler = NULL;
    133   int result;
    134 
    135   if (!kit_target_from_triple("aarch64-none-elf", &spec)) return 10;
    136   options.spec = spec;
    137   if (kit_target_new(&context, &options, &target) != KIT_OK) return 11;
    138   if (kit_compiler_new(target, &context, &compiler) != KIT_OK) {
    139     kit_target_free(target);
    140     return 12;
    141   }
    142   result = emit_object(compiler, &heap);
    143   kit_compiler_free(compiler);
    144   kit_target_free(target);
    145   return result;
    146 }