msgpack 1.3.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yaml +57 -0
  3. data/.gitignore +3 -1
  4. data/.rubocop.yml +2 -2
  5. data/ChangeLog +86 -0
  6. data/Gemfile +3 -0
  7. data/README.md +266 -0
  8. data/Rakefile +1 -9
  9. data/bench/bench.rb +78 -0
  10. data/bin/console +8 -0
  11. data/doclib/msgpack/factory.rb +47 -3
  12. data/doclib/msgpack/packer.rb +5 -4
  13. data/doclib/msgpack/time.rb +1 -1
  14. data/doclib/msgpack/unpacker.rb +2 -2
  15. data/ext/java/org/msgpack/jruby/Buffer.java +23 -16
  16. data/ext/java/org/msgpack/jruby/Decoder.java +46 -23
  17. data/ext/java/org/msgpack/jruby/Encoder.java +68 -30
  18. data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +37 -49
  19. data/ext/java/org/msgpack/jruby/ExtensionValue.java +5 -8
  20. data/ext/java/org/msgpack/jruby/Factory.java +47 -7
  21. data/ext/java/org/msgpack/jruby/Packer.java +29 -17
  22. data/ext/java/org/msgpack/jruby/Unpacker.java +72 -37
  23. data/ext/msgpack/buffer.c +42 -68
  24. data/ext/msgpack/buffer.h +59 -14
  25. data/ext/msgpack/buffer_class.c +90 -52
  26. data/ext/msgpack/compat.h +1 -111
  27. data/ext/msgpack/extconf.rb +45 -19
  28. data/ext/msgpack/factory_class.c +133 -43
  29. data/ext/msgpack/packer.c +60 -36
  30. data/ext/msgpack/packer.h +27 -25
  31. data/ext/msgpack/packer_class.c +84 -77
  32. data/ext/msgpack/packer_class.h +11 -0
  33. data/ext/msgpack/packer_ext_registry.c +24 -32
  34. data/ext/msgpack/packer_ext_registry.h +40 -33
  35. data/ext/msgpack/sysdep.h +5 -2
  36. data/ext/msgpack/unpacker.c +132 -115
  37. data/ext/msgpack/unpacker.h +23 -10
  38. data/ext/msgpack/unpacker_class.c +83 -81
  39. data/ext/msgpack/unpacker_class.h +11 -0
  40. data/ext/msgpack/unpacker_ext_registry.c +42 -18
  41. data/ext/msgpack/unpacker_ext_registry.h +23 -16
  42. data/lib/msgpack/bigint.rb +69 -0
  43. data/lib/msgpack/factory.rb +103 -0
  44. data/lib/msgpack/symbol.rb +21 -4
  45. data/lib/msgpack/time.rb +1 -1
  46. data/lib/msgpack/timestamp.rb +1 -1
  47. data/lib/msgpack/version.rb +4 -7
  48. data/lib/msgpack.rb +6 -12
  49. data/msgpack.gemspec +4 -7
  50. data/spec/bigint_spec.rb +26 -0
  51. data/spec/cruby/buffer_spec.rb +17 -0
  52. data/spec/factory_spec.rb +351 -12
  53. data/spec/msgpack_spec.rb +1 -1
  54. data/spec/packer_spec.rb +18 -0
  55. data/spec/spec_helper.rb +37 -3
  56. data/spec/timestamp_spec.rb +42 -0
  57. data/spec/unpacker_spec.rb +157 -4
  58. metadata +32 -62
  59. data/.travis.yml +0 -43
  60. data/README.rdoc +0 -225
  61. data/bench/pack.rb +0 -23
  62. data/bench/pack_log.rb +0 -33
  63. data/bench/pack_log_long.rb +0 -65
  64. data/bench/pack_symbols.rb +0 -28
  65. data/bench/run.sh +0 -14
  66. data/bench/run_long.sh +0 -35
  67. data/bench/run_symbols.sh +0 -26
  68. data/bench/unpack.rb +0 -21
  69. data/bench/unpack_log.rb +0 -34
  70. data/bench/unpack_log_long.rb +0 -67
@@ -28,13 +28,12 @@ static ID s_readpartial;
28
28
  static ID s_write;
