msgpack 1.4.5 → 1.5.6

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yaml +5 -5
  3. data/ChangeLog +32 -0
  4. data/README.md +25 -1
  5. data/bench/bench.rb +78 -0
  6. data/doclib/msgpack/factory.rb +45 -2
  7. data/ext/java/org/msgpack/jruby/Buffer.java +6 -0
  8. data/ext/java/org/msgpack/jruby/Decoder.java +23 -19
  9. data/ext/java/org/msgpack/jruby/Encoder.java +46 -18
  10. data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +24 -31
  11. data/ext/java/org/msgpack/jruby/Factory.java +40 -5
  12. data/ext/java/org/msgpack/jruby/Packer.java +21 -11
  13. data/ext/java/org/msgpack/jruby/Unpacker.java +44 -22
  14. data/ext/msgpack/buffer.c +9 -36
  15. data/ext/msgpack/buffer.h +9 -1
  16. data/ext/msgpack/buffer_class.c +18 -9
  17. data/ext/msgpack/compat.h +0 -99
  18. data/ext/msgpack/extconf.rb +9 -11
  19. data/ext/msgpack/factory_class.c +62 -5
  20. data/ext/msgpack/packer.c +42 -29
  21. data/ext/msgpack/packer.h +25 -7
  22. data/ext/msgpack/packer_class.c +23 -20
  23. data/ext/msgpack/packer_ext_registry.c +13 -4
  24. data/ext/msgpack/packer_ext_registry.h +10 -5
  25. data/ext/msgpack/unpacker.c +99 -68
  26. data/ext/msgpack/unpacker.h +10 -6
  27. data/ext/msgpack/unpacker_class.c +16 -8
  28. data/ext/msgpack/unpacker_ext_registry.c +3 -2
  29. data/ext/msgpack/unpacker_ext_registry.h +5 -2
  30. data/lib/msgpack/bigint.rb +69 -0
  31. data/lib/msgpack/factory.rb +103 -0
  32. data/lib/msgpack/version.rb +1 -1
  33. data/lib/msgpack.rb +4 -5
  34. data/msgpack.gemspec +1 -0
  35. data/spec/bigint_spec.rb +26 -0
  36. data/spec/factory_spec.rb +248 -0
  37. data/spec/spec_helper.rb +9 -1
  38. data/spec/timestamp_spec.rb +2 -2
  39. data/spec/unpacker_spec.rb +12 -0
  40. metadata +20 -13
  41. data/bench/pack.rb +0 -23
  42. data/bench/pack_log.rb +0 -33
  43. data/bench/pack_log_long.rb +0 -65
  44. data/bench/pack_symbols.rb +0 -28
  45. data/bench/run.sh +0 -14
  46. data/bench/run_long.sh +0 -35
  47. data/bench/run_symbols.sh +0 -26
  48. data/bench/unpack.rb +0 -21
  49. data/bench/unpack_log.rb +0 -34
  50. data/bench/unpack_log_long.rb +0 -67
@@ -31,6 +31,7 @@ typedef struct msgpack_factory_t msgpack_factory_t;
31
31
  struct msgpack_factory_t {
32
32
  msgpack_packer_ext_registry_t pkrg;
33
33
  msgpack_unpacker_ext_registry_t *ukrg;
34
+ bool has_bigint_ext_type;
34
35
  bool has_symbol_ext_type;
35
36
  bool optimized_symbol_ext_type;
36
37
  int symbol_ext_type;
@@ -87,6 +88,41 @@ static VALUE Factory_initialize(int argc, VALUE* argv, VALUE self)
87
88
  return Qnil;
88
89
  }
89
90
 
