[ruby/prism] Properly handle freeing ephemeral node lists

https://github.com/ruby/prism/commit/f49261a9b9
This commit is contained in:
Kevin Newton 2024-03-26 10:31:51 -04:00
parent 2a3601d64e
commit 8ec7c3ce30

View File

@ -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); 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. * 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); 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 pm_interpolated_symbol_node_t *symbol = pm_interpolated_symbol_node_create(parser, &opening, NULL, &opening);
// InterpolatedSymbolNode or a SymbolNode. if (part) pm_interpolated_symbol_node_append(symbol, part);
pm_node_list_t node_list = { 0 };
if (part) pm_node_list_append(&node_list, part);
while (!match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) { while (!match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) {
if ((part = parse_string_part(parser)) != NULL) { 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); 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; 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 // 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. // interpolated string node, so that's what we'll do here.
if (match1(parser, PM_TOKEN_STRING_CONTENT)) { 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_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_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); 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) { if (next_state != PM_LEX_STATE_NONE) {
lex_state_set(parser, next_state); 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); parser_lex(parser);
expect1(parser, PM_TOKEN_STRING_END, PM_ERR_SYMBOL_TERM_DYNAMIC); 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 { } else {
content = (pm_token_t) { .type = PM_TOKEN_STRING_CONTENT, .start = parser->previous.end, .end = parser->previous.end }; 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); 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); 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) { } 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)); 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)) { } 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); 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); node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->previous);
} }
pm_node_list_free(&parts);
} }
} else { } else {
// If we get here, then the first part of the string is not plain // 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); 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); node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->previous);
} }
pm_node_list_free(&parts);
} }
if (current == NULL) { 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; node = (pm_node_t *) cast;
} else { } else {
pm_interpolated_string_node_t *cast = pm_interpolated_string_node_create(parser, &opening, &parts, &opening); pm_interpolated_string_node_t *cast = pm_interpolated_string_node_create(parser, &opening, &parts, &opening);
pm_node_list_free(&parts);
lex_mode_pop(parser); lex_mode_pop(parser);
expect1(parser, PM_TOKEN_HEREDOC_END, PM_ERR_HEREDOC_TERM); expect1(parser, PM_TOKEN_HEREDOC_END, PM_ERR_HEREDOC_TERM);