55static VALUE mJSON , eNestingError , eParserError , Encoding_UTF_8 ;
66static VALUE CNaN , CInfinity , CMinusInfinity ;
77
8- static ID i_new , i_try_convert , i_uminus , i_encode , i_at_line , i_at_column , i_at_eos ;
8+ static ID i_new , i_try_convert , i_uminus , i_encode , i_at_line , i_at_column ;
99
1010static VALUE sym_max_nesting , sym_allow_nan , sym_allow_trailing_comma , sym_allow_comments ,
1111 sym_allow_control_characters , sym_allow_invalid_escape , sym_symbolize_names ,
@@ -669,19 +669,46 @@ static VALUE parse_error_new(JSON_ParserState *state, VALUE message, long line,
669669 VALUE exc = rb_exc_new_str (eParserError , message );
670670 rb_ivar_set (exc , i_at_line , LONG2NUM (line ));
671671 rb_ivar_set (exc , i_at_column , LONG2NUM (column ));
672- if (eos && state -> parser ) {
673- rb_ivar_set (exc , i_at_eos , state -> parser );
674- }
675672 return exc ;
676673}
677674
675+ #ifdef JSON_WORKAROUND_RB_CATCH_BUG
676+ #define JSON_CATCH_FUNC_ARGLIST (yielded_arg , func_args ) VALUE func_args
677+
678+ NORETURN (static ) void parser_throw_eos (VALUE parser )
679+ {
680+ VALUE exc = rb_exc_new_str (eParserError , rb_utf8_str_new_cstr ("EOS" ));
681+ rb_ivar_set (exc , rb_intern ("@resumable_parser_eos" ), parser );
682+ rb_exc_raise (exc );
683+ }
684+
685+ static VALUE parser_catch_eos (VALUE parser , VALUE (* func )(VALUE args ), VALUE func_args )
686+ {
687+ int status ;
688+ VALUE result = rb_protect (func , func_args , & status );
689+ if (status ) {
690+ VALUE error_source = rb_ivar_get (rb_errinfo (), rb_intern ("@resumable_parser_eos" ));
691+ if (error_source == parser ) {
692+ rb_set_errinfo (Qnil );
693+ return parser ;
694+ }
695+ rb_jump_tag (status );
696+ }
697+ return result ;
698+ }
699+ #else
700+ #define JSON_CATCH_FUNC_ARGLIST RB_BLOCK_CALL_FUNC_ARGLIST
701+ #define parser_throw_eos (parser ) rb_throw_obj(parser, parser)
702+ #define parser_catch_eos (parser , func , func_args ) rb_catch_obj(parser, func, func_args)
703+ #endif
704+
678705NORETURN (static ) void raise_parse_error (const char * format , JSON_ParserState * state , bool eos )
679706{
680707 if (state -> parser ) {
681708 if (eos ) {
682709 // the error will be swallowed by ResumableParser#parse, so no
683710 // point building a message or backtrace.
684- rb_throw_obj ( state -> parser , state -> parser );
711+ parser_throw_eos ( state -> parser );
685712 } else {
686713 // line and columns can't be accurate in resumable
687714 rb_exc_raise (parse_error_new (state , build_parse_error_message (format , state ), 0 , 0 , eos ));
@@ -2389,7 +2416,7 @@ struct json_parse_any_args {
23892416 VALUE parser ;
23902417};
23912418
2392- static VALUE json_parse_any_resumable_safe0 (RB_BLOCK_CALL_FUNC_ARGLIST (yielded_arg , _args ))
2419+ static VALUE json_parse_any_resumable_safe0 (JSON_CATCH_FUNC_ARGLIST (yielded_arg , _args ))
23932420{
23942421 struct json_parse_any_args * args = (struct json_parse_any_args * )_args ;
23952422 return (VALUE )json_parse_any (args -> state , args -> config , true);
@@ -2398,11 +2425,8 @@ static VALUE json_parse_any_resumable_safe0(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_a
23982425static VALUE json_parse_any_resumable_safe (VALUE _args )
23992426{
24002427 struct json_parse_any_args * args = (struct json_parse_any_args * )_args ;
2401- VALUE result = rb_catch_obj (args -> parser , json_parse_any_resumable_safe0 , _args );
2402- if (result == args -> parser ) {
2403- return (VALUE )false;
2404- }
2405- return result ;
2428+ VALUE result = parser_catch_eos (args -> parser , json_parse_any_resumable_safe0 , _args );
2429+ return result == args -> parser ? Qfalse : result ;
24062430}
24072431
24082432static JSON_ResumableParser * ResumableParser_acquire (VALUE self , bool lock )
@@ -2778,7 +2802,6 @@ void Init_parser(void)
27782802 i_encode = rb_intern ("encode" );
27792803 i_at_line = rb_intern ("@line" );
27802804 i_at_column = rb_intern ("@column" );
2781- i_at_eos = rb_intern ("@eos" );
27822805
27832806 binary_encindex = rb_ascii8bit_encindex ();
27842807 utf8_encindex = rb_utf8_encindex ();
0 commit comments