Skip to content

Commit 7e557ee

Browse files
committed
parser.rl: extract build_string
1 parent 0c797b4 commit 7e557ee

File tree

2 files changed

+97
-83
lines changed

2 files changed

+97
-83
lines changed

ext/json/ext/parser/parser.c

Lines changed: 57 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,6 +1450,43 @@ case 16:
14501450
}
14511451
}
14521452

1453+
static inline VALUE build_string(const char *buffer, const char *bufferStart, bool intern, bool symbolize)
1454+
{
1455+
if (symbolize) {
1456+
intern = true;
1457+
}
1458+
VALUE result;
1459+
# ifdef HAVE_RB_ENC_INTERNED_STR
1460+
if (intern) {
1461+
result = rb_enc_interned_str(bufferStart, (long)(buffer - bufferStart), rb_utf8_encoding());
1462+
} else {
1463+
result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
1464+
}
1465+
# else
1466+
result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
1467+
if (intern) {
1468+
# if STR_UMINUS_DEDUPE_FROZEN
1469+
// Starting from MRI 3.0 it is preferable to freeze the string
1470+
// before deduplication so that it can be interned directly
1471+
// otherwise it would be duplicated first which is wasteful.
1472+
result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
1473+
# elif STR_UMINUS_DEDUPE
1474+
// MRI 2.5 and older do not deduplicate strings that are already
1475+
// frozen.
1476+
result = rb_funcall(result, i_uminus, 0);
1477+
# else
1478+
result = rb_str_freeze(result);
1479+
# endif
1480+
}
1481+
# endif
1482+
1483+
if (symbolize) {
1484+
result = rb_str_intern(result);
1485+
}
1486+
1487+
return result;
1488+
}
1489+
14531490
static const size_t MAX_STACK_BUFFER_SIZE = 128;
14541491
static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int symbolize)
14551492
{
@@ -1561,55 +1598,25 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
15611598
buffer += pe - p;
15621599
}
15631600

1564-
# ifdef HAVE_RB_ENC_INTERNED_STR
1565-
if (intern) {
1566-
result = rb_enc_interned_str(bufferStart, (long)(buffer - bufferStart), rb_utf8_encoding());
1567-
} else {
1568-
result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
1569-
}
1570-
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1571-
ruby_xfree(bufferStart);
1572-
}
1573-
# else
1574-
result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
1575-
1576-
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1577-
ruby_xfree(bufferStart);
1578-
}
1601+
result = build_string(buffer, bufferStart, intern, symbolize);
15791602

1580-
if (intern) {
1581-
# if STR_UMINUS_DEDUPE_FROZEN
1582-
// Starting from MRI 2.8 it is preferable to freeze the string
1583-
// before deduplication so that it can be interned directly
1584-
// otherwise it would be duplicated first which is wasteful.
1585-
result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
1586-
# elif STR_UMINUS_DEDUPE
1587-
// MRI 2.5 and older do not deduplicate strings that are already
1588-
// frozen.
1589-
result = rb_funcall(result, i_uminus, 0);
1590-
# else
1591-
result = rb_str_freeze(result);
1592-
# endif
1593-
}
1594-
# endif
1595-
1596-
if (symbolize) {
1597-
result = rb_str_intern(result);
1603+
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
1604+
ruby_xfree(bufferStart);
15981605
}
15991606

16001607
return result;
16011608
}
16021609

16031610

1604-
#line 1605 "parser.c"
1611+
#line 1612 "parser.c"
16051612
enum {JSON_string_start = 1};
16061613
enum {JSON_string_first_final = 8};
16071614
enum {JSON_string_error = 0};
16081615

16091616
enum {JSON_string_en_main = 1};
16101617

16111618

1612-
#line 633 "parser.rl"
1619+
#line 640 "parser.rl"
16131620

16141621

16151622
static int
@@ -1630,15 +1637,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
16301637
VALUE match_string;
16311638

16321639

1633-
#line 1634 "parser.c"
1640+
#line 1641 "parser.c"
16341641
{
16351642
cs = JSON_string_start;
16361643
}
16371644

1638-
#line 653 "parser.rl"
1645+
#line 660 "parser.rl"
16391646
json->memo = p;
16401647

