diff --git a/include/asm/fstack.hpp b/include/asm/fstack.hpp index 45fa907b..ea1a965e 100644 --- a/include/asm/fstack.hpp +++ b/include/asm/fstack.hpp @@ -19,7 +19,6 @@ struct FileStackNode { // Line at which the parent context was exited; meaningless for the root level uint32_t lineNo; - struct FileStackNode *next; // Next node in the output linked list bool referenced; // If referenced, don't free! uint32_t ID; // Set only if referenced: ID within the object file, -1 if not output yet diff --git a/src/asm/fstack.cpp b/src/asm/fstack.cpp index e3b9108f..907592ee 100644 --- a/src/asm/fstack.cpp +++ b/src/asm/fstack.cpp @@ -211,7 +211,6 @@ bool yywrap(void) if (!copy || !copy->iters) fatalerror("Failed to duplicate REPT file node: %s\n", strerror(errno)); *copy->iters = *fileInfo->iters; // Copies `fileInfo->iters` - copy->node.next = NULL; copy->node.referenced = false; fileInfo = copy; diff --git a/src/asm/output.cpp b/src/asm/output.cpp index 9b02525b..aa41be34 100644 --- a/src/asm/output.cpp +++ b/src/asm/output.cpp @@ -52,7 +52,7 @@ static std::vector objectSymbols; static std::deque assertions; -static struct FileStackNode *fileStackNodes = NULL; +static std::deque fileStackNodes; // Write a long to a file (little-endian) static void putlong(uint32_t i, FILE *f) @@ -71,20 +71,12 @@ static void putstring(char const *s, FILE *f) putc(0, f); } -static uint32_t getNbFileStackNodes(void) -{ - return fileStackNodes ? fileStackNodes->ID + 1 : 0; -} - void out_RegisterNode(struct FileStackNode *node) { // If node is not already registered, register it (and parents), and give it a unique ID while (node->ID == (uint32_t)-1) { - node->ID = getNbFileStackNodes(); - if (node->ID == (uint32_t)-1) - fatalerror("Reached too many file stack nodes; try splitting the file up\n"); - node->next = fileStackNodes; - fileStackNodes = node; + node->ID = fileStackNodes.size(); + fileStackNodes.push_front(node); // Also register the node's parents node = node->parent; @@ -98,19 +90,14 @@ void out_ReplaceNode(struct FileStackNode * /* node */) #if 0 This is code intended to replace a node, which is pretty useless until ref counting is added... - struct FileStackNode **ptr = &fileStackNodes; + auto search = std::find(RANGE(fileStackNodes), node); + assert(search != fileStackNodes.end()); + // The list is supposed to have decrementing IDs; catch inconsistencies early + assert(search->ID == node->ID); + assert(search + 1 == fileStackNodes.end() || (search + 1)->ID == node->ID - 1); - // The linked list is supposed to have decrementing IDs, so iterate with less memory reads, - // to hopefully hit the cache less. A debug check is added after, in case a change is made - // that breaks this assumption. - for (uint32_t i = fileStackNodes->ID; i != node->ID; i--) - ptr = &(*ptr)->next; - assert((*ptr)->ID == node->ID); - - node->next = (*ptr)->next; - assert(!node->next || node->next->ID == node->ID - 1); // Catch inconsistencies early // TODO: unreference the node - *ptr = node; + *search = node; #endif } @@ -446,13 +433,17 @@ void out_WriteObject(void) putlong(objectSymbols.size(), f); putlong(sectionList.size(), f); - putlong(getNbFileStackNodes(), f); - for (struct FileStackNode const *node = fileStackNodes; node; node = node->next) { + putlong(fileStackNodes.size(), f); + for (auto it = fileStackNodes.begin(); it != fileStackNodes.end(); it++) { + struct FileStackNode const *node = *it; + writeFileStackNode(node, f); - if (node->next && node->next->ID != node->ID - 1) + + // The list is supposed to have decrementing IDs + if (it + 1 != fileStackNodes.end() && it[1]->ID != node->ID - 1) fatalerror("Internal error: fstack node #%" PRIu32 " follows #%" PRIu32 ". Please report this to the developers!\n", - node->next->ID, node->ID); + it[1]->ID, node->ID); } for (struct Symbol const *sym : objectSymbols)