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 }