Skip to content

Commit 3488eda

Browse files
committed
Fix gc_verify_internal_consistency error for pattern_matching in ripper
`gc_verify_internal_consistency` reports "found internal inconsistency" for "test_pattern_matching.rb". http://ci.rvm.jp/results/trunk-gc-asserts@ruby-sp2-docker/4501173 Ruby's parser manages objects by two different ways. 1. For parser * markable node holds objects * call `RB_OBJ_WRITTEN` with `p->ast` as parent * `mark_ast_value` marks objects 2. For ripper * unmarkable node, NODE_RIPPER/NODE_CDECL, holds objects * call `rb_ast_add_mark_object`. This function calls `rb_hash_aset` then `RB_OBJ_WRITTEN` is called with `mark_hash` as parent * `mark_hash` marks objects However in current pattern_matching implementation * markable node holds objects * call `rb_ast_add_mark_object` This commit fix it to be #2. This was inconsistency however always `mark_hash` is made young by `rb_ast_add_mark_object` call then objects are not collected.
1 parent a8782c4 commit 3488eda

File tree

1 file changed

+14
-21
lines changed

1 file changed

+14
-21
lines changed

parse.y

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,8 @@ static void check_literal_when(struct parser_params *p, NODE *args, const YYLTYP
830830
#else /* RIPPER */
831831
#define NODE_RIPPER NODE_CDECL
832832
#define NEW_RIPPER(a,b,c,loc) (VALUE)NEW_CDECL(a,b,c,loc)
833+
#define NODE_RIPPER2 NODE_OP_CDECL
834+
#define NEW_RIPPER2(a,b,c,loc) (VALUE)NEW_OP_CDECL(a,c,b,loc)
833835

834836
static inline int ripper_is_node_yylval(VALUE n);
835837

@@ -842,6 +844,15 @@ ripper_new_yylval(struct parser_params *p, ID a, VALUE b, VALUE c)
842844
return NEW_RIPPER(a, b, c, &NULL_LOC);
843845
}
844846

847+
static inline VALUE
848+
ripper_new_yylval2(struct parser_params *p, VALUE a, VALUE b, VALUE c)
849+
{
850+
add_mark_object(p, a);
851+
add_mark_object(p, b);
852+
add_mark_object(p, c);
853+
return NEW_RIPPER2(a, b, c, &NULL_LOC);
854+
}
855+
845856
static inline int
846857
ripper_is_node_yylval(VALUE n)
847858
{
@@ -1115,14 +1126,7 @@ new_array_pattern(struct parser_params *p, VALUE constant, VALUE pre_arg, VALUE
11151126
static VALUE
11161127
new_array_pattern_tail(struct parser_params *p, VALUE pre_args, VALUE has_rest, VALUE rest_arg, VALUE post_args, const YYLTYPE *loc)
11171128
{
1118-
NODE *t;
1119-
1120-
1121-
t = rb_node_newnode(NODE_ARYPTN, pre_args, rest_arg, post_args, &NULL_LOC);
1122-
add_mark_object(p, pre_args);
1123-
add_mark_object(p, rest_arg);
1124-
add_mark_object(p, post_args);
1125-
return (VALUE)t;
1129+
return ripper_new_yylval2(p, pre_args, rest_arg, post_args);
11261130
}
11271131

11281132
static VALUE
@@ -1137,13 +1141,7 @@ new_find_pattern(struct parser_params *p, VALUE constant, VALUE fndptn, const YY
11371141
static VALUE
11381142
new_find_pattern_tail(struct parser_params *p, VALUE pre_rest_arg, VALUE args, VALUE post_rest_arg, const YYLTYPE *loc)
11391143
{
1140-
NODE *t;
1141-
1142-
t = rb_node_newnode(NODE_FNDPTN, pre_rest_arg, args, post_rest_arg, &NULL_LOC);
1143-
add_mark_object(p, pre_rest_arg);
1144-
add_mark_object(p, args);
1145-
add_mark_object(p, post_rest_arg);
1146-
return (VALUE)t;
1144+
return ripper_new_yylval2(p, pre_rest_arg, args, post_rest_arg);
11471145
}
11481146

11491147
#define new_hash(p,h,l) rb_ary_new_from_args(0)
@@ -1165,18 +1163,13 @@ new_hash_pattern(struct parser_params *p, VALUE constant, VALUE hshptn, const YY
11651163
static VALUE
11661164
new_hash_pattern_tail(struct parser_params *p, VALUE kw_args, VALUE kw_rest_arg, const YYLTYPE *loc)
11671165
{
1168-
NODE *t;
11691166
if (kw_rest_arg) {
11701167
kw_rest_arg = dispatch1(var_field, kw_rest_arg);
11711168
}
11721169
else {
11731170
kw_rest_arg = Qnil;
11741171
}
1175-
t = rb_node_newnode(NODE_HSHPTN, kw_args, kw_rest_arg, 0, &NULL_LOC);
1176-
1177-
add_mark_object(p, kw_args);
1178-
add_mark_object(p, kw_rest_arg);
1179-
return (VALUE)t;
1172+
return ripper_new_yylval2(p, kw_args, kw_rest_arg, Qnil);
11801173
}
11811174

11821175
#define new_defined(p,expr,loc) dispatch1(defined, (expr))

0 commit comments

Comments
 (0)