mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Use std::shared_ptr for fstack nodes (#1371)
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
#ifndef RGBDS_ASM_FSTACK_H
|
#ifndef RGBDS_ASM_FSTACK_H
|
||||||
#define RGBDS_ASM_FSTACK_H
|
#define RGBDS_ASM_FSTACK_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -22,12 +23,10 @@ struct FileStackNode {
|
|||||||
>
|
>
|
||||||
data;
|
data;
|
||||||
|
|
||||||
FileStackNode *parent; // Pointer to parent node, for error reporting
|
std::shared_ptr<FileStackNode> parent; // Pointer to parent node, for error reporting
|
||||||
// Line at which the parent context was exited; meaningless for the root level
|
// Line at which the parent context was exited; meaningless for the root level
|
||||||
uint32_t lineNo;
|
uint32_t lineNo;
|
||||||
|
|
||||||
// If referenced by a Symbol, Section, or Patch's `src`, don't `delete`!
|
|
||||||
bool referenced = false;
|
|
||||||
// Set only if referenced: ID within the object file, -1 if not output yet
|
// Set only if referenced: ID within the object file, -1 if not output yet
|
||||||
uint32_t ID = -1;
|
uint32_t ID = -1;
|
||||||
|
|
||||||
@@ -50,7 +49,7 @@ extern size_t maxRecursionDepth;
|
|||||||
struct MacroArgs;
|
struct MacroArgs;
|
||||||
|
|
||||||
void fstk_DumpCurrent();
|
void fstk_DumpCurrent();
|
||||||
FileStackNode *fstk_GetFileStack();
|
std::shared_ptr<FileStackNode> fstk_GetFileStack();
|
||||||
|
|
||||||
void fstk_AddIncludePath(std::string const &path);
|
void fstk_AddIncludePath(std::string const &path);
|
||||||
void fstk_SetPreIncludeFile(std::string const &path);
|
void fstk_SetPreIncludeFile(std::string const &path);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#ifndef RGBDS_ASM_OUTPUT_H
|
#ifndef RGBDS_ASM_OUTPUT_H
|
||||||
#define RGBDS_ASM_OUTPUT_H
|
#define RGBDS_ASM_OUTPUT_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -13,8 +14,7 @@ struct FileStackNode;
|
|||||||
|
|
||||||
extern std::string objectName;
|
extern std::string objectName;
|
||||||
|
|
||||||
void out_RegisterNode(FileStackNode *node);
|
void out_RegisterNode(std::shared_ptr<FileStackNode> node);
|
||||||
void out_ReplaceNode(FileStackNode *node);
|
|
||||||
void out_SetFileName(std::string const &name);
|
void out_SetFileName(std::string const &name);
|
||||||
void out_CreatePatch(uint32_t type, Expression const &expr, uint32_t ofs, uint32_t pcShift);
|
void out_CreatePatch(uint32_t type, Expression const &expr, uint32_t ofs, uint32_t pcShift);
|
||||||
void out_CreateAssert(
|
void out_CreateAssert(
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#define RGBDS_SECTION_H
|
#define RGBDS_SECTION_H
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <memory>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
@@ -18,7 +19,7 @@ struct FileStackNode;
|
|||||||
struct Section;
|
struct Section;
|
||||||
|
|
||||||
struct Patch {
|
struct Patch {
|
||||||
FileStackNode const *src;
|
std::shared_ptr<FileStackNode> src;
|
||||||
uint32_t lineNo;
|
uint32_t lineNo;
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
Section *pcSection;
|
Section *pcSection;
|
||||||
@@ -31,8 +32,8 @@ struct Section {
|
|||||||
std::string name;
|
std::string name;
|
||||||
SectionType type;
|
SectionType type;
|
||||||
SectionModifier modifier;
|
SectionModifier modifier;
|
||||||
FileStackNode const *src; // Where the section was defined
|
std::shared_ptr<FileStackNode> src; // Where the section was defined
|
||||||
uint32_t fileLine; // Line where the section was defined
|
uint32_t fileLine; // Line where the section was defined
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint32_t org;
|
uint32_t org;
|
||||||
uint32_t bank;
|
uint32_t bank;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#ifndef RGBDS_SYMBOL_H
|
#ifndef RGBDS_SYMBOL_H
|
||||||
#define RGBDS_SYMBOL_H
|
#define RGBDS_SYMBOL_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -31,8 +32,8 @@ struct Symbol {
|
|||||||
bool isExported; // Whether the symbol is to be exported
|
bool isExported; // Whether the symbol is to be exported
|
||||||
bool isBuiltin; // Whether the symbol is a built-in
|
bool isBuiltin; // Whether the symbol is a built-in
|
||||||
Section *section;
|
Section *section;
|
||||||
FileStackNode *src; // Where the symbol was defined
|
std::shared_ptr<FileStackNode> src; // Where the symbol was defined
|
||||||
uint32_t fileLine; // Line where the symbol was defined
|
uint32_t fileLine; // Line where the symbol was defined
|
||||||
|
|
||||||
std::variant<
|
std::variant<
|
||||||
int32_t, // If isNumeric()
|
int32_t, // If isNumeric()
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <new>
|
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -25,7 +24,7 @@
|
|||||||
#include "asm/warning.hpp"
|
#include "asm/warning.hpp"
|
||||||
|
|
||||||
struct Context {
|
struct Context {
|
||||||
FileStackNode *fileInfo;
|
std::shared_ptr<FileStackNode> fileInfo;
|
||||||
LexerState lexerState{};
|
LexerState lexerState{};
|
||||||
uint32_t uniqueID = 0;
|
uint32_t uniqueID = 0;
|
||||||
MacroArgs *macroArgs = nullptr; // Macro args are *saved* here
|
MacroArgs *macroArgs = nullptr; // Macro args are *saved* here
|
||||||
@@ -96,17 +95,8 @@ void fstk_DumpCurrent() {
|
|||||||
contextStack.top().fileInfo->dump(lexer_GetLineNo());
|
contextStack.top().fileInfo->dump(lexer_GetLineNo());
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStackNode *fstk_GetFileStack() {
|
std::shared_ptr<FileStackNode> fstk_GetFileStack() {
|
||||||
if (contextStack.empty())
|
return contextStack.empty() ? nullptr : contextStack.top().fileInfo;
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
FileStackNode *topNode = contextStack.top().fileInfo;
|
|
||||||
|
|
||||||
// Mark node and all of its parents as referenced if not already so they don't get freed
|
|
||||||
for (FileStackNode *node = topNode; node && !node->referenced; node = node->parent)
|
|
||||||
node->referenced = true;
|
|
||||||
|
|
||||||
return topNode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fstk_AddIncludePath(std::string const &path) {
|
void fstk_AddIncludePath(std::string const &path) {
|
||||||
@@ -173,14 +163,10 @@ bool yywrap() {
|
|||||||
if (Context &context = contextStack.top(); context.fileInfo->type == NODE_REPT) {
|
if (Context &context = contextStack.top(); context.fileInfo->type == NODE_REPT) {
|
||||||
// The context is a REPT or FOR block, which may loop
|
// The context is a REPT or FOR block, which may loop
|
||||||
|
|
||||||
// If the node is referenced, we can't edit it; duplicate it
|
// If the node is referenced outside this context, we can't edit it, so duplicate it
|
||||||
if (context.fileInfo->referenced) {
|
if (context.fileInfo.use_count() > 1) {
|
||||||
context.fileInfo = new (std::nothrow) FileStackNode(*context.fileInfo);
|
context.fileInfo = std::make_shared<FileStackNode>(*context.fileInfo);
|
||||||
if (!context.fileInfo)
|
context.fileInfo->ID = -1; // The copy is not yet registered
|
||||||
fatalerror("Failed to duplicate REPT file node: %s\n", strerror(errno));
|
|
||||||
// Copy all info but the referencing
|
|
||||||
context.fileInfo->referenced = false;
|
|
||||||
context.fileInfo->ID = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint32_t> &fileInfoIters = context.fileInfo->iters();
|
std::vector<uint32_t> &fileInfoIters = context.fileInfo->iters();
|
||||||
@@ -212,6 +198,7 @@ bool yywrap() {
|
|||||||
contextStack.pop();
|
contextStack.pop();
|
||||||
|
|
||||||
lexer_CleanupState(oldContext.lexerState);
|
lexer_CleanupState(oldContext.lexerState);
|
||||||
|
|
||||||
// Restore args if a macro (not REPT) saved them
|
// Restore args if a macro (not REPT) saved them
|
||||||
if (oldContext.fileInfo->type == NODE_MACRO)
|
if (oldContext.fileInfo->type == NODE_MACRO)
|
||||||
macro_UseNewArgs(contextStack.top().macroArgs);
|
macro_UseNewArgs(contextStack.top().macroArgs);
|
||||||
@@ -220,9 +207,6 @@ bool yywrap() {
|
|||||||
if (oldContext.fileInfo->type == NODE_REPT || oldContext.fileInfo->type == NODE_MACRO
|
if (oldContext.fileInfo->type == NODE_REPT || oldContext.fileInfo->type == NODE_MACRO
|
||||||
|| contextStack.top().uniqueID > 0)
|
|| contextStack.top().uniqueID > 0)
|
||||||
macro_SetUniqueID(contextStack.top().uniqueID);
|
macro_SetUniqueID(contextStack.top().uniqueID);
|
||||||
// Free the file stack node
|
|
||||||
if (!oldContext.fileInfo->referenced)
|
|
||||||
delete oldContext.fileInfo;
|
|
||||||
|
|
||||||
lexer_SetState(&contextStack.top().lexerState);
|
lexer_SetState(&contextStack.top().lexerState);
|
||||||
|
|
||||||
@@ -232,17 +216,17 @@ bool yywrap() {
|
|||||||
// Make sure not to switch the lexer state before calling this, so the saved line no is correct.
|
// Make sure not to switch the lexer state before calling this, so the saved line no is correct.
|
||||||
// BE CAREFUL! This modifies the file stack directly, you should have set up the file info first.
|
// BE CAREFUL! This modifies the file stack directly, you should have set up the file info first.
|
||||||
// Callers should set `contextStack.top().lexerState` after this so it is not `nullptr`.
|
// Callers should set `contextStack.top().lexerState` after this so it is not `nullptr`.
|
||||||
static Context &newContext(FileStackNode &fileInfo) {
|
static Context &newContext(std::shared_ptr<FileStackNode> fileInfo) {
|
||||||
if (contextStack.size() > maxRecursionDepth)
|
if (contextStack.size() > maxRecursionDepth)
|
||||||
fatalerror("Recursion limit (%zu) exceeded\n", maxRecursionDepth);
|
fatalerror("Recursion limit (%zu) exceeded\n", maxRecursionDepth);
|
||||||
|
|
||||||
// Save the current `\@` value, to be restored when this context ends
|
// Save the current `\@` value, to be restored when this context ends
|
||||||
contextStack.top().uniqueID = macro_GetUniqueID();
|
contextStack.top().uniqueID = macro_GetUniqueID();
|
||||||
|
|
||||||
fileInfo.parent = contextStack.top().fileInfo;
|
fileInfo->parent = contextStack.top().fileInfo;
|
||||||
fileInfo.lineNo = lexer_GetLineNo();
|
fileInfo->lineNo = lexer_GetLineNo();
|
||||||
|
|
||||||
return contextStack.emplace(Context{.fileInfo = &fileInfo});
|
return contextStack.emplace(Context{.fileInfo = fileInfo});
|
||||||
}
|
}
|
||||||
|
|
||||||
void fstk_RunInclude(std::string const &path) {
|
void fstk_RunInclude(std::string const &path) {
|
||||||
@@ -258,15 +242,10 @@ void fstk_RunInclude(std::string const &path) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStackNode *fileInfo = new (std::nothrow) FileStackNode(NODE_FILE, *fullPath);
|
|
||||||
if (!fileInfo) {
|
|
||||||
error("Failed to alloc file info for INCLUDE: %s\n", strerror(errno));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t uniqueID = contextStack.top().uniqueID;
|
uint32_t uniqueID = contextStack.top().uniqueID;
|
||||||
|
|
||||||
Context &context = newContext(*fileInfo);
|
auto fileInfo = std::make_shared<FileStackNode>(NODE_FILE, *fullPath);
|
||||||
|
Context &context = newContext(fileInfo);
|
||||||
if (!lexer_OpenFile(context.lexerState, fileInfo->name()))
|
if (!lexer_OpenFile(context.lexerState, fileInfo->name()))
|
||||||
fatalerror("Failed to set up lexer for file include\n");
|
fatalerror("Failed to set up lexer for file include\n");
|
||||||
lexer_SetStateAtEOL(&context.lexerState);
|
lexer_SetStateAtEOL(&context.lexerState);
|
||||||
@@ -288,13 +267,8 @@ static void runPreIncludeFile() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStackNode *fileInfo = new (std::nothrow) FileStackNode(NODE_FILE, *fullPath);
|
auto fileInfo = std::make_shared<FileStackNode>(NODE_FILE, *fullPath);
|
||||||
if (!fileInfo) {
|
Context &context = newContext(fileInfo);
|
||||||
error("Failed to alloc file info for pre-include: %s\n", strerror(errno));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Context &context = newContext(*fileInfo);
|
|
||||||
if (!lexer_OpenFile(context.lexerState, fileInfo->name()))
|
if (!lexer_OpenFile(context.lexerState, fileInfo->name()))
|
||||||
fatalerror("Failed to set up lexer for file include\n");
|
fatalerror("Failed to set up lexer for file include\n");
|
||||||
lexer_SetState(&context.lexerState);
|
lexer_SetState(&context.lexerState);
|
||||||
@@ -315,15 +289,11 @@ void fstk_RunMacro(std::string const ¯oName, MacroArgs &args) {
|
|||||||
}
|
}
|
||||||
contextStack.top().macroArgs = macro_GetCurrentArgs();
|
contextStack.top().macroArgs = macro_GetCurrentArgs();
|
||||||
|
|
||||||
FileStackNode *fileInfo = new (std::nothrow) FileStackNode(NODE_MACRO, "");
|
auto fileInfo = std::make_shared<FileStackNode>(NODE_MACRO, "");
|
||||||
if (!fileInfo) {
|
|
||||||
error("Failed to alloc file info for \"%s\": %s\n", macro->name.c_str(), strerror(errno));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print the name...
|
// Print the name...
|
||||||
std::string &fileInfoName = fileInfo->name();
|
std::string &fileInfoName = fileInfo->name();
|
||||||
for (FileStackNode const *node = macro->src; node; node = node->parent) {
|
for (FileStackNode const *node = macro->src.get(); node; node = node->parent.get()) {
|
||||||
if (node->type != NODE_REPT) {
|
if (node->type != NODE_REPT) {
|
||||||
fileInfoName.append(node->name());
|
fileInfoName.append(node->name());
|
||||||
break;
|
break;
|
||||||
@@ -340,7 +310,7 @@ void fstk_RunMacro(std::string const ¯oName, MacroArgs &args) {
|
|||||||
fileInfoName.append("::");
|
fileInfoName.append("::");
|
||||||
fileInfoName.append(macro->name);
|
fileInfoName.append(macro->name);
|
||||||
|
|
||||||
Context &context = newContext(*fileInfo);
|
Context &context = newContext(fileInfo);
|
||||||
std::string_view *macroView = macro->getMacro();
|
std::string_view *macroView = macro->getMacro();
|
||||||
lexer_OpenFileView(
|
lexer_OpenFileView(
|
||||||
context.lexerState, "MACRO", macroView->data(), macroView->size(), macro->fileLine
|
context.lexerState, "MACRO", macroView->data(), macroView->size(), macro->fileLine
|
||||||
@@ -351,11 +321,7 @@ void fstk_RunMacro(std::string const ¯oName, MacroArgs &args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool newReptContext(int32_t reptLineNo, char const *body, size_t size) {
|
static bool newReptContext(int32_t reptLineNo, char const *body, size_t size) {
|
||||||
FileStackNode *fileInfo = new (std::nothrow) FileStackNode(NODE_REPT, std::vector<uint32_t>{1});
|
auto fileInfo = std::make_shared<FileStackNode>(NODE_REPT, std::vector<uint32_t>{1});
|
||||||
if (!fileInfo) {
|
|
||||||
error("Failed to alloc file info for REPT: %s\n", strerror(errno));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (contextStack.top().fileInfo->type == NODE_REPT
|
if (contextStack.top().fileInfo->type == NODE_REPT
|
||||||
&& !contextStack.top().fileInfo->iters().empty()) {
|
&& !contextStack.top().fileInfo->iters().empty()) {
|
||||||
@@ -365,7 +331,7 @@ static bool newReptContext(int32_t reptLineNo, char const *body, size_t size) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Context &context = newContext(*fileInfo);
|
Context &context = newContext(fileInfo);
|
||||||
// Correct our line number, which currently points to the `ENDR` line
|
// Correct our line number, which currently points to the `ENDR` line
|
||||||
context.fileInfo->lineNo = reptLineNo;
|
context.fileInfo->lineNo = reptLineNo;
|
||||||
lexer_OpenFileView(context.lexerState, "REPT", body, size, reptLineNo);
|
lexer_OpenFileView(context.lexerState, "REPT", body, size, reptLineNo);
|
||||||
@@ -453,9 +419,7 @@ void fstk_Init(std::string const &mainPath, size_t maxDepth) {
|
|||||||
fatalerror("Failed to open main file\n");
|
fatalerror("Failed to open main file\n");
|
||||||
lexer_SetState(&context.lexerState);
|
lexer_SetState(&context.lexerState);
|
||||||
|
|
||||||
context.fileInfo = new (std::nothrow) FileStackNode(NODE_FILE, context.lexerState.path);
|
context.fileInfo = std::make_shared<FileStackNode>(NODE_FILE, context.lexerState.path);
|
||||||
if (!context.fileInfo)
|
|
||||||
fatalerror("Failed to allocate memory for main file info: %s\n", strerror(errno));
|
|
||||||
// lineNo and nbReptIters are unused on the top-level context
|
// lineNo and nbReptIters are unused on the top-level context
|
||||||
context.fileInfo->parent = nullptr;
|
context.fileInfo->parent = nullptr;
|
||||||
context.fileInfo->lineNo = 0; // This still gets written to the object file, so init it
|
context.fileInfo->lineNo = 0; // This still gets written to the object file, so init it
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ static std::vector<Symbol *> objectSymbols;
|
|||||||
|
|
||||||
static std::deque<Assertion> assertions;
|
static std::deque<Assertion> assertions;
|
||||||
|
|
||||||
static std::deque<FileStackNode *> fileStackNodes;
|
static std::deque<std::shared_ptr<FileStackNode>> fileStackNodes;
|
||||||
|
|
||||||
// Write a long to a file (little-endian)
|
// Write a long to a file (little-endian)
|
||||||
static void putlong(uint32_t n, FILE *file) {
|
static void putlong(uint32_t n, FILE *file) {
|
||||||
@@ -53,7 +53,7 @@ static void putstring(std::string const &s, FILE *file) {
|
|||||||
putc('\0', file);
|
putc('\0', file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void out_RegisterNode(FileStackNode *node) {
|
void out_RegisterNode(std::shared_ptr<FileStackNode> node) {
|
||||||
// If node is not already registered, register it (and parents), and give it a unique ID
|
// If node is not already registered, register it (and parents), and give it a unique ID
|
||||||
for (; node && node->ID == (uint32_t)-1; node = node->parent) {
|
for (; node && node->ID == (uint32_t)-1; node = node->parent) {
|
||||||
node->ID = fileStackNodes.size();
|
node->ID = fileStackNodes.size();
|
||||||
@@ -61,21 +61,6 @@ void out_RegisterNode(FileStackNode *node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void out_ReplaceNode(FileStackNode * /* node */) {
|
|
||||||
#if 0
|
|
||||||
This is code intended to replace a node, which is pretty useless until ref counting is added...
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// TODO: unreference the node
|
|
||||||
*search = node;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return a section's ID, or -1 if the section is not in the list
|
// Return a section's ID, or -1 if the section is not in the list
|
||||||
static uint32_t getSectIDIfAny(Section *sect) {
|
static uint32_t getSectIDIfAny(Section *sect) {
|
||||||
if (!sect)
|
if (!sect)
|
||||||
@@ -249,12 +234,10 @@ static void writerpn(std::vector<uint8_t> &rpnexpr, std::vector<uint8_t> const &
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void initpatch(Patch &patch, uint32_t type, Expression const &expr, uint32_t ofs) {
|
static void initpatch(Patch &patch, uint32_t type, Expression const &expr, uint32_t ofs) {
|
||||||
FileStackNode *node = fstk_GetFileStack();
|
|
||||||
|
|
||||||
patch.type = type;
|
patch.type = type;
|
||||||
patch.src = node;
|
patch.src = fstk_GetFileStack();
|
||||||
// All patches are assumed to eventually be written, so the file stack node is registered
|
// All patches are assumed to eventually be written, so the file stack node is registered
|
||||||
out_RegisterNode(node);
|
out_RegisterNode(patch.src);
|
||||||
patch.lineNo = lexer_GetLineNo();
|
patch.lineNo = lexer_GetLineNo();
|
||||||
patch.offset = ofs;
|
patch.offset = ofs;
|
||||||
patch.pcSection = sect_GetSymbolSection();
|
patch.pcSection = sect_GetSymbolSection();
|
||||||
@@ -342,17 +325,17 @@ void out_WriteObject() {
|
|||||||
|
|
||||||
putlong(fileStackNodes.size(), file);
|
putlong(fileStackNodes.size(), file);
|
||||||
for (auto it = fileStackNodes.begin(); it != fileStackNodes.end(); it++) {
|
for (auto it = fileStackNodes.begin(); it != fileStackNodes.end(); it++) {
|
||||||
FileStackNode const *node = *it;
|
FileStackNode const &node = **it;
|
||||||
|
|
||||||
writeFileStackNode(*node, file);
|
writeFileStackNode(node, file);
|
||||||
|
|
||||||
// The list is supposed to have decrementing IDs
|
// The list is supposed to have decrementing IDs
|
||||||
if (it + 1 != fileStackNodes.end() && it[1]->ID != node->ID - 1)
|
if (it + 1 != fileStackNodes.end() && it[1]->ID != node.ID - 1)
|
||||||
fatalerror(
|
fatalerror(
|
||||||
"Internal error: fstack node #%" PRIu32 " follows #%" PRIu32
|
"Internal error: fstack node #%" PRIu32 " follows #%" PRIu32
|
||||||
". Please report this to the developers!\n",
|
". Please report this to the developers!\n",
|
||||||
it[1]->ID,
|
it[1]->ID,
|
||||||
node->ID
|
node.ID
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <new>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|||||||
@@ -97,15 +97,13 @@ static void dumpFilename(Symbol const &sym) {
|
|||||||
|
|
||||||
// Update a symbol's definition filename and line
|
// Update a symbol's definition filename and line
|
||||||
static void updateSymbolFilename(Symbol &sym) {
|
static void updateSymbolFilename(Symbol &sym) {
|
||||||
FileStackNode *oldSrc = sym.src;
|
std::shared_ptr<FileStackNode> oldSrc = std::move(sym.src);
|
||||||
|
|
||||||
sym.src = fstk_GetFileStack();
|
sym.src = fstk_GetFileStack();
|
||||||
sym.fileLine = sym.src ? lexer_GetLineNo() : 0;
|
sym.fileLine = sym.src ? lexer_GetLineNo() : 0;
|
||||||
|
|
||||||
// If the old node was referenced, ensure the new one is
|
// If the old node was registered, ensure the new one is too
|
||||||
if (oldSrc && oldSrc->referenced && oldSrc->ID != (uint32_t)-1)
|
if (oldSrc && oldSrc->ID != (uint32_t)-1)
|
||||||
out_RegisterNode(sym.src);
|
out_RegisterNode(sym.src);
|
||||||
// TODO: unref the old node, and use `out_ReplaceNode` instead of deleting it
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new symbol by name
|
// Create a new symbol by name
|
||||||
|
|||||||
Reference in New Issue
Block a user