Avoid pooling discarded literal text

Only acquire and release a string-pool entry when the consumer retains text or reads an identifier. Discarded literals no longer assign their first character to a pooled string.

Generated with the assistance of an AI coding tool.
This commit is contained in:
Thomas Krijnen
2026-09-15 14:17:14 +02:00
parent 3b808a8930
commit cb66a2ddae
+17 -10
View File
@@ -223,20 +223,22 @@ void spf_lexer<Reader>::scan(Consumer& consumer) {
continue; continue;
} }
auto& str = get_temp_string();
auto ttype = token::Token_NONE; auto ttype = token::Token_NONE;
if (character == '"' || character == '.') {
if (character == '"') { if (character == '"') {
ttype = token::Token_BINARY; ttype = token::Token_BINARY;
} else { } else if (character == '.') {
ttype = token::Token_ENUMERATION; ttype = token::Token_ENUMERATION;
}
str.clear();
} else if (character == '#') { } else if (character == '#') {
ttype = token::Token_IDENTIFIER; ttype = token::Token_IDENTIFIER;
str.clear(); }
std::string* text = nullptr;
if (Consumer::keep_keywords || ttype == token::Token_IDENTIFIER) {
text = &get_temp_string();
if (ttype == token::Token_NONE) {
text->assign(&character, 1);
} else { } else {
str.assign(&character, 1); text->clear();
}
} }
auto remaining = stream->remaining(); auto remaining = stream->remaining();
@@ -245,7 +247,7 @@ void spf_lexer<Reader>::scan(Consumer& consumer) {
uint64_t x = stream->peek_u64(); uint64_t x = stream->peek_u64();
if ((ttype == token::Token_NONE ? SWAR::has_special_char<false>(x) : SWAR::has_special_char<true>(x)) == 0) { if ((ttype == token::Token_NONE ? SWAR::has_special_char<false>(x) : SWAR::has_special_char<true>(x)) == 0) {
if (Consumer::keep_keywords || ttype == token::Token_IDENTIFIER) { if (Consumer::keep_keywords || ttype == token::Token_IDENTIFIER) {
str.append(reinterpret_cast<const char*>(&x), 8); text->append(reinterpret_cast<const char*>(&x), 8);
} }
stream->increment(8); stream->increment(8);
remaining -= 8; remaining -= 8;
@@ -256,7 +258,7 @@ void spf_lexer<Reader>::scan(Consumer& consumer) {
uint32_t x = stream->peek_u32(); uint32_t x = stream->peek_u32();
if ((ttype == token::Token_NONE ? SWAR::has_special_char<false>(x) : SWAR::has_special_char<true>(x)) == 0) { if ((ttype == token::Token_NONE ? SWAR::has_special_char<false>(x) : SWAR::has_special_char<true>(x)) == 0) {
if (Consumer::keep_keywords || ttype == token::Token_IDENTIFIER) { if (Consumer::keep_keywords || ttype == token::Token_IDENTIFIER) {
str.append(reinterpret_cast<const char*>(&x), 4); text->append(reinterpret_cast<const char*>(&x), 4);
} }
stream->increment(4); stream->increment(4);
remaining -= 4; remaining -= 4;
@@ -279,7 +281,7 @@ void spf_lexer<Reader>::scan(Consumer& consumer) {
(ttype == token::Token_ENUMERATION && c == '.')) { (ttype == token::Token_ENUMERATION && c == '.')) {
// Skip // Skip
} else if (Consumer::keep_keywords || ttype == token::Token_IDENTIFIER) { } else if (Consumer::keep_keywords || ttype == token::Token_IDENTIFIER) {
str.push_back(c); text->push_back(c);
} }
} }
stream->increment(); stream->increment();
@@ -287,6 +289,7 @@ void spf_lexer<Reader>::scan(Consumer& consumer) {
} }
if (ttype == token::Token_IDENTIFIER) { if (ttype == token::Token_IDENTIFIER) {
auto& str = *text;
int int_val; int int_val;
if (!parse_num_(str.c_str(), str.size(), int_val)) { if (!parse_num_(str.c_str(), str.size(), int_val)) {
throw invalid_token_exception(pos, str, "instance name"); throw invalid_token_exception(pos, str, "instance name");
@@ -302,6 +305,7 @@ void spf_lexer<Reader>::scan(Consumer& consumer) {
// Only names and keywords are read; everything else is a literal // Only names and keywords are read; everything else is a literal
// whose position is all the consumer wants. // whose position is all the consumer wants.
if constexpr (Consumer::keep_keywords) { if constexpr (Consumer::keep_keywords) {
auto& str = *text;
if (ttype == token::Token_NONE && !str.empty()) { if (ttype == token::Token_NONE && !str.empty()) {
const char first = str.front(); const char first = str.front();
if ((first >= 'A' && first <= 'Z') || (first >= 'a' && first <= 'z')) { if ((first >= 'A' && first <= 'Z') || (first >= 'a' && first <= 'z')) {
@@ -312,12 +316,15 @@ void spf_lexer<Reader>::scan(Consumer& consumer) {
} }
} }
} }
if constexpr (Consumer::keep_keywords) {
pop_pool_entry(); pop_pool_entry();
}
if (!consumer.literal(pos)) { if (!consumer.literal(pos)) {
return; return;
} }
continue; continue;
} else { } else {
auto& str = *text;
if (ttype == token::Token_ENUMERATION && str.size() == 1 && (str[0] == 'T' || str[0] == 'F' || str[0] == 'U')) { if (ttype == token::Token_ENUMERATION && str.size() == 1 && (str[0] == 'T' || str[0] == 'F' || str[0] == 'U')) {
pop_pool_entry(); pop_pool_entry();
if (!consumer.boolean(pos, str[0])) { if (!consumer.boolean(pos, str[0])) {