msgpack 1.6.0 → 1.7.2

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