@@ -841,15 +841,19 @@ json_object_i(VALUE key, VALUE val, VALUE _arg)
841841 return ST_CONTINUE ;
842842}
843843
844- static void generate_json_object ( FBuffer * buffer , struct generate_json_data * data , JSON_Generator_State * state , VALUE obj )
844+ static inline long increase_depth ( JSON_Generator_State * state )
845845{
846- long max_nesting = state -> max_nesting ;
847846 long depth = ++ state -> depth ;
848- int j ;
849-
850- if (max_nesting != 0 && depth > max_nesting ) {
847+ if (RB_UNLIKELY (depth > state -> max_nesting && state -> max_nesting )) {
851848 rb_raise (eNestingError , "nesting of %ld is too deep" , -- state -> depth );
852849 }
850+ return depth ;
851+ }
852+
853+ static void generate_json_object (FBuffer * buffer , struct generate_json_data * data , JSON_Generator_State * state , VALUE obj )
854+ {
855+ int j ;
856+ long depth = increase_depth (state );
853857
854858 if (RHASH_SIZE (obj ) == 0 ) {
855859 fbuffer_append (buffer , "{}" , 2 );
@@ -879,12 +883,8 @@ static void generate_json_object(FBuffer *buffer, struct generate_json_data *dat
879883
880884static void generate_json_array (FBuffer * buffer , struct generate_json_data * data , JSON_Generator_State * state , VALUE obj )
881885{
882- long max_nesting = state -> max_nesting ;
883- long depth = ++ state -> depth ;
884886 int i , j ;
885- if (max_nesting != 0 && depth > max_nesting ) {
886- rb_raise (eNestingError , "nesting of %ld is too deep" , -- state -> depth );
887- }
887+ long depth = increase_depth (state );
888888
889889 if (RARRAY_LEN (obj ) == 0 ) {
890890 fbuffer_append (buffer , "[]" , 2 );
@@ -1031,13 +1031,21 @@ static void generate_json_float(FBuffer *buffer, struct generate_json_data *data
10311031{
10321032 double value = RFLOAT_VALUE (obj );
10331033 char allow_nan = state -> allow_nan ;
1034- VALUE tmp = rb_funcall (obj , i_to_s , 0 );
10351034 if (!allow_nan ) {
10361035 if (isinf (value ) || isnan (value )) {
1037- raise_generator_error (obj , "%" PRIsVALUE " not allowed in JSON" , tmp );
1036+ if (state -> strict && state -> as_json ) {
1037+ VALUE casted_obj = rb_proc_call_with_block (state -> as_json , 1 , & obj , Qnil );
1038+ if (casted_obj != obj ) {
1039+ increase_depth (state );
1040+ generate_json (buffer , data , state , casted_obj );
1041+ state -> depth -- ;
1042+ return ;
1043+ }
1044+ }
1045+ raise_generator_error (obj , "%" PRIsVALUE " not allowed in JSON" , rb_funcall (obj , i_to_s , 0 ));
10381046 }
10391047 }
1040- fbuffer_append_str (buffer , tmp );
1048+ fbuffer_append_str (buffer , rb_funcall ( obj , i_to_s , 0 ) );
10411049}
10421050
10431051static void generate_json_fragment (FBuffer * buffer , struct generate_json_data * data , JSON_Generator_State * state , VALUE obj )
0 commit comments