msgpack 1.6.0 → 1.7.2

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 (79) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +25 -0
  3. data/README.md +27 -0
  4. data/ext/java/org/msgpack/jruby/Buffer.java +3 -3
  5. data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +11 -20
  6. data/ext/java/org/msgpack/jruby/ExtensionValue.java +1 -1
  7. data/ext/java/org/msgpack/jruby/Factory.java +11 -50
  8. data/ext/java/org/msgpack/jruby/Packer.java +9 -24
  9. data/ext/java/org/msgpack/jruby/Unpacker.java +15 -32
  10. data/ext/msgpack/buffer.c +16 -17
  11. data/ext/msgpack/buffer.h +2 -8
  12. data/ext/msgpack/buffer_class.c +76 -5
  13. data/ext/msgpack/buffer_class.h +1 -0
  14. data/ext/msgpack/extconf.rb +18 -26
  15. data/ext/msgpack/factory_class.c +27 -61
  16. data/ext/msgpack/packer.c +13 -14
  17. data/ext/msgpack/packer.h +0 -4
  18. data/ext/msgpack/packer_class.c +19 -54
  19. data/ext/msgpack/packer_ext_registry.c +31 -28
  20. data/ext/msgpack/packer_ext_registry.h +10 -14
  21. data/ext/msgpack/rbinit.c +1 -1
  22. data/ext/msgpack/rmem.c +3 -4
  23. data/ext/msgpack/unpacker.c +12 -25
  24. data/ext/msgpack/unpacker.h +0 -4
  25. data/ext/msgpack/unpacker_class.c +14 -49
  26. data/ext/msgpack/unpacker_ext_registry.c +4 -16
  27. data/ext/msgpack/unpacker_ext_registry.h +3 -7
  28. data/lib/msgpack/buffer.rb +9 -0
  29. data/lib/msgpack/factory.rb +90 -63
  30. data/lib/msgpack/packer.rb +10 -1
  31. data/lib/msgpack/unpacker.rb +14 -1
  32. data/lib/msgpack/version.rb +1 -1
  33. data/lib/msgpack.rb +1 -0
  34. data/msgpack.gemspec +6 -3
  35. metadata +19 -48
  36. data/.github/workflows/ci.yaml +0 -57
  37. data/.gitignore +0 -23
  38. data/.rubocop.yml +0 -36
  39. data/Gemfile +0 -9
  40. data/Rakefile +0 -70
  41. data/appveyor.yml +0 -18
  42. data/bench/bench.rb +0 -78
  43. data/bin/console +0 -8
  44. data/doclib/msgpack/buffer.rb +0 -193
  45. data/doclib/msgpack/core_ext.rb +0 -101
  46. data/doclib/msgpack/error.rb +0 -19
  47. data/doclib/msgpack/extension_value.rb +0 -9
  48. data/doclib/msgpack/factory.rb +0 -145
  49. data/doclib/msgpack/packer.rb +0 -209
  50. data/doclib/msgpack/time.rb +0 -22
  51. data/doclib/msgpack/timestamp.rb +0 -44
  52. data/doclib/msgpack/unpacker.rb +0 -183
  53. data/doclib/msgpack.rb +0 -87
  54. data/msgpack.org.md +0 -46
  55. data/spec/bigint_spec.rb +0 -26
  56. data/spec/cases.json +0 -1
  57. data/spec/cases.msg +0 -0
  58. data/spec/cases_compact.msg +0 -0
  59. data/spec/cases_spec.rb +0 -39
  60. data/spec/cruby/buffer_io_spec.rb +0 -255
  61. data/spec/cruby/buffer_packer.rb +0 -29
  62. data/spec/cruby/buffer_spec.rb +0 -592
  63. data/spec/cruby/buffer_unpacker.rb +0 -19
  64. data/spec/cruby/unpacker_spec.rb +0 -70
  65. data/spec/ext_value_spec.rb +0 -99
  66. data/spec/exttypes.rb +0 -51
  67. data/spec/factory_spec.rb +0 -706
  68. data/spec/format_spec.rb +0 -301
  69. data/spec/jruby/benchmarks/shootout_bm.rb +0 -73
  70. data/spec/jruby/benchmarks/symbolize_keys_bm.rb +0 -25
  71. data/spec/jruby/unpacker_spec.rb +0 -186
  72. data/spec/msgpack_spec.rb +0 -214
  73. data/spec/pack_spec.rb +0 -61
  74. data/spec/packer_spec.rb +0 -575
  75. data/spec/random_compat.rb +0 -24
  76. data/spec/spec_helper.rb +0 -72
  77. data/spec/timestamp_spec.rb +0 -159
  78. data/spec/unpack_spec.rb +0 -57
  79. data/spec/unpacker_spec.rb +0 -869