91
+ static VALUE Factory_dup(VALUE self)
92
+ {
93
+ VALUE clone = Factory_alloc(rb_obj_class(self));
94
+
95
+ FACTORY(self, fc);
96
+ FACTORY(clone, cloned_fc);
97
+
98
+ cloned_fc->has_symbol_ext_type = fc->has_symbol_ext_type;
99
+ cloned_fc->pkrg = fc->pkrg;
100
+ msgpack_unpacker_ext_registry_borrow(fc->ukrg, &cloned_fc->ukrg);
101
+ msgpack_packer_ext_registry_dup(&fc->pkrg, &cloned_fc->pkrg);
102
+
103
+ return clone;
104
+ }
105
+
106
+ static VALUE Factory_freeze(VALUE self) {
107
+ if(!rb_obj_frozen_p(self)) {
108
+ FACTORY(self, fc);
109
+
110
+ if (RTEST(fc->pkrg.hash)) {
111
+ rb_hash_freeze(fc->pkrg.hash);
112
+ if (!RTEST(fc->pkrg.cache)) {
113
+ // If the factory is frozen, we can safely share the packer cache between
114
+ // all packers. So we eagerly create it now so it's available when #packer
115
+ // is called.
116
+ fc->pkrg.cache = rb_hash_new();
117
+ }
118
+ }
119
+
120
+ rb_obj_freeze(self);
121
+ }
122
+
123
+ return self;
124
+ }
125
+
90
126
  VALUE MessagePack_Factory_packer(int argc, VALUE* argv, VALUE self)
91
127
  {
92
128
  FACTORY(self, fc);
@@ -99,6 +135,7 @@ VALUE MessagePack_Factory_packer(int argc, VALUE* argv, VALUE self)
99
135
 
100
136
  msgpack_packer_ext_registry_destroy(&pk->ext_registry);
101
137
  msgpack_packer_ext_registry_dup(&fc->pkrg, &pk->ext_registry);
138
+ pk->has_bigint_ext_type = fc->has_bigint_ext_type;
102
139
  pk->has_symbol_ext_type = fc->has_symbol_ext_type;
103
140
 
104
141
  return packer;
@@ -145,6 +182,7 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
145
182
  FACTORY(self, fc);
146
183
 
147
184
  int ext_type;
185
+ int flags = 0;
148
186
  VALUE ext_module;
149
187
  VALUE options = Qnil;
150
188
  VALUE packer_arg, unpacker_arg;
@@ -173,6 +211,10 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
173
211
  rb_raise(rb_eArgError, "wrong number of arguments (%d for 2..3)", argc);
174
212
  }
175
213
 
214
+ if (options != Qnil) {
215
+ Check_Type(options, T_HASH);
216
+ }
217
+
176
218
  ext_type = NUM2INT(argv[0]);
177
219
  if(ext_type < -128 || ext_type > 127) {
178
220
  rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
@@ -200,16 +242,29 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
200
242
  }
201
243
  }
202
244
 