29
29
  static ID s_append;
30
30
  static ID s_close;
31
+ static ID s_at_owner;
32
+
33
+ static VALUE sym_read_reference_threshold;
34
+ static VALUE sym_write_reference_threshold;
35
+ static VALUE sym_io_buffer_size;
31
36
 
32
- #define BUFFER(from, name) \
33
- msgpack_buffer_t *name = NULL; \
34
- Data_Get_Struct(from, msgpack_buffer_t, name); \
35
- if(name == NULL) { \
36
- rb_raise(rb_eArgError, "NULL found for " # name " when shouldn't be."); \
37
- }
38
37
 
39
38
  #define CHECK_STRING_TYPE(value) \
40
39
  value = rb_check_string_type(value); \
@@ -52,34 +51,69 @@ static void Buffer_free(void* data)
52
51
  xfree(b);
53
52
  }
54
53
 
54
+ static size_t Buffer_memsize(const void *data)
55
+ {
56
+ return sizeof(msgpack_buffer_t) + msgpack_buffer_memsize(data);
57
+ }
58
+
59
+ const rb_data_type_t buffer_data_type = {
60
+ .wrap_struct_name = "msgpack:buffer",
61
+ .function = {
62
+ .dmark = msgpack_buffer_mark,
63
+ .dfree = Buffer_free,
64
+ .dsize = Buffer_memsize,
65
+ },
66
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
67
+ };
68
+
69
+ const rb_data_type_t buffer_view_data_type = {
70
+ .wrap_struct_name = "msgpack:buffer_view",
71
+ .function = {
72
+ .dmark = msgpack_buffer_mark,
73
+ .dfree = NULL,
74
+ .dsize = NULL,
75
+ },
76
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
77
+ };
78
+
79
+ static inline msgpack_buffer_t *MessagePack_Buffer_get(VALUE object)
80
+ {
81
+ msgpack_buffer_t *buffer;
82
+ bool view = RTEST(rb_ivar_get(object, s_at_owner));
83
+ TypedData_Get_Struct(object, msgpack_buffer_t, view ? &buffer_view_data_type : &buffer_data_type, buffer);
84
+ if (!buffer) {
85
+ rb_raise(rb_eArgError, "Uninitialized Buffer object");
86
+ }
87
+ return buffer;
88
+ }
89
+
55
90
  static VALUE Buffer_alloc(VALUE klass)
56
91
  {
57
- msgpack_buffer_t* b = ZALLOC_N(msgpack_buffer_t, 1);
92
+ msgpack_buffer_t* b;
93
+ VALUE buffer = TypedData_Make_Struct(klass, msgpack_buffer_t, &buffer_data_type, b);
94
+ rb_ivar_set(buffer, s_at_owner, Qnil);
58
95
  msgpack_buffer_init(b);
59
-
60
- return Data_Wrap_Struct(klass, msgpack_buffer_mark, Buffer_free, b);
96
+ return buffer;
61
97
  }
62
98
 
63
99
  static ID get_partial_read_method(VALUE io)
