Skip to content

Commit

Permalink
[ruby/prism] Properly handle freeing ephemeral node lists
Browse files Browse the repository at this point in the history
  • Loading branch information
kddnewton committed Mar 26, 2024
1 parent 2a3601d commit 8ec7c3c
Showing 1 changed file with 24 additions and 10 deletions.
34 changes: 24 additions & 10 deletions prism/prism.c
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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);
}
}

Expand All @@ -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;
Expand All @@ -14190,22 +14195,24 @@ 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);
}

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 };
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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
Expand All @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 8ec7c3c

Please sign in to comment.