Skip to content

Commit b75e2e8

Browse files
committed
json_ryu_parse_float -> json_decode_float
1 parent 062a418 commit b75e2e8

File tree

1 file changed

+10
-28
lines changed

1 file changed

+10
-28
lines changed

ext/json/ext/parser/parser.c

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -819,32 +819,24 @@ static VALUE json_decode_large_float(const char *start, long len)
819819
/* Ruby JSON optimized float decoder using vendored Ryu algorithm
820820
* Accepts pre-extracted mantissa and exponent from first-pass validation
821821
*/
822-
static inline VALUE json_ryu_parse_float(uint64_t m10, int m10digits, int32_t e10, bool signedM,
822+
static inline VALUE json_decode_float(JSON_ParserConfig *config, uint64_t m10, int m10digits, int32_t e10, bool signedM,
823823
const char *start, const char *end)
824824
{
825+
if (RB_UNLIKELY(config->decimal_class)) {
826+
VALUE text = rb_str_new(start, end - start);
827+
return rb_funcallv(config->decimal_class, config->decimal_method_id, 1, &text);
828+
}
829+
825830
// Fall back to rb_cstr_to_dbl for potential subnormals (rare edge case)
826831
// Ryu has rounding issues with subnormals around 1e-310 (< 2.225e-308)
827-
if (m10digits + e10 < -307) {
828-
// Use original string directly via shared helper
832+
if (RB_UNLIKELY(m10digits > 17 || m10digits + e10 < -307)) {
829833
return json_decode_large_float(start, end - start);
830834
}
831835

832836
double result = ryu_s2d_from_parts(m10, m10digits, e10, signedM);
833837
return DBL2NUM(result);
834838
}
835839

836-
static VALUE json_decode_float(JSON_ParserConfig *config, const char *start, const char *end)
837-
{
838-
long len = end - start;
839-
840-
if (RB_UNLIKELY(config->decimal_class)) {
841-
VALUE text = rb_str_new(start, len);
842-
return rb_funcallv(config->decimal_class, config->decimal_method_id, 1, &text);
843-
} else {
844-
return json_decode_large_float(start, len);
845-
}
846-
}
847-
848840
static inline VALUE json_decode_array(JSON_ParserState *state, JSON_ParserConfig *config, long count)
849841
{
850842
VALUE array = rb_ary_new_from_values(count, rvalue_stack_peek(state->stack, count));
@@ -1123,9 +1115,7 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config)
11231115

11241116
// Parse integer part and extract mantissa digits
11251117
while ((state->cursor < state->end) && rb_isdigit(*state->cursor)) {
1126-
if (m10digits < 17) { // Only keep first 17 significant digits
1127-
m10 = m10 * 10 + (*state->cursor - '0');
1128-
}
1118+
m10 = m10 * 10 + (*state->cursor - '0');
11291119
m10digits++;
11301120
state->cursor++;
11311121
}
@@ -1150,9 +1140,7 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config)
11501140
}
11511141

11521142
while ((state->cursor < state->end) && rb_isdigit(*state->cursor)) {
1153-
if (m10digits < 17) { // Only keep first 17 significant digits
1154-
m10 = m10 * 10 + (*state->cursor - '0');
1155-
}
1143+
m10 = m10 * 10 + (*state->cursor - '0');
11561144
m10digits++;
11571145
state->cursor++;
11581146
}
@@ -1191,13 +1179,7 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config)
11911179
e10 -= (m10digits - decimal_point_pos);
11921180
}
11931181

1194-
// Use optimized Ryu path if we have a valid mantissa
1195-
if (m10digits > 0 && m10digits <= 17 && !config->decimal_class) {
1196-
return json_push_value(state, config, json_ryu_parse_float(m10, m10digits, e10, signedM, start, state->cursor));
1197-
}
1198-
1199-
// Fallback to standard path for edge cases
1200-
return json_push_value(state, config, json_decode_float(config, start, state->cursor));
1182+
return json_push_value(state, config, json_decode_float(config, m10, m10digits, e10, signedM, start, state->cursor));
12011183
}
12021184
case '"': {
12031185
// %r{\A"[^"\\\t\n\x00]*(?:\\[bfnrtu\\/"][^"\\]*)*"}

0 commit comments

Comments
 (0)