implemented Entity_Type_Memory_Reservation
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 20 Apr 2021 01:14:41 +0000 (20:14 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 20 Apr 2021 01:14:41 +0000 (20:14 -0500)
build.bat
include/onyxc.h
src/onyxc.c
src/onyxc_output.c

index 3e3bc625429c83d1ba423bd418f3655a21f7c0c0..60977bacde8a82f3d6d65014aa8fed41565013dd 100644 (file)
--- 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
index 25902420b1e129d281036fb6879fa94c11949e9e..ceb6f2f6040b9e88f6487378e93e9c04595d358d 100644 (file)
@@ -7,7 +7,7 @@
 typedef struct CMemoryReservation {
     i32   number;
     i32   size;
-    void* initial_value;
+    u8 * initial_value;
 } CMemoryReservation;
 
 typedef struct CStringLiteral {
index 807866890f28114721a4f949f688684efbfd393f..5c8196212fdfa31d38f6bf4067aafc7998f3e32c 100644 (file)
@@ -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"
 
index 40cc4894e807ab4d81f8037d5d2ea32e0594b9d1..32264d80185b81805231d96c43420e697c751e9e 100644 (file)
@@ -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);