#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);
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;
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"
" 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);
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);