oj 3.13.11 → 3.13.12

Sign up to get free protection for your applications and to get access to all the features.
data/ext/oj/odd.c CHANGED
@@ -5,28 +5,27 @@
5
5
 
6
6
  #include <string.h>
7
7
 
8
- static struct _odd _odds[4]; // bump up if new initial Odd classes are added
9
- static struct _odd *odds = _odds;
10
- static long odd_cnt = 0;
11
- static ID sec_id;
12
- static ID sec_fraction_id;
13
- static ID to_f_id;
14
- static ID numerator_id;
15
- static ID denominator_id;
16
- static ID rational_id;
17
- static VALUE rational_class;
8
+ static Odd odds = NULL;
9
+ static ID sec_id;
10
+ static ID sec_fraction_id;
11
+ static ID to_f_id;
12
+ static ID numerator_id;
13
+ static ID denominator_id;
14
+ static ID rational_id;
18
15
 
19
16
  static void set_class(Odd odd, const char *classname) {
20
17
  const char **np;
21
- ID * idp;
18
+ ID *idp;
22
19
 
23
- odd->classname = classname;
24
- odd->clen = strlen(classname);
25
- odd->clas = rb_const_get(rb_cObject, rb_intern(classname));
20
+ odd->classname = classname;
21
+ odd->clen = strlen(classname);
22
+ odd->clas = rb_const_get(rb_cObject, rb_intern(classname));
23
+ rb_gc_register_mark_object(odd->clas);
26
24
  odd->create_obj = odd->clas;
27
- odd->create_op = rb_intern("new");
28
- odd->is_module = (T_MODULE == rb_type(odd->clas));
29
- odd->raw = 0;
25
+ rb_gc_register_mark_object(odd->create_obj);
26
+ odd->create_op = rb_intern("new");
27
+ odd->is_module = (T_MODULE == rb_type(odd->clas));
28
+ odd->raw = 0;
30
29
  for (np = odd->attr_names, idp = odd->attrs; 0 != *np; np++, idp++) {
31
30
  *idp = rb_intern(*np);
32
31
  }
@@ -37,15 +36,48 @@ static VALUE get_datetime_secs(VALUE obj) {
37
36
  volatile VALUE rsecs = rb_funcall(obj, sec_id, 0);
38
37
  volatile VALUE rfrac = rb_funcall(obj, sec_fraction_id, 0);
39
38
  long sec = NUM2LONG(rsecs);
40
- long long num = rb_num2ll(rb_funcall(rfrac, numerator_id, 0));
41
- long long den = rb_num2ll(rb_funcall(rfrac, denominator_id, 0));
39
+ long long num = NUM2LL(rb_funcall(rfrac, numerator_id, 0));
40
+ long long den = NUM2LL(rb_funcall(rfrac, denominator_id, 0));
42
41
 
43
42
  num += sec * den;
44
43
 
45
44
  return rb_funcall(rb_cObject, rational_id, 2, rb_ll2inum(num), rb_ll2inum(den));
46
45
  }
47
46
 
48
- void oj_odd_init() {
47
+ static void print_odd(Odd odd) {
48
+ const char **np;
49
+ int i;
50
+
51
+ printf(" %s {\n", odd->classname);
52
+ printf(" attr_cnt: %d %p\n", odd->attr_cnt, (void *)odd->attr_names);
53
+ printf(" attr_names: %p\n", (void *)*odd->attr_names);
54
+ printf(" attr_names: %c\n", **odd->attr_names);
55
+ for (i = odd->attr_cnt, np = odd->attr_names; 0 < i; i--, np++) {
56
+ printf(" %d %s\n", i, *np);
57
+ }
58
+ printf(" }\n");
59
+ }
60
+
61
+ void print_all_odds(const char *label) {
62
+ Odd odd;
63
+ printf("@ %s {\n", label);
64
+ for (odd = odds; NULL != odd; odd = odd->next) {
65
+ print_odd(odd);
66
+ }
67
+ printf("}\n");
68
+ }
69
+
70
+ static Odd odd_create(void) {
71
+ Odd odd = ALLOC(struct _odd);
72
+
73
+ memset(odd, 0, sizeof(struct _odd));
74
+ odd->next = odds;
75
+ odds = odd;
76
+
77
+ return odd;
78
+ }
79
+
80
+ void oj_odd_init(void) {
49
81
  Odd odd;
50
82
  const char **np;
51
83
 
@@ -55,11 +87,9 @@ void oj_odd_init() {
55
87
  numerator_id = rb_intern("numerator");
56
88
  denominator_id = rb_intern("denominator");
57
89
  rational_id = rb_intern("Rational");
58
- rational_class = rb_const_get(rb_cObject, rational_id);
59
90
 
60
- memset(_odds, 0, sizeof(_odds));
61
- odd = odds;
62
91
  // Rational
92
+ odd = odd_create();
63
93
  np = odd->attr_names;
64
94
  *np++ = "numerator";
65
95
  *np++ = "denominator";
@@ -68,8 +98,9 @@ void oj_odd_init() {
68
98
  odd->create_obj = rb_cObject;
69
99
  odd->create_op = rational_id;
70
100
  odd->attr_cnt = 2;
101
+
71
102
  // Date
72
- odd++;
103
+ odd = odd_create();
73
104
  np = odd->attr_names;
74
105
  *np++ = "year";
75
106
  *np++ = "month";
@@ -78,8 +109,9 @@ void oj_odd_init() {
78
109
  *np++ = 0;
79
110
  set_class(odd, "Date");
80
111
  odd->attr_cnt = 4;
112
+
81
113
  // DateTime
82
- odd++;
114
+ odd = odd_create();
83
115
  np = odd->attr_names;
84
116
  *np++ = "year";
85
117
  *np++ = "month";
@@ -93,8 +125,9 @@ void oj_odd_init() {
93
125
  set_class(odd, "DateTime");
94
126
  odd->attr_cnt = 8;
95
127
  odd->attrFuncs[5] = get_datetime_secs;
128
+
96
129
  // Range
97
- odd++;
130
+ odd = odd_create();
98
131
  np = odd->attr_names;
99
132
  *np++ = "begin";
100
133
  *np++ = "end";
@@ -102,15 +135,13 @@ void oj_odd_init() {
102
135
  *np++ = 0;
103
136
  set_class(odd, "Range");
104
137
  odd->attr_cnt = 3;
105
-
106
- odd_cnt = odd - odds + 1;
107
138
  }
108
139
 
109
140
  Odd oj_get_odd(VALUE clas) {
110
141
  Odd odd;
111
142
  const char *classname = NULL;
112
143
 
113
- for (odd = odds + odd_cnt - 1; odds <= odd; odd--) {
144
+ for (odd = odds; NULL != odd; odd = odd->next) {
114
145
  if (clas == odd->clas) {
115
146
  return odd;
116
147
  }
@@ -129,21 +160,20 @@ Odd oj_get_odd(VALUE clas) {
129
160
  Odd oj_get_oddc(const char *classname, size_t len) {
130
161
  Odd odd;
131
162
 
132
- for (odd = odds + odd_cnt - 1; odds <= odd; odd--) {
163
+ for (odd = odds; NULL != odd; odd = odd->next) {
133
164
  if (len == odd->clen && 0 == strncmp(classname, odd->classname, len)) {
134
165
  return odd;
135
166
  }
136
- if (odd->is_module && 0 == strncmp(odd->classname, classname, odd->clen) &&
137
- ':' == classname[odd->clen]) {
167
+ if (odd->is_module && 0 == strncmp(odd->classname, classname, odd->clen) && ':' == classname[odd->clen]) {
138
168
  return odd;
139
169
  }
140
170
  }
141
- return 0;
171
+ return NULL;
142
172
  }
143
173
 
144
174
  OddArgs oj_odd_alloc_args(Odd odd) {
145
175
  OddArgs oa = ALLOC_N(struct _oddArgs, 1);
146
- VALUE * a;
176
+ VALUE *a;
147
177
  int i;
148
178
 
149
179
  oa->odd = odd;
@@ -159,11 +189,10 @@ void oj_odd_free(OddArgs args) {
159
189
 
160
190
  int oj_odd_set_arg(OddArgs args, const char *key, size_t klen, VALUE value) {
161
191
  const char **np;
162
- VALUE * vp;
192
+ VALUE *vp;
163
193
  int i;
164
194
 
165
- for (i = args->odd->attr_cnt, np = args->odd->attr_names, vp = args->args; 0 < i;
166
- i--, np++, vp++) {
195
+ for (i = args->odd->attr_cnt, np = args->odd->attr_names, vp = args->args; 0 < i; i--, np++, vp++) {
167
196
  if (0 == strncmp(key, *np, klen) && '\0' == *((*np) + klen)) {
168
197
  *vp = value;
169
198
  return 0;
@@ -172,37 +201,26 @@ int oj_odd_set_arg(OddArgs args, const char *key, size_t klen, VALUE value) {
172
201
  return -1;
173
202
  }
174
203
 
175
- void oj_reg_odd(VALUE clas,
176
- VALUE create_object,
177
- VALUE create_method,
178
- int mcnt,
179
- VALUE *members,
180
- bool raw) {
204
+ void oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt, VALUE *members, bool raw) {
181
205
  Odd odd;
182
206
  const char **np;
183
- ID * ap;
207
+ ID *ap;
184
208
  AttrGetFunc *fp;
185
209
 
186
- if (_odds == odds) {
187
- odds = ALLOC_N(struct _odd, odd_cnt + 1);
188
-
189
- memcpy(odds, _odds, sizeof(struct _odd) * odd_cnt);
190
- } else {
191
- REALLOC_N(odds, struct _odd, odd_cnt + 1);
192
- }
193
- odd = odds + odd_cnt;
210
+ odd = odd_create();
194
211
  odd->clas = clas;
212
+ rb_gc_register_mark_object(odd->clas);
195
213
  if (NULL == (odd->classname = strdup(rb_class2name(clas)))) {
196
- rb_raise(rb_eNoMemError, "for attribute name.");
214
+ rb_raise(rb_eNoMemError, "for class name.");
197
215
  }
198
216
  odd->clen = strlen(odd->classname);
199
217
  odd->create_obj = create_object;
200
- odd->create_op = SYM2ID(create_method);
201
- odd->attr_cnt = mcnt;
202
- odd->is_module = (T_MODULE == rb_type(clas));
203
- odd->raw = raw;
204
- for (ap = odd->attrs, np = odd->attr_names, fp = odd->attrFuncs; 0 < mcnt;
205
- mcnt--, ap++, np++, members++, fp++) {
218
+ rb_gc_register_mark_object(odd->create_obj);
219
+ odd->create_op = SYM2ID(create_method);
220
+ odd->attr_cnt = mcnt;
221
+ odd->is_module = (T_MODULE == rb_type(clas));
222
+ odd->raw = raw;
223
+ for (ap = odd->attrs, np = odd->attr_names, fp = odd->attrFuncs; 0 < mcnt; mcnt--, ap++, np++, members++, fp++) {
206
224
  *fp = 0;
207
225
  switch (rb_type(*members)) {
208
226
  case T_STRING:
@@ -210,14 +228,16 @@ void oj_reg_odd(VALUE clas,
210
228
  rb_raise(rb_eNoMemError, "for attribute name.");
211
229
  }
212
230
  break;
213
- case T_SYMBOL: *np = rb_id2name(SYM2ID(*members)); break;
214
- default:
215
- rb_raise(rb_eArgError, "registered member identifiers must be Strings or Symbols.");
231
+ case T_SYMBOL:
232
+ // The symbol can move and invalidate the name so make a copy.
233
+ if (NULL == (*np = strdup(rb_id2name(SYM2ID(*members))))) {
234
+ rb_raise(rb_eNoMemError, "for attribute name.");
235
+ }
216
236
  break;
237
+ default: rb_raise(rb_eArgError, "registered member identifiers must be Strings or Symbols."); break;
217
238
  }
218
239
  *ap = rb_intern(*np);
219
240
  }
220
241
  *np = 0;
221
242
  *ap = 0;
222
- odd_cnt++;
223
243
  }
data/ext/oj/odd.h CHANGED
@@ -13,17 +13,18 @@
13
13
  typedef VALUE (*AttrGetFunc)(VALUE obj);
14
14
 
15
15
  typedef struct _odd {
16
- const char *classname;
17
- size_t clen;
18
- VALUE clas; // Ruby class or module
19
- VALUE create_obj;
20
- ID create_op;
21
- int attr_cnt;
22
- bool is_module;
23
- bool raw;
24
- const char *attr_names[MAX_ODD_ARGS]; // NULL terminated attr names
25
- ID attrs[MAX_ODD_ARGS]; // 0 terminated attr IDs
26
- AttrGetFunc attrFuncs[MAX_ODD_ARGS];
16
+ struct _odd *next;
17
+ const char * classname;
18
+ size_t clen;
19
+ VALUE clas; // Ruby class or module
20
+ VALUE create_obj;
21
+ ID create_op;
22
+ int attr_cnt;
23
+ bool is_module;
24
+ bool raw;
25
+ const char * attr_names[MAX_ODD_ARGS]; // NULL terminated attr names
26
+ ID attrs[MAX_ODD_ARGS]; // 0 terminated attr IDs
27
+ AttrGetFunc attrFuncs[MAX_ODD_ARGS];
27
28
  } * Odd;
28
29
 
29
30
  typedef struct _oddArgs {
@@ -37,7 +38,6 @@ extern Odd oj_get_oddc(const char *classname, size_t len);
37
38
  extern OddArgs oj_odd_alloc_args(Odd odd);
38
39
  extern void oj_odd_free(OddArgs args);
39
40
  extern int oj_odd_set_arg(OddArgs args, const char *key, size_t klen, VALUE value);
40
- extern void
41
- oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt, VALUE *members, bool raw);
41
+ extern void oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt, VALUE *members, bool raw);
42
42
 
43
43
  #endif /* OJ_ODD_H */
data/ext/oj/oj.c CHANGED
@@ -153,6 +153,7 @@ static VALUE xmlschema_sym;
153
153
  static VALUE xss_safe_sym;
154
154
 
155
155
  rb_encoding *oj_utf8_encoding = 0;
156
+ int oj_utf8_encoding_index = 0;
156
157
 
157
158
  #ifdef HAVE_PTHREAD_MUTEX_INIT
158
159
  pthread_mutex_t oj_cache_mutex;
@@ -1243,9 +1244,8 @@ static VALUE dump_body(VALUE a) {
1243
1244
  static VALUE dump_ensure(VALUE a) {
1244
1245
  volatile struct dump_arg *arg = (void *)a;
1245
1246
 
1246
- if (arg->out->allocated) {
1247
- xfree(arg->out->buf);
1248
- }
1247
+ oj_out_free(arg->out);
1248
+
1249
1249
  return Qnil;
1250
1250
  }
1251
1251
 
@@ -1257,7 +1257,6 @@ static VALUE dump_ensure(VALUE a) {
1257
1257
  * - *options* [_Hash_] same as default_options
1258
1258
  */
1259
1259
  static VALUE dump(int argc, VALUE *argv, VALUE self) {
1260
- char buf[4096];
1261
1260
  struct dump_arg arg;
1262
1261
  struct _out out;
1263
1262
  struct _options copts = oj_default_options;
@@ -1279,9 +1278,8 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) {
1279
1278
  arg.argc = argc;
1280
1279
  arg.argv = argv;
1281
1280
 
1282
- arg.out->buf = buf;
1283
- arg.out->end = buf + sizeof(buf) - 10;
1284
- arg.out->allocated = false;
1281
+ oj_out_init(arg.out);
1282
+
1285
1283
  arg.out->omit_nil = copts.dump_opts.omit_nil;
1286
1284
  arg.out->caller = CALLER_DUMP;
1287
1285
 
@@ -1313,7 +1311,6 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) {
1313
1311
  * Returns [_String_] the encoded JSON.
1314
1312
  */
1315
1313
  static VALUE to_json(int argc, VALUE *argv, VALUE self) {
1316
- char buf[4096];
1317
1314
  struct _out out;
1318
1315
  struct _options copts = oj_default_options;
1319
1316
  VALUE rstr;
@@ -1328,9 +1325,9 @@ static VALUE to_json(int argc, VALUE *argv, VALUE self) {
1328
1325
  }
1329
1326
  copts.mode = CompatMode;
1330
1327
  copts.to_json = Yes;
1331
- out.buf = buf;
1332
- out.end = buf + sizeof(buf) - 10;
1333
- out.allocated = false;
1328
+
1329
+ oj_out_init(&out);
1330
+
1334
1331
  out.omit_nil = copts.dump_opts.omit_nil;
1335
1332
  // For obj.to_json or generate nan is not allowed but if called from dump
1336
1333
  // it is.
@@ -1341,9 +1338,9 @@ static VALUE to_json(int argc, VALUE *argv, VALUE self) {
1341
1338
  }
1342
1339
  rstr = rb_str_new2(out.buf);
1343
1340
  rstr = oj_encode(rstr);
1344
- if (out.allocated) {
1345
- xfree(out.buf);
1346
- }
1341
+
1342
+ oj_out_free(&out);
1343
+
1347
1344
  return rstr;
1348
1345
  }
1349
1346
 
@@ -1703,6 +1700,15 @@ static VALUE protect_require(VALUE x) {
1703
1700
  return Qnil;
1704
1701
  }
1705
1702
 
1703
+ extern void print_all_odds(const char *label);
1704
+
1705
+ static VALUE
1706
+ debug_odd(VALUE self, VALUE label) {
1707
+ print_all_odds(RSTRING_PTR(label));
1708
+ return Qnil;
1709
+ }
1710
+
1711
+
1706
1712
  /* Document-module: Oj
1707
1713
  *
1708
1714
  * Optimized JSON (Oj), as the name implies was written to provide speed
@@ -1731,15 +1737,19 @@ static VALUE protect_require(VALUE x) {
1731
1737
  *
1732
1738
  * - *:wab* specifically for WAB data exchange.
1733
1739
  */
1734
- void Init_oj() {
1740
+ void Init_oj(void) {
1735
1741
  int err = 0;
1736
1742
 
1737
1743
  #if HAVE_RB_EXT_RACTOR_SAFE
1738
1744
  rb_ext_ractor_safe(true);
1739
1745
  #endif
1740
1746
  Oj = rb_define_module("Oj");
1747
+ rb_gc_register_address(&Oj);
1741
1748
 
1742
1749
  oj_cstack_class = rb_define_class_under(Oj, "CStack", rb_cObject);
1750
+ rb_gc_register_address(&oj_cstack_class);
1751
+
1752
+ rb_undef_alloc_func(oj_cstack_class);
1743
1753
 
1744
1754
  oj_string_writer_init();
1745
1755
  oj_stream_writer_init();
@@ -1748,9 +1758,11 @@ void Init_oj() {
1748
1758
  // On Rubinius the require fails but can be done from a ruby file.
1749
1759
  rb_protect(protect_require, Qnil, &err);
1750
1760
  rb_require("stringio");
1751
- oj_utf8_encoding = rb_enc_find("UTF-8");
1761
+ oj_utf8_encoding_index = rb_enc_find_index("UTF-8");
1762
+ oj_utf8_encoding = rb_enc_from_index(oj_utf8_encoding_index);
1752
1763
 
1753
1764
  // rb_define_module_function(Oj, "hash_test", hash_test, 0);
1765
+ rb_define_module_function(Oj, "debug_odd", debug_odd, 1);
1754
1766
 
1755
1767
  rb_define_module_function(Oj, "default_options", get_def_opts, 0);
1756
1768
  rb_define_module_function(Oj, "default_options=", set_def_opts, 1);
data/ext/oj/oj.h CHANGED
@@ -39,6 +39,16 @@ enum st_retval { ST_CONTINUE = 0, ST_STOP = 1, ST_DELETE = 2, ST_CHECK };
39
39
  #define NINF_VAL "-3.0e14159265358979323846"
40
40
  #define NAN_VAL "3.3e14159265358979323846"
41
41
 
42
+ #if __STDC_VERSION__ >= 199901L
43
+ // To avoid using ruby_snprintf with C99.
44
+ #undef snprintf
45
+ #include <stdio.h>
46
+ #endif
47
+
48
+ // To avoid using ruby_nonempty_memcpy().
49
+ #undef memcpy
50
+ #include <string.h>
51
+
42
52
  typedef enum { Yes = 'y', No = 'n', NotSet = 0 } YesNo;
43
53
 
44
54
  typedef enum {
@@ -176,6 +186,7 @@ typedef struct _rOptTable {
176
186
  } * ROptTable;
177
187
 
178
188
  typedef struct _out {
189
+ char stack_buffer[4096];
179
190
  char * buf;
180
191
  char * end;
181
192
  char * cur;
@@ -265,8 +276,8 @@ extern void oj_str_writer_pop(StrWriter sw);
265
276
  extern void oj_str_writer_pop_all(StrWriter sw);
266
277
 
267
278
  extern void oj_init_doc(void);
268
- extern void oj_string_writer_init();
269
- extern void oj_stream_writer_init();
279
+ extern void oj_string_writer_init(void);
280
+ extern void oj_stream_writer_init(void);
270
281
  extern void oj_str_writer_init(StrWriter sw, int buf_size);
271
282
  extern VALUE oj_define_mimic_json(int argc, VALUE *argv, VALUE self);
272
283
  extern VALUE oj_mimic_generate(int argc, VALUE *argv, VALUE self);
@@ -282,6 +293,7 @@ extern VALUE oj_rails_encode(int argc, VALUE *argv, VALUE self);
282
293
  extern VALUE Oj;
283
294
  extern struct _options oj_default_options;
284
295
  extern rb_encoding * oj_utf8_encoding;
296
+ extern int oj_utf8_encoding_index;
285
297
 
286
298
  extern VALUE oj_bag_class;
287
299
  extern VALUE oj_bigdecimal_class;
@@ -364,6 +376,12 @@ extern bool oj_use_hash_alt;
364
376
  extern bool oj_use_array_alt;
365
377
  extern bool string_writer_optimized;
366
378
 
379
+ #define APPEND_CHARS(buffer, chars, size) \
380
+ { \
381
+ memcpy(buffer, chars, size); \
382
+ buffer += size; \
383
+ }
384
+
367
385
  #ifdef HAVE_PTHREAD_MUTEX_INIT
368
386
  extern pthread_mutex_t oj_cache_mutex;
369
387
  #else
data/ext/oj/parse.c CHANGED
@@ -972,9 +972,10 @@ static VALUE protect_parse(VALUE pip) {
972
972
  extern int oj_utf8_index;
973
973
 
974
974
  static void oj_pi_set_input_str(ParseInfo pi, volatile VALUE *inputp) {
975
- rb_encoding *enc = rb_enc_get(*inputp);
975
+ int idx = RB_ENCODING_GET(*inputp);
976
976
 
977
- if (oj_utf8_encoding != enc) {
977
+ if (oj_utf8_encoding_index != idx) {
978
+ rb_encoding *enc = rb_enc_from_index(idx);
978
979
  *inputp = rb_str_conv_enc(*inputp, enc, oj_utf8_encoding);
979
980
  }
980
981
  pi->json = RSTRING_PTR(*inputp);
data/ext/oj/parser.c CHANGED
@@ -11,8 +11,8 @@
11
11
  #define USE_THREAD_LIMIT 0
12
12
  // #define USE_THREAD_LIMIT 100000
13
13
  #define MAX_EXP 4932
14
- // max in the pow_map
15
- #define MAX_POW 400
14
+ // max in the pow_map which is the limit for double
15
+ #define MAX_POW 308
16
16
 
17
17
  #define MIN_SLEEP (1000000000LL / (double)CLOCKS_PER_SEC)
18
18
  // 9,223,372,036,854,775,807
@@ -385,7 +385,7 @@ static const byte hex_map[256] = "\
385
385
  ................................\
386
386
  ................................";
387
387
 
388
- static long double pow_map[401] = {
388
+ static long double pow_map[309] = {
389
389
  1.0L, 1.0e1L, 1.0e2L, 1.0e3L, 1.0e4L, 1.0e5L, 1.0e6L, 1.0e7L, 1.0e8L, 1.0e9L, 1.0e10L,
390
390
  1.0e11L, 1.0e12L, 1.0e13L, 1.0e14L, 1.0e15L, 1.0e16L, 1.0e17L, 1.0e18L, 1.0e19L, 1.0e20L, 1.0e21L,
391
391
  1.0e22L, 1.0e23L, 1.0e24L, 1.0e25L, 1.0e26L, 1.0e27L, 1.0e28L, 1.0e29L, 1.0e30L, 1.0e31L, 1.0e32L,
@@ -414,15 +414,7 @@ static long double pow_map[401] = {
414
414
  1.0e275L, 1.0e276L, 1.0e277L, 1.0e278L, 1.0e279L, 1.0e280L, 1.0e281L, 1.0e282L, 1.0e283L, 1.0e284L, 1.0e285L,
415
415
  1.0e286L, 1.0e287L, 1.0e288L, 1.0e289L, 1.0e290L, 1.0e291L, 1.0e292L, 1.0e293L, 1.0e294L, 1.0e295L, 1.0e296L,
416
416
  1.0e297L, 1.0e298L, 1.0e299L, 1.0e300L, 1.0e301L, 1.0e302L, 1.0e303L, 1.0e304L, 1.0e305L, 1.0e306L, 1.0e307L,
417
- 1.0e308L, 1.0e309L, 1.0e310L, 1.0e311L, 1.0e312L, 1.0e313L, 1.0e314L, 1.0e315L, 1.0e316L, 1.0e317L, 1.0e318L,
418
- 1.0e319L, 1.0e320L, 1.0e321L, 1.0e322L, 1.0e323L, 1.0e324L, 1.0e325L, 1.0e326L, 1.0e327L, 1.0e328L, 1.0e329L,
419
- 1.0e330L, 1.0e331L, 1.0e332L, 1.0e333L, 1.0e334L, 1.0e335L, 1.0e336L, 1.0e337L, 1.0e338L, 1.0e339L, 1.0e340L,
420
- 1.0e341L, 1.0e342L, 1.0e343L, 1.0e344L, 1.0e345L, 1.0e346L, 1.0e347L, 1.0e348L, 1.0e349L, 1.0e350L, 1.0e351L,
421
- 1.0e352L, 1.0e353L, 1.0e354L, 1.0e355L, 1.0e356L, 1.0e357L, 1.0e358L, 1.0e359L, 1.0e360L, 1.0e361L, 1.0e362L,
422
- 1.0e363L, 1.0e364L, 1.0e365L, 1.0e366L, 1.0e367L, 1.0e368L, 1.0e369L, 1.0e370L, 1.0e371L, 1.0e372L, 1.0e373L,
423
- 1.0e374L, 1.0e375L, 1.0e376L, 1.0e377L, 1.0e378L, 1.0e379L, 1.0e380L, 1.0e381L, 1.0e382L, 1.0e383L, 1.0e384L,
424
- 1.0e385L, 1.0e386L, 1.0e387L, 1.0e388L, 1.0e389L, 1.0e390L, 1.0e391L, 1.0e392L, 1.0e393L, 1.0e394L, 1.0e395L,
425
- 1.0e396L, 1.0e397L, 1.0e398L, 1.0e399L, 1.0e400L};
417
+ 1.0e308L};
426
418
 
427
419
  static VALUE parser_class;
428
420
 
@@ -1190,7 +1182,7 @@ static VALUE parser_new(int argc, VALUE *argv, VALUE self) {
1190
1182
  p->map = value_map;
1191
1183
 
1192
1184
  if (argc < 1) {
1193
- oj_set_parser_validator(p);
1185
+ oj_set_parser_validator(p);
1194
1186
  } else {
1195
1187
  VALUE mode = argv[0];
1196
1188
 
@@ -1284,7 +1276,7 @@ static VALUE parser_new(int argc, VALUE *argv, VALUE self) {
1284
1276
  */
1285
1277
  static VALUE parser_missing(int argc, VALUE *argv, VALUE self) {
1286
1278
  ojParser p = (ojParser)DATA_PTR(self);
1287
- const char * key = NULL;
1279
+ const char *key = NULL;
1288
1280
  volatile VALUE rkey = *argv;
1289
1281
  volatile VALUE rv = Qnil;
1290
1282
 
@@ -1515,8 +1507,11 @@ static VALUE parser_validate(VALUE self) {
1515
1507
  * isolates options to just the parser so that other parts of the code are not
1516
1508
  * forced to use the same options.
1517
1509
  */
1518
- void oj_parser_init() {
1510
+ void oj_parser_init(void) {
1519
1511
  parser_class = rb_define_class_under(Oj, "Parser", rb_cObject);
1512
+ rb_gc_register_address(&parser_class);
1513
+ rb_undef_alloc_func(parser_class);
1514
+
1520
1515
  rb_define_module_function(parser_class, "new", parser_new, -1);
1521
1516
  rb_define_method(parser_class, "parse", parser_parse, 1);
1522
1517
  rb_define_method(parser_class, "load", parser_load, 1);