json 2.18.1 → 2.19.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES.md +33 -0
- data/ext/json/ext/fbuffer/fbuffer.h +17 -15
- data/ext/json/ext/generator/extconf.rb +2 -0
- data/ext/json/ext/generator/generator.c +78 -310
- data/ext/json/ext/json.h +15 -0
- data/ext/json/ext/parser/extconf.rb +4 -0
- data/ext/json/ext/parser/parser.c +118 -75
- data/ext/json/ext/simd/simd.h +0 -10
- data/lib/json/common.rb +41 -10
- data/lib/json/ext/generator/state.rb +1 -1
- data/lib/json/truffle_ruby/generator.rb +21 -9
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +14 -2
- metadata +2 -2
|
@@ -74,9 +74,6 @@ static void generate_json_string(FBuffer *buffer, struct generate_json_data *dat
|
|
|
74
74
|
static void generate_json_null(FBuffer *buffer, struct generate_json_data *data, VALUE obj);
|
|
75
75
|
static void generate_json_false(FBuffer *buffer, struct generate_json_data *data, VALUE obj);
|
|
76
76
|
static void generate_json_true(FBuffer *buffer, struct generate_json_data *data, VALUE obj);
|
|
77
|
-
#ifdef RUBY_INTEGER_UNIFICATION
|
|
78
|
-
static void generate_json_integer(FBuffer *buffer, struct generate_json_data *data, VALUE obj);
|
|
79
|
-
#endif
|
|
80
77
|
static void generate_json_fixnum(FBuffer *buffer, struct generate_json_data *data, VALUE obj);
|
|
81
78
|
static void generate_json_bignum(FBuffer *buffer, struct generate_json_data *data, VALUE obj);
|
|
82
79
|
static void generate_json_float(FBuffer *buffer, struct generate_json_data *data, VALUE obj);
|
|
@@ -703,233 +700,6 @@ static void convert_UTF8_to_ASCII_only_JSON(search_state *search, const unsigned
|
|
|
703
700
|
}
|
|
704
701
|
}
|
|
705
702
|
|
|
706
|
-
/*
|
|
707
|
-
* Document-module: JSON::Ext::Generator
|
|
708
|
-
*
|
|
709
|
-
* This is the JSON generator implemented as a C extension. It can be
|
|
710
|
-
* configured to be used by setting
|
|
711
|
-
*
|
|
712
|
-
* JSON.generator = JSON::Ext::Generator
|
|
713
|
-
*
|
|
714
|
-
* with the method generator= in JSON.
|
|
715
|
-
*
|
|
716
|
-
*/
|
|
717
|
-
|
|
718
|
-
/* Explanation of the following: that's the only way to not pollute
|
|
719
|
-
* standard library's docs with GeneratorMethods::<ClassName> which
|
|
720
|
-
* are uninformative and take a large place in a list of classes
|
|
721
|
-
*/
|
|
722
|
-
|
|
723
|
-
/*
|
|
724
|
-
* Document-module: JSON::Ext::Generator::GeneratorMethods
|
|
725
|
-
* :nodoc:
|
|
726
|
-
*/
|
|
727
|
-
|
|
728
|
-
/*
|
|
729
|
-
* Document-module: JSON::Ext::Generator::GeneratorMethods::Array
|
|
730
|
-
* :nodoc:
|
|
731
|
-
*/
|
|
732
|
-
|
|
733
|
-
/*
|
|
734
|
-
* Document-module: JSON::Ext::Generator::GeneratorMethods::Bignum
|
|
735
|
-
* :nodoc:
|
|
736
|
-
*/
|
|
737
|
-
|
|
738
|
-
/*
|
|
739
|
-
* Document-module: JSON::Ext::Generator::GeneratorMethods::FalseClass
|
|
740
|
-
* :nodoc:
|
|
741
|
-
*/
|
|
742
|
-
|
|
743
|
-
/*
|
|
744
|
-
* Document-module: JSON::Ext::Generator::GeneratorMethods::Fixnum
|
|
745
|
-
* :nodoc:
|
|
746
|
-
*/
|
|
747
|
-
|
|
748
|
-
/*
|
|
749
|
-
* Document-module: JSON::Ext::Generator::GeneratorMethods::Float
|
|
750
|
-
* :nodoc:
|
|
751
|
-
*/
|
|
752
|
-
|
|
753
|
-
/*
|
|
754
|
-
* Document-module: JSON::Ext::Generator::GeneratorMethods::Hash
|
|
755
|
-
* :nodoc:
|
|
756
|
-
*/
|
|
757
|
-
|
|
758
|
-
/*
|
|
759
|
-
* Document-module: JSON::Ext::Generator::GeneratorMethods::Integer
|
|
760
|
-
* :nodoc:
|
|
761
|
-
*/
|
|
762
|
-
|
|
763
|
-
/*
|
|
764
|
-
* Document-module: JSON::Ext::Generator::GeneratorMethods::NilClass
|
|
765
|
-
* :nodoc:
|
|
766
|
-
*/
|
|
767
|
-
|
|
768
|
-
/*
|
|
769
|
-
* Document-module: JSON::Ext::Generator::GeneratorMethods::Object
|
|
770
|
-
* :nodoc:
|
|
771
|
-
*/
|
|
772
|
-
|
|
773
|
-
/*
|
|
774
|
-
* Document-module: JSON::Ext::Generator::GeneratorMethods::String
|
|
775
|
-
* :nodoc:
|
|
776
|
-
*/
|
|
777
|
-
|
|
778
|
-
/*
|
|
779
|
-
* Document-module: JSON::Ext::Generator::GeneratorMethods::String::Extend
|
|
780
|
-
* :nodoc:
|
|
781
|
-
*/
|
|
782
|
-
|
|
783
|
-
/*
|
|
784
|
-
* Document-module: JSON::Ext::Generator::GeneratorMethods::TrueClass
|
|
785
|
-
* :nodoc:
|
|
786
|
-
*/
|
|
787
|
-
|
|
788
|
-
/*
|
|
789
|
-
* call-seq: to_json(state = nil)
|
|
790
|
-
*
|
|
791
|
-
* Returns a JSON string containing a JSON object, that is generated from
|
|
792
|
-
* this Hash instance.
|
|
793
|
-
* _state_ is a JSON::State object, that can also be used to configure the
|
|
794
|
-
* produced JSON string output further.
|
|
795
|
-
*/
|
|
796
|
-
static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self)
|
|
797
|
-
{
|
|
798
|
-
rb_check_arity(argc, 0, 1);
|
|
799
|
-
VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil);
|
|
800
|
-
return cState_partial_generate(Vstate, self, generate_json_object, Qfalse);
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
/*
|
|
804
|
-
* call-seq: to_json(state = nil)
|
|
805
|
-
*
|
|
806
|
-
* Returns a JSON string containing a JSON array, that is generated from
|
|
807
|
-
* this Array instance.
|
|
808
|
-
* _state_ is a JSON::State object, that can also be used to configure the
|
|
809
|
-
* produced JSON string output further.
|
|
810
|
-
*/
|
|
811
|
-
static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self)
|
|
812
|
-
{
|
|
813
|
-
rb_check_arity(argc, 0, 1);
|
|
814
|
-
VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil);
|
|
815
|
-
return cState_partial_generate(Vstate, self, generate_json_array, Qfalse);
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
#ifdef RUBY_INTEGER_UNIFICATION
|
|
819
|
-
/*
|
|
820
|
-
* call-seq: to_json(*)
|
|
821
|
-
*
|
|
822
|
-
* Returns a JSON string representation for this Integer number.
|
|
823
|
-
*/
|
|
824
|
-
static VALUE mInteger_to_json(int argc, VALUE *argv, VALUE self)
|
|
825
|
-
{
|
|
826
|
-
rb_check_arity(argc, 0, 1);
|
|
827
|
-
VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil);
|
|
828
|
-
return cState_partial_generate(Vstate, self, generate_json_integer, Qfalse);
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
#else
|
|
832
|
-
/*
|
|
833
|
-
* call-seq: to_json(*)
|
|
834
|
-
*
|
|
835
|
-
* Returns a JSON string representation for this Integer number.
|
|
836
|
-
*/
|
|
837
|
-
static VALUE mFixnum_to_json(int argc, VALUE *argv, VALUE self)
|
|
838
|
-
{
|
|
839
|
-
rb_check_arity(argc, 0, 1);
|
|
840
|
-
VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil);
|
|
841
|
-
return cState_partial_generate(Vstate, self, generate_json_fixnum, Qfalse);
|
|
842
|
-
}
|
|
843
|
-
|
|
844
|
-
/*
|
|
845
|
-
* call-seq: to_json(*)
|
|
846
|
-
*
|
|
847
|
-
* Returns a JSON string representation for this Integer number.
|
|
848
|
-
*/
|
|
849
|
-
static VALUE mBignum_to_json(int argc, VALUE *argv, VALUE self)
|
|
850
|
-
{
|
|
851
|
-
rb_check_arity(argc, 0, 1);
|
|
852
|
-
VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil);
|
|
853
|
-
return cState_partial_generate(Vstate, self, generate_json_bignum, Qfalse);
|
|
854
|
-
}
|
|
855
|
-
#endif
|
|
856
|
-
|
|
857
|
-
/*
|
|
858
|
-
* call-seq: to_json(*)
|
|
859
|
-
*
|
|
860
|
-
* Returns a JSON string representation for this Float number.
|
|
861
|
-
*/
|
|
862
|
-
static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self)
|
|
863
|
-
{
|
|
864
|
-
rb_check_arity(argc, 0, 1);
|
|
865
|
-
VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil);
|
|
866
|
-
return cState_partial_generate(Vstate, self, generate_json_float, Qfalse);
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
/*
|
|
870
|
-
* call-seq: to_json(*)
|
|
871
|
-
*
|
|
872
|
-
* This string should be encoded with UTF-8 A call to this method
|
|
873
|
-
* returns a JSON string encoded with UTF16 big endian characters as
|
|
874
|
-
* \u????.
|
|
875
|
-
*/
|
|
876
|
-
static VALUE mString_to_json(int argc, VALUE *argv, VALUE self)
|
|
877
|
-
{
|
|
878
|
-
rb_check_arity(argc, 0, 1);
|
|
879
|
-
VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil);
|
|
880
|
-
return cState_partial_generate(Vstate, self, generate_json_string, Qfalse);
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
/*
|
|
884
|
-
* call-seq: to_json(*)
|
|
885
|
-
*
|
|
886
|
-
* Returns a JSON string for true: 'true'.
|
|
887
|
-
*/
|
|
888
|
-
static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self)
|
|
889
|
-
{
|
|
890
|
-
rb_check_arity(argc, 0, 1);
|
|
891
|
-
return rb_utf8_str_new("true", 4);
|
|
892
|
-
}
|
|
893
|
-
|
|
894
|
-
/*
|
|
895
|
-
* call-seq: to_json(*)
|
|
896
|
-
*
|
|
897
|
-
* Returns a JSON string for false: 'false'.
|
|
898
|
-
*/
|
|
899
|
-
static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self)
|
|
900
|
-
{
|
|
901
|
-
rb_check_arity(argc, 0, 1);
|
|
902
|
-
return rb_utf8_str_new("false", 5);
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
/*
|
|
906
|
-
* call-seq: to_json(*)
|
|
907
|
-
*
|
|
908
|
-
* Returns a JSON string for nil: 'null'.
|
|
909
|
-
*/
|
|
910
|
-
static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self)
|
|
911
|
-
{
|
|
912
|
-
rb_check_arity(argc, 0, 1);
|
|
913
|
-
return rb_utf8_str_new("null", 4);
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
/*
|
|
917
|
-
* call-seq: to_json(*)
|
|
918
|
-
*
|
|
919
|
-
* Converts this object to a string (calling #to_s), converts
|
|
920
|
-
* it to a JSON string, and returns the result. This is a fallback, if no
|
|
921
|
-
* special method #to_json was defined for some object.
|
|
922
|
-
*/
|
|
923
|
-
static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self)
|
|
924
|
-
{
|
|
925
|
-
VALUE state;
|
|
926
|
-
VALUE string = rb_funcall(self, i_to_s, 0);
|
|
927
|
-
rb_scan_args(argc, argv, "01", &state);
|
|
928
|
-
Check_Type(string, T_STRING);
|
|
929
|
-
state = cState_from_state_s(cState, state);
|
|
930
|
-
return cState_partial_generate(state, string, generate_json_string, Qfalse);
|
|
931
|
-
}
|
|
932
|
-
|
|
933
703
|
static void State_mark(void *ptr)
|
|
934
704
|
{
|
|
935
705
|
JSON_Generator_State *state = ptr;
|
|
@@ -952,27 +722,20 @@ static void State_compact(void *ptr)
|
|
|
952
722
|
state->as_json = rb_gc_location(state->as_json);
|
|
953
723
|
}
|
|
954
724
|
|
|
955
|
-
static void State_free(void *ptr)
|
|
956
|
-
{
|
|
957
|
-
JSON_Generator_State *state = ptr;
|
|
958
|
-
ruby_xfree(state);
|
|
959
|
-
}
|
|
960
|
-
|
|
961
725
|
static size_t State_memsize(const void *ptr)
|
|
962
726
|
{
|
|
963
727
|
return sizeof(JSON_Generator_State);
|
|
964
728
|
}
|
|
965
729
|
|
|
966
730
|
static const rb_data_type_t JSON_Generator_State_type = {
|
|
967
|
-
"JSON/Generator/State",
|
|
968
|
-
{
|
|
731
|
+
.wrap_struct_name = "JSON/Generator/State",
|
|
732
|
+
.function = {
|
|
969
733
|
.dmark = State_mark,
|
|
970
|
-
.dfree =
|
|
734
|
+
.dfree = RUBY_DEFAULT_FREE,
|
|
971
735
|
.dsize = State_memsize,
|
|
972
736
|
.dcompact = State_compact,
|
|
973
737
|
},
|
|
974
|
-
|
|
975
|
-
RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE,
|
|
738
|
+
.flags = RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE | RUBY_TYPED_EMBEDDABLE,
|
|
976
739
|
};
|
|
977
740
|
|
|
978
741
|
static void state_init(JSON_Generator_State *state)
|
|
@@ -1056,9 +819,17 @@ static VALUE encode_json_string_rescue(VALUE str, VALUE exception)
|
|
|
1056
819
|
return Qundef;
|
|
1057
820
|
}
|
|
1058
821
|
|
|
822
|
+
static inline int json_str_coderange(VALUE str) {
|
|
823
|
+
int coderange = RB_ENC_CODERANGE(str);
|
|
824
|
+
if (coderange == RUBY_ENC_CODERANGE_UNKNOWN) {
|
|
825
|
+
coderange = rb_enc_str_coderange(str);
|
|
826
|
+
}
|
|
827
|
+
return coderange;
|
|
828
|
+
}
|
|
829
|
+
|
|
1059
830
|
static inline bool valid_json_string_p(VALUE str)
|
|
1060
831
|
{
|
|
1061
|
-
int coderange =
|
|
832
|
+
int coderange = json_str_coderange(str);
|
|
1062
833
|
|
|
1063
834
|
if (RB_LIKELY(coderange == ENC_CODERANGE_7BIT)) {
|
|
1064
835
|
return true;
|
|
@@ -1071,12 +842,8 @@ static inline bool valid_json_string_p(VALUE str)
|
|
|
1071
842
|
return false;
|
|
1072
843
|
}
|
|
1073
844
|
|
|
1074
|
-
static
|
|
845
|
+
NOINLINE(static) VALUE convert_invalid_encoding(struct generate_json_data *data, VALUE str, bool as_json_called, bool is_key)
|
|
1075
846
|
{
|
|
1076
|
-
if (RB_LIKELY(valid_json_string_p(str))) {
|
|
1077
|
-
return str;
|
|
1078
|
-
}
|
|
1079
|
-
|
|
1080
847
|
if (!as_json_called && data->state->strict && RTEST(data->state->as_json)) {
|
|
1081
848
|
VALUE coerced_str = json_call_as_json(data->state, str, Qfalse);
|
|
1082
849
|
if (coerced_str != str) {
|
|
@@ -1112,6 +879,16 @@ static inline VALUE ensure_valid_encoding(struct generate_json_data *data, VALUE
|
|
|
1112
879
|
return rb_rescue(encode_json_string_try, str, encode_json_string_rescue, str);
|
|
1113
880
|
}
|
|
1114
881
|
|
|
882
|
+
ALWAYS_INLINE(static) VALUE ensure_valid_encoding(struct generate_json_data *data, VALUE str, bool as_json_called, bool is_key)
|
|
883
|
+
{
|
|
884
|
+
if (RB_LIKELY(valid_json_string_p(str))) {
|
|
885
|
+
return str;
|
|
886
|
+
}
|
|
887
|
+
else {
|
|
888
|
+
return convert_invalid_encoding(data, str, as_json_called, is_key);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
|
|
1115
892
|
static void raw_generate_json_string(FBuffer *buffer, struct generate_json_data *data, VALUE obj)
|
|
1116
893
|
{
|
|
1117
894
|
fbuffer_append_char(buffer, '"');
|
|
@@ -1130,7 +907,7 @@ static void raw_generate_json_string(FBuffer *buffer, struct generate_json_data
|
|
|
1130
907
|
search.chunk_end = NULL;
|
|
1131
908
|
#endif /* HAVE_SIMD */
|
|
1132
909
|
|
|
1133
|
-
switch (
|
|
910
|
+
switch (json_str_coderange(obj)) {
|
|
1134
911
|
case ENC_CODERANGE_7BIT:
|
|
1135
912
|
case ENC_CODERANGE_VALID:
|
|
1136
913
|
if (RB_UNLIKELY(data->state->ascii_only)) {
|
|
@@ -1377,16 +1154,6 @@ static void generate_json_bignum(FBuffer *buffer, struct generate_json_data *dat
|
|
|
1377
1154
|
fbuffer_append_str(buffer, StringValue(tmp));
|
|
1378
1155
|
}
|
|
1379
1156
|
|
|
1380
|
-
#ifdef RUBY_INTEGER_UNIFICATION
|
|
1381
|
-
static void generate_json_integer(FBuffer *buffer, struct generate_json_data *data, VALUE obj)
|
|
1382
|
-
{
|
|
1383
|
-
if (FIXNUM_P(obj))
|
|
1384
|
-
generate_json_fixnum(buffer, data, obj);
|
|
1385
|
-
else
|
|
1386
|
-
generate_json_bignum(buffer, data, obj);
|
|
1387
|
-
}
|
|
1388
|
-
#endif
|
|
1389
|
-
|
|
1390
1157
|
static void generate_json_float(FBuffer *buffer, struct generate_json_data *data, VALUE obj)
|
|
1391
1158
|
{
|
|
1392
1159
|
double value = RFLOAT_VALUE(obj);
|
|
@@ -1430,7 +1197,7 @@ static void generate_json_fragment(FBuffer *buffer, struct generate_json_data *d
|
|
|
1430
1197
|
fbuffer_append_str(buffer, fragment);
|
|
1431
1198
|
}
|
|
1432
1199
|
|
|
1433
|
-
static void
|
|
1200
|
+
static inline void generate_json_general(FBuffer *buffer, struct generate_json_data *data, VALUE obj, bool fallback)
|
|
1434
1201
|
{
|
|
1435
1202
|
bool as_json_called = false;
|
|
1436
1203
|
start:
|
|
@@ -1457,15 +1224,15 @@ start:
|
|
|
1457
1224
|
generate_json_bignum(buffer, data, obj);
|
|
1458
1225
|
break;
|
|
1459
1226
|
case T_HASH:
|
|
1460
|
-
if (klass != rb_cHash) goto general;
|
|
1227
|
+
if (fallback && klass != rb_cHash) goto general;
|
|
1461
1228
|
generate_json_object(buffer, data, obj);
|
|
1462
1229
|
break;
|
|
1463
1230
|
case T_ARRAY:
|
|
1464
|
-
if (klass != rb_cArray) goto general;
|
|
1231
|
+
if (fallback && klass != rb_cArray) goto general;
|
|
1465
1232
|
generate_json_array(buffer, data, obj);
|
|
1466
1233
|
break;
|
|
1467
1234
|
case T_STRING:
|
|
1468
|
-
if (klass != rb_cString) goto general;
|
|
1235
|
+
if (fallback && klass != rb_cString) goto general;
|
|
1469
1236
|
|
|
1470
1237
|
if (RB_LIKELY(valid_json_string_p(obj))) {
|
|
1471
1238
|
raw_generate_json_string(buffer, data, obj);
|
|
@@ -1481,7 +1248,7 @@ start:
|
|
|
1481
1248
|
generate_json_symbol(buffer, data, obj);
|
|
1482
1249
|
break;
|
|
1483
1250
|
case T_FLOAT:
|
|
1484
|
-
if (klass != rb_cFloat) goto general;
|
|
1251
|
+
if (fallback && klass != rb_cFloat) goto general;
|
|
1485
1252
|
generate_json_float(buffer, data, obj);
|
|
1486
1253
|
break;
|
|
1487
1254
|
case T_STRUCT:
|
|
@@ -1505,6 +1272,16 @@ start:
|
|
|
1505
1272
|
}
|
|
1506
1273
|
}
|
|
1507
1274
|
|
|
1275
|
+
static void generate_json(FBuffer *buffer, struct generate_json_data *data, VALUE obj)
|
|
1276
|
+
{
|
|
1277
|
+
generate_json_general(buffer, data, obj, true);
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
static void generate_json_no_fallback(FBuffer *buffer, struct generate_json_data *data, VALUE obj)
|
|
1281
|
+
{
|
|
1282
|
+
generate_json_general(buffer, data, obj, false);
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1508
1285
|
static VALUE generate_json_try(VALUE d)
|
|
1509
1286
|
{
|
|
1510
1287
|
struct generate_json_data *data = (struct generate_json_data *)d;
|
|
@@ -1522,7 +1299,7 @@ static VALUE generate_json_ensure(VALUE d)
|
|
|
1522
1299
|
return Qundef;
|
|
1523
1300
|
}
|
|
1524
1301
|
|
|
1525
|
-
static VALUE cState_partial_generate(VALUE self, VALUE obj, generator_func func, VALUE io)
|
|
1302
|
+
static inline VALUE cState_partial_generate(VALUE self, VALUE obj, generator_func func, VALUE io)
|
|
1526
1303
|
{
|
|
1527
1304
|
GET_STATE(self);
|
|
1528
1305
|
|
|
@@ -1540,9 +1317,7 @@ static VALUE cState_partial_generate(VALUE self, VALUE obj, generator_func func,
|
|
|
1540
1317
|
.obj = obj,
|
|
1541
1318
|
.func = func
|
|
1542
1319
|
};
|
|
1543
|
-
|
|
1544
|
-
RB_GC_GUARD(self);
|
|
1545
|
-
return result;
|
|
1320
|
+
return rb_ensure(generate_json_try, (VALUE)&data, generate_json_ensure, (VALUE)&data);
|
|
1546
1321
|
}
|
|
1547
1322
|
|
|
1548
1323
|
/* call-seq:
|
|
@@ -1561,6 +1336,15 @@ static VALUE cState_generate(int argc, VALUE *argv, VALUE self)
|
|
|
1561
1336
|
return cState_partial_generate(self, obj, generate_json, io);
|
|
1562
1337
|
}
|
|
1563
1338
|
|
|
1339
|
+
/* :nodoc: */
|
|
1340
|
+
static VALUE cState_generate_no_fallback(int argc, VALUE *argv, VALUE self)
|
|
1341
|
+
{
|
|
1342
|
+
rb_check_arity(argc, 1, 2);
|
|
1343
|
+
VALUE obj = argv[0];
|
|
1344
|
+
VALUE io = argc > 1 ? argv[1] : Qnil;
|
|
1345
|
+
return cState_partial_generate(self, obj, generate_json_no_fallback, io);
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1564
1348
|
static VALUE cState_initialize(int argc, VALUE *argv, VALUE self)
|
|
1565
1349
|
{
|
|
1566
1350
|
rb_warn("The json gem extension was loaded with the stdlib ruby code. You should upgrade rubygems with `gem update --system`");
|
|
@@ -1798,6 +1582,17 @@ static long long_config(VALUE num)
|
|
|
1798
1582
|
return RTEST(num) ? FIX2LONG(num) : 0;
|
|
1799
1583
|
}
|
|
1800
1584
|
|
|
1585
|
+
// depth must never be negative; reject early with a clear error.
|
|
1586
|
+
static long depth_config(VALUE num)
|
|
1587
|
+
{
|
|
1588
|
+
if (!RTEST(num)) return 0;
|
|
1589
|
+
long d = NUM2LONG(num);
|
|
1590
|
+
if (RB_UNLIKELY(d < 0)) {
|
|
1591
|
+
rb_raise(rb_eArgError, "depth must be >= 0 (got %ld)", d);
|
|
1592
|
+
}
|
|
1593
|
+
return d;
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1801
1596
|
/*
|
|
1802
1597
|
* call-seq: max_nesting=(depth)
|
|
1803
1598
|
*
|
|
@@ -1954,7 +1749,7 @@ static VALUE cState_depth_set(VALUE self, VALUE depth)
|
|
|
1954
1749
|
{
|
|
1955
1750
|
rb_check_frozen(self);
|
|
1956
1751
|
GET_STATE(self);
|
|
1957
|
-
state->depth =
|
|
1752
|
+
state->depth = depth_config(depth);
|
|
1958
1753
|
return Qnil;
|
|
1959
1754
|
}
|
|
1960
1755
|
|
|
@@ -2019,7 +1814,7 @@ static int configure_state_i(VALUE key, VALUE val, VALUE _arg)
|
|
|
2019
1814
|
else if (key == sym_max_nesting) { state->max_nesting = long_config(val); }
|
|
2020
1815
|
else if (key == sym_allow_nan) { state->allow_nan = RTEST(val); }
|
|
2021
1816
|
else if (key == sym_ascii_only) { state->ascii_only = RTEST(val); }
|
|
2022
|
-
else if (key == sym_depth) { state->depth =
|
|
1817
|
+
else if (key == sym_depth) { state->depth = depth_config(val); }
|
|
2023
1818
|
else if (key == sym_buffer_initial_length) { buffer_initial_length_set(state, val); }
|
|
2024
1819
|
else if (key == sym_script_safe) { state->script_safe = RTEST(val); }
|
|
2025
1820
|
else if (key == sym_escape_slash) { state->script_safe = RTEST(val); }
|
|
@@ -2059,7 +1854,7 @@ static VALUE cState_configure(VALUE self, VALUE opts)
|
|
|
2059
1854
|
return self;
|
|
2060
1855
|
}
|
|
2061
1856
|
|
|
2062
|
-
static VALUE
|
|
1857
|
+
static VALUE cState_m_do_generate(VALUE klass, VALUE obj, VALUE opts, VALUE io, generator_func func)
|
|
2063
1858
|
{
|
|
2064
1859
|
JSON_Generator_State state = {0};
|
|
2065
1860
|
state_init(&state);
|
|
@@ -2077,14 +1872,21 @@ static VALUE cState_m_generate(VALUE klass, VALUE obj, VALUE opts, VALUE io)
|
|
|
2077
1872
|
.state = &state,
|
|
2078
1873
|
.depth = state.depth,
|
|
2079
1874
|
.obj = obj,
|
|
2080
|
-
.func =
|
|
1875
|
+
.func = func,
|
|
2081
1876
|
};
|
|
2082
1877
|
return rb_ensure(generate_json_try, (VALUE)&data, generate_json_ensure, (VALUE)&data);
|
|
2083
1878
|
}
|
|
2084
1879
|
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
1880
|
+
static VALUE cState_m_generate(VALUE klass, VALUE obj, VALUE opts, VALUE io)
|
|
1881
|
+
{
|
|
1882
|
+
return cState_m_do_generate(klass, obj, opts, io, generate_json);
|
|
1883
|
+
}
|
|
1884
|
+
|
|
1885
|
+
static VALUE cState_m_generate_no_fallback(VALUE klass, VALUE obj, VALUE opts, VALUE io)
|
|
1886
|
+
{
|
|
1887
|
+
return cState_m_do_generate(klass, obj, opts, io, generate_json_no_fallback);
|
|
1888
|
+
}
|
|
1889
|
+
|
|
2088
1890
|
void Init_generator(void)
|
|
2089
1891
|
{
|
|
2090
1892
|
#ifdef HAVE_RB_EXT_RACTOR_SAFE
|
|
@@ -2149,46 +1951,12 @@ void Init_generator(void)
|
|
|
2149
1951
|
rb_define_method(cState, "buffer_initial_length", cState_buffer_initial_length, 0);
|
|
2150
1952
|
rb_define_method(cState, "buffer_initial_length=", cState_buffer_initial_length_set, 1);
|
|
2151
1953
|
rb_define_method(cState, "generate", cState_generate, -1);
|
|
1954
|
+
rb_define_method(cState, "_generate_no_fallback", cState_generate_no_fallback, -1);
|
|
2152
1955
|
|
|
2153
1956
|
rb_define_private_method(cState, "allow_duplicate_key?", cState_allow_duplicate_key_p, 0);
|
|
2154
1957
|
|
|
2155
1958
|
rb_define_singleton_method(cState, "generate", cState_m_generate, 3);
|
|
2156
|
-
|
|
2157
|
-
VALUE mGeneratorMethods = rb_define_module_under(mGenerator, "GeneratorMethods");
|
|
2158
|
-
|
|
2159
|
-
VALUE mObject = rb_define_module_under(mGeneratorMethods, "Object");
|
|
2160
|
-
rb_define_method(mObject, "to_json", mObject_to_json, -1);
|
|
2161
|
-
|
|
2162
|
-
VALUE mHash = rb_define_module_under(mGeneratorMethods, "Hash");
|
|
2163
|
-
rb_define_method(mHash, "to_json", mHash_to_json, -1);
|
|
2164
|
-
|
|
2165
|
-
VALUE mArray = rb_define_module_under(mGeneratorMethods, "Array");
|
|
2166
|
-
rb_define_method(mArray, "to_json", mArray_to_json, -1);
|
|
2167
|
-
|
|
2168
|
-
#ifdef RUBY_INTEGER_UNIFICATION
|
|
2169
|
-
VALUE mInteger = rb_define_module_under(mGeneratorMethods, "Integer");
|
|
2170
|
-
rb_define_method(mInteger, "to_json", mInteger_to_json, -1);
|
|
2171
|
-
#else
|
|
2172
|
-
VALUE mFixnum = rb_define_module_under(mGeneratorMethods, "Fixnum");
|
|
2173
|
-
rb_define_method(mFixnum, "to_json", mFixnum_to_json, -1);
|
|
2174
|
-
|
|
2175
|
-
VALUE mBignum = rb_define_module_under(mGeneratorMethods, "Bignum");
|
|
2176
|
-
rb_define_method(mBignum, "to_json", mBignum_to_json, -1);
|
|
2177
|
-
#endif
|
|
2178
|
-
VALUE mFloat = rb_define_module_under(mGeneratorMethods, "Float");
|
|
2179
|
-
rb_define_method(mFloat, "to_json", mFloat_to_json, -1);
|
|
2180
|
-
|
|
2181
|
-
VALUE mString = rb_define_module_under(mGeneratorMethods, "String");
|
|
2182
|
-
rb_define_method(mString, "to_json", mString_to_json, -1);
|
|
2183
|
-
|
|
2184
|
-
VALUE mTrueClass = rb_define_module_under(mGeneratorMethods, "TrueClass");
|
|
2185
|
-
rb_define_method(mTrueClass, "to_json", mTrueClass_to_json, -1);
|
|
2186
|
-
|
|
2187
|
-
VALUE mFalseClass = rb_define_module_under(mGeneratorMethods, "FalseClass");
|
|
2188
|
-
rb_define_method(mFalseClass, "to_json", mFalseClass_to_json, -1);
|
|
2189
|
-
|
|
2190
|
-
VALUE mNilClass = rb_define_module_under(mGeneratorMethods, "NilClass");
|
|
2191
|
-
rb_define_method(mNilClass, "to_json", mNilClass_to_json, -1);
|
|
1959
|
+
rb_define_singleton_method(cState, "_generate_no_fallback", cState_m_generate_no_fallback, 3);
|
|
2192
1960
|
|
|
2193
1961
|
rb_global_variable(&Encoding_UTF_8);
|
|
2194
1962
|
Encoding_UTF_8 = rb_const_get(rb_path2class("Encoding"), rb_intern("UTF_8"));
|
data/ext/json/ext/json.h
CHANGED
|
@@ -54,9 +54,24 @@ typedef unsigned char _Bool;
|
|
|
54
54
|
# define RUBY_TYPED_FROZEN_SHAREABLE 0
|
|
55
55
|
#endif
|
|
56
56
|
|
|
57
|
+
#ifdef RUBY_TYPED_EMBEDDABLE
|
|
58
|
+
# define HAVE_RUBY_TYPED_EMBEDDABLE 1
|
|
59
|
+
#else
|
|
60
|
+
# ifdef HAVE_CONST_RUBY_TYPED_EMBEDDABLE
|
|
61
|
+
# define RUBY_TYPED_EMBEDDABLE RUBY_TYPED_EMBEDDABLE
|
|
62
|
+
# define HAVE_RUBY_TYPED_EMBEDDABLE 1
|
|
63
|
+
# else
|
|
64
|
+
# define RUBY_TYPED_EMBEDDABLE 0
|
|
65
|
+
# endif
|
|
66
|
+
#endif
|
|
67
|
+
|
|
57
68
|
#ifndef NORETURN
|
|
69
|
+
#if defined(__has_attribute) && __has_attribute(noreturn)
|
|
70
|
+
#define NORETURN(x) __attribute__((noreturn)) x
|
|
71
|
+
#else
|
|
58
72
|
#define NORETURN(x) x
|
|
59
73
|
#endif
|
|
74
|
+
#endif
|
|
60
75
|
|
|
61
76
|
#ifndef NOINLINE
|
|
62
77
|
#if defined(__has_attribute) && __has_attribute(noinline)
|
|
@@ -7,6 +7,10 @@ have_func("rb_str_to_interned_str", "ruby.h") # RUBY_VERSION >= 3.0
|
|
|
7
7
|
have_func("rb_hash_new_capa", "ruby.h") # RUBY_VERSION >= 3.2
|
|
8
8
|
have_func("rb_hash_bulk_insert", "ruby.h") # Missing on TruffleRuby
|
|
9
9
|
|
|
10
|
+
if RUBY_ENGINE == "ruby"
|
|
11
|
+
have_const("RUBY_TYPED_EMBEDDABLE", "ruby.h") # RUBY_VERSION >= 3.3
|
|
12
|
+
end
|
|
13
|
+
|
|
10
14
|
append_cflags("-std=c99")
|
|
11
15
|
|
|
12
16
|
if enable_config('parser-use-simd', default=!ENV["JSON_DISABLE_SIMD"])
|