From: Brendan Hansen Date: Tue, 20 Apr 2021 01:14:41 +0000 (-0500) Subject: implemented Entity_Type_Memory_Reservation X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=2f36625167bb02e4e8e9c2046d707755da22647e;p=onyx.git implemented Entity_Type_Memory_Reservation --- diff --git a/build.bat b/build.bat index 3e3bc625..60977bac 100644 --- a/build.bat +++ b/build.bat @@ -1,6 +1,6 @@ @echo off -set SOURCE_FILES=src/onyx.c src/onyxastnodes.c src/onyxbuiltins.c src/onyxchecker.c src/onyxclone.c src/onyxdoc.c src/onyxentities.c src/onyxerrors.c src/onyxlex.c src/onyxparser.c src/onyxsymres.c src/onyxtypes.c src/onyxutils.c src/onyxwasm.c src/onyxc.c +set SOURCE_FILES=src/onyx.c src/onyxastnodes.c src/onyxbuiltins.c src/onyxchecker.c src/onyxclone.c src/onyxdoc.c src/onyxentities.c src/onyxerrors.c src/onyxlex.c src/onyxparser.c src/onyxsymres.c src/onyxtypes.c src/onyxutils.c src/onyxc.c if "%1" == "1" ( set FLAGS=/O2 /MT /Z7 diff --git a/include/onyxc.h b/include/onyxc.h index 25902420..ceb6f2f6 100644 --- a/include/onyxc.h +++ b/include/onyxc.h @@ -7,7 +7,7 @@ typedef struct CMemoryReservation { i32 number; i32 size; - void* initial_value; + u8 * initial_value; } CMemoryReservation; typedef struct CStringLiteral { diff --git a/src/onyxc.c b/src/onyxc.c index 80786689..5c819621 100644 --- a/src/onyxc.c +++ b/src/onyxc.c @@ -2,6 +2,137 @@ #include "onyxutils.h" #include "onyxerrors.h" +static void emit_raw_data(OnyxCFile* c_file, ptr data, AstTyped* node) { + switch (node->kind) { + case Ast_Kind_Array_Literal: { + AstArrayLiteral* al = (AstArrayLiteral *) node; + + i32 i = 0; + i32 elem_size = type_size_of(al->type->Array.elem); + + bh_arr_each(AstTyped *, expr, al->values) { + emit_raw_data(c_file, bh_pointer_add(data, i * elem_size), *expr); + i++; + } + + break; + } + + case Ast_Kind_Struct_Literal: { + AstStructLiteral* sl = (AstStructLiteral *) node; + + Type* sl_type = sl->type; + assert(sl_type->kind == Type_Kind_Struct); + + i32 i = 0; + bh_arr_each(AstTyped *, expr, sl->args.values) { + emit_raw_data(c_file, bh_pointer_add(data, sl_type->Struct.memarr[i]->offset), *expr); + i++; + } + + break; + } + + case Ast_Kind_StrLit: { + AstStrLit* sl = (AstStrLit *) node; + + // NOTE: This assumes the address and the length fields have been filled out + // by emit_string_literal. + u32* sdata = (u32 *) data; + sdata[0] = sl->addr; + sdata[1] = 0x00; + sdata[2] = sl->length; + break; + } + + case Ast_Kind_Enum_Value: { + AstEnumValue* ev = (AstEnumValue *) node; + emit_raw_data(c_file, data, (AstTyped *) ev->value); + break; + } + + case Ast_Kind_Function: { + AstFunction* func = (AstFunction *) node; + *((u32 *) data) = 0; // :Imcomplete + break; + } + + case Ast_Kind_NumLit: { + // NOTE: This makes a big assumption that we are running on a + // little endian machine, since WebAssembly is little endian + // by specification. This is probably a safe assumption, but + // should probably be fixed at some point. + // - brendanfh 2020/12/15 + + Type* effective_type = node->type; + + if (effective_type->kind == Type_Kind_Enum) + effective_type = effective_type->Enum.backing; + + switch (effective_type->Basic.kind) { + case Basic_Kind_Bool: + case Basic_Kind_I8: + case Basic_Kind_U8: + *((i8 *) data) = (i8) ((AstNumLit *) node)->value.i; + return; + + case Basic_Kind_I16: + case Basic_Kind_U16: + *((i16 *) data) = (i16) ((AstNumLit *) node)->value.i; + return; + + case Basic_Kind_I32: + case Basic_Kind_U32: + *((i32 *) data) = ((AstNumLit *) node)->value.i; + return; + + case Basic_Kind_I64: + case Basic_Kind_U64: + case Basic_Kind_Rawptr: + *((i64 *) data) = ((AstNumLit *) node)->value.l; + return; + + case Basic_Kind_F32: + *((f32 *) data) = ((AstNumLit *) node)->value.f; + return; + + case Basic_Kind_F64: + *((f64 *) data) = ((AstNumLit *) node)->value.d; + return; + + default: break; + } + + //fallthrough + } + default: onyx_report_error(node->token->pos, + "Cannot generate constant data for '%s'.", + onyx_ast_node_kind_string(node->kind)); + } +} + +static void emit_memory_reservation(OnyxCFile* c_file, AstMemRes* memres) { + Type* effective_type = memres->type; + + u64 alignment = type_alignment_of(effective_type); + u64 size = type_size_of(effective_type); + u8* data = NULL; + + if (memres->initial_value != NULL) { + data = bh_alloc(global_heap_allocator, size); + emit_raw_data(c_file, data, memres->initial_value); + } + + CMemoryReservation cmr = { + .number = bh_arr_length(c_file->memory_reservations), + .size = size, + .initial_value = (u8 *) data, + }; + + bh_arr_push(c_file->memory_reservations, cmr); + memres->addr = cmr.number; +} + // :Duplicated static void emit_string_literal(OnyxCFile* c_file, AstStrLit* strlit) { i8* strdata = bh_alloc_array(global_heap_allocator, i8, strlit->token->length + 1); @@ -84,6 +215,11 @@ void emit_c_entity(Entity *ent) { emit_file_contents(c_file, ent->file_contents); break; } + + case Entity_Type_Memory_Reservation: { + emit_memory_reservation(c_file, ent->mem_res); + break; + } } ent->state = Entity_State_Finalized; @@ -107,5 +243,11 @@ OnyxCFile onyx_c_file_create(bh_allocator alloc) { return cfile; } +void onyx_c_file_free(OnyxCFile* c_file) { + bh_arr_free(c_file->memory_reservations); + bh_table_free(c_file->string_literals); + bh_table_free(c_file->loaded_file_info); +} + #include "onyxc_output.c" diff --git a/src/onyxc_output.c b/src/onyxc_output.c index 40cc4894..32264d80 100644 --- a/src/onyxc_output.c +++ b/src/onyxc_output.c @@ -40,6 +40,22 @@ static char* ENTRYPOINT = " return 0;\n" "}\n\n"; +static void output_memory_reservations(OnyxCFile* c_file, bh_file file) { + bh_fprintf(&file, "// Memory reservations\n"); + bh_arr_each(CMemoryReservation, value, c_file->memory_reservations) { + if (value->initial_value == NULL) { + bh_fprintf(&file, "static u8 __memory%d[%d] = { 0 };", value->number, value->size); + } else { + bh_fprintf(&file, "static u8 __memory%d[] = {", value->number); + fori (i, 0, value->size) { + bh_fprintf(&file, "%d,", (u32) value->initial_value[i]); + } + bh_fprintf(&file, "};"); + } + bh_fprintf(&file, "\n"); + } +} + static void output_string_literals(OnyxCFile* c_file, bh_file file) { bh_fprintf(&file, "// String Literals\n"); bh_table_each_start(CStringLiteral, c_file->string_literals); @@ -68,6 +84,7 @@ void onyx_output_c_file(OnyxCFile* c_file, bh_file file) { bh_file_write(&file, BOILERPLATE_TOP, strlen(BOILERPLATE_TOP)); bh_file_write(&file, REGISTER_DEFINITION, strlen(REGISTER_DEFINITION)); + output_memory_reservations(c_file, file); output_string_literals(c_file, file); output_file_contents(c_file, file);