64
100
  {
65
- if(rb_respond_to(io, s_readpartial)) {
101
+ if(io != Qnil && rb_respond_to(io, s_readpartial)) {
66
102
  return s_readpartial;
67
- } else if(rb_respond_to(io, s_read)) {
68
- return s_read;
69
- } else {
70
- return s_read;
71
103
  }
104
+ return s_read;
72
105
  }
73
106
 
74
107
  static ID get_write_all_method(VALUE io)
75
108
  {
76
- if(rb_respond_to(io, s_write)) {
77
- return s_write;
78
- } else if(rb_respond_to(io, s_append)) {
79
- return s_append;
80
- } else {
81
- return s_write;
109
+ if(io != Qnil) {
110
+ if(rb_respond_to(io, s_write)) {
111
+ return s_write;
112
+ } else if(rb_respond_to(io, s_append)) {
113
+ return s_append;
114
+ }
82
115
  }
116
+ return s_write;
83
117
  }
84
118
 
85
119
  void MessagePack_Buffer_set_options(msgpack_buffer_t* b, VALUE io, VALUE options)
@@ -91,27 +125,28 @@ void MessagePack_Buffer_set_options(msgpack_buffer_t* b, VALUE io, VALUE options
91
125
  if(options != Qnil) {
92
126
  VALUE v;
93
127
 
94
- v = rb_hash_aref(options, ID2SYM(rb_intern("read_reference_threshold")));
128
+ v = rb_hash_aref(options, sym_read_reference_threshold);
95
129
  if(v != Qnil) {
96
- msgpack_buffer_set_read_reference_threshold(b, NUM2ULONG(v));
130
+ msgpack_buffer_set_read_reference_threshold(b, NUM2SIZET(v));
97
131
  }
98
132
 
99
- v = rb_hash_aref(options, ID2SYM(rb_intern("write_reference_threshold")));
133
+ v = rb_hash_aref(options, sym_write_reference_threshold);
100
134
  if(v != Qnil) {
101
- msgpack_buffer_set_write_reference_threshold(b, NUM2ULONG(v));
135
+ msgpack_buffer_set_write_reference_threshold(b, NUM2SIZET(v));
102
136
  }
103
137
 
104
- v = rb_hash_aref(options, ID2SYM(rb_intern("io_buffer_size")));
138
+ v = rb_hash_aref(options, sym_io_buffer_size);
105
139
  if(v != Qnil) {
106
- msgpack_buffer_set_io_buffer_size(b, NUM2ULONG(v));
140
+ msgpack_buffer_set_io_buffer_size(b, NUM2SIZET(v));
107
141
  }
108
142
  }
109
143
  }
110
144
 
111
145
  VALUE MessagePack_Buffer_wrap(msgpack_buffer_t* b, VALUE owner)
112
146
  {
113
- b->owner = owner;
114
- return Data_Wrap_Struct(cMessagePack_Buffer, msgpack_buffer_mark, NULL, b);
147
+ VALUE buffer = TypedData_Wrap_Struct(cMessagePack_Buffer, &buffer_view_data_type, b);
148
+ rb_ivar_set(buffer, s_at_owner, owner);
149
+ return buffer;
115
150
  }
116
151
 
117
152
  static VALUE Buffer_initialize(int argc, VALUE* argv, VALUE self)
@@ -141,7 +176,7 @@ static VALUE Buffer_initialize(int argc, VALUE* argv, VALUE self)
141
176
  rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..1)", argc);
142
177
  }
143
178
 
144
- BUFFER(self, b);
179
+ msgpack_buffer_t *b = MessagePack_Buffer_get(self);
145
180
 
146
181
  MessagePack_Buffer_set_options(b, io, options);
147
182
 
@@ -150,21 +185,21 @@ static VALUE Buffer_initialize(int argc, VALUE* argv, VALUE self)
150
185
 
151
186
  static VALUE Buffer_clear(VALUE self)
152
187
  {
153
- BUFFER(self, b);
188
+ msgpack_buffer_t *b = MessagePack_Buffer_get(self);
154
189
  msgpack_buffer_clear(b);
155
190
  return Qnil;
156
191
  }
157
192
 
158
193
  static VALUE Buffer_size(VALUE self)
159
194
  {
160
- BUFFER(self, b);
195
+ msgpack_buffer_t *b = MessagePack_Buffer_get(self);
161
196
  size_t size = msgpack_buffer_all_readable_size(b);
162
197
  return SIZET2NUM(size);
163
198
  }
164
199
 
165
200
  static VALUE Buffer_empty_p(VALUE self)
