msgpack 1.6.0 → 1.7.0

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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +14 -0
  3. data/README.md +27 -0
  4. data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +4 -9
  5. data/ext/java/org/msgpack/jruby/Factory.java +1 -1
  6. data/ext/java/org/msgpack/jruby/Packer.java +3 -0
  7. data/ext/java/org/msgpack/jruby/Unpacker.java +3 -0
  8. data/ext/msgpack/buffer.c +9 -12
  9. data/ext/msgpack/buffer.h +2 -10
  10. data/ext/msgpack/buffer_class.c +4 -4
  11. data/ext/msgpack/extconf.rb +3 -15
  12. data/ext/msgpack/factory_class.c +1 -1
  13. data/ext/msgpack/packer.c +1 -0
  14. data/ext/msgpack/packer_class.c +9 -19
  15. data/ext/msgpack/rbinit.c +1 -1
  16. data/ext/msgpack/rmem.c +3 -4
  17. data/ext/msgpack/unpacker.c +8 -20
  18. data/ext/msgpack/unpacker.h +0 -4
  19. data/ext/msgpack/unpacker_class.c +11 -21
  20. data/lib/msgpack/buffer.rb +9 -0
  21. data/lib/msgpack/factory.rb +41 -53
  22. data/lib/msgpack/packer.rb +4 -0
  23. data/lib/msgpack/unpacker.rb +4 -0
  24. data/lib/msgpack/version.rb +1 -1
  25. data/lib/msgpack.rb +1 -0
  26. data/msgpack.gemspec +6 -3
  27. metadata +19 -48
  28. data/.github/workflows/ci.yaml +0 -57
  29. data/.gitignore +0 -23
  30. data/.rubocop.yml +0 -36
  31. data/Gemfile +0 -9
  32. data/Rakefile +0 -70
  33. data/appveyor.yml +0 -18
  34. data/bench/bench.rb +0 -78
  35. data/bin/console +0 -8
  36. data/doclib/msgpack/buffer.rb +0 -193
  37. data/doclib/msgpack/core_ext.rb +0 -101
  38. data/doclib/msgpack/error.rb +0 -19
  39. data/doclib/msgpack/extension_value.rb +0 -9
  40. data/doclib/msgpack/factory.rb +0 -145
  41. data/doclib/msgpack/packer.rb +0 -209
  42. data/doclib/msgpack/time.rb +0 -22
  43. data/doclib/msgpack/timestamp.rb +0 -44
  44. data/doclib/msgpack/unpacker.rb +0 -183
  45. data/doclib/msgpack.rb +0 -87
  46. data/msgpack.org.md +0 -46
  47. data/spec/bigint_spec.rb +0 -26
  48. data/spec/cases.json +0 -1
  49. data/spec/cases.msg +0 -0
  50. data/spec/cases_compact.msg +0 -0
  51. data/spec/cases_spec.rb +0 -39
  52. data/spec/cruby/buffer_io_spec.rb +0 -255
  53. data/spec/cruby/buffer_packer.rb +0 -29
  54. data/spec/cruby/buffer_spec.rb +0 -592
  55. data/spec/cruby/buffer_unpacker.rb +0 -19
  56. data/spec/cruby/unpacker_spec.rb +0 -70
  57. data/spec/ext_value_spec.rb +0 -99
  58. data/spec/exttypes.rb +0 -51
  59. data/spec/factory_spec.rb +0 -706
  60. data/spec/format_spec.rb +0 -301
  61. data/spec/jruby/benchmarks/shootout_bm.rb +0 -73
  62. data/spec/jruby/benchmarks/symbolize_keys_bm.rb +0 -25
  63. data/spec/jruby/unpacker_spec.rb +0 -186
  64. data/spec/msgpack_spec.rb +0 -214
  65. data/spec/pack_spec.rb +0 -61
  66. data/spec/packer_spec.rb +0 -575
  67. data/spec/random_compat.rb +0 -24
  68. data/spec/spec_helper.rb +0 -72
  69. data/spec/timestamp_spec.rb +0 -159
  70. data/spec/unpack_spec.rb +0 -57
  71. data/spec/unpacker_spec.rb +0 -869
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bb08f890b2d9a36312600e284933cd0de93a00a6b949507bfc3d7c5c7eab1638
4
- data.tar.gz: 11e536f8bde329edbc966e5e1050134350024f89f1cb911878f86fd59ff1fc79
3
+ metadata.gz: 1414cbfba4f8503d851d6084ef42eb39cfe652d0cadedcf75523e5f472bf425b
4
+ data.tar.gz: a863d42ac8880a77afe84398b103f4b27d0782db70dd31aad4c785759bcfa20f
5
5
  SHA512:
