-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compiler V3 #39
Compiler V3 #39
Changes from all commits
f04018a
8228e15
09f6fb2
19fa7f2
5c6553b
b117b32
a659532
0a991ed
a2ebf86
d80c897
0e0f010
b1bbe29
56e1f10
9187c95
3939f06
aef6ef9
537d402
914f9d6
2834230
0dad446
edfed2a
290f135
a3b33d7
8a995c5
b5d4d0c
959d83d
b04bf02
d44e242
da0ee1f
62fbc62
43b93a4
6e3337a
9efdb12
e07d3e7
720c21c
0d108a5
7b4a80a
07c367e
a263300
0883149
5c07010
acfad1f
f35c273
aba326a
ad8c1fb
4de307e
445a236
c9f1567
e26945c
2e4d9c7
c06611b
fb81854
f99bc8a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -123,7 +123,7 @@ void main(int argc, char* argv[]) { | |
endTimer(i, 0); | ||
startTimer(); | ||
|
||
struct LexerResult result = runLexer(buff); | ||
struct LexerResult result = runLexer(buff, size); | ||
|
||
free(buff); | ||
|
||
|
@@ -136,20 +136,14 @@ void main(int argc, char* argv[]) { | |
endTimer(i, 2); | ||
startTimer(); | ||
|
||
struct Context ctx = parseContext(node); | ||
char* compiled = compileV2(ctx); | ||
fptr = fopen("output.txt", "w"); | ||
|
||
endTimer(i, 3); | ||
|
||
startTimer(); | ||
|
||
fptr = fopen("output.txt", "w"); | ||
fprintf(fptr, compiled); | ||
fclose(fptr); | ||
IR_CTX* ctx = makeContext(node); | ||
compile(ctx, fptr); | ||
|
||
endTimer(i, 4); | ||
fclose(fptr); | ||
|
||
free(compiled); | ||
endTimer(i, 3); | ||
Comment on lines
+139
to
+146
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Codebase verification Add error handling for IR context creation and file operations
🔗 Analysis chainConsolidate compilation steps Let me gather information about error handling in the codebase, particularly around IR_CTX creation and file operations. 🏁 Scripts executedThe following scripts were executed for the analysis: Error: No shell scripts found Script: #!/bin/bash
# Check IR_CTX creation and error handling patterns
ast-grep --pattern 'makeContext($_)'
# Look for error handling patterns around fopen
rg "fopen.*\(" -A 3
# Check IR_CTX struct definition and related error handling
rg "IR_CTX" -A 3
Length of output: 2457 |
||
} | ||
|
||
printf("========= Benchmarking Results =========\n"); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
* The compiler of Quickfall. | ||
*/ | ||
|
||
#include <stdint.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
|
@@ -13,6 +14,8 @@ | |
#include "../utils/hash.h" | ||
#include "../utils/hashmap.h" | ||
|
||
#include "./pe/pe.h" | ||
|
||
/** | ||
* Parses the AST tree into a context. | ||
* @param tree the AST tree. | ||
|
@@ -26,9 +29,7 @@ IR_CTX* makeContext(AST_NODE* tree) { | |
ctx->nodeIndex = 0; | ||
ctx->nodeMap = createHashmap(512,200); | ||
|
||
while(tree->next != NULL) { | ||
tree = tree->next; | ||
|
||
while(tree != NULL) { | ||
switch(tree->type) { | ||
case AST_VARIABLE_DECLARATION: | ||
|
||
|
@@ -59,10 +60,10 @@ IR_CTX* makeContext(AST_NODE* tree) { | |
|
||
case AST_FUNCTION_DECLARATION: | ||
|
||
hash = hashstr(tree->left->value); | ||
hash = hashstr(tree->left->right->value); | ||
|
||
if(hashGet(ctx->nodeMap, hash) != NULL) { | ||
printf("Function %s was already declared!\n", tree->left->value); | ||
printf("Function %s was already declared!\n", tree->left->right->value); | ||
return NULL; | ||
} | ||
|
||
|
@@ -77,18 +78,20 @@ IR_CTX* makeContext(AST_NODE* tree) { | |
node->variables[node->variableIndex] = var; | ||
node->variableIndex++; | ||
|
||
hashPut(node->variableMap, hashstr(tree->right->value), var); | ||
hashPut(node->variableMap, hashstr(tree->left->left->right->value), var); | ||
|
||
tree->left->left = tree->left->left->next; | ||
} | ||
|
||
node->tree = tree->right; | ||
|
||
ctx->nodes[ctx->nodeIndex] = node; | ||
ctx->nodeIndex++; | ||
|
||
hashPut(ctx->nodeMap, hash, node); | ||
break; | ||
|
||
case AST_ASM_FUNCTION_DECLARATION: | ||
|
||
hash = hashstr(tree->left->right->value); | ||
|
||
if(hashGet(ctx->nodeMap, hash) != NULL) { | ||
|
@@ -99,6 +102,7 @@ IR_CTX* makeContext(AST_NODE* tree) { | |
node = createIRNode(IR_ASM_FUNCTION, tree->left->right->value); | ||
|
||
node->value = tree->value; | ||
node->valueSize = tree->valueSize; | ||
|
||
while(tree->left->left->next != NULL) { | ||
|
||
|
@@ -121,6 +125,8 @@ IR_CTX* makeContext(AST_NODE* tree) { | |
break; | ||
|
||
} | ||
|
||
tree = tree->next; | ||
} | ||
|
||
return ctx; | ||
|
@@ -131,6 +137,52 @@ IR_CTX* makeContext(AST_NODE* tree) { | |
* @param ctx the IR context. | ||
* @param char the output file name. | ||
*/ | ||
void compile(IR_CTX* ctx, char* outputFileName) { | ||
void compile(IR_CTX* ctx, FILE* out) { | ||
|
||
uint8_t* buff = malloc(sizeof(uint8_t) * 512); | ||
int i = 0; | ||
|
||
int h = hashstr("main"); | ||
|
||
if(hashGet(ctx->nodeMap, h) == NULL) { | ||
printf("Error: the main function wasn't defined!\n"); | ||
return; | ||
} | ||
Comment on lines
+147
to
+150
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix memory leaks on early returns. When returning at lines 149 or 157, the allocated buffer "buff" is never freed. Apply this minimal patch to free memory before returning: if(hashGet(ctx->nodeMap, h) == NULL) {
printf("Error: the main function wasn't defined!\n");
+ free(buff);
return;
}
if(node->nodeType != IR_FUNCTION) {
printf("Error: main must be a function!\n");
+ free(buff);
return;
} Also applies to: 155-157 🧰 Tools🪛 cppcheck (2.10-2)[error] 149-149: Memory leak (memleak) |
||
|
||
IR_NODE* node = hashGet(ctx->nodeMap, h); | ||
|
||
if(node->nodeType != IR_FUNCTION) { | ||
printf("Error: main must be a function!\n"); | ||
return; | ||
} | ||
|
||
while(node->tree != NULL) { | ||
|
||
if(node->tree->type == AST_FUNCTION_INVOKE) { | ||
|
||
int hash = hashstr(node->tree->value); | ||
|
||
IR_NODE* wa = hashGet(ctx->nodeMap, hash); | ||
|
||
if(wa == NULL) { | ||
printf("Error: The %s function doesn't exist!\n", node->tree->value); | ||
return; | ||
} | ||
|
||
if(wa->nodeType == IR_ASM_FUNCTION) { | ||
unsigned char b; | ||
unsigned char* ptr = (unsigned char*) wa->value; | ||
|
||
for(int ii = 0; ii < wa->valueSize; ++ii) { | ||
buff[i] = ptr[ii]; | ||
++i; | ||
} | ||
} | ||
} | ||
|
||
node->tree = node->tree->next; | ||
} | ||
|
||
//todo: change format based on user | ||
compilePE(out, buff, i); | ||
Comment on lines
+186
to
+187
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Deallocate "buff" after compiling. Add a free call to avoid leaking memory in the normal completion path: compilePE(out, buff, i);
+free(buff);
}
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/** | ||
* Quickfall PE Format Defintion. | ||
*/ | ||
|
||
#include "../units.h" | ||
|
||
#ifndef PE_FORMAT | ||
#define PE_FORMAT | ||
|
||
/** | ||
* Constants. | ||
*/ | ||
|
||
#define PE_HEADER_SIGNATURE 0x00004550 | ||
#define PE_DOS_HDR_SZ 0x40 | ||
|
||
/** | ||
* Structures. | ||
*/ | ||
|
||
#pragma pack(push, 1) | ||
|
||
typedef struct { | ||
uint16_t e_magic; | ||
uint16_t e_cblp; | ||
uint16_t e_cp; | ||
uint16_t e_crlc; | ||
uint16_t e_cparhdr; | ||
uint16_t e_minalloc; | ||
uint16_t e_maxalloc; | ||
uint16_t e_ss; | ||
uint16_t e_sp; | ||
uint16_t e_csum; | ||
uint16_t e_ip; | ||
uint16_t e_cs; | ||
uint16_t e_lfarlc; | ||
uint16_t e_ovno; | ||
uint16_t e_res[4]; | ||
uint16_t e_oemid; | ||
uint16_t e_oeminfo; | ||
uint16_t e_res2[10]; | ||
uint32_t e_lfanew; | ||
} PE_DOS_HEADER; | ||
|
||
typedef struct { | ||
uint32_t Signature; | ||
uint16_t Machine; | ||
uint16_t NumberOfSections; | ||
uint32_t TimeDateStamp; | ||
uint32_t PointerToSymbolTable; | ||
uint32_t NumberOfSymbols; | ||
uint16_t SizeOfOptionalHeader; | ||
uint16_t Characteristics; | ||
} PE_NT_HEADERS; | ||
|
||
typedef struct { | ||
uint16_t Magic; | ||
uint8_t MajorLinkerVersion; | ||
uint8_t MinorLinkerVersion; | ||
uint32_t SizeOfCode; | ||
uint32_t SizeOfInitializedData; | ||
uint32_t SizeOfUninitializedData; | ||
uint32_t AddressOfEntryPoint; | ||
uint32_t BaseOfCode; | ||
uint64_t ImageBase; | ||
uint32_t SectionAlignment; | ||
uint32_t FileAlignment; | ||
uint16_t MajorOperatingSystemVersion; | ||
uint16_t MinorOperatingSystemVersion; | ||
uint16_t MajorImageVersion; | ||
uint16_t MinorImageVersion; | ||
uint16_t MajorSubsystemVersion; | ||
uint16_t MinorSubsystemVersion; | ||
uint32_t Win32VersionValue; | ||
uint32_t SizeOfImage; | ||
uint32_t SizeOfHeaders; | ||
uint32_t CheckSum; | ||
uint16_t Subsystem; | ||
uint16_t DllCharacteristics; | ||
uint64_t SizeOfStackReserve; | ||
uint64_t SizeOfStackCommit; | ||
uint64_t SizeOfHeapReserve; | ||
uint64_t SizeOfHeapCommit; | ||
uint32_t LoaderFlags; | ||
uint32_t NumberOfRvaAndSizes; | ||
struct { | ||
uint32_t VirtualAddress; | ||
uint32_t Size; | ||
} DataDirectory[16]; | ||
} PE_OPTIONAL_HEADER; | ||
|
||
typedef struct { | ||
uint8_t Name[8]; | ||
union { | ||
uint32_t PhysicalAddress; | ||
uint32_t VirtualSize; | ||
} Misc; | ||
uint32_t VirtualAddress; | ||
uint32_t SizeOfRawData; | ||
uint32_t PointerToRawData; | ||
uint32_t PointerToRelocations; | ||
uint32_t PointerToLinenumbers; | ||
uint16_t NumberOfRelocations; | ||
uint16_t NumberOfLinenumbers; | ||
uint32_t Characteristics; | ||
} PE_SECTION_HEADER; | ||
|
||
#pragma pack(pop) | ||
|
||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add .PHONY declaration for the clean target
The clean target should be declared as .PHONY to ensure it runs even if a file named 'clean' exists in the directory. This is a common Makefile best practice.
Add this line at the beginning of the Makefile:
+.PHONY: clean