msgpack 1.6.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
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