6
- metadata.gz: 9491cdf494d1826cce7f5e420d73a65ce88c029e060338d9c28fb1e20e4d01dc71fdb46b91859d025bbcc8f5a0471100b171cb9b3bac5fed6f0f0715fd76abb2
7
- data.tar.gz: 8d0b4db4f93ebf98063f275c0629648ab9316c7cc3cd81738f7f083c6ed4c47fc647c2fc5df1308089b96c36d7e13944028e75bae7e5897b5bb357701c0bcfd9
6
+ metadata.gz: 9ffd9d63c8354684cedfcd682beaf525823646aa9b0b6854175e81f1879eea22fcbf3fba560744210129001263ff80b2fc83ebc99a7405d9f03570921567b1d7
7
+ data.tar.gz: 4bd0b851caa3d39c05e32d6d90f9f52c376aae4f799247d3d9569db9bc273171c85973e6229de6b9c55e956e2f8c9790a9a4c23e8482944233ed499b421f30c6
data/ChangeLog CHANGED
@@ -1,3 +1,17 @@
1
+ 2023-03-29 1.7.0:
2
+
3
+ * Fix a possible double-free issue when GC triggers inside `_msgpack_rmem_alloc2`.
4
+ * `Unpacker#feed` now always directly read in provided strings instead of copying content in its buffer.
5
+ * `Unpacker#feed` is now an alias of `Unpacker#feed_reference`.
6
+ * Implement `Factory::Pool#unpacker` and `Factory::Pool#packer` to allow for more precise serialization.
7
+ * Require Ruby 2.5+.
8
+
9
+ 2023-03-03 1.6.1:
10
+
11
+ * Undefine `#clone` and `#dup` on `MessagePack::Buffer`, `MessagePack::Packer` and `MessagePack::Unpacker`.
12
+ These methods were never intended, and using them could cause leaks or crashes or worse.
13
+ * Fix a possible GC crash when GC trigger inside `MessagePack::Buffer.new` (#314).
14
+
1
15
  2022-09-30 1.6.0:
2
16
 
3
17
  * Fix a potential use-after-free bug in Buffer_free when accessing a packer or unpacker buffer.
data/README.md CHANGED
@@ -211,6 +211,33 @@ factory.register_type(
211
211
  factory.load(factory.dump(Point.new(12, 34))) # => #<struct Point x=12, y=34>
212
212
  ```
213
213
 
214
+ ## Pooling
215
+
216
+ Creating `Packer` and `Unpacker` objects is expensive. For best performance it is preferable to re-use these objects.
217
+
218
+ `MessagePack::Factory#pool` makes that easier:
219
+
220
+ ```ruby
221
+ factory = MessagePack::Factory.new
222
+ factory.register_type(
223
+ 0x01,
224
+ Point,
225
+ packer: ->(point, packer) {
226
+ packer.write(point.x)
227
+ packer.write(point.y)
228
+ },
229
+ unpacker: ->(unpacker) {
230
+ x = unpacker.read
231
+ y = unpacker.read
232
+ Point.new(x, y)
233
+ },
234
+ recursive: true,
235
+ )
236
+ pool = factory.pool(5) # The pool size should match the number of threads expected to use the factory concurrently.
237
+
238
+ pool.load(pool.dump(Point.new(12, 34))) # => #<struct Point x=12, y=34>
239
+ ```
240
+
214
241
  ## Buffer API
215
242
 
216
243
  MessagePack for Ruby provides a buffer API so that you can read or write data by hand, not via Packer or Unpacker API.
@@ -18,22 +18,17 @@ public class ExtensionRegistry {
18
18
  private final ExtensionEntry[] extensionsByTypeId;
19
19
 
20
20
  public ExtensionRegistry() {
21
- this(new HashMap<RubyModule, ExtensionEntry>());
21
+ this(new HashMap<RubyModule, ExtensionEntry>(), new ExtensionEntry[256]);
22
22
  }
23
23
 
24
- private ExtensionRegistry(Map<RubyModule, ExtensionEntry> extensionsByModule) {
24
+ private ExtensionRegistry(Map<RubyModule, ExtensionEntry> extensionsByModule, ExtensionEntry[] extensionsByTypeId) {
25
25
  this.extensionsByModule = new HashMap<RubyModule, ExtensionEntry>(extensionsByModule);
26
26
  this.extensionsByAncestor = new HashMap<RubyModule, ExtensionEntry>();
27
- this.extensionsByTypeId = new ExtensionEntry[256];
28
- for (ExtensionEntry entry : extensionsByModule.values()) {
29
- if (entry.hasUnpacker()) {
30
- extensionsByTypeId[entry.getTypeId() + 128] = entry;
31
- }
32
- }
27
+ this.extensionsByTypeId = extensionsByTypeId.clone();
33
28
  }
34
29
 
35
30
  public ExtensionRegistry dup() {
36
- return new ExtensionRegistry(extensionsByModule);
31
+ return new ExtensionRegistry(extensionsByModule, extensionsByTypeId);
37
32
  }
38
33
 
39
34
  public IRubyObject toInternalPackerRegistry(ThreadContext ctx) {
@@ -92,7 +92,7 @@ public class Factory extends RubyObject {
92
92
  RubyHash options = null;
93
93
 
94
94
  if (isFrozen()) {
95
- throw runtime.newRuntimeError("can't modify frozen Factory");
95
+ throw runtime.newFrozenError("MessagePack::Factory");
96
96
  }
97
97
 
98
98
  if (args.length == 2) {
@@ -96,6 +96,9 @@ public class Packer extends RubyObject {
96
96
  @JRubyMethod(name = "register_type", required = 2, optional = 1)
97
97
  public IRubyObject registerType(ThreadContext ctx, IRubyObject[] args, final Block block) {
98
98
  Ruby runtime = ctx.runtime;
99
+ if (isFrozen()) {
100
+ throw runtime.newFrozenError("MessagePack::Packer");
101
+ }
99
102
  IRubyObject type = args[0];
100
103
  IRubyObject mod = args[1];
101
104
 
@@ -130,6 +130,9 @@ public class Unpacker extends RubyObject {
130
130
  @JRubyMethod(name = "register_type", required = 1, optional = 2)
131
131
  public IRubyObject registerType(ThreadContext ctx, IRubyObject[] args, final Block block) {
132
132
  Ruby runtime = ctx.runtime;
133
+ if (isFrozen()) {
134
+ throw runtime.newFrozenError("MessagePack::Unpacker");
135
+ }
133
136
  IRubyObject type = args[0];
134
137
 
135
138
  RubyModule extModule;
data/ext/msgpack/buffer.c CHANGED
@@ -19,10 +19,6 @@
19
19
  #include "buffer.h"
20
20
  #include "rmem.h"
21
21
 
22
- #ifndef HAVE_RB_STR_REPLACE
23
- static ID s_replace;
24
- #endif
25
-
26
22
  int msgpack_rb_encindex_utf8;
27
23
  int msgpack_rb_encindex_usascii;
28
24
  int msgpack_rb_encindex_ascii8bit;
@@ -40,10 +36,6 @@ void msgpack_buffer_static_init(void)
40
36
  msgpack_rb_encindex_ascii8bit = rb_ascii8bit_encindex();
41
37
 
42
38
  msgpack_rmem_init(&s_rmem);
43
-
44
- #ifndef HAVE_RB_STR_REPLACE
45
- s_replace = rb_intern("replace");
46
- #endif
47
39
  }
48
40
 
49
41
  void msgpack_buffer_static_destroy(void)
@@ -66,7 +58,11 @@ void msgpack_buffer_init(msgpack_buffer_t* b)
66
58
  static void _msgpack_buffer_chunk_destroy(msgpack_buffer_chunk_t* c)
67
59
  {
68
60
  if(c->mem != NULL) {
69
- if(!msgpack_rmem_free(&s_rmem, c->mem)) {
61
+ if(c->rmem) {
62
+ if(!msgpack_rmem_free(&s_rmem, c->mem)) {
63
+ rb_bug("Failed to free an rmem pointer, memory leak?");
64
+ }
65
+ } else {
70
66
  xfree(c->mem);
71
67
  }
72
68
  /* no needs to update rmem_owner because chunks will not be
@@ -330,14 +326,12 @@ static inline void _msgpack_buffer_append_reference(msgpack_buffer_t* b, VALUE s
330
326
 
331
327
  void _msgpack_buffer_append_long_string(msgpack_buffer_t* b, VALUE string)
332
328
  {
333
- size_t length = RSTRING_LEN(string);
334
-
335
329
  if(b->io != Qnil) {
336
330
  msgpack_buffer_flush(b);
337
331
  if (ENCODING_GET(string) == msgpack_rb_encindex_ascii8bit) {
338
332
  rb_funcall(b->io, b->io_write_all_method, 1, string);
339
333
  } else {
340
- msgpack_buffer_append(b, RSTRING_PTR(string), length);
334
+ msgpack_buffer_append(b, RSTRING_PTR(string), RSTRING_LEN(string));
341
335
  }
342
336
  } else {
343
337
  _msgpack_buffer_append_reference(b, string);
@@ -349,6 +343,8 @@ static inline void* _msgpack_buffer_chunk_malloc(
349
343
  size_t required_size, size_t* allocated_size)
350
344
  {
351
345
  if(required_size <= MSGPACK_RMEM_PAGE_SIZE) {
346
+ c->rmem = true;
347
+
352
348
  if((size_t)(b->rmem_end - b->rmem_last) < required_size) {
353
349
  /* alloc new rmem page */
354
350
  *allocated_size = MSGPACK_RMEM_PAGE_SIZE;
@@ -379,6 +375,7 @@ static inline void* _msgpack_buffer_chunk_malloc(
379
375
  *allocated_size = required_size;
380
376
  void* mem = xmalloc(required_size);
381
377
  c->mem = mem;
378
+ c->rmem = false;
382
379
  return mem;
383
380
  }
384
381
 
data/ext/msgpack/buffer.h CHANGED
@@ -78,6 +78,7 @@ struct msgpack_buffer_chunk_t {
78
78
  void* mem;
79
79
  msgpack_buffer_chunk_t* next;
80
80
  VALUE mapped_string; /* RBString or NO_MAPPED_STRING */
81
+ bool rmem;
81
82
  };
82
83
 
83
84
  union msgpack_buffer_cast_block_t {
@@ -267,14 +268,7 @@ static inline size_t msgpack_buffer_append_string(msgpack_buffer_t* b, VALUE str
267
268
  static inline size_t msgpack_buffer_append_string_reference(msgpack_buffer_t* b, VALUE string)
268
269
  {
269
270
  size_t length = RSTRING_LEN(string);
270
-
271
- if(length > MSGPACK_BUFFER_STRING_WRITE_REFERENCE_MINIMUM) {
272
- _msgpack_buffer_append_long_string(b, string);
273
-
274
- } else {
275
- msgpack_buffer_append(b, RSTRING_PTR(string), length);
276
- }
277
-
271
+ _msgpack_buffer_append_long_string(b, string);
278
272
  return length;
279
273
  }
280
274
 
@@ -479,7 +473,6 @@ static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, size_
479
473
  result = rb_str_new(b->read_buffer, length);
480
474
  }
481
475
 
482
- #if STR_UMINUS_DEDUPE
483
476
  if (will_be_frozen) {
484
477
  #if STR_UMINUS_DEDUPE_FROZEN
485
478
  // Starting from MRI 2.8 it is preferable to freeze the string
@@ -491,7 +484,6 @@ static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, size_
491
484
  // frozen.
492
485
  result = rb_funcall(result, s_uminus, 0);
493
486
  }
494
- #endif // STR_UMINUS_DEDUPE
495
487
  _msgpack_buffer_consumed(b, length);
496
488
  return result;
497
489
 
@@ -56,7 +56,7 @@ static size_t Buffer_memsize(const void *data)
56
56
  return sizeof(msgpack_buffer_t) + msgpack_buffer_memsize(data);
57
57
  }
58
58
 
59
- const rb_data_type_t buffer_data_type = {
59
+ static const rb_data_type_t buffer_data_type = {
60
60
  .wrap_struct_name = "msgpack:buffer",
61
61
  .function = {
62
62
  .dmark = msgpack_buffer_mark,
@@ -66,10 +66,10 @@ const rb_data_type_t buffer_data_type = {
66
66
  .flags = RUBY_TYPED_FREE_IMMEDIATELY
67
67
  };
68
68
 
69
- const rb_data_type_t buffer_view_data_type = {
69
+ static const rb_data_type_t buffer_view_data_type = {
70
70
  .wrap_struct_name = "msgpack:buffer_view",
71
71
  .function = {
72
- .dmark = msgpack_buffer_mark,
72
+ .dmark = NULL,
73
73
  .dfree = NULL,
74
74
  .dsize = NULL,
75
75
  },
@@ -91,8 +91,8 @@ static VALUE Buffer_alloc(VALUE klass)
91
91
  {
92
92
  msgpack_buffer_t* b;
93
93
  VALUE buffer = TypedData_Make_Struct(klass, msgpack_buffer_t, &buffer_data_type, b);
94
- rb_ivar_set(buffer, s_at_owner, Qnil);
95
94
  msgpack_buffer_init(b);
95
+ rb_ivar_set(buffer, s_at_owner, Qnil);
96
96
  return buffer;
97
97
  }
98
98
 
@@ -5,11 +5,13 @@ have_header("st.h")
5
5
  have_func("rb_enc_interned_str", "ruby.h") # Ruby 3.0+
6
6
  have_func("rb_hash_new_capa", "ruby.h") # Ruby 3.2+
7
7
 
8
+ $CFLAGS << " -fvisibility=hidden "
9
+
8
10
  unless RUBY_PLATFORM.include? 'mswin'
9
11
  $CFLAGS << %[ -I.. -Wall -O3 #{RbConfig::CONFIG["debugflags"]} -std=gnu99]
10
12
  end
11
13
 
12
- if RUBY_VERSION.start_with?('3.0.')
14
+ if RUBY_VERSION.start_with?('3.0.') && RUBY_VERSION <= '3.0.5'
13
15
  # https://bugs.ruby-lang.org/issues/18772
14
16
  $CFLAGS << ' -DRB_ENC_INTERNED_STR_NULL_CHECK=1 '
15
17
  end
@@ -26,20 +28,6 @@ else
26
28
  $CFLAGS << ' -DHASH_ASET_DEDUPE=0 '
27
29
  end
28
30
 
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
31
  # checking if String#-@ (str_uminus) directly interns frozen strings... ' (Ruby 3.0+)
44
32
  begin
45
33
  s = rand.to_s.freeze
@@ -212,7 +212,7 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
212
212
  VALUE packer_proc, unpacker_proc;
213
213
 
214
214
  if (OBJ_FROZEN(self)) {
215
- rb_raise(rb_eRuntimeError, "can't modify frozen Factory");
215
+ rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Factory");
216
216
  }
217
217
 
218
218
  switch (argc) {
data/ext/msgpack/packer.c CHANGED
@@ -43,6 +43,7 @@ void msgpack_packer_mark(msgpack_packer_t* pk)
43
43
  /* See MessagePack_Buffer_wrap */
44
44
  /* msgpack_buffer_mark(PACKER_BUFFER_(pk)); */
45
45
  rb_gc_mark(pk->buffer_ref);
46
+ rb_gc_mark(pk->to_msgpack_arg);
46
47
  }
47
48
 
48
49
  void msgpack_packer_reset(msgpack_packer_t* pk)
@@ -47,6 +47,7 @@ static void Packer_free(void *ptr)
47
47
  static void Packer_mark(void *ptr)
48
48
  {
49
49
  msgpack_packer_t* pk = ptr;
50
+ msgpack_buffer_mark(pk);
50
51
  msgpack_packer_mark(pk);
51
52
  msgpack_packer_ext_registry_mark(&pk->ext_registry);
52
53
  }
@@ -106,7 +107,7 @@ VALUE MessagePack_Packer_initialize(int argc, VALUE* argv, VALUE self)
106
107
  msgpack_packer_t *pk = MessagePack_Packer_get(self);
107
108
 
108
109
  msgpack_packer_ext_registry_init(&pk->ext_registry);
109
- pk->buffer_ref = MessagePack_Buffer_wrap(PACKER_BUFFER_(pk), self);
110
+ pk->buffer_ref = Qnil;
110
111
 
111
112
  MessagePack_Buffer_set_options(PACKER_BUFFER_(pk), io, options);
112
113
 
@@ -129,6 +130,9 @@ static VALUE Packer_compatibility_mode_p(VALUE self)
129
130
  static VALUE Packer_buffer(VALUE self)
130
131
  {
131
132
  msgpack_packer_t *pk = MessagePack_Packer_get(self);
133
+ if (!RTEST(pk->buffer_ref)) {
134
+ pk->buffer_ref = MessagePack_Buffer_wrap(PACKER_BUFFER_(pk), self);
135
+ }
132
136
  return pk->buffer_ref;
133
137
  }
134
138
 
@@ -334,18 +338,6 @@ static VALUE Packer_write_to(VALUE self, VALUE io)
334
338
  return SIZET2NUM(sz);
335
339
  }
336
340
 
337
- //static VALUE Packer_append(VALUE self, VALUE string_or_buffer)
338
- //{
339
- // msgpack_packer_t *pk = MessagePack_Packer_get(self);
340
- //
341
- // // TODO if string_or_buffer is a Buffer
342
- // VALUE string = string_or_buffer;
343
- //
344
- // msgpack_buffer_append_string(PACKER_BUFFER_(pk), string);
345
- //
346
- // return self;
347
- //}
348
-
349
341
  static VALUE Packer_registered_types_internal(VALUE self)
350
342
  {
351
343
  msgpack_packer_t *pk = MessagePack_Packer_get(self);
@@ -357,6 +349,10 @@ static VALUE Packer_registered_types_internal(VALUE self)
357
349
 
358
350
  static VALUE Packer_register_type(int argc, VALUE* argv, VALUE self)
359
351
  {
352
+ if (OBJ_FROZEN(self)) {
353
+ rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Packer");
354
+ }
355
+
360
356
  msgpack_packer_t *pk = MessagePack_Packer_get(self);
361
357
 
362
358
  int ext_type;
@@ -463,15 +459,9 @@ void MessagePack_Packer_module_init(VALUE mMessagePack)
463
459
  rb_define_method(cMessagePack_Packer, "to_str", Packer_to_str, 0);
464
460
  rb_define_alias(cMessagePack_Packer, "to_s", "to_str");
465
461
  rb_define_method(cMessagePack_Packer, "to_a", Packer_to_a, 0);
466
- //rb_define_method(cMessagePack_Packer, "append", Packer_append, 1);
467
- //rb_define_alias(cMessagePack_Packer, "<<", "append");
468
462
 
469
463
  rb_define_private_method(cMessagePack_Packer, "registered_types_internal", Packer_registered_types_internal, 0);
470
464
  rb_define_method(cMessagePack_Packer, "register_type", Packer_register_type, -1);
471
465
 
472
- //s_packer_value = MessagePack_Packer_alloc(cMessagePack_Packer);
473
- //rb_gc_register_address(&s_packer_value);
474
- //Data_Get_Struct(s_packer_value, msgpack_packer_t, s_packer);
475
-
476
466
  rb_define_method(cMessagePack_Packer, "full_pack", Packer_full_pack, 0);
477
467
  }
data/ext/msgpack/rbinit.c CHANGED
@@ -22,7 +22,7 @@
22
22
  #include "factory_class.h"
23
23
  #include "extension_value_class.h"
24
24
 
25
- void Init_msgpack(void)
25
+ RUBY_FUNC_EXPORTED void Init_msgpack(void)
26
26
  {
27
27
  VALUE mMessagePack = rb_define_module("MessagePack");
28
28
 
data/ext/msgpack/rmem.c CHANGED
@@ -65,11 +65,10 @@ void* _msgpack_rmem_alloc2(msgpack_rmem_t* pm)
65
65
  /* allocate new chunk */
66
66
  c = pm->array_last++;
67
67
 
68
- /* move to head */
69
- msgpack_rmem_chunk_t tmp = pm->head;
70
- pm->head = *c;
71
- *c = tmp;
68
+ /* move head to array */
69
+ *c = pm->head;
72
70
 
71
+ pm->head.pages = NULL; /* make sure we don't point to another chunk's pages in case xmalloc triggers GC */
73
72
  pm->head.mask = 0xffffffff & (~1); /* "& (~1)" means first chunk is already allocated */
74
73
  pm->head.pages = xmalloc(MSGPACK_RMEM_PAGE_SIZE * 32);
75
74
 
@@ -20,19 +20,17 @@
20
20
  #include "rmem.h"
21
21
  #include "extension_value_class.h"
22
22
 
23
- #if !defined(DISABLE_UNPACKER_STACK_RMEM) && \
24
- MSGPACK_UNPACKER_STACK_CAPACITY * MSGPACK_UNPACKER_STACK_SIZE <= MSGPACK_RMEM_PAGE_SIZE
25
- #define UNPACKER_STACK_RMEM
26
- #endif
23
+ _Static_assert(
24
+ sizeof(msgpack_unpacker_stack_entry_t) * MSGPACK_UNPACKER_STACK_CAPACITY <= MSGPACK_RMEM_PAGE_SIZE,
25
+ "msgpack_unpacker_stack_entry_t is too big to fit MSGPACK_UNPACKER_STACK_CAPACITY in MSGPACK_RMEM_PAGE_SIZE"
26
+ );
27
27
 
28
28
  static int RAW_TYPE_STRING = 256;
29
29
  static int RAW_TYPE_BINARY = 257;
30
30
 
31
31
  static ID s_call;
32
32
 
33
- #ifdef UNPACKER_STACK_RMEM
34
33
  static msgpack_rmem_t s_stack_rmem;
35
- #endif
36
34
 
37
35
  #if !defined(HAVE_RB_HASH_NEW_CAPA)
38
36
  static inline VALUE rb_hash_new_capa(long capa)
@@ -43,18 +41,14 @@ static inline VALUE rb_hash_new_capa(long capa)
43
41
 
44
42
  void msgpack_unpacker_static_init(void)
45
43
  {
46
- #ifdef UNPACKER_STACK_RMEM
47
44
  msgpack_rmem_init(&s_stack_rmem);
48
- #endif
49
45
 
50
46
  s_call = rb_intern("call");
51
47
  }
52
48
 
53
49
  void msgpack_unpacker_static_destroy(void)
54
50
  {
55
- #ifdef UNPACKER_STACK_RMEM
56
51
  msgpack_rmem_destroy(&s_stack_rmem);
57
- #endif
58
52
  }
59
53
 
60
54
  #define HEAD_BYTE_REQUIRED 0xc1
@@ -62,13 +56,8 @@ void msgpack_unpacker_static_destroy(void)
62
56
  static inline msgpack_unpacker_stack_t* _msgpack_unpacker_new_stack(void) {
63
57
  msgpack_unpacker_stack_t *stack = ZALLOC(msgpack_unpacker_stack_t);
64
58
  stack->capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
65
- #ifdef UNPACKER_STACK_RMEM
66
59
  stack->data = msgpack_rmem_alloc(&s_stack_rmem);
67
60
  /*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
68
- #else
69
- /*uk->stack = calloc(MSGPACK_UNPACKER_STACK_CAPACITY, sizeof(msgpack_unpacker_stack_entry_t));*/
70
- stack->data = xmalloc(MSGPACK_UNPACKER_STACK_CAPACITY * sizeof(msgpack_unpacker_stack_entry_t));
71
- #endif
72
61
  return stack;
73
62
  }
74
63
 
@@ -85,11 +74,9 @@ void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
85
74
  }
86
75
 
87
76
  static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
88
- #ifdef UNPACKER_STACK_RMEM
89
- msgpack_rmem_free(&s_stack_rmem, stack->data);
90
- #else
91
- xfree(stack->data);
92
- #endif
77
+ if (!msgpack_rmem_free(&s_stack_rmem, stack->data)) {
78
+ rb_bug("Failed to free an rmem pointer, memory leak?");
79
+ }
93
80
  xfree(stack);
94
81
  }
95
82
 
@@ -120,6 +107,7 @@ void msgpack_unpacker_mark(msgpack_unpacker_t* uk)
120
107
  /* See MessagePack_Buffer_wrap */
121
108
  /* msgpack_buffer_mark(UNPACKER_BUFFER_(uk)); */
122
109
  rb_gc_mark(uk->buffer_ref);
110
+ rb_gc_mark(uk->self);
123
111
  }
124
112
 
125
113
  void _msgpack_unpacker_reset(msgpack_unpacker_t* uk)
@@ -21,9 +21,7 @@
21
21
  #include "buffer.h"
22
22
  #include "unpacker_ext_registry.h"
23
23
 
24
- #ifndef MSGPACK_UNPACKER_STACK_CAPACITY
25
24
  #define MSGPACK_UNPACKER_STACK_CAPACITY 128
26
- #endif
27
25
 
28
26
  struct msgpack_unpacker_t;
29
27
  typedef struct msgpack_unpacker_t msgpack_unpacker_t;
@@ -49,8 +47,6 @@ struct msgpack_unpacker_stack_t {
49
47
  msgpack_unpacker_stack_t *parent;
50
48
  };
51
49
 
52
- #define MSGPACK_UNPACKER_STACK_SIZE (8+4+8+8) /* assumes size_t <= 64bit, enum <= 32bit, VALUE <= 64bit */
53
-
54
50
  struct msgpack_unpacker_t {
55
51
  msgpack_buffer_t buffer;
56
52
  msgpack_unpacker_stack_t *stack;
@@ -51,6 +51,7 @@ static void Unpacker_free(void *ptr)
51
51
  static void Unpacker_mark(void *ptr)
52
52
  {
53
53
  msgpack_unpacker_t* uk = ptr;
54
+ msgpack_buffer_mark(uk);
54
55
  msgpack_unpacker_mark(uk);
55
56
  msgpack_unpacker_ext_registry_mark(uk->ext_registry);
56
57
  }
@@ -117,7 +118,7 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
117
118
 
118
119
  msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
119
120
 
120
- uk->buffer_ref = MessagePack_Buffer_wrap(UNPACKER_BUFFER_(uk), self);
121
+ uk->buffer_ref = Qnil;
121
122
 
122
123
  MessagePack_Buffer_set_options(UNPACKER_BUFFER_(uk), io, options);
123
124
 
@@ -177,6 +178,9 @@ NORETURN(static void raise_unpacker_error(int r))
177
178
  static VALUE Unpacker_buffer(VALUE self)
178
179
  {
179
180
  msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
181
+ if (!RTEST(uk->buffer_ref)) {
182
+ uk->buffer_ref = MessagePack_Buffer_wrap(UNPACKER_BUFFER_(uk), self);
183
+ }
180
184
  return uk->buffer_ref;
181
185
  }
182
186
 
@@ -245,18 +249,6 @@ static VALUE Unpacker_read_map_header(VALUE self)
245
249
  return ULONG2NUM(size); // long at least 32 bits
246
250
  }
247
251
 
248
-
249
- static VALUE Unpacker_feed(VALUE self, VALUE data)
250
- {
251
- msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
252
-
253
- StringValue(data);
254
-
255
- msgpack_buffer_append_string(UNPACKER_BUFFER_(uk), data);
256
-
257
- return self;
258
- }
259
-
260
252
  static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
261
253
  {
262
254
  msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
@@ -356,6 +348,10 @@ static VALUE Unpacker_registered_types_internal(VALUE self)
356
348
 
357
349
  static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
358
350
  {
351
+ if (OBJ_FROZEN(self)) {
352
+ rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Unpacker");
353
+ }
354
+
359
355
  msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
360
356
 
361
357
  int ext_type;
@@ -453,8 +449,8 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
453
449
  rb_define_method(cMessagePack_Unpacker, "skip_nil", Unpacker_skip_nil, 0);
454
450
  rb_define_method(cMessagePack_Unpacker, "read_array_header", Unpacker_read_array_header, 0);
455
451
  rb_define_method(cMessagePack_Unpacker, "read_map_header", Unpacker_read_map_header, 0);
456
- rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed, 1);
457
- rb_define_method(cMessagePack_Unpacker, "feed_reference", Unpacker_feed_reference, 1);
452
+ rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed_reference, 1);
453
+ rb_define_alias(cMessagePack_Unpacker, "feed_reference", "feed");
458
454
  rb_define_method(cMessagePack_Unpacker, "each", Unpacker_each, 0);
459
455
  rb_define_method(cMessagePack_Unpacker, "feed_each", Unpacker_feed_each, 1);
460
456
  rb_define_method(cMessagePack_Unpacker, "reset", Unpacker_reset, 0);
@@ -462,11 +458,5 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
462
458
  rb_define_private_method(cMessagePack_Unpacker, "registered_types_internal", Unpacker_registered_types_internal, 0);
463
459
  rb_define_method(cMessagePack_Unpacker, "register_type", Unpacker_register_type, -1);
464
460
 
465
- //s_unpacker_value = MessagePack_Unpacker_alloc(cMessagePack_Unpacker);
466
- //rb_gc_register_address(&s_unpacker_value);
467
- //Data_Get_Struct(s_unpacker_value, msgpack_unpacker_t, s_unpacker);
468
- /* prefer reference than copying */
469
- //msgpack_buffer_set_write_reference_threshold(UNPACKER_BUFFER_(s_unpacker), 0);
470
-
471
461
  rb_define_method(cMessagePack_Unpacker, "full_unpack", Unpacker_full_unpack, 0);
472
462
  }
@@ -0,0 +1,9 @@
1
+ module MessagePack
2
+ class Buffer
3
+ # see ext for other methods
4
+
5
+ # The semantic of duping a buffer is just too weird.
6
+ undef_method :dup
7
+ undef_method :clone
8
+ end
9
+ end