json 2.18.0 → 2.19.3

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.
@@ -63,6 +63,8 @@ struct generate_json_data {
63
63
  long depth;
64
64
  };
65
65
 
66
+ static SIMD_Implementation simd_impl;
67
+
66
68
  static VALUE cState_from_state_s(VALUE self, VALUE opts);
67
69
  static VALUE cState_partial_generate(VALUE self, VALUE obj, generator_func, VALUE io);
68
70
  static void generate_json(FBuffer *buffer, struct generate_json_data *data, VALUE obj);
@@ -72,9 +74,6 @@ static void generate_json_string(FBuffer *buffer, struct generate_json_data *dat
72
74
  static void generate_json_null(FBuffer *buffer, struct generate_json_data *data, VALUE obj);
73
75
  static void generate_json_false(FBuffer *buffer, struct generate_json_data *data, VALUE obj);
74
76
  static void generate_json_true(FBuffer *buffer, struct generate_json_data *data, VALUE obj);
75
- #ifdef RUBY_INTEGER_UNIFICATION
76
- static void generate_json_integer(FBuffer *buffer, struct generate_json_data *data, VALUE obj);
77
- #endif
78
77
  static void generate_json_fixnum(FBuffer *buffer, struct generate_json_data *data, VALUE obj);
79
78
  static void generate_json_bignum(FBuffer *buffer, struct generate_json_data *data, VALUE obj);
80
79
  static void generate_json_float(FBuffer *buffer, struct generate_json_data *data, VALUE obj);
@@ -155,8 +154,6 @@ static const unsigned char escape_table_basic[256] = {
155
154
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
156
155
  };
157
156
 
158
- static unsigned char (*search_escape_basic_impl)(search_state *);
159
-
160
157
  static inline unsigned char search_escape_basic(search_state *search)
161
158
  {
162
159
  while (search->ptr < search->end) {
@@ -212,11 +209,39 @@ ALWAYS_INLINE(static) void escape_UTF8_char_basic(search_state *search)
212
209
  * Everything else (should be UTF-8) is just passed through and
213
210
  * appended to the result.
214
211
  */
212
+
213
+
214
+ #if defined(HAVE_SIMD_NEON)
215
+ static inline unsigned char search_escape_basic_neon(search_state *search);
216
+ #elif defined(HAVE_SIMD_SSE2)
217
+ static inline unsigned char search_escape_basic_sse2(search_state *search);
218
+ #endif
219
+
220
+ static inline unsigned char search_escape_basic(search_state *search);
221
+
215
222
  static inline void convert_UTF8_to_JSON(search_state *search)
216
223
  {
217
- while (search_escape_basic_impl(search)) {
224
+ #ifdef HAVE_SIMD
225
+ #if defined(HAVE_SIMD_NEON)
226
+ while (search_escape_basic_neon(search)) {
218
227
  escape_UTF8_char_basic(search);
219
228
  }
229
+ #elif defined(HAVE_SIMD_SSE2)
230
+ if (simd_impl == SIMD_SSE2) {
231
+ while (search_escape_basic_sse2(search)) {
232
+ escape_UTF8_char_basic(search);
233
+ }
234
+ return;
235
+ }
236
+ while (search_escape_basic(search)) {
237
+ escape_UTF8_char_basic(search);
238
+ }
239
+ #endif
240
+ #else
241
+ while (search_escape_basic(search)) {
242
+ escape_UTF8_char_basic(search);
243
+ }
244
+ #endif /* HAVE_SIMD */
220
245
  }
221
246
 
222
247
  static inline void escape_UTF8_char(search_state *search, unsigned char ch_len)
@@ -260,6 +285,8 @@ static inline void escape_UTF8_char(search_state *search, unsigned char ch_len)
260
285
 
261
286
  ALWAYS_INLINE(static) char *copy_remaining_bytes(search_state *search, unsigned long vec_len, unsigned long len)
262
287
  {
288
+ RBIMPL_ASSERT_OR_ASSUME(len < vec_len);
289
+
263
290
  // Flush the buffer so everything up until the last 'len' characters are unflushed.
264
291
  search_flush(search);
265
292
 
@@ -269,12 +296,18 @@ ALWAYS_INLINE(static) char *copy_remaining_bytes(search_state *search, unsigned
269
296
  char *s = (buf->ptr + buf->len);
270
297
 
271
298
  // Pad the buffer with dummy characters that won't need escaping.
272
- // This seem wateful at first sight, but memset of vector length is very fast.
273
- memset(s, 'X', vec_len);
299
+ // This seem wasteful at first sight, but memset of vector length is very fast.
300
+ // This is a space as it can be directly represented as an immediate on AArch64.
301
+ memset(s, ' ', vec_len);
274
302
 
275
303
  // Optimistically copy the remaining 'len' characters to the output FBuffer. If there are no characters
276
304
  // to escape, then everything ends up in the correct spot. Otherwise it was convenient temporary storage.
277
- MEMCPY(s, search->ptr, char, len);
305
+ if (vec_len == 16) {
306
+ RBIMPL_ASSERT_OR_ASSUME(len >= SIMD_MINIMUM_THRESHOLD);
307
+ json_fast_memcpy16(s, search->ptr, len);
308
+ } else {
309
+ MEMCPY(s, search->ptr, char, len);
310
+ }
278
311
 
279
312
  return s;
280
313
  }
@@ -667,233 +700,6 @@ static void convert_UTF8_to_ASCII_only_JSON(search_state *search, const unsigned
667
700
  }
668
701
  }
669
702
 
670
- /*
671
- * Document-module: JSON::Ext::Generator
672
- *
673
- * This is the JSON generator implemented as a C extension. It can be
674
- * configured to be used by setting
675
- *
676
- * JSON.generator = JSON::Ext::Generator
677
- *
678
- * with the method generator= in JSON.
679
- *
680
- */
681
-
682
- /* Explanation of the following: that's the only way to not pollute
683
- * standard library's docs with GeneratorMethods::<ClassName> which
684
- * are uninformative and take a large place in a list of classes
685
- */
686
-
687
- /*
688
- * Document-module: JSON::Ext::Generator::GeneratorMethods
689
- * :nodoc:
690
- */
691
-
692
- /*
693
- * Document-module: JSON::Ext::Generator::GeneratorMethods::Array
694
- * :nodoc:
695
- */
696
-
697
- /*
698
- * Document-module: JSON::Ext::Generator::GeneratorMethods::Bignum
699
- * :nodoc:
700
- */
701
-
702
- /*
703
- * Document-module: JSON::Ext::Generator::GeneratorMethods::FalseClass
704
- * :nodoc:
705
- */
706
-
707
- /*
708
- * Document-module: JSON::Ext::Generator::GeneratorMethods::Fixnum
709
- * :nodoc:
710
- */
711
-
712
- /*
713
- * Document-module: JSON::Ext::Generator::GeneratorMethods::Float
714
- * :nodoc:
715
- */
716
-
717
- /*
718
- * Document-module: JSON::Ext::Generator::GeneratorMethods::Hash
719
- * :nodoc:
720
- */
721
-
722
- /*
723
- * Document-module: JSON::Ext::Generator::GeneratorMethods::Integer
724
- * :nodoc:
725
- */
726
-
727
- /*
728
- * Document-module: JSON::Ext::Generator::GeneratorMethods::NilClass
729
- * :nodoc:
730
- */
731
-
732
- /*
733
- * Document-module: JSON::Ext::Generator::GeneratorMethods::Object
734
- * :nodoc:
735
- */
736
-
737
- /*
738
- * Document-module: JSON::Ext::Generator::GeneratorMethods::String
739
- * :nodoc:
740
- */
741
-
742
- /*
743
- * Document-module: JSON::Ext::Generator::GeneratorMethods::String::Extend
744
- * :nodoc:
745
- */
746
-
747
- /*
748
- * Document-module: JSON::Ext::Generator::GeneratorMethods::TrueClass
749
- * :nodoc:
750
- */
751
-
752
- /*
753
- * call-seq: to_json(state = nil)
754
- *
755
- * Returns a JSON string containing a JSON object, that is generated from
756
- * this Hash instance.
757
- * _state_ is a JSON::State object, that can also be used to configure the
758
- * produced JSON string output further.
759
- */
760
- static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self)
761
- {
762
- rb_check_arity(argc, 0, 1);
763
- VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil);
764
- return cState_partial_generate(Vstate, self, generate_json_object, Qfalse);
765
- }
766
-
767
- /*
768
- * call-seq: to_json(state = nil)
769
- *
770
- * Returns a JSON string containing a JSON array, that is generated from
771
- * this Array instance.
772
- * _state_ is a JSON::State object, that can also be used to configure the
773
- * produced JSON string output further.
774
- */
775
- static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self)
776
- {
777
- rb_check_arity(argc, 0, 1);
778
- VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil);
779
- return cState_partial_generate(Vstate, self, generate_json_array, Qfalse);
780
- }
781
-
782
- #ifdef RUBY_INTEGER_UNIFICATION
783
- /*
784
- * call-seq: to_json(*)
785
- *
786
- * Returns a JSON string representation for this Integer number.
787
- */
788
- static VALUE mInteger_to_json(int argc, VALUE *argv, VALUE self)
789
- {
790
- rb_check_arity(argc, 0, 1);
791
- VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil);
792
- return cState_partial_generate(Vstate, self, generate_json_integer, Qfalse);
793
- }
794
-
795
- #else
796
- /*
797
- * call-seq: to_json(*)
798
- *
799
- * Returns a JSON string representation for this Integer number.
800
- */
801
- static VALUE mFixnum_to_json(int argc, VALUE *argv, VALUE self)
802
- {
803
- rb_check_arity(argc, 0, 1);
804
- VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil);
805
- return cState_partial_generate(Vstate, self, generate_json_fixnum, Qfalse);
806
- }
807
-
808
- /*
809
- * call-seq: to_json(*)
810
- *
811
- * Returns a JSON string representation for this Integer number.
812
- */
813
- static VALUE mBignum_to_json(int argc, VALUE *argv, VALUE self)
814
- {
815
- rb_check_arity(argc, 0, 1);
816
- VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil);
817
- return cState_partial_generate(Vstate, self, generate_json_bignum, Qfalse);
818
- }
819
- #endif
820
-
821
- /*
822
- * call-seq: to_json(*)
823
- *
824
- * Returns a JSON string representation for this Float number.
825
- */
826
- static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self)
827
- {
828
- rb_check_arity(argc, 0, 1);
829
- VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil);
830
- return cState_partial_generate(Vstate, self, generate_json_float, Qfalse);
831
- }
832
-
833
- /*
834
- * call-seq: to_json(*)
835
- *
836
- * This string should be encoded with UTF-8 A call to this method
837
- * returns a JSON string encoded with UTF16 big endian characters as
838
- * \u????.
839
- */
840
- static VALUE mString_to_json(int argc, VALUE *argv, VALUE self)
841
- {
842
- rb_check_arity(argc, 0, 1);
843
- VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil);
844
- return cState_partial_generate(Vstate, self, generate_json_string, Qfalse);
845
- }
846
-
847
- /*
848
- * call-seq: to_json(*)
849
- *
850
- * Returns a JSON string for true: 'true'.
851
- */
852
- static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self)
853
- {
854
- rb_check_arity(argc, 0, 1);
855
- return rb_utf8_str_new("true", 4);
856
- }
857
-
858
- /*
859
- * call-seq: to_json(*)
860
- *
861
- * Returns a JSON string for false: 'false'.
862
- */
863
- static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self)
864
- {
865
- rb_check_arity(argc, 0, 1);
866
- return rb_utf8_str_new("false", 5);
867
- }
868
-
869
- /*
870
- * call-seq: to_json(*)
871
- *
872
- * Returns a JSON string for nil: 'null'.
873
- */
874
- static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self)
875
- {
876
- rb_check_arity(argc, 0, 1);
877
- return rb_utf8_str_new("null", 4);
878
- }
879
-
880
- /*
881
- * call-seq: to_json(*)
882
- *
883
- * Converts this object to a string (calling #to_s), converts
884
- * it to a JSON string, and returns the result. This is a fallback, if no
885
- * special method #to_json was defined for some object.
886
- */
887
- static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self)
888
- {
889
- VALUE state;
890
- VALUE string = rb_funcall(self, i_to_s, 0);
891
- rb_scan_args(argc, argv, "01", &state);
892
- Check_Type(string, T_STRING);
893
- state = cState_from_state_s(cState, state);
894
- return cState_partial_generate(state, string, generate_json_string, Qfalse);
895
- }
896
-
897
703
  static void State_mark(void *ptr)