166
201
  {
167
- BUFFER(self, b);
202
+ msgpack_buffer_t *b = MessagePack_Buffer_get(self);
168
203
  if(msgpack_buffer_top_readable_size(b) == 0) {
169
204
  return Qtrue;
170
205
  } else {
@@ -174,7 +209,7 @@ static VALUE Buffer_empty_p(VALUE self)
174
209
 
175
210
  static VALUE Buffer_write(VALUE self, VALUE string_or_buffer)
176
211
  {
177
- BUFFER(self, b);
212
+ msgpack_buffer_t *b = MessagePack_Buffer_get(self);
178
213
 
179
214
  VALUE string = string_or_buffer; // TODO optimize if string_or_buffer is a Buffer
180
215
  StringValue(string);
@@ -186,7 +221,7 @@ static VALUE Buffer_write(VALUE self, VALUE string_or_buffer)
186
221
 
187
222
  static VALUE Buffer_append(VALUE self, VALUE string_or_buffer)
188
223
  {
189
- BUFFER(self, b);
224
+ msgpack_buffer_t *b = MessagePack_Buffer_get(self);
190
225
 
191
226
  VALUE string = string_or_buffer; // TODO optimize if string_or_buffer is a Buffer
192
227
  StringValue(string);
@@ -245,10 +280,11 @@ static VALUE read_until_eof_rescue(VALUE args)
245
280
  return Qnil;
246
281
  }
247
282
 
248
- static VALUE read_until_eof_error(VALUE args)
283
+ static VALUE read_until_eof_error(VALUE args, VALUE error)
249
284
  {
250
285
  /* ignore EOFError */
251
286
  UNUSED(args);
287
+ UNUSED(error);
252
288
  return Qnil;
253
289
  }
254
290
 
@@ -276,14 +312,13 @@ static inline size_t read_until_eof(msgpack_buffer_t* b, VALUE out, unsigned lon
276
312
 
277
313
  static inline VALUE read_all(msgpack_buffer_t* b, VALUE out)
278
314
  {
279
- #ifndef DISABLE_BUFFER_READ_TO_S_OPTIMIZE
280
315
  if(out == Qnil && !msgpack_buffer_has_io(b)) {
281
316
  /* same as to_s && clear; optimize */
282
317
  VALUE str = msgpack_buffer_all_as_string(b);
283
318
  msgpack_buffer_clear(b);
284
319
  return str;
285
320
  }
286
- #endif
321
+
287
322
  MAKE_EMPTY_STRING(out);
288
323
  read_until_eof(b, out, 0);
289
324
  return out;
@@ -291,22 +326,22 @@ static inline VALUE read_all(msgpack_buffer_t* b, VALUE out)
291
326
 
292
327
  static VALUE Buffer_skip(VALUE self, VALUE sn)
293
328
  {
294
- BUFFER(self, b);
329
+ msgpack_buffer_t *b = MessagePack_Buffer_get(self);
295
330
 
296
331
  unsigned long n = FIX2ULONG(sn);
297
332
 
298
333
  /* do nothing */
299
334
  if(n == 0) {
300
- return ULONG2NUM(0);
335
+ return INT2NUM(0);
301
336
  }
302
337
 
303
338
  size_t sz = read_until_eof(b, Qnil, n);
304
- return ULONG2NUM(sz);
339
+ return SIZET2NUM(sz);
305
340
  }
306
341
 
307
342
  static VALUE Buffer_skip_all(VALUE self, VALUE sn)
308
343
  {
309
- BUFFER(self, b);
344
+ msgpack_buffer_t *b = MessagePack_Buffer_get(self);
310
345
 
311
346
  unsigned long n = FIX2ULONG(sn);
312
347
 
@@ -344,7 +379,7 @@ static VALUE Buffer_read_all(int argc, VALUE* argv, VALUE self)
344
379
  rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc);
345
380
  }
346
381
 
347
- BUFFER(self, b);
382
+ msgpack_buffer_t *b = MessagePack_Buffer_get(self);
348
383
 
349
384
  if(out != Qnil) {
350
385
  CHECK_STRING_TYPE(out);
@@ -390,7 +425,7 @@ static VALUE Buffer_read(int argc, VALUE* argv, VALUE self)
390
425
  rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc);
391
426
  }
392
427
 
393
- BUFFER(self, b);
428
+ msgpack_buffer_t *b = MessagePack_Buffer_get(self);
394
429
 
395
430
  if(out != Qnil) {
396
431
  CHECK_STRING_TYPE(out);
@@ -406,7 +441,6 @@ static VALUE Buffer_read(int argc, VALUE* argv, VALUE self)
406
441
  return out;
407
442
  }
408
443
 
409
- #ifndef DISABLE_BUFFER_READ_TO_S_OPTIMIZE
410
444
  if(!msgpack_buffer_has_io(b) && out == Qnil &&
411
445
  msgpack_buffer_all_readable_size(b) <= n) {
412
446
  /* same as to_s && clear; optimize */
@@ -419,7 +453,6 @@ static VALUE Buffer_read(int argc, VALUE* argv, VALUE self)
419
453
  return str;
420
454
  }
421
455
  }
422
- #endif
423
456
 
424
457
  MAKE_EMPTY_STRING(out);
425
458
  read_until_eof(b, out, n);
@@ -433,32 +466,32 @@ static VALUE Buffer_read(int argc, VALUE* argv, VALUE self)
433
466
 
434
467
  static VALUE Buffer_to_str(VALUE self)
435
468
  {
436
- BUFFER(self, b);
469
+ msgpack_buffer_t *b = MessagePack_Buffer_get(self);
437
470
  return msgpack_buffer_all_as_string(b);
438
471
  }
439
472
 
440
473
  static VALUE Buffer_to_a(VALUE self)
441
474
  {
442
- BUFFER(self, b);
475
+ msgpack_buffer_t *b = MessagePack_Buffer_get(self);
443
476
  return msgpack_buffer_all_as_string_array(b);
444
477
  }
445
478
 
446
479
  static VALUE Buffer_flush(VALUE self)
447
480
  {
448
- BUFFER(self, b);
481
+ msgpack_buffer_t *b = MessagePack_Buffer_get(self);
449
482
  msgpack_buffer_flush(b);
450
483
  return self;
451
484
  }
452
485
 
453
486
  static VALUE Buffer_io(VALUE self)
454
487
  {
455
- BUFFER(self, b);
488
+ msgpack_buffer_t *b = MessagePack_Buffer_get(self);
456
489
  return b->io;
457
490
  }
458
491
 
459
492
  static VALUE Buffer_close(VALUE self)
460
493
  {
461
- BUFFER(self, b);
494
+ msgpack_buffer_t *b = MessagePack_Buffer_get(self);
462
495
  if(b->io != Qnil) {
463
496
  return rb_funcall(b->io, s_close, 0);
464
497
  }
@@ -467,9 +500,9 @@ static VALUE Buffer_close(VALUE self)
467
500
 
468
501
  static VALUE Buffer_write_to(VALUE self, VALUE io)
469
502
  {
470
- BUFFER(self, b);
503
+ msgpack_buffer_t *b = MessagePack_Buffer_get(self);
471
504
  size_t sz = msgpack_buffer_flush_to_io(b, io, s_write, true);
472
- return ULONG2NUM(sz);
505
+ return SIZET2NUM(sz);
473
506
  }
474
507
 
475
508
  void MessagePack_Buffer_module_init(VALUE mMessagePack)
@@ -479,6 +512,11 @@ void MessagePack_Buffer_module_init(VALUE mMessagePack)
479
512
  s_write = rb_intern("write");
480
513
  s_append = rb_intern("<<");
481
514
  s_close = rb_intern("close");
515
+ s_at_owner = rb_intern("@owner");
516
+
517
+ sym_read_reference_threshold = ID2SYM(rb_intern("read_reference_threshold"));
518
+ sym_write_reference_threshold = ID2SYM(rb_intern("write_reference_threshold"));
519
+ sym_io_buffer_size = ID2SYM(rb_intern("io_buffer_size"));
482
520
 
483
521
  msgpack_buffer_static_init();
484
522
 
data/ext/msgpack/compat.h CHANGED
@@ -20,117 +20,7 @@
20
20
 
21
21
  #include <stdbool.h>
22
22
  #include "ruby.h"
23
-
24
- #if defined(HAVE_RUBY_ST_H)
25
- # include "ruby/st.h" /* ruby hash on Ruby 1.9 */
26
- #elif defined(HAVE_ST_H)
27
- # include "st.h" /* ruby hash on Ruby 1.8 */
28
- #endif
29
-
30
-
31
- /*
32
- * ZALLOC_N (ruby 2.2 or later)
33
- */
34
- #ifndef RB_ZALLOC_N
35
- # define RB_ZALLOC_N(type,n) ((type*)ruby_xcalloc((size_t)(n),sizeof(type)))
36
- #endif
37
- #ifndef ZALLOC_N
38
- # define ZALLOC_N(type,n) RB_ZALLOC_N(type,n)
39
- #endif
40
-
41
- /*
42
- * COMPAT_HAVE_ENCODING
43
- */
44
- #ifdef HAVE_RUBY_ENCODING_H
45
- # include "ruby/encoding.h"
46
- # define COMPAT_HAVE_ENCODING
47
- #endif
48
-
49
- #if defined(__MACRUBY__) /* MacRuby */
50
- # undef COMPAT_HAVE_ENCODING
51
- #endif
52
-
53
-
54
- /*
55
- * define STR_DUP_LIKELY_DOES_COPY
56
- * check rb_str_dup actually copies the string or not
57
- */
58
- #if defined(RUBY_VM) && defined(FL_ALL) && defined(FL_USER1) && defined(FL_USER3) /* MRI 1.9 */
59
- # define STR_DUP_LIKELY_DOES_COPY(str) FL_ALL(str, FL_USER1|FL_USER3) /* same as STR_ASSOC_P(str) */
60
-
61
- #elif defined(FL_TEST) && defined(ELTS_SHARED) /* MRI 1.8 */
62
- # define STR_DUP_LIKELY_DOES_COPY(str) (!FL_TEST(str, ELTS_SHARED))
63
-
64
- //#elif defined(RUBINIUS) || defined(JRUBY) /* Rubinius and JRuby */
65
- #else
66
- # define STR_DUP_LIKELY_DOES_COPY(str) (1)
67
-
68
- #endif
69
-
70
-
71
- /*
72
- * SIZET2NUM
73
- */
74
- #ifndef SIZET2NUM /* MRI 1.8 */
75
- # define SIZET2NUM(v) ULL2NUM(v)
76
- #endif
77
-
78
-
79
- /*
80
- * rb_errinfo()
81
- */
82
- #if defined(RUBY_VM) /* MRI 1.9 */
83
- # define COMPAT_RERAISE rb_exc_raise(rb_errinfo())
84
-
85
- #elif defined(JRUBY) /* JRuby */
86
- # define COMPAT_RERAISE rb_exc_raise(rb_gv_get("$!"))
87
-
88
- #else /* MRI 1.8 and Rubinius */
89
- # define COMPAT_RERAISE rb_exc_raise(ruby_errinfo)
90
- #endif
91
-
92
-
93
- /*
94
- * RBIGNUM_POSITIVE_P
95
- */
96
- #ifndef RBIGNUM_POSITIVE_P
97
- # if defined(RUBINIUS) /* Rubinius <= v1.2.3 */
98
- # define RBIGNUM_POSITIVE_P(b) (rb_funcall(b, rb_intern(">="), 1, INT2FIX(0)) == Qtrue)
99
-
100
- # elif defined(JRUBY) /* JRuby */
101
- # define RBIGNUM_POSITIVE_P(b) (rb_funcall(b, rb_intern(">="), 1, INT2FIX(0)) == Qtrue)
102
- # define rb_big2ull(b) rb_num2ull(b)
103
- /*#define rb_big2ll(b) rb_num2ll(b)*/
104
-
105
- # else /* MRI 1.8 */
106
- # define RBIGNUM_POSITIVE_P(b) (RBIGNUM(b)->sign)
107
- # endif
108
- #endif
109
-
110
-
111
- /*
112
- * RSTRING_PTR, RSTRING_LEN
113
- */
114
- #ifndef RSTRING_PTR /* MRI 1.8.5 */
115
- # define RSTRING_PTR(s) (RSTRING(s)->ptr)
116
- #endif
117
-
118
- #ifndef RSTRING_LEN /* MRI 1.8.5 */
119
- # define RSTRING_LEN(s) (RSTRING(s)->len)
120
- #endif
121
-
122
-
123
- /*
124
- * RSTRUCT_GET
125
- */
126
- #ifndef RSTRUCT_GET
127
- # ifdef RSTRUCT_PTR /* MRI <= 2.0.0 */
128
- # define RSTRUCT_GET(st, idx) (RSTRUCT_PTR(st)[idx])
129
- # else /* Rubinius */
130
- # define RSTRUCT_GET(st, idx) (rb_struct_aref(st, INT2FIX(idx)))
131
- # endif
132
- #endif
133
-
23
+ #include "ruby/encoding.h"
134
24
 
135
25
  #endif
136
26
 
@@ -2,27 +2,54 @@ require 'mkmf'
2
2
 
3
3
  have_header("ruby/st.h")
4
4
  have_header("st.h")
5
- have_func("rb_str_replace", ["ruby.h"])
6
- have_func("rb_intern_str", ["ruby.h"])
7
- have_func("rb_sym2str", ["ruby.h"])
8
- have_func("rb_str_intern", ["ruby.h"])
9
- have_func("rb_block_lambda", ["ruby.h"])
10
- have_func("rb_hash_dup", ["ruby.h"])
11
- have_func("rb_hash_clear", ["ruby.h"])
5
+ have_func("rb_enc_interned_str", "ruby.h") # Ruby 3.0+
6
+ have_func("rb_hash_new_capa", "ruby.h") # Ruby 3.2+
12
7
 
13
8
  unless RUBY_PLATFORM.include? 'mswin'
14
- $CFLAGS << %[ -I.. -Wall -O3 -g -std=gnu99]
9
+ $CFLAGS << %[ -I.. -Wall -O3 #{RbConfig::CONFIG["debugflags"]} -std=gnu99]
15
10
  end
16
- #$CFLAGS << %[ -DDISABLE_RMEM]
17
- #$CFLAGS << %[ -DDISABLE_RMEM_REUSE_INTERNAL_FRAGMENT]
18
- #$CFLAGS << %[ -DDISABLE_BUFFER_READ_REFERENCE_OPTIMIZE]
19
- #$CFLAGS << %[ -DDISABLE_BUFFER_READ_TO_S_OPTIMIZE]
20
-
21
- if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
22
- # msgpack-ruby doesn't modify data came from RSTRING_PTR(str)
23
- $CFLAGS << %[ -DRSTRING_NOT_MODIFIED]
24
- # Rubinius C extensions don't grab GVL while rmem is not thread safe
25
- $CFLAGS << %[ -DDISABLE_RMEM]
11
+
12
+ if RUBY_VERSION.start_with?('3.0.')
13
+ # https://bugs.ruby-lang.org/issues/18772
14
+ $CFLAGS << ' -DRB_ENC_INTERNED_STR_NULL_CHECK=1 '
15
+ end
16
+
17
+ # checking if Hash#[]= (rb_hash_aset) dedupes string keys (Ruby 2.6+)
18
+ h = {}
19
+ x = {}
20
+ r = rand.to_s
21
+ h[%W(#{r}).join('')] = :foo
22
+ x[%W(#{r}).join('')] = :foo
23
+ if x.keys[0].equal?(h.keys[0])
24
+ $CFLAGS << ' -DHASH_ASET_DEDUPE=1 '
25
+ else
26
+ $CFLAGS << ' -DHASH_ASET_DEDUPE=0 '
27
+ end
28
+
29
+
30
+ # checking if String#-@ (str_uminus) dedupes... ' (Ruby 2.5+)
31
+ begin
32
+ a = -(%w(t e s t).join)
33
+ b = -(%w(t e s t).join)
34
+ if a.equal?(b)
35
+ $CFLAGS << ' -DSTR_UMINUS_DEDUPE=1 '
36
+ else
37
+ $CFLAGS += ' -DSTR_UMINUS_DEDUPE=0 '
38
+ end
39
+ rescue NoMethodError
40
+ $CFLAGS << ' -DSTR_UMINUS_DEDUPE=0 '
41
+ end
42
+
43
+ # checking if String#-@ (str_uminus) directly interns frozen strings... ' (Ruby 3.0+)
44
+ begin
45
+ s = rand.to_s.freeze
46
+ if (-s).equal?(s) && (-s.dup).equal?(s)
47
+ $CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=1 '
48
+ else
49
+ $CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=0 '
50
+ end
51
+ rescue NoMethodError
52
+ $CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=0 '
26
53
  end
27
54
 
28
55
  if warnflags = CONFIG['warnflags']
@@ -30,4 +57,3 @@ if warnflags = CONFIG['warnflags']
30
57
  end
31
58
 
32
59
  create_makefile('msgpack/msgpack')
33
-