oj 3.13.23 → 3.14.2

Sign up to get free protection for your applications and to get access to all the features.
data/ext/oj/dump_object.c CHANGED
@@ -1,6 +1,7 @@
1
1
  // Copyright (c) 2012, 2017 Peter Ohler. All rights reserved.
2
2
  // Licensed under the MIT License. See LICENSE file in the project root for license details.
3
3
 
4
+ #include "mem.h"
4
5
  #include "dump.h"
5
6
  #include "odd.h"
6
7
  #include "trace.h"
@@ -30,7 +31,7 @@ static void dump_data(VALUE obj, int depth, Out out, bool as_ok) {
30
31
  *out->cur = '\0';
31
32
  } else {
32
33
  if (oj_bigdecimal_class == clas) {
33
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
34
+ volatile VALUE rstr = oj_safe_string_convert(obj);
34
35
  const char * str = RSTRING_PTR(rstr);
35
36
  int len = (int)RSTRING_LEN(rstr);
36
37
 
@@ -59,7 +60,7 @@ static void dump_obj(VALUE obj, int depth, Out out, bool as_ok) {
59
60
  VALUE clas = rb_obj_class(obj);
60
61
 
61
62
  if (oj_bigdecimal_class == clas) {
62
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
63
+ volatile VALUE rstr = oj_safe_string_convert(obj);
63
64
  const char * str = RSTRING_PTR(rstr);
64
65
  int len = (int)RSTRING_LEN(rstr);
65
66
 
@@ -422,7 +423,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
422
423
  ID i;
423
424
 
424
425
  if (sizeof(nbuf) <= nlen) {
425
- if (NULL == (n2 = strdup(name))) {
426
+ if (NULL == (n2 = OJ_STRDUP(name))) {
426
427
  rb_raise(rb_eNoMemError, "for attribute name.");
427
428
  }
428
429
  } else {
@@ -439,7 +440,7 @@ static void dump_odd(VALUE obj, Odd odd, VALUE clas, int depth, Out out) {
439
440
  i = rb_intern(n);
440
441
  v = rb_funcall(v, i, 0);
441
442
  if (nbuf != n2) {
442
- free(n2);
443
+ OJ_FREE(n2);
443
444
  }
444
445
  }
445
446
  fill_indent(out, d2);
@@ -682,9 +683,7 @@ static DumpFunc obj_funcs[] = {
682
683
  void oj_dump_obj_val(VALUE obj, int depth, Out out) {
683
684
  int type = rb_type(obj);
684
685
 
685
- if (RB_UNLIKELY(Yes == out->opts->trace)) {
686
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
687
- }
686
+ TRACE(out->opts->trace, "dump", obj, depth, TraceIn);
688
687
  if (MAX_DEPTH < depth) {
689
688
  rb_raise(rb_eNoMemError, "Too deeply nested.\n");
690
689
  }
@@ -693,14 +692,10 @@ void oj_dump_obj_val(VALUE obj, int depth, Out out) {
693
692
 
694
693
  if (NULL != f) {
695
694
  f(obj, depth, out, false);
696
- if (RB_UNLIKELY(Yes == out->opts->trace)) {
697
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
698
- }
695
+ TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
699
696
  return;
700
697
  }
701
698
  }
702
699
  oj_dump_nil(Qnil, depth, out, false);
703
- if (RB_UNLIKELY(Yes == out->opts->trace)) {
704
- oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
705
- }
700
+ TRACE(out->opts->trace, "dump", Qnil, depth, TraceOut);
706
701
  }
data/ext/oj/dump_strict.c CHANGED
@@ -92,7 +92,7 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
92
92
  } else if (d == (double)(long long int)d) {
93
93
  cnt = snprintf(buf, sizeof(buf), "%.1f", d);
94
94
  } else if (0 == out->opts->float_prec) {
95
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
95
+ volatile VALUE rstr = oj_safe_string_convert(obj);
96
96
 
97
97
  cnt = (int)RSTRING_LEN(rstr);
98
98
  if ((int)sizeof(buf) <= cnt) {
@@ -290,7 +290,7 @@ static void dump_data_strict(VALUE obj, int depth, Out out, bool as_ok) {
290
290
  VALUE clas = rb_obj_class(obj);
291
291
 
292
292
  if (oj_bigdecimal_class == clas) {
293
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
293
+ volatile VALUE rstr = oj_safe_string_convert(obj);
294
294
 
295
295
  oj_dump_raw(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), out);
296
296
  } else {
@@ -302,7 +302,7 @@ static void dump_data_null(VALUE obj, int depth, Out out, bool as_ok) {
302
302
  VALUE clas = rb_obj_class(obj);
303
303
 
304
304
  if (oj_bigdecimal_class == clas) {
305
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
305
+ volatile VALUE rstr = oj_safe_string_convert(obj);
306
306
 
307
307
  oj_dump_raw(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), out);
308
308
  } else {
@@ -338,9 +338,7 @@ static DumpFunc strict_funcs[] = {
338
338
  void oj_dump_strict_val(VALUE obj, int depth, Out out) {
339
339
  int type = rb_type(obj);
340
340
 
341
- if (RB_UNLIKELY(Yes == out->opts->trace)) {
342
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
343
- }
341
+ TRACE(out->opts->trace, "dump", obj, depth, TraceIn);
344
342
  if (MAX_DEPTH < depth) {
345
343
  rb_raise(rb_eNoMemError, "Too deeply nested.\n");
346
344
  }
@@ -349,9 +347,7 @@ void oj_dump_strict_val(VALUE obj, int depth, Out out) {
349
347
 
350
348
  if (NULL != f) {
351
349
  f(obj, depth, out, false);
352
- if (RB_UNLIKELY(Yes == out->opts->trace)) {
353
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
354
- }
350
+ TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
355
351
  return;
356
352
  }
357
353
  }
@@ -386,9 +382,7 @@ static DumpFunc null_funcs[] = {
386
382
  void oj_dump_null_val(VALUE obj, int depth, Out out) {
387
383
  int type = rb_type(obj);
388
384
 
389
- if (RB_UNLIKELY(Yes == out->opts->trace)) {
390
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
391
- }
385
+ TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
392
386
  if (MAX_DEPTH < depth) {
393
387
  rb_raise(rb_eNoMemError, "Too deeply nested.\n");
394
388
  }
@@ -397,14 +391,10 @@ void oj_dump_null_val(VALUE obj, int depth, Out out) {
397
391
 
398
392
  if (NULL != f) {
399
393
  f(obj, depth, out, false);
400
- if (RB_UNLIKELY(Yes == out->opts->trace)) {
401
- oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
402
- }
394
+ TRACE(out->opts->trace, "dump", obj, depth, TraceOut);
403
395
  return;
404
396
  }
405
397
  }
406
398
  oj_dump_nil(Qnil, depth, out, false);
407
- if (RB_UNLIKELY(Yes == out->opts->trace)) {
408
- oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
409
- }
399
+ TRACE(out->opts->trace, "dump", Qnil, depth, TraceOut);
410
400
  }
data/ext/oj/extconf.rb CHANGED
@@ -35,8 +35,16 @@ have_func('rb_hash_bulk_insert', 'ruby.h') unless '2' == version[0] && '6' == ve
35
35
  dflags['OJ_DEBUG'] = true unless ENV['OJ_DEBUG'].nil?
36
36
 
37
37
  if with_config('--with-sse42')
38
- $CPPFLAGS += ' -msse4.2'
39
- dflags['OJ_USE_SSE4_2'] = 1
38
+ if try_cflags('-msse4.2')
39
+ $CPPFLAGS += ' -msse4.2'
40
+ dflags['OJ_USE_SSE4_2'] = 1
41
+ else
42
+ warn 'SSE 4.2 is not supported on this platform.'
43
+ end
44
+ end
45
+
46
+ if enable_config('trace-log', false)
47
+ dflags['OJ_ENABLE_TRACE_LOG'] = 1
40
48
  end
41
49
 
42
50
  dflags.each do |k,v|
data/ext/oj/fast.c CHANGED
@@ -11,6 +11,7 @@
11
11
  #include <stdlib.h>
12
12
  #include <string.h>
13
13
 
14
+ #include "mem.h"
14
15
  #include "encode.h"
15
16
  #include "oj.h"
16
17
  #include "dump.h"
@@ -74,7 +75,7 @@ static char *read_quoted_value(ParseInfo pi);
74
75
  static void skip_comment(ParseInfo pi);
75
76
 
76
77
  static VALUE protect_open_proc(VALUE x);
77
- static VALUE parse_json(VALUE clas, char *json, bool given, bool allocated);
78
+ static VALUE parse_json(VALUE clas, char *json, bool given);
78
79
  static void each_leaf(Doc doc, VALUE self);
79
80
  static int move_step(Doc doc, const char *path, int loc);
80
81
  static Leaf get_doc_leaf(Doc doc, const char *path);
@@ -160,7 +161,7 @@ inline static Leaf leaf_new(Doc doc, int type) {
160
161
  Leaf leaf;
161
162
 
162
163
  if (0 == doc->batches || BATCH_SIZE == doc->batches->next_avail) {
163
- Batch b = ALLOC(struct _batch);
164
+ Batch b = OJ_R_ALLOC(struct _batch);
164
165
 
165
166
  // Initializes all leaves with a NO_VAL value_type
166
167
  memset(b, 0, sizeof(struct _batch));
@@ -648,10 +649,11 @@ static void doc_free(Doc doc) {
648
649
  while (0 != (b = doc->batches)) {
649
650
  doc->batches = doc->batches->next;
650
651
  if (&doc->batch0 != b) {
651
- xfree(b);
652
+ OJ_R_FREE(b);
652
653
  }
653
654
  }
654
- // xfree(f);
655
+ OJ_R_FREE(doc->json);
656
+ OJ_R_FREE(doc);
655
657
  }
656
658
  }
657
659
 
@@ -671,7 +673,6 @@ static void free_doc_cb(void *x) {
671
673
  Doc doc = (Doc)x;
672
674
 
673
675
  if (0 != doc) {
674
- xfree(doc->json);
675
676
  doc_free(doc);
676
677
  }
677
678
  }
@@ -749,20 +750,15 @@ static const rb_data_type_t oj_doc_type = {
749
750
  0,
750
751
  };
751
752
 
752
- static VALUE parse_json(VALUE clas, char *json, bool given, bool allocated) {
753
+ static VALUE parse_json(VALUE clas, char *json, bool given) {
753
754
  struct _parseInfo pi;
754
755
  volatile VALUE result = Qnil;
755
756
  Doc doc;
756
757
  int ex = 0;
757
758
  volatile VALUE self;
758
759
 
759
- // TBD are both needed? is stack allocation ever needed?
760
+ doc = OJ_R_ALLOC_N(struct _doc, 1);
760
761
 
761
- if (given) {
762
- doc = ALLOCA_N(struct _doc, 1);
763
- } else {
764
- doc = ALLOC(struct _doc);
765
- }
766
762
  // skip UTF-8 BOM if present
767
763
  if (0xEF == (uint8_t)*json && 0xBB == (uint8_t)json[1] && 0xBF == (uint8_t)json[2]) {
768
764
  pi.str = json + 3;
@@ -787,18 +783,20 @@ static VALUE parse_json(VALUE clas, char *json, bool given, bool allocated) {
787
783
  }
788
784
  }
789
785
  #endif
786
+ doc->json = json;
790
787
  self = TypedData_Wrap_Struct(clas, &oj_doc_type, doc);
791
788
  doc->self = self;
792
- doc->json = json;
793
789
  DATA_PTR(doc->self) = doc;
794
790
  result = rb_protect(protect_open_proc, (VALUE)&pi, &ex);
795
791
  if (given || 0 != ex) {
796
792
  DATA_PTR(doc->self) = NULL;
793
+ // TBD is this needed?
794
+ /*
797
795
  doc_free(pi.doc);
798
- if (allocated && 0 != ex) { // will jump so caller will not free
799
- xfree(json);
796
+ if (0 != ex) { // will jump so caller will not free
797
+ OJ_R_FREE(json);
800
798
  }
801
- rb_gc_enable();
799
+ */
802
800
  } else {
803
801
  result = doc->self;
804
802
  }
@@ -1092,27 +1090,19 @@ static VALUE doc_open(VALUE clas, VALUE str) {
1092
1090
  size_t len;
1093
1091
  volatile VALUE obj;
1094
1092
  int given = rb_block_given_p();
1095
- int allocate;
1096
1093
 
1097
1094
  Check_Type(str, T_STRING);
1098
1095
  len = (int)RSTRING_LEN(str) + 1;
1099
- allocate = (SMALL_JSON < len || !given);
1100
- if (allocate) {
1101
- json = ALLOC_N(char, len);
1102
- } else {
1103
- json = ALLOCA_N(char, len);
1104
- }
1105
- // It should not be necessaary to stop GC but if it is not stopped and a
1106
- // large string is parsed that string is corrupted or freed during
1107
- // parsing. I'm not sure what is going on exactly but disabling GC avoids
1108
- // the issue.
1109
- rb_gc_disable();
1096
+ json = OJ_R_ALLOC_N(char, len);
1097
+
1110
1098
  memcpy(json, StringValuePtr(str), len);
1111
- obj = parse_json(clas, json, given, allocate);
1112
- rb_gc_enable();
1113
- if (given && allocate) {
1114
- xfree(json);
1099
+ obj = parse_json(clas, json, given);
1100
+ // TBD is this needed
1101
+ /*
1102
+ if (given) {
1103
+ OJ_R_FREE(json);
1115
1104
  }
1105
+ */
1116
1106
  return obj;
1117
1107
  }
1118
1108
 
@@ -1142,7 +1132,6 @@ static VALUE doc_open_file(VALUE clas, VALUE filename) {
1142
1132
  size_t len;
1143
1133
  volatile VALUE obj;
1144
1134
  int given = rb_block_given_p();
1145
- int allocate;
1146
1135
 
1147
1136
  Check_Type(filename, T_STRING);
1148
1137
  path = StringValuePtr(filename);
@@ -1151,12 +1140,8 @@ static VALUE doc_open_file(VALUE clas, VALUE filename) {
1151
1140
  }
1152
1141
  fseek(f, 0, SEEK_END);
1153
1142
  len = ftell(f);
1154
- allocate = (SMALL_JSON < len || !given);
1155
- if (allocate) {
1156
- json = ALLOC_N(char, len + 1);
1157
- } else {
1158
- json = ALLOCA_N(char, len + 1);
1159
- }
1143
+ json = OJ_R_ALLOC_N(char, len + 1);
1144
+
1160
1145
  fseek(f, 0, SEEK_SET);
1161
1146
  if (len != fread(json, 1, len, f)) {
1162
1147
  fclose(f);
@@ -1167,12 +1152,13 @@ static VALUE doc_open_file(VALUE clas, VALUE filename) {
1167
1152
  }
1168
1153
  fclose(f);
1169
1154
  json[len] = '\0';
1170
- rb_gc_disable();
1171
- obj = parse_json(clas, json, given, allocate);
1172
- rb_gc_enable();
1173
- if (given && allocate) {
1174
- xfree(json);
1155
+ obj = parse_json(clas, json, given);
1156
+ // TBD is this needed
1157
+ /*
1158
+ if (given) {
1159
+ OJ_R_FREE(json);
1175
1160
  }
1161
+ */
1176
1162
  return obj;
1177
1163
  }
1178
1164
 
@@ -1656,11 +1642,9 @@ static VALUE doc_close(VALUE self) {
1656
1642
  Doc doc = self_doc(self);
1657
1643
 
1658
1644
  rb_gc_unregister_address(&doc->self);
1659
- DATA_PTR(doc->self) = 0;
1645
+ DATA_PTR(doc->self) = NULL;
1660
1646
  if (0 != doc) {
1661
- xfree(doc->json);
1662
1647
  doc_free(doc);
1663
- xfree(doc);
1664
1648
  }
1665
1649
  return Qnil;
1666
1650
  }
data/ext/oj/intern.c CHANGED
@@ -8,6 +8,8 @@
8
8
  #if HAVE_PTHREAD_MUTEX_INIT
9
9
  #include <pthread.h>
10
10
  #endif
11
+
12
+ #include "mem.h"
11
13
  #include "cache.h"
12
14
  #include "parse.h"
13
15
 
@@ -55,7 +57,7 @@ static VALUE form_attr(const char *str, size_t len) {
55
57
  char buf[256];
56
58
 
57
59
  if (sizeof(buf) - 2 <= len) {
58
- char *b = ALLOC_N(char, len + 2);
60
+ char *b = OJ_R_ALLOC_N(char, len + 2);
59
61
  ID id;
60
62
 
61
63
  if ('~' == *str) {
@@ -68,7 +70,7 @@ static VALUE form_attr(const char *str, size_t len) {
68
70
  b[len + 1] = '\0';
69
71
  }
70
72
  id = rb_intern3(buf, len + 1, oj_utf8_encoding);
71
- xfree(b);
73
+ OJ_R_FREE(b);
72
74
  return id;
73
75
  }
74
76
  if ('~' == *str) {
@@ -246,7 +248,7 @@ VALUE oj_class_intern(const char *key, size_t len, bool safe, ParseInfo pi, int
246
248
  }
247
249
  bucket = b;
248
250
  }
249
- b = ALLOC(struct _keyVal);
251
+ b = OJ_R_ALLOC(struct _keyVal);
250
252
  b->next = NULL;
251
253
  bucket->next = b;
252
254
  bucket = b;
@@ -267,7 +269,7 @@ VALUE oj_class_intern(const char *key, size_t len, bool safe, ParseInfo pi, int
267
269
  }
268
270
  bucket = b;
269
271
  }
270
- b = ALLOC(struct _keyVal);
272
+ b = OJ_R_ALLOC(struct _keyVal);
271
273
  b->next = NULL;
272
274
  bucket->next = b;
273
275
  bucket = b;
@@ -281,7 +283,7 @@ VALUE oj_class_intern(const char *key, size_t len, bool safe, ParseInfo pi, int
281
283
  }
282
284
 
283
285
  char *oj_strndup(const char *s, size_t len) {
284
- char *d = ALLOC_N(char, len + 1);
286
+ char *d = OJ_R_ALLOC_N(char, len + 1);
285
287
 
286
288
  memcpy(d, s, len);
287
289
  d[len] = '\0';