From 6a5518e0c5683cb9b42afc17436ad7b07e2c73dc Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Fri, 22 Mar 2024 14:03:04 -0400 Subject: [PATCH] Use RAII to unmap or close the lexer states' files automatically --- include/asm/lexer.hpp | 12 +++++++++++- src/asm/fstack.cpp | 1 - src/asm/lexer.cpp | 8 ++++---- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/include/asm/lexer.hpp b/include/asm/lexer.hpp index 00b6096f..f1368b67 100644 --- a/include/asm/lexer.hpp +++ b/include/asm/lexer.hpp @@ -83,6 +83,17 @@ struct LexerState { std::deque expansions; // Front is the innermost current expansion std::variant content; + + LexerState() = default; + LexerState(LexerState &&) = default; + LexerState(LexerState const &) = delete; + + // This destructor unmaps or closes the content file if applicable. + // As such, lexer states should not be copyable. + ~LexerState(); + + LexerState &operator=(LexerState &&) = default; + LexerState &operator=(LexerState const &) = delete; }; extern LexerState *lexerState; @@ -117,7 +128,6 @@ void lexer_OpenFileView( LexerState &state, char const *path, char const *buf, size_t size, uint32_t lineNo ); void lexer_RestartRept(uint32_t lineNo); -void lexer_CleanupState(LexerState &state); void lexer_Init(); void lexer_SetMode(LexerMode mode); void lexer_ToggleStringExpansion(bool enable); diff --git a/src/asm/fstack.cpp b/src/asm/fstack.cpp index bfc09c21..64d5ff76 100644 --- a/src/asm/fstack.cpp +++ b/src/asm/fstack.cpp @@ -220,7 +220,6 @@ bool yywrap() { return true; } - lexer_CleanupState(contextStack.top().lexerState); contextStack.pop(); lexer_SetState(&contextStack.top().lexerState); diff --git a/src/asm/lexer.cpp b/src/asm/lexer.cpp index 5293c82e..c8c9705e 100644 --- a/src/asm/lexer.cpp +++ b/src/asm/lexer.cpp @@ -459,7 +459,7 @@ void lexer_RestartRept(uint32_t lineNo) { lexerState->lineNo = lineNo; } -void lexer_CleanupState(LexerState &state) { +LexerState::~LexerState() { // A big chunk of the lexer state soundness is the file stack ("fstack"). // Each context in the fstack has its own *unique* lexer state; thus, we always guarantee // that lexer states lifetimes are always properly managed, since they're handled solely @@ -471,12 +471,12 @@ void lexer_CleanupState(LexerState &state) { // This assertion checks that this doesn't happen again. // It could be argued that deleting a state that's scheduled for EOF could simply clear // `lexerStateEOL`, but there's currently no situation in which this should happen. - assert(&state != lexerStateEOL); + assert(this != lexerStateEOL); - if (auto *mmap = std::get_if(&state.content); mmap) { + if (auto *mmap = std::get_if(&content); mmap) { if (!mmap->isReferenced) munmap(mmap->ptr, mmap->size); - } else if (auto *cbuf = std::get_if(&state.content); cbuf) { + } else if (auto *cbuf = std::get_if(&content); cbuf) { close(cbuf->fd); } }