@@ -1,17 +1,23 @@
1
1
  require 'mkmf'
2
2
 
3
- have_header("ruby/st.h")
4
- have_header("st.h")
5
3
  have_func("rb_enc_interned_str", "ruby.h") # Ruby 3.0+
6
4
  have_func("rb_hash_new_capa", "ruby.h") # Ruby 3.2+
5
+ have_func("rb_proc_call_with_block", "ruby.h") # CRuby (TruffleRuby doesn't have it)
7
6
 
8
- unless RUBY_PLATFORM.include? 'mswin'
9
- $CFLAGS << %[ -I.. -Wall -O3 #{RbConfig::CONFIG["debugflags"]} -std=gnu99]
10
- end
7
+ append_cflags([
8
+ "-fvisibility=hidden",
9
+ "-I..",
10
+ "-Wall",
11
+ "-O3",
12
+ "-std=gnu99"
13
+ ])
14
+ append_cflags(RbConfig::CONFIG["debugflags"]) if RbConfig::CONFIG["debugflags"]
15
+
16
+ append_cflags("-DRUBY_DEBUG=1") if ENV["MSGPACK_DEBUG"]
11
17
 
12
- if RUBY_VERSION.start_with?('3.0.')
18
+ if RUBY_VERSION.start_with?('3.0.') && RUBY_VERSION <= '3.0.5'
13
19
  # https://bugs.ruby-lang.org/issues/18772
14
- $CFLAGS << ' -DRB_ENC_INTERNED_STR_NULL_CHECK=1 '
20
+ append_cflags("-DRB_ENC_INTERNED_STR_NULL_CHECK=1")
15
21
  end
16
22
 
17
23
  # checking if Hash#[]= (rb_hash_aset) dedupes string keys (Ruby 2.6+)
@@ -21,35 +27,21 @@ r = rand.to_s
21
27
  h[%W(#{r}).join('')] = :foo
22
28
  x[%W(#{r}).join('')] = :foo
23
29
  if x.keys[0].equal?(h.keys[0])
24
- $CFLAGS << ' -DHASH_ASET_DEDUPE=1 '
30
+ append_cflags("-DHASH_ASET_DEDUPE=1")
25
31
  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 '
32
+ append_cflags("-DHASH_ASET_DEDUPE=0")
41
33
  end
42
34
 
43
35
  # checking if String#-@ (str_uminus) directly interns frozen strings... ' (Ruby 3.0+)
44
36
  begin
45
37
  s = rand.to_s.freeze
46
38
  if (-s).equal?(s) && (-s.dup).equal?(s)
47
- $CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=1 '
39
+ append_cflags("-DSTR_UMINUS_DEDUPE_FROZEN=1")
48
40
  else
49
- $CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=0 '
41
+ append_cflags("-DSTR_UMINUS_DEDUPE_FROZEN=0")
50
42
  end
51
43
  rescue NoMethodError
52
- $CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=0 '
44
+ append_cflags("-DSTR_UMINUS_DEDUPE_FROZEN=0")
53
45
  end
54
46
 
55
47
  if warnflags = CONFIG['warnflags']
@@ -75,7 +75,7 @@ static const rb_data_type_t factory_data_type = {
75
75
  .dfree = Factory_free,
76
76
  .dsize = Factory_memsize,
77
77
  },
78
- .flags = RUBY_TYPED_FREE_IMMEDIATELY
78
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
79
79
  };
80
80
 
81
81
  static inline msgpack_factory_t *Factory_get(VALUE object)
@@ -98,7 +98,7 @@ static VALUE Factory_initialize(int argc, VALUE* argv, VALUE self)
98
98
  {
99
99
  msgpack_factory_t *fc = Factory_get(self);
100
100
 
101
- msgpack_packer_ext_registry_init(&fc->pkrg);
101
+ msgpack_packer_ext_registry_init(self, &fc->pkrg);
102
102
  // fc->ukrg is lazily initialized
103
103
 
104
104
  fc->has_symbol_ext_type = false;
@@ -124,7 +124,7 @@ static VALUE Factory_dup(VALUE self)
124
124
  cloned_fc->has_symbol_ext_type = fc->has_symbol_ext_type;
125
125
  cloned_fc->pkrg = fc->pkrg;
126
126
  msgpack_unpacker_ext_registry_borrow(fc->ukrg, &cloned_fc->ukrg);
127
- msgpack_packer_ext_registry_dup(&fc->pkrg, &cloned_fc->pkrg);
127
+ msgpack_packer_ext_registry_dup(clone, &fc->pkrg, &cloned_fc->pkrg);
128
128
 
129
129
  return clone;
130
130
  }
@@ -139,7 +139,7 @@ static VALUE Factory_freeze(VALUE self) {
139
139
  // If the factory is frozen, we can safely share the packer cache between
140
140
  // all packers. So we eagerly create it now so it's available when #packer
141
141
  // is called.
142
- fc->pkrg.cache = rb_hash_new();
142
+ RB_OBJ_WRITE(self, &fc->pkrg.cache, rb_hash_new());
143
143
  }
144
144
  }
145
145
 
@@ -158,7 +158,7 @@ VALUE MessagePack_Factory_packer(int argc, VALUE* argv, VALUE self)
158
158
 
159
159
  msgpack_packer_t* pk = MessagePack_Packer_get(packer);
160
160
  msgpack_packer_ext_registry_destroy(&pk->ext_registry);
161
- msgpack_packer_ext_registry_dup(&fc->pkrg, &pk->ext_registry);
161
+ msgpack_packer_ext_registry_borrow(packer, &fc->pkrg, &pk->ext_registry);
162
162
  pk->has_bigint_ext_type = fc->has_bigint_ext_type;
163
163
  pk->has_symbol_ext_type = fc->has_symbol_ext_type;
164
164
 
@@ -187,7 +187,7 @@ static VALUE Factory_registered_types_internal(VALUE self)
187
187
  VALUE uk_mapping = rb_hash_new();
188
188
  if (fc->ukrg) {
189
189
  for(int i=0; i < 256; i++) {
190
- if(fc->ukrg->array[i] != Qnil) {
190
+ if(!NIL_P(fc->ukrg->array[i])) {
191
191
  rb_hash_aset(uk_mapping, INT2FIX(i - 128), fc->ukrg->array[i]);
192
192
  }
193
193
  }
@@ -200,73 +200,39 @@ static VALUE Factory_registered_types_internal(VALUE self)
200
200
  );
201
201
  }
202
202
 
203
- static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
203
+ static VALUE Factory_register_type_internal(VALUE self, VALUE rb_ext_type, VALUE ext_module, VALUE options)
204
204
  {
205
205
  msgpack_factory_t *fc = Factory_get(self);
206
206
 
207
- int ext_type;
208
- int flags = 0;
209
- VALUE ext_module;
210
- VALUE options = Qnil;
211
- VALUE packer_arg, unpacker_arg;
212
- VALUE packer_proc, unpacker_proc;
207
+ Check_Type(rb_ext_type, T_FIXNUM);
213
208
 
214
- if (OBJ_FROZEN(self)) {
215
- rb_raise(rb_eRuntimeError, "can't modify frozen Factory");
209
+ if(rb_type(ext_module) != T_MODULE && rb_type(ext_module) != T_CLASS) {
210
+ rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
216
211
  }
217
212
 
218
- switch (argc) {
219
- case 2:
220
- /* register_type(0x7f, Time) */
221
- packer_arg = ID2SYM(rb_intern("to_msgpack_ext"));
222
- unpacker_arg = ID2SYM(rb_intern("from_msgpack_ext"));
223
- break;
224
- case 3:
225
- /* register_type(0x7f, Time, packer: proc-like, unapcker: proc-like) */
226
- options = argv[2];
227
- if(rb_type(options) != T_HASH) {
228
- rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
229
- }
230
- packer_arg = rb_hash_aref(options, ID2SYM(rb_intern("packer")));
231
- unpacker_arg = rb_hash_aref(options, ID2SYM(rb_intern("unpacker")));
232
- break;
233
- default:
234
- rb_raise(rb_eArgError, "wrong number of arguments (%d for 2..3)", argc);
235
- }
213
+ int flags = 0;
236
214
 
237
- if (options != Qnil) {
215
+ VALUE packer_proc = Qnil;
216
+ VALUE unpacker_proc = Qnil;
217
+ if(!NIL_P(options)) {
238
218
  Check_Type(options, T_HASH);
219
+ packer_proc = rb_hash_aref(options, ID2SYM(rb_intern("packer")));
220
+ unpacker_proc = rb_hash_aref(options, ID2SYM(rb_intern("unpacker")));
239
221
  }
240
222
 
241
- ext_type = NUM2INT(argv[0]);
242
- if(ext_type < -128 || ext_type > 127) {
243
- rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
244
- }
245
-
246
- ext_module = argv[1];
247
- if(rb_type(ext_module) != T_MODULE && rb_type(ext_module) != T_CLASS) {
248
- rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
249
- }
250
-
251
- packer_proc = Qnil;
252
- unpacker_proc = Qnil;
253
-
254
- if(packer_arg != Qnil) {
255
- packer_proc = rb_funcall(packer_arg, rb_intern("to_proc"), 0);
223
+ if (OBJ_FROZEN(self)) {
224
+ rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Factory");
256
225
  }
257
226
 
258
- if(unpacker_arg != Qnil) {
259
- if(rb_type(unpacker_arg) == T_SYMBOL || rb_type(unpacker_arg) == T_STRING) {
260
- unpacker_proc = rb_obj_method(ext_module, unpacker_arg);
261
- } else if (rb_respond_to(unpacker_arg, rb_intern("call"))) {
262
- unpacker_proc = unpacker_arg;
263
- } else {
264
- unpacker_proc = rb_funcall(unpacker_arg, rb_intern("method"), 1, ID2SYM(rb_intern("call")));
265
- }
227
+ int ext_type = NUM2INT(rb_ext_type);
228
+ if(ext_type < -128 || ext_type > 127) {
229
+ rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
266
230
  }
267
231
 
268
232
  if(ext_module == rb_cSymbol) {
269
- fc->has_symbol_ext_type = true;
233
+ if(NIL_P(options) || RTEST(rb_hash_aref(options, ID2SYM(rb_intern("packer"))))) {
234
+ fc->has_symbol_ext_type = true;
235
+ }
270
236
  if(RTEST(options) && RTEST(rb_hash_aref(options, ID2SYM(rb_intern("optimized_symbols_parsing"))))) {
271
237
  fc->optimized_symbol_ext_type = true;
272
238
  }
@@ -286,8 +252,8 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
286
252
  }
287
253
  }
288
254
 
289
- msgpack_packer_ext_registry_put(&fc->pkrg, ext_module, ext_type, flags, packer_proc, packer_arg);
290
- msgpack_unpacker_ext_registry_put(&fc->ukrg, ext_module, ext_type, flags, unpacker_proc, unpacker_arg);
255
+ msgpack_packer_ext_registry_put(self, &fc->pkrg, ext_module, ext_type, flags, packer_proc);
256
+ msgpack_unpacker_ext_registry_put(self, &fc->ukrg, ext_module, ext_type, flags, unpacker_proc);
291
257
 
292
258
  return Qnil;
293
259
  }
@@ -306,5 +272,5 @@ void MessagePack_Factory_module_init(VALUE mMessagePack)
306
272
  rb_define_method(cMessagePack_Factory, "unpacker", MessagePack_Factory_unpacker, -1);
307
273
 
308
274
  rb_define_private_method(cMessagePack_Factory, "registered_types_internal", Factory_registered_types_internal, 0);
309
- rb_define_method(cMessagePack_Factory, "register_type", Factory_register_type, -1);
275
+ rb_define_private_method(cMessagePack_Factory, "register_type_internal", Factory_register_type_internal, 3);
310
276
  }
data/ext/msgpack/packer.c CHANGED
@@ -17,16 +17,11 @@
17
17
  */
18
18
 
19
19
  #include "packer.h"
20
+ #include "buffer_class.h"
20
21
 
21
- static ID s_call;
22
-
23
- void msgpack_packer_static_init(void)
24
- {
25
- s_call = rb_intern("call");
26
- }
27
-
28
- void msgpack_packer_static_destroy(void)
29
- { }
22
+ #if !defined(HAVE_RB_PROC_CALL_WITH_BLOCK)
23
+ #define rb_proc_call_with_block(recv, argc, argv, block) rb_funcallv(recv, rb_intern("call"), argc, argv)
24
+ #endif
30
25
 
31
26
  void msgpack_packer_init(msgpack_packer_t* pk)
32
27
  {
@@ -43,6 +38,7 @@ void msgpack_packer_mark(msgpack_packer_t* pk)
43
38
  /* See MessagePack_Buffer_wrap */
44
39
  /* msgpack_buffer_mark(PACKER_BUFFER_(pk)); */
45
40
  rb_gc_mark(pk->buffer_ref);
41
+ rb_gc_mark(pk->to_msgpack_arg);
46
42
  }
47
43
 
48
44
  void msgpack_packer_reset(msgpack_packer_t* pk)
@@ -99,14 +95,13 @@ struct msgpack_call_proc_args_t;
99
95
  typedef struct msgpack_call_proc_args_t msgpack_call_proc_args_t;
100
96
  struct msgpack_call_proc_args_t {
101
97
  VALUE proc;
102
- VALUE arg;
103
- VALUE packer;
98
+ VALUE args[2];
104
99
  };
105
100
 
106
101
  VALUE msgpack_packer_try_calling_proc(VALUE value)
107
102
  {
108
103
  msgpack_call_proc_args_t *args = (msgpack_call_proc_args_t *)value;
109
- return rb_funcall(args->proc, s_call, 2, args->arg, args->packer);
104
+ return rb_proc_call_with_block(args->proc, 2, args->args, Qnil);
110
105
  }
111
106
 
112
107
  bool msgpack_packer_try_write_with_ext_type_lookup(msgpack_packer_t* pk, VALUE v)
@@ -120,11 +115,13 @@ bool msgpack_packer_try_write_with_ext_type_lookup(msgpack_packer_t* pk, VALUE v
120
115
  }
121
116
 
122
117
  if(ext_flags & MSGPACK_EXT_RECURSIVE) {
118
+ VALUE held_buffer = MessagePack_Buffer_hold(&pk->buffer);
119
+
123
120
  msgpack_buffer_t parent_buffer = pk->buffer;
124
121
  msgpack_buffer_init(PACKER_BUFFER_(pk));
125
122
 
126
123
  int exception_occured = 0;
127
- msgpack_call_proc_args_t args = { proc, v, pk->to_msgpack_arg };
124
+ msgpack_call_proc_args_t args = { proc, { v, pk->to_msgpack_arg } };
128
125
  rb_protect(msgpack_packer_try_calling_proc, (VALUE)&args, &exception_occured);
129
126
 
130
127
  if (exception_occured) {
@@ -138,8 +135,10 @@ bool msgpack_packer_try_write_with_ext_type_lookup(msgpack_packer_t* pk, VALUE v
138
135
  pk->buffer = parent_buffer;
139
136
  msgpack_packer_write_ext(pk, ext_type, payload);
140
137
  }
138
+
139
+ RB_GC_GUARD(held_buffer);
141
140
  } else {
142
- VALUE payload = rb_funcall(proc, s_call, 1, v);
141
+ VALUE payload = rb_proc_call_with_block(proc, 1, &v, Qnil);
143
142
  StringValue(payload);
144
143
  msgpack_packer_write_ext(pk, ext_type, payload);
145
144
  }
data/ext/msgpack/packer.h CHANGED
@@ -47,10 +47,6 @@ struct msgpack_packer_t {
47
47
 
48
48
  #define PACKER_BUFFER_(pk) (&(pk)->buffer)
49
49
 
50
- void msgpack_packer_static_init(void);
51
-
52
- void msgpack_packer_static_destroy(void);
53
-
54
50
  void msgpack_packer_init(msgpack_packer_t* pk);
55
51
 
56
52
  void msgpack_packer_destroy(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
  }
@@ -105,7 +106,7 @@ VALUE MessagePack_Packer_initialize(int argc, VALUE* argv, VALUE self)
105
106
 
106
107
  msgpack_packer_t *pk = MessagePack_Packer_get(self);
107
108
 
108
- msgpack_packer_ext_registry_init(&pk->ext_registry);
109
+ msgpack_packer_ext_registry_init(self, &pk->ext_registry);
109
110
  pk->buffer_ref = MessagePack_Buffer_wrap(PACKER_BUFFER_(pk), self);
110
111
 
111
112
  MessagePack_Buffer_set_options(PACKER_BUFFER_(pk), io, options);
@@ -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
 
@@ -229,7 +233,12 @@ static VALUE Packer_write_extension(VALUE self, VALUE obj)
229
233
  msgpack_packer_t *pk = MessagePack_Packer_get(self);
230
234
  Check_Type(obj, T_STRUCT);
231
235
 
232
- int ext_type = FIX2INT(RSTRUCT_GET(obj, 0));
236
+ VALUE rb_ext_type = RSTRUCT_GET(obj, 0);
237
+ if(!RB_TYPE_P(rb_ext_type, T_FIXNUM)) {
238
+ rb_raise(rb_eRangeError, "integer %s too big to convert to `signed char'", RSTRING_PTR(rb_String(rb_ext_type)));
239
+ }
240
+
241
+ int ext_type = FIX2INT(rb_ext_type);
233
242
  if(ext_type < -128 || ext_type > 127) {
234
243
  rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
235
244
  }
@@ -334,18 +343,6 @@ static VALUE Packer_write_to(VALUE self, VALUE io)
334
343
  return SIZET2NUM(sz);
335
344
  }
336
345
 
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
346
  static VALUE Packer_registered_types_internal(VALUE self)
350
347
  {
351
348
  msgpack_packer_t *pk = MessagePack_Packer_get(self);
@@ -355,42 +352,20 @@ static VALUE Packer_registered_types_internal(VALUE self)
355
352
  return rb_hash_new();
356
353
  }
357
354
 
358
- static VALUE Packer_register_type(int argc, VALUE* argv, VALUE self)
355
+ static VALUE Packer_register_type_internal(VALUE self, VALUE rb_ext_type, VALUE ext_module, VALUE proc)
359
356
  {
360
- msgpack_packer_t *pk = MessagePack_Packer_get(self);
361
-
362
- int ext_type;
363
- VALUE ext_module;
364
- VALUE proc;
365
- VALUE arg;
366
-
367
- switch (argc) {
368
- case 2:
369
- /* register_type(0x7f, Time) {|obj| block... } */
370
- rb_need_block();
371
- proc = rb_block_lambda();
372
- arg = proc;
373
- break;
374
- case 3:
375
- /* register_type(0x7f, Time, :to_msgpack_ext) */
376
- arg = argv[2];
377
- proc = rb_funcall(arg, rb_intern("to_proc"), 0);
378
- break;
379
- default:
380
- rb_raise(rb_eArgError, "wrong number of arguments (%d for 2..3)", argc);
357
+ if (OBJ_FROZEN(self)) {
358
+ rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Packer");
381
359
  }
382
360
 
383
- ext_type = NUM2INT(argv[0]);
361
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
362
+
363
+ int ext_type = NUM2INT(rb_ext_type);
384
364
  if(ext_type < -128 || ext_type > 127) {
385
365
  rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
386
366
  }
387
367
 
388
- ext_module = argv[1];
389
- if(rb_type(ext_module) != T_MODULE && rb_type(ext_module) != T_CLASS) {
390
- rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
391
- }
392
-
393
- msgpack_packer_ext_registry_put(&pk->ext_registry, ext_module, ext_type, 0, proc, arg);
368
+ msgpack_packer_ext_registry_put(self, &pk->ext_registry, ext_module, ext_type, 0, proc);
394
369
 
395
370
  if (ext_module == rb_cSymbol) {
396
371
  pk->has_symbol_ext_type = true;
@@ -423,10 +398,6 @@ void MessagePack_Packer_module_init(VALUE mMessagePack)
423
398
  s_write = rb_intern("write");
424
399
 
425
400
  sym_compatibility_mode = ID2SYM(rb_intern("compatibility_mode"));
426
-
427
- msgpack_packer_static_init();
428
- msgpack_packer_ext_registry_static_init();
429
-
430
401
  cMessagePack_Packer = rb_define_class_under(mMessagePack, "Packer", rb_cObject);
431
402
 
432
403
  rb_define_alloc_func(cMessagePack_Packer, MessagePack_Packer_alloc);
@@ -463,15 +434,9 @@ void MessagePack_Packer_module_init(VALUE mMessagePack)
463
434
  rb_define_method(cMessagePack_Packer, "to_str", Packer_to_str, 0);
464
435
  rb_define_alias(cMessagePack_Packer, "to_s", "to_str");
465
436
  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
437
 
469
438
  rb_define_private_method(cMessagePack_Packer, "registered_types_internal", Packer_registered_types_internal, 0);
470
- rb_define_method(cMessagePack_Packer, "register_type", Packer_register_type, -1);
471
-
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);
439
+ rb_define_method(cMessagePack_Packer, "register_type_internal", Packer_register_type_internal, 3);
475
440
 
476
441
  rb_define_method(cMessagePack_Packer, "full_pack", Packer_full_pack, 0);
477
442
  }
@@ -18,20 +18,10 @@
18
18
 
19
19
  #include "packer_ext_registry.h"
20
20
 
21
- static ID s_call;
22
-
23
- void msgpack_packer_ext_registry_static_init(void)
24
- {
25
- s_call = rb_intern("call");
26
- }
27
-
28
- void msgpack_packer_ext_registry_static_destroy(void)
29
- { }
30
-
31
- void msgpack_packer_ext_registry_init(msgpack_packer_ext_registry_t* pkrg)
21
+ void msgpack_packer_ext_registry_init(VALUE owner, msgpack_packer_ext_registry_t* pkrg)
32
22
  {
33
- pkrg->hash = Qnil;
34
- pkrg->cache = Qnil;
23
+ RB_OBJ_WRITE(owner, &pkrg->hash, Qnil);
24
+ RB_OBJ_WRITE(owner, &pkrg->cache, Qnil);
35
25
  }
36
26
 
37
27
  void msgpack_packer_ext_registry_mark(msgpack_packer_ext_registry_t* pkrg)
@@ -40,32 +30,45 @@ void msgpack_packer_ext_registry_mark(msgpack_packer_ext_registry_t* pkrg)
40
30
  rb_gc_mark(pkrg->cache);
41
31
  }
42
32
 
43
- void msgpack_packer_ext_registry_dup(msgpack_packer_ext_registry_t* src,
33
+ void msgpack_packer_ext_registry_borrow(VALUE owner, msgpack_packer_ext_registry_t* src,
44
34
  msgpack_packer_ext_registry_t* dst)
45
35
  {
46
- if(RTEST(src->hash) && !rb_obj_frozen_p(src->hash)) {
47
- dst->hash = rb_hash_dup(src->hash);
48
- dst->cache = RTEST(src->cache) ? rb_hash_dup(src->cache) : Qnil;
36
+ if(RTEST(src->hash)) {
37
+ if(rb_obj_frozen_p(src->hash)) {
38
+ // If the type registry is frozen we can safely share it, and share the cache as well.
39
+ RB_OBJ_WRITE(owner, &dst->hash, src->hash);
40
+ RB_OBJ_WRITE(owner, &dst->cache, src->cache);
41
+ } else {
42
+ RB_OBJ_WRITE(owner, &dst->hash, rb_hash_dup(src->hash));
43
+ RB_OBJ_WRITE(owner, &dst->cache, NIL_P(src->cache) ? Qnil : rb_hash_dup(src->cache));
44
+ }
49
45
  } else {
50
- // If the type registry is frozen we can safely share it, and share the cache as well.
51
- dst->hash = src->hash;
52
- dst->cache = src->cache;
46
+ RB_OBJ_WRITE(owner, &dst->hash, Qnil);
47
+ RB_OBJ_WRITE(owner, &dst->cache, Qnil);
53
48
  }
54
49
  }
55
50
 
56
- VALUE msgpack_packer_ext_registry_put(msgpack_packer_ext_registry_t* pkrg,
57
- VALUE ext_module, int ext_type, int flags, VALUE proc, VALUE arg)
51
+ void msgpack_packer_ext_registry_dup(VALUE owner, msgpack_packer_ext_registry_t* src,
52
+ msgpack_packer_ext_registry_t* dst)
58
53
  {
59
- if (!RTEST(pkrg->hash)) {
60
- pkrg->hash = rb_hash_new();
54
+ RB_OBJ_WRITE(owner, &dst->hash, NIL_P(src->hash) ? Qnil : rb_hash_dup(src->hash));
55
+ RB_OBJ_WRITE(owner, &dst->cache, NIL_P(src->cache) ? Qnil : rb_hash_dup(src->cache));
56
+ }
57
+
58
+ void msgpack_packer_ext_registry_put(VALUE owner, msgpack_packer_ext_registry_t* pkrg,
59
+ VALUE ext_module, int ext_type, int flags, VALUE proc)
60
+ {
61
+ if(NIL_P(pkrg->hash)) {
62
+ RB_OBJ_WRITE(owner, &pkrg->hash, rb_hash_new());
61
63
  }
62
64
 
63
- if (RTEST(pkrg->cache)) {
65
+ if(NIL_P(pkrg->cache)) {
66
+ RB_OBJ_WRITE(owner, &pkrg->cache, rb_hash_new());
67
+ } else {
64
68
  /* clear lookup cache not to miss added type */
65
69
  rb_hash_clear(pkrg->cache);
66
70
  }
67
71
 
68
- // TODO: Ruby embeded array limit is 3, merging `proc` and `arg` would be good.
69
- VALUE entry = rb_ary_new3(4, INT2FIX(ext_type), proc, arg, INT2FIX(flags));
70
- return rb_hash_aset(pkrg->hash, ext_module, entry);
72
+ VALUE entry = rb_ary_new3(3, INT2FIX(ext_type), proc, INT2FIX(flags));
73
+ rb_hash_aset(pkrg->hash, ext_module, entry);
71
74
  }
@@ -31,22 +31,21 @@ struct msgpack_packer_ext_registry_t {
31
31
  VALUE cache; // lookup cache for ext types inherited from a super class
32
32
  };
33
33
 
34
- void msgpack_packer_ext_registry_static_init(void);
35
-
36
- void msgpack_packer_ext_registry_static_destroy(void);
37
-
38
- void msgpack_packer_ext_registry_init(msgpack_packer_ext_registry_t* pkrg);
34
+ void msgpack_packer_ext_registry_init(VALUE owner, msgpack_packer_ext_registry_t* pkrg);
39
35
 
40
36
  static inline void msgpack_packer_ext_registry_destroy(msgpack_packer_ext_registry_t* pkrg)
41
37
  { }
42
38
 
43
39
  void msgpack_packer_ext_registry_mark(msgpack_packer_ext_registry_t* pkrg);
44
40
 
45
- void msgpack_packer_ext_registry_dup(msgpack_packer_ext_registry_t* src,
41
+ void msgpack_packer_ext_registry_borrow(VALUE owner, msgpack_packer_ext_registry_t* src,
46
42
  msgpack_packer_ext_registry_t* dst);
47
43
 
48
- VALUE msgpack_packer_ext_registry_put(msgpack_packer_ext_registry_t* pkrg,
49
- VALUE ext_module, int ext_type, int flags, VALUE proc, VALUE arg);
44
+ void msgpack_packer_ext_registry_dup(VALUE owner, msgpack_packer_ext_registry_t* src,
45
+ msgpack_packer_ext_registry_t* dst);
46
+
47
+ void msgpack_packer_ext_registry_put(VALUE owner, msgpack_packer_ext_registry_t* pkrg,
48
+ VALUE ext_module, int ext_type, int flags, VALUE proc);
50
49
 
51
50
  static int msgpack_packer_ext_find_superclass(VALUE key, VALUE value, VALUE arg)
52
51
  {
@@ -68,7 +67,7 @@ static inline VALUE msgpack_packer_ext_registry_fetch(msgpack_packer_ext_registr
68
67
  VALUE type = rb_hash_lookup(pkrg->hash, lookup_class);
69
68
  if(type != Qnil) {
70
69
  *ext_type_result = FIX2INT(rb_ary_entry(type, 0));
71
- *ext_flags_result = FIX2INT(rb_ary_entry(type, 3));
70
+ *ext_flags_result = FIX2INT(rb_ary_entry(type, 2));
72
71
  return rb_ary_entry(type, 1);
73
72
  }
74
73
 
@@ -77,7 +76,7 @@ static inline VALUE msgpack_packer_ext_registry_fetch(msgpack_packer_ext_registr
77
76
  VALUE type_inht = rb_hash_lookup(pkrg->cache, lookup_class);
78
77
  if(type_inht != Qnil) {
79
78
  *ext_type_result = FIX2INT(rb_ary_entry(type_inht, 0));
80
- *ext_flags_result = FIX2INT(rb_ary_entry(type_inht, 3));
79
+ *ext_flags_result = FIX2INT(rb_ary_entry(type_inht, 2));
81
80
  return rb_ary_entry(type_inht, 1);
82
81
  }
83
82
  }
@@ -129,12 +128,9 @@ static inline VALUE msgpack_packer_ext_registry_lookup(msgpack_packer_ext_regist
129
128
  VALUE superclass = args[1];
130
129
  if(superclass != Qnil) {
131
130
  VALUE superclass_type = rb_hash_lookup(pkrg->hash, superclass);
132
- if (!RTEST(pkrg->cache)) {
133
- pkrg->cache = rb_hash_new();
134
- }
135
131
  rb_hash_aset(pkrg->cache, lookup_class, superclass_type);
136
132
  *ext_type_result = FIX2INT(rb_ary_entry(superclass_type, 0));
137
- *ext_flags_result = FIX2INT(rb_ary_entry(superclass_type, 3));
133
+ *ext_flags_result = FIX2INT(rb_ary_entry(superclass_type, 2));
138
134
  return rb_ary_entry(superclass_type, 1);
139
135
  }
140
136
 
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