Skip to content

Commit

Permalink
Optimize Symbol generation in strict mode
Browse files Browse the repository at this point in the history
Co-authored-by: Jean Boussier <[email protected]>
  • Loading branch information
etiennebarrie and byroot committed Feb 5, 2025
1 parent c472d72 commit a43983e
Showing 1 changed file with 30 additions and 8 deletions.
38 changes: 30 additions & 8 deletions ext/json/ext/generator/generator.c
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,29 @@ static void generate_json_string(FBuffer *buffer, struct generate_json_data *dat
fbuffer_append_char(buffer, '"');
}

static void generate_json_fallback(FBuffer *buffer, struct generate_json_data *data, JSON_Generator_State *state, VALUE obj)
{
VALUE tmp;
if (rb_respond_to(obj, i_to_json)) {
tmp = rb_funcall(obj, i_to_json, 1, vstate_get(data));
Check_Type(tmp, T_STRING);
fbuffer_append_str(buffer, tmp);
} else {
tmp = rb_funcall(obj, i_to_s, 0);
Check_Type(tmp, T_STRING);
generate_json_string(buffer, data, state, tmp);
}
}

static inline void generate_json_symbol(FBuffer *buffer, struct generate_json_data *data, JSON_Generator_State *state, VALUE obj)
{
if (state->strict) {
generate_json_string(buffer, data, state, rb_sym2str(obj));
} else {
generate_json_fallback(buffer, data, state, obj);
}
}

static void generate_json_null(FBuffer *buffer, struct generate_json_data *data, JSON_Generator_State *state, VALUE obj)
{
fbuffer_append(buffer, "null", 4);
Expand Down Expand Up @@ -1049,7 +1072,6 @@ static void generate_json_fragment(FBuffer *buffer, struct generate_json_data *d

static void generate_json(FBuffer *buffer, struct generate_json_data *data, JSON_Generator_State *state, VALUE obj)
{
VALUE tmp;
bool as_json_called = false;
start:
if (obj == Qnil) {
Expand All @@ -1063,6 +1085,8 @@ static void generate_json(FBuffer *buffer, struct generate_json_data *data, JSON
generate_json_fixnum(buffer, data, state, obj);
} else if (RB_FLONUM_P(obj)) {
generate_json_float(buffer, data, state, obj);
} else if (RB_STATIC_SYM_P(obj)) {
generate_json_symbol(buffer, data, state, obj);
} else {
goto general;
}
Expand All @@ -1084,6 +1108,10 @@ static void generate_json(FBuffer *buffer, struct generate_json_data *data, JSON
if (klass != rb_cString) goto general;
generate_json_string(buffer, data, state, obj);
break;
case T_SYMBOL:
if (klass != rb_cSymbol) goto general;
generate_json_string(buffer, data, state, rb_sym2str(obj));
break;
case T_FLOAT:
if (klass != rb_cFloat) goto general;
generate_json_float(buffer, data, state, obj);
Expand All @@ -1102,14 +1130,8 @@ static void generate_json(FBuffer *buffer, struct generate_json_data *data, JSON
} else {
raise_generator_error(obj, "%"PRIsVALUE" not allowed in JSON", CLASS_OF(obj));
}
} else if (rb_respond_to(obj, i_to_json)) {
tmp = rb_funcall(obj, i_to_json, 1, vstate_get(data));
Check_Type(tmp, T_STRING);
fbuffer_append_str(buffer, tmp);
} else {
tmp = rb_funcall(obj, i_to_s, 0);
Check_Type(tmp, T_STRING);
generate_json_string(buffer, data, state, tmp);
generate_json_fallback(buffer, data, state, obj);
}
}
}
Expand Down

0 comments on commit a43983e

Please sign in to comment.