@@ -21062,6 +21062,42 @@ parse_assignment_values(pm_parser_t *parser, pm_binding_power_t previous_binding
2106221062 return value;
2106321063}
2106421064
21065+ static bool
21066+ parse_call_operator_write_block_exits_each(const pm_node_t *node, void *data) {
21067+ pm_parser_t *parser = (pm_parser_t *) data;
21068+ size_t index = 0;
21069+
21070+ while (index < parser->current_block_exits->size) {
21071+ pm_node_t *block_exit = parser->current_block_exits->nodes[index];
21072+
21073+ if (block_exit == node) {
21074+ if (index + 1 < parser->current_block_exits->size) {
21075+ memmove(
21076+ &parser->current_block_exits->nodes[index],
21077+ &parser->current_block_exits->nodes[index + 1],
21078+ (parser->current_block_exits->size - index - 1) * sizeof(pm_node_t *)
21079+ );
21080+ }
21081+ parser->current_block_exits->size--;
21082+ return false;
21083+ }
21084+
21085+ index++;
21086+ }
21087+
21088+ return true;
21089+ }
21090+
21091+ /**
21092+ * When we are about to destroy a set of nodes that could potentially contain
21093+ * block exits for the current scope, we need to check if they are contained in
21094+ * the list of block exits and remove them if they are.
21095+ */
21096+ static void
21097+ parse_call_operator_write_block_exits(pm_parser_t *parser, const pm_node_t *node) {
21098+ pm_visit_node(node, parse_call_operator_write_block_exits_each, parser);
21099+ }
21100+
2106521101/**
2106621102 * Ensure a call node that is about to become a call operator node does not
2106721103 * have arguments or a block attached. If it does, then we'll need to add an
@@ -21073,12 +21109,14 @@ static void
2107321109parse_call_operator_write(pm_parser_t *parser, pm_call_node_t *call_node, const pm_token_t *operator) {
2107421110 if (call_node->arguments != NULL) {
2107521111 pm_parser_err_token(parser, operator, PM_ERR_OPERATOR_WRITE_ARGUMENTS);
21112+ parse_call_operator_write_block_exits(parser, (pm_node_t *) call_node->arguments);
2107621113 pm_node_destroy(parser, (pm_node_t *) call_node->arguments);
2107721114 call_node->arguments = NULL;
2107821115 }
2107921116
2108021117 if (call_node->block != NULL) {
2108121118 pm_parser_err_token(parser, operator, PM_ERR_OPERATOR_WRITE_BLOCK);
21119+ parse_call_operator_write_block_exits(parser, (pm_node_t *) call_node->block);
2108221120 pm_node_destroy(parser, (pm_node_t *) call_node->block);
2108321121 call_node->block = NULL;
2108421122 }
0 commit comments