From 3fd45311c5bc027ca2dbfca86f9c59f5d60a3ad1 Mon Sep 17 00:00:00 2001 From: Timerix Date: Wed, 5 Feb 2025 17:25:12 +0500 Subject: [PATCH] constant data names linking --- src/compiler/Binary.c | 8 ++- src/compiler/Binary.h | 8 +-- src/compiler/Compiler.c | 106 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 113 insertions(+), 9 deletions(-) diff --git a/src/compiler/Binary.c b/src/compiler/Binary.c index 4044060..f382724 100644 --- a/src/compiler/Binary.c +++ b/src/compiler/Binary.c @@ -1,6 +1,7 @@ #include "Binary.h" List_define(ConstDataProps); +HashMap_define(ConstDataProps, HashMap_DESTROY_VALUE_FUNC_NULL); List_define(NamedRef); List_define(CompiledSection); HashMap_define(CompiledSectionPtr, HashMap_DESTROY_VALUE_FUNC_NULL); @@ -10,13 +11,13 @@ void CompiledSection_construct(CompiledSection* ptr, str name){ ptr->name = name; ptr->next = NULL; ptr->offset = 0; - ptr->const_data_offsets = List_ConstDataProps_construct(NULL, 0, 0); + ptr->const_data_props_list = List_ConstDataProps_construct(NULL, 0, 0); ptr->named_refs = List_NamedRef_construct(NULL, 0, 0); ptr->bytes = List_u8_alloc(64); } void CompiledSection_free(CompiledSection* ptr){ - free(ptr->const_data_offsets.data); + free(ptr->const_data_props_list.data); free(ptr->named_refs.data); free(ptr->bytes.data); } @@ -25,6 +26,7 @@ void CompiledSection_free(CompiledSection* ptr){ void BinaryObject_construct(BinaryObject* ptr){ ptr->section_list = List_CompiledSection_alloc(64); HashMap_CompiledSectionPtr_alloc(&ptr->section_map); + HashMap_ConstDataProps_alloc(&ptr->const_data_map); } void BinaryObject_free(BinaryObject* ptr){ @@ -32,5 +34,7 @@ void BinaryObject_free(BinaryObject* ptr){ CompiledSection_free(&ptr->section_list.data[i]); } free(ptr->section_list.data); + HashMap_CompiledSectionPtr_free(&ptr->section_map); + HashMap_ConstDataProps_free(&ptr->const_data_map); } diff --git a/src/compiler/Binary.h b/src/compiler/Binary.h index 66d12a8..5a28436 100644 --- a/src/compiler/Binary.h +++ b/src/compiler/Binary.h @@ -17,6 +17,7 @@ typedef struct ConstDataProps { #define ConstDataProps_construct(NAME, SIZE, OFFSET) ((ConstDataProps){ .name = NAME, .size = SIZE, .offset = OFFSET}) List_declare(ConstDataProps); +HashMap_declare(ConstDataProps); typedef enum NamedRefType { @@ -35,11 +36,12 @@ typedef struct NamedRef { List_declare(NamedRef); + typedef struct CompiledSection { str name; CompiledSection* next; u32 offset; - List_ConstDataProps const_data_offsets; + List_ConstDataProps const_data_props_list; List_NamedRef named_refs; List_u8 bytes; } CompiledSection; @@ -47,15 +49,15 @@ typedef struct CompiledSection { void CompiledSection_construct(CompiledSection* ptr, str name); void CompiledSection_free(CompiledSection* ptr); - - List_declare(CompiledSection); typedef CompiledSection* CompiledSectionPtr; HashMap_declare(CompiledSectionPtr); + typedef struct BinaryObject { List_CompiledSection section_list; HashMap_CompiledSectionPtr section_map; + HashMap_ConstDataProps const_data_map; u32 total_size; } BinaryObject; diff --git a/src/compiler/Compiler.c b/src/compiler/Compiler.c index 50e657f..f0e2701 100644 --- a/src/compiler/Compiler.c +++ b/src/compiler/Compiler.c @@ -77,7 +77,7 @@ static bool compileSection(Compiler* cmp, Section* sec){ Operation* op = &sec->code.data[i]; List_u8_pushMany(&cs->bytes, (void*)&op->opcode, sizeof(op->opcode)); for(u32 j = 0; j < op->args.len; j++){ - Argument* arg = &op->args.data[i]; + Argument* arg = &op->args.data[j]; switch(arg->type){ case ArgumentType_VarDataName: returnError("argument type 'VarDataName' is not supported yet"); @@ -113,9 +113,9 @@ static bool compileSection(Compiler* cmp, Section* sec){ // compile data for(u32 i = 0; i < sec->data.len; i++){ - DataDefinition* ddf = &sec->data.data[i]; - List_ConstDataProps_push(&cs->const_data_offsets, ConstDataProps_construct(ddf->name, ddf->data.len, cs->bytes.len)); - List_u8_pushMany(&cs->bytes, ddf->data.data, ddf->data.len); + DataDefinition* dd = &sec->data.data[i]; + List_ConstDataProps_push(&cs->const_data_props_list, ConstDataProps_construct(dd->name, dd->data.len, cs->bytes.len)); + List_u8_pushMany(&cs->bytes, dd->data.data, dd->data.len); } // TODO: push padding @@ -148,6 +148,45 @@ static bool compileBinary(Compiler* cmp){ continue; prev_sec->next = sec; sec->offset = prev_sec->offset + prev_sec->bytes.len; + + ConstDataProps cd = ConstDataProps_construct(sec->name, sec->bytes.len, sec->offset); + if(!HashMap_ConstDataProps_tryPush(&cmp->binary.const_data_map, cd.name, cd)){ + returnError("duplicate named data '%s'", str_copy(cd.name).data); + } + for(u32 j = 0; j < sec->const_data_props_list.len; j++){ + cd = sec->const_data_props_list.data[j]; + cd.offset += sec->offset; + if(!HashMap_ConstDataProps_tryPush(&cmp->binary.const_data_map, cd.name, cd)){ + returnError("duplicate named data '%s'", str_copy(cd.name).data); + } + } + } + + // insert calculated offsets into sections + for(u32 i = 0; i < cmp->binary.section_list.len; i++){ + CompiledSection* sec = &cmp->binary.section_list.data[i]; + for(u32 j = 0; j < sec->named_refs.len; j++){ + NamedRef* ref = &sec->named_refs.data[j]; + + ConstDataProps* target_data = HashMap_ConstDataProps_tryGetPtr( + &cmp->binary.const_data_map, ref->name); + if(target_data == NULL){ + returnError("can't find named data '%s'", str_copy(ref->name).data); + } + + void* ref_value_ptr = sec->bytes.data + ref->offset; + + switch(ref->type){ + default: + returnError("invalid NamedRefType %i", ref->type); + case NamedRefType_Size: + *((u32*)ref_value_ptr) = target_data->size; + break; + case NamedRefType_Ptr: + *((u32*)ref_value_ptr) = target_data->offset; + break; + } + } } cmp->binary.total_size = total_size; @@ -250,6 +289,65 @@ bool Compiler_compile(Compiler* cmp, cstr source_file_name, cstr out_file_name, if(debug_log) printf("===================================[parsing]===================================\n"); success = Compiler_parse(cmp); + if (debug_log){ + printf("-------------------------------------[AST]-------------------------------------\n"); + for(u32 i = 0; i < cmp->ast.sections.len; i++){ + Section* sec = &cmp->ast.sections.data[i]; + str tmpstr = str_copy(sec->name); + printf("section '%s'\n", tmpstr.data); + free(tmpstr.data); + + for(u32 j = 0; j < sec->data.len; j++){ + DataDefinition* dd = &sec->data.data[j]; + tmpstr = str_copy(dd->name); + printf(" const%u %s (len %u)\n", dd->element_size * 8, tmpstr.data, dd->data.len/dd->element_size); + free(tmpstr.data); + } + + + for(u32 j = 0; j < sec->code.len; j++){ + Operation* op = &sec->code.data[j]; + const Instruction* instr = Instruction_getByOpcode(op->opcode); + printf(" %s", instr->name.data); + for(u32 k = 0; k < op->args.len; k++){ + Argument* arg = &op->args.data[k]; + printf(" %s(", ArgumentType_toString(arg->type).data); + + switch(arg->type){ + default: + fclose(f); + returnError("invalid argument type %i", arg->type); + case ArgumentType_Register: + const char* register_names[] = {"null", "ax", "bx", "cx", "dx"}; + printf("%s", register_names[arg->value.register_code]); + break; + case ArgumentType_ConstValue: + printf(IFWIN("%lli", "%li"), arg->value.i); + break; + case ArgumentType_ConstDataPointer: + tmpstr = str_copy(arg->value.data_name); + printf("@%s", tmpstr.data); + free(tmpstr.data); + break; + case ArgumentType_ConstDataSize: + tmpstr = str_copy(arg->value.data_name); + printf("#%s", tmpstr.data); + free(tmpstr.data); + break; + case ArgumentType_VarDataName: + tmpstr = str_copy(arg->value.data_name); + printf("%s", tmpstr.data); + free(tmpstr.data); + break; + } + + printf(")"); + } + + printf("\n"); + } + } + } if(!success){ fclose(f); return false;