summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2024-03-26 10:31:51 -0400
committerKevin Newton <kddnewton@gmail.com>2024-03-26 12:11:09 -0400
commit8ec7c3ce3069177a9e8eb9ca93cced9aa0533085 (patch)
tree055877c056c77124c2d88404bd677517f37faeea
parent2a3601d64ead632fb9f0709ac6986a44da76efe3 (diff)
[ruby/prism] Properly handle freeing ephemeral node lists
https://github.com/ruby/prism/commit/f49261a9b9
-rw-r--r--prism/prism.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/prism/prism.c b/prism/prism.c
index e02bceed65..4f65e1e017 100644
--- a/prism/prism.c
+++ b/prism/prism.c
@@ -4411,6 +4411,12 @@ pm_interpolated_symbol_node_append(pm_interpolated_symbol_node_t *node, pm_node_
node->base.location.end = MAX(node->base.location.end, part->location.end);
}
+static void
+pm_interpolated_symbol_node_closing_loc_set(pm_interpolated_symbol_node_t *node, const pm_token_t *closing) {
+ node->closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing);
+ node->base.location.end = closing->end;
+}
+
/**
* Allocate and initialize a new InterpolatedSymbolNode node.
*/
@@ -14151,14 +14157,12 @@ parse_symbol(pm_parser_t *parser, pm_lex_mode_t *lex_mode, pm_lex_state_t next_s
return (pm_node_t *) pm_string_node_to_symbol_node(parser, (pm_string_node_t *) part, &opening, &parser->previous);
}
- // Create a node_list first. We'll use this to check if it should be an
- // InterpolatedSymbolNode or a SymbolNode.
- pm_node_list_t node_list = { 0 };
- if (part) pm_node_list_append(&node_list, part);
+ pm_interpolated_symbol_node_t *symbol = pm_interpolated_symbol_node_create(parser, &opening, NULL, &opening);
+ if (part) pm_interpolated_symbol_node_append(symbol, part);
while (!match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) {
if ((part = parse_string_part(parser)) != NULL) {
- pm_node_list_append(&node_list, part);
+ pm_interpolated_symbol_node_append(symbol, part);
}
}
@@ -14169,7 +14173,8 @@ parse_symbol(pm_parser_t *parser, pm_lex_mode_t *lex_mode, pm_lex_state_t next_s
expect1(parser, PM_TOKEN_STRING_END, PM_ERR_SYMBOL_TERM_INTERPOLATED);
}
- return (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, &node_list, &parser->previous);
+ pm_interpolated_symbol_node_closing_loc_set(symbol, &parser->previous);
+ return (pm_node_t *) symbol;
}
pm_token_t content;
@@ -14190,14 +14195,14 @@ parse_symbol(pm_parser_t *parser, pm_lex_mode_t *lex_mode, pm_lex_state_t next_s
// In this case, the best way we have to represent this is as an
// interpolated string node, so that's what we'll do here.
if (match1(parser, PM_TOKEN_STRING_CONTENT)) {
- pm_node_list_t parts = { 0 };
+ pm_interpolated_symbol_node_t *symbol = pm_interpolated_symbol_node_create(parser, &opening, NULL, &opening);
pm_token_t bounds = not_provided(parser);
pm_node_t *part = (pm_node_t *) pm_string_node_create_unescaped(parser, &bounds, &content, &bounds, &unescaped);
- pm_node_list_append(&parts, part);
+ pm_interpolated_symbol_node_append(symbol, part);
part = (pm_node_t *) pm_string_node_create_unescaped(parser, &bounds, &parser->current, &bounds, &parser->current_string);
- pm_node_list_append(&parts, part);
+ pm_interpolated_symbol_node_append(symbol, part);
if (next_state != PM_LEX_STATE_NONE) {
lex_state_set(parser, next_state);
@@ -14205,7 +14210,9 @@ parse_symbol(pm_parser_t *parser, pm_lex_mode_t *lex_mode, pm_lex_state_t next_s
parser_lex(parser);
expect1(parser, PM_TOKEN_STRING_END, PM_ERR_SYMBOL_TERM_DYNAMIC);
- return (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, &parts, &parser->previous);
+
+ pm_interpolated_symbol_node_closing_loc_set(symbol, &parser->previous);
+ return (pm_node_t *) symbol;
}
} else {
content = (pm_token_t) { .type = PM_TOKEN_STRING_CONTENT, .start = parser->previous.end, .end = parser->previous.end };
@@ -15373,6 +15380,8 @@ parse_strings(pm_parser_t *parser, pm_node_t *current) {
expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_LITERAL_EOF);
node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->previous);
+
+ pm_node_list_free(&parts);
} else if (accept1(parser, PM_TOKEN_LABEL_END) && !state_is_arg_labeled) {
node = (pm_node_t *) pm_symbol_node_create_unescaped(parser, &opening, &content, &parser->previous, &unescaped, parse_symbol_encoding(parser, &unescaped));
} else if (match1(parser, PM_TOKEN_EOF)) {
@@ -15427,6 +15436,8 @@ parse_strings(pm_parser_t *parser, pm_node_t *current) {
expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_INTERPOLATED_TERM);
node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->previous);
}
+
+ pm_node_list_free(&parts);
}
} else {
// If we get here, then the first part of the string is not plain
@@ -15450,6 +15461,8 @@ parse_strings(pm_parser_t *parser, pm_node_t *current) {
expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_INTERPOLATED_TERM);
node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->previous);
}
+
+ pm_node_list_free(&parts);
}
if (current == NULL) {
@@ -16058,6 +16071,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
node = (pm_node_t *) cast;
} else {
pm_interpolated_string_node_t *cast = pm_interpolated_string_node_create(parser, &opening, &parts, &opening);
+ pm_node_list_free(&parts);
lex_mode_pop(parser);
expect1(parser, PM_TOKEN_HEREDOC_END, PM_ERR_HEREDOC_TERM);