898
704
  {
899
705
  JSON_Generator_State *state = ptr;
@@ -1091,6 +897,7 @@ static void raw_generate_json_string(FBuffer *buffer, struct generate_json_data
1091
897
  search.matches_mask = 0;
1092
898
  search.has_matches = false;
1093
899
  search.chunk_base = NULL;
900
+ search.chunk_end = NULL;
1094
901
  #endif /* HAVE_SIMD */
1095
902
 
1096
903
  switch (rb_enc_str_coderange(obj)) {
@@ -1337,18 +1144,8 @@ static void generate_json_fixnum(FBuffer *buffer, struct generate_json_data *dat
1337
1144
  static void generate_json_bignum(FBuffer *buffer, struct generate_json_data *data, VALUE obj)
1338
1145
  {
1339
1146
  VALUE tmp = rb_funcall(obj, i_to_s, 0);
1340
- fbuffer_append_str(buffer, tmp);
1341
- }
1342
-
1343
- #ifdef RUBY_INTEGER_UNIFICATION
1344
- static void generate_json_integer(FBuffer *buffer, struct generate_json_data *data, VALUE obj)
1345
- {
1346
- if (FIXNUM_P(obj))
1347
- generate_json_fixnum(buffer, data, obj);
1348
- else
1349
- generate_json_bignum(buffer, data, obj);
1147
+ fbuffer_append_str(buffer, StringValue(tmp));
1350
1148
  }
1351
- #endif
1352
1149
 
1353
1150
  static void generate_json_float(FBuffer *buffer, struct generate_json_data *data, VALUE obj)
1354
1151
  {
@@ -1393,7 +1190,7 @@ static void generate_json_fragment(FBuffer *buffer, struct generate_json_data *d
1393
1190
  fbuffer_append_str(buffer, fragment);
1394
1191
  }
1395
1192
 
1396
- static void generate_json(FBuffer *buffer, struct generate_json_data *data, VALUE obj)
1193
+ static inline void generate_json_general(FBuffer *buffer, struct generate_json_data *data, VALUE obj, bool fallback)
1397
1194
  {
1398
1195
  bool as_json_called = false;
1399
1196
  start:
@@ -1420,15 +1217,15 @@ start:
1420
1217
  generate_json_bignum(buffer, data, obj);
1421
1218
  break;
1422
1219
  case T_HASH:
1423
- if (klass != rb_cHash) goto general;
1220
+ if (fallback && klass != rb_cHash) goto general;
1424
1221
  generate_json_object(buffer, data, obj);
1425
1222
  break;
1426
1223
  case T_ARRAY:
1427
- if (klass != rb_cArray) goto general;
1224
+ if (fallback && klass != rb_cArray) goto general;
1428
1225
  generate_json_array(buffer, data, obj);
1429
1226
  break;
1430
1227
  case T_STRING:
1431
- if (klass != rb_cString) goto general;
1228
+ if (fallback && klass != rb_cString) goto general;
1432
1229
 
1433
1230
  if (RB_LIKELY(valid_json_string_p(obj))) {
1434
1231
  raw_generate_json_string(buffer, data, obj);
@@ -1444,7 +1241,7 @@ start:
1444
1241
  generate_json_symbol(buffer, data, obj);
1445
1242
  break;
1446
1243
  case T_FLOAT:
1447
- if (klass != rb_cFloat) goto general;
1244
+ if (fallback && klass != rb_cFloat) goto general;
1448
1245
  generate_json_float(buffer, data, obj);
1449
1246
  break;
1450
1247
  case T_STRUCT:
@@ -1468,6 +1265,16 @@ start:
1468
1265
  }
1469
1266
  }
1470
1267
 
1268
+ static void generate_json(FBuffer *buffer, struct generate_json_data *data, VALUE obj)
1269
+ {
1270
+ generate_json_general(buffer, data, obj, true);
1271
+ }
1272
+
1273
+ static void generate_json_no_fallback(FBuffer *buffer, struct generate_json_data *data, VALUE obj)
1274
+ {
1275
+ generate_json_general(buffer, data, obj, false);
1276
+ }
1277
+
1471
1278
  static VALUE generate_json_try(VALUE d)
1472
1279
  {
1473
1280
  struct generate_json_data *data = (struct generate_json_data *)d;
@@ -1485,7 +1292,7 @@ static VALUE generate_json_ensure(VALUE d)
1485
1292
  return Qundef;
1486
1293
  }
1487
1294
 
1488
- static VALUE cState_partial_generate(VALUE self, VALUE obj, generator_func func, VALUE io)
1295
+ static inline VALUE cState_partial_generate(VALUE self, VALUE obj, generator_func func, VALUE io)
1489
1296
  {
1490
1297
  GET_STATE(self);
1491
1298
 
@@ -1522,6 +1329,15 @@ static VALUE cState_generate(int argc, VALUE *argv, VALUE self)
1522
1329
  return cState_partial_generate(self, obj, generate_json, io);
1523
1330
  }
1524
1331
 
1332
+ /* :nodoc: */
1333
+ static VALUE cState_generate_no_fallback(int argc, VALUE *argv, VALUE self)
1334
+ {
1335
+ rb_check_arity(argc, 1, 2);
1336
+ VALUE obj = argv[0];
1337
+ VALUE io = argc > 1 ? argv[1] : Qnil;
1338
+ return cState_partial_generate(self, obj, generate_json_no_fallback, io);
1339
+ }
1340
+
1525
1341
  static VALUE cState_initialize(int argc, VALUE *argv, VALUE self)
1526
1342
  {
1527
1343
  rb_warn("The json gem extension was loaded with the stdlib ruby code. You should upgrade rubygems with `gem update --system`");
@@ -1759,6 +1575,17 @@ static long long_config(VALUE num)
1759
1575
  return RTEST(num) ? FIX2LONG(num) : 0;
1760
1576
  }
1761
1577
 
1578
+ // depth must never be negative; reject early with a clear error.
1579
+ static long depth_config(VALUE num)
1580
+ {
1581
+ if (!RTEST(num)) return 0;
1582
+ long d = NUM2LONG(num);
1583
+ if (RB_UNLIKELY(d < 0)) {
1584
+ rb_raise(rb_eArgError, "depth must be >= 0 (got %ld)", d);
1585
+ }
1586
+ return d;
1587
+ }
1588
+
1762
1589
  /*
1763
1590
  * call-seq: max_nesting=(depth)
1764
1591
  *
@@ -1915,7 +1742,7 @@ static VALUE cState_depth_set(VALUE self, VALUE depth)
1915
1742
  {
1916
1743
  rb_check_frozen(self);
1917
1744
  GET_STATE(self);
1918
- state->depth = long_config(depth);
1745
+ state->depth = depth_config(depth);
1919
1746
  return Qnil;
1920
1747
  }
1921
1748
 
@@ -1980,7 +1807,7 @@ static int configure_state_i(VALUE key, VALUE val, VALUE _arg)
1980
1807
  else if (key == sym_max_nesting) { state->max_nesting = long_config(val); }
1981
1808
  else if (key == sym_allow_nan) { state->allow_nan = RTEST(val); }
1982
1809
  else if (key == sym_ascii_only) { state->ascii_only = RTEST(val); }
1983
- else if (key == sym_depth) { state->depth = long_config(val); }
1810
+ else if (key == sym_depth) { state->depth = depth_config(val); }
1984
1811
  else if (key == sym_buffer_initial_length) { buffer_initial_length_set(state, val); }
1985
1812
  else if (key == sym_script_safe) { state->script_safe = RTEST(val); }
1986
1813
  else if (key == sym_escape_slash) { state->script_safe = RTEST(val); }
@@ -2020,7 +1847,7 @@ static VALUE cState_configure(VALUE self, VALUE opts)
2020
1847
  return self;
2021
1848
  }
2022
1849
 
2023
- static VALUE cState_m_generate(VALUE klass, VALUE obj, VALUE opts, VALUE io)
1850
+ static VALUE cState_m_do_generate(VALUE klass, VALUE obj, VALUE opts, VALUE io, generator_func func)
2024
1851
  {
2025
1852
  JSON_Generator_State state = {0};
2026
1853
  state_init(&state);
@@ -2038,14 +1865,21 @@ static VALUE cState_m_generate(VALUE klass, VALUE obj, VALUE opts, VALUE io)
2038
1865
  .state = &state,
2039
1866
  .depth = state.depth,
2040
1867
  .obj = obj,
2041
- .func = generate_json,
1868
+ .func = func,
2042
1869
  };
2043
1870
  return rb_ensure(generate_json_try, (VALUE)&data, generate_json_ensure, (VALUE)&data);
2044
1871
  }
2045
1872
 
2046
- /*
2047
- *
2048
- */
1873
+ static VALUE cState_m_generate(VALUE klass, VALUE obj, VALUE opts, VALUE io)
1874
+ {
1875
+ return cState_m_do_generate(klass, obj, opts, io, generate_json);
1876
+ }
1877
+
1878
+ static VALUE cState_m_generate_no_fallback(VALUE klass, VALUE obj, VALUE opts, VALUE io)
1879
+ {
1880
+ return cState_m_do_generate(klass, obj, opts, io, generate_json_no_fallback);
1881
+ }
1882
+
2049
1883
  void Init_generator(void)
2050
1884
  {
2051
1885
  #ifdef HAVE_RB_EXT_RACTOR_SAFE
@@ -2110,46 +1944,12 @@ void Init_generator(void)
2110
1944
  rb_define_method(cState, "buffer_initial_length", cState_buffer_initial_length, 0);
2111
1945
  rb_define_method(cState, "buffer_initial_length=", cState_buffer_initial_length_set, 1);
2112
1946
  rb_define_method(cState, "generate", cState_generate, -1);
1947
+ rb_define_method(cState, "_generate_no_fallback", cState_generate_no_fallback, -1);
2113
1948
 
2114
1949
  rb_define_private_method(cState, "allow_duplicate_key?", cState_allow_duplicate_key_p, 0);
2115
1950
 
2116
1951
  rb_define_singleton_method(cState, "generate", cState_m_generate, 3);
2117
-
2118
- VALUE mGeneratorMethods = rb_define_module_under(mGenerator, "GeneratorMethods");
2119
-
2120
- VALUE mObject = rb_define_module_under(mGeneratorMethods, "Object");
2121
- rb_define_method(mObject, "to_json", mObject_to_json, -1);
2122
-
2123
- VALUE mHash = rb_define_module_under(mGeneratorMethods, "Hash");
2124
- rb_define_method(mHash, "to_json", mHash_to_json, -1);
2125
-
2126
- VALUE mArray = rb_define_module_under(mGeneratorMethods, "Array");
2127
- rb_define_method(mArray, "to_json", mArray_to_json, -1);
2128
-
2129
- #ifdef RUBY_INTEGER_UNIFICATION
2130
- VALUE mInteger = rb_define_module_under(mGeneratorMethods, "Integer");
2131
- rb_define_method(mInteger, "to_json", mInteger_to_json, -1);
2132
- #else
2133
- VALUE mFixnum = rb_define_module_under(mGeneratorMethods, "Fixnum");
2134
- rb_define_method(mFixnum, "to_json", mFixnum_to_json, -1);
2135
-
2136
- VALUE mBignum = rb_define_module_under(mGeneratorMethods, "Bignum");
2137
- rb_define_method(mBignum, "to_json", mBignum_to_json, -1);
2138
- #endif
2139
- VALUE mFloat = rb_define_module_under(mGeneratorMethods, "Float");
2140
- rb_define_method(mFloat, "to_json", mFloat_to_json, -1);
2141
-
2142
- VALUE mString = rb_define_module_under(mGeneratorMethods, "String");
2143
- rb_define_method(mString, "to_json", mString_to_json, -1);
2144
-
2145
- VALUE mTrueClass = rb_define_module_under(mGeneratorMethods, "TrueClass");
2146
- rb_define_method(mTrueClass, "to_json", mTrueClass_to_json, -1);
2147
-
2148
- VALUE mFalseClass = rb_define_module_under(mGeneratorMethods, "FalseClass");
2149
- rb_define_method(mFalseClass, "to_json", mFalseClass_to_json, -1);
2150
-
2151
- VALUE mNilClass = rb_define_module_under(mGeneratorMethods, "NilClass");
2152
- rb_define_method(mNilClass, "to_json", mNilClass_to_json, -1);
1952
+ rb_define_singleton_method(cState, "_generate_no_fallback", cState_m_generate_no_fallback, 3);
2153
1953
 
2154
1954
  rb_global_variable(&Encoding_UTF_8);
2155
1955
  Encoding_UTF_8 = rb_const_get(rb_path2class("Encoding"), rb_intern("UTF_8"));
@@ -2181,22 +1981,5 @@ void Init_generator(void)
2181
1981
 
2182
1982
  rb_require("json/ext/generator/state");
2183
1983
 
2184
-
2185
- switch (find_simd_implementation()) {
2186
- #ifdef HAVE_SIMD
2187
- #ifdef HAVE_SIMD_NEON
2188
- case SIMD_NEON:
2189
- search_escape_basic_impl = search_escape_basic_neon;
2190
- break;
2191
- #endif /* HAVE_SIMD_NEON */
2192
- #ifdef HAVE_SIMD_SSE2
2193
- case SIMD_SSE2:
2194
- search_escape_basic_impl = search_escape_basic_sse2;
2195
- break;
2196
- #endif /* HAVE_SIMD_SSE2 */
2197
- #endif /* HAVE_SIMD */
2198
- default:
2199
- search_escape_basic_impl = search_escape_basic;
2200
- break;
2201
- }
1984
+ simd_impl = find_simd_implementation();
2202
1985
  }
data/ext/json/ext/json.h CHANGED
@@ -5,6 +5,10 @@
5
5
  #include "ruby/encoding.h"
6
6
  #include <stdint.h>
7
7
 
8
+ #ifndef RBIMPL_ASSERT_OR_ASSUME
9
+ # define RBIMPL_ASSERT_OR_ASSUME(x)
10
+ #endif
11
+
8
12
  #if defined(RUBY_DEBUG) && RUBY_DEBUG
9
13
  # define JSON_ASSERT RUBY_ASSERT
10
14
  #else
@@ -51,8 +55,12 @@ typedef unsigned char _Bool;
51
55
  #endif
52
56
 
53
57
  #ifndef NORETURN
58
+ #if defined(__has_attribute) && __has_attribute(noreturn)
59
+ #define NORETURN(x) __attribute__((noreturn)) x
60
+ #else
54
61
  #define NORETURN(x) x
55
62
  #endif
63
+ #endif
56
64
 
57
65
  #ifndef NOINLINE
58
66
  #if defined(__has_attribute) && __has_attribute(noinline)