1641-
#line 1642 "parser.c"
1648+
#line 1649 "parser.c"
16421649
{
16431650
if ( p == pe )
16441651
goto _test_eof;
@@ -1663,7 +1670,7 @@ case 2:
16631670
goto st0;
16641671
goto st2;
16651672
tr2:
1666-
#line 620 "parser.rl"
1673+
#line 627 "parser.rl"
16671674
{
16681675
*result = json_string_unescape(json->memo + 1, p, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
16691676
if (NIL_P(*result)) {
@@ -1673,14 +1680,14 @@ case 2:
16731680
{p = (( p + 1))-1;}
16741681
}
16751682
}
1676-
#line 630 "parser.rl"
1683+
#line 637 "parser.rl"
16771684
{ p--; {p++; cs = 8; goto _out;} }
16781685
goto st8;
16791686
st8:
16801687
if ( ++p == pe )
16811688
goto _test_eof8;
16821689
case 8:
1683-
#line 1684 "parser.c"
1690+
#line 1691 "parser.c"
16841691
goto st0;
16851692
st3:
16861693
if ( ++p == pe )
@@ -1756,7 +1763,7 @@ case 7:
17561763
_out: {}
17571764
}
17581765

1759-
#line 655 "parser.rl"
1766+
#line 662 "parser.rl"
17601767

17611768
if (json->create_additions && RTEST(match_string = json->match_string)) {
17621769
VALUE klass;
@@ -1953,15 +1960,15 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
19531960
}
19541961

19551962

1956-
#line 1957 "parser.c"
1963+
#line 1964 "parser.c"
19571964
enum {JSON_start = 1};
19581965
enum {JSON_first_final = 10};
19591966
enum {JSON_error = 0};
19601967

19611968
enum {JSON_en_main = 1};
19621969

19631970

1964-
#line 865 "parser.rl"
1971+
#line 872 "parser.rl"
19651972

19661973

19671974
/*
@@ -1979,16 +1986,16 @@ static VALUE cParser_parse(VALUE self)
19791986
GET_PARSER;
19801987

19811988

1982-
#line 1983 "parser.c"
1989+
#line 1990 "parser.c"
19831990
{
19841991
cs = JSON_start;
19851992
}
19861993

1987-
#line 882 "parser.rl"
1994+
#line 889 "parser.rl"
19881995
p = json->source;
19891996
pe = p + json->len;
19901997

1991-
#line 1992 "parser.c"
1998+
#line 1999 "parser.c"
19921999
{
19932000
if ( p == pe )
19942001
goto _test_eof;
@@ -2022,7 +2029,7 @@ case 1:
20222029
cs = 0;
20232030
goto _out;
20242031
tr2:
2025-
#line 857 "parser.rl"
2032+
#line 864 "parser.rl"
20262033
{
20272034
char *np = JSON_parse_value(json, p, pe, &result, 0);
20282035
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
@@ -2032,7 +2039,7 @@ cs = 0;
20322039
if ( ++p == pe )
20332040
goto _test_eof10;
20342041
case 10:
2035-
#line 2036 "parser.c"
2042+
#line 2043 "parser.c"
20362043
switch( (*p) ) {
20372044
case 13: goto st10;
20382045
case 32: goto st10;
@@ -2121,7 +2128,7 @@ case 9:
21212128
_out: {}
21222129
}
21232130

2124-
#line 885 "parser.rl"
2131+
#line 892 "parser.rl"
21252132

21262133
if (cs >= JSON_first_final && p == pe) {
21272134
return result;

ext/json/ext/parser/parser.rl

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,43 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
461461
}
462462
}
463463

464+
static inline VALUE build_string(const char *buffer, const char *bufferStart, bool intern, bool symbolize)
465+
{
466+
if (symbolize) {
467+
intern = true;
468+
}
469+
VALUE result;
470+
# ifdef HAVE_RB_ENC_INTERNED_STR
471+
if (intern) {
472+
result = rb_enc_interned_str(bufferStart, (long)(buffer - bufferStart), rb_utf8_encoding());
473+
} else {
474+
result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
475+
}
476+
# else
477+
result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
478+
if (intern) {
479+
# if STR_UMINUS_DEDUPE_FROZEN
480+
// Starting from MRI 3.0 it is preferable to freeze the string
481+
// before deduplication so that it can be interned directly
482+
// otherwise it would be duplicated first which is wasteful.
483+
result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
484+
# elif STR_UMINUS_DEDUPE
485+
// MRI 2.5 and older do not deduplicate strings that are already
486+
// frozen.
487+
result = rb_funcall(result, i_uminus, 0);
488+
# else
489+
result = rb_str_freeze(result);
490+
# endif
491+
}
492+
# endif
493+
494+
if (symbolize) {
495+
result = rb_str_intern(result);
496+
}
497+
498+
return result;
499+
}
500+
464501
static const size_t MAX_STACK_BUFFER_SIZE = 128;
465502
static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int symbolize)
466503
{
@@ -572,40 +609,10 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
572609
buffer += pe - p;
573610
}
574611

575-
# ifdef HAVE_RB_ENC_INTERNED_STR
576-
if (intern) {
577-
result = rb_enc_interned_str(bufferStart, (long)(buffer - bufferStart), rb_utf8_encoding());
578-
} else {
579-
result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
580-
}
581-
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
582-
ruby_xfree(bufferStart);
583-
}
584-
# else
585-
result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
586-
587-
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
588-
ruby_xfree(bufferStart);
589-
}
612+
result = build_string(buffer, bufferStart, intern, symbolize);
590613

591-
if (intern) {
592-
# if STR_UMINUS_DEDUPE_FROZEN
593-
// Starting from MRI 2.8 it is preferable to freeze the string
594-
// before deduplication so that it can be interned directly
595-
// otherwise it would be duplicated first which is wasteful.
596-
result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
597-
# elif STR_UMINUS_DEDUPE
598-
// MRI 2.5 and older do not deduplicate strings that are already
599-
// frozen.
600-
result = rb_funcall(result, i_uminus, 0);
601-
# else
602-
result = rb_str_freeze(result);
603-
# endif
604-
}
605-
# endif
606-
607-
if (symbolize) {
608-
result = rb_str_intern(result);
614+
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
615+
ruby_xfree(bufferStart);
609616
}
610617

611618
return result;

0 commit comments

Comments
 (0)