203
- msgpack_packer_ext_registry_put(&fc->pkrg, ext_module, ext_type, packer_proc, packer_arg);
204
-
205
- if (ext_module == rb_cSymbol) {
245
+ if(ext_module == rb_cSymbol) {
206
246
  fc->has_symbol_ext_type = true;
207
- if(RB_TEST(options) && RB_TEST(rb_hash_aref(options, ID2SYM(rb_intern("optimized_symbols_parsing"))))) {
247
+ if(RTEST(options) && RTEST(rb_hash_aref(options, ID2SYM(rb_intern("optimized_symbols_parsing"))))) {
208
248
  fc->optimized_symbol_ext_type = true;
209
249
  }
210
250
  }
211
251
 
212
- msgpack_unpacker_ext_registry_put(&fc->ukrg, ext_module, ext_type, unpacker_proc, unpacker_arg);
252
+ if(RTEST(options)) {
253
+ if(RTEST(rb_hash_aref(options, ID2SYM(rb_intern("oversized_integer_extension"))))) {
254
+ if(ext_module == rb_cInteger) {
255
+ fc->has_bigint_ext_type = true;
256
+ } else {
257
+ rb_raise(rb_eArgError, "oversized_integer_extension: true is only for Integer class");
258
+ }
259
+ }
260
+
261
+ if(RTEST(rb_hash_aref(options, ID2SYM(rb_intern("recursive"))))) {
262
+ flags |= MSGPACK_EXT_RECURSIVE;
263
+ }
264
+ }
265
+
266
+ msgpack_packer_ext_registry_put(&fc->pkrg, ext_module, ext_type, flags, packer_proc, packer_arg);
267
+ msgpack_unpacker_ext_registry_put(&fc->ukrg, ext_module, ext_type, flags, unpacker_proc, unpacker_arg);
213
268
 
214
269
  return Qnil;
215
270
  }
@@ -221,6 +276,8 @@ void MessagePack_Factory_module_init(VALUE mMessagePack)
221
276
  rb_define_alloc_func(cMessagePack_Factory, Factory_alloc);
222
277
 
223
278
  rb_define_method(cMessagePack_Factory, "initialize", Factory_initialize, -1);
279
+ rb_define_method(cMessagePack_Factory, "dup", Factory_dup, 0);
280
+ rb_define_method(cMessagePack_Factory, "freeze", Factory_freeze, 0);
224
281
 
225
282
  rb_define_method(cMessagePack_Factory, "packer", MessagePack_Factory_packer, -1);
226
283
  rb_define_method(cMessagePack_Factory, "unpacker", MessagePack_Factory_unpacker, -1);
data/ext/msgpack/packer.c CHANGED
@@ -18,24 +18,10 @@
18
18
 
19
19
  #include "packer.h"
20
20
 
21
- #ifdef RUBINIUS
22
- static ID s_to_iter;
23
- static ID s_next;
24
- static ID s_key;
25
- static ID s_value;
26
- #endif
27
-
28
21
  static ID s_call;
29
22
 
30
23
  void msgpack_packer_static_init()
31
24
  {
32
- #ifdef RUBINIUS
33
- s_to_iter = rb_intern("to_iter");
34
- s_next = rb_intern("next");
35
- s_key = rb_intern("key");
36
- s_value = rb_intern("value");
37
- #endif
38
-
39
25
  s_call = rb_intern("call");
40
26
  }
41
27
 
@@ -108,32 +94,59 @@ void msgpack_packer_write_hash_value(msgpack_packer_t* pk, VALUE v)
108
94
  unsigned int len32 = (unsigned int)len;
109
95
  msgpack_packer_write_map_header(pk, len32);
110
96
 
111
- #ifdef RUBINIUS
112
- VALUE iter = rb_funcall(v, s_to_iter, 0);
113
- VALUE entry = Qnil;
114
- while(RTEST(entry = rb_funcall(iter, s_next, 1, entry))) {
115
- VALUE key = rb_funcall(entry, s_key, 0);
116
- VALUE val = rb_funcall(entry, s_value, 0);
117
- write_hash_foreach(key, val, (VALUE) pk);
118
- }
119
- #else
120
97
  rb_hash_foreach(v, write_hash_foreach, (VALUE) pk);
121
- #endif
98
+ }
99
+
100
+ struct msgpack_call_proc_args_t;
101
+ typedef struct msgpack_call_proc_args_t msgpack_call_proc_args_t;
102
+ struct msgpack_call_proc_args_t {
103
+ VALUE proc;
104
+ VALUE arg;
105
+ VALUE packer;
106
+ };
107
+
108
+ VALUE msgpack_packer_try_calling_proc(VALUE value)
109
+ {
110
+ msgpack_call_proc_args_t *args = (msgpack_call_proc_args_t *)value;
111
+ return rb_funcall(args->proc, s_call, 2, args->arg, args->packer);
122
112
  }
123
113
 
124
114
  bool msgpack_packer_try_write_with_ext_type_lookup(msgpack_packer_t* pk, VALUE v)
