Skip to content

Commit 7c0c2e7

Browse files
authored
Merge pull request #2308 from pocke/dedup-hash-on-parse
Dedup hash object on parsing
2 parents 1209f49 + a64d1c2 commit 7c0c2e7

File tree

1 file changed

+20
-7
lines changed

1 file changed

+20
-7
lines changed

ext/rbs_extension/parser.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,20 @@ typedef struct {
6161
} method_params;
6262

6363
static VALUE EMPTY_ARRAY;
64+
static VALUE EMPTY_HASH;
6465

6566
static inline void melt_array(VALUE *array) {
6667
if (*array == EMPTY_ARRAY) {
6768
*array = rb_ary_new();
6869
}
6970
}
7071

72+
static inline void melt_hash(VALUE *hash) {
73+
if (*hash == EMPTY_HASH) {
74+
*hash = rb_hash_new();
75+
}
76+
}
77+
7178
static bool rbs_is_untyped_params(method_params *params) {
7279
return NIL_P(params->required_positionals);
7380
}
@@ -343,7 +350,7 @@ static VALUE parse_keyword_key(parserstate *state) {
343350
/*
344351
keyword ::= {} keyword `:` <function_param>
345352
*/
346-
static void parse_keyword(parserstate *state, VALUE keywords, VALUE memo) {
353+
static void parse_keyword(parserstate *state, VALUE *keywords, VALUE memo) {
347354
VALUE key = parse_keyword_key(state);
348355

349356
if (!NIL_P(rb_hash_aref(memo, key))) {
@@ -359,7 +366,8 @@ static void parse_keyword(parserstate *state, VALUE keywords, VALUE memo) {
359366
parser_advance_assert(state, pCOLON);
360367
VALUE param = parse_function_param(state);
361368

362-
rb_hash_aset(keywords, key, param);
369+
melt_hash(keywords);
370+
rb_hash_aset(*keywords, key, param);
363371

364372
return;
365373
}
@@ -466,7 +474,7 @@ static void parse_params(parserstate *state, method_params *params) {
466474
parser_advance(state);
467475

468476
if (is_keyword(state)) {
469-
parse_keyword(state, params->optional_keywords, memo);
477+
parse_keyword(state, &params->optional_keywords, memo);
470478
parser_advance_if(state, pCOMMA);
471479
goto PARSE_KEYWORDS;
472480
}
@@ -533,7 +541,7 @@ static void parse_params(parserstate *state, method_params *params) {
533541
case pQUESTION:
534542
parser_advance(state);
535543
if (is_keyword(state)) {
536-
parse_keyword(state, params->optional_keywords, memo);
544+
parse_keyword(state, &params->optional_keywords, memo);
537545
} else {
538546
raise_syntax_error(
539547
state,
@@ -556,7 +564,7 @@ static void parse_params(parserstate *state, method_params *params) {
556564
case tBANGIDENT:
557565
KEYWORD_CASES
558566
if (is_keyword(state)) {
559-
parse_keyword(state, params->required_keywords, memo);
567+
parse_keyword(state, &params->required_keywords, memo);
560568
} else {
561569
raise_syntax_error(
562570
state,
@@ -613,8 +621,8 @@ static void initialize_method_params(method_params *params){
613621
.optional_positionals = EMPTY_ARRAY,
614622
.rest_positionals = Qnil,
615623
.trailing_positionals = EMPTY_ARRAY,
616-
.required_keywords = rb_hash_new(),
617-
.optional_keywords = rb_hash_new(),
624+
.required_keywords = EMPTY_HASH,
625+
.optional_keywords = EMPTY_HASH,
618626
.rest_keywords = Qnil,
619627
};
620628
}
@@ -2958,10 +2966,15 @@ rbsparser_lex(VALUE self, VALUE buffer, VALUE end_pos) {
29582966
void rbs__init_parser(void) {
29592967
RBS_Parser = rb_define_class_under(RBS, "Parser", rb_cObject);
29602968
rb_gc_register_mark_object(RBS_Parser);
2969+
29612970
VALUE empty_array = rb_obj_freeze(rb_ary_new());
29622971
rb_gc_register_mark_object(empty_array);
29632972
EMPTY_ARRAY = empty_array;
29642973

2974+
VALUE empty_hash = rb_obj_freeze(rb_hash_new());
2975+
rb_gc_register_mark_object(empty_hash);
2976+
EMPTY_HASH = empty_hash;
2977+
29652978
rb_define_singleton_method(RBS_Parser, "_parse_type", rbsparser_parse_type, 5);
29662979
rb_define_singleton_method(RBS_Parser, "_parse_method_type", rbsparser_parse_method_type, 5);
29672980
rb_define_singleton_method(RBS_Parser, "_parse_signature", rbsparser_parse_signature, 3);

0 commit comments

Comments
 (0)