diff --git a/ext/rbs_extension/parser.c b/ext/rbs_extension/parser.c index cafb4a0d5..c6f89a1fc 100644 --- a/ext/rbs_extension/parser.c +++ b/ext/rbs_extension/parser.c @@ -2836,7 +2836,10 @@ parse_type_try(VALUE a) { static VALUE rbsparser_parse_type(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos, VALUE variables, VALUE require_eof) { - parserstate *parser = alloc_parser(buffer, FIX2INT(start_pos), FIX2INT(end_pos), variables); + VALUE string = rb_funcall(buffer, rb_intern("content"), 0); + StringValue(string); + lexstate *lexer = alloc_lexer(string, FIX2INT(start_pos), FIX2INT(end_pos)); + parserstate *parser = alloc_parser(buffer, lexer, FIX2INT(start_pos), FIX2INT(end_pos), variables); struct parse_type_arg arg = { parser, require_eof @@ -2864,7 +2867,10 @@ parse_method_type_try(VALUE a) { static VALUE rbsparser_parse_method_type(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos, VALUE variables, VALUE require_eof) { - parserstate *parser = alloc_parser(buffer, FIX2INT(start_pos), FIX2INT(end_pos), variables); + VALUE string = rb_funcall(buffer, rb_intern("content"), 0); + StringValue(string); + lexstate *lexer = alloc_lexer(string, FIX2INT(start_pos), FIX2INT(end_pos)); + parserstate *parser = alloc_parser(buffer, lexer, FIX2INT(start_pos), FIX2INT(end_pos), variables); struct parse_type_arg arg = { parser, require_eof @@ -2881,13 +2887,18 @@ parse_signature_try(VALUE a) { static VALUE rbsparser_parse_signature(VALUE self, VALUE buffer, VALUE end_pos) { - parserstate *parser = alloc_parser(buffer, 0, FIX2INT(end_pos), Qnil); + VALUE string = rb_funcall(buffer, rb_intern("content"), 0); + StringValue(string); + lexstate *lexer = alloc_lexer(string, 0, FIX2INT(end_pos)); + parserstate *parser = alloc_parser(buffer, lexer, 0, FIX2INT(end_pos), Qnil); return rb_ensure(parse_signature_try, (VALUE)parser, ensure_free_parser, (VALUE)parser); } static VALUE rbsparser_lex(VALUE self, VALUE buffer, VALUE end_pos) { - lexstate *lexer = alloc_lexer(buffer, 0, FIX2INT(end_pos)); + VALUE string = rb_funcall(buffer, rb_intern("content"), 0); + StringValue(string); + lexstate *lexer = alloc_lexer(string, 0, FIX2INT(end_pos)); VALUE results = rb_ary_new(); token token = NullToken; @@ -2906,6 +2917,7 @@ rbsparser_lex(VALUE self, VALUE buffer, VALUE end_pos) { void rbs__init_parser(void) { RBS_Parser = rb_define_class_under(RBS, "Parser", rb_cObject); + rb_gc_register_mark_object(RBS_Parser); rb_define_singleton_method(RBS_Parser, "_parse_type", rbsparser_parse_type, 5); rb_define_singleton_method(RBS_Parser, "_parse_method_type", rbsparser_parse_method_type, 5); rb_define_singleton_method(RBS_Parser, "_parse_signature", rbsparser_parse_signature, 2); diff --git a/ext/rbs_extension/parserstate.c b/ext/rbs_extension/parserstate.c index 58e4b0206..4818f05a7 100644 --- a/ext/rbs_extension/parserstate.c +++ b/ext/rbs_extension/parserstate.c @@ -274,11 +274,7 @@ VALUE comment_to_ruby(comment *com, VALUE buffer) { ); } -lexstate *alloc_lexer(VALUE buffer, int start_pos, int end_pos) { - VALUE string = rb_funcall(buffer, rb_intern("content"), 0); - - StringValue(string); - +lexstate *alloc_lexer(VALUE string, int start_pos, int end_pos) { if (start_pos < 0 || end_pos < 0) { rb_raise(rb_eArgError, "negative position range: %d...%d", start_pos, end_pos); } @@ -295,8 +291,7 @@ lexstate *alloc_lexer(VALUE buffer, int start_pos, int end_pos) { return lexer; } -parserstate *alloc_parser(VALUE buffer, int start_pos, int end_pos, VALUE variables) { - lexstate *lexer = alloc_lexer(buffer, start_pos, end_pos); +parserstate *alloc_parser(VALUE buffer, lexstate *lexer, int start_pos, int end_pos, VALUE variables) { parserstate *parser = calloc(1, sizeof(parserstate)); parser->lexstate = lexer; parser->buffer = buffer; diff --git a/ext/rbs_extension/parserstate.h b/ext/rbs_extension/parserstate.h index 4f495dbbe..4e443f19c 100644 --- a/ext/rbs_extension/parserstate.h +++ b/ext/rbs_extension/parserstate.h @@ -97,20 +97,21 @@ bool parser_typevar_member(parserstate *state, ID id); * Allocate new lexstate object. * * ``` - * alloc_lexer(buffer, 0, 31) // New lexstate with buffer + * VALUE string = rb_funcall(buffer, rb_intern("content"), 0); + * alloc_lexer(string, 0, 31) // New lexstate with buffer content * ``` * */ -lexstate *alloc_lexer(VALUE buffer, int start_pos, int end_pos); +lexstate *alloc_lexer(VALUE string, int start_pos, int end_pos); /** * Allocate new parserstate object. * * ``` - * alloc_parser(buffer, 0, 1, variables) // New parserstate with variables - * alloc_parser(buffer, 3, 5, Qnil) // New parserstate without variables + * alloc_parser(buffer, lexer, 0, 1, variables) // New parserstate with variables + * alloc_parser(buffer, lexer, 3, 5, Qnil) // New parserstate without variables * ``` * */ -parserstate *alloc_parser(VALUE buffer, int start_pos, int end_pos, VALUE variables); +parserstate *alloc_parser(VALUE buffer, lexstate *lexer, int start_pos, int end_pos, VALUE variables); void free_parser(parserstate *parser); /** * Advance one token.