125
115
  {
126
- int ext_type;
116
+ int ext_type, ext_flags;
117
+
118
+ VALUE proc = msgpack_packer_ext_registry_lookup(&pk->ext_registry, v, &ext_type, &ext_flags);
127
119
 
128
- VALUE proc = msgpack_packer_ext_registry_lookup(&pk->ext_registry, v, &ext_type);
120
+ if(proc == Qnil) {
121
+ return false;
122
+ }
129
123
 
130
- if(proc != Qnil) {
124
+ if(ext_flags & MSGPACK_EXT_RECURSIVE) {
125
+ msgpack_buffer_t parent_buffer = pk->buffer;
126
+ msgpack_buffer_init(PACKER_BUFFER_(pk));
127
+
128
+ int exception_occured = 0;
129
+ msgpack_call_proc_args_t args = { proc, v, pk->to_msgpack_arg };
130
+ rb_protect(msgpack_packer_try_calling_proc, (VALUE)&args, &exception_occured);
131
+
132
+ if (exception_occured) {
133
+ msgpack_buffer_destroy(PACKER_BUFFER_(pk));
134
+ pk->buffer = parent_buffer;
135
+ rb_jump_tag(exception_occured); // re-raise the exception
136
+ } else {
137
+ VALUE payload = msgpack_buffer_all_as_string(PACKER_BUFFER_(pk));
138
+ StringValue(payload);
139
+ msgpack_buffer_destroy(PACKER_BUFFER_(pk));
140
+ pk->buffer = parent_buffer;
141
+ msgpack_packer_write_ext(pk, ext_type, payload);
142
+ }
143
+ } else {
131
144
  VALUE payload = rb_funcall(proc, s_call, 1, v);
132
145
  StringValue(payload);
133
146
  msgpack_packer_write_ext(pk, ext_type, payload);
134
- return true;
135
147
  }
136
- return false;
148
+
149
+ return true;
137
150
  }
138
151
 
139
152
  void msgpack_packer_write_other_value(msgpack_packer_t* pk, VALUE v)
data/ext/msgpack/packer.h CHANGED
@@ -32,6 +32,7 @@ struct msgpack_packer_t {
32
32
  msgpack_buffer_t buffer;
33
33
 
34
34
  bool compatibility_mode;
35
+ bool has_bigint_ext_type;
35
36
  bool has_symbol_ext_type;
36
37
 
37
38
  ID to_msgpack_method;
@@ -56,6 +57,8 @@ void msgpack_packer_destroy(msgpack_packer_t* pk);
56
57
 
57
58
  void msgpack_packer_mark(msgpack_packer_t* pk);
58
59
 
60
+ bool msgpack_packer_try_write_with_ext_type_lookup(msgpack_packer_t* pk, VALUE v);
61
+
59
62
  static inline void msgpack_packer_set_to_msgpack_method(msgpack_packer_t* pk,
60
63
  ID to_msgpack_method, VALUE to_msgpack_arg)
61
64
  {
@@ -405,13 +408,7 @@ static inline bool msgpack_packer_is_utf8_compat_string(VALUE v, int encindex)
405
408
  {
406
409
  return encindex == msgpack_rb_encindex_utf8
407
410
  || encindex == msgpack_rb_encindex_usascii
408
- #ifdef ENC_CODERANGE_ASCIIONLY
409
- /* Because ENC_CODERANGE_ASCIIONLY does not scan string, it may return ENC_CODERANGE_UNKNOWN unlike */
410
- /* rb_enc_str_asciionly_p. It is always faster than rb_str_encode if it is available. */
411
- /* Very old Rubinius (< v1.3.1) doesn't have ENC_CODERANGE_ASCIIONLY. */
412
- || (rb_enc_asciicompat(rb_enc_from_index(encindex)) && ENC_CODERANGE_ASCIIONLY(v))
413
- #endif
414
- ;
411
+ || (rb_enc_asciicompat(rb_enc_from_index(encindex)) && ENC_CODERANGE_ASCIIONLY(v));
415
412
  }
416
413
 
417
414
  static inline void msgpack_packer_write_string_value(msgpack_packer_t* pk, VALUE v)
@@ -469,9 +466,30 @@ static inline void msgpack_packer_write_fixnum_value(msgpack_packer_t* pk, VALUE
469
466
 
470
467
  static inline void msgpack_packer_write_bignum_value(msgpack_packer_t* pk, VALUE v)
471
468
  {
469
+ int leading_zero_bits;
470
+ size_t required_size = rb_absint_size(v, &leading_zero_bits);
471
+
472
472
  if(RBIGNUM_POSITIVE_P(v)) {
473
+ if(required_size > 8 && pk->has_bigint_ext_type) {
474
+ if(msgpack_packer_try_write_with_ext_type_lookup(pk, v)) {
475
+ return;
476
+ }
477
+ // if we didn't return here `msgpack_packer_write_u64` will raise a RangeError
478
+ }
479
+
473
480
  msgpack_packer_write_u64(pk, rb_big2ull(v));
474
481
  } else {
482
+ if(leading_zero_bits == 0) {
483
+ required_size += 1;
484
+ }
485
+
486
+ if(required_size > 8 && pk->has_bigint_ext_type) {
487
+ if(msgpack_packer_try_write_with_ext_type_lookup(pk, v)) {
488
+ return;
489
+ }
490
+ // if we didn't return here `msgpack_packer_write_u64` will raise a RangeError
491
+ }
492
+
475
493
  msgpack_packer_write_long_long(pk, rb_big2ll(v));
476
494
  }
477
495
  }
@@ -28,6 +28,8 @@ VALUE cMessagePack_Packer;
28
28
  static ID s_to_msgpack;
29
29
  static ID s_write;
30
30
 
31
+ static VALUE sym_compatibility_mode;
32
+
31
33
  //static VALUE s_packer_value;
32
34
  //static msgpack_packer_t* s_packer;
33
35
 
@@ -68,29 +70,28 @@ VALUE MessagePack_Packer_alloc(VALUE klass)
68
70
 
69
71
  VALUE MessagePack_Packer_initialize(int argc, VALUE* argv, VALUE self)
70
72
  {
73
+ if(argc > 2) {
74
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc);
75
+ }
76
+
71
77
  VALUE io = Qnil;
72
78
  VALUE options = Qnil;
73
79
 
74
- if(argc == 0 || (argc == 1 && argv[0] == Qnil)) {
75
- /* Qnil */
76
-
77
- } else if(argc == 1) {
78
- VALUE v = argv[0];
79
- if(rb_type(v) == T_HASH) {
80
- options = v;
81
- } else {
82
- io = v;
83
- }
84
-
85
- } else if(argc == 2) {
80
+ if(argc >= 1) {
86
81
  io = argv[0];
82
+ }
83
+
84
+ if(argc == 2) {
87
85
  options = argv[1];
88
- if(rb_type(options) != T_HASH) {
89
- rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
90
- }
86
+ }
91
87
 
92
- } else {
93
- rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc);
88
+ if (options == Qnil && rb_type(io) == T_HASH) {
89
+ options = io;
90
+ io = Qnil;
91
+ }
92
+
93
+ if(options != Qnil) {
94
+ Check_Type(options, T_HASH);
94
95
  }
95
96
 
96
97
  PACKER(self, pk);
@@ -103,7 +104,7 @@ VALUE MessagePack_Packer_initialize(int argc, VALUE* argv, VALUE self)
103
104
  if(options != Qnil) {
104
105
  VALUE v;
105
106
 
106
- v = rb_hash_aref(options, ID2SYM(rb_intern("compatibility_mode")));
107
+ v = rb_hash_aref(options, sym_compatibility_mode);
107
108
  msgpack_packer_set_compat(pk, RTEST(v));
108
109
  }
109
110
 
@@ -321,7 +322,7 @@ static VALUE Packer_write_to(VALUE self, VALUE io)
321
322
  {
322
323
  PACKER(self, pk);
323
324
  size_t sz = msgpack_buffer_flush_to_io(PACKER_BUFFER_(pk), io, s_write, true);
324
- return ULONG2NUM(sz);
325
+ return SIZET2NUM(sz);
325
326
  }
326
327
 
327
328
  //static VALUE Packer_append(VALUE self, VALUE string_or_buffer)
@@ -380,7 +381,7 @@ static VALUE Packer_register_type(int argc, VALUE* argv, VALUE self)
380
381
  rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
381
382
  }
382
383
 
383
- msgpack_packer_ext_registry_put(&pk->ext_registry, ext_module, ext_type, proc, arg);
384
+ msgpack_packer_ext_registry_put(&pk->ext_registry, ext_module, ext_type, 0, proc, arg);
384
385
 
385
386
  if (ext_module == rb_cSymbol) {
386
387
  pk->has_symbol_ext_type = true;
@@ -412,6 +413,8 @@ void MessagePack_Packer_module_init(VALUE mMessagePack)
412
413
  s_to_msgpack = rb_intern("to_msgpack");
413
414
  s_write = rb_intern("write");
414
415
 
416
+ sym_compatibility_mode = ID2SYM(rb_intern("compatibility_mode"));
417
+
415
418
  msgpack_packer_static_init();
416
419
  msgpack_packer_ext_registry_static_init();
417
420
 
@@ -43,12 +43,18 @@ void msgpack_packer_ext_registry_mark(msgpack_packer_ext_registry_t* pkrg)
43
43
  void msgpack_packer_ext_registry_dup(msgpack_packer_ext_registry_t* src,
44
44
  msgpack_packer_ext_registry_t* dst)
45
45
  {
46
- dst->hash = RTEST(src->hash) ? rb_hash_dup(src->hash) : Qnil;
47
- dst->cache = RTEST(src->cache) ? rb_hash_dup(src->cache): Qnil;
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;
49
+ } 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;
53
+ }
48
54
  }
49
55
 
50
56
  VALUE msgpack_packer_ext_registry_put(msgpack_packer_ext_registry_t* pkrg,
51
- VALUE ext_module, int ext_type, VALUE proc, VALUE arg)
57
+ VALUE ext_module, int ext_type, int flags, VALUE proc, VALUE arg)
52
58
  {
53
59
  if (!RTEST(pkrg->hash)) {
54
60
  pkrg->hash = rb_hash_new();
@@ -58,5 +64,8 @@ VALUE msgpack_packer_ext_registry_put(msgpack_packer_ext_registry_t* pkrg,
58
64
  /* clear lookup cache not to miss added type */
59
65
  rb_hash_clear(pkrg->cache);
60
66
  }
61
- return rb_hash_aset(pkrg->hash, ext_module, rb_ary_new3(3, INT2FIX(ext_type), proc, arg));
67
+
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);
62
71
  }
@@ -21,6 +21,8 @@
21
21
  #include "compat.h"
22
22
  #include "ruby.h"
23
23
 
24
+ #define MSGPACK_EXT_RECURSIVE 0b0001
25
+
24
26
  struct msgpack_packer_ext_registry_t;
25
27
  typedef struct msgpack_packer_ext_registry_t msgpack_packer_ext_registry_t;
26
28
 
@@ -44,7 +46,7 @@ void msgpack_packer_ext_registry_dup(msgpack_packer_ext_registry_t* src,
44
46
  msgpack_packer_ext_registry_t* dst);
45
47
 
46
48
  VALUE msgpack_packer_ext_registry_put(msgpack_packer_ext_registry_t* pkrg,
47
- VALUE ext_module, int ext_type, VALUE proc, VALUE arg);
49
+ VALUE ext_module, int ext_type, int flags, VALUE proc, VALUE arg);
48
50
 
49
51
  static int msgpack_packer_ext_find_superclass(VALUE key, VALUE value, VALUE arg)
50
52
  {
@@ -60,12 +62,13 @@ static int msgpack_packer_ext_find_superclass(VALUE key, VALUE value, VALUE arg)
60
62
  }
61
63
 
62
64
  static inline VALUE msgpack_packer_ext_registry_fetch(msgpack_packer_ext_registry_t* pkrg,
63
- VALUE lookup_class, int* ext_type_result)
65
+ VALUE lookup_class, int* ext_type_result, int* ext_flags_result)
64
66
  {
65
67
  // fetch lookup_class from hash, which is a hash to register classes
66
68
  VALUE type = rb_hash_lookup(pkrg->hash, lookup_class);
67
69
  if(type != Qnil) {
68
70
  *ext_type_result = FIX2INT(rb_ary_entry(type, 0));
71
+ *ext_flags_result = FIX2INT(rb_ary_entry(type, 3));
69
72
  return rb_ary_entry(type, 1);
70
73
  }
71
74
 
@@ -74,6 +77,7 @@ static inline VALUE msgpack_packer_ext_registry_fetch(msgpack_packer_ext_registr
74
77
  VALUE type_inht = rb_hash_lookup(pkrg->cache, lookup_class);
75
78
  if(type_inht != Qnil) {
76
79
  *ext_type_result = FIX2INT(rb_ary_entry(type_inht, 0));
80
+ *ext_flags_result = FIX2INT(rb_ary_entry(type_inht, 3));
77
81
  return rb_ary_entry(type_inht, 1);
78
82
  }
79
83
  }
@@ -82,7 +86,7 @@ static inline VALUE msgpack_packer_ext_registry_fetch(msgpack_packer_ext_registr
82
86
  }
83
87
 
84
88
  static inline VALUE msgpack_packer_ext_registry_lookup(msgpack_packer_ext_registry_t* pkrg,
85
- VALUE instance, int* ext_type_result)
89
+ VALUE instance, int* ext_type_result, int* ext_flags_result)
86
90
  {
87
91
  VALUE type;
88
92
 
@@ -97,7 +101,7 @@ static inline VALUE msgpack_packer_ext_registry_lookup(msgpack_packer_ext_regist
97
101
  * `rb_class_of` returns the singleton_class if the object has one, or the "real class" otherwise.
98
102
  */
99
103
  VALUE lookup_class = rb_class_of(instance);
100
- type = msgpack_packer_ext_registry_fetch(pkrg, lookup_class, ext_type_result);
104
+ type = msgpack_packer_ext_registry_fetch(pkrg, lookup_class, ext_type_result, ext_flags_result);
101
105
  if(type != Qnil) {
102
106
  return type;
103
107
  }
@@ -108,7 +112,7 @@ static inline VALUE msgpack_packer_ext_registry_lookup(msgpack_packer_ext_regist
108
112
  */
109
113
  VALUE real_class = rb_obj_class(instance);
110
114
  if(lookup_class != real_class) {
111
- type = msgpack_packer_ext_registry_fetch(pkrg, real_class, ext_type_result);
115
+ type = msgpack_packer_ext_registry_fetch(pkrg, real_class, ext_type_result, ext_flags_result);
112
116
  if(type != Qnil) {
113
117
  return type;
114
118
  }
@@ -130,6 +134,7 @@ static inline VALUE msgpack_packer_ext_registry_lookup(msgpack_packer_ext_regist
130
134
  }
131
135
  rb_hash_aset(pkrg->cache, lookup_class, superclass_type);
132
136
  *ext_type_result = FIX2INT(rb_ary_entry(superclass_type, 0));
137
+ *ext_flags_result = FIX2INT(rb_ary_entry(superclass_type, 3));
133
138
  return rb_ary_entry(superclass_type, 1);
134
139